Skip to main content
Glama

mcp-google-sheets

date-time-picker-range.tsx9.89 kB
'use client'; import { format, subDays, addDays } from 'date-fns'; import { t } from 'i18next'; import { Calendar as CalendarIcon, Clock } from 'lucide-react'; import * as React from 'react'; import { DateRange } from 'react-day-picker'; import { Button } from '@/components/ui/button'; import { Calendar } from '@/components/ui/calendar'; import { Popover, PopoverContent, PopoverTrigger, } from '@/components/ui/popover'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select'; import { cn } from '@/lib/utils'; import { Separator } from './separator'; import { TimePicker } from './time-picker'; type DateTimePickerWithRangeProps = { onChange: (date: DateRange | undefined) => void; className?: string; from?: string; to?: string; maxDate?: Date; minDate?: Date; presetType: 'past' | 'future'; }; const applyTimeToDate = ({ timeDate, targetDate, }: { timeDate: Date; targetDate: Date; }): Date => { // Extract time components from sourceDate const hours = timeDate.getHours(); const minutes = timeDate.getMinutes(); const seconds = timeDate.getSeconds(); const milliseconds = timeDate.getMilliseconds(); return new Date( new Date(new Date(targetDate)).setHours( hours, minutes, seconds, milliseconds, ), ); // Return the updated targetDate }; const getStartToEndDayTime = () => { const now = new Date(); const startDate = new Date( now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0, ); const endDate = new Date( now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999, ); return { from: startDate, to: endDate, }; }; export function DateTimePickerWithRange({ className, onChange, from, to, maxDate = new Date(), minDate, presetType = 'past', }: DateTimePickerWithRangeProps) { const [date, setDate] = React.useState<DateRange | undefined>({ from: from ? new Date(from) : undefined, to: to ? new Date(to) : undefined, }); const [timeDate, setTimeDate] = React.useState<DateRange>({ from: from ? new Date(from) : undefined, to: to ? new Date(to) : undefined, }); const handleSelect = (selectedDate: DateRange | undefined) => { if (selectedDate) { const newDate = { from: selectedDate.from && timeDate.from ? applyTimeToDate({ timeDate: timeDate.from, targetDate: selectedDate.from, }) : selectedDate.from ? applyTimeToDate({ timeDate: getStartToEndDayTime().from, targetDate: selectedDate.from, }) : undefined, to: selectedDate.to && timeDate.to ? applyTimeToDate({ timeDate: timeDate.to, targetDate: selectedDate.to, }) : selectedDate.to ? applyTimeToDate({ timeDate: getStartToEndDayTime().to, targetDate: selectedDate.to, }) : undefined, }; setDate(newDate); onChange(newDate); } else { setDate(selectedDate); onChange(selectedDate); } }; const handlePresetChange = (value: string) => { const today = new Date(); let newDate: DateRange; switch (value) { case 'week': newDate = { from: subDays(today, 7), to: today }; break; case 'month': newDate = { from: subDays(today, 30), to: today }; break; case '3months': newDate = { from: subDays(today, 90), to: today }; break; case '6months': newDate = { from: subDays(today, 180), to: today }; break; default: newDate = { from: today, to: addDays(today, parseInt(value)) }; } newDate.from!.setHours(0, 0, 0, 0); newDate.to!.setHours(23, 59, 59, 999); setDate(newDate); onChange(newDate); }; return ( <div className={cn('grid gap-2', className)}> <Popover> <PopoverTrigger asChild> <Button id="date" variant={'outline'} className={cn( 'min-w-[90px] border-dashed justify-start text-left font-normal', !date && 'text-muted-foreground', )} > <CalendarIcon className="mr-2 h-4 w-4" /> {date?.from ? ( date.to ? ( <div className="flex gap-2 items-center"> <div>{format(date.from, 'LLL dd, y, hh:mm a')}</div> <div>{t('to')}</div> <div>{format(date.to, 'LLL dd, y, hh:mm a')}</div> </div> ) : ( format(date.from, 'LLL dd, y, hh:mm a') ) ) : ( <span>{t('Pick a date range')}</span> )} </Button> </PopoverTrigger> <PopoverContent className="w-auto p-2" align="start"> <div className="flex space-x-2 mb-2"> <Select onValueChange={handlePresetChange}> <SelectTrigger> <SelectValue placeholder="Select preset" /> </SelectTrigger> <SelectContent> {presetType === 'past' ? ( <> <SelectItem value="week">{t('Last Week')}</SelectItem> <SelectItem value="month">{t('Last Month')}</SelectItem> <SelectItem value="3months"> {t('Last 3 Months')} </SelectItem> <SelectItem value="6months"> {t('Last 6 Months')} </SelectItem> </> ) : ( <> <SelectItem value="7">{t('Next 7 days')}</SelectItem> <SelectItem value="30">{t('Next 30 days')}</SelectItem> <SelectItem value="90">{t('Next 90 days')}</SelectItem> <SelectItem value="180">{t('Next 180 days')}</SelectItem> </> )} </SelectContent> </Select> </div> <Calendar initialFocus mode="range" defaultMonth={date?.from} selected={date} onSelect={handleSelect} numberOfMonths={2} min={2} weekStartsOn={1} toDate={maxDate} fromDate={minDate} /> <Separator className="mb-4"></Separator> <div className="flex justify-between items-center "> <div className="flex gap-1.5 px-2 items-center text-sm"> <Clock className="w-4 h-4 text-muted-foreground"></Clock> {t('Select Time Range')} </div> <Button variant={'ghost'} size={'sm'} className="text-primary hover:!text-primary" onClick={() => { const fromTime = getStartToEndDayTime().from; const toTime = getStartToEndDayTime().to; const fromDate = date?.from ? applyTimeToDate({ timeDate: fromTime, targetDate: date.from, }) : undefined; const toDate = date?.to ? applyTimeToDate({ timeDate: toTime, targetDate: date.to, }) : undefined; setTimeDate({ from: fromTime, to: toTime, }); setDate({ from: fromDate, to: toDate, }); onChange({ from: fromDate, to: toDate, }); }} > {t('Clear')} </Button> </div> <div className="flex gap-3 items-center mt-3 px-2 mb-2"> <div className="flex gap-2 grow justify-center items-center items-center"> <TimePicker date={timeDate.from} name="from" setDate={(fromTime) => { const fromDate = date?.from ?? new Date(); const fromWithCorrectedTime = applyTimeToDate({ timeDate: fromTime, targetDate: fromDate, }); setDate({ from: fromWithCorrectedTime, to: date?.to, }); onChange({ from: fromWithCorrectedTime, to: date?.to, }); setTimeDate({ ...timeDate, from: fromTime }); }} ></TimePicker> </div> {t('to')} <div className="flex gap-2 grow justify-center items-center "> <TimePicker date={timeDate.to} name="to" setDate={(toTime) => { const toDate = date?.to ?? date?.from ?? new Date(); const toWithCorrectedTime = applyTimeToDate({ timeDate: toTime, targetDate: toDate, }); setDate({ from: date?.from, to: toWithCorrectedTime, }); onChange({ from: date?.from, to: toWithCorrectedTime, }); setTimeDate({ ...timeDate, to: toTime }); }} ></TimePicker> </div> </div> </PopoverContent> </Popover> </div> ); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/activepieces/activepieces'

If you have feedback or need assistance with the MCP directory API, please join our Discord server