| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- 'use client';
- import './style.scss';
- import { useState, useCallback, useRef } from 'react';
- import Loading from '@/app/component/Loading';
- import { Button } from '@/components/ui/button';
- import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
- import { fetchApi } from '@/lib/utils/client';
- import { ReportTypeLabels } from '@/constants/forum';
- type Props = {
- isEnable: boolean;
- open: boolean;
- onChange: (_: boolean) => void;
- onComplete: (_: boolean) => void;
- postID: number;
- commentID?: number;
- memberID?: number;
- }
- export default function Report({ isEnable, open, onChange, onComplete, postID, commentID, memberID }: Props)
- {
- const [loading, setLoading] = useState<boolean>(false);
- const [form, setForm] = useState<{
- type: string;
- reason: string;
- }>({
- type: '',
- reason: ''
- });
- const typeRef = useRef<HTMLSelectElement>(null);
- const reasonRef = useRef<HTMLTextAreaElement>(null);
- const handleChange = useCallback((e: React.ChangeEvent<HTMLSelectElement|HTMLTextAreaElement>) => {
- const { name, value } = e.target;
- setForm((prev) => ({
- ...prev,
- [name]: value
- }));
- }, []);
- const handleSubmit = useCallback(async () => {
- if (!form.type) {
- alert('신고 유형을 선택하세요.');
- typeRef.current?.focus();
- return;
- }
- if (!form.reason) {
- alert('신고 내용을 입력해주세요.');
- reasonRef.current?.focus();
- return;
- }
- if (!memberID) {
- alert('로그인 후 이용해주세요.');
- return;
- }
- setLoading(true);
- onChange(false);
- try {
- const url = commentID
- ? '/api/forum/comments/' + commentID + '/report'
- : '/api/forum/posts/' + postID + '/report';
- const res = await fetchApi(url, {
- method: 'POST',
- body: { type: Number(form.type), reason: form.reason }
- });
- if (res.success) {
- alert('신고가 접수되었습니다.');
- setForm({ type: '', reason: '' });
- onComplete(true);
- } else {
- }
- } catch (err) {
- if (err instanceof Error) {
- alert(err.message);
- }
- } finally {
- setLoading(false);
- }
- }, [form, postID, commentID, memberID, onChange, onComplete]);
- if (!isEnable) {
- return null;
- }
- return (
- <>
- {loading && <Loading />}
- <Dialog open={open} onOpenChange={onChange}>
- <DialogContent className='w-3xs sm:max-w-md'>
- <DialogHeader>
- <DialogTitle>{commentID ? '댓글 신고' : '게시글 신고'}</DialogTitle>
- </DialogHeader>
- <div id='report' className='flex flex-col items-center gap-4'>
- <select ref={typeRef} name='type' value={form.type} title='신고 유형' onChange={handleChange}>
- {Object.entries(ReportTypeLabels).map(([key, label]) => (
- <option key={key} value={key}>
- {label}
- </option>
- ))}
- </select>
- <textarea ref={reasonRef} name='reason' rows={4} value={form.reason} title='신고 내용' onChange={handleChange} maxLength={500} placeholder='신고 내용을 구체적으로 입력해주세요.(500자 이하)'></textarea>
- <Button type='button' variant='outline' className='hover:bg-[#E07D0A] hover:text-white hover:border-[#b96606] sm:w-24' onClick={handleSubmit}>
- 신고하기
- </Button>
- </div>
- </DialogContent>
- </Dialog>
- </>
- );
- }
|