infoalloggi-monorepo/apps/infoalloggi/src/components/servizio/annuncio_card.tsx

111 lines
3.4 KiB
TypeScript
Raw Normal View History

import { ExternalLink } from "lucide-react";
2025-08-04 17:45:44 +02:00
import Link from "next/link";
2025-08-28 18:27:07 +02:00
import { ImageFlbk } from "~/components/ImageWithFallback";
import { AnnuncioActions } from "~/components/servizio/annuncio_actions";
import { Interactions } from "~/components/servizio/interactions";
import { Button } from "~/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import { handleConsegna } from "~/lib/annuncio_details";
import { getStorageUrl } from "~/lib/storage_utils";
2025-08-28 18:27:07 +02:00
import { cn, formatCurrency } from "~/lib/utils";
import { useTranslation } from "~/providers/I18nProvider";
import { useServizioAnnuncio } from "~/providers/ServizioProvider";
import type { AnnuncioRicerca } from "~/server/controllers/annunci.controller";
import { AnnuncioDettaglio, TipoBadge } from "./annuncio_dettaglio";
2025-08-04 17:45:44 +02:00
export const AnnuncioCard = ({ className }: { className?: string }) => {
2025-08-28 18:27:07 +02:00
const { data } = useServizioAnnuncio();
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
return (
<BasicAnnuncioCard
actions={<AnnuncioActions />}
2025-08-29 16:18:32 +02:00
className={className}
data={{
...data,
modificato_il: data.modificato_il ? new Date(data.modificato_il) : null,
media_updated_at: data.media_updated_at
? new Date(data.media_updated_at)
: null,
}}
2025-08-28 18:27:07 +02:00
interactions={<Interactions />}
/>
);
2025-08-04 17:45:44 +02:00
};
export const BasicAnnuncioCard = ({
2025-08-28 18:27:07 +02:00
actions,
interactions,
className,
data,
2025-08-04 17:45:44 +02:00
}: {
2025-08-28 18:27:07 +02:00
actions?: React.ReactNode;
interactions?: React.ReactNode;
className?: string;
data: AnnuncioRicerca;
2025-08-04 17:45:44 +02:00
}) => {
2025-08-28 18:27:07 +02:00
const { t } = useTranslation();
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
return (
<Card className={cn("w-full border-white py-5", className)}>
<CardHeader className="flex flex-row flex-wrap items-center justify-between space-y-0 pb-0">
<CardTitle className="text-2xl">Codice: {data.codice}</CardTitle>
{actions}
</CardHeader>
<CardContent className="px-4">
<div className="flex w-full flex-col gap-4 md:flex-row md:gap-10">
<ImageFlbk
2025-08-29 16:18:32 +02:00
alt={data.codice}
className="h-auto max-h-72 w-full rounded-md bg-[#e6e9ec] object-contain sm:max-w-xs"
2025-08-29 16:18:32 +02:00
height={1080}
priority
2025-08-28 18:27:07 +02:00
src={
(data?.images[0] &&
getStorageUrl({
storageId: data.images[0].img,
params: {
cacheKey: data.media_updated_at?.toISOString(),
media: "image",
},
})) ||
2025-08-28 18:27:07 +02:00
"/fallback-image.png"
}
width={1920}
/>
<div className="flex w-full flex-col gap-5">
{interactions}
2025-08-04 17:45:44 +02:00
2025-08-28 18:27:07 +02:00
<div className="flex flex-wrap items-center gap-3">
<TipoBadge tipo={data.tipo} />
<span>
{handleConsegna({
2025-08-29 16:18:32 +02:00
aggiornamento: t.card.in_aggiornamento,
2025-08-28 18:27:07 +02:00
consegna: data.consegna,
consegna_da: t.card.consegna_da,
mesi: t.preferenze.mesi,
subito: t.card.consegna_subito,
})}
</span>
<span>{formatCurrency(data.prezzo / 1e2)}</span>
</div>
<div className="flex w-full flex-wrap items-center gap-5">
<span className="text-wrap">{data.titolo_it || data.codice}</span>
<div className="flex flex-wrap items-center gap-2">
<AnnuncioDettaglio data={data} />
{data.stato !== "Sospeso" && data.web && (
<Link
aria-label="Pagina Annuncio"
2025-08-29 16:18:32 +02:00
href={`/annuncio/${data.codice}`}
2025-08-28 18:27:07 +02:00
>
<Button variant="outline">
2025-08-28 18:27:07 +02:00
<ExternalLink className="size-6" />
</Button>
</Link>
)}
</div>
</div>
</div>
</div>
</CardContent>
</Card>
);
2025-08-04 17:45:44 +02:00
};