Skip to content

Commit

Permalink
✨ Feat(create-post): 게시글 작성 Form UI 추가
Browse files Browse the repository at this point in the history
- 활동 날짜, 게시글 입력은 추후에 추가

related to: #169
  • Loading branch information
ppochaco committed Aug 14, 2024
1 parent 33796af commit 0a3b425
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { kstFormat } from '@toss/date'

import { Button } from '@/components/ui/button'
import { DialogTrigger } from '@/components/ui/dialog'
import { FormControl } from '@/components/ui/form'

interface DateDialogTriggerButtonProps {
startDate?: Date
endDate?: Date
}

export const DateDialogTriggerButton = ({
startDate,
endDate,
}: DateDialogTriggerButtonProps) => {
return (
<DialogTrigger asChild>
<FormControl>
<Button variant="outline" className="flex w-full justify-start">
{startDate ? (
endDate ? (
<>
{kstFormat(startDate, 'yyyy.LL.dd')} -{' '}
{kstFormat(endDate, 'yyyy.LL.dd')}
</>
) : (
kstFormat(startDate, 'yyyy.LL.dd')
)
) : (
<span className="font-light text-muted-foreground">
활동 날짜를 선택해주세요
</span>
)}
</Button>
</FormControl>
</DialogTrigger>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
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 {
Dialog,
DialogContent,
DialogDescription,
DialogTitle,
DialogTrigger,
} from '@/components/ui/dialog'
import {
FormControl,
FormField,
FormItem,
FormMessage,
} from '@/components/ui/form'
import { CreatePost } from '@/schema/post'

import { DateDialogTriggerButton } from './DateDialogTriggerButton'

export const ActivityDateFieldDialog = () => {
const form = useFormContext<CreatePost>()

return (
<FormField
control={form.control}
name="activityDate"
render={({ field }) => (
<FormItem className="flex flex-col">
<div className="flex flex-col md:flex-row md:items-center">
<Label className="text-md w-40">활동 날짜</Label>
<div className="w-full">
<Dialog>
<DateDialogTriggerButton
startDate={field.value.start}
endDate={field.value.end}
/>
<DialogContent>
<DialogTitle>test</DialogTitle>
<DialogDescription>gg</DialogDescription>
</DialogContent>
</Dialog>
</div>
</div>
<div className="flex justify-end">
<FormMessage />
</div>
</FormItem>
)}
/>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use client'

import { useForm } from 'react-hook-form'

import { zodResolver } from '@hookform/resolvers/zod'

import { Button } from '@/components/ui/button'
import { Form } from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { Seperator } from '@/components/ui/seperator'
import { CreatePost, CreatePostSchema } from '@/schema/post'

import { ActivityFormField } from '~activity/_components/ActivityFormField'
import { ActivityImageInput } from '~activity/_components/ActivityImageInput'

import { ActivityDateFieldDialog } from './ActivityDateFieldDialog'

export const CreatePostForm = () => {
const form = useForm<CreatePost>({
resolver: zodResolver(CreatePostSchema),
defaultValues: {
postTitle: '',
postContent: '',
imageFile: new File([], ''),
activityDate: {
start: undefined,
end: undefined,
},
},
})

const onSubmit = (form: CreatePost) => {
console.log(form)
}

return (
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="flex flex-col gap-4"
>
<ActivityFormField name="postTitle" label="게시글 제목">
{(field) => <Input {...field} />}
</ActivityFormField>
<ActivityDateFieldDialog />
<Seperator />
<div>게시글 내용 작성하기</div>
<Seperator />
<ActivityFormField name="imageFile" label="게시글 대표 사진">
{(field) => <ActivityImageInput field={field} />}
</ActivityFormField>
<div className="flex justify-end">
<Button type="submit">게시글 업로드</Button>
</div>
</form>
</Form>
)
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { CreatePostForm } from './_components/CreatePostForm'
import { CreatePostHero } from './_components/CreatePostHero'

type CreatePostPageParams = {
Expand All @@ -14,6 +15,7 @@ const CreatePostPage = ({ params }: CreatePostPageParams) => {
activityId={Number(params.activityId)}
boardId={Number(params.boardId)}
/>
<CreatePostForm />
</div>
)
}
Expand Down
24 changes: 24 additions & 0 deletions src/schema/post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use client'

import { z } from 'zod'

export const CreatePostSchema = z.object({
postTitle: z
.string()
.min(1, { message: '게시글 제목을 입력해주세요.' })
.max(50, { message: '게시글 제목은 50자 이내이어야 합니다.' }),
postContent: z.string(),
imageFile: z.instanceof(File).refine((f) => f.size < 5000000, {
message: '이미지 파일 크기는 5MB 이하만 가능합니다.',
}),
activityDate: z
.object({
start: z.date().optional(),
end: z.date().optional(),
})
.refine((date) => {
return !!date.start
}, '활동 날짜를 선택해주세요.'),
})

export type CreatePost = z.infer<typeof CreatePostSchema>

0 comments on commit 0a3b425

Please sign in to comment.