feat: QuizsetWrite 카드 삭제기능 추가

This commit is contained in:
FF 2024-08-03 10:10:02 +09:00
parent f14a7c2095
commit 4c958a68d9
4 changed files with 77 additions and 81 deletions

View File

@ -13,26 +13,26 @@ export default function LectureLayout() {
const { lectureId } = useParams(); const { lectureId } = useParams();
const navigate = useNavigate(); const navigate = useNavigate();
const { lectureDelete } = useLectureDelete(); // const { lectureDelete } = useLectureDelete();
const { data } = useLectureInfo(lectureId); // const { data } = useLectureInfo(lectureId);
const lecture = data?.data; // const lecture = data?.data;
const userType = useBoundStore((state) => state.userType); // const userType = useBoundStore((state) => state.userType);
const handleDelete = () => { // const handleDelete = () => {
lectureDelete(lectureId); // lectureDelete(lectureId);
navigate('..'); // navigate('..');
}; // };
const lectureData = { // const lectureData = {
title: lecture.title, // title: lecture.title,
description: lecture.description, // description: lecture.description,
plan: lecture.plan, // plan: lecture.plan,
startDate: lecture.startDate, // startDate: lecture.startDate,
endDate: lecture.endDate, // endDate: lecture.endDate,
time: lecture.time, // time: lecture.time,
}; // };
console.log(lectureData); // console.log(lectureData);
return ( return (
<> <>
<LectureHeader {/* <LectureHeader
title={lecture.title} title={lecture.title}
tutor={lecture.teacherName} tutor={lecture.teacherName}
img={lecture.image} img={lecture.image}
@ -80,13 +80,13 @@ export default function LectureLayout() {
/> />
</SideBar> </SideBar>
)} )}
</aside> </aside> */}
<main> <main>
<Suspense fallback={<LoadingIndicator fill />}> <Suspense fallback={<LoadingIndicator fill />}>
<Outlet /> <Outlet />
</Suspense> </Suspense>
</main> </main>
</MaxWidthLayout> {/* </MaxWidthLayout> */}
</> </>
); );
} }

View File

@ -1,15 +1,18 @@
import { useState } from 'react'; import { useState } from 'react';
import styles from './QuizCard.module.css'; 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 [question, setQuestion] = useState(quiz.question || '');
const [answer, setAnswer] = useState(quiz.answer || ''); const [answer, setAnswer] = useState(quiz.answer || '');
const [choices, setChoices] = useState(quiz.choices || []); const [choices, setChoices] = useState(quiz.choices || []);
const [imageFile, setImageFile] = useState(quiz.imageFile || null);
const handleChoiceChange = (num, content) => { 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); setChoices(updatedChoices);
updateQuiz(index, { question, answer, choices: updatedChoices }); updateQuiz(quiz.id, { ...quiz, question, answer, choices: updatedChoices, imageFile });
}; };
const handleAddChoice = () => { const handleAddChoice = () => {
@ -17,7 +20,7 @@ export default function QuizCard({ quiz, index, updateQuiz, updateImage, deleteQ
const newChoice = { num: choices.length + 1, content: '' }; const newChoice = { num: choices.length + 1, content: '' };
const updatedChoices = [...choices, newChoice]; const updatedChoices = [...choices, newChoice];
setChoices(updatedChoices); 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) { if (choices.length > 0) {
const updatedChoices = choices.slice(0, -1); const updatedChoices = choices.slice(0, -1);
setChoices(updatedChoices); setChoices(updatedChoices);
updateQuiz(index, { question, answer, choices: updatedChoices }); updateQuiz(quiz.id, { ...quiz, question, answer, choices: updatedChoices, imageFile });
} }
}; };
const handleFileChange = (e) => { const handleFileChange = (e) => {
const file = e.target.files[0] ?? null; const file = e.target.files[0] ?? null;
updateImage(index, file); setImageFile(file);
updateQuiz(quiz.id, { ...quiz, question, answer, choices, imageFile: file });
}; };
return ( return (
<div className={styles.card}> <div className={styles.card}>
<div className={styles.header}> <div className={styles.header}>
<span>퀴즈 생성 카드</span> <span>퀴즈 생성 카드</span>
<span onClick={() => deleteQuiz(index)}>X</span> <span onClick={() => deleteQuiz(quiz.id)}>X</span> {/* id를 기반으로 삭제 */}
</div> </div>
<label>질문</label> <label>질문</label>
<input <input
@ -46,7 +50,7 @@ export default function QuizCard({ quiz, index, updateQuiz, updateImage, deleteQ
value={question} value={question}
onChange={(e) => { onChange={(e) => {
setQuestion(e.target.value); setQuestion(e.target.value);
updateQuiz(index, { question: e.target.value, answer, choices }); updateQuiz(quiz.id, { ...quiz, question: e.target.value, answer, choices, imageFile });
}} }}
placeholder="질문 내용을 입력하세요" placeholder="질문 내용을 입력하세요"
/> />
@ -56,7 +60,7 @@ export default function QuizCard({ quiz, index, updateQuiz, updateImage, deleteQ
value={answer} value={answer}
onChange={(e) => { onChange={(e) => {
setAnswer(e.target.value); setAnswer(e.target.value);
updateQuiz(index, { question, answer: e.target.value, choices }); updateQuiz(quiz.id, { ...quiz, question, answer: e.target.value, choices, imageFile });
}} }}
placeholder="정답을 입력하세요" placeholder="정답을 입력하세요"
/> />
@ -64,18 +68,10 @@ export default function QuizCard({ quiz, index, updateQuiz, updateImage, deleteQ
<span>Tip: 선택지를 넣지 않는다면 단답형 문제가 됩니다</span> <span>Tip: 선택지를 넣지 않는다면 단답형 문제가 됩니다</span>
</div> </div>
<div className={styles.buttonsWrapper}> <div className={styles.buttonsWrapper}>
<button <button type="button" onClick={handleAddChoice} className={styles.button}>
type="button"
onClick={handleAddChoice}
className={styles.button}
>
선택지 추가하기 선택지 추가하기
</button> </button>
<button <button type="button" onClick={handlePopChoice} className={styles.removeButton}>
type="button"
onClick={handlePopChoice}
className={styles.removeButton}
>
선택지 줄이기 선택지 줄이기
</button> </button>
</div> </div>
@ -91,11 +87,7 @@ export default function QuizCard({ quiz, index, updateQuiz, updateImage, deleteQ
</div> </div>
))} ))}
<label>퀴즈 이미지</label> <label>퀴즈 이미지</label>
<input <input type="file" accept=".png, .jpg, .jpeg" onChange={handleFileChange} />
type="file"
accept=".png, .jpg, .jpeg"
onChange={handleFileChange}
/>
</div> </div>
); );
} }

View File

@ -8,37 +8,31 @@ import { Link } from 'react-router-dom';
export default function QuizsetForm({ headerTitle, topic, to, onSubmit }) { export default function QuizsetForm({ headerTitle, topic, to, onSubmit }) {
const [title, setTitle] = useState(''); const [title, setTitle] = useState('');
const [quizzes, setQuizzes] = useState([]); const [quizzes, setQuizzes] = useState([]);
const [images, setImages] = useState([]); const [quizId, setQuizId] = useState(0);
const handleAddQuiz = () => { const handleAddQuiz = () => {
setQuizzes([...quizzes, { question: '', answer: '', choices: [] }]); setQuizzes([
setImages([...images, null]); ...quizzes,
{ id: quizId, question: '', answer: '', choices: [], imageFile: null },
]);
setQuizId(quizId + 1);
}; };
const updateQuiz = (index, updatedQuiz) => { const updateQuiz = (id, updatedQuiz) => {
const updatedQuizzes = quizzes.map((quiz, idx) => (idx === index ? updatedQuiz : quiz)); const updatedQuizzes = quizzes.map((quiz) =>
quiz.id === id ? updatedQuiz : quiz
);
setQuizzes(updatedQuizzes); setQuizzes(updatedQuizzes);
}; };
const updateImage = (index, imageFile) => { const deleteQuiz = (id) => {
const updatedImages = images.map((img, idx) => (idx === index ? imageFile : img)); setQuizzes(quizzes.filter((quiz) => quiz.id !== id));
setImages(updatedImages);
};
const deleteQuiz = (index) => {
console.log(index);
setQuizzes(quizzes.filter((_, idx) => idx !== index));
setImages(images.filter((_, idx) => idx !== index));
console.log(quizzes);
}; };
return ( return (
<div className={styles.quizsetForm}> <div className={styles.quizsetForm}>
<header className={styles.header}> <header className={styles.header}>
<Link <Link to={to} className={styles.goBack}>
to={to}
className={styles.goBack}
>
<BackIcon /> <BackIcon />
<span>{headerTitle}</span> <span>{headerTitle}</span>
</Link> </Link>
@ -46,7 +40,7 @@ export default function QuizsetForm({ headerTitle, topic, to, onSubmit }) {
</header> </header>
<form <form
className={styles.form} className={styles.form}
onSubmit={(e) => onSubmit(e, title, quizzes, images)} onSubmit={(e) => onSubmit(e, title, quizzes)}
> >
<input <input
type="text" type="text"
@ -54,13 +48,11 @@ export default function QuizsetForm({ headerTitle, topic, to, onSubmit }) {
onChange={(e) => setTitle(e.target.value)} onChange={(e) => setTitle(e.target.value)}
placeholder="퀴즈셋 제목을 입력해주세요" placeholder="퀴즈셋 제목을 입력해주세요"
/> />
{quizzes.map((quiz, index) => ( {quizzes.map((quiz) => (
<QuizCard <QuizCard
key={index} key={quiz.id}
quiz={quiz} quiz={quiz}
index={index}
updateQuiz={updateQuiz} updateQuiz={updateQuiz}
updateImage={updateImage}
deleteQuiz={deleteQuiz} deleteQuiz={deleteQuiz}
/> />
))} ))}
@ -71,10 +63,7 @@ export default function QuizsetForm({ headerTitle, topic, to, onSubmit }) {
> >
퀴즈 추가하기 퀴즈 추가하기
</button> </button>
<button <button type="submit" className={styles.button}>
type="submit"
className={styles.button}
>
<EditIcon /> <EditIcon />
<div>제출</div> <div>제출</div>
</button> </button>

View File

@ -5,28 +5,43 @@ import { useNavigate } from 'react-router-dom';
export default function QuizsetWritePage() { export default function QuizsetWritePage() {
const navigate = useNavigate(); const navigate = useNavigate();
const { quizsetWrite } = useQuizsetWrite(); const { quizsetWrite } = useQuizsetWrite();
const handleSubmit = async (e, title, quizzes, images = []) => {
const handleSubmit = async (e, title, quizzes) => {
e.preventDefault(); e.preventDefault();
console.log(quizzes)
const images = [];
const quizContents = [];
quizzes.forEach((quiz) => {
const { imageFile, ...quizData } = quiz;
images.push(imageFile);
quizContents.push(quizData);
});
const quizsetObject = { const quizsetObject = {
title, title,
quizzes, quizzes: quizContents,
}; };
console.log(quizsetObject);
console.log(images);
const formData = new FormData(); 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) => { images.forEach((imageFile) => {
if (imageFile) { if (imageFile) {
formData.append('images', imageFile); formData.append('images', imageFile);
} else { } else {
formData.append('images', new Blob(), { type: 'image/jpg' }); formData.append('images', new Blob([''], { type: 'image/jpg' }));
} }
}); });
await quizsetWrite(formData); await quizsetWrite(formData);
navigate('..'); navigate('..');
}; };
return ( return (
<QuizsetForm <QuizsetForm
onSubmit={handleSubmit} onSubmit={handleSubmit}