From 86aa0fa418c5dc27158c09c504a25cec07b24904 Mon Sep 17 00:00:00 2001 From: Marcin Dolatowski Date: Thu, 2 Jan 2025 15:39:49 +0100 Subject: [PATCH] feat: display rating on group card (#121) * feat: display rating on group card * fix: typecheck --- .../src/app/plans/edit/[id]/page.client.tsx | 3 +- frontend/src/components/class-block-stars.tsx | 39 +++++++++++++++++++ frontend/src/components/class-block.tsx | 24 +++++++++++- frontend/src/lib/types.ts | 2 + frontend/src/lib/utils/update-local-plan.ts | 2 + frontend/src/types/index.ts | 2 + 6 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 frontend/src/components/class-block-stars.tsx diff --git a/frontend/src/app/plans/edit/[id]/page.client.tsx b/frontend/src/app/plans/edit/[id]/page.client.tsx index b3c2a4e..9e06fbd 100644 --- a/frontend/src/app/plans/edit/[id]/page.client.tsx +++ b/frontend/src/app/plans/edit/[id]/page.client.tsx @@ -237,7 +237,6 @@ export function CreateNewPlanPage({ ); } - return (
@@ -399,6 +398,8 @@ export function CreateNewPlanPage({ .split(":") .slice(0, 2) .join(":"), + spotsOccupied: g.spotsOccupied, + spotsTotal: g.spotsTotal, }) satisfies ExtendedGroup, ), })) diff --git a/frontend/src/components/class-block-stars.tsx b/frontend/src/components/class-block-stars.tsx new file mode 100644 index 0000000..3795c3a --- /dev/null +++ b/frontend/src/components/class-block-stars.tsx @@ -0,0 +1,39 @@ +import { StarHalfIcon, StarIcon } from "lucide-react"; + +function customRound(rating: number): number { + const integerPart = Math.floor(rating); + const decimalPart = rating - integerPart; + + if (decimalPart > 0.7) { + return integerPart + 1; + } else if (decimalPart >= 0.3) { + return integerPart + 0.5; + } else { + return integerPart; + } +} + +export function StarsRating({ rating }: { rating: number }) { + const roundedRating = customRound(rating); + const fullPoints = Math.floor(roundedRating); + const isHalfPoint = roundedRating % 1 === 0.5; + return ( +
+ {Array.from({ length: fullPoints }).map((_, index) => { + return ( + + ); + })} + {isHalfPoint ? ( + + ) : null} +
+ ); +} diff --git a/frontend/src/components/class-block.tsx b/frontend/src/components/class-block.tsx index dae543a..43993bd 100644 --- a/frontend/src/components/class-block.tsx +++ b/frontend/src/components/class-block.tsx @@ -1,5 +1,6 @@ import React from "react"; +import { StarsRating } from "@/components/class-block-stars"; import { cn } from "@/lib/utils"; export const typeClasses = { @@ -34,6 +35,8 @@ export function ClassBlock({ courseType, isChecked, isDisabled, + spotsOccupied, + spotsTotal, onClick, isReadonly = false, }: { @@ -47,11 +50,13 @@ export function ClassBlock({ isChecked: boolean; isDisabled: boolean; isReadonly?: boolean; + spotsOccupied: number; + spotsTotal: number; onClick: () => void; }) { const position = calculatePosition(startTime, endTime); const [startGrid, durationSpan] = position; - + const randomRating = Math.random() * 5; return ( ); } diff --git a/frontend/src/lib/types.ts b/frontend/src/lib/types.ts index b9093bd..afe2f0f 100644 --- a/frontend/src/lib/types.ts +++ b/frontend/src/lib/types.ts @@ -13,6 +13,8 @@ export interface ClassBlockProps { week: "" | "TN" | "TP"; courseType: "C" | "L" | "P" | "S" | "W"; registrationId: string; + spotsOccupied: number; + spotsTotal: number; } export interface Registration { diff --git a/frontend/src/lib/utils/update-local-plan.ts b/frontend/src/lib/utils/update-local-plan.ts index 15812c6..d50e8a2 100644 --- a/frontend/src/lib/utils/update-local-plan.ts +++ b/frontend/src/lib/utils/update-local-plan.ts @@ -58,6 +58,8 @@ export const updateLocalPlan = async ( week: g.week.replace("-", "") as "" | "TN" | "TP", endTime: g.endTime.split(":").slice(0, 2).join(":"), startTime: g.startTime.split(":").slice(0, 2).join(":"), + spotsOccupied: g.spotsOccupied, + spotsTotal: g.spotsTotal, })); return { id: c.id, diff --git a/frontend/src/types/index.ts b/frontend/src/types/index.ts index 1df74af..36e6341 100644 --- a/frontend/src/types/index.ts +++ b/frontend/src/types/index.ts @@ -80,6 +80,8 @@ export type CourseType = { type: "C" | "L" | "P" | "S" | "W"; url: string; courseId: string; + spotsOccupied: number; + spotsTotal: number; createdAt: string; updatedAt: string; }[];