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

129 lines
3.6 KiB
TypeScript
Raw Normal View History

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