From 51f2c1e8036e7ea0f4cacd70bbfb396b966bff40 Mon Sep 17 00:00:00 2001 From: "shinku: Shinku Takahashi" Date: Wed, 15 Jul 2026 07:41:28 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=E7=A7=91=E7=9B=AE=E6=A4=9C=E7=B4=A2?= =?UTF-8?q?=E7=B5=90=E6=9E=9C=E3=81=AB=E6=9B=9C=E6=97=A5=E3=83=BB=E6=99=82?= =?UTF-8?q?=E9=99=90=E3=82=92=E8=A1=A8=E7=A4=BA=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/subjects/SubjectsSearchView.tsx | 71 +++++++++++++++++++------ 1 file changed, 54 insertions(+), 17 deletions(-) diff --git a/src/app/subjects/SubjectsSearchView.tsx b/src/app/subjects/SubjectsSearchView.tsx index a8c83b4..5f1f9d4 100644 --- a/src/app/subjects/SubjectsSearchView.tsx +++ b/src/app/subjects/SubjectsSearchView.tsx @@ -44,6 +44,13 @@ const SEMESTER_LABEL: Record = { SummerIntensive: "夏季集中", WinterIntensive: "冬季集中", }; +const DAY_MAP: Record = { + Monday: "月", Tuesday: "火", Wednesday: "水", + Thursday: "木", Friday: "金", Saturday: "土", Sunday: "日", +}; + +const ALL_SEMESTERS = Object.values(TERM_MAP); + type Subject = components["schemas"]["SubjectSummary"]; function toggle(set: Set, value: string): Set { @@ -137,6 +144,7 @@ export default function SubjectsSearchView() { const [selectedGrades, setSelectedGrades] = useState>(new Set()); const [selectedClasses, setSelectedClasses] = useState>(new Set()); const [subjects, setSubjects] = useState([]); + const [slotMap, setSlotMap] = useState>(new Map()); const [isLoading, setIsLoading] = useState(false); const [hasError, setHasError] = useState(false); @@ -174,24 +182,49 @@ export default function SubjectsSearchView() { setIsLoading(true); setHasError(false); try { - const { data, error } = await api.GET("/v1/subjects", { - params: { - query: { - q: query || undefined, - semesters: mapSet(selectedTerms, TERM_MAP) as never, - requirementTypes: mapSet(selectedRequiredTypes, REQUIRED_TYPE_MAP) as never, - classifications: mapSet(selectedCategories, CATEGORY_MAP) as never, - courses: mapSet(selectedCourses, COURSE_MAP) as never, - grades: mapSet(selectedGrades, GRADE_MAP) as never, - classes: selectedClasses.size > 0 ? ([...selectedClasses] as never) : undefined, + const semesters = selectedTerms.size > 0 + ? mapSet(selectedTerms, TERM_MAP)! + : ALL_SEMESTERS; + + const [subjectsRes, timetableRes] = await Promise.all([ + api.GET("/v1/subjects", { + params: { + query: { + q: query || undefined, + semesters: mapSet(selectedTerms, TERM_MAP) as never, + requirementTypes: mapSet(selectedRequiredTypes, REQUIRED_TYPE_MAP) as never, + classifications: mapSet(selectedCategories, CATEGORY_MAP) as never, + courses: mapSet(selectedCourses, COURSE_MAP) as never, + grades: mapSet(selectedGrades, GRADE_MAP) as never, + classes: selectedClasses.size > 0 ? ([...selectedClasses] as never) : undefined, + }, }, - }, - signal: controller.signal, - }); - if (error || !data) { + signal: controller.signal, + }), + api.GET("/v1/timetableItems", { + params: { + query: { semesters: semesters as never }, + }, + signal: controller.signal, + }), + ]); + + if (subjectsRes.error || !subjectsRes.data) { setHasError(true); } else { - setSubjects(data.subjects); + setSubjects(subjectsRes.data.subjects); + } + + if (timetableRes.data) { + const map = new Map(); + for (const item of timetableRes.data.timetableItems) { + if (item.slot && !map.has(item.subject.id)) { + const day = DAY_MAP[item.slot.dayOfWeek] ?? ""; + const period = item.slot.period.replace("Period", ""); + map.set(item.subject.id, `${day}${period}`); + } + } + setSlotMap(map); } } catch { // abort によるキャンセルは無視する @@ -316,8 +349,12 @@ export default function SubjectsSearchView() {
  • {subject.name}

    -

    - {SEMESTER_LABEL[subject.semester] ?? subject.semester}・{subject.credit}単位 +

    + {[ + SEMESTER_LABEL[subject.semester] ?? subject.semester, + slotMap.get(subject.id), + `${subject.credit}単位`, + ].filter(Boolean).join(" ")}

    {facultyLabel && (

    {facultyLabel}

    From 66ec8f40e8acf75a36b2c4e40b686b13fd99e329 Mon Sep 17 00:00:00 2001 From: "shinku: Shinku Takahashi" Date: Wed, 15 Jul 2026 08:44:18 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=E5=90=8C=E3=81=98=E6=8E=88=E6=A5=AD?= =?UTF-8?q?=E3=81=8C=E9=80=B1=E3=81=AB=E8=A4=87=E6=95=B0=E5=9B=9E=E3=81=82?= =?UTF-8?q?=E3=82=8B=E5=A0=B4=E5=90=88=E3=81=AB=E3=80=81=E6=9B=9C=E6=97=A5?= =?UTF-8?q?=E3=83=BB=E6=99=82=E9=99=90=E3=82=92=E3=81=99=E3=81=B9=E3=81=A6?= =?UTF-8?q?=E8=A1=A8=E7=A4=BA=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/subjects/SubjectsSearchView.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/app/subjects/SubjectsSearchView.tsx b/src/app/subjects/SubjectsSearchView.tsx index 5f1f9d4..bc16129 100644 --- a/src/app/subjects/SubjectsSearchView.tsx +++ b/src/app/subjects/SubjectsSearchView.tsx @@ -144,7 +144,7 @@ export default function SubjectsSearchView() { const [selectedGrades, setSelectedGrades] = useState>(new Set()); const [selectedClasses, setSelectedClasses] = useState>(new Set()); const [subjects, setSubjects] = useState([]); - const [slotMap, setSlotMap] = useState>(new Map()); + const [slotMap, setSlotMap] = useState>(new Map()); const [isLoading, setIsLoading] = useState(false); const [hasError, setHasError] = useState(false); @@ -216,12 +216,18 @@ export default function SubjectsSearchView() { } if (timetableRes.data) { - const map = new Map(); + const map = new Map(); for (const item of timetableRes.data.timetableItems) { - if (item.slot && !map.has(item.subject.id)) { + if (item.slot) { const day = DAY_MAP[item.slot.dayOfWeek] ?? ""; const period = item.slot.period.replace("Period", ""); - map.set(item.subject.id, `${day}${period}`); + const label = `${day}${period}`; + const existing = map.get(item.subject.id); + if (existing) { + existing.push(label); + } else { + map.set(item.subject.id, [label]); + } } } setSlotMap(map); @@ -352,7 +358,7 @@ export default function SubjectsSearchView() {

    {[ SEMESTER_LABEL[subject.semester] ?? subject.semester, - slotMap.get(subject.id), + slotMap.get(subject.id)?.join(","), `${subject.credit}単位`, ].filter(Boolean).join(" ")}