From 17d81460692ad9d752a5853b0733a766efb72d4a Mon Sep 17 00:00:00 2001 From: David Lin <13061926+DavidLHW@users.noreply.github.com> Date: Sun, 21 Jan 2024 16:58:53 +0800 Subject: [PATCH 1/9] feat: thumbs up filled icon --- .../components/CustomIcon/ThumbUpFilledIcon.tsx | 12 ++++++++++++ src/common/components/CustomIcon/index.ts | 1 + 2 files changed, 13 insertions(+) create mode 100644 src/common/components/CustomIcon/ThumbUpFilledIcon.tsx diff --git a/src/common/components/CustomIcon/ThumbUpFilledIcon.tsx b/src/common/components/CustomIcon/ThumbUpFilledIcon.tsx new file mode 100644 index 00000000..7a4ca920 --- /dev/null +++ b/src/common/components/CustomIcon/ThumbUpFilledIcon.tsx @@ -0,0 +1,12 @@ +import { CustomIcon, type CustomIconProps } from "./CustomIcon"; + +export const ThumbUpFilledIcon = (props: CustomIconProps) => { + return ( + + + + ); +}; diff --git a/src/common/components/CustomIcon/index.ts b/src/common/components/CustomIcon/index.ts index 64e98227..91902274 100644 --- a/src/common/components/CustomIcon/index.ts +++ b/src/common/components/CustomIcon/index.ts @@ -12,5 +12,6 @@ export * from "./LockIcon"; export * from "./MinusIcon"; export * from "./SearchIcon"; export * from "./StarLineAltIcon"; +export * from "./ThumbUpFilledIcon"; export * from "./WarningCircleIcon"; export * from "./XCloseIcon"; From b6c75dbfa557aff99333c64dcf11e9d7f8f1ca4e Mon Sep 17 00:00:00 2001 From: David Lin <13061926+DavidLHW@users.noreply.github.com> Date: Sun, 21 Jan 2024 17:01:56 +0800 Subject: [PATCH 2/9] chore: clean up functions --- src/app/(school)/layout.tsx | 4 +- .../components/MobileHeader/MobileHeader.tsx | 6 +-- .../Modal/ModalHeader/ModalHeader.tsx | 2 +- src/common/components/Sidebar/Sidebar.tsx | 2 +- .../components/SidebarItem/SidebarItem.tsx | 2 +- .../getHumanReadableTimestampDelta.ts | 38 +++++++++++++++++++ src/common/functions/index.ts | 3 ++ 7 files changed, 49 insertions(+), 8 deletions(-) create mode 100644 src/common/functions/getHumanReadableTimestampDelta.ts create mode 100644 src/common/functions/index.ts diff --git a/src/app/(school)/layout.tsx b/src/app/(school)/layout.tsx index 1e6e62ec..105a27b2 100644 --- a/src/app/(school)/layout.tsx +++ b/src/app/(school)/layout.tsx @@ -1,4 +1,4 @@ -import { cn } from "@/common/functions/cn"; +import { cn } from "@/common/functions"; import { type PropsWithChildren } from "react"; export default function SchoolLayout({ children }: PropsWithChildren) { @@ -6,7 +6,7 @@ export default function SchoolLayout({ children }: PropsWithChildren) {
{ {/* Overlay */}
{ {/* Sidebar */}
{ className?: string; diff --git a/src/common/components/Sidebar/Sidebar.tsx b/src/common/components/Sidebar/Sidebar.tsx index 233a508e..0f001ac5 100644 --- a/src/common/components/Sidebar/Sidebar.tsx +++ b/src/common/components/Sidebar/Sidebar.tsx @@ -13,7 +13,7 @@ import { Icon } from "@iconify-icon/react"; import { SidebarItem } from "@/common/components/SidebarItem"; import { Logo } from "@/common/components/Logo"; import { Input } from "@/common/components/Input"; -import { cn } from "@/common/functions/cn"; +import { cn } from "@/common/functions"; const SIDEBAR_ITEMS = [ { diff --git a/src/common/components/SidebarItem/SidebarItem.tsx b/src/common/components/SidebarItem/SidebarItem.tsx index 6b944e50..d50bb249 100644 --- a/src/common/components/SidebarItem/SidebarItem.tsx +++ b/src/common/components/SidebarItem/SidebarItem.tsx @@ -1,5 +1,5 @@ import { type SidebarItemType } from "@/common/components/Sidebar/Sidebar"; -import { cn } from "@/common/functions/cn"; +import { cn } from "@/common/functions"; import Link from "next/link"; export type SidebarListItem = SidebarItemType & { diff --git a/src/common/functions/getHumanReadableTimestampDelta.ts b/src/common/functions/getHumanReadableTimestampDelta.ts new file mode 100644 index 00000000..dddfd60b --- /dev/null +++ b/src/common/functions/getHumanReadableTimestampDelta.ts @@ -0,0 +1,38 @@ +/** + * Calculates the human-readable time delta between two Unix epoch timestamps. + * + * @param t0 - The Unix epoch timestamp to compare against (in seconds). + * @param t1 - [optional] The Unix epoch timestamp to compare with (in seconds). + * If omitted, the current time is used. + * @returns A human-readable representation of the time delta. eg `1d`, `2h`, `just now`. + * + * @example + * const t0 = 1642694400; // Unix timestamp for 2022-01-21 00:00:00 + * const t1 = 1642780800; // Unix timestamp for 2022-01-22 00:00:00 + * const delta = getHumanReadableTimestampDelta(t0, t1); + * console.log(delta); // Output: '1d' + * + * @example + * const delta = getHumanReadableTimestampDelta(Date.now() / 1000); + * console.log(delta); // Output: 'just now' + */ +export function getHumanReadableTimestampDelta( + t0: number, + t1: number = Date.now() / 1000, +) { + const deltaSeconds = Math.abs(t1 - t0); + const denominators = [ + { unit: "y", seconds: 365 * 24 * 60 * 60 }, + { unit: "mo", seconds: 30 * 24 * 60 * 60 }, + { unit: "w", seconds: 7 * 24 * 60 * 60 }, + { unit: "d", seconds: 24 * 60 * 60 }, + { unit: "h", seconds: 60 * 60 }, + { unit: "m", seconds: 60 }, + { unit: "s", seconds: 1 }, + ]; + for (const denominator of denominators) { + const value = Math.floor(deltaSeconds / denominator.seconds); + if (value > 0) return `${value}${denominator.unit}`; + } + return "just now"; // If the delta is less than a second +} diff --git a/src/common/functions/index.ts b/src/common/functions/index.ts new file mode 100644 index 00000000..914281ba --- /dev/null +++ b/src/common/functions/index.ts @@ -0,0 +1,3 @@ +export * from "./cn"; +export * from "./formatPercentage"; +export * from "./getHumanReadableTimestampDelta"; From b2c66fb44b216e5ad943670fe534e6c51e7c00d1 Mon Sep 17 00:00:00 2001 From: David Lin <13061926+DavidLHW@users.noreply.github.com> Date: Sun, 21 Jan 2024 17:02:45 +0800 Subject: [PATCH 3/9] chore: add variant to lock cta overlay component --- .../LockCtaOverlay/LockCtaOverlay.theme.ts | 38 +++++++++++++------ .../LockCtaOverlay/LockCtaOverlay.tsx | 32 +++++++++++++--- .../RatingSection/RatingSection.tsx | 2 +- 3 files changed, 54 insertions(+), 18 deletions(-) diff --git a/src/common/components/LockCtaOverlay/LockCtaOverlay.theme.ts b/src/common/components/LockCtaOverlay/LockCtaOverlay.theme.ts index fb445d6d..ef9671a8 100644 --- a/src/common/components/LockCtaOverlay/LockCtaOverlay.theme.ts +++ b/src/common/components/LockCtaOverlay/LockCtaOverlay.theme.ts @@ -19,26 +19,42 @@ export const lockCtaOverlayTheme = tv( ], wrapper: [ "inline-flex", + "absolute", + "left-0", + "top-0", "items-center", "justify-center", "h-full", "w-full", - "gap-1", "text-text-em-low", + "z-10", ], - icon: ["h-6", "w-6"], - ctaTextContainer: [ - "flex", - "items-center", - "gap-1", - "text-lg", - "font-medium", - ], + icon: [], + ctaTextContainer: ["flex", "items-center", "gap-1", "font-medium"], }, variants: { size: { - md: {}, - sm: {}, + md: { + wrapper: ["gap-2"], + icon: ["h-6", "w-6"], + ctaTextContainer: ["text-lg"], + }, + sm: { + wrapper: ["gap-[0.375rem]"], + icon: ["h-4", "w-4"], + ctaTextContainer: ["text-sm"], + }, + }, + variant: { + border: { + overlay: ["hidden"], + wrapper: [ + "rounded-lg", + "border-2", + "border-solid", + "border-border-default", + ], + }, }, }, }, diff --git a/src/common/components/LockCtaOverlay/LockCtaOverlay.tsx b/src/common/components/LockCtaOverlay/LockCtaOverlay.tsx index 16cf9ded..3b7819a4 100644 --- a/src/common/components/LockCtaOverlay/LockCtaOverlay.tsx +++ b/src/common/components/LockCtaOverlay/LockCtaOverlay.tsx @@ -1,20 +1,40 @@ import { Button } from "@/common/components/Button"; import { LockIcon } from "@/common/components/CustomIcon/LockIcon"; -import { lockCtaOverlayTheme } from "./LockCtaOverlay.theme"; +import { + lockCtaOverlayTheme, + type LockCtaOverlayVariants, +} from "./LockCtaOverlay.theme"; -export const LockCtaOverlay = () => { - const { wrapper, overlay, ctaTextContainer, icon } = lockCtaOverlayTheme(); +const ctaTextMap = { + rating: "to see rating", + review: "to see review", +} as const; + +export type LockCtaOverlayProps = LockCtaOverlayVariants & { + ctaType?: keyof typeof ctaTextMap; +}; + +export const LockCtaOverlay = ({ + variant, + size = "md", + ctaType = "rating", +}: LockCtaOverlayProps) => { + const { wrapper, overlay, ctaTextContainer, icon } = lockCtaOverlayTheme({ + variant, + size, + }); return ( -
+ <> +
- to see rating + {ctaTextMap[ctaType]}
-
+ ); }; diff --git a/src/common/components/RatingSection/RatingSection.tsx b/src/common/components/RatingSection/RatingSection.tsx index fae3a6bf..12ebea95 100644 --- a/src/common/components/RatingSection/RatingSection.tsx +++ b/src/common/components/RatingSection/RatingSection.tsx @@ -3,7 +3,7 @@ import { type RatingSectionVariants, } from "./RatingSection.theme"; import { HeartIcon } from "@/common/components/CustomIcon"; -import { LockCtaOverlay } from "@/common/components/LockCtaOverlay/LockCtaOverlay"; +import { LockCtaOverlay } from "@/common/components/LockCtaOverlay"; import { StatItem, type StatItemProps } from "@/common/components/StatItem"; export type RatingSectionProps = RatingSectionVariants & { From 385adbaf07fc97f833836dd64bcbc302776c2898 Mon Sep 17 00:00:00 2001 From: David Lin <13061926+DavidLHW@users.noreply.github.com> Date: Sun, 21 Jan 2024 17:03:28 +0800 Subject: [PATCH 4/9] feat: review item component --- src/app/components/page.tsx | 41 ++++++ .../components/ReviewItem/ReviewItem.theme.ts | 71 ++++++++++ .../components/ReviewItem/ReviewItem.tsx | 125 ++++++++++++++++++ src/common/components/ReviewItem/index.ts | 2 + 4 files changed, 239 insertions(+) create mode 100644 src/common/components/ReviewItem/ReviewItem.theme.ts create mode 100644 src/common/components/ReviewItem/ReviewItem.tsx create mode 100644 src/common/components/ReviewItem/index.ts diff --git a/src/app/components/page.tsx b/src/app/components/page.tsx index ca6a9573..17dff613 100644 --- a/src/app/components/page.tsx +++ b/src/app/components/page.tsx @@ -25,6 +25,7 @@ import { Combobox } from "@/modules/reviews/Combobox"; import { exampleListCountries } from "./exampleCountryList"; import { Modal } from "@/common/components/Modal"; import Heading from "@/common/components/Heading"; +import { type Label, ReviewItem } from "@/common/components/ReviewItem"; import { Tag } from "@/common/components/Tag"; const exampleListObj = exampleListCountries.map((el) => ({ @@ -83,6 +84,40 @@ const CommandContent = () => ( ); +const review = { + body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec auctor nunc a velit congue, et faucibus sapien iaculis. Quisque id felis non sapien egestas ultricies vulputate posuere quam. Vestibulum scelerisque arcu leo, sit amet interdum enim suscipit ut. Sed dolor turpis, tincidunt sed elementum at, posuere ac justo. Curabitur sem turpis, porttitor at ante sed, laoreet condimentum magna. Suspendisse ex orci, laoreet in cursus nec, rhoncus quis eros. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aliquam lacinia varius quam, ut blandit quam suscipit nec. Morbi facilisis mauris erat, quis porttitor purus consequat id. Maecenas.", + courseCode: "COR-MGMT1302", + username: "Anonymous", + likeCount: 10, + createdAt: 1705745162, + labels: [ + { + name: "Engaging", + typeof: "professor", + }, + { + name: "Fair Grading", + typeof: "professor", + }, + { + name: "Effective Teaching", + typeof: "professor", + }, + { + name: "Interesting", + typeof: "course", + }, + { + name: "Practical", + typeof: "course", + }, + { + name: "Gained New Skills", + typeof: "course", + }, + ] as Label[], +}; + export default function Components() { const [isMounted, setIsMounted] = useState(false); const { theme, setTheme } = useTheme(); @@ -480,6 +515,12 @@ export default function Components() {
+
+ + + + +
); } diff --git a/src/common/components/ReviewItem/ReviewItem.theme.ts b/src/common/components/ReviewItem/ReviewItem.theme.ts new file mode 100644 index 00000000..fbf0dfe4 --- /dev/null +++ b/src/common/components/ReviewItem/ReviewItem.theme.ts @@ -0,0 +1,71 @@ +import { type VariantProps, tv } from "tailwind-variants"; + +export type ReviewItemVariants = VariantProps; + +export const reviewItemTheme = tv( + { + slots: { + wrapper: [ + "flex", + "flex-col", + "p-2", + "items-start", + "w-[45rem]", + "gap-[0.375rem]", + ], + headingContainer: [ + "flex", + "self-stretch", + "justify-between", + "items-center", + "rounded-none", + "w-full", + "gap-10", + ], + schoolContainer: ["flex", "items-center", "gap-2"], + schoolIcon: [], + schoolCourseCode: [ + "flex", + "overflow-hidden", + "text-sm", + "text-ellipsis", + "text-text-em-mid", + ], + metadataContainer: ["flex", "gap-4", "items-center", "justify-end"], + profileContainer: ["flex", "items-center", "gap-2"], + profileName: [ + "overflow-hidden", + "text-sm", + "text-ellipsis", + "text-text-em-mid", + ], + profileIcon: [], + likeIcon: [], + timedelta: [ + "overflow-hidden", + "text-sm", + "text-ellipsis", + "text-text-em-low", + ], + body: [ + "relative", + "flex", + "h-16", + "w-full", + "self-stretch", + "overflow-hidden", + "text-sm", + "text-ellipsis", + "text-text-em-high", + ], + labels: [ + "text-sm", + "text-text-on-secondary", + "flex", + "gap-4", + "items-start", + ], + }, + }, + { responsiveVariants: true }, +); diff --git a/src/common/components/ReviewItem/ReviewItem.tsx b/src/common/components/ReviewItem/ReviewItem.tsx new file mode 100644 index 00000000..02aa6a61 --- /dev/null +++ b/src/common/components/ReviewItem/ReviewItem.tsx @@ -0,0 +1,125 @@ +import { Button } from "@/common/components/Button"; +import { reviewItemTheme, type ReviewItemVariants } from "./ReviewItem.theme"; +import { ThumbUpFilledIcon } from "@/common/components/CustomIcon"; +import { LockCtaOverlay } from "@/common/components/LockCtaOverlay"; +import { Tag } from "@/common/components/Tag"; +import { getHumanReadableTimestampDelta } from "@/common/functions"; + +// TODO: to replace with prisma generated types +export type Label = { + name: string; + typeof: "professor" | "course"; +}; + +export type Review = { + body: string; + courseCode: string; + username: string; + likeCount: number; + labels: Label[]; + createdAt: number; +}; + +export type ReviewItemProps = ReviewItemVariants & { + review: Review; + isLocked?: boolean; + variant?: "home" | "subpage"; +}; + +export const ReviewItem = ({ + review, + isLocked, + variant = "home", +}: ReviewItemProps) => { + const { + wrapper, + headingContainer, + schoolContainer, + schoolIcon, + schoolCourseCode, + metadataContainer, + profileContainer, + profileName, + profileIcon, + likeIcon, + timedelta, + body, + labels, + } = reviewItemTheme({ variant }); + + const HeaderCourse = () => ( +
+
+
+
+
{review.courseCode}
+
+ ); + + const HeaderReviewer = () => ( +
+
+
+
+
{review.username}
+
+ ); + + const ReviewContent = ({ isDetailed }: { isDetailed: boolean }) => { + return ( +
+ {isDetailed && ( +
+ {review.labels + .filter((label) => label.typeof === "professor") + .map((label) => ( + {label.name} + ))} +
+ )} + {isDetailed && ( +
+ {review.labels + .filter((label) => label.typeof === "course") + .map((label) => ( + {label.name} + ))} +
+ )} +
{review.body}
+ {isDetailed && ( + + )} +
+ ); + }; + + return ( +
+
+ {variant === "home" ? : } +
+ {variant === "home" ? : } + } + > + {review.likeCount} + +
+ {getHumanReadableTimestampDelta(review.createdAt)} +
+
+
+ {isLocked ? ( +
+ +
+ ) : ( + + )} +
+ ); +}; diff --git a/src/common/components/ReviewItem/index.ts b/src/common/components/ReviewItem/index.ts new file mode 100644 index 00000000..fc57828e --- /dev/null +++ b/src/common/components/ReviewItem/index.ts @@ -0,0 +1,2 @@ +export * from "./ReviewItem"; +export * from "./ReviewItem.theme"; From 5252839a1d3427f20357b73bfc0ee2f962e6c5ab Mon Sep 17 00:00:00 2001 From: David Lin <13061926+DavidLHW@users.noreply.github.com> Date: Wed, 31 Jan 2024 14:28:50 +0800 Subject: [PATCH 5/9] feat: add new rounded button variant --- src/common/components/Button/Button.theme.ts | 12 ++++++++++++ src/common/components/Button/Button.tsx | 2 ++ 2 files changed, 14 insertions(+) diff --git a/src/common/components/Button/Button.theme.ts b/src/common/components/Button/Button.theme.ts index 0ec2dcde..10b6729b 100644 --- a/src/common/components/Button/Button.theme.ts +++ b/src/common/components/Button/Button.theme.ts @@ -127,6 +127,18 @@ export const buttonTheme = tv( "[&>*:not(.loading)]:invisible", ], }, + rounded: { + true: [ + "inline-flex", + "min-w-14", + "py-[0.125rem]", + "px-3", + "gap-2", + "rounded-[6.1875rem]", + "border-solid", + "border-border-default", + ], + }, }, compoundVariants: [ { diff --git a/src/common/components/Button/Button.tsx b/src/common/components/Button/Button.tsx index a0a24ebe..463291b0 100644 --- a/src/common/components/Button/Button.tsx +++ b/src/common/components/Button/Button.tsx @@ -46,6 +46,7 @@ export const Button = forwardRef( iconLeft, iconRight, isResponsive = false, + rounded, fullWidth, disabled, loading, @@ -104,6 +105,7 @@ export const Button = forwardRef( iconOnly, size, as, + rounded, fullWidth, disabled, loading, From 2eaf9f01aaaf5deb5d527482bd985b2579610917 Mon Sep 17 00:00:00 2001 From: David Lin <13061926+DavidLHW@users.noreply.github.com> Date: Wed, 31 Jan 2024 14:53:08 +0800 Subject: [PATCH 6/9] feat: review item with 3 variants --- src/app/components/page.tsx | 19 +++- .../components/ReviewItem/ProfileReviewer.tsx | 17 ++++ .../components/ReviewItem/ProfileSchool.tsx | 17 ++++ .../components/ReviewItem/ReviewBody.tsx | 37 ++++++++ .../components/ReviewItem/ReviewItem.tsx | 95 +++++-------------- 5 files changed, 112 insertions(+), 73 deletions(-) create mode 100644 src/common/components/ReviewItem/ProfileReviewer.tsx create mode 100644 src/common/components/ReviewItem/ProfileSchool.tsx create mode 100644 src/common/components/ReviewItem/ReviewBody.tsx diff --git a/src/app/components/page.tsx b/src/app/components/page.tsx index 17dff613..a739e15c 100644 --- a/src/app/components/page.tsx +++ b/src/app/components/page.tsx @@ -25,7 +25,7 @@ import { Combobox } from "@/modules/reviews/Combobox"; import { exampleListCountries } from "./exampleCountryList"; import { Modal } from "@/common/components/Modal"; import Heading from "@/common/components/Heading"; -import { type Label, ReviewItem } from "@/common/components/ReviewItem"; +import { type ReviewLabel, ReviewItem } from "@/common/components/ReviewItem"; import { Tag } from "@/common/components/Tag"; const exampleListObj = exampleListCountries.map((el) => ({ @@ -115,7 +115,7 @@ const review = { name: "Gained New Skills", typeof: "course", }, - ] as Label[], + ] as ReviewLabel[], }; export default function Components() { @@ -516,10 +516,21 @@ export default function Components() {
+ + Home Page + - - + + Professor Page + + + + + Course Page + + +
); diff --git a/src/common/components/ReviewItem/ProfileReviewer.tsx b/src/common/components/ReviewItem/ProfileReviewer.tsx new file mode 100644 index 00000000..551826ee --- /dev/null +++ b/src/common/components/ReviewItem/ProfileReviewer.tsx @@ -0,0 +1,17 @@ +import { reviewItemTheme, type ReviewItemVariants } from "./ReviewItem.theme"; + +export type ProfileReviewerProps = ReviewItemVariants & { + name: string; +}; + +export const ProfileReviewer = ({ name }: ProfileReviewerProps) => { + const { profileContainer, profileName, profileIcon } = reviewItemTheme(); + return ( +
+
+
+
+
{name}
+
+ ); +}; diff --git a/src/common/components/ReviewItem/ProfileSchool.tsx b/src/common/components/ReviewItem/ProfileSchool.tsx new file mode 100644 index 00000000..39a0f403 --- /dev/null +++ b/src/common/components/ReviewItem/ProfileSchool.tsx @@ -0,0 +1,17 @@ +import { reviewItemTheme, type ReviewItemVariants } from "./ReviewItem.theme"; + +export type ProfileSchoolProps = ReviewItemVariants & { + courseCode: string; +}; + +export const ProfileSchool = ({ courseCode }: ProfileSchoolProps) => { + const { schoolContainer, schoolCourseCode, schoolIcon } = reviewItemTheme(); + return ( +
+
+
+
+
{courseCode}
+
+ ); +}; diff --git a/src/common/components/ReviewItem/ReviewBody.tsx b/src/common/components/ReviewItem/ReviewBody.tsx new file mode 100644 index 00000000..8522809c --- /dev/null +++ b/src/common/components/ReviewItem/ReviewBody.tsx @@ -0,0 +1,37 @@ +import { Button } from "@/common/components/Button"; +import { reviewItemTheme, type ReviewItemVariants } from "./ReviewItem.theme"; +import { Review } from "./ReviewItem"; + +export type ReviewBodyProps = ReviewItemVariants & { + review: Review; + isDetailed: boolean; + variant?: "home" | "subpage"; +}; + +export const ReviewBody = ({ review, isDetailed }: ReviewBodyProps) => { + const { body, labels } = reviewItemTheme(); + return ( +
+ {isDetailed && ( +
+ {review.labels + .filter((label) => label.typeof === "professor") + .map((label) => ( + {label.name} + ))} +
+ )} + {isDetailed && ( +
+ {review.labels + .filter((label) => label.typeof === "course") + .map((label) => ( + {label.name} + ))} +
+ )} +
{review.body}
+ {isDetailed && } +
+ ); +}; diff --git a/src/common/components/ReviewItem/ReviewItem.tsx b/src/common/components/ReviewItem/ReviewItem.tsx index 02aa6a61..bee8e2c1 100644 --- a/src/common/components/ReviewItem/ReviewItem.tsx +++ b/src/common/components/ReviewItem/ReviewItem.tsx @@ -1,12 +1,14 @@ -import { Button } from "@/common/components/Button"; import { reviewItemTheme, type ReviewItemVariants } from "./ReviewItem.theme"; +import { ReviewBody } from "./ReviewBody"; +import { ProfileSchool } from "./ProfileSchool"; +import { ProfileReviewer } from "./ProfileReviewer"; +import { getHumanReadableTimestampDelta } from "@/common/functions"; import { ThumbUpFilledIcon } from "@/common/components/CustomIcon"; import { LockCtaOverlay } from "@/common/components/LockCtaOverlay"; -import { Tag } from "@/common/components/Tag"; -import { getHumanReadableTimestampDelta } from "@/common/functions"; +import { Button } from "@/common/components/Button"; // TODO: to replace with prisma generated types -export type Label = { +export type ReviewLabel = { name: string; typeof: "professor" | "course"; }; @@ -16,14 +18,14 @@ export type Review = { courseCode: string; username: string; likeCount: number; - labels: Label[]; + labels: ReviewLabel[]; createdAt: number; }; export type ReviewItemProps = ReviewItemVariants & { review: Review; isLocked?: boolean; - variant?: "home" | "subpage"; + variant?: "home" | "professor" | "course"; }; export const ReviewItem = ({ @@ -34,80 +36,35 @@ export const ReviewItem = ({ const { wrapper, headingContainer, - schoolContainer, - schoolIcon, - schoolCourseCode, metadataContainer, - profileContainer, - profileName, - profileIcon, likeIcon, timedelta, body, - labels, - } = reviewItemTheme({ variant }); - - const HeaderCourse = () => ( -
-
-
-
-
{review.courseCode}
-
- ); - - const HeaderReviewer = () => ( -
-
-
-
-
{review.username}
-
- ); - - const ReviewContent = ({ isDetailed }: { isDetailed: boolean }) => { - return ( -
- {isDetailed && ( -
- {review.labels - .filter((label) => label.typeof === "professor") - .map((label) => ( - {label.name} - ))} -
- )} - {isDetailed && ( -
- {review.labels - .filter((label) => label.typeof === "course") - .map((label) => ( - {label.name} - ))} -
- )} -
{review.body}
- {isDetailed && ( - - )} -
- ); - }; + } = reviewItemTheme(); return (
- {variant === "home" ? : } + {variant === "home" ? ( + + ) : ( + + )}
- {variant === "home" ? : } - + ) : ( + variant === "professor" && ( + + ) + )} +
{getHumanReadableTimestampDelta(review.createdAt)}
@@ -118,7 +75,7 @@ export const ReviewItem = ({
) : ( - + )}
); From 5d75c582a4e0a950cb09d776707e651b224931d8 Mon Sep 17 00:00:00 2001 From: David Lin <13061926+DavidLHW@users.noreply.github.com> Date: Sat, 3 Feb 2024 01:09:03 +0800 Subject: [PATCH 7/9] refactor: unnecessary ternary --- src/common/components/ReviewItem/ReviewItem.tsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/common/components/ReviewItem/ReviewItem.tsx b/src/common/components/ReviewItem/ReviewItem.tsx index bee8e2c1..ac9efe4d 100644 --- a/src/common/components/ReviewItem/ReviewItem.tsx +++ b/src/common/components/ReviewItem/ReviewItem.tsx @@ -51,12 +51,9 @@ export const ReviewItem = ({ )}
- {variant === "home" ? ( - - ) : ( - variant === "professor" && ( - - ) + {variant === "home" && } + {variant === "professor" && ( + )}