-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add search bar form with DateRange
- Loading branch information
1 parent
78073c2
commit 0937fd0
Showing
17 changed files
with
1,304 additions
and
52 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import * as React from "react"; | ||
import { addDays, format } from "date-fns"; | ||
import { Calendar as CalendarIcon } from "lucide-react"; | ||
|
||
import { cn } from "@/lib/utils"; | ||
import { Button } from "@/components/ui/button"; | ||
import { Calendar } from "@/components/ui/calendar"; | ||
import { | ||
Popover, | ||
PopoverContent, | ||
PopoverTrigger, | ||
} from "@/components/ui/popover"; | ||
import type { DateRange, SelectRangeEventHandler } from "react-day-picker"; | ||
|
||
type DateRangeProps = { | ||
className?: string; | ||
onSelect: SelectRangeEventHandler; | ||
selected: DateRange; | ||
}; | ||
|
||
export function DateRange({ className, selected, onSelect }: DateRangeProps) { | ||
return ( | ||
<div className={cn("grid gap-2", className)}> | ||
<Popover> | ||
<PopoverTrigger asChild> | ||
<Button | ||
id="date" | ||
variant={"outline"} | ||
className={cn( | ||
"w-[300px] justify-start text-left font-normal", | ||
!selected && "text-muted-foreground" | ||
)} | ||
> | ||
<CalendarIcon className="mr-2 h-4 w-4" /> | ||
{selected?.from ? ( | ||
selected.to ? ( | ||
<> | ||
{format(selected.from, "LLL dd, y")} -{" "} | ||
{format(selected.to, "LLL dd, y")} | ||
</> | ||
) : ( | ||
format(selected.from, "LLL dd, y") | ||
) | ||
) : ( | ||
<span>Pick a date</span> | ||
)} | ||
</Button> | ||
</PopoverTrigger> | ||
<PopoverContent className="w-auto p-0" align="start"> | ||
<Calendar | ||
initialFocus | ||
mode="range" | ||
defaultMonth={selected?.from} | ||
selected={selected} | ||
onSelect={onSelect} | ||
numberOfMonths={2} | ||
/> | ||
</PopoverContent> | ||
</Popover> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { | ||
Card, | ||
CardContent, | ||
CardDescription, | ||
CardFooter, | ||
CardHeader, | ||
CardTitle, | ||
} from "@/components/ui/card"; | ||
import { Glamp } from "@/generated/graphql"; | ||
import { cn } from "@/lib/utils"; | ||
|
||
type CardProps = React.ComponentProps<typeof Card> & { | ||
glamp: Glamp; | ||
}; | ||
|
||
export function PreviewCard({ className, glamp, ...props }: CardProps) { | ||
return ( | ||
<Card className={cn("w-[380px]", className)} {...props}> | ||
<CardHeader> | ||
<CardTitle>{glamp.title}</CardTitle> | ||
<CardDescription>{glamp.description}</CardDescription> | ||
</CardHeader> | ||
<CardContent className="grid gap-4"></CardContent> | ||
<CardFooter></CardFooter> | ||
</Card> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { zodResolver } from "@hookform/resolvers/zod"; | ||
import { useForm } from "react-hook-form"; | ||
import { z } from "zod"; | ||
|
||
import { Button } from "@/components/ui/button"; | ||
import { | ||
Form, | ||
FormDescription, | ||
FormField, | ||
FormItem, | ||
FormLabel, | ||
FormMessage, | ||
} from "@/components/ui/form"; | ||
import { toast } from "@/components/ui/use-toast"; | ||
import { DateRange } from "./DateRange"; | ||
|
||
const FormSchema = z.object({ | ||
dateRange: z.object({ | ||
from: z.date({ required_error: "A date of birth is required." }), | ||
to: z.date({ required_error: "A date to is required" }), | ||
}), | ||
}); | ||
|
||
function SearchBar() { | ||
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="dateRange" | ||
render={({ field }) => ( | ||
<FormItem className="flex flex-col"> | ||
<FormLabel>Date of birth</FormLabel> | ||
<DateRange selected={field.value} onSelect={field.onChange} /> | ||
<FormDescription> | ||
Your date of birth is used to calculate your age. | ||
</FormDescription> | ||
<FormMessage /> | ||
</FormItem> | ||
)} | ||
/> | ||
<Button type="submit">Submit</Button> | ||
</form> | ||
</Form> | ||
</> | ||
); | ||
} | ||
|
||
export default SearchBar; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import * as React from "react"; | ||
import { cva, type VariantProps } from "class-variance-authority"; | ||
|
||
import { cn } from "@/lib/utils"; | ||
|
||
const shellVariants = cva("grid items-center gap-8 pb-8 pt-6 md:py-8", { | ||
variants: { | ||
variant: { | ||
default: "container", | ||
sidebar: "", | ||
centered: "container flex h-[100dvh] max-w-2xl flex-col justify-center", | ||
markdown: "container max-w-3xl py-8 md:py-10 lg:py-10", | ||
}, | ||
}, | ||
defaultVariants: { | ||
variant: "default", | ||
}, | ||
}); | ||
|
||
interface ShellProps | ||
extends React.HTMLAttributes<HTMLDivElement>, | ||
VariantProps<typeof shellVariants> { | ||
as?: React.ElementType; | ||
} | ||
|
||
function Shell({ | ||
className, | ||
as: Comp = "section", | ||
variant, | ||
...props | ||
}: ShellProps) { | ||
return ( | ||
<Comp className={cn(shellVariants({ variant }), className)} {...props} /> | ||
); | ||
} | ||
|
||
export { Shell, shellVariants }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import * as React from "react" | ||
import { ChevronLeftIcon, ChevronRightIcon } from "@radix-ui/react-icons" | ||
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-8 font-normal text-[0.8rem]", | ||
row: "flex w-full mt-2", | ||
cell: cn( | ||
"relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent [&:has([aria-selected].day-outside)]:bg-accent/50 [&:has([aria-selected].day-range-end)]:rounded-r-md", | ||
props.mode === "range" | ||
? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md" | ||
: "[&:has([aria-selected])]:rounded-md" | ||
), | ||
day: cn( | ||
buttonVariants({ variant: "ghost" }), | ||
"h-8 w-8 p-0 font-normal aria-selected:opacity-100" | ||
), | ||
day_range_start: "day-range-start", | ||
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 }) => <ChevronLeftIcon className="h-4 w-4" />, | ||
IconRight: ({ ...props }) => <ChevronRightIcon className="h-4 w-4" />, | ||
}} | ||
{...props} | ||
/> | ||
) | ||
} | ||
Calendar.displayName = "Calendar" | ||
|
||
export { Calendar } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import * as React from "react" | ||
|
||
import { cn } from "@/lib/utils" | ||
|
||
const Card = React.forwardRef< | ||
HTMLDivElement, | ||
React.HTMLAttributes<HTMLDivElement> | ||
>(({ className, ...props }, ref) => ( | ||
<div | ||
ref={ref} | ||
className={cn( | ||
"rounded-xl border bg-card text-card-foreground shadow", | ||
className | ||
)} | ||
{...props} | ||
/> | ||
)) | ||
Card.displayName = "Card" | ||
|
||
const CardHeader = React.forwardRef< | ||
HTMLDivElement, | ||
React.HTMLAttributes<HTMLDivElement> | ||
>(({ className, ...props }, ref) => ( | ||
<div | ||
ref={ref} | ||
className={cn("flex flex-col space-y-1.5 p-6", className)} | ||
{...props} | ||
/> | ||
)) | ||
CardHeader.displayName = "CardHeader" | ||
|
||
const CardTitle = React.forwardRef< | ||
HTMLParagraphElement, | ||
React.HTMLAttributes<HTMLHeadingElement> | ||
>(({ className, ...props }, ref) => ( | ||
<h3 | ||
ref={ref} | ||
className={cn("font-semibold leading-none tracking-tight", className)} | ||
{...props} | ||
/> | ||
)) | ||
CardTitle.displayName = "CardTitle" | ||
|
||
const CardDescription = React.forwardRef< | ||
HTMLParagraphElement, | ||
React.HTMLAttributes<HTMLParagraphElement> | ||
>(({ className, ...props }, ref) => ( | ||
<p | ||
ref={ref} | ||
className={cn("text-sm text-muted-foreground", className)} | ||
{...props} | ||
/> | ||
)) | ||
CardDescription.displayName = "CardDescription" | ||
|
||
const CardContent = React.forwardRef< | ||
HTMLDivElement, | ||
React.HTMLAttributes<HTMLDivElement> | ||
>(({ className, ...props }, ref) => ( | ||
<div ref={ref} className={cn("p-6 pt-0", className)} {...props} /> | ||
)) | ||
CardContent.displayName = "CardContent" | ||
|
||
const CardFooter = React.forwardRef< | ||
HTMLDivElement, | ||
React.HTMLAttributes<HTMLDivElement> | ||
>(({ className, ...props }, ref) => ( | ||
<div | ||
ref={ref} | ||
className={cn("flex items-center p-6 pt-0", className)} | ||
{...props} | ||
/> | ||
)) | ||
CardFooter.displayName = "CardFooter" | ||
|
||
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } |
Oops, something went wrong.