Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | import { usePostQuestionMutation } from '@lib/api/mutations';
import QuillEditor from '@lib/components/QuillEditor';
import { Checkbox, Form, Input, InputNumber, Modal, ModalProps, message } from 'antd';
import { Delta, DeltaStatic } from 'quill';
import React from 'react';
import axios from 'axios';
declare global {
interface Window {
Quill: object;
}
}
interface CreateQuestionModalProps {
modalData: ModalProps;
closeModal: () => unknown;
}
export default function CreateQuestionModal({ modalData, closeModal }: CreateQuestionModalProps) {
const [content, setContent] = React.useState<Delta>();
const [hint, setHint] = React.useState<{ delta?: Delta; id: string }>();
const { mutateAsync } = usePostQuestionMutation();
const [form] = Form.useForm();
const handleClose = () => {
form.resetFields();
setContent(undefined);
setHint(undefined);
};
const handleOkClick = () => {
form.submit();
};
const handleFinish = async (values: {
title: string;
answer: string;
objectVideoUrl?: string;
isRandomAllowed: boolean;
questionHintDeductionPoint: string;
}) => {
const { title, answer, objectVideoUrl, isRandomAllowed, questionHintDeductionPoint } = values;
if (!hint) {
message.error('힌트를 작성해주세요.');
return;
}
try {
const data = await mutateAsync({
title,
content: JSON.stringify(content),
answer,
isQuestionHintAllowed: true,
createOrUpdateHint: {
content: JSON.stringify(hint.delta),
deductionScore: Number(questionHintDeductionPoint)
},
objectVideoUrl,
isRandomAllowed: isRandomAllowed || false
});
if (data.success) {
message.success('문제를 생성했습니다.');
closeModal();
}
} catch (e) {
if (axios.isAxiosError(e)) {
message.error(e.response?.data.message);
} else {
message.error('다시 시도해주세요.');
}
}
};
return (
<Modal
{...modalData}
title="문제 생성"
width={1000}
onOk={handleOkClick}
okText="확인"
cancelText="닫기"
afterClose={handleClose}
>
<Form
form={form}
onFinish={handleFinish}
labelCol={{ span: 24 }}
wrapperCol={{ span: 24 }}
// eslint-disable-next-line no-template-curly-in-string
validateMessages={{ required: '${label}은(는) 필수로 입력해주세요.' }}
>
<Form.Item name="title" label="문제" rules={[{ required: true }]}>
<Input placeholder="문제를 입력해주세요." />
</Form.Item>
<Form.Item name="description" label="문제 설명" rules={[{ required: true }]}>
<QuillEditor onChange={setContent} />
</Form.Item>
<Form.Item name="answer" label="정답" rules={[{ required: true }]}>
<Input placeholder="정답을 입력해주세요." />
</Form.Item>
<Form.Item name="objectVideoUrl" label="비디오 URL (선택)">
<Input placeholder="유튜브 URL을 입력해주세요." />
</Form.Item>
<Form.Item name="isRandomAllowed" valuePropName="checked">
<Checkbox>랜덤 배정 여부</Checkbox>
</Form.Item>
<Form.Item name="questionHint" label="문제 힌트" rules={[{ required: true }]}>
<QuillEditor
value={hint as unknown as DeltaStatic}
onChange={(delta) => {
setHint((prev) => ({ delta, id: prev?.id || '' }));
}}
/>
</Form.Item>
<Form.Item
name="questionHintDeductionPoint"
label="감점될 점수"
rules={[{ required: true }]}
>
<InputNumber placeholder="감점될 점수" controls={false} />
</Form.Item>
</Form>
</Modal>
);
}
|