refactor: enhance styling and layout of AnnuncioCard and AnnuncioDettaglio components
This commit is contained in:
parent
831ae0edef
commit
496a947f97
6 changed files with 116 additions and 139 deletions
|
|
@ -1,9 +1,6 @@
|
||||||
import { ExternalLink } from "lucide-react";
|
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Link from "next/link";
|
|
||||||
import { AnnuncioActions } from "~/components/servizio/annuncio_actions";
|
import { AnnuncioActions } from "~/components/servizio/annuncio_actions";
|
||||||
import { Interactions } from "~/components/servizio/interactions";
|
import { Interactions } from "~/components/servizio/interactions";
|
||||||
import { Button } from "~/components/ui/button";
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
|
||||||
import { handleConsegna } from "~/lib/annuncio_details";
|
import { handleConsegna } from "~/lib/annuncio_details";
|
||||||
import { getStorageUrl } from "~/lib/storage_utils";
|
import { getStorageUrl } from "~/lib/storage_utils";
|
||||||
|
|
@ -45,16 +42,18 @@ export const BasicAnnuncioCard = ({
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className={cn("w-full border-white py-5", className)}>
|
<Card className={cn("w-full border-white py-3", className)}>
|
||||||
<CardHeader className="flex flex-row flex-wrap items-center justify-between space-y-0 pb-0">
|
<CardHeader className="flex flex-row flex-wrap items-center justify-between space-y-0 px-3 pb-0">
|
||||||
<CardTitle className="text-2xl">Codice: {data.codice}</CardTitle>
|
<CardTitle className="text-2xl">Annuncio {data.codice}</CardTitle>
|
||||||
{actions}
|
{actions}
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent className="px-4">
|
<CardContent className="px-3">
|
||||||
<div className="flex w-full flex-col gap-4 md:flex-row md:gap-10">
|
<div className="flex w-full flex-col gap-4 md:gap-10">
|
||||||
|
<div className="grid grid-cols-[6rem_auto] gap-2 gap-x-4 md:grid-cols-[12rem_auto] md:gap-x-10">
|
||||||
|
<div className="row-span-3">
|
||||||
<Image
|
<Image
|
||||||
alt={data.codice}
|
alt={data.codice}
|
||||||
className="h-auto max-h-72 w-full rounded-md bg-[#e6e9ec] object-contain sm:max-w-xs"
|
className="size-24 rounded-md bg-[#e6e9ec] object-cover md:size-48"
|
||||||
height={1080}
|
height={1080}
|
||||||
priority
|
priority
|
||||||
src={
|
src={
|
||||||
|
|
@ -70,10 +69,13 @@ export const BasicAnnuncioCard = ({
|
||||||
}
|
}
|
||||||
width={1920}
|
width={1920}
|
||||||
/>
|
/>
|
||||||
<div className="flex w-full flex-col gap-5">
|
</div>
|
||||||
{interactions}
|
|
||||||
|
|
||||||
<div className="flex flex-wrap items-center gap-3">
|
<div className="flex w-full max-w-xl flex-wrap gap-5 md:col-span-1">
|
||||||
|
<span className="text-wrap">{data.titolo_it}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="col-span-2 flex w-full max-w-xl flex-wrap items-center justify-between gap-3 md:col-span-1">
|
||||||
<TipoBadge tipo={data.tipo} />
|
<TipoBadge tipo={data.tipo} />
|
||||||
<span>
|
<span>
|
||||||
{handleConsegna({
|
{handleConsegna({
|
||||||
|
|
@ -84,25 +86,15 @@ export const BasicAnnuncioCard = ({
|
||||||
subito: t.card.consegna_subito,
|
subito: t.card.consegna_subito,
|
||||||
})}
|
})}
|
||||||
</span>
|
</span>
|
||||||
<span>{formatCurrency(data.prezzo / 1e2)}</span>
|
<span className="font-semibold">
|
||||||
|
{formatCurrency(data.prezzo / 1e2)}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex w-full flex-wrap items-center gap-5">
|
<div className="col-span-2 w-full max-w-xl md:col-span-1">
|
||||||
<span className="text-wrap">{data.titolo_it || data.codice}</span>
|
|
||||||
<div className="flex flex-wrap items-center gap-2">
|
|
||||||
<AnnuncioDettaglio data={data} />
|
<AnnuncioDettaglio data={data} />
|
||||||
{data.stato !== "Sospeso" && data.web && (
|
|
||||||
<Link
|
|
||||||
aria-label="Pagina Annuncio"
|
|
||||||
href={`/annuncio/${data.codice}`}
|
|
||||||
>
|
|
||||||
<Button variant="outline">
|
|
||||||
<ExternalLink className="size-6" />
|
|
||||||
</Button>
|
|
||||||
</Link>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex w-full flex-col gap-5">{interactions}</div>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { ExternalLink, UnfoldVertical } from "lucide-react";
|
import { Expand, ExternalLink } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { replaceWithBr } from "~/lib/newlineToBr";
|
import { replaceWithBr } from "~/lib/newlineToBr";
|
||||||
import { cn, formatCurrency } from "~/lib/utils";
|
import { cn, formatCurrency } from "~/lib/utils";
|
||||||
|
|
@ -6,16 +6,17 @@ import { useTranslation } from "~/providers/I18nProvider";
|
||||||
import type { Annunci } from "~/schemas/public/Annunci";
|
import type { Annunci } from "~/schemas/public/Annunci";
|
||||||
import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller";
|
import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller";
|
||||||
import { CarouselAnnuncio } from "../annuncio_card";
|
import { CarouselAnnuncio } from "../annuncio_card";
|
||||||
|
import {
|
||||||
|
Credenza,
|
||||||
|
CredenzaBody,
|
||||||
|
CredenzaContent,
|
||||||
|
CredenzaDescription,
|
||||||
|
CredenzaHeader,
|
||||||
|
CredenzaTitle,
|
||||||
|
CredenzaTrigger,
|
||||||
|
} from "../custom_ui/credenza";
|
||||||
import { Badge } from "../ui/badge";
|
import { Badge } from "../ui/badge";
|
||||||
import { Button } from "../ui/button";
|
import { Button } from "../ui/button";
|
||||||
import {
|
|
||||||
Dialog,
|
|
||||||
DialogContent,
|
|
||||||
DialogDescription,
|
|
||||||
DialogHeader,
|
|
||||||
DialogTitle,
|
|
||||||
DialogTrigger,
|
|
||||||
} from "../ui/dialog";
|
|
||||||
|
|
||||||
export const TipoBadge = ({ tipo }: { tipo: Annunci["tipo"] }) => {
|
export const TipoBadge = ({ tipo }: { tipo: Annunci["tipo"] }) => {
|
||||||
return (
|
return (
|
||||||
|
|
@ -37,25 +38,32 @@ export const AnnuncioDettaglio = ({ data }: { data: AnnuncioRicerca }) => {
|
||||||
const { locale, t } = useTranslation();
|
const { locale, t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog>
|
<Credenza>
|
||||||
<DialogTrigger asChild>
|
<CredenzaTrigger asChild>
|
||||||
<Button aria-label="Dettagli Annuncio" variant="outline">
|
<Button
|
||||||
<UnfoldVertical className="size-6" /> Dettagli annuncio
|
aria-label="Dettagli Annuncio"
|
||||||
|
className="w-full"
|
||||||
|
size="sm"
|
||||||
|
variant="outline"
|
||||||
|
>
|
||||||
|
<Expand /> Dettaglio
|
||||||
</Button>
|
</Button>
|
||||||
</DialogTrigger>
|
</CredenzaTrigger>
|
||||||
<DialogContent className="max-h-[70vh] max-w-xl overflow-y-auto sm:max-w-6xl">
|
<CredenzaContent className="max-w-xl sm:max-w-6xl md:max-h-[90vh] md:overflow-y-auto">
|
||||||
<DialogHeader className="flex-row items-center gap-4">
|
<CredenzaHeader className="flex-row items-center justify-between gap-4 md:justify-start">
|
||||||
<DialogTitle className="text-xl">Annuncio {data.codice}</DialogTitle>
|
<CredenzaTitle className="text-xl">
|
||||||
|
Annuncio {data.codice}
|
||||||
|
</CredenzaTitle>
|
||||||
<Link href={`/annuncio/${data.codice}`} target="_blank">
|
<Link href={`/annuncio/${data.codice}`} target="_blank">
|
||||||
<Button size="sm" variant="info">
|
<Button size="sm" variant="info">
|
||||||
<span>Vai alla pagina completa</span>{" "}
|
<span>Pagina completa</span> <ExternalLink />
|
||||||
<ExternalLink className="size-4" />
|
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
<DialogDescription className="sr-only">
|
<CredenzaDescription className="sr-only">
|
||||||
Annuncio {data.codice}
|
Dettaglio
|
||||||
</DialogDescription>
|
</CredenzaDescription>
|
||||||
</DialogHeader>
|
</CredenzaHeader>
|
||||||
|
<CredenzaBody className="h-full overflow-auto pb-5">
|
||||||
<div className="flex flex-col gap-2 px-2">
|
<div className="flex flex-col gap-2 px-2">
|
||||||
<div className="w-full contain-inline-size">
|
<div className="w-full contain-inline-size">
|
||||||
<CarouselAnnuncio
|
<CarouselAnnuncio
|
||||||
|
|
@ -65,7 +73,7 @@ export const AnnuncioDettaglio = ({ data }: { data: AnnuncioRicerca }) => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div className="space-y-3">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<TipoBadge tipo={data.tipo} />
|
<TipoBadge tipo={data.tipo} />
|
||||||
{data.stato === "Trattativa" && (
|
{data.stato === "Trattativa" && (
|
||||||
|
|
@ -75,12 +83,14 @@ export const AnnuncioDettaglio = ({ data }: { data: AnnuncioRicerca }) => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-1 space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="flex flex-row justify-around">
|
<div className="flex flex-row justify-around">
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<dt className="sr-only">{t.card.codice}</dt>
|
<dt className="sr-only">{t.card.codice}</dt>
|
||||||
|
|
||||||
<dd className="font-semibold text-lg">Cod: {data.codice}</dd>
|
<dd className="font-semibold text-lg">
|
||||||
|
Cod: {data.codice}
|
||||||
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-center">
|
<div className="text-center">
|
||||||
<dt className="sr-only">{t.card.prezzo}</dt>
|
<dt className="sr-only">{t.card.prezzo}</dt>
|
||||||
|
|
@ -91,7 +101,7 @@ export const AnnuncioDettaglio = ({ data }: { data: AnnuncioRicerca }) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mb-3">
|
<div className="">
|
||||||
<dt className="sr-only">{t.card.titolo}</dt>
|
<dt className="sr-only">{t.card.titolo}</dt>
|
||||||
|
|
||||||
<dd className="font-semibold text-base md:text-lg">
|
<dd className="font-semibold text-base md:text-lg">
|
||||||
|
|
@ -99,8 +109,7 @@ export const AnnuncioDettaglio = ({ data }: { data: AnnuncioRicerca }) => {
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mb-3">
|
<div
|
||||||
<dd
|
|
||||||
className="text-base"
|
className="text-base"
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: replaceWithBr(
|
__html: replaceWithBr(
|
||||||
|
|
@ -111,8 +120,8 @@ export const AnnuncioDettaglio = ({ data }: { data: AnnuncioRicerca }) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</CredenzaBody>
|
||||||
</DialogContent>
|
</CredenzaContent>
|
||||||
</Dialog>
|
</Credenza>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ export const Interactions = () => {
|
||||||
const { data } = useServizioAnnuncio();
|
const { data } = useServizioAnnuncio();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex w-full flex-col gap-3">
|
||||||
<ContattiProprietarioModal />
|
<ContattiProprietarioModal />
|
||||||
|
|
||||||
<SezioneConferma />
|
<SezioneConferma />
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ const ServizioCard = ({
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
className={cn(
|
className={cn(
|
||||||
"gap-2 rounded-none rounded-b-md border-primary border-t-0",
|
"gap-2 rounded-none rounded-b-md border-primary border-t-0 pb-0",
|
||||||
cardClassName,
|
cardClassName,
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
@ -218,32 +218,6 @@ export const ServizioContent = () => {
|
||||||
<ServizioCard
|
<ServizioCard
|
||||||
content={
|
content={
|
||||||
<>
|
<>
|
||||||
{/* <div className="flex w-full flex-col gap-8 sm:flex-row sm:items-start">
|
|
||||||
<div className="flex flex-2 flex-col gap-2 sm:max-w-1/2">
|
|
||||||
<div className="flex items-center justify-between">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<UserCircle className="size-6 text-primary" />
|
|
||||||
<span className="font-medium">Contatti sbloccati</span>
|
|
||||||
</div>
|
|
||||||
<span className="text-sm">
|
|
||||||
{openContattiAnnunci.length} / 10
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<Progress
|
|
||||||
className="h-2"
|
|
||||||
value={openContattiAnnunci.length * 10}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col flex-wrap gap-2 sm:flex-row sm:items-center">
|
|
||||||
<div className="flex items-center gap-2">
|
|
||||||
<CalendarClock className="size-6 text-primary" />
|
|
||||||
<span className="font-medium">Durata servizio:</span>
|
|
||||||
</div>
|
|
||||||
<span>
|
|
||||||
{`${new Date(servizio.decorrenza).toLocaleDateString("it-IT")} - ${new Date(add(servizio.decorrenza, { days: 60 })).toLocaleDateString("it-IT")}`}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div> */}
|
|
||||||
{annuncioConfermato.length > 0 && (
|
{annuncioConfermato.length > 0 && (
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ export const ContattiProprietarioModal = () => {
|
||||||
{isUnlocked ? (
|
{isUnlocked ? (
|
||||||
<Button
|
<Button
|
||||||
aria-label="Vedi contatti proprietario"
|
aria-label="Vedi contatti proprietario"
|
||||||
className="w-fit"
|
className="w-full md:w-fit"
|
||||||
variant="success"
|
variant="success"
|
||||||
>
|
>
|
||||||
<CircleUser className="size-7" />
|
<CircleUser className="size-7" />
|
||||||
|
|
@ -58,7 +58,7 @@ export const ContattiProprietarioModal = () => {
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
aria-label="Contatta proprietario"
|
aria-label="Contatta proprietario"
|
||||||
className="w-fit"
|
className="w-full md:w-fit"
|
||||||
variant="warning"
|
variant="warning"
|
||||||
>
|
>
|
||||||
<CircleUser className="size-7" />
|
<CircleUser className="size-7" />
|
||||||
|
|
|
||||||
|
|
@ -765,7 +765,9 @@ export const PasswordSVG = (props: SVGProps<SVGSVGElement>) => (
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
/*
|
||||||
|
from: https://www.svgrepo.com/svg/477007/alarm-clock
|
||||||
|
*/
|
||||||
export const AlarmClockSVG = (props: SVGProps<SVGSVGElement>) => (
|
export const AlarmClockSVG = (props: SVGProps<SVGSVGElement>) => (
|
||||||
<svg
|
<svg
|
||||||
className="icon"
|
className="icon"
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue