1
0
Fork 0
polaris-task-force/src/app/(frontend)/awards/page.tsx

95 lines
3.4 KiB
TypeScript

import config from "@payload-config";
import { getPayload } from "payload";
import type { Award, Media } from "@/payload-types";
import { AwardWithGrantButton } from "@/components/frontend/account/AwardWithGrantButton";
import { Item, ItemContent, ItemHeader, ItemTitle } from "@/components/ui/item";
import { MedalIcon } from "lucide-react";
export const metadata = {
title: "Awards",
description:
"Browse every medal and ribbon that can be granted to a member of Polaris Task Force.",
};
const TYPE_LABEL: Record<"ribbon" | "medal", string> = {
ribbon: "Ribbons",
medal: "Medals",
};
export default async function AwardsPage() {
const payload = await getPayload({ config });
const res = await payload.find({
collection: "awards",
where: {
type: { in: ["ribbon", "medal"] },
},
sort: "name",
limit: 100,
depth: 1,
overrideAccess: true,
});
const awards: Award[] = res.docs;
const ribbons = awards.filter((a) => a.type === "ribbon");
const medals = awards.filter((a) => a.type === "medal");
const sections: { title: string; items: Award[] }[] = [];
if (medals.length > 0) sections.push({ title: TYPE_LABEL.medal, items: medals });
if (ribbons.length > 0) sections.push({ title: TYPE_LABEL.ribbon, items: ribbons });
return (
<div className="p-5 flex flex-col gap-6 max-w-7xl">
<div className="flex flex-col gap-1.5">
<div className="flex items-center gap-2">
<MedalIcon className="size-4 text-muted-foreground" />
<h1 className="text-2xl font-bold tracking-tight uppercase">Awards</h1>
</div>
<p className="text-sm text-muted-foreground max-w-2xl">
A reference of every medal and ribbon that can be earned by a member of Polaris Task
Force. Review the requirements for each award and its artwork. Commendations are granted
on the fly and are not catalogued here.
</p>
</div>
{awards.length === 0 ? (
<Item variant="muted">
<ItemHeader>
<ItemTitle>No awards defined</ItemTitle>
</ItemHeader>
<ItemContent>
<p className="text-sm text-muted-foreground italic">
No medals or ribbons have been catalogued yet. Check back soon.
</p>
</ItemContent>
</Item>
) : (
sections.map((section) => (
<section key={section.title} className="flex flex-col gap-3">
<h2 className="text-sm font-semibold uppercase tracking-wider text-muted-foreground">
{section.title}
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{section.items.map((award) => {
const awardImage =
typeof award.image === "object" && award.image ? (award.image as Media) : null;
const backgroundImage =
typeof award.backgroundImage === "object" && award.backgroundImage
? (award.backgroundImage as Media)
: null;
return (
<AwardWithGrantButton
key={award.id}
award={award}
awardImage={awardImage}
backgroundImage={backgroundImage}
/>
);
})}
</div>
</section>
))
)}
</div>
);
}