Skip to content

Commit

Permalink
Added code modularization for components
Browse files Browse the repository at this point in the history
  • Loading branch information
ivntsng committed Nov 15, 2024
1 parent 703fc70 commit 25b3508
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 131 deletions.
16 changes: 2 additions & 14 deletions frontend/src/components/listings/ListingGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -49,20 +50,7 @@ const ListingGrid = (props: ListingGridProps) => {
return;
}

const detailsMap: Record<string, ListingDetails> = {};
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]);
Expand Down
16 changes: 2 additions & 14 deletions frontend/src/components/listings/MyListingGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -61,20 +62,7 @@ const MyListingGrid = ({ userId }: MyListingGridProps) => {
return;
}

const detailsMap: Record<string, ListingDetails> = {};
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(
Expand Down
16 changes: 2 additions & 14 deletions frontend/src/components/listings/UpvotedGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -76,20 +77,7 @@ const UpvotedGrid = ({ page, setPage }: UpvotedGridProps) => {
return;
}

const detailsMap: Record<string, ListingDetails> = {};
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;
Expand Down
50 changes: 50 additions & 0 deletions frontend/src/components/nav/NavButton.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Button
asChild
variant="outline"
className="px-2 xl:px-3 py-2 text-sm tracking-wide xl:tracking-widest text-gray-1"
>
<a
href={to}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-2"
>
{children}
</a>
</Button>
);
}

return (
<Button
asChild
variant={isActive ? "ghost" : "outline"}
className={`px-3 py-2 text-gray-1 ${
isActive ? "underline underline-offset-4 decoration-2" : ""
}`}
>
<Link to={to}>{children}</Link>
</Button>
);
};
124 changes: 35 additions & 89 deletions frontend/src/components/nav/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -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";

Expand All @@ -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<boolean>(false);
Expand Down Expand Up @@ -82,110 +83,55 @@ const Navbar = () => {
</div>
{navItems.map((item) =>
item.isExternal ? (
<Button
key={item.name}
asChild
variant="outline"
className="px-2 xl:px-3 py-2 text-sm tracking-wide xl:tracking-widest text-gray-1"
<NavButton
key={item.path}
to={item.path}
currentPath={location.pathname}
isExternal
>
<a
href={item.path}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-2"
>
{item.name}
<FaExternalLinkAlt className="h-3 w-3 text-gray-1" />
</a>
</Button>
{item.name}
</NavButton>
) : (
<Button
key={item.name}
asChild
variant={
location.pathname.startsWith(item.path)
? "ghost"
: "outline"
}
className={`px-2 xl:px-3 py-2 text-sm tracking-widest ${
location.pathname.startsWith(item.path)
? "underline underline-offset-4 decoration-2"
: ""
}`}
<NavButton
key={item.path}
to={item.path}
currentPath={location.pathname}
>
<Link to={item.path}>
<div className="flex items-center gap-2">{item.name}</div>
</Link>
</Button>
{item.name}
</NavButton>
),
)}
</div>
<div className="flex items-center space-x-4 text-gray-1 p-2 ml-4 text-sm tracking-widest">
{isAuthenticated ? (
<>
<Button
asChild
variant={
location.pathname.startsWith(ROUTES.ACCOUNT.path)
? "ghost"
: "outline"
}
className={`px-3 py-2 text-gray-1 ${
location.pathname.startsWith(ROUTES.ACCOUNT.path)
? "underline underline-offset-4 decoration-2"
: ""
}`}
<NavButton
to={ROUTES.ACCOUNT.path}
currentPath={location.pathname}
>
<Link to={ROUTES.ACCOUNT.path}>Account</Link>
</Button>
<Button
asChild
variant={
location.pathname.startsWith(ROUTES.LOGOUT.path)
? "ghost"
: "outline"
}
className={`px-3 py-2 text-gray-1 ${
location.pathname.startsWith(ROUTES.LOGOUT.path)
? "underline underline-offset-4 decoration-2"
: ""
}`}
Account
</NavButton>
<NavButton
to={ROUTES.LOGOUT.path}
currentPath={location.pathname}
>
<Link to={ROUTES.LOGOUT.path}>Logout</Link>
</Button>
Logout
</NavButton>
</>
) : (
<>
<Button
asChild
variant={
location.pathname.startsWith(ROUTES.LOGIN.path)
? "ghost"
: "outline"
}
className={`px-3 py-2 text-gray-1 ${
location.pathname.startsWith(ROUTES.LOGIN.path)
? "underline underline-offset-4 decoration-2"
: ""
}`}
<NavButton
to={ROUTES.LOGIN.path}
currentPath={location.pathname}
>
<Link to={ROUTES.LOGIN.path}>Log In</Link>
</Button>
<Button
asChild
variant={
location.pathname.startsWith(ROUTES.SIGNUP.path)
? "ghost"
: "outline"
}
className={`px-3 py-2 text-gray-1 ${
location.pathname.startsWith(ROUTES.SIGNUP.path)
? "underline underline-offset-4 decoration-2"
: ""
}`}
Log In
</NavButton>
<NavButton
to={ROUTES.SIGNUP.path}
currentPath={location.pathname}
>
<Link to={ROUTES.SIGNUP.path}>Sign Up</Link>
</Button>
Sign Up
</NavButton>
</>
)}
</div>
Expand Down
25 changes: 25 additions & 0 deletions frontend/src/lib/utils/listingUtils.ts
Original file line number Diff line number Diff line change
@@ -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<string, ListingDetails> = {};

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;
};

0 comments on commit 25b3508

Please sign in to comment.