Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue#5 post upload image #85

Merged
merged 5 commits into from
Jan 12, 2025
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
'use client'

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

import { Block } from '@blocknote/core'
import { zodResolver } from '@hookform/resolvers/zod'
import { useMutation } from '@tanstack/react-query'
import dynamic from 'next/dynamic'
import { usePathname, useRouter } from 'next/navigation'

import { PostContentFieldEditor } from '@/components/feature/post/create-post-form/editor'
import {
Button,
Form,
Expand All @@ -17,6 +19,7 @@ import {
Input,
Label,
Separator,
Skeleton,
useToast,
} from '@/components/ui'
import { queryClient } from '@/lib/query-client'
Expand All @@ -25,6 +28,14 @@ import { activityPostQuries, addActivityPostApi } from '@/service/api'

import { ActivityDateFieldDialog } from './date-field-dialog'

const PostContentFieldEditor = dynamic(
() => import('@/components/feature/post/post-editor/EditorField'),
{
ssr: false,
loading: () => <Skeleton className="h-[500px] w-full bg-slate-100" />,
},
)

interface CreateActivityPostFormProps {
boardId: number
}
Expand Down Expand Up @@ -52,6 +63,31 @@ export const CreateActivityPostForm = ({
},
})

const imageMapRef = useRef<Map<string, number>>(new Map())

const addImageId = (url: string, id: number) => {
imageMapRef.current.set(url, id)
}

const onSubmit = (values: CreateActivityPost) => {
const imageIds: number[] = []

JSON.parse(values.postContent)
.filter((block: Block) => block.type === 'image')
.forEach((block: Block) => {
if (block.type === 'image') {
const url = block.props.url.split('/').pop() ?? ''
const imageId = imageMapRef.current.get(url)

if (imageId) imageIds.push(imageId)
}
})

form.setValue('postImageIds', imageIds)

addActivityPost({ boardId, data: values })
}

const onSuccess = (message?: string) => {
toast({
title: message,
Expand All @@ -69,9 +105,7 @@ export const CreateActivityPostForm = ({
return (
<Form {...form}>
<form
onSubmit={form.handleSubmit((values) =>
addActivityPost({ boardId, data: values }),
)}
onSubmit={form.handleSubmit(onSubmit)}
className="flex flex-col gap-4"
>
<FormField
Expand All @@ -94,7 +128,9 @@ export const CreateActivityPostForm = ({
<ActivityDateFieldDialog />
<Separator />
<div>๊ฒŒ์‹œ๊ธ€ ๋‚ด์šฉ ์ž‘์„ฑํ•˜๊ธฐ</div>
<PostContentFieldEditor />
<PostContentFieldEditor
addImageId={(url: string, id: number) => addImageId(url, id)}
/>
<div className="flex justify-end">
<Button type="submit" disabled={isPending}>
๊ฒŒ์‹œ๊ธ€ ์—…๋กœ๋“œ
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { CreateBoardDetail } from './BoardDetail'
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@ import { useMutation } from '@tanstack/react-query'
import { AxiosError } from 'axios'
import { usePathname, useRouter } from 'next/navigation'

import {
PostFormField as BoardFormField,
ImageInput,
} from '@/components/feature'
import { ImageInput } from '@/components/feature'
import { Button, Form, Input, Textarea, useToast } from '@/components/ui'
import { queryClient } from '@/lib/query-client'
import { CreateBoard, CreateBoardSchema } from '@/schema/board'
import { addBoardApi, boardQueries } from '@/service/api'
import { UserResponseDto } from '@/service/models'

import { SelectMemberInput } from './SelectMemberInput'
import { BoardFormField } from './form-field'
import { SelectMemberInput } from './select-member-input'

type CreateBoardFromProps = {
activityId: number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ import {
Label,
} from '@/components/ui'

type PostFormFieldProps = {
type BoardFormFieldProps = {
name: string
label: string
children: (field: ControllerRenderProps) => ReactNode
}

export const PostFormField = ({
export const BoardFormField = ({
name,
label,
children,
}: PostFormFieldProps) => {
}: BoardFormFieldProps) => {
const form = useFormContext()

return (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { BoardFormField } from './FormField'
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Skeleton } from '@/components/ui'
import { UserQuries } from '@/service/api'
import { UserResponseDto } from '@/service/models'

import { MultipleMemberSelect } from './MultipleMemberSelect'
import { MultipleMemberSelect } from './multiple-member-select'

type SelectMemberInputProps = {
selectedMember: UserResponseDto[]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { SelectMemberInput } from './SelectMemberInput'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { MultipleMemberSelect } from './MultipleMemberSelect'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { CreateBoardHero } from './BoardHero'
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export { CreateBoardDetail } from './BoardDetail'
export { CreateBoardHero } from './BoardHero'
export { CreateBoardSkeleton } from './Skeleton'
export * from './hero'
export * from './detail'
export * from './form'
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

import { useQuery } from '@tanstack/react-query'

import { Spinner } from '@/components/common'
import { Separator, Skeleton } from '@/components/ui'
import { activityQueries, semesterQueries } from '@/service/api'
import { useMyInfoStore } from '@/store/myInfo'

import {
CreateBoardDetail,
CreateBoardForm,
CreateBoardHero,
CreateBoardSkeleton,
} from './_components'

type CreateBoardPageParams = {
Expand Down Expand Up @@ -60,3 +61,16 @@ const CreateBoardPage = ({ params }: CreateBoardPageParams) => {
}

export default CreateBoardPage

const CreateBoardSkeleton = () => {
return (
<div className="w-full pt-10">
<div>
<Separator variant="dark" />
<Skeleton className="my-4 h-5 w-full" />
<Separator variant="dark" />
</div>
<Spinner />
</div>
)
}
Comment on lines +64 to +76
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

skeleton์€ ๋กœ๋”ฉ์ค‘์ผ๋•Œ ๋ณด์—ฌ์ง€๋Š” ๋ถ€๋ถ„์ธ๊ฐ€์š”?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋„น

13 changes: 6 additions & 7 deletions src/app/(main)/event/board/create-post/_components/form/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useForm } from 'react-hook-form'

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

import { CreatePostForm } from '@/components/feature'
import { Form } from '@/components/ui'
import { CreateEventPost, CreateEventPostSchema } from '@/schema/post'

export const CreateEventPostForm = () => {
Expand All @@ -17,11 +17,10 @@ export const CreateEventPostForm = () => {
})

return (
<CreatePostForm
form={form}
onSubmit={() => {}}
isExecuting={false}
isImageRequired={false}
/>
<Form {...form}>
<form>
<div>temp form ui</div>
</form>
</Form>
Comment on lines +20 to +24
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

์—ฌ๊ธด ์ฝ”๋“œ๊ฐ€ ์ง€์›Œ์ง„๊ฒƒ ๊ฐ™๋„ค์š”...?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๋„ค~ ํ˜„์žฌ ๋ฐฑ์—”๋“œ api๋กœ ํ–‰์‚ฌ ๊ฒŒ์‹œ๊ธ€์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋กœ์ง์ด ์ œ๊ฑฐ๋˜์–ด, ์ถ”ํ›„์— ์ธ์Šคํƒ€ api ์—ฐ๊ฒฐํ•˜๋ฉด ์ถ”๊ฐ€ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค

)
}
91 changes: 83 additions & 8 deletions src/app/(main)/notice/create-post/_components/Form.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
'use client'

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

import { Block } from '@blocknote/core'
import { zodResolver } from '@hookform/resolvers/zod'
import { useMutation } from '@tanstack/react-query'
import dynamic from 'next/dynamic'
import { usePathname, useRouter } from 'next/navigation'

import { CreatePostForm } from '@/components/feature'
import { useToast } from '@/components/ui'
import {
Button,
Form,
FormControl,
FormField,
FormItem,
FormMessage,
Input,
Label,
Separator,
Skeleton,
useToast,
} from '@/components/ui'
import { queryClient } from '@/lib/query-client'
import { CreateNoticePost, CreateNoticePostSchema } from '@/schema/post'
import { NoticePostQuries, addNoticePostApi } from '@/service/api'

const PostContentFieldEditor = dynamic(
() => import('@/components/feature/post/post-editor/EditorField'),
{
ssr: false,
loading: () => <Skeleton className="h-[500px] w-full bg-slate-100" />,
},
)

export const CreateNoticePostForm = () => {
const { toast } = useToast()
const router = useRouter()
Expand All @@ -31,6 +53,31 @@ export const CreateNoticePostForm = () => {
},
})

const imageMapRef = useRef<Map<string, number>>(new Map())

const addImageId = (url: string, id: number) => {
imageMapRef.current.set(url, id)
}

const onSubmit = (values: CreateNoticePost) => {
const imageIds: number[] = []

JSON.parse(values.postContent)
.filter((block: Block) => block.type === 'image')
.forEach((block: Block) => {
if (block.type === 'image') {
const url = block.props.url.split('/').pop() ?? ''
const imageId = imageMapRef.current.get(url)

if (imageId) imageIds.push(imageId)
}
})

form.setValue('postImageIds', imageIds)

addNoticePost({ data: values })
}

const onSuccess = (message?: string) => {
toast({
title: message,
Expand All @@ -44,11 +91,39 @@ export const CreateNoticePostForm = () => {
}

return (
<CreatePostForm
form={form}
onSubmit={(values) => addNoticePost({ data: values })}
isExecuting={isPending}
isImageRequired={false}
/>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="flex flex-col gap-4"
>
<FormField
control={form.control}
name="postTitle"
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>
<FormControl>
<Input value={field.value} onChange={field.onChange} />
</FormControl>
</div>
<div className="flex justify-end">
<FormMessage />
</div>
</FormItem>
)}
/>
<Separator />
<div>๊ฒŒ์‹œ๊ธ€ ๋‚ด์šฉ ์ž‘์„ฑํ•˜๊ธฐ</div>
<PostContentFieldEditor
addImageId={(url: string, id: number) => addImageId(url, id)}
/>
<div className="flex justify-end">
<Button type="submit" disabled={isPending}>
๊ฒŒ์‹œ๊ธ€ ์—…๋กœ๋“œ
</Button>
</div>
</form>
</Form>
)
}
Loading
Loading