69 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			69 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { DateTime } from "luxon";
 | |
| import { CalendarIcon } from "lucide-react";
 | |
| import { fr } from "date-fns/locale";
 | |
| import { Calendar } from "~/components/ui/calendar";
 | |
| import {
 | |
|   Popover,
 | |
|   PopoverContent,
 | |
|   PopoverTrigger,
 | |
| } from "~/components/ui/popover";
 | |
| import { cn } from "~/lib/utils";
 | |
| 
 | |
| export default function DatePickerWithRange({
 | |
|   className,
 | |
|   startDate,
 | |
|   setStartDate,
 | |
| }: {
 | |
|   className?: string;
 | |
|   startDate: DateTime;
 | |
|   setStartDate: (date: DateTime) => void;
 | |
| }) {
 | |
|   const endDate = startDate.endOf("week");
 | |
| 
 | |
|   function handleDateSelect(selectedDate?: Date) {
 | |
|     if (selectedDate) {
 | |
|       setStartDate(DateTime.fromJSDate(selectedDate));
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return (
 | |
|     <div className={cn("grid gap-2 w-full", className)}>
 | |
|       <Popover>
 | |
|         <PopoverTrigger asChild>
 | |
|           <button
 | |
|             id="date"
 | |
|             className={
 | |
|               "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive h-9 px-4 py-2 has-[>svg]:px-3 border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:hover:bg-input/50 " +
 | |
|               cn(
 | |
|                 "w-full justify-start text-left font-normal",
 | |
|                 !startDate && "text-muted-foreground"
 | |
|               )
 | |
|             }
 | |
|           >
 | |
|             <CalendarIcon className="mr-2 h-4 w-4" />
 | |
|             Du {formatDate(startDate)} au {formatDate(endDate, true)}
 | |
|           </button>
 | |
|         </PopoverTrigger>
 | |
|         <PopoverContent className="w-auto p-0" align="start">
 | |
|           <Calendar
 | |
|             mode="single"
 | |
|             selected={startDate.toJSDate()}
 | |
|             defaultMonth={startDate.startOf("month").toJSDate()}
 | |
|             onSelect={handleDateSelect}
 | |
|             weekStartsOn={1}
 | |
|             locale={fr}
 | |
|             className="rounded-md border shadow-sm"
 | |
|             captionLayout="dropdown"
 | |
|           />
 | |
|         </PopoverContent>
 | |
|       </Popover>
 | |
|     </div>
 | |
|   );
 | |
| }
 | |
| 
 | |
| const formatDate = (date: DateTime, includeYear = false) => {
 | |
|   const localDate = date.setLocale("fr");
 | |
|   return includeYear
 | |
|     ? localDate.toFormat("dd MMM yyyy")
 | |
|     : localDate.toFormat("dd MMM");
 | |
| };
 | 
