Skip to content

Commit

Permalink
✨ Feat(create-post): 활동 날짜 input calendar UI 추가
Browse files Browse the repository at this point in the history
- shadcn ui와 react-day-picker 버전 에러로 date 세팅 안됨
-  해당 에러 해결된 이후 코드 수정하기

related to: #169
  • Loading branch information
ppochaco committed Aug 14, 2024
1 parent 195fa78 commit 19e3f49
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 71 deletions.
Original file line number Diff line number Diff line change
@@ -1,32 +1,28 @@
import { useFormContext } from 'react-hook-form'

import { Label } from '@radix-ui/react-dropdown-menu'
import { kstFormat } from '@toss/date'

import { Button } from '@/components/ui/button'
import { Calendar } from '@/components/ui/calendar'
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from '@/components/ui/dialog'
import {
FormControl,
FormField,
FormItem,
FormMessage,
} from '@/components/ui/form'
import { FormField, FormItem, FormMessage } from '@/components/ui/form'
import { Label } from '@/components/ui/label'
import { CreatePost } from '@/schema/post'

import { DateDialogTriggerButton } from './DateDialogTriggerButton'

export const ActivityDateFieldDialog = () => {
const form = useFormContext<CreatePost>()
const { control, setValue } = useFormContext<CreatePost>()

return (
<FormField
control={form.control}
control={control}
name="activityDate"
render={({ field }) => (
<FormItem className="flex flex-col">
Expand All @@ -39,8 +35,37 @@ export const ActivityDateFieldDialog = () => {
endDate={field.value.end}
/>
<DialogContent>
<DialogTitle>test</DialogTitle>
<DialogDescription>gg</DialogDescription>
<DialogHeader>
<DialogTitle>활동 날짜 선택하기</DialogTitle>
<DialogDescription>
시작일과 종료일을 선택해주세요.
</DialogDescription>
</DialogHeader>
<div className="flex justify-center">
<Calendar
mode="range"
selected={{
from: field.value.start!,
to: field.value.end,
}}
onSelect={(range) => field.onChange(range)}
/>
</div>
<DialogFooter>
<DialogClose asChild>
<Button
className="w-fit"
onClick={() => {
setValue('activityDate', {
start: new Date(), //TODO: field.value.start
end: field.value.end,
})
}}
>
저장하기
</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
Expand Down
75 changes: 38 additions & 37 deletions src/components/ui/calendar.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
"use client"
'use client'

import * as React from "react"
import { ChevronLeftIcon, ChevronRightIcon } from "@radix-ui/react-icons"
import { DayPicker } from "react-day-picker"
import * as React from 'react'
import { DayPicker } from 'react-day-picker'

import { cn } from "@/lib/utils"
import { buttonVariants } from "@/components/ui/button"
import { ChevronLeftIcon, ChevronRightIcon } from '@radix-ui/react-icons'

import { buttonVariants } from '@/components/ui/button'
import { cn } from '@/lib/utils'

export type CalendarProps = React.ComponentProps<typeof DayPicker>

Expand All @@ -18,55 +19,55 @@ function Calendar({
return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn("p-3", className)}
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",
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"
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",
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",
'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"
'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"
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_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",
'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-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",
'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" />,
IconLeft: () => <ChevronLeftIcon className="h-4 w-4" />,
IconRight: () => <ChevronRightIcon className="h-4 w-4" />,
}}
{...props}
/>
)
}
Calendar.displayName = "Calendar"
Calendar.displayName = 'Calendar'

export { Calendar }
38 changes: 18 additions & 20 deletions src/components/ui/dialog.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
"use client"
'use client'

import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { Cross2Icon } from "@radix-ui/react-icons"
import * as React from 'react'

import { cn } from "@/lib/utils"
import * as DialogPrimitive from '@radix-ui/react-dialog'
import { Cross2Icon } from '@radix-ui/react-icons'

import { cn } from '@/lib/utils'

const Dialog = DialogPrimitive.Root

Expand All @@ -21,8 +22,8 @@ const DialogOverlay = React.forwardRef<
<DialogPrimitive.Overlay
ref={ref}
className={cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
className,
)}
{...props}
/>
Expand All @@ -38,8 +39,8 @@ const DialogContent = React.forwardRef<
<DialogPrimitive.Content
ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
className
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg',
className,
)}
{...props}
>
Expand All @@ -59,27 +60,24 @@ const DialogHeader = ({
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col space-y-1.5 text-center sm:text-left",
className
'flex flex-col space-y-1.5 text-center sm:text-left',
className,
)}
{...props}
/>
)
DialogHeader.displayName = "DialogHeader"
DialogHeader.displayName = 'DialogHeader'

const DialogFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
className={cn('flex flex-row justify-end sm:space-x-2', className)}
{...props}
/>
)
DialogFooter.displayName = "DialogFooter"
DialogFooter.displayName = 'DialogFooter'

const DialogTitle = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Title>,
Expand All @@ -88,8 +86,8 @@ const DialogTitle = React.forwardRef<
<DialogPrimitive.Title
ref={ref}
className={cn(
"text-lg font-semibold leading-none tracking-tight",
className
'text-lg font-semibold leading-none tracking-tight',
className,
)}
{...props}
/>
Expand All @@ -102,7 +100,7 @@ const DialogDescription = React.forwardRef<
>(({ className, ...props }, ref) => (
<DialogPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
className={cn('text-sm text-muted-foreground', className)}
{...props}
/>
))
Expand Down

0 comments on commit 19e3f49

Please sign in to comment.