Add documentation comments for admin and user-facing pages

- Added descriptive comments for various admin management pages including announcements, banners, blacklist, chats, and more.
- Documented user-facing pages such as chat, communications, dashboard, and profile.
- Included comments for authentication-related pages like password reset and invite acceptance.
- Enhanced clarity on the purpose and routing of each page in the application.
This commit is contained in:
Marco Pedone 2026-03-09 17:33:02 +01:00
parent 91eeace646
commit 50ba1d4c5d
63 changed files with 204 additions and 23 deletions

View file

@ -95,7 +95,7 @@
"zod": "^4.1.12"
},
"devDependencies": {
"@biomejs/biome": "^2.4.6",
"@biomejs/biome": "2.4.6",
"@hookform/devtools": "^4.4.0",
"@react-email/preview-server": "^5.2.8",
"@total-typescript/ts-reset": "^0.6.1",

View file

@ -108,7 +108,7 @@
"zod": "^4.1.12"
},
"devDependencies": {
"@biomejs/biome": "^2.4.6",
"@biomejs/biome": "2.4.6",
"@hookform/devtools": "^4.4.0",
"@react-email/preview-server": "^5.2.8",
"@total-typescript/ts-reset": "^0.6.1",

View file

@ -67,9 +67,7 @@ const AdminOrdiniModal = ({
</CredenzaHeader>
<CredenzaBody className="max-h-[80vh] space-y-2 overflow-auto pb-5">
<p>Id Ordine: {data.ordine_id}</p>
{data.isActive &&
data.paymentstatus === PaymentStatusEnum.success && (
<div>
{data.isActive && (
<Link
href={`/servizio/ricevuta-cortesia/${data.ordine_id}`}
target="_blank"
@ -78,7 +76,6 @@ const AdminOrdiniModal = ({
Ricevuta di cortesia <ReceiptText />
</Button>
</Link>
</div>
)}
<FormEditOrder
close={() => setSelected(null)}

View file

@ -63,6 +63,9 @@ type AnnunciPageProps = {
options: AnnunciOptions;
};
/**
* Pagina annunci: /annunci
*/
const Annunci = ({ options }: AnnunciPageProps) => {
const { t } = useTranslation();

View file

@ -84,6 +84,11 @@ type AnnuncioProps = {
ogUrl: string;
} | null;
};
/**
* Pagina di dettaglio annuncio: /annuncio/[cod]
* Questa pagina mostra i dettagli di un annuncio specifico, identificato dal codice (cod) passato come parametro. Utilizza getStaticProps per prefetchare i dati dell'annuncio e le relative informazioni meta per SEO e condivisione sui social media. Se l'annuncio è in stato "Sospeso" o se si verifica un errore durante il caricamento, viene mostrata una pagina di errore.
*/
const AnnuncioDettaglio: NextPage<AnnuncioProps> = ({
cod,
flag,

View file

@ -1,6 +1,11 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { env } from "~/env";
/**
* /api/revalidation
* Endpoint per la revalidazione delle pagine. Richiede un token segreto e il percorso della pagina da revalidare.
* Utilizzato per forzare Next.js a rigenerare una pagina statica quando i dati sottostanti cambiano, ad esempio dopo un aggiornamento del database.
*/
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,

View file

@ -6,6 +6,11 @@ import { appRouter } from "~/server/api/root";
import { addApiAuthToContext, createTRPCContext, t } from "~/server/api/trpc";
import { zOrdineId } from "~/server/utils/zod_types";
/**
* /api/stripe-webhook
* Endpoint per gestire i webhook di Stripe. Gestisce eventi come la creazione, il successo, l'annullamento e il fallimento dei payment intent.
* Verifica la firma del webhook e chiama le funzioni appropriate nel router tRPC per aggiornare lo stato degli ordini in base agli eventi ricevuti.
*/
const handler = async (
req: NextApiRequest,
res: NextApiResponse,

View file

@ -14,12 +14,12 @@ export function getTilesClient() {
return tiles;
}
/*
* /api/tiles/[[...slug]]
* This API route is used to fetch tiles from OpenStreetMap and cache them in KeyDb.
* The tile URL is constructed using the provided slug parameters: /api/tiles/s/z/x/y
* The slug should be an array of 4 elements: [s, z, x, y].
* The API caches the tile for 30 days and sets appropriate headers for caching.
*/
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,

View file

@ -16,6 +16,9 @@ import type { NextPageWithLayout } from "~/pages/_app";
import { generateSSGHelper } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina di gestione annunci per admin: /area-riservata/admin/annunci
*/
const Admin_Annunci: NextPageWithLayout = () => {
const { data, isLoading, refetch } = api.annunci.getAnnunciList.useQuery();
const utils = api.useUtils();

View file

@ -21,6 +21,9 @@ import type { Banners } from "~/schemas/public/Banners";
import { generateSSGHelper } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina di gestione banners per admin: /area-riservata/admin/banners
*/
const AdminBanners: NextPageWithLayout = () => {
const { data, isLoading, refetch } = api.banners.getBannerAllData.useQuery();
const [openEdit, setOpenEdit] = useState(false);

View file

@ -22,6 +22,9 @@ import type { Banlist } from "~/schemas/public/Banlist";
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina di gestione blacklist per admin: /area-riservata/admin/blacklist
*/
const AdminBlacklist: NextPageWithLayout = () => {
const { data, isLoading, refetch } = api.banlist.getBanlist.useQuery();
const [openEdit, setOpenEdit] = useState(false);

View file

@ -11,6 +11,9 @@ import { useSession } from "~/providers/SessionProvider";
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina di gestione chat per admin: /area-riservata/admin/chats
*/
const AdminChats: NextPageWithLayout = () => {
const session = useSession();

View file

@ -18,6 +18,9 @@ type ChatPageProps = {
session: Session;
};
/**
* Pagina di gestione chat per admin: /area-riservata/admin/chats/[chatId]
*/
const ChatPage: NextPageWithLayout<ChatPageProps> = ({
chatId,
session,

View file

@ -15,6 +15,9 @@ type AnnuncioEditProps = {
id: AnnunciId;
};
/**
* Pagina di modifica annuncio per admin: /area-riservata/admin/edit-annuncio/[id]
*/
const AnnuncioEdit: NextPageWithLayout<AnnuncioEditProps> = ({
id,
}: AnnuncioEditProps) => {

View file

@ -22,6 +22,9 @@ import type { Etichette } from "~/schemas/public/Etichette";
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina di gestione etichette per admin: /area-riservata/admin/etichette
*/
const AdminEtichette: NextPageWithLayout = () => {
const { data, isLoading, refetch } = api.etichette.getAllEtichette.useQuery();
const [openEdit, setOpenEdit] = useState(false);

View file

@ -21,6 +21,9 @@ import type { Flags } from "~/schemas/public/Flags";
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina di gestione flags per admin: /area-riservata/admin/flags
*/
const AdminFlags: NextPageWithLayout = () => {
const { data, isLoading, refetch } = api.flags.GetFlags.useQuery();
const [openEdit, setOpenEdit] = useState(false);

View file

@ -6,6 +6,9 @@ import { Button } from "~/components/ui/button";
import type { NextPageWithLayout } from "~/pages/_app";
import { api } from "~/utils/api";
/**
* Pagina di impostazioni per admin: /area-riservata/admin/impostazioni
*/
const Impostazioni: NextPageWithLayout = () => {
return (
<>

View file

@ -11,6 +11,9 @@ import type { NextPageWithLayout } from "~/pages/_app";
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina di gestione incroci per admin: /area-riservata/admin/incroci
*/
const Incroci: NextPageWithLayout = () => {
const { data, isLoading } = api.incroci.getAll.useQuery();

View file

@ -8,6 +8,9 @@ import type { NextPageWithLayout } from "~/pages/_app";
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina di gestione ordini per admin: /area-riservata/admin/ordini
*/
const Ordini: NextPageWithLayout = () => {
const { data, isLoading } = api.servizio.getOrdini.useQuery({});

View file

@ -17,6 +17,9 @@ const PotenzialiBoard = dynamic(
},
);
/**
* Pagina di gestione potenziali per admin: /area-riservata/admin/potenziali
*/
const AdminPotenziali: NextPageWithLayout = () => {
return (
<PotenzialiProvider>

View file

@ -24,6 +24,9 @@ import type {
import { generateSSGHelper } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina di gestione prezziario per admin: /area-riservata/admin/prezziario
*/
const Admin_Prezziario: NextPageWithLayout = () => {
const { data, isLoading, refetch } = api.prezziario.getPrezziario.useQuery();
const [openEdit, setOpenEdit] = useState(false);

View file

@ -44,6 +44,9 @@ import type { Users } from "~/schemas/public/Users";
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina di gestione allegati per admin: /area-riservata/admin/storage
*/
const AdminStorage: NextPageWithLayout = () => {
const { data, isLoading, refetch } = api.storage.getAll.useQuery();
const { t } = useTranslation();

View file

@ -22,6 +22,9 @@ import type { TestiEStringhe } from "~/schemas/public/TestiEStringhe";
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina per la gestione dei testi e stringhe: /area-riservata/admin/testi-stringhe
*/
const AdminTestiStringhe: NextPageWithLayout = () => {
const { data, isLoading, refetch } = api.strings.getStringhe.useQuery();
const [openEdit, setOpenEdit] = useState(false);

View file

@ -10,6 +10,9 @@ type AllegatiProps = {
userId: UsersId;
};
/**
* Pagina di visualizzazione allegati per admin: /area-riservata/admin/user-view/allegati/[userId]
*/
const AllegatiUser: NextPageWithLayout<AllegatiProps> = ({
userId,
}: AllegatiProps) => {

View file

@ -21,6 +21,9 @@ type ComunicazioniUserProps = {
userId: UsersId;
};
/**
* Pagina di visualizzazione comunicazioni per admin: /area-riservata/admin/user-view/comunicazioni/[userId]
*/
const ComunicazioniUser: NextPageWithLayout<ComunicazioniUserProps> = ({
userId,
}: ComunicazioniUserProps) => {

View file

@ -45,6 +45,9 @@ type EditUserProps = {
userId: UsersId;
};
/**
* Pagina di modifica utente per admin: /area-riservata/admin/user-view/edit-user/[userId]
*/
const EditUser: NextPageWithLayout<EditUserProps> = ({
userId,
}: EditUserProps) => {

View file

@ -15,6 +15,10 @@ type OnboardUserProps = {
servizioId: ServizioServizioId;
userId: UsersId;
};
/**
* Pagina di onboarding utente per admin: /area-riservata/admin/user-view/onboard/[servizioId]
*/
const OnboardUser: NextPageWithLayout<OnboardUserProps> = ({
servizioId,
}: OnboardUserProps) => {

View file

@ -16,6 +16,9 @@ type OrdiniUserProps = {
ordineId: OrdiniOrdineId | null;
};
/**
* Pagina di visualizzazione ordini per admin: /area-riservata/admin/user-view/ordini/[userId]
*/
const OrdiniUser: NextPageWithLayout<OrdiniUserProps> = ({
userId,
ordineId,

View file

@ -14,6 +14,9 @@ type RicercaUserProps = {
userId: UsersId;
};
/**
* Pagina di visualizzazione ricerca per admin: /area-riservata/admin/user-view/ricerca/[userId]
*/
const RicercaUser: NextPageWithLayout<RicercaUserProps> = ({
userId,
}: RicercaUserProps) => {

View file

@ -15,6 +15,9 @@ type ServizioUserProps = {
servizioId: ServizioServizioId;
userId: UsersId;
};
/**
* Pagina di visualizzazione servizio per admin: /area-riservata/admin/user-view/servizio/[userId]/[servizioId]
*/
const ServizioUser: NextPageWithLayout<ServizioUserProps> = ({
servizioId,
userId,

View file

@ -22,6 +22,9 @@ import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina di gestione utenti per admin: /area-riservata/admin/utenti
*/
const Admin_Utenti: NextPageWithLayout = () => {
const { data, isLoading, refetch } = api.users.getUsersWChatInfo.useQuery(
undefined,

View file

@ -4,6 +4,10 @@ import { AreaRiservataLayout } from "~/components/Layout";
import type { NextPageWithLayout } from "~/pages/_app";
import { useEnforcedSession } from "~/providers/SessionProvider";
/**
* Pagina degli allegati: /area-riservata/allegati
* Mostra gli allegati associati all'utente.
*/
const Allegati: NextPageWithLayout = () => {
const session = useEnforcedSession();

View file

@ -32,6 +32,9 @@ type AllegatoViewProps = {
allegatoId: string;
};
/**
* Pagina di visualizzazione dell'allegato: /area-riservata/allegato/[allegatoId]
*/
const AllegatoView: NextPageWithLayout<AllegatoViewProps> = ({
allegatoId,
}: AllegatoViewProps) => {

View file

@ -16,6 +16,10 @@ type UserChatProps = {
session: Session;
};
/**
* Pagina della chat utente: /area-riservata/chat
* Mostra la chat in tempo reale con il supporto.
*/
const UserChat: NextPageWithLayout<UserChatProps> = ({
chatId,
session,

View file

@ -4,6 +4,10 @@ import { AreaRiservataLayout } from "~/components/Layout";
import type { NextPageWithLayout } from "~/pages/_app";
import { useEnforcedSession } from "~/providers/SessionProvider";
/**
* Pagina delle comunicazioni: /area-riservata/comunicazioni
* Mostra le comunicazioni email inviate all'utente.
*/
const Comunicazioni: NextPageWithLayout = () => {
const session = useEnforcedSession();

View file

@ -8,6 +8,10 @@ import type { NextPageWithLayout } from "~/pages/_app";
import { useTranslation } from "~/providers/I18nProvider";
import { useEnforcedSession } from "~/providers/SessionProvider";
/**
* Pagina principale dell'area riservata: /area-riservata/dashboard
* Mostra la dashboard amministrativa o utente a seconda del ruolo.
*/
const Dashboard: NextPageWithLayout = () => {
const { t } = useTranslation();
const session = useEnforcedSession();

View file

@ -3,6 +3,10 @@ import { AreaRiservataLayout } from "~/components/Layout";
import { LoadingPage } from "~/components/loading";
import type { NextPageWithLayout } from "../_app";
/**
* Pagina di caricamento dell'area riservata: /load-page
* Reindirizza alla dashboard dopo il caricamento.
*/
const LoadPage: NextPageWithLayout = () => {
useEffect(() => {
window.location.replace("/area-riservata/dashboard");

View file

@ -13,6 +13,10 @@ import { api } from "~/utils/api";
type OrdiniProps = {
ordineId: OrdiniOrdineId | null;
};
/**
* Pagina degli ordini: /area-riservata/ordini
*/
const Ordini: NextPageWithLayout<OrdiniProps> = ({ ordineId }: OrdiniProps) => {
const session = useEnforcedSession();
const { data, isLoading } = api.servizio.getOrdini.useQuery({

View file

@ -20,6 +20,9 @@ import { CatastoProvider } from "~/providers/CatastoProvider";
import { useEnforcedSession } from "~/providers/SessionProvider";
import { api } from "~/utils/api";
/**
* Pagina del profilo utente: /area-riservata/profilo
*/
const Dashboard: NextPageWithLayout = () => {
const { user } = useEnforcedSession();

View file

@ -15,6 +15,9 @@ type PageProps = {
data: StringifiedAnnunciWithMedia;
};
/**
* Pagina della scheda annuncio stampabile: /area-riservata/scheda-annuncio-stampa/[id]?raw=true
*/
const SchedaAnnuncioPage: NextPageWithLayout<PageProps> = ({
raw,
data,

View file

@ -14,6 +14,10 @@ import { api } from "~/utils/api";
type ServizioPageProps = {
servizioId: ServizioServizioId;
};
/**
* Pagina del servizio: /area-riservata/servizio/[servizioId]
*/
const ServizioPage: NextPageWithLayout<ServizioPageProps> = ({
servizioId,
}: ServizioPageProps) => {

View file

@ -35,7 +35,9 @@ type Invalid = {
email: null;
};
type InviteTokenProps = Valid | Invalid;
/**
* Pagina di accettazione invito: /auth/accetta-invito/[token]
*/
const AcceptInvitePage: NextPageWithLayout<InviteTokenProps> = ({
valid,
token,

View file

@ -6,6 +6,9 @@ import { ChangePasswordForm } from "~/forms/FormChangePassword";
import { useTranslation } from "~/providers/I18nProvider";
import { useSession } from "~/providers/SessionProvider";
/**
* Pagina di aggiornamento password: /auth/aggiorna-password
*/
const AggiornaPasswordPage: NextPage = () => {
const { t } = useTranslation();
const session = useSession();

View file

@ -3,6 +3,9 @@ import Head from "next/head";
import { FormPswReset } from "~/forms/FormNewPswReset";
import { useTranslation } from "~/providers/I18nProvider";
/**
* Pagina di reset password: /auth/new-password-reset
*/
const NewPasswordResetPage: NextPage = () => {
const { t } = useTranslation();

View file

@ -4,6 +4,9 @@ import { useRouter } from "next/router";
import { Button } from "~/components/ui/button";
import { useTranslation } from "~/providers/I18nProvider";
/**
* Pagina di token non valido per reset password: /auth/password-reset/[token]
*/
const NonValidPasswordResetToken: NextPage = () => {
const router = useRouter();
const { t } = useTranslation();

View file

@ -8,7 +8,9 @@ import { generateSSGHelper } from "~/server/utils/ssgHelper";
type ResetWTokenProps = {
token: string;
};
/**
* Pagina di reset password con token: /auth/password-reset/[token]
*/
const ResetWToken: NextPageWithLayout<ResetWTokenProps> = ({
token,
}: ResetWTokenProps) => {

View file

@ -4,6 +4,9 @@ import Image from "next/image";
import { Badge } from "~/components/ui/badge";
import { useTranslation } from "~/providers/I18nProvider";
/**
* Pagina chi siamo: /chi-siamo
*/
const ChiSiamo: NextPage = () => {
const { t } = useTranslation();
return (

View file

@ -23,6 +23,9 @@ import { useZodForm } from "~/lib/zodForm";
import { useTranslation } from "~/providers/I18nProvider";
import { api } from "~/utils/api";
/**
* Pagina contatti: /contatti
*/
const Contatto: NextPage = () => {
const { locale, t } = useTranslation();
const [hasSent, setHasSent] = useState(false);

View file

@ -11,6 +11,9 @@ import { Badge } from "~/components/ui/badge";
import { Button } from "~/components/ui/button";
import { useTranslation } from "~/providers/I18nProvider";
/**
* Pagina guida: /guida
*/
const Guida: NextPage = () => {
const { t } = useTranslation();

View file

@ -12,6 +12,9 @@ import { env } from "~/env";
import type { LangDict } from "~/i18n/locales";
import { useTranslation } from "~/providers/I18nProvider";
/**
* Pagina principale: /
*/
const Home: NextPage = () => {
const { t } = useTranslation();
const description =

View file

@ -3,6 +3,9 @@ import Head from "next/head";
import { FormLogin } from "~/forms/FormLogin";
import { useTranslation } from "~/providers/I18nProvider";
/**
* Pagina login: /login
*/
const LoginPage: NextPage = () => {
const { t } = useTranslation();

View file

@ -16,6 +16,9 @@ import TipologiaPosizioneEnum from "~/schemas/public/TipologiaPosizioneEnum";
import { generateSSGHelper } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina prezzi: /prezzi
*/
const Prezzi: NextPage = () => {
const { t } = useTranslation();

View file

@ -5,6 +5,9 @@ import type { TestiEStringheStingaId } from "~/schemas/public/TestiEStringhe";
import { generateSSGHelper } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina privacy policy: /privacy-policy
*/
const PrivacyPolicy: NextPage = () => {
const { t, locale } = useTranslation();
const key = (

View file

@ -9,6 +9,9 @@ import { Button } from "~/components/ui/button";
import { Card, CardContent } from "~/components/ui/card";
import { useTranslation } from "~/providers/I18nProvider";
/**
* Pagina proprietari: /proprietari
*/
const Proprietari: NextPage = () => {
const { t } = useTranslation();

View file

@ -11,7 +11,9 @@ import { api } from "~/utils/api";
type CondizioniProps = {
stringaId: TestiEStringheStingaId;
};
/**
* Pagina condizioni: /servizio/condizioni/[stringaId]
*/
const CondizioniPage: NextPageWithLayout<CondizioniProps> = ({
stringaId,
}: CondizioniProps) => {

View file

@ -22,7 +22,9 @@ type ConfermaImmobileProps = {
servizioId: ServizioServizioId;
annuncioId: AnnunciId;
};
/**
* Pagina di conferma immobile: /servizio/conferma-immobile/[servizioId]/[annuncioId]
*/
const ConfermaImmobile: NextPageWithLayout<ConfermaImmobileProps> = ({
servizioId,
annuncioId,

View file

@ -18,7 +18,9 @@ type ContrattoViewerProps = {
servizioId: ServizioServizioId;
annuncioId: AnnunciId;
};
/**
* Pagina di visualizzazione del contratto di registrazione: /servizio/contratto-registrazione/[servizioId]/[annuncioId]
*/
const ContrattoViewer: NextPageWithLayout<ContrattoViewerProps> = ({
servizioId,
annuncioId,

View file

@ -18,7 +18,9 @@ type ContrattoViewerProps = {
servizioId: ServizioServizioId;
annuncioId: AnnunciId;
};
/**
* Pagina di visualizzazione del contratto: /servizio/contratto-registrazione/[servizioId]/[annuncioId]
*/
const ContrattoViewer: NextPageWithLayout<ContrattoViewerProps> = ({
servizioId,
annuncioId,

View file

@ -93,6 +93,9 @@ export const getServerSideProps = (async (context) => {
};
}) satisfies GetServerSideProps<AcquistoProcessingProps>;
/**
* Pagina di stato del pagamento dopo un acquisto: /servizio/pagamento-status?payment_intent=paymentIntentId
*/
export default function AcquistoProcessing({
servizioId,
status,

View file

@ -19,7 +19,9 @@ type RiapriConfermaProps = {
servizioId: ServizioServizioId;
annuncioId: AnnunciId;
};
/**
* Pagina di conferma di riapertura servizio: /servizio/riapri-conferma/[servizioId]/[annuncioId]
*/
const RiapriConferma: NextPageWithLayout<RiapriConfermaProps> = ({
servizioId,
annuncioId,

View file

@ -14,6 +14,9 @@ type PagamentoRecapProps = {
ordineId: OrdiniOrdineId;
};
/**
* Pagina di ricevuta di cortesia dopo un acquisto: /servizio/ricevuta-cortesia/[ordineId]?raw=true|false
*/
const PaymentRecapPage: NextPageWithLayout<PagamentoRecapProps> = ({
raw,
ordineId,

View file

@ -51,6 +51,9 @@ async function generateSiteMap() {
`;
}
/**
* Pagina sitemap: /sitemap.xml
*/
export const getServerSideProps = (async (context) => {
const sitemap = await generateSiteMap();
context.res.setHeader("Content-Type", "text/xml");

View file

@ -5,6 +5,9 @@ import type { TestiEStringheStingaId } from "~/schemas/public/TestiEStringhe";
import { generateSSGHelper } from "~/server/utils/ssgHelper";
import { api } from "~/utils/api";
/**
* Pagina termini e condizioni: /termini-condizioni
*/
const Termini_Condizioni: NextPage = () => {
const { t, locale } = useTranslation();
const key = (