infoalloggi-monorepo/apps/infoalloggi/src/components/servizio/service-duration-display.tsx

129 lines
4 KiB
TypeScript
Raw Normal View History

2025-08-04 17:45:44 +02:00
import { Card, CardContent } from "~/components/ui/card";
import { CalendarDays, Hourglass, CalendarClock, Clock } from "lucide-react";
import { Progress } from "~/components/ui/progress"; // Import the Progress component
import { add, differenceInDays } from "date-fns";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "~/components/ui/accordion";
import { useMediaQuery } from "~/hooks/use-media-query";
export const ServizioDuration = ({
decorrenza,
}: {
decorrenza: Date | null;
}) => {
const isDesktop = useMediaQuery("(min-width: 768px)");
if (!decorrenza) {
return null; // If decorrenza is null, do not render the component
}
return (
<Accordion
type="single"
collapsible
defaultValue={isDesktop ? "validity" : undefined}
>
<AccordionItem value="validity">
<AccordionTrigger>
<div className="flex items-center gap-2 text-base font-medium">
<Clock className="text-primary size-6" />
Validità servizio
</div>
</AccordionTrigger>
<AccordionContent>
<ServiceDurationDisplay
decorrenza={decorrenza}
scadenza={add(decorrenza, { days: 60 })}
recessoDays={14}
/>
</AccordionContent>
</AccordionItem>
</Accordion>
);
};
interface ServiceDurationDisplayProps {
decorrenza: Date;
scadenza: Date;
recessoDays: number;
}
/**
* A sleek, light-themed component for displaying service duration,
* including start date, end date, and trial period, with a progress bar.
*/
function ServiceDurationDisplay({
decorrenza,
scadenza,
recessoDays,
}: ServiceDurationDisplayProps) {
// Calculate remaining days
const diffDays = differenceInDays(scadenza, new Date()) + 1;
const remainingDaysText = diffDays >= 0 ? `${diffDays} giorni` : "Concluso";
const progressPercentage = ((60 - diffDays) / 60) * 100; // Assuming 60 days is the full duration for 100% progress
return (
<Card className="w-full rounded-xl p-2 shadow-lg sm:py-3">
<CardContent className="flex flex-col gap-5 px-1">
<div className="flex w-full flex-col justify-between gap-4 sm:flex-row sm:items-center">
<div className="flex items-center gap-4">
<CalendarDays className="text-primary h-6 w-6" aria-hidden="true" />
<div>
<div className="text-muted-foreground text-sm">Decorrenza</div>
<div className="text-foreground text-lg font-semibold">
{decorrenza.toLocaleDateString("it-IT", {
day: "2-digit",
month: "long",
})}
</div>
</div>
</div>
<div className="flex items-center gap-4">
<CalendarClock
className="text-primary h-6 w-6"
aria-hidden="true"
/>
<div>
<div className="text-muted-foreground text-sm">Scadenza</div>
<div className="text-foreground text-lg font-semibold">
{scadenza.toLocaleDateString("it-IT", {
day: "2-digit",
month: "long",
})}
</div>
</div>
</div>
<div className="flex items-center gap-4">
<Hourglass className="text-primary h-6 w-6" aria-hidden="true" />
<div>
<div className="text-muted-foreground text-sm">
Periodo di recesso
</div>
<div className="text-foreground text-lg font-semibold">
{recessoDays} giorni
</div>
</div>
</div>
</div>
{/* Progress Bar */}
<div className="pt-2">
<Progress
value={progressPercentage}
className="h-2"
aria-label="Service duration progress"
/>
<div className="text-muted-foreground mt-1 text-right text-sm">
{remainingDaysText}
</div>
</div>
</CardContent>
</Card>
);
}