Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
4.5 kB ยท 128 lines
TSX
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129"use client";
import { Button } from "@openstatus/ui/components/ui/button";import { Calendar } from "@openstatus/ui/components/ui/calendar";import { Input } from "@openstatus/ui/components/ui/input";import { Kbd } from "@openstatus/ui/components/ui/kbd";import { Label } from "@openstatus/ui/components/ui/label";import { Separator } from "@openstatus/ui/components/ui/separator";import { endOfDay } from "date-fns";import { useState } from "react";import type { DateRange } from "react-day-picker";
import { formatDateForInput } from "@/lib/formatter";
type DatePickerProps = { range: DateRange; onSelect: (range: DateRange) => void; presets: { id: string; label: string; values: DateRange; shortcut: string }[];};
export function DatePicker({ range, onSelect, presets }: DatePickerProps) { const [today] = useState(new Date()); const disableBefore = presets[presets.length - 1]?.values?.from;
return ( <div> <div className="flex flex-row"> <div className="relative py-4"> <div className="h-full"> <div className="flex flex-col px-1"> <div className="text-muted-foreground px-3 py-1 text-xs font-medium"> Presets </div> {presets.map((preset) => { const isSelected = range.from?.getTime() === preset.values.from?.getTime() && range.to?.getTime() === preset.values.to?.getTime();
return ( <Button key={preset.id} variant={isSelected ? "outline" : "ghost"} size="sm" className="w-full justify-between border border-transparent" onClick={() => { onSelect(preset.values); }} > <span>{preset.label}</span> <Kbd className="font-mono uppercase">{preset.shortcut}</Kbd> </Button> ); })} </div> </div> </div> <Separator orientation="vertical" className="h-auto! w-px" /> <div className="flex flex-1 items-center justify-center"> <Calendar mode="range" selected={range} onSelect={(newDate) => { if (newDate) { onSelect({ ...newDate, to: newDate.to ? endOfDay(newDate.to) : undefined, }); } }} className="p-2" disabled={[ { after: today }, // Dates before today { before: disableBefore ?? today }, // Dates before last action ]} /> </div> </div> <Separator /> <div className="flex flex-col gap-2 px-3 py-4"> <p className="text-muted-foreground px-1 text-xs font-medium"> Custom Range </p> <div className="grid gap-2 sm:grid-cols-2"> <div className="grid w-full gap-1.5"> <Label htmlFor="from" className="px-1"> Start </Label> <Input type="datetime-local" id="from" name="from" min={formatDateForInput(disableBefore ?? today)} max={formatDateForInput(today)} value={range.from ? formatDateForInput(range.from) : ""} onChange={(e) => { const newDate = new Date(e.target.value); if (!Number.isNaN(newDate.getTime())) { onSelect({ ...range, from: newDate }); } }} disabled={!range.from} /> </div> <div className="grid w-full gap-1.5"> <Label htmlFor="to" className="px-1"> End </Label> <Input type="datetime-local" id="to" name="to" min={formatDateForInput(range.from ?? today)} max={formatDateForInput(today)} value={range.to ? formatDateForInput(range.to) : ""} onChange={(e) => { const newDate = new Date(e.target.value); if (!Number.isNaN(newDate.getTime())) { onSelect({ ...range, to: newDate }); } }} disabled={!range.to} /> </div> </div> </div> </div> );}