'use client';
import Button from '@/components/Button';
import Input from '@/components/Input';
import { useCategories, useTags } from '@/utils/hooks';
import axios from 'axios';
import hljs from 'highlight.js';
import { useSession } from 'next-auth/react';
import dynamic from 'next/dynamic';
import { useRouter } from 'next/navigation';
import { FormEvent, useRef, useState } from 'react';
import { MultiValue } from 'react-select';
import ReactSelect from 'react-select/creatable';
import { toast } from 'react-toastify';
const QuillEidtor = dynamic(
async () => {
hljs.configure({
languages: ['javascript', 'CSS', 'HTML'],
});
// @ts-ignore
window.hljs = hljs;
return await import('@/components/QuillEditor');
},
{
ssr: false,
}
);
export default function Page() {
const { data: session } = useSession();
const router = useRouter();
const titleRef = useRef<HTMLInputElement>(null);
const fileRef = useRef<HTMLInputElement>(null);
const { data: existingCategories } = useCategories();
const { data: existingTags } = useTags();
const [category, setCategory] = useState('');
const [tags, setTags] = useState<{ label: string; value: string }[]>([]);
const [content, setContent] = useState('');
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (!titleRef.current?.value || titleRef.current.value.length === 0)
return toast.error('제목을 입력해주세요.');
if (category.length === 0) return toast.error('카테고리를 입력해주세요.');
if (tags.length === 0) return toast.error('태그를 입력해주세요.');
if (content.length === 0) return toast.error('글 내용을 입력해주세요.');
const tagsValue = JSON.stringify(tags.map((tag) => tag.value));
const formData = new FormData();
formData.append('userId', session?.user.id!);
formData.append('title', titleRef.current?.value);
formData.append('category', category);
formData.append('tags', tagsValue);
formData.append('content', content);
if (fileRef.current?.files?.[0]) {
formData.append('previewImage', fileRef.current.files[0]);
}
try {
const response = await axios.post('/api/posts', formData, {
headers: {
'Content-Type': 'multipart/form-data', // FormData를 사용할 때 필요한 헤더
},
});
if (response.status === 201) {
toast.success(response.data.message);
router.push(`/posts/${response.data.postId}`);
} else {
toast.error('글 작성에 실패했습니다.');
}
} catch (error) {
console.error('Post creation failed:', error);
toast.error('글 작성 중 에러가 발생했습니다.');
}
};
return (
<div className="container z-10 flex flex-col gap-6 pb-20 pt-12">
<h1 className="mb-8 text-2xl font-medium">새로운 글</h1>
<form onSubmit={handleSubmit}>
<div className="flex flex-col gap-3 text-black">
<Input type="text" placeholder="제목" ref={titleRef} />
<Input
type="file"
accept="image/*"
ref={fileRef}
className="bg-white"
/>
<ReactSelect
options={(existingCategories ?? []).map((category) => ({
label: category,
value: category,
}))}
placeholder="카테고리"
instanceId="categories"
onChange={(e) => e && setCategory(e?.value)}
isMulti={false}
/>
<ReactSelect
options={(existingTags ?? []).map((tag) => ({
label: tag,
value: tag,
}))}
placeholder="태그"
instanceId="tags"
value={tags}
onChange={(
selectedOptions: MultiValue<{ label: string; value: string }>
) => {
setTags([...selectedOptions]);
}}
isMulti
/>
<QuillEidtor content={content} setContent={setContent} />
</div>
<Button type="submit" className="mt-4">
작성하기
</Button>
</form>
</div>
);
}