2023-06-06 22:05:27 -05:00

193 lines
5.3 KiB
TypeScript

import { type InferGetStaticPropsType, type GetStaticPropsContext } from "next";
import { GlobeAltIcon, DocumentIcon } from "@heroicons/react/24/solid";
import { PencilSquareIcon } from "@heroicons/react/20/solid";
import { createServerSideHelpers } from "@trpc/react-query/server";
import { appRouter } from "~/server/api/root";
import { prisma } from "~/server/db";
import { api } from "~/utils/api";
import { ResourceDescription, ResourceInfo } from "~/components/ResourceTable";
import { type PlatformLink } from "@prisma/client";
import Image from "next/image";
import Link from "next/link";
import Footer from "~/components/Footer";
import Header from "~/components/Header";
import { AdminBarLayout } from "~/components/admin/ControlBar";
import { AdminActionLink } from "~/components/admin/common";
import { useRouter } from "next/router";
export const getStaticPaths = async () => {
const resources = await prisma.auditoryResource.findMany({
select: {
id: true,
},
});
return {
paths: resources.map((resource) => ({
params: {
id: resource.id,
},
})),
fallback: "blocking",
};
};
export async function getStaticProps(
context: GetStaticPropsContext<{ id: string }>
) {
const helpers = createServerSideHelpers({
router: appRouter,
ctx: {
prisma,
session: null,
},
});
const id = context.params?.id as string;
await helpers.auditoryResource.byId.prefetch({ id });
return {
props: {
trpcState: helpers.dehydrate(),
id,
},
revalidate: 1,
};
}
const PlatformLinkButton = ({
platformLink,
}: {
platformLink: PlatformLink;
}) => {
const Inner = () => {
switch (platformLink.platform) {
case "APP_ANDROID": {
return (
<Image
className="w-full"
src={`/google-play-badge.png`}
alt={`Download on the Apple AppStore`}
width={512}
height={216}
/>
);
}
case "APP_IOS": {
return (
<Image
className="w-full"
src={`/app-store-badge.png`}
alt={`Download on the Apple AppStore`}
width={512}
height={216}
/>
);
}
case "PDF": {
return (
<div className="flex h-16 flex-row space-x-2 rounded-lg border-2 border-neutral-900 bg-amber-300 px-2 align-middle hover:bg-amber-200">
<DocumentIcon className="w-6" />
<span className="my-auto text-sm font-bold">Document</span>
</div>
);
}
case "WEBSITE": {
return (
<div className="flex h-14 flex-row space-x-2 rounded-lg border-2 border-neutral-900 bg-amber-300 px-2 align-middle hover:bg-amber-200">
<GlobeAltIcon className="w-6" />
<span className="my-auto text-sm font-bold">Website</span>
</div>
);
}
}
};
return (
<Link href={platformLink.link} target="_blank" rel="noopener noreferrer">
<Inner />
</Link>
);
};
const DownloadButtons = ({
platformLinks,
}: {
platformLinks: PlatformLink[];
}) => {
const buttons = platformLinks.map((paltformLink, index) => {
return <PlatformLinkButton key={index} platformLink={paltformLink} />;
});
return <div className="mx-auto flex w-48 flex-col space-y-2">{buttons}</div>;
};
const ResourceViewPage = (
props: InferGetStaticPropsType<typeof getStaticProps>
) => {
const { id } = props;
const resourceQuery = api.auditoryResource.byId.useQuery({ id });
const router = useRouter();
const ConditionalView = () => {
if (!resourceQuery.data) {
return <></>;
}
return (
<div className="mx-auto flex max-w-2xl flex-col flex-col-reverse divide-x py-4 sm:flex-row">
<div className="my-5 mr-4 flex flex-col justify-end text-lg font-bold">
<div className="mx-4">
<h1 className="mb-2 border-b border-neutral-400">Links</h1>
<DownloadButtons
platformLinks={resourceQuery.data.platform_links}
/>
</div>
</div>
<div className="justify-left flex flex-col pb-5">
<ResourceInfo resource={resourceQuery.data} />
<div className="mx-4 overflow-hidden rounded-xl border border-neutral-400 bg-neutral-200 text-left shadow">
<ResourceDescription
manufacturer={resourceQuery.data.manufacturer}
description={resourceQuery.data.description}
/>
</div>
<div className="ml-4 mr-auto mt-4 rounded-lg border-2 border-neutral-900 bg-neutral-600">
<span className="px-2 py-2 text-sm text-neutral-200">
Ages {resourceQuery.data.ages.min}
{resourceQuery.data.ages.max >= 100
? "+"
: `-${resourceQuery.data.ages.max}`}
</span>
</div>
</div>
</div>
);
};
return (
<>
<div className="min-h-screen">
<Header />
<AdminBarLayout
actions={
<AdminActionLink
symbol={<PencilSquareIcon className="w-4" />}
label="Edit Page"
href={`${router.asPath}/edit`}
/>
}
>
<main className="mb-12">
<ConditionalView />
</main>
</AdminBarLayout>
<Footer />
</div>
</>
);
};
export default ResourceViewPage;