feat: enhance contact modal and guide components with translation support; update pricing display and improve accessibility
This commit is contained in:
parent
47be8bd54a
commit
cb97919157
7 changed files with 188 additions and 69 deletions
|
|
@ -11,22 +11,27 @@ import {
|
|||
import { Button } from "~/components/ui/button";
|
||||
import { FormContattoAnnucio } from "~/forms/FormContattoAnnuncio";
|
||||
import { useAnnuncio } from "~/providers/AnnuncioProvider";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
|
||||
export const ContattoAnnuncio = () => {
|
||||
const { codice } = useAnnuncio();
|
||||
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<Credenza>
|
||||
<CredenzaTrigger asChild>
|
||||
<Button className="w-full" variant="destructive">
|
||||
<MessageCirclePlus /> Contattaci
|
||||
<Button
|
||||
className="w-full text-lg md:text-base lg:text-lg"
|
||||
size="xl"
|
||||
variant="success"
|
||||
>
|
||||
<MessageCirclePlus /> {t.contatto.annuncio_cta.button}
|
||||
</Button>
|
||||
</CredenzaTrigger>
|
||||
<CredenzaContent className="max-h-[90vh]">
|
||||
<CredenzaHeader>
|
||||
<CredenzaTitle>Contattaci per avere informazioni</CredenzaTitle>
|
||||
<CredenzaTitle>{t.contatto.annuncio_cta.title}</CredenzaTitle>
|
||||
<CredenzaDescription>
|
||||
Ti contatteremo il prima possibile per darti più informazioni
|
||||
{t.contatto.annuncio_cta.description}
|
||||
</CredenzaDescription>
|
||||
</CredenzaHeader>
|
||||
<CredenzaBody className="max-h-[80vh] overflow-auto pb-5">
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { HelpCircle } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { useTranslation } from "~/providers/I18nProvider";
|
||||
import {
|
||||
ExpandableScreen,
|
||||
ExpandableScreenContent,
|
||||
|
|
@ -8,39 +9,8 @@ import {
|
|||
import { Button } from "./ui/button";
|
||||
import { Separator } from "./ui/separator";
|
||||
|
||||
const texts: {
|
||||
title: string;
|
||||
parts: (string | { href: string; text: string })[];
|
||||
}[] = [
|
||||
{
|
||||
title: "Costo del servizio",
|
||||
parts: [
|
||||
"Il costo del servizio è personalizzato in base alla tipologia e parametri della tua ricerca.",
|
||||
"Per contattare i proprietari ti chiederemo un acconto di 35€ sul totale.",
|
||||
"Potrai contattare tutti i proprietari degli immobili che desideri durante la durata del servizio.",
|
||||
{ href: "/prezzi", text: "Scopri i prezzi" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Come procedere",
|
||||
parts: [
|
||||
"Contattaci per un immobile, prepareremo per te degli annunci compatibili alle tue esigenze e ti invieremo un invito via email per accedere alla piattaforma.",
|
||||
"Una volta effettuato l'accesso, potrai acquistare il servizio e visualizzare i contatti dei proprietari degli immobili.",
|
||||
{
|
||||
href: "/annunci",
|
||||
text: "Vai agli annunci",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Nulla di fatto",
|
||||
parts: [
|
||||
"Se non trovi un immobile che soddisfi le tue esigenze, avrai 14 giorni di tempo per interrompere il servizio senza necessità di ulteriori pagamenti.",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export const ComeFunziona = () => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<ExpandableScreen
|
||||
contentRadius="14px"
|
||||
|
|
@ -48,15 +18,19 @@ export const ComeFunziona = () => {
|
|||
triggerRadius="100px"
|
||||
>
|
||||
<ExpandableScreenTrigger className="w-full">
|
||||
<Button className="w-full">
|
||||
<Button
|
||||
className="w-full text-lg md:text-base lg:text-lg"
|
||||
size="xl"
|
||||
variant="info"
|
||||
>
|
||||
<HelpCircle />
|
||||
<span>Scopri come funziona</span>
|
||||
<span>{t.come_funziona_guida.title}</span>
|
||||
</Button>
|
||||
</ExpandableScreenTrigger>
|
||||
|
||||
<ExpandableScreenContent className="bg-primary text-primary-foreground">
|
||||
<ExpandableScreenContent className="bg-info text-primary-foreground">
|
||||
<div className="h-full space-y-6 p-6 py-12 sm:space-y-16 sm:px-10">
|
||||
{texts.map((text, index) => (
|
||||
{t.come_funziona_guida.features.map((text, index) => (
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: <ok>
|
||||
<div className="space-y-6" key={index}>
|
||||
<div className="space-y-2">
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ export const PricingComponent = ({
|
|||
data-role="wrapper"
|
||||
>
|
||||
<div className="flex w-2/5 xs:w-1/3 flex-col items-center gap-2">
|
||||
<h2 className="font-semibold text-2xl" data-role="title">
|
||||
<h2 className="truncate font-semibold text-2xl" data-role="title">
|
||||
{t.acconto}
|
||||
</h2>
|
||||
<p
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ export const en: LangDict = {
|
|||
},
|
||||
accedi_per_procedere: "Log in to proceed",
|
||||
accetta: "Accept",
|
||||
acconto: "Down payment",
|
||||
acconto: "Dwn. Paym.",
|
||||
account: {
|
||||
azieda_titolo: "Company Data",
|
||||
azienda_o_pf: "Personal or Company?",
|
||||
|
|
@ -295,6 +295,20 @@ export const en: LangDict = {
|
|||
tutto: "All",
|
||||
},
|
||||
titolo: "Search Properties",
|
||||
find_similar: "Find similar ads",
|
||||
codice: "Code",
|
||||
euro_mese: "€/month",
|
||||
prezzo_giorno: "Price per day",
|
||||
euro_giorno: "€/day",
|
||||
fornitura: "Supply",
|
||||
bagni: "bathrooms",
|
||||
posti_auto: "parking sp.",
|
||||
dati_immobile: "Property data",
|
||||
p_terra: "ground floor",
|
||||
p_rialzato: "raised floor",
|
||||
piano: "floor",
|
||||
in_aggiornamento: "Ad updating",
|
||||
disponibile: "Availability",
|
||||
},
|
||||
annuncio_load_fail: {
|
||||
CTA: "Back",
|
||||
|
|
@ -453,7 +467,44 @@ export const en: LangDict = {
|
|||
titolo: "Contact Form",
|
||||
},
|
||||
contatti: "Contacts",
|
||||
come_funziona_guida: {
|
||||
title: "How does Infoalloggi work?",
|
||||
features: [
|
||||
{
|
||||
title: "Service cost",
|
||||
parts: [
|
||||
"The cost of the service is customized based on the type and parameters of your search.",
|
||||
"To contact the owners, we will ask you for a deposit of €35 on the total.",
|
||||
"You can contact all the owners of the properties you want during the duration of the service.",
|
||||
{ href: "/prezzi", text: "Discover the prices" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "How to proceed",
|
||||
parts: [
|
||||
"Contact us for a property, we will prepare compatible listings for you based on your needs and send you an email invitation to access the platform.",
|
||||
"Once logged in, you can purchase the service and view the contacts of the property owners.",
|
||||
{
|
||||
href: "/annunci",
|
||||
text: "Go to listings",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "No results",
|
||||
parts: [
|
||||
"If you do not find a property that meets your needs, you will have 14 days to cancel the service without any further payments.",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
contatto: {
|
||||
annuncio_cta: {
|
||||
button: "Are you interested? Contact us!",
|
||||
title: "Contact us for more information",
|
||||
description:
|
||||
"We will contact you as soon as possible to provide more information about the property.",
|
||||
},
|
||||
apri_nav: "Open in navigator",
|
||||
button: "Contact details",
|
||||
contatta: "Contact the owners at appropriate times.",
|
||||
|
|
|
|||
|
|
@ -301,6 +301,20 @@ export const it: LangDict = {
|
|||
tutto: "Tutto",
|
||||
},
|
||||
titolo: "Ricerca Immobili",
|
||||
find_similar: "Cerca annunci simili",
|
||||
codice: "Codice",
|
||||
euro_mese: "€/mese",
|
||||
prezzo_giorno: "Prezzo al giorno",
|
||||
euro_giorno: "€/gg",
|
||||
fornitura: "Fornitura",
|
||||
bagni: "bagni",
|
||||
posti_auto: "posti auto",
|
||||
dati_immobile: "Dati immobile",
|
||||
p_terra: "piano terra",
|
||||
p_rialzato: "piano rialz.",
|
||||
piano: "piano",
|
||||
in_aggiornamento: "Annuncio in aggiornamento",
|
||||
disponibile: "Disponibilità",
|
||||
},
|
||||
annuncio_load_fail: {
|
||||
CTA: "Indietro",
|
||||
|
|
@ -458,7 +472,44 @@ export const it: LangDict = {
|
|||
titolo: "Form di contatto",
|
||||
},
|
||||
contatti: "Contatti",
|
||||
come_funziona_guida: {
|
||||
title: "Come funziona Infoalloggi?",
|
||||
features: [
|
||||
{
|
||||
title: "Costo del servizio",
|
||||
parts: [
|
||||
"Il costo del servizio è personalizzato in base alla tipologia e parametri della tua ricerca.",
|
||||
"Per contattare i proprietari ti chiederemo un acconto di 35€ sul totale.",
|
||||
"Potrai contattare tutti i proprietari degli immobili che desideri durante la durata del servizio.",
|
||||
{ href: "/prezzi", text: "Scopri i prezzi" },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Come procedere",
|
||||
parts: [
|
||||
"Contattaci per un immobile, prepareremo per te degli annunci compatibili alle tue esigenze e ti invieremo un invito via email per accedere alla piattaforma.",
|
||||
"Una volta effettuato l'accesso, potrai acquistare il servizio e visualizzare i contatti dei proprietari degli immobili.",
|
||||
{
|
||||
href: "/annunci",
|
||||
text: "Vai agli annunci",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Nulla di fatto",
|
||||
parts: [
|
||||
"Se non trovi un immobile che soddisfi le tue esigenze, avrai 14 giorni di tempo per interrompere il servizio senza necessità di ulteriori pagamenti.",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
contatto: {
|
||||
annuncio_cta: {
|
||||
button: "Sei Interessato? Contattaci!",
|
||||
title: "Contattaci per avere informazioni",
|
||||
description:
|
||||
"Ti contatteremo il prima possibile per darti più informazioni sull'immobile.",
|
||||
},
|
||||
apri_nav: "Apri nel navigatore",
|
||||
button: "Dati di contatto",
|
||||
contatta: "Contattare i proprietari in orari consoni.",
|
||||
|
|
|
|||
|
|
@ -252,6 +252,20 @@ export type LangDict = {
|
|||
budgetMin: string;
|
||||
budgetMax: string;
|
||||
accordion_minifaq: Faq[];
|
||||
find_similar: string;
|
||||
codice: string;
|
||||
euro_mese: string;
|
||||
prezzo_giorno: string;
|
||||
euro_giorno: string;
|
||||
fornitura: string;
|
||||
bagni: string;
|
||||
posti_auto: string;
|
||||
dati_immobile: string;
|
||||
p_terra: string;
|
||||
p_rialzato: string;
|
||||
piano: string;
|
||||
in_aggiornamento: string;
|
||||
disponibile: string;
|
||||
};
|
||||
faq: {
|
||||
titolo: string;
|
||||
|
|
@ -640,7 +654,20 @@ export type LangDict = {
|
|||
già_verificata: string;
|
||||
inviata: string;
|
||||
};
|
||||
come_funziona_guida: {
|
||||
title: string;
|
||||
features: {
|
||||
title: string;
|
||||
parts: (string | { href: string; text: string })[];
|
||||
}[];
|
||||
};
|
||||
contatto: {
|
||||
annuncio_cta: {
|
||||
button: string;
|
||||
title: string;
|
||||
description: string;
|
||||
};
|
||||
|
||||
title: string;
|
||||
button: string;
|
||||
descrizione: string;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import {
|
||||
Armchair,
|
||||
ArrowUp01,
|
||||
BadgeEuro,
|
||||
Bath,
|
||||
BedDouble,
|
||||
Building2,
|
||||
Car,
|
||||
Clock,
|
||||
Copy,
|
||||
|
|
@ -352,7 +352,7 @@ const Pricing = ({
|
|||
</CollapsibleTrigger>
|
||||
<CollapsibleContent className="mt-2">
|
||||
<PricingComponent
|
||||
className={cn(style)}
|
||||
className={cn(style, "max-w-full")}
|
||||
cta={cta}
|
||||
opzioni={opzioni}
|
||||
pricingData={pricing}
|
||||
|
|
@ -441,7 +441,7 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
|||
<Card className="relative w-full bg-secondary text-secondary-foreground outline outline-secondary-foreground">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-center font-bold text-3xl md:pl-8 lg:pl-0">
|
||||
Codice {data.codice}
|
||||
{t.annunci.codice} {data.codice}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent className="flex flex-col gap-4 p-4 py-0">
|
||||
|
|
@ -449,7 +449,7 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
|||
<div className="relative">
|
||||
<div className="rounded-md bg-primary-foreground p-2 text-center text-primary">
|
||||
{data.prezzo && (data.prezzo / 1e2).toFixed(2).replace(".", ",")}{" "}
|
||||
€/mese
|
||||
{t.annunci.euro_mese}
|
||||
</div>
|
||||
{data.prezzo && (
|
||||
<InformationBubble
|
||||
|
|
@ -458,10 +458,11 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
|||
>
|
||||
<div className="text-fxd-foreground">
|
||||
<span className="font-semibold text-sm">
|
||||
Prezzo al giorno
|
||||
{t.annunci.prezzo_giorno}
|
||||
</span>
|
||||
<div className="text-sm">
|
||||
{(data.prezzo / 1e2 / 30).toFixed(2).replace(".", ",")} €/gg
|
||||
{(data.prezzo / 1e2 / 30).toFixed(2).replace(".", ",")}{" "}
|
||||
{t.annunci.euro_giorno}
|
||||
</div>
|
||||
</div>
|
||||
</InformationBubble>
|
||||
|
|
@ -487,7 +488,7 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
|||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<h3 className="px-2">Fornitura:</h3>
|
||||
<h3 className="px-2">{t.annunci.fornitura}:</h3>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
||||
<BedDouble />
|
||||
|
|
@ -501,7 +502,9 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
|||
</div>
|
||||
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
||||
<Bath />
|
||||
<span>{data.numero_bagni || 0} bagni</span>
|
||||
<span>
|
||||
{data.numero_bagni || 0} {t.annunci.bagni}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
||||
<Armchair />
|
||||
|
|
@ -509,12 +512,14 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
|||
</div>
|
||||
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
||||
<Car />
|
||||
<span>{data.numero_postiauto || 0} posti auto</span>
|
||||
<span>
|
||||
{data.numero_postiauto || 0} {t.annunci.posti_auto}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col gap-2">
|
||||
<h3 className="px-2">Dati immobile:</h3>
|
||||
<h3 className="px-2">{t.annunci.dati_immobile}:</h3>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
||||
<Ruler />
|
||||
|
|
@ -525,15 +530,20 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
|||
</div>
|
||||
|
||||
<div className="flex justify-center gap-2 rounded-md bg-primary-foreground p-2 text-primary">
|
||||
<Building2 />
|
||||
{data.piano !== null && data.piano !== "" && (
|
||||
<>
|
||||
<ArrowUp01 />
|
||||
<span>
|
||||
{(() => {
|
||||
if (data.piano === "0") return "piano terra";
|
||||
if (data.piano === "0.5") return "piano rialz.";
|
||||
if (data.piano) return `${data.piano}° piano`;
|
||||
return "";
|
||||
if (data.piano === "0") return t.annunci.p_terra;
|
||||
if (data.piano === "0.5") return t.annunci.p_rialzato;
|
||||
if (data.piano)
|
||||
return `${data.piano}° ${t.annunci.piano}`;
|
||||
return "--";
|
||||
})()}
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -542,12 +552,12 @@ const CardInfos = ({ data }: { data: Annunci }) => {
|
|||
{data.stato === "Trattativa" ? (
|
||||
<div className="flex items-center justify-center gap-1 rounded-md py-1.5 text-trattativa outline-2 outline-trattativa dark:bg-secondary-foreground">
|
||||
<TrafficCone className="inline-block size-5" />
|
||||
<span>Annuncio in aggiornamento</span>
|
||||
<span>{t.annunci.in_aggiornamento}</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center justify-center gap-1 rounded-md py-1.5 outline-2 outline-secondary-foreground">
|
||||
<Clock className="inline-block size-5" />
|
||||
Disponibilità:{" "}
|
||||
{t.annunci.disponibile}:{" "}
|
||||
<span className="text-red-500">
|
||||
{handleConsegna({
|
||||
aggiornamento: t.card.in_aggiornamento,
|
||||
|
|
@ -656,6 +666,7 @@ const AnnuncioFooter = ({
|
|||
external_videos: string[];
|
||||
updated_at: Date | null;
|
||||
}) => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
<p className="px-2 font-semibold text-lg">Video:</p>
|
||||
|
|
@ -698,15 +709,15 @@ const AnnuncioFooter = ({
|
|||
href={{
|
||||
pathname: "/annunci",
|
||||
query: {
|
||||
comune: comune,
|
||||
consegna: consegna,
|
||||
tipo: tipo,
|
||||
c: comune,
|
||||
f: consegna,
|
||||
t: tipo,
|
||||
},
|
||||
}}
|
||||
target="_blank"
|
||||
>
|
||||
<Button className="my-10 w-full text-xl" variant="info">
|
||||
Cerca annunci simili <ExternalLink className="size-6" />
|
||||
<Button className="my-10 w-full text-xl" variant="secondary">
|
||||
{t.annunci.find_similar} <ExternalLink className="size-6" />
|
||||
</Button>
|
||||
</Link>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue