infoalloggi-monorepo/apps/infoalloggi/src/pages/servizio/contratto/[...slug].tsx

136 lines
4 KiB
TypeScript
Raw Normal View History

2025-08-04 17:45:44 +02:00
import type { GetServerSideProps } from "next";
import type { NextPageWithLayout } from "~/pages/_app";
import { zAnnuncioId, zServizioId } from "~/server/utils/zod_types";
import { AreaRiservataLayout } from "~/components/Layout";
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
import { Button } from "~/components/ui/button";
import { api } from "~/utils/api";
import { LoadingPage } from "~/components/loading";
import type { StorageindexId } from "~/schemas/public/Storageindex";
import { AllegatoIframe } from "~/components/allegato-iframe";
import { handleDownload } from "~/hooks/filesHooks";
import type { ServizioServizioId } from "~/schemas/public/Servizio";
import type { AnnunciId } from "~/schemas/public/Annunci";
import { Status500 } from "~/components/status-page";
import { DocNotFoundPage } from "~/components/doc_not_found";
import { useTranslation } from "~/providers/I18nProvider";
2025-08-04 17:45:44 +02:00
type ContrattoViewerProps = {
servizioId: ServizioServizioId;
annuncioId: AnnunciId;
};
const ContrattoViewer: NextPageWithLayout<ContrattoViewerProps> = ({
servizioId,
annuncioId,
}: ContrattoViewerProps) => {
const { data, isLoading } = api.servizio.getServizioAnnuncio.useQuery({
servizioId,
annuncioId,
});
const { t } = useTranslation();
2025-08-04 17:45:44 +02:00
if (isLoading) return <LoadingPage />;
if (!data) return <Status500 />;
if (!data.doc_contratto_ref) return <DocNotFoundPage />;
return (
<div className="mx-2 flex flex-1 overflow-auto">
<div className="mx-auto flex grow sm:grow-0">
<div className="flex flex-col items-center space-y-4 py-4">
<h1 className="text-xl font-bold">{t.servizio.contratto.titolo}</h1>
<p className="text-center">{t.servizio.contratto.descrizione}</p>
2025-08-04 17:45:44 +02:00
<FileSection storageId={data.doc_contratto_ref} />
</div>
</div>
</div>
);
};
const FileSection = ({ storageId }: { storageId: StorageindexId }) => {
const { data: fileInfos, isLoading } = api.storage.getStorageFromId.useQuery({
storageId,
});
const { mutateAsync: getToken } = api.storage.getStorageToken.useMutation();
const { t } = useTranslation();
2025-08-04 17:45:44 +02:00
if (isLoading) return <LoadingPage />;
if (!fileInfos) return <p>{t.file_section.error}</p>;
2025-08-04 17:45:44 +02:00
return (
<>
<AllegatoIframe
allegato={fileInfos.id + fileInfos.ext}
className="h-full max-h-[70vh]"
/>
<Button
onClick={() =>
handleDownload({
file: fileInfos,
getToken: async () => await getToken(),
})
}
variant="link"
className="underline underline-offset-1 after:content-['_↗']"
>
{t.file_section.download}
2025-08-04 17:45:44 +02:00
</Button>
</>
);
};
ContrattoViewer.getLayout = function getLayout(page) {
return (
<AreaRiservataLayout noSidebar noFooter>
{page}
</AreaRiservataLayout>
);
};
export default ContrattoViewer;
export const getServerSideProps = (async (context) => {
const slug = context.params?.slug;
if (!slug || slug.length != 2) {
return {
notFound: true,
};
}
const [servizioId, annuncioId] = slug;
if (!servizioId || !annuncioId) {
return {
notFound: true,
};
}
const parsedServizioId = zServizioId.safeParse(servizioId);
const parsedAnnuncioId = zAnnuncioId.safeParse(parseInt(annuncioId));
if (!parsedServizioId.success || !parsedAnnuncioId.success) {
return {
notFound: true,
};
}
const access_token = context.req.cookies.access_token;
const helper = await TrpcAuthedFetchingIstance({ access_token });
if (helper) {
await helper.trpc.servizio.getServizioAnnuncio.prefetch({
servizioId: parsedServizioId.data,
annuncioId: parsedAnnuncioId.data,
});
return {
props: {
servizioId: parsedServizioId.data,
annuncioId: parsedAnnuncioId.data,
trpcState: helper.trpc.dehydrate(),
},
};
}
return {
redirect: {
destination: "/500",
permanent: false,
},
};
}) satisfies GetServerSideProps<ContrattoViewerProps>;