working shadcn date picker

This commit is contained in:
andrzej 2024-06-14 11:42:31 +02:00
parent 4cb077e7b9
commit 0c4b3167ce
8 changed files with 513 additions and 1 deletions

71
package-lock.json generated
View File

@ -12,16 +12,20 @@
"@prisma/client": "^5.15.0", "@prisma/client": "^5.15.0",
"@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2", "@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-select": "^2.0.0", "@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-toast": "^1.1.5", "@radix-ui/react-toast": "^1.1.5",
"@tanstack/react-table": "^8.17.3", "@tanstack/react-table": "^8.17.3",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"date-fns": "^3.6.0",
"lucide-react": "^0.394.0", "lucide-react": "^0.394.0",
"next": "14.2.3", "next": "14.2.3",
"react": "^18", "react": "^18",
"react-day-picker": "^8.10.1",
"react-dom": "^18", "react-dom": "^18",
"react-hook-form": "^7.51.5", "react-hook-form": "^7.51.5",
"tailwind-merge": "^2.3.0", "tailwind-merge": "^2.3.0",
@ -802,6 +806,14 @@
} }
} }
}, },
"node_modules/@radix-ui/react-icons": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz",
"integrity": "sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==",
"peerDependencies": {
"react": "^16.x || ^17.x || ^18.x"
}
},
"node_modules/@radix-ui/react-id": { "node_modules/@radix-ui/react-id": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.1.tgz",
@ -883,6 +895,43 @@
} }
} }
}, },
"node_modules/@radix-ui/react-popover": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.0.7.tgz",
"integrity": "sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "1.0.1",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-context": "1.0.1",
"@radix-ui/react-dismissable-layer": "1.0.5",
"@radix-ui/react-focus-guards": "1.0.1",
"@radix-ui/react-focus-scope": "1.0.4",
"@radix-ui/react-id": "1.0.1",
"@radix-ui/react-popper": "1.1.3",
"@radix-ui/react-portal": "1.0.4",
"@radix-ui/react-presence": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-slot": "1.0.2",
"@radix-ui/react-use-controllable-state": "1.0.1",
"aria-hidden": "^1.1.1",
"react-remove-scroll": "2.5.5"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-popper": { "node_modules/@radix-ui/react-popper": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.1.3.tgz",
@ -2231,6 +2280,15 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/date-fns": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz",
"integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/kossnocorp"
}
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.5", "version": "4.3.5",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
@ -4936,6 +4994,19 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/react-day-picker": {
"version": "8.10.1",
"resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-8.10.1.tgz",
"integrity": "sha512-TMx7fNbhLk15eqcMt+7Z7S2KF7mfTId/XJDjKE8f+IUcFn0l08/kI4FiYTL/0yuOLmEcbR4Fwe3GJf/NiiMnPA==",
"funding": {
"type": "individual",
"url": "https://github.com/sponsors/gpbl"
},
"peerDependencies": {
"date-fns": "^2.28.0 || ^3.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-dom": { "node_modules/react-dom": {
"version": "18.3.1", "version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",

View File

@ -14,16 +14,20 @@
"@prisma/client": "^5.15.0", "@prisma/client": "^5.15.0",
"@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2", "@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-select": "^2.0.0", "@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-slot": "^1.0.2", "@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-toast": "^1.1.5", "@radix-ui/react-toast": "^1.1.5",
"@tanstack/react-table": "^8.17.3", "@tanstack/react-table": "^8.17.3",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"date-fns": "^3.6.0",
"lucide-react": "^0.394.0", "lucide-react": "^0.394.0",
"next": "14.2.3", "next": "14.2.3",
"react": "^18", "react": "^18",
"react-day-picker": "^8.10.1",
"react-dom": "^18", "react-dom": "^18",
"react-hook-form": "^7.51.5", "react-hook-form": "^7.51.5",
"tailwind-merge": "^2.3.0", "tailwind-merge": "^2.3.0",

View File

@ -0,0 +1,66 @@
"use client"
import * as React from "react"
import { ChevronLeft, ChevronRight } from "lucide-react"
import { DayPicker } from "react-day-picker"
import { cn } from "@/lib/utils"
import { buttonVariants } from "@/components/ui/button"
export type CalendarProps = React.ComponentProps<typeof DayPicker>
function Calendar({
className,
classNames,
showOutsideDays = true,
...props
}: CalendarProps) {
return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn("p-3", className)}
classNames={{
months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
month: "space-y-4",
caption: "flex justify-center pt-1 relative items-center",
caption_label: "text-sm font-medium",
nav: "space-x-1 flex items-center",
nav_button: cn(
buttonVariants({ variant: "outline" }),
"h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100"
),
nav_button_previous: "absolute left-1",
nav_button_next: "absolute right-1",
table: "w-full border-collapse space-y-1",
head_row: "flex",
head_cell:
"text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
row: "flex w-full mt-2",
cell: "h-9 w-9 text-center text-sm p-0 relative [&:has([aria-selected].day-range-end)]:rounded-r-md [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected])]:bg-accent first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md focus-within:relative focus-within:z-20",
day: cn(
buttonVariants({ variant: "ghost" }),
"h-9 w-9 p-0 font-normal aria-selected:opacity-100"
),
day_range_end: "day-range-end",
day_selected:
"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
day_today: "bg-accent text-accent-foreground",
day_outside:
"day-outside text-muted-foreground opacity-50 aria-selected:bg-accent/50 aria-selected:text-muted-foreground aria-selected:opacity-30",
day_disabled: "text-muted-foreground opacity-50",
day_range_middle:
"aria-selected:bg-accent aria-selected:text-accent-foreground",
day_hidden: "invisible",
...classNames,
}}
components={{
IconLeft: ({ ...props }) => <ChevronLeft className="h-4 w-4" />,
IconRight: ({ ...props }) => <ChevronRight className="h-4 w-4" />,
}}
{...props}
/>
)
}
Calendar.displayName = "Calendar"
export { Calendar }

View File

@ -0,0 +1,31 @@
"use client"
import * as React from "react"
import * as PopoverPrimitive from "@radix-ui/react-popover"
import { cn } from "@/lib/utils"
const Popover = PopoverPrimitive.Root
const PopoverTrigger = PopoverPrimitive.Trigger
const PopoverContent = React.forwardRef<
React.ElementRef<typeof PopoverPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof PopoverPrimitive.Content>
>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
<PopoverPrimitive.Portal>
<PopoverPrimitive.Content
ref={ref}
align={align}
sideOffset={sideOffset}
className={cn(
"z-50 w-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
/>
</PopoverPrimitive.Portal>
))
PopoverContent.displayName = PopoverPrimitive.Content.displayName
export { Popover, PopoverTrigger, PopoverContent }

View File

@ -604,6 +604,10 @@ body {
pointer-events: auto; pointer-events: auto;
} }
.invisible {
visibility: hidden;
}
.fixed { .fixed {
position: fixed; position: fixed;
} }
@ -632,6 +636,14 @@ body {
top: 0.5rem; top: 0.5rem;
} }
.left-1 {
left: 0.25rem;
}
.right-1 {
right: 0.25rem;
}
.z-50 { .z-50 {
z-index: 50; z-index: 50;
} }
@ -743,6 +755,10 @@ body {
height: 2rem; height: 2rem;
} }
.h-7 {
height: 1.75rem;
}
.max-h-96 { .max-h-96 {
max-height: 24rem; max-height: 24rem;
} }
@ -783,6 +799,26 @@ body {
width: 66.666667%; width: 66.666667%;
} }
.w-72 {
width: 18rem;
}
.w-7 {
width: 1.75rem;
}
.w-9 {
width: 2.25rem;
}
.w-\[240px\] {
width: 240px;
}
.w-auto {
width: auto;
}
.min-w-\[8rem\] { .min-w-\[8rem\] {
min-width: 8rem; min-width: 8rem;
} }
@ -803,6 +839,10 @@ body {
caption-side: bottom; caption-side: bottom;
} }
.border-collapse {
border-collapse: collapse;
}
.cursor-default { .cursor-default {
cursor: default; cursor: default;
} }
@ -817,6 +857,10 @@ body {
flex-direction: row; flex-direction: row;
} }
.flex-col {
flex-direction: column;
}
.flex-col-reverse { .flex-col-reverse {
flex-direction: column-reverse; flex-direction: column-reverse;
} }
@ -887,6 +931,24 @@ body {
margin-bottom: calc(1.5rem * var(--tw-space-y-reverse)); margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
} }
.space-x-1 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(0.25rem * var(--tw-space-x-reverse));
margin-left: calc(0.25rem * calc(1 - var(--tw-space-x-reverse)));
}
.space-y-1 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(0.25rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0.25rem * var(--tw-space-y-reverse));
}
.space-y-4 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(1rem * var(--tw-space-y-reverse));
}
.overflow-auto { .overflow-auto {
overflow: auto; overflow: auto;
} }
@ -968,6 +1030,10 @@ body {
background-color: transparent; background-color: transparent;
} }
.bg-accent {
background-color: hsl(var(--accent));
}
.fill-current { .fill-current {
fill: currentColor; fill: currentColor;
} }
@ -984,6 +1050,14 @@ body {
padding: 1.5rem; padding: 1.5rem;
} }
.p-0 {
padding: 0px;
}
.p-3 {
padding: 0.75rem;
}
.px-2 { .px-2 {
padding-left: 0.5rem; padding-left: 0.5rem;
padding-right: 0.5rem; padding-right: 0.5rem;
@ -1041,6 +1115,14 @@ body {
padding-right: 2rem; padding-right: 2rem;
} }
.pt-1 {
padding-top: 0.25rem;
}
.pl-3 {
padding-left: 0.75rem;
}
.text-left { .text-left {
text-align: left; text-align: left;
} }
@ -1073,6 +1155,10 @@ body {
line-height: 1rem; line-height: 1rem;
} }
.text-\[0\.8rem\] {
font-size: 0.8rem;
}
.font-black { .font-black {
font-weight: 900; font-weight: 900;
} }
@ -1146,6 +1232,10 @@ body {
color: hsl(var(--foreground) / 0.5); color: hsl(var(--foreground) / 0.5);
} }
.text-accent-foreground {
color: hsl(var(--accent-foreground));
}
.underline { .underline {
text-decoration-line: underline; text-decoration-line: underline;
} }
@ -1256,6 +1346,14 @@ body {
color: hsl(var(--muted-foreground)); color: hsl(var(--muted-foreground));
} }
.focus-within\:relative:focus-within {
position: relative;
}
.focus-within\:z-20:focus-within {
z-index: 20;
}
.hover\:bg-accent:hover { .hover\:bg-accent:hover {
background-color: hsl(var(--accent)); background-color: hsl(var(--accent));
} }
@ -1280,6 +1378,10 @@ body {
background-color: hsl(var(--secondary)); background-color: hsl(var(--secondary));
} }
.hover\:bg-primary:hover {
background-color: hsl(var(--primary));
}
.hover\:text-accent-foreground:hover { .hover\:text-accent-foreground:hover {
color: hsl(var(--accent-foreground)); color: hsl(var(--accent-foreground));
} }
@ -1288,18 +1390,34 @@ body {
color: hsl(var(--foreground)); color: hsl(var(--foreground));
} }
.hover\:text-primary-foreground:hover {
color: hsl(var(--primary-foreground));
}
.hover\:underline:hover { .hover\:underline:hover {
text-decoration-line: underline; text-decoration-line: underline;
} }
.hover\:opacity-100:hover {
opacity: 1;
}
.focus\:bg-accent:focus { .focus\:bg-accent:focus {
background-color: hsl(var(--accent)); background-color: hsl(var(--accent));
} }
.focus\:bg-primary:focus {
background-color: hsl(var(--primary));
}
.focus\:text-accent-foreground:focus { .focus\:text-accent-foreground:focus {
color: hsl(var(--accent-foreground)); color: hsl(var(--accent-foreground));
} }
.focus\:text-primary-foreground:focus {
color: hsl(var(--primary-foreground));
}
.focus\:opacity-100:focus { .focus\:opacity-100:focus {
opacity: 1; opacity: 1;
} }
@ -1405,6 +1523,30 @@ body {
opacity: 0.7; opacity: 0.7;
} }
.aria-selected\:bg-accent[aria-selected="true"] {
background-color: hsl(var(--accent));
}
.aria-selected\:bg-accent\/50[aria-selected="true"] {
background-color: hsl(var(--accent) / 0.5);
}
.aria-selected\:text-accent-foreground[aria-selected="true"] {
color: hsl(var(--accent-foreground));
}
.aria-selected\:text-muted-foreground[aria-selected="true"] {
color: hsl(var(--muted-foreground));
}
.aria-selected\:opacity-100[aria-selected="true"] {
opacity: 1;
}
.aria-selected\:opacity-30[aria-selected="true"] {
opacity: 0.3;
}
.data-\[disabled\]\:pointer-events-none[data-disabled] { .data-\[disabled\]\:pointer-events-none[data-disabled] {
pointer-events: none; pointer-events: none;
} }
@ -1555,10 +1697,26 @@ body {
top: auto; top: auto;
} }
.sm\:flex-row {
flex-direction: row;
}
.sm\:flex-col { .sm\:flex-col {
flex-direction: column; flex-direction: column;
} }
.sm\:space-x-4 > :not([hidden]) ~ :not([hidden]) {
--tw-space-x-reverse: 0;
margin-right: calc(1rem * var(--tw-space-x-reverse));
margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));
}
.sm\:space-y-0 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0px * var(--tw-space-y-reverse));
}
.data-\[state\=open\]\:sm\:slide-in-from-bottom-full[data-state=open] { .data-\[state\=open\]\:sm\:slide-in-from-bottom-full[data-state=open] {
--tw-enter-translate-y: 100%; --tw-enter-translate-y: 100%;
} }
@ -1570,6 +1728,29 @@ body {
} }
} }
.\[\&\:has\(\[aria-selected\]\)\]\:bg-accent:has([aria-selected]) {
background-color: hsl(var(--accent));
}
.first\:\[\&\:has\(\[aria-selected\]\)\]\:rounded-l-md:has([aria-selected]):first-child {
border-top-left-radius: calc(var(--radius) - 2px);
border-bottom-left-radius: calc(var(--radius) - 2px);
}
.last\:\[\&\:has\(\[aria-selected\]\)\]\:rounded-r-md:has([aria-selected]):last-child {
border-top-right-radius: calc(var(--radius) - 2px);
border-bottom-right-radius: calc(var(--radius) - 2px);
}
.\[\&\:has\(\[aria-selected\]\.day-outside\)\]\:bg-accent\/50:has([aria-selected].day-outside) {
background-color: hsl(var(--accent) / 0.5);
}
.\[\&\:has\(\[aria-selected\]\.day-range-end\)\]\:rounded-r-md:has([aria-selected].day-range-end) {
border-top-right-radius: calc(var(--radius) - 2px);
border-bottom-right-radius: calc(var(--radius) - 2px);
}
.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]) { .\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]) {
padding-right: 0px; padding-right: 0px;
} }

View File

@ -0,0 +1,103 @@
"use client"
import { zodResolver } from "@hookform/resolvers/zod"
import { CalendarIcon } from "@radix-ui/react-icons"
import { format } from "date-fns"
import { useForm } from "react-hook-form"
import { z } from "zod"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Calendar } from "@/components/ui/calendar"
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"
import { toast } from "@/components/ui/use-toast"
const FormSchema = z.object({
dob: z.date({
required_error: "A date of birth is required.",
}),
})
export function DatePickerForm() {
const form = useForm<z.infer<typeof FormSchema>>({
resolver: zodResolver(FormSchema),
})
function onSubmit(data: z.infer<typeof FormSchema>) {
toast({
title: "You submitted the following values:",
description: (
<pre className="mt-2 w-[340px] rounded-md bg-slate-950 p-4">
<code className="text-white">{JSON.stringify(data, null, 2)}</code>
</pre>
),
})
}
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
<FormField
control={form.control}
name="dob"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Date of birth</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
<Button
variant={"outline"}
className={cn(
"w-[240px] pl-3 text-left font-normal",
!field.value && "text-muted-foreground"
)}
>
{field.value ? (
format(field.value, "PPP")
) : (
<span>Pick a date</span>
)}
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="single"
selected={field.value}
onSelect={field.onChange}
disabled={(date) =>
date > new Date() || date < new Date("1900-01-01")
}
initialFocus
/>
</PopoverContent>
</Popover>
<FormDescription>
Your date of birth is used to calculate your age.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button>
</form>
</Form>
)
}

View File

@ -5,6 +5,16 @@ import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form" import { useForm } from "react-hook-form"
import { Button } from "@/components/ui/button" import { Button } from "@/components/ui/button"
import { toast } from "@/components/ui/use-toast" import { toast } from "@/components/ui/use-toast"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"
import { Calendar } from "@/components/ui/calendar"
import { CalendarIcon } from "@radix-ui/react-icons"
import { cn } from "@/lib/utils"
import { format } from "date-fns"
import { import {
Form, Form,
FormItem, FormItem,
@ -26,7 +36,7 @@ import { ItemText, SelectItemIndicator, SelectItemText } from "@radix-ui/react-s
const FormSchema = z.object({ const FormSchema = z.object({
storyId: z.string(), storyId: z.string(),
pubId: z.string(), pubId: z.string(),
// submitted: z.date(), submitted: z.date(),
// responded: z.date(), // responded: z.date(),
// responseId: z.string() // responseId: z.string()
}) })
@ -131,6 +141,52 @@ export default function SubmissionForm({ stories, pubs, responses }) {
)} )}
/> />
<FormField
control={form.control}
name="submitted"
render={({ field }) => (
<FormItem className="flex flex-col">
<FormLabel>Date of birth</FormLabel>
<Popover>
<PopoverTrigger asChild>
<FormControl>
<Button
variant={"outline"}
className={cn(
"w-[240px] pl-3 text-left font-normal",
!field.value && "text-muted-foreground"
)}
>
{field.value ? (
format(field.value, "PPP")
) : (
<span>Pick a date</span>
)}
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
</Button>
</FormControl>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="single"
selected={field.value}
onSelect={field.onChange}
disabled={(date) =>
date > new Date() || date < new Date("1900-01-01")
}
initialFocus
/>
</PopoverContent>
</Popover>
<FormDescription>
The date you sent it
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<Button type="submit">Submit</Button> <Button type="submit">Submit</Button>
</form> </form>

Binary file not shown.