feat: QuizsetWrite 카드 삭제기능 추가
This commit is contained in:
parent
f14a7c2095
commit
4c958a68d9
@ -13,26 +13,26 @@ export default function LectureLayout() {
|
||||
const { lectureId } = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { lectureDelete } = useLectureDelete();
|
||||
const { data } = useLectureInfo(lectureId);
|
||||
const lecture = data?.data;
|
||||
const userType = useBoundStore((state) => state.userType);
|
||||
const handleDelete = () => {
|
||||
lectureDelete(lectureId);
|
||||
navigate('..');
|
||||
};
|
||||
const lectureData = {
|
||||
title: lecture.title,
|
||||
description: lecture.description,
|
||||
plan: lecture.plan,
|
||||
startDate: lecture.startDate,
|
||||
endDate: lecture.endDate,
|
||||
time: lecture.time,
|
||||
};
|
||||
console.log(lectureData);
|
||||
// const { lectureDelete } = useLectureDelete();
|
||||
// const { data } = useLectureInfo(lectureId);
|
||||
// const lecture = data?.data;
|
||||
// const userType = useBoundStore((state) => state.userType);
|
||||
// const handleDelete = () => {
|
||||
// lectureDelete(lectureId);
|
||||
// navigate('..');
|
||||
// };
|
||||
// const lectureData = {
|
||||
// title: lecture.title,
|
||||
// description: lecture.description,
|
||||
// plan: lecture.plan,
|
||||
// startDate: lecture.startDate,
|
||||
// endDate: lecture.endDate,
|
||||
// time: lecture.time,
|
||||
// };
|
||||
// console.log(lectureData);
|
||||
return (
|
||||
<>
|
||||
<LectureHeader
|
||||
{/* <LectureHeader
|
||||
title={lecture.title}
|
||||
tutor={lecture.teacherName}
|
||||
img={lecture.image}
|
||||
@ -80,13 +80,13 @@ export default function LectureLayout() {
|
||||
/>
|
||||
</SideBar>
|
||||
)}
|
||||
</aside>
|
||||
</aside> */}
|
||||
<main>
|
||||
<Suspense fallback={<LoadingIndicator fill />}>
|
||||
<Outlet />
|
||||
</Suspense>
|
||||
</main>
|
||||
</MaxWidthLayout>
|
||||
{/* </MaxWidthLayout> */}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,15 +1,18 @@
|
||||
import { useState } from 'react';
|
||||
import styles from './QuizCard.module.css';
|
||||
|
||||
export default function QuizCard({ quiz, index, updateQuiz, updateImage, deleteQuiz }) {
|
||||
export default function QuizCard({ quiz, updateQuiz, deleteQuiz }) {
|
||||
const [question, setQuestion] = useState(quiz.question || '');
|
||||
const [answer, setAnswer] = useState(quiz.answer || '');
|
||||
const [choices, setChoices] = useState(quiz.choices || []);
|
||||
const [imageFile, setImageFile] = useState(quiz.imageFile || null);
|
||||
|
||||
const handleChoiceChange = (num, content) => {
|
||||
const updatedChoices = choices.map((choice) => (choice.num === num ? { ...choice, content } : choice));
|
||||
const updatedChoices = choices.map((choice) =>
|
||||
choice.num === num ? { ...choice, content } : choice
|
||||
);
|
||||
setChoices(updatedChoices);
|
||||
updateQuiz(index, { question, answer, choices: updatedChoices });
|
||||
updateQuiz(quiz.id, { ...quiz, question, answer, choices: updatedChoices, imageFile });
|
||||
};
|
||||
|
||||
const handleAddChoice = () => {
|
||||
@ -17,7 +20,7 @@ export default function QuizCard({ quiz, index, updateQuiz, updateImage, deleteQ
|
||||
const newChoice = { num: choices.length + 1, content: '' };
|
||||
const updatedChoices = [...choices, newChoice];
|
||||
setChoices(updatedChoices);
|
||||
updateQuiz(index, { question, answer, choices: updatedChoices });
|
||||
updateQuiz(quiz.id, { ...quiz, question, answer, choices: updatedChoices, imageFile });
|
||||
}
|
||||
};
|
||||
|
||||
@ -25,20 +28,21 @@ export default function QuizCard({ quiz, index, updateQuiz, updateImage, deleteQ
|
||||
if (choices.length > 0) {
|
||||
const updatedChoices = choices.slice(0, -1);
|
||||
setChoices(updatedChoices);
|
||||
updateQuiz(index, { question, answer, choices: updatedChoices });
|
||||
updateQuiz(quiz.id, { ...quiz, question, answer, choices: updatedChoices, imageFile });
|
||||
}
|
||||
};
|
||||
|
||||
const handleFileChange = (e) => {
|
||||
const file = e.target.files[0] ?? null;
|
||||
updateImage(index, file);
|
||||
setImageFile(file);
|
||||
updateQuiz(quiz.id, { ...quiz, question, answer, choices, imageFile: file });
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.card}>
|
||||
<div className={styles.header}>
|
||||
<span>퀴즈 생성 카드</span>
|
||||
<span onClick={() => deleteQuiz(index)}>X</span>
|
||||
<span onClick={() => deleteQuiz(quiz.id)}>X</span> {/* id를 기반으로 삭제 */}
|
||||
</div>
|
||||
<label>질문</label>
|
||||
<input
|
||||
@ -46,7 +50,7 @@ export default function QuizCard({ quiz, index, updateQuiz, updateImage, deleteQ
|
||||
value={question}
|
||||
onChange={(e) => {
|
||||
setQuestion(e.target.value);
|
||||
updateQuiz(index, { question: e.target.value, answer, choices });
|
||||
updateQuiz(quiz.id, { ...quiz, question: e.target.value, answer, choices, imageFile });
|
||||
}}
|
||||
placeholder="질문 내용을 입력하세요"
|
||||
/>
|
||||
@ -56,7 +60,7 @@ export default function QuizCard({ quiz, index, updateQuiz, updateImage, deleteQ
|
||||
value={answer}
|
||||
onChange={(e) => {
|
||||
setAnswer(e.target.value);
|
||||
updateQuiz(index, { question, answer: e.target.value, choices });
|
||||
updateQuiz(quiz.id, { ...quiz, question, answer: e.target.value, choices, imageFile });
|
||||
}}
|
||||
placeholder="정답을 입력하세요"
|
||||
/>
|
||||
@ -64,18 +68,10 @@ export default function QuizCard({ quiz, index, updateQuiz, updateImage, deleteQ
|
||||
<span>Tip: 선택지를 넣지 않는다면 단답형 문제가 됩니다</span>
|
||||
</div>
|
||||
<div className={styles.buttonsWrapper}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleAddChoice}
|
||||
className={styles.button}
|
||||
>
|
||||
<button type="button" onClick={handleAddChoice} className={styles.button}>
|
||||
선택지 추가하기
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={handlePopChoice}
|
||||
className={styles.removeButton}
|
||||
>
|
||||
<button type="button" onClick={handlePopChoice} className={styles.removeButton}>
|
||||
선택지 줄이기
|
||||
</button>
|
||||
</div>
|
||||
@ -91,11 +87,7 @@ export default function QuizCard({ quiz, index, updateQuiz, updateImage, deleteQ
|
||||
</div>
|
||||
))}
|
||||
<label>퀴즈 이미지</label>
|
||||
<input
|
||||
type="file"
|
||||
accept=".png, .jpg, .jpeg"
|
||||
onChange={handleFileChange}
|
||||
/>
|
||||
<input type="file" accept=".png, .jpg, .jpeg" onChange={handleFileChange} />
|
||||
</div>
|
||||
);
|
||||
}
|
@ -8,37 +8,31 @@ import { Link } from 'react-router-dom';
|
||||
export default function QuizsetForm({ headerTitle, topic, to, onSubmit }) {
|
||||
const [title, setTitle] = useState('');
|
||||
const [quizzes, setQuizzes] = useState([]);
|
||||
const [images, setImages] = useState([]);
|
||||
const [quizId, setQuizId] = useState(0);
|
||||
|
||||
const handleAddQuiz = () => {
|
||||
setQuizzes([...quizzes, { question: '', answer: '', choices: [] }]);
|
||||
setImages([...images, null]);
|
||||
setQuizzes([
|
||||
...quizzes,
|
||||
{ id: quizId, question: '', answer: '', choices: [], imageFile: null },
|
||||
]);
|
||||
setQuizId(quizId + 1);
|
||||
};
|
||||
|
||||
const updateQuiz = (index, updatedQuiz) => {
|
||||
const updatedQuizzes = quizzes.map((quiz, idx) => (idx === index ? updatedQuiz : quiz));
|
||||
const updateQuiz = (id, updatedQuiz) => {
|
||||
const updatedQuizzes = quizzes.map((quiz) =>
|
||||
quiz.id === id ? updatedQuiz : quiz
|
||||
);
|
||||
setQuizzes(updatedQuizzes);
|
||||
};
|
||||
|
||||
const updateImage = (index, imageFile) => {
|
||||
const updatedImages = images.map((img, idx) => (idx === index ? imageFile : img));
|
||||
setImages(updatedImages);
|
||||
};
|
||||
|
||||
const deleteQuiz = (index) => {
|
||||
console.log(index);
|
||||
setQuizzes(quizzes.filter((_, idx) => idx !== index));
|
||||
setImages(images.filter((_, idx) => idx !== index));
|
||||
console.log(quizzes);
|
||||
const deleteQuiz = (id) => {
|
||||
setQuizzes(quizzes.filter((quiz) => quiz.id !== id));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.quizsetForm}>
|
||||
<header className={styles.header}>
|
||||
<Link
|
||||
to={to}
|
||||
className={styles.goBack}
|
||||
>
|
||||
<Link to={to} className={styles.goBack}>
|
||||
<BackIcon />
|
||||
<span>{headerTitle}</span>
|
||||
</Link>
|
||||
@ -46,7 +40,7 @@ export default function QuizsetForm({ headerTitle, topic, to, onSubmit }) {
|
||||
</header>
|
||||
<form
|
||||
className={styles.form}
|
||||
onSubmit={(e) => onSubmit(e, title, quizzes, images)}
|
||||
onSubmit={(e) => onSubmit(e, title, quizzes)}
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
@ -54,13 +48,11 @@ export default function QuizsetForm({ headerTitle, topic, to, onSubmit }) {
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
placeholder="퀴즈셋 제목을 입력해주세요"
|
||||
/>
|
||||
{quizzes.map((quiz, index) => (
|
||||
{quizzes.map((quiz) => (
|
||||
<QuizCard
|
||||
key={index}
|
||||
key={quiz.id}
|
||||
quiz={quiz}
|
||||
index={index}
|
||||
updateQuiz={updateQuiz}
|
||||
updateImage={updateImage}
|
||||
deleteQuiz={deleteQuiz}
|
||||
/>
|
||||
))}
|
||||
@ -71,10 +63,7 @@ export default function QuizsetForm({ headerTitle, topic, to, onSubmit }) {
|
||||
>
|
||||
퀴즈 추가하기
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
className={styles.button}
|
||||
>
|
||||
<button type="submit" className={styles.button}>
|
||||
<EditIcon />
|
||||
<div>제출</div>
|
||||
</button>
|
||||
|
@ -5,28 +5,43 @@ import { useNavigate } from 'react-router-dom';
|
||||
export default function QuizsetWritePage() {
|
||||
const navigate = useNavigate();
|
||||
const { quizsetWrite } = useQuizsetWrite();
|
||||
const handleSubmit = async (e, title, quizzes, images = []) => {
|
||||
|
||||
const handleSubmit = async (e, title, quizzes) => {
|
||||
e.preventDefault();
|
||||
console.log(quizzes)
|
||||
|
||||
const images = [];
|
||||
const quizContents = [];
|
||||
|
||||
quizzes.forEach((quiz) => {
|
||||
const { imageFile, ...quizData } = quiz;
|
||||
images.push(imageFile);
|
||||
quizContents.push(quizData);
|
||||
});
|
||||
|
||||
const quizsetObject = {
|
||||
title,
|
||||
quizzes,
|
||||
quizzes: quizContents,
|
||||
};
|
||||
console.log(quizsetObject);
|
||||
console.log(images);
|
||||
|
||||
const formData = new FormData();
|
||||
formData.append('quizSetCreateRequest', new Blob([JSON.stringify(quizsetObject)], { type: 'application/json' }));
|
||||
formData.append(
|
||||
'quizSetCreateRequest',
|
||||
new Blob([JSON.stringify(quizsetObject)], { type: 'application/json' })
|
||||
);
|
||||
|
||||
images.forEach((imageFile) => {
|
||||
if (imageFile) {
|
||||
formData.append('images', imageFile);
|
||||
} else {
|
||||
formData.append('images', new Blob(), { type: 'image/jpg' });
|
||||
formData.append('images', new Blob([''], { type: 'image/jpg' }));
|
||||
}
|
||||
});
|
||||
|
||||
await quizsetWrite(formData);
|
||||
navigate('..');
|
||||
};
|
||||
|
||||
return (
|
||||
<QuizsetForm
|
||||
onSubmit={handleSubmit}
|
||||
|
Loading…
Reference in New Issue
Block a user