|
1 | 1 | import type { Course } from "common/types"; |
2 | 2 | import { useEffect, useState } from "react"; |
3 | | -import { addMyCourse, getMyCoursesOverlapWith } from "~/api/course"; |
| 3 | +import { MdAddCircleOutline } from "react-icons/md"; |
| 4 | +import { MdRemoveCircleOutline } from "react-icons/md"; |
| 5 | +import { |
| 6 | + addMyCourse, |
| 7 | + deleteMyCourse, |
| 8 | + getMyCoursesOverlapWith, |
| 9 | +} from "~/api/course"; |
4 | 10 |
|
5 | 11 | export default function CourseRegisterConfirmDialog({ |
6 | 12 | open, |
7 | 13 | onClose, |
8 | | - course, |
| 14 | + mode, |
| 15 | + courseToAddOrDelete, |
9 | 16 | handleSelectDialogClose, |
10 | 17 | handleCoursesUpdate, |
11 | 18 | }: { |
12 | 19 | open: boolean; |
13 | 20 | onClose: () => void; |
14 | | - course: Course | null; |
| 21 | + mode: "add" | "delete"; |
| 22 | + courseToAddOrDelete: Course; |
15 | 23 | handleSelectDialogClose: () => void; |
16 | 24 | handleCoursesUpdate: (courses: Course[]) => void; |
17 | 25 | }) { |
18 | 26 | const [overlapCourses, setOverlapCourses] = useState<Course[]>([]); |
19 | 27 | const [isLoading, setIsLoading] = useState(false); |
20 | 28 |
|
21 | 29 | useEffect(() => { |
22 | | - if (!course) return; |
23 | | - |
| 30 | + if (!courseToAddOrDelete) return; |
24 | 31 | setIsLoading(true); |
25 | 32 | setOverlapCourses([]); |
26 | | - |
27 | 33 | (async () => { |
28 | | - const courses = await getMyCoursesOverlapWith(course.id); |
| 34 | + const courses = await getMyCoursesOverlapWith(courseToAddOrDelete.id); |
29 | 35 | setOverlapCourses(courses); |
30 | 36 | setIsLoading(false); |
31 | 37 | })(); |
32 | | - }, [course]); |
| 38 | + }, [courseToAddOrDelete]); |
| 39 | + |
| 40 | + const coursesToBeDeletedString = overlapCourses |
| 41 | + .map((overlapCourse) => `${overlapCourse.name} (${overlapCourse.teacher})`) |
| 42 | + .join("・"); |
33 | 43 |
|
34 | 44 | return ( |
35 | 45 | <div className={`modal ${open ? "modal-open" : ""}`}> |
36 | 46 | <div className="modal-box"> |
37 | | - <h3 className="font-bold text-lg">変更の確認</h3> |
38 | | - <p className="py-4">次のように変更します。よろしいですか?</p> |
| 47 | + <h3 className="font-bold text-lg"> |
| 48 | + {mode === "add" ? "変更" : "削除"}の確認 |
| 49 | + </h3> |
| 50 | + <p className="py-4"> |
| 51 | + {mode === "add" ? "次のように変更" : "次の授業を削除"} |
| 52 | + します。よろしいですか? |
| 53 | + </p> |
39 | 54 | <div className="mt-2 space-y-2"> |
40 | | - {course && ( |
41 | | - <div className="alert alert-success"> |
42 | | - {`追加: ${course.name} (${course.teacher})`} |
| 55 | + {courseToAddOrDelete && mode === "add" ? ( |
| 56 | + <div className="bg-green-100 px-4 py-2"> |
| 57 | + <div className="flex items-center text-gray-500"> |
| 58 | + <MdAddCircleOutline /> |
| 59 | + <span>追加</span> |
| 60 | + </div> |
| 61 | + <p className="text-md">{`${courseToAddOrDelete.name} (${courseToAddOrDelete.teacher})`}</p> |
| 62 | + </div> |
| 63 | + ) : ( |
| 64 | + <div className="bg-red-100 px-4 py-2"> |
| 65 | + <div className="flex items-center text-gray-500"> |
| 66 | + <MdRemoveCircleOutline /> |
| 67 | + <span>削除</span> |
| 68 | + </div> |
| 69 | + <p className="text-md">{`${courseToAddOrDelete.name} (${courseToAddOrDelete.teacher})`}</p> |
43 | 70 | </div> |
44 | 71 | )} |
45 | 72 | {isLoading ? ( |
46 | 73 | <div className="alert alert-info">読み込み中...</div> |
47 | 74 | ) : ( |
48 | | - <div className="alert alert-error"> |
49 | | - {`削除: ${ |
50 | | - overlapCourses |
51 | | - .map( |
52 | | - (overlapCourse) => |
53 | | - `${overlapCourse.name} (${overlapCourse.teacher})`, |
54 | | - ) |
55 | | - .join("・") || "なし" |
56 | | - }`} |
57 | | - </div> |
| 75 | + mode === "add" && |
| 76 | + coursesToBeDeletedString && ( |
| 77 | + <div className="bg-red-100 px-4 py-2"> |
| 78 | + <div className="flex items-center text-gray-500"> |
| 79 | + <MdRemoveCircleOutline /> |
| 80 | + <span>削除</span> |
| 81 | + </div> |
| 82 | + <p className="text-md">{coursesToBeDeletedString}</p> |
| 83 | + </div> |
| 84 | + ) |
58 | 85 | )} |
59 | 86 | </div> |
60 | 87 | <div className="modal-action"> |
61 | 88 | {/* biome-ignore lint/a11y/useButtonType: <explanation> */} |
62 | 89 | <button className="btn btn-ghost" onClick={onClose}> |
63 | 90 | キャンセル |
64 | 91 | </button> |
65 | | - {course && ( |
| 92 | + {courseToAddOrDelete && ( |
66 | 93 | // biome-ignore lint/a11y/useButtonType: <explanation> |
67 | 94 | <button |
68 | 95 | className="btn btn-primary" |
69 | 96 | onClick={async () => { |
70 | | - const newCourses = await addMyCourse(course.id); |
71 | | - handleCoursesUpdate(newCourses); |
| 97 | + if (mode === "add") { |
| 98 | + const newCourses = await addMyCourse(courseToAddOrDelete.id); |
| 99 | + handleCoursesUpdate(newCourses); |
| 100 | + } else { |
| 101 | + const newCourses = await deleteMyCourse( |
| 102 | + courseToAddOrDelete.id, |
| 103 | + ); |
| 104 | + handleCoursesUpdate(newCourses); |
| 105 | + } |
72 | 106 | onClose(); |
73 | 107 | handleSelectDialogClose(); |
74 | 108 | }} |
|
0 commit comments