From 9a875f738155b72e7356ca205a00599755ce047a Mon Sep 17 00:00:00 2001 From: Kamran Ahmed Date: Tue, 30 Jul 2024 02:18:50 +0100 Subject: [PATCH] Refactor rating logic --- .../CustomRoadmap/CustomRoadmapRatings.tsx | 42 +++- .../CustomRoadmapRatingsModal.tsx | 4 +- .../CustomRoadmap/RateRoadmapForm.tsx | 236 ++++++++++-------- .../CustomRoadmap/RoadmapHeader.tsx | 7 +- src/components/Rating/Rating.tsx | 6 +- 5 files changed, 174 insertions(+), 121 deletions(-) diff --git a/src/components/CustomRoadmap/CustomRoadmapRatings.tsx b/src/components/CustomRoadmap/CustomRoadmapRatings.tsx index 257014b11..9cf4f1160 100644 --- a/src/components/CustomRoadmap/CustomRoadmapRatings.tsx +++ b/src/components/CustomRoadmap/CustomRoadmapRatings.tsx @@ -1,9 +1,8 @@ -import { useState, type CSSProperties } from 'react'; +import { useState } from 'react'; import { Rating } from '../Rating/Rating'; import type { RoadmapDocument } from './CreateRoadmap/CreateRoadmapModal'; import { CustomRoadmapRatingsModal } from './CustomRoadmapRatingsModal'; import { Star } from 'lucide-react'; -import { cn } from '../../lib/classname'; type CustomRoadmapRatingsProps = { roadmapSlug: string; @@ -16,6 +15,11 @@ export function CustomRoadmapRatings(props: CustomRoadmapRatingsProps) { const { ratings, roadmapSlug, canManage, unseenRatingCount } = props; const average = ratings?.average || 0; + const totalPeopleWhoRated = Object.keys(ratings?.breakdown || {}).reduce( + (acc, key) => acc + ratings?.breakdown[key as any], + 0, + ); + const [isDetailsOpen, setIsDetailsOpen] = useState(false); return ( @@ -30,30 +34,46 @@ export function CustomRoadmapRatings(props: CustomRoadmapRatingsProps) { canManage={canManage} /> )} -
- - - + {average === 0 && ( + + )} + {average > 0 && ( -
+ )} ); } diff --git a/src/components/CustomRoadmap/CustomRoadmapRatingsModal.tsx b/src/components/CustomRoadmap/CustomRoadmapRatingsModal.tsx index 3babe647a..75dfdc177 100644 --- a/src/components/CustomRoadmap/CustomRoadmapRatingsModal.tsx +++ b/src/components/CustomRoadmap/CustomRoadmapRatingsModal.tsx @@ -37,7 +37,7 @@ export function CustomRoadmapRatingsModal( ]; return ( - + {canManage && (
{tabs.map((tab) => { @@ -64,7 +64,7 @@ export function CustomRoadmapRatingsModal( )} {activeTab === 'ratings' && ( - + )} {activeTab === 'feedback' && ( diff --git a/src/components/CustomRoadmap/RateRoadmapForm.tsx b/src/components/CustomRoadmap/RateRoadmapForm.tsx index df5ca423a..cdf21b7cd 100644 --- a/src/components/CustomRoadmap/RateRoadmapForm.tsx +++ b/src/components/CustomRoadmap/RateRoadmapForm.tsx @@ -1,13 +1,14 @@ -import { useEffect, useState, type CSSProperties } from 'react'; +import { useEffect, useState } from 'react'; import type { RoadmapDocument } from './CreateRoadmap/CreateRoadmapModal'; import { formatCommaNumber } from '../../lib/number'; import { Rating } from '../Rating/Rating'; import { httpGet, httpPost } from '../../lib/http'; import { useToast } from '../../hooks/use-toast'; import { isLoggedIn } from '../../lib/jwt'; -import { Loader2 } from 'lucide-react'; +import { Loader2, Star } from 'lucide-react'; import { cn } from '../../lib/classname'; import { showLoginPopup } from '../../lib/popup'; +import { Spinner } from '../ReactIcons/Spinner.tsx'; type GetMyRoadmapRatingResponse = { id?: string; @@ -18,10 +19,11 @@ type GetMyRoadmapRatingResponse = { type RateRoadmapFormProps = { ratings: RoadmapDocument['ratings']; roadmapSlug: string; + canManage?: boolean; }; export function RateRoadmapForm(props: RateRoadmapFormProps) { - const { ratings, roadmapSlug } = props; + const { ratings, canManage = false, roadmapSlug } = props; const { breakdown = {}, average: _average } = ratings || {}; const average = _average || 0; @@ -31,9 +33,14 @@ export function RateRoadmapForm(props: RateRoadmapFormProps) { 0, ); + // if no rating then only show the ratings breakdown if the user can manage the roadmap + const showRatingsBreakdown = average > 0 || canManage; + const toast = useToast(); const [isLoading, setIsLoading] = useState(true); - const [isRatingRoadmap, setIsRatingRoadmap] = useState(false); + const [isSubmitting, setIsSubmitting] = useState(false); + + const [isRatingRoadmap, setIsRatingRoadmap] = useState(!showRatingsBreakdown); const [userRatingId, setUserRatingId] = useState(); const [userRating, setUserRating] = useState(0); const [userFeedback, setUserFeedback] = useState(''); @@ -61,7 +68,7 @@ export function RateRoadmapForm(props: RateRoadmapFormProps) { return; } - setIsLoading(true); + setIsSubmitting(true); const path = userRatingId ? 'v1-update-custom-roadmap-rating' : 'v1-rate-custom-roadmap'; @@ -74,7 +81,7 @@ export function RateRoadmapForm(props: RateRoadmapFormProps) { if (!response || error) { toast.error(error?.message || 'Something went wrong'); - setIsLoading(false); + setIsSubmitting(false); return; } @@ -91,51 +98,109 @@ export function RateRoadmapForm(props: RateRoadmapFormProps) { }, [roadmapSlug]); return ( - <> -
- - {average} out of 5 -
- - - {formatCommaNumber(totalRatings)} ratings - - -
    - {ratingsKeys.map((rating) => { - const percentage = - totalRatings <= 0 - ? 0 - : ((breakdown?.[rating] || 0) / totalRatings) * 100; - - return ( -
  • - {rating} star -
    - - {percentage}% - -
  • - ); - })} -
- -
- -
-

Rate this roadmap

-

- Share your thoughts with the roadmap creator. -

- - {(isRatingRoadmap || userRatingId) && ( +
+ {showRatingsBreakdown && !isRatingRoadmap && ( + <> +
    + {ratingsKeys.map((rating) => { + const percentage = + totalRatings <= 0 + ? 0 + : ((breakdown?.[rating] || 0) / totalRatings) * 100; + + return ( +
  • + {rating} star +
    +
    + + {percentage > 0 && ( + + {formatCommaNumber(breakdown?.[rating] || 0)} + + )} +
    + + + {percentage}% + +
  • + ); + })} +
+ + )} + + {!canManage && !isRatingRoadmap && ( +
+ {isLoading && ( +
+ +
+ )} + + {!isLoading && !isRatingRoadmap && !userRatingId && ( + <> +

+ Rate and share your thoughts with the roadmap creator. +

+ + + )} + + {!isLoading && !isRatingRoadmap && userRatingId && ( +
+

+ Your Feedback + +

+
+ ( + {userRating}) +
+ {userFeedback &&

{userFeedback}

} +
+ )} +
+ )} + + {!canManage && isRatingRoadmap && ( +
+

Rate this roadmap

+

+ Share your thoughts with the roadmap creator. +

+
{ @@ -155,45 +220,37 @@ export function RateRoadmapForm(props: RateRoadmapFormProps) { htmlFor="rating-feedback" className="block text-sm font-medium" > - Feedback + Feedback to Creator{' '} + (Optional)