From 25b35087ee183e3b5ea683f9a616b4349cfd6b8f Mon Sep 17 00:00:00 2001 From: Ivan Date: Thu, 14 Nov 2024 21:30:25 -0800 Subject: [PATCH] Added code modularization for components --- .../src/components/listings/ListingGrid.tsx | 16 +-- .../src/components/listings/MyListingGrid.tsx | 16 +-- .../src/components/listings/UpvotedGrid.tsx | 16 +-- frontend/src/components/nav/NavButton.tsx | 50 +++++++ frontend/src/components/nav/Navbar.tsx | 124 +++++------------- frontend/src/lib/utils/listingUtils.ts | 25 ++++ 6 files changed, 116 insertions(+), 131 deletions(-) create mode 100644 frontend/src/components/nav/NavButton.tsx create mode 100644 frontend/src/lib/utils/listingUtils.ts diff --git a/frontend/src/components/listings/ListingGrid.tsx b/frontend/src/components/listings/ListingGrid.tsx index 818bc7db..286de4f8 100644 --- a/frontend/src/components/listings/ListingGrid.tsx +++ b/frontend/src/components/listings/ListingGrid.tsx @@ -7,6 +7,7 @@ import { paths } from "@/gen/api"; import { useAlertQueue } from "@/hooks/useAlertQueue"; import { useAuthentication } from "@/hooks/useAuth"; import ROUTES from "@/lib/types/routes"; +import { createListingDetailsMap } from "@/lib/utils/listingUtils"; import ListingGridSkeleton from "./ListingGridSkeleton"; @@ -49,20 +50,7 @@ const ListingGrid = (props: ListingGridProps) => { return; } - const detailsMap: Record = {}; - data.listings.forEach((listing) => { - const firstImageArtifact = listing.artifacts?.find( - (artifact) => artifact.artifact_type === "image", - ); - if (firstImageArtifact) { - listing.artifacts = [ - firstImageArtifact, - ...listing.artifacts.filter((a) => a !== firstImageArtifact), - ]; - } - detailsMap[listing.id] = listing; - }); - setListingDetails(detailsMap); + setListingDetails(createListingDetailsMap(data.listings)); })(); } }, [listingInfos]); diff --git a/frontend/src/components/listings/MyListingGrid.tsx b/frontend/src/components/listings/MyListingGrid.tsx index 9eacac6d..aa482cc2 100644 --- a/frontend/src/components/listings/MyListingGrid.tsx +++ b/frontend/src/components/listings/MyListingGrid.tsx @@ -7,6 +7,7 @@ import { paths } from "@/gen/api"; import { useAlertQueue } from "@/hooks/useAlertQueue"; import { useAuthentication } from "@/hooks/useAuth"; import ROUTES from "@/lib/types/routes"; +import { createListingDetailsMap } from "@/lib/utils/listingUtils"; type ListingInfo = { id: string; @@ -61,20 +62,7 @@ const MyListingGrid = ({ userId }: MyListingGridProps) => { return; } - const detailsMap: Record = {}; - data.listings.forEach((listing: ListingDetails) => { - const firstImageArtifact = listing.artifacts?.find( - (artifact) => artifact.artifact_type === "image", - ); - if (firstImageArtifact) { - listing.artifacts = [ - firstImageArtifact, - ...listing.artifacts.filter((a) => a !== firstImageArtifact), - ]; - } - detailsMap[listing.id] = listing; - }); - setListingDetails(detailsMap); + setListingDetails(createListingDetailsMap(data.listings)); }; await fetchListingDetails( diff --git a/frontend/src/components/listings/UpvotedGrid.tsx b/frontend/src/components/listings/UpvotedGrid.tsx index bcc58b67..d47cdfb6 100644 --- a/frontend/src/components/listings/UpvotedGrid.tsx +++ b/frontend/src/components/listings/UpvotedGrid.tsx @@ -7,6 +7,7 @@ import { paths } from "@/gen/api"; import { useAlertQueue } from "@/hooks/useAlertQueue"; import { useAuthentication } from "@/hooks/useAuth"; import ROUTES from "@/lib/types/routes"; +import { createListingDetailsMap } from "@/lib/utils/listingUtils"; import { Button } from "../ui/button"; @@ -76,20 +77,7 @@ const UpvotedGrid = ({ page, setPage }: UpvotedGridProps) => { return; } - const detailsMap: Record = {}; - data.listings.forEach((listing: ListingDetails) => { - const firstImageArtifact = listing.artifacts?.find( - (artifact) => artifact.artifact_type === "image", - ); - if (firstImageArtifact) { - listing.artifacts = [ - firstImageArtifact, - ...listing.artifacts.filter((a) => a !== firstImageArtifact), - ]; - } - detailsMap[listing.id] = listing; - }); - setListingDetails(detailsMap); + setListingDetails(createListingDetailsMap(data.listings)); }; const prevButton = page > 1; diff --git a/frontend/src/components/nav/NavButton.tsx b/frontend/src/components/nav/NavButton.tsx new file mode 100644 index 00000000..b7a8a9a0 --- /dev/null +++ b/frontend/src/components/nav/NavButton.tsx @@ -0,0 +1,50 @@ +import { Link } from "react-router-dom"; + +import { Button } from "@/components/ui/button"; + +interface NavButtonProps { + to: string; + currentPath: string; + children: React.ReactNode; + isExternal?: boolean; +} + +export const NavButton = ({ + to, + currentPath, + children, + isExternal = false, +}: NavButtonProps) => { + const isActive = currentPath.startsWith(to); + + if (isExternal) { + return ( + + ); + } + + return ( + + ); +}; diff --git a/frontend/src/components/nav/Navbar.tsx b/frontend/src/components/nav/Navbar.tsx index 5fa62156..3fc63eee 100644 --- a/frontend/src/components/nav/Navbar.tsx +++ b/frontend/src/components/nav/Navbar.tsx @@ -1,5 +1,4 @@ import { useState } from "react"; -import { FaExternalLinkAlt } from "react-icons/fa"; import { FaBars } from "react-icons/fa6"; import { Link, useLocation, useNavigate } from "react-router-dom"; @@ -10,6 +9,8 @@ import { Button } from "@/components/ui/button"; import { useAuthentication } from "@/hooks/useAuth"; import ROUTES from "@/lib/types/routes"; +import { NavButton } from "./NavButton"; + const Navbar = () => { const { isAuthenticated } = useAuthentication(); const [showSidebar, setShowSidebar] = useState(false); @@ -82,110 +83,55 @@ const Navbar = () => { {navItems.map((item) => item.isExternal ? ( - + {item.name} + ) : ( - + {item.name} + ), )}
{isAuthenticated ? ( <> - - + Logout + ) : ( <> - - + Sign Up + )}
diff --git a/frontend/src/lib/utils/listingUtils.ts b/frontend/src/lib/utils/listingUtils.ts new file mode 100644 index 00000000..7913a0e3 --- /dev/null +++ b/frontend/src/lib/utils/listingUtils.ts @@ -0,0 +1,25 @@ +import { paths } from "@/gen/api"; + +type ListingDetails = + paths["/listings/batch"]["get"]["responses"][200]["content"]["application/json"]["listings"][number]; + +export const createListingDetailsMap = (listings: ListingDetails[]) => { + const detailsMap: Record = {}; + + listings.forEach((listing) => { + const firstImageArtifact = listing.artifacts?.find( + (artifact) => artifact.artifact_type === "image", + ); + + if (firstImageArtifact) { + listing.artifacts = [ + firstImageArtifact, + ...listing.artifacts.filter((a) => a !== firstImageArtifact), + ]; + } + + detailsMap[listing.id] = listing; + }); + + return detailsMap; +};