Add localization support for service confirmation and payment pages

This commit is contained in:
Marco Pedone 2025-08-13 17:29:26 +02:00
parent 8c85316c9f
commit 3127f773ba
13 changed files with 233 additions and 82 deletions

View file

@ -4,15 +4,16 @@ import { LoadingPage } from "~/components/loading";
import { AllegatoIframe } from "~/components/allegato-iframe"; import { AllegatoIframe } from "~/components/allegato-iframe";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { handleDownload } from "~/hooks/filesHooks"; import { handleDownload } from "~/hooks/filesHooks";
import { useTranslation } from "~/providers/I18nProvider";
export const FileSection = ({ storageId }: { storageId: StorageindexId }) => { export const FileSection = ({ storageId }: { storageId: StorageindexId }) => {
const { data: fileInfos, isLoading } = api.storage.getStorageFromId.useQuery({ const { data: fileInfos, isLoading } = api.storage.getStorageFromId.useQuery({
storageId, storageId,
}); });
const { mutateAsync: getToken } = api.storage.getStorageToken.useMutation(); const { mutateAsync: getToken } = api.storage.getStorageToken.useMutation();
const { t } = useTranslation();
if (isLoading) return <LoadingPage />; if (isLoading) return <LoadingPage />;
if (!fileInfos) return <p>Errore nel caricamento del documento</p>; if (!fileInfos) return <p>{t.file_section.error}</p>;
return ( return (
<> <>
<AllegatoIframe <AllegatoIframe
@ -30,7 +31,7 @@ export const FileSection = ({ storageId }: { storageId: StorageindexId }) => {
variant="link" variant="link"
className="underline underline-offset-1 after:content-['_↗']" className="underline underline-offset-1 after:content-['_↗']"
> >
Scarica una copia del documento {t.file_section.download}
</Button> </Button>
</> </>
); );

View file

@ -415,15 +415,34 @@ export const FormNewServizioAcquisto = ({
"budget", "budget",
]); ]);
const texts =
locale === "it"
? {
dettagli: "Dettagli del servizio",
dettagli_desc: "Questi dati rappresentano la tua ricerca",
personali: "Dati personali",
personali_desc: "Inserisci i tuoi dati personali",
fattura: "Vuoi che la fatturazione sia intestata alla tua azienda?",
sdi: "Codice destinatario SDI",
salva: "Salva e procedi al pagamento",
}
: {
dettagli: "Service Details",
dettagli_desc: "These data represent your search",
personali: "Personal Data",
personali_desc: "Enter your personal data",
fattura: "Do you want the invoice to be issued to your company?",
sdi: "SDI Recipient Code",
salva: "Save and proceed to payment",
};
return ( return (
<Form {...form}> <Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8 px-0.5"> <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8 px-0.5">
<Card> <Card>
<CardHeader> <CardHeader>
<CardTitle>Dettagli del servizio</CardTitle> <CardTitle>{texts.dettagli}</CardTitle>
<CardDescription> <CardDescription>{texts.dettagli_desc}</CardDescription>
Questi dati rappresentano la tua ricerca
</CardDescription>
</CardHeader> </CardHeader>
<CardContent className="space-y-6"> <CardContent className="space-y-6">
<FormField <FormField
@ -432,7 +451,9 @@ export const FormNewServizioAcquisto = ({
render={({ field }) => ( render={({ field }) => (
<FormItem> <FormItem>
<div className="flex flex-wrap items-center gap-x-2"> <div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="select-tipologia">Tipologia</FormLabel> <FormLabel htmlFor="select-tipologia">
{t.preferenze.tipologia}
</FormLabel>
<FormMessage /> <FormMessage />
</div> </div>
@ -790,10 +811,8 @@ export const FormNewServizioAcquisto = ({
</Card> </Card>
<Card> <Card>
<CardHeader> <CardHeader>
<CardTitle>Dati personali</CardTitle> <CardTitle>{texts.personali}</CardTitle>
<CardDescription> <CardDescription>{texts.personali_desc}</CardDescription>
Questi dati sono necessari per la fatturazione
</CardDescription>
</CardHeader> </CardHeader>
<CardContent className="space-y-6"> <CardContent className="space-y-6">
<div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row"> <div className="flex w-full flex-col items-start justify-between gap-4 sm:flex-row">
@ -963,8 +982,7 @@ export const FormNewServizioAcquisto = ({
<FormItem className="py-2"> <FormItem className="py-2">
<div className="flex items-center justify-start gap-x-4"> <div className="flex items-center justify-start gap-x-4">
<FormLabel htmlFor="fatturazione_aziendale"> <FormLabel htmlFor="fatturazione_aziendale">
Vuoi che la fatturazione sia intestata alla tua {texts.fattura}
azienda?
</FormLabel> </FormLabel>
<FormControl> <FormControl>
<Switch <Switch
@ -992,7 +1010,7 @@ export const FormNewServizioAcquisto = ({
<FormItem className="w-full"> <FormItem className="w-full">
<div className="flex flex-wrap items-center gap-x-2"> <div className="flex flex-wrap items-center gap-x-2">
<FormLabel htmlFor="codice_destinatario"> <FormLabel htmlFor="codice_destinatario">
Codice destinatario (SDI) {texts.sdi}
</FormLabel> </FormLabel>
<FormMessage /> <FormMessage />
</div> </div>
@ -1495,7 +1513,7 @@ export const FormNewServizioAcquisto = ({
/> />
)} )}
<Button type="submit" className="w-full sm:w-auto"> <Button type="submit" className="w-full sm:w-auto">
Salva e Procedi {texts.salva}
</Button> </Button>
</div> </div>
</form> </form>

View file

@ -88,15 +88,26 @@ export const FormPwSetup = ({ user, servizioId }: FormPwSetupProps) => {
}); });
} }
const texts =
locale === "it"
? {
scegli_password: "Scegli la tua password",
imposta_password: "Imposta una password per accedere al tuo account.",
salva_password: "Salva la password e prosegui",
}
: {
scegli_password: "Choose your password",
imposta_password: "Set a password to access your account.",
salva_password: "Save password and proceed",
};
return ( return (
<div className="mx-auto w-full max-w-3xl space-y-8 px-4 py-8"> <div className="mx-auto w-full max-w-3xl space-y-8 px-4 py-8">
<div className="my-8 space-y-5"> <div className="my-8 space-y-5">
<h3 className="text-3xl font-bold text-gray-800 sm:text-3xl"> <h3 className="text-3xl font-bold text-gray-800 sm:text-3xl">
Scegli la tua password {texts.scegli_password}
</h3> </h3>
<p className="text-muted-foreground"> <p className="text-muted-foreground">{texts.imposta_password}</p>
Imposta una password per accedere al tuo account.
</p>
</div> </div>
<Form {...form}> <Form {...form}>
@ -203,7 +214,7 @@ export const FormPwSetup = ({ user, servizioId }: FormPwSetupProps) => {
<LoadingSpinner size={25} /> <LoadingSpinner size={25} />
</div> </div>
) : ( ) : (
<span>Salva la password e prosegui</span> <span>{texts.salva_password}</span>
)} )}
</Button> </Button>
</form> </form>

View file

@ -292,6 +292,7 @@ export const en: LangDict = {
}, },
code_search_frases: ["Search by code", "Enter the code", "Type the code"], code_search_frases: ["Search by code", "Enter the code", "Type the code"],
acquisto: { acquisto: {
pagamento: "Payment",
titolo: "PURCHASE", titolo: "PURCHASE",
preparazione: "PAYMENT IN PREPARATION", preparazione: "PAYMENT IN PREPARATION",
servizi_acquisto: "SERVICE IN PURCHASE", servizi_acquisto: "SERVICE IN PURCHASE",
@ -1294,4 +1295,36 @@ The Stable Rent service, ideal for those with demonstrable work references and f
desc: "With our more than 25 years of experience in the real estate sector, we will guide you in choosing the type of lease best suited to your needs and that can guarantee you the best economic return.", desc: "With our more than 25 years of experience in the real estate sector, we will guide you in choosing the type of lease best suited to your needs and that can guarantee you the best economic return.",
}, },
}, },
servizio: {
conferma: {
titolo: "Property Confirmation",
descrizione:
"The document below summarizes the rental conditions between you and the owner",
cta: "To confirm the property, proceed with the deposit bank transfer!",
coordinate: "Bank details:",
intestazione: "Account holder:",
iban: "IBAN:",
importo: "Amount:",
causale: "Payment reference:",
coord_footer: "Send us the bank transfer receipt once completed!",
ho_letto: "I declare that I have read and understood the document.",
accetto: "I accept the terms and conditions.",
confermo_termini:
"You confirm your acceptance of the Terms of Service and Privacy Policy of InfoAlloggi.it.",
conferma: "Confirm acknowledgment and proceed with service payment",
},
contratto: {
titolo: "Rental Contract",
descrizione:
"You can view and download the rental contract. For any questions, contact us via chat or email.",
},
contratto_view: {
ricevuta: "Registration receipt",
ricevuta_cta: "You can view and download the registration receipt",
},
},
file_section: {
error: "Error loading file",
download: "Download a copy of the document",
},
}; };

View file

@ -457,6 +457,7 @@ export const it: LangDict = {
in_aggiornamento: "In aggiornamento", in_aggiornamento: "In aggiornamento",
}, },
acquisto: { acquisto: {
pagamento: "Pagamento",
titolo: "ACQUISTO", titolo: "ACQUISTO",
preparazione: "PAGAMENTO IN PREPARAZIONE", preparazione: "PAGAMENTO IN PREPARAZIONE",
servizi_acquisto: "SERVIZIO IN ACQUISTO", servizi_acquisto: "SERVIZIO IN ACQUISTO",
@ -1295,4 +1296,37 @@ export const it: LangDict = {
desc: "Con i nostri più di 25 anni di esperienza nel settore immobiliare, ti guideremo nella scelta della tipologia di locazione più adatta alle tue esigenze e che possa garantirti il miglior ritorno economico.", desc: "Con i nostri più di 25 anni di esperienza nel settore immobiliare, ti guideremo nella scelta della tipologia di locazione più adatta alle tue esigenze e che possa garantirti il miglior ritorno economico.",
}, },
}, },
servizio: {
conferma: {
titolo: "Conferma Immobile",
descrizione:
" Il documento sottostante riassume le condizioni della locazione tra te e il proprietario",
cta: "Per confermare l'immobile procedi al bonifico di caparra!",
coordinate: "Coordinate bancarie:",
intestazione: "Intestazione:",
iban: "IBAN:",
importo: "Importo:",
causale: "Causale:",
coord_footer: "Mandaci la contabile del bonifico una volta effettuato!",
ho_letto: "Dichiaro di aver letto e compreso il documento.",
accetto: "Accetto i termini e condizioni.",
confermo_termini:
"Confermi la tua accettazione dei Termini di servizio e della Politica sulla privacy di InfoAlloggi.it.",
conferma: "Conferma la presa visione e Procedi al saldo del servizio",
},
contratto: {
titolo: "Contratto di locazione",
descrizione:
"Hai modo di visualizzare e scaricare il contratto di locazione. Per qualunque dubbio, contattaci via chat o email.",
},
contratto_view: {
ricevuta: "Ricevuta di registrazione",
ricevuta_cta:
" Hai modo di visualizzare e scaricare la ricevuta. Per qualunque dubbio, contattaci via chat o email.",
},
},
file_section: {
error: "Errore nel caricamento del file",
download: "Scarica una copia del documento",
},
}; };

View file

@ -277,6 +277,7 @@ export type LangDict = {
in_aggiornamento: string; in_aggiornamento: string;
}; };
acquisto: { acquisto: {
pagamento: string;
titolo: string; titolo: string;
preparazione: string; preparazione: string;
servizi_acquisto: string; servizi_acquisto: string;
@ -738,6 +739,35 @@ export type LangDict = {
desc: string; desc: string;
}; };
}; };
servizio: {
conferma: {
titolo: string;
descrizione: string;
cta: string;
coordinate: string;
intestazione: string;
iban: string;
importo: string;
causale: string;
coord_footer: string;
ho_letto: string;
accetto: string;
confermo_termini: string;
conferma: string;
};
contratto: {
titolo: string;
descrizione: string;
};
contratto_view: {
ricevuta: string;
ricevuta_cta: string;
};
};
file_section: {
error: string;
download: string;
};
}; };
export type Locales = "it" | "en"; export type Locales = "it" | "en";

View file

@ -30,7 +30,7 @@ const ConfermaImmobile: NextPageWithLayout<ConfermaImmobileProps> = ({
servizioId, servizioId,
annuncioId, annuncioId,
}); });
const { t } = useTranslation();
if (isLoading) return <LoadingPage />; if (isLoading) return <LoadingPage />;
if (!data) return <Status500 />; if (!data) return <Status500 />;
if (!data.doc_conferma_ref) return <DocNotFoundPage />; if (!data.doc_conferma_ref) return <DocNotFoundPage />;
@ -38,25 +38,29 @@ const ConfermaImmobile: NextPageWithLayout<ConfermaImmobileProps> = ({
<div className="mx-2 flex flex-1 overflow-auto"> <div className="mx-2 flex flex-1 overflow-auto">
<div className="mx-auto flex grow sm:grow-0"> <div className="mx-auto flex grow sm:grow-0">
<div className="flex flex-col items-center space-y-4 py-4"> <div className="flex flex-col items-center space-y-4 py-4">
<h1 className="text-xl font-bold">Conferma Immobile</h1> <h1 className="text-xl font-bold">{t.servizio.conferma.titolo}</h1>
<p className="text-center"> <p className="text-center">{t.servizio.conferma.descrizione}</p>
Il documento sottostante riassume le condizioni della locazione tra
te e il proprietario
</p>
<FileSection storageId={data.doc_conferma_ref} /> <FileSection storageId={data.doc_conferma_ref} />
<div className="flex max-w-3xl flex-col gap-2 rounded-md bg-green-400 p-4 text-left"> <div className="flex max-w-3xl flex-col gap-2 rounded-md bg-green-400 p-4 text-left">
<p className="text-xl font-semibold"> <p className="text-xl font-semibold">{t.servizio.conferma.cta}</p>
Per confermare l&apos;immobile procedi al bonifico di caparra! <p>{t.servizio.conferma.coordinate}</p>
<p>
{t.servizio.conferma.intestazione}{" "}
{data.caparra_intestazione || ""}
</p>
<p>
{t.servizio.conferma.iban} {data.caparra_iban || ""}
</p>
<p>
{t.servizio.conferma.importo} {data.caparra_importo || ""}
</p>
<p>
{t.servizio.conferma.causale} {data.caparra_causale || ""}
</p> </p>
<p>Coordinate bancarie:</p>
<p>Intestazione: {data.caparra_intestazione || ""}</p>
<p>IBAN: {data.caparra_iban || ""}</p>
<p>Importo: {data.caparra_importo || ""}</p>
<p>Causale: {data.caparra_causale || ""}</p>
<p className="text-xl font-semibold"> <p className="text-xl font-semibold">
Mandaci la contabile del bonifico una volta effettuato! {t.servizio.conferma.coord_footer}
</p> </p>
</div> </div>
@ -111,7 +115,7 @@ const ConfirmSection = ({
htmlFor="letto" htmlFor="letto"
className="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70" className="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
> >
Dichiaro di aver letto e compreso il documento. {t.servizio.conferma.ho_letto}
</label> </label>
</div> </div>
</div> </div>
@ -126,11 +130,10 @@ const ConfirmSection = ({
htmlFor="termini" htmlFor="termini"
className="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70" className="text-sm leading-none font-medium peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
> >
Accetto i termini e condizioni. {t.servizio.conferma.accetto}
</label> </label>
<p className="text-muted-foreground text-sm"> <p className="text-muted-foreground text-sm">
Confermi la tua accettazione dei Termini di servizio e della {t.servizio.conferma.confermo_termini}
Politica sulla privacy di InfoAlloggi.it.
</p> </p>
</div> </div>
</div> </div>
@ -146,11 +149,9 @@ const ConfirmSection = ({
accettato_conferma_at: new Date(), accettato_conferma_at: new Date(),
}, },
}); });
//TODO mandare al saldo o in qualche modo segnare il servizio come completato e da pagare
}} }}
> >
Conferma la presa visione e Procedi al saldo del servizio {t.servizio.conferma.conferma}
</Button> </Button>
</> </>
); );

View file

@ -13,6 +13,7 @@ import type { ServizioServizioId } from "~/schemas/public/Servizio";
import type { AnnunciId } from "~/schemas/public/Annunci"; import type { AnnunciId } from "~/schemas/public/Annunci";
import { Status500 } from "~/components/status-page"; import { Status500 } from "~/components/status-page";
import { DocNotFoundPage } from "~/components/doc_not_found"; import { DocNotFoundPage } from "~/components/doc_not_found";
import { useTranslation } from "~/providers/I18nProvider";
type ContrattoViewerProps = { type ContrattoViewerProps = {
servizioId: ServizioServizioId; servizioId: ServizioServizioId;
@ -27,7 +28,7 @@ const ContrattoViewer: NextPageWithLayout<ContrattoViewerProps> = ({
servizioId, servizioId,
annuncioId, annuncioId,
}); });
const { t } = useTranslation();
if (isLoading) return <LoadingPage />; if (isLoading) return <LoadingPage />;
if (!data) return <Status500 />; if (!data) return <Status500 />;
if (!data.doc_registrazione_ref) return <DocNotFoundPage />; if (!data.doc_registrazione_ref) return <DocNotFoundPage />;
@ -35,10 +36,11 @@ const ContrattoViewer: NextPageWithLayout<ContrattoViewerProps> = ({
<div className="mx-2 flex flex-1 overflow-auto"> <div className="mx-2 flex flex-1 overflow-auto">
<div className="mx-auto flex grow sm:grow-0"> <div className="mx-auto flex grow sm:grow-0">
<div className="flex flex-col items-center space-y-4 py-4"> <div className="flex flex-col items-center space-y-4 py-4">
<h1 className="text-xl font-bold">Ricevuta di registrazione</h1> <h1 className="text-xl font-bold">
{t.servizio.contratto_view.ricevuta}
</h1>
<p className="text-center"> <p className="text-center">
Hai modo di visualizzare e scaricare la ricevuta. Per qualunque {t.servizio.contratto_view.ricevuta_cta}
dubbio, contattaci via chat o email.
</p> </p>
<FileSection storageId={data.doc_registrazione_ref} /> <FileSection storageId={data.doc_registrazione_ref} />
</div> </div>
@ -52,9 +54,9 @@ const FileSection = ({ storageId }: { storageId: StorageindexId }) => {
storageId, storageId,
}); });
const { mutateAsync: getToken } = api.storage.getStorageToken.useMutation(); const { mutateAsync: getToken } = api.storage.getStorageToken.useMutation();
const { t } = useTranslation();
if (isLoading) return <LoadingPage />; if (isLoading) return <LoadingPage />;
if (!fileInfos) return <p>Errore nel caricamento del documento</p>; if (!fileInfos) return <p>{t.file_section.error}</p>;
return ( return (
<> <>
<AllegatoIframe <AllegatoIframe
@ -72,7 +74,7 @@ const FileSection = ({ storageId }: { storageId: StorageindexId }) => {
variant="link" variant="link"
className="underline underline-offset-1 after:content-['_↗']" className="underline underline-offset-1 after:content-['_↗']"
> >
Scarica una copia del documento {t.file_section.download}
</Button> </Button>
</> </>
); );

View file

@ -13,6 +13,7 @@ import type { ServizioServizioId } from "~/schemas/public/Servizio";
import type { AnnunciId } from "~/schemas/public/Annunci"; import type { AnnunciId } from "~/schemas/public/Annunci";
import { Status500 } from "~/components/status-page"; import { Status500 } from "~/components/status-page";
import { DocNotFoundPage } from "~/components/doc_not_found"; import { DocNotFoundPage } from "~/components/doc_not_found";
import { useTranslation } from "~/providers/I18nProvider";
type ContrattoViewerProps = { type ContrattoViewerProps = {
servizioId: ServizioServizioId; servizioId: ServizioServizioId;
@ -27,7 +28,7 @@ const ContrattoViewer: NextPageWithLayout<ContrattoViewerProps> = ({
servizioId, servizioId,
annuncioId, annuncioId,
}); });
const { t } = useTranslation();
if (isLoading) return <LoadingPage />; if (isLoading) return <LoadingPage />;
if (!data) return <Status500 />; if (!data) return <Status500 />;
if (!data.doc_contratto_ref) return <DocNotFoundPage />; if (!data.doc_contratto_ref) return <DocNotFoundPage />;
@ -35,11 +36,8 @@ const ContrattoViewer: NextPageWithLayout<ContrattoViewerProps> = ({
<div className="mx-2 flex flex-1 overflow-auto"> <div className="mx-2 flex flex-1 overflow-auto">
<div className="mx-auto flex grow sm:grow-0"> <div className="mx-auto flex grow sm:grow-0">
<div className="flex flex-col items-center space-y-4 py-4"> <div className="flex flex-col items-center space-y-4 py-4">
<h1 className="text-xl font-bold">Contratto di locazione</h1> <h1 className="text-xl font-bold">{t.servizio.contratto.titolo}</h1>
<p className="text-center"> <p className="text-center">{t.servizio.contratto.descrizione}</p>
Hai modo di visualizzare e scaricare il contratto di locazione. Per
qualunque dubbio, contattaci via chat o email.
</p>
<FileSection storageId={data.doc_contratto_ref} /> <FileSection storageId={data.doc_contratto_ref} />
</div> </div>
</div> </div>
@ -52,9 +50,9 @@ const FileSection = ({ storageId }: { storageId: StorageindexId }) => {
storageId, storageId,
}); });
const { mutateAsync: getToken } = api.storage.getStorageToken.useMutation(); const { mutateAsync: getToken } = api.storage.getStorageToken.useMutation();
const { t } = useTranslation();
if (isLoading) return <LoadingPage />; if (isLoading) return <LoadingPage />;
if (!fileInfos) return <p>Errore nel caricamento del documento</p>; if (!fileInfos) return <p>{t.file_section.error}</p>;
return ( return (
<> <>
<AllegatoIframe <AllegatoIframe
@ -72,7 +70,7 @@ const FileSection = ({ storageId }: { storageId: StorageindexId }) => {
variant="link" variant="link"
className="underline underline-offset-1 after:content-['_↗']" className="underline underline-offset-1 after:content-['_↗']"
> >
Scarica una copia del documento {t.file_section.download}
</Button> </Button>
</> </>
); );

View file

@ -8,6 +8,7 @@ import { Status500 } from "~/components/status-page";
import { LoadingPage } from "~/components/loading"; import { LoadingPage } from "~/components/loading";
import { FormNewServizioAcquisto } from "~/forms/FormNewServizioAcquisto"; import { FormNewServizioAcquisto } from "~/forms/FormNewServizioAcquisto";
import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper"; import { TrpcAuthedFetchingIstance } from "~/server/utils/ssgHelper";
import { useTranslation } from "~/providers/I18nProvider";
type OnboardServizioProps = { type OnboardServizioProps = {
servizioId: ServizioServizioId; servizioId: ServizioServizioId;
@ -19,7 +20,7 @@ const OnboardServizio: NextPageWithLayout<OnboardServizioProps> = ({
const { data, isLoading } = api.servizio.getAcquistoData.useQuery({ const { data, isLoading } = api.servizio.getAcquistoData.useQuery({
servizioId: servizioId, servizioId: servizioId,
}); });
const { locale } = useTranslation();
if (isLoading) { if (isLoading) {
return <LoadingPage />; return <LoadingPage />;
} }
@ -29,8 +30,8 @@ const OnboardServizio: NextPageWithLayout<OnboardServizioProps> = ({
return ( return (
<div className="mx-auto w-full max-w-6xl grow space-y-6 p-2 sm:px-8 sm:py-6"> <div className="mx-auto w-full max-w-6xl grow space-y-6 p-2 sm:px-8 sm:py-6">
<div className="flex justify-center"> <div className="flex justify-center">
<h3 className="text-3xl font-bold text-primary"> <h3 className="text-primary text-3xl font-bold">
Dettagli del servizio {locale === "it" ? "Dettagli del servizio" : "Service Details"}
</h3> </h3>
</div> </div>

View file

@ -10,6 +10,7 @@ import { loadStripe } from "@stripe/stripe-js";
import { AcquistoProcessing } from "~/components/acquisto_processing"; import { AcquistoProcessing } from "~/components/acquisto_processing";
import { env } from "~/env.mjs"; import { env } from "~/env.mjs";
import type { OrdiniOrdineId } from "~/schemas/public/Ordini"; import type { OrdiniOrdineId } from "~/schemas/public/Ordini";
import { useTranslation } from "~/providers/I18nProvider";
type ServizioPurchaseProps = { type ServizioPurchaseProps = {
ordineId: OrdiniOrdineId; ordineId: OrdiniOrdineId;
@ -21,7 +22,7 @@ const ServicePurchasePage: NextPageWithLayout<ServizioPurchaseProps> = ({
const { data, isLoading } = api.servizio.getServizioPaymentData.useQuery({ const { data, isLoading } = api.servizio.getServizioPaymentData.useQuery({
ordineId, ordineId,
}); });
const { t } = useTranslation();
const stripePromise = loadStripe(env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY); const stripePromise = loadStripe(env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY);
if (isLoading) { if (isLoading) {
@ -33,7 +34,9 @@ const ServicePurchasePage: NextPageWithLayout<ServizioPurchaseProps> = ({
return ( return (
<div className="mx-auto w-full max-w-6xl grow space-y-4 p-2 sm:px-8 sm:py-4"> <div className="mx-auto w-full max-w-6xl grow space-y-4 p-2 sm:px-8 sm:py-4">
<div className="flex justify-between"> <div className="flex justify-between">
<h3 className="text-3xl font-bold text-primary">Pagamento</h3> <h3 className="text-primary text-3xl font-bold">
{t.acquisto.pagamento}
</h3>
</div> </div>
<AcquistoProcessing <AcquistoProcessing
paymentId={data.payment.id} paymentId={data.payment.id}

View file

@ -15,6 +15,7 @@ import { ArrowRight } from "lucide-react";
import { PrezziShow } from "~/components/prezzi"; import { PrezziShow } from "~/components/prezzi";
import Link from "next/link"; import Link from "next/link";
import { useState } from "react"; import { useState } from "react";
import { useTranslation } from "~/providers/I18nProvider";
type PreOnboardServizioProps = { type PreOnboardServizioProps = {
servizioId: ServizioServizioId; servizioId: ServizioServizioId;
@ -35,6 +36,19 @@ const PreOnboardServizio: NextPageWithLayout<PreOnboardServizioProps> = ({
if (!data) { if (!data) {
return <Status500 />; return <Status500 />;
} }
const { locale } = useTranslation();
const texts =
locale === "it"
? {
hai_domande: "Hai altre domande sul servizio?",
consulta_faq: "Consulta le domande frequenti",
procedi: "Procedi",
}
: {
hai_domande: "Do you have any other questions about the service?",
consulta_faq: "Check the FAQs",
procedi: "Proceed",
};
return ( return (
<main className="mx-auto w-full max-w-6xl px-2 py-5 md:px-8"> <main className="mx-auto w-full max-w-6xl px-2 py-5 md:px-8">
{discalimerAccepted ? ( {discalimerAccepted ? (
@ -44,11 +58,9 @@ const PreOnboardServizio: NextPageWithLayout<PreOnboardServizioProps> = ({
<ComeFunziona /> <ComeFunziona />
<PrezziShow /> <PrezziShow />
<div className="flex w-full flex-wrap items-center justify-center gap-4 py-4"> <div className="flex w-full flex-wrap items-center justify-center gap-4 py-4">
<h3 className="text-xl font-semibold"> <h3 className="text-xl font-semibold">{texts.hai_domande}</h3>
Hai altre domande sul servizio?
</h3>
<Link href="/guida#faq" target="_blank"> <Link href="/guida#faq" target="_blank">
<Button variant="outline">Consulta le domande frequenti</Button> <Button variant="outline">{texts.consulta_faq}</Button>
</Link> </Link>
</div> </div>
<div className="flex justify-center"> <div className="flex justify-center">
@ -67,7 +79,7 @@ const PreOnboardServizio: NextPageWithLayout<PreOnboardServizioProps> = ({
}} }}
size="xl" size="xl"
> >
Procedi {texts.procedi}
<ArrowRight /> <ArrowRight />
</Button> </Button>
</div> </div>

View file

@ -13,6 +13,7 @@ import { FileSection } from "~/components/servizio/conferma";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import { ArrowLeft } from "lucide-react"; import { ArrowLeft } from "lucide-react";
import { useTranslation } from "~/providers/I18nProvider";
type RiapriConfermaProps = { type RiapriConfermaProps = {
servizioId: ServizioServizioId; servizioId: ServizioServizioId;
@ -28,6 +29,7 @@ const RiapriConferma: NextPageWithLayout<RiapriConfermaProps> = ({
annuncioId, annuncioId,
}); });
const router = useRouter(); const router = useRouter();
const { t } = useTranslation();
if (isLoading) return <LoadingPage />; if (isLoading) return <LoadingPage />;
if (!data) return <Status500 />; if (!data) return <Status500 />;
@ -36,34 +38,39 @@ const RiapriConferma: NextPageWithLayout<RiapriConfermaProps> = ({
<div className="mx-2 flex flex-1 overflow-auto"> <div className="mx-2 flex flex-1 overflow-auto">
<div className="mx-auto flex grow sm:grow-0"> <div className="mx-auto flex grow sm:grow-0">
<div className="flex flex-col items-center space-y-4 py-4"> <div className="flex flex-col items-center space-y-4 py-4">
<h1 className="text-xl font-bold">Conferma Immobile</h1> <h1 className="text-xl font-bold">{t.servizio.conferma.titolo}</h1>
<p className="text-center"> <p className="text-center">{t.servizio.conferma.descrizione}</p>
Il documento sottostante riassume le condizioni della locazione tra
te e il proprietario
</p>
<FileSection storageId={data.doc_conferma_ref} /> <FileSection storageId={data.doc_conferma_ref} />
<div className="flex max-w-3xl flex-col gap-2 rounded-md bg-green-400 p-4 text-left"> <div className="flex max-w-3xl flex-col gap-2 rounded-md bg-green-400 p-4 text-left">
<p className="text-xl font-semibold"> <p className="text-xl font-semibold">{t.servizio.conferma.cta}</p>
Per confermare l&apos;immobile procedi al bonifico di caparra! <p>{t.servizio.conferma.coordinate}</p>
<p>
{t.servizio.conferma.intestazione}{" "}
{data.caparra_intestazione || ""}
</p>
<p>
{t.servizio.conferma.iban} {data.caparra_iban || ""}
</p>
<p>
{t.servizio.conferma.importo} {data.caparra_importo || ""}
</p>
<p>
{t.servizio.conferma.causale} {data.caparra_causale || ""}
</p> </p>
<p>Coordinate bancarie:</p>
<p>Intestazione: {data.caparra_intestazione || ""}</p>
<p>IBAN: {data.caparra_iban || ""}</p>
<p>Importo: {data.caparra_importo || ""}</p>
<p>Causale: {data.caparra_causale || ""}</p>
<p className="text-xl font-semibold"> <p className="text-xl font-semibold">
Mandaci la contabile del bonifico una volta effettuato! {t.servizio.conferma.coord_footer}
</p> </p>
</div> </div>
<Button <Button
onClick={() => router.back()} onClick={() => router.back()}
variant="secondary" variant="secondary"
className="mx-auto mb-4 flex items-center gap-2" className="mx-auto mb-4 flex items-center gap-2"
> >
<ArrowLeft className="size-5" /> <ArrowLeft className="size-5" />
Torna indietro {t.indietro}
</Button> </Button>
</div> </div>
</div> </div>