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

128 lines
3.6 KiB
TypeScript

import { add, differenceInDays } from "date-fns";
import { CalendarClock, CalendarDays, Clock, Hourglass } from "lucide-react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "~/components/ui/accordion";
import { Card, CardContent } from "~/components/ui/card";
import { Progress } from "~/components/ui/progress"; // Import the Progress component
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
collapsible
defaultValue={isDesktop ? "validity" : undefined}
type="single"
>
<AccordionItem value="validity">
<AccordionTrigger>
<div className="flex items-center gap-2 font-medium text-base">
<Clock className="size-6 text-primary" />
Validità servizio
</div>
</AccordionTrigger>
<AccordionContent>
<ServiceDurationDisplay
decorrenza={decorrenza}
recessoDays={14}
scadenza={add(decorrenza, { days: 60 })}
/>
</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 aria-hidden="true" className="h-6 w-6 text-primary" />
<div>
<div className="text-muted-foreground text-sm">Decorrenza</div>
<div className="font-semibold text-foreground text-lg">
{decorrenza.toLocaleDateString("it-IT", {
day: "2-digit",
month: "long",
})}
</div>
</div>
</div>
<div className="flex items-center gap-4">
<CalendarClock
aria-hidden="true"
className="h-6 w-6 text-primary"
/>
<div>
<div className="text-muted-foreground text-sm">Scadenza</div>
<div className="font-semibold text-foreground text-lg">
{scadenza.toLocaleDateString("it-IT", {
day: "2-digit",
month: "long",
})}
</div>
</div>
</div>
<div className="flex items-center gap-4">
<Hourglass aria-hidden="true" className="h-6 w-6 text-primary" />
<div>
<div className="text-muted-foreground text-sm">
Periodo di recesso
</div>
<div className="font-semibold text-foreground text-lg">
{recessoDays} giorni
</div>
</div>
</div>
</div>
{/* Progress Bar */}
<div className="pt-2">
<Progress
aria-label="Service duration progress"
className="h-2"
value={progressPercentage}
/>
<div className="mt-1 text-right text-muted-foreground text-sm">
{remainingDaysText}
</div>
</div>
</CardContent>
</Card>
);
}