timetable-app

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 4bf565a42227850ce39b6530fc0cc25b4d90a679
parent 8cc5f679a14c03431f3ad105d7a37f96f2eb9060
Author: Yuukin256 <Yuukin256@gmail.com>
Date:   Thu, 10 Nov 2022 01:04:03 +0900

時間割表示ページを修正

Diffstat:
Msrc/components/daily/DailyView.tsx | 18+++++++++---------
Dsrc/index.ts | 102-------------------------------------------------------------------------------
Msrc/pages/[class].tsx | 106+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/types/index.ts | 8++++----
Msrc/utils.ts | 6------
5 files changed, 68 insertions(+), 172 deletions(-)

diff --git a/src/components/daily/DailyView.tsx b/src/components/daily/DailyView.tsx @@ -44,19 +44,19 @@ const DailyView: FC<Props> = ({ calendar }) => { variant='outlined' sx={(theme) => ({ listStylePosition: 'inside', - [theme.breakpoints.up('xs')]: { p: 2, fontSize: 36 }, - [theme.breakpoints.up('sm')]: { py: 3, px: 5, fontSize: 48 }, + [theme.breakpoints.up('xs')]: { p: 2, fontSize: 32 }, + [theme.breakpoints.up('sm')]: { py: 3, px: 5, fontSize: 40 }, })} key={d} > <ol style={{ margin: 0, padding: 0 }}> - <li>{lessons[1]}</li> - <li>{lessons[2]}</li> - <li>{lessons[3]}</li> - <li>{lessons[4]}</li> - <li>{lessons[5]}</li> - <li>{lessons[6]}</li> - <li>{lessons[7]}</li> + <li>{lessons.period1.join('/')}</li> + <li>{lessons.period2.join('/')}</li> + <li>{lessons.period3.join('/')}</li> + <li>{lessons.period4.join('/')}</li> + <li>{lessons.period5.join('/')}</li> + <li>{lessons.period6.join('/')}</li> + <li>{lessons.period7.join('/')}</li> </ol> </Paper> ))} diff --git a/src/index.ts b/src/index.ts @@ -1,102 +0,0 @@ -// import { Temporal } from '@js-temporal/polyfill'; -// import { Map, merge } from 'immutable'; - -// import { isAbstractLessonName } from './utils'; - -// import type { Grade, Class, Calendar, StandardJa, Unusual } from './types'; - -// export const main = async (g: Grade, c: Class) => { -// console.log(g, c); - -// let calendar: Calendar = Map(); -// calendar = calendar.set(new Temporal.PlainDate(2022, 1, 26).toJSON(), { -// 1: '水1', -// 2: '水2', -// 3: '水5', -// 4: '水6', -// 5: '水3', -// 6: '水4', -// 7: '水7', -// }); - -// const standard: StandardJa = { -// 月1: '', -// 月2: '', -// 月3: '', -// 月4: '', -// 月5: '', -// 月6: '', -// 月7: '', -// 火1: '', -// 火2: '', -// 火3: '', -// 火4: '', -// 火5: '', -// 火6: '', -// 火7: '', -// 水1: '古典', -// 水2: '化学', -// 水3: '英語G', -// 水4: '数学Ⅰ', -// 水5: '書道', -// 水6: '体育', -// 水7: 'SD', -// 木1: '', -// 木2: '', -// 木3: '', -// 木4: '', -// 木5: '', -// 木6: '', -// 金1: '', -// 金2: '', -// 金3: '', -// 金4: '', -// 金5: '', -// 金6: '', -// 金7: '', -// }; -// let unusual: Unusual = Map(); -// unusual = unusual.set(new Temporal.PlainDate(2022, 1, 26).toJSON(), { 1: '数学A', 3: '古典' }); - -// const standardAppliedCalendar = applyStandard(calendar, standard); - -// return applyUnusual(standardAppliedCalendar, unusual); -// }; - -// const applyStandard = (calendar: Calendar, standard: StandardJa): Calendar => { -// // 標準時間割表のオブジェクトからから授業名を取り出す関数 -// const getActualLesson = (lessonName: string | null) => { -// if (lessonName !== null && isAbstractLessonName(lessonName)) { -// return standard[lessonName]; -// } else { -// return lessonName; -// } -// }; - -// return calendar.map((lessons) => ({ -// 1: getActualLesson(lessons[1]), -// 2: getActualLesson(lessons[2]), -// 3: getActualLesson(lessons[3]), -// 4: getActualLesson(lessons[4]), -// 5: getActualLesson(lessons[5]), -// 6: getActualLesson(lessons[6]), -// 7: getActualLesson(lessons[7]), -// })); -// }; - -// const applyUnusual = (calendar: Calendar, unusual: Unusual): Calendar => { -// return calendar.map((originalLessons, date) => { -// // この日の臨時時間割 -// const unusualLessons = unusual.find((_, k) => k === date); - -// // ない場合は終了 -// if (typeof unusualLessons === 'undefined') { -// return originalLessons; -// } - -// // merge して返す -// return merge(originalLessons, unusualLessons); -// }); -// }; - -export default {}; diff --git a/src/pages/[class].tsx b/src/pages/[class].tsx @@ -1,21 +1,23 @@ -import { Temporal } from '@js-temporal/polyfill'; +import format from 'date-fns/format'; import { Map } from 'immutable'; import Head from 'components/common/Head'; import DailyView from 'components/daily/DailyView'; import Layout from 'components/layouts/Layout'; - -import { CLASSES } from '../constant'; +import { CLASSES, DATE_FORMAT } from 'constant'; +import { prisma } from 'lib/prisma'; import type { GetStaticPaths, GetStaticProps, NextPage } from 'next'; -import type { Calendar } from 'types'; +import type { Calendar, DayLessons } from 'types'; type UrlQuery = { class: string; }; type PageProps = { - class: string; + grade: number; + class: number; + calendar: { [key: string]: DayLessons }; }; export const getStaticPaths: GetStaticPaths<UrlQuery> = async () => { @@ -28,65 +30,67 @@ export const getStaticPaths: GetStaticPaths<UrlQuery> = async () => { }; export const getStaticProps: GetStaticProps<PageProps, UrlQuery> = async ({ params }) => { - const className = params?.class; + if (typeof params === 'undefined') { + return { + notFound: true, + }; + } - if (className == null) { + const [gradeNum, classNum] = params.class.split('-').map((v) => parseInt(v)); + + if (typeof gradeNum === 'undefined' || typeof classNum === 'undefined' || isNaN(gradeNum) || isNaN(classNum)) { return { notFound: true, }; } + const [schoolClass, dayTimetables] = await Promise.all([ + prisma.schoolClass.findUnique({ + where: { grade_class: { grade: gradeNum, class: classNum } }, + select: { Standard: true, UnusualTimetableUnit: true }, + }), + prisma.dayTimetable.findMany({ where: { grade: gradeNum }, orderBy: { date: 'asc' } }), + ]); + + if (!schoolClass || !schoolClass.Standard) { + return { + props: { grade: gradeNum, class: classNum, calendar: {} }, + revalidate: 60 * 60, // 1時間毎の訪問で再生成 + }; + } + + const standard = schoolClass.Standard; + + // TODO: 臨時変更に対応 + const calendar: Calendar = Map( + dayTimetables.map((dayTimetable) => { + return [ + format(dayTimetable.date, DATE_FORMAT), + { + period1: dayTimetable.period1 ? standard[dayTimetable.period1] : [], + period2: dayTimetable.period2 ? standard[dayTimetable.period2] : [], + period3: dayTimetable.period3 ? standard[dayTimetable.period3] : [], + period4: dayTimetable.period4 ? standard[dayTimetable.period4] : [], + period5: dayTimetable.period5 ? standard[dayTimetable.period5] : [], + period6: dayTimetable.period6 ? standard[dayTimetable.period6] : [], + period7: dayTimetable.period7 ? standard[dayTimetable.period7] : [], + }, + ]; + }) + ); + return { - props: { class: className }, + props: { grade: gradeNum, class: classNum, calendar: calendar.toJSON() }, + revalidate: 60 * 60, // 1時間毎の訪問で再生成 }; }; const Page: NextPage<PageProps> = (props) => { - const calendar: Calendar = Map(); - const newCalendar = calendar - .set(new Temporal.PlainDate(2022, 8, 11).toJSON(), { - 1: '08/06', - 2: '英語構文', - 3: '倫理政経', - 4: '現代文', - 5: 'HR', - 6: '体育', - 7: '家庭科', - }) - .set(new Temporal.PlainDate(2022, 8, 23).toJSON(), { - 1: '数学II', - 2: '英語構文', - 3: '倫理政経', - 4: '現代文', - 5: 'HR', - 6: '体育', - 7: '家庭科', - }) - .set(new Temporal.PlainDate(2022, 8, 24).toJSON(), { - 1: '数学II', - 2: '英語構文', - 3: '倫理政経', - 4: '現代文', - 5: 'HR', - 6: '体育', - 7: '家庭科', - }) - .set(new Temporal.PlainDate(2022, 8, 21).toJSON(), { - 1: null, - 2: null, - 3: null, - 4: null, - 5: null, - 6: null, - 7: null, - }) - .sortBy((_, date) => Temporal.PlainDate.from(date), Temporal.PlainDate.compare); - return ( <> - <Head title={props.class} /> - <Layout title={props.class}> - {newCalendar.size ? <DailyView calendar={newCalendar} /> : <p>データがありません</p>} + <Head title={`${props.grade}-${props.class}`} /> + <Layout title={`${props.grade}-${props.class}`}> + {Object.keys(props.calendar).length ? <DailyView calendar={Map(props.calendar)} /> : <p>データがありません</p>} </Layout> </> ); diff --git a/src/types/index.ts b/src/types/index.ts @@ -7,24 +7,24 @@ export type Grade = 1 | 2 | 3; // クラス export type Class = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8; -type SchoolTime = 1 | 2 | 3 | 4 | 5 | 6 | 7; +type SchoolTime = `period${1 | 2 | 3 | 4 | 5 | 6 | 7}`; // 月1 から 金7 (木7 以外) export type AbstractLessonNameJa = typeof ABSTRACT_LESSON_NAMES_JA[number]; export type AbstractLessonNameEn = typeof ABSTRACT_LESSON_NAMES_EN[number]; // 授業名 -export type ActualLessonName = string; +export type ActualLessonName = string[]; export type LessonName = AbstractLessonNameJa | ActualLessonName; // 1日の授業 -export type DayLessons = Record<SchoolTime, LessonName | null>; +export type DayLessons = Record<SchoolTime, string[]>; // クラスの標準時間割 export type StandardJa = Readonly<Record<AbstractLessonNameJa, string[]>>; export type StandardEn = Readonly<Record<AbstractLessonNameEn, string[]>>; -// 曜日変更込みの時間割表 (月1, 月2,… など) または、授業名代入済みの時間割表 +// 授業名代入済みの時間割表 export type Calendar = Map<string, DayLessons>; // クラスの臨時変更 diff --git a/src/utils.ts b/src/utils.ts @@ -1,11 +1,5 @@ import { Temporal } from '@js-temporal/polyfill'; -import type { AbstractLessonNameJa } from 'types'; - -export const isAbstractLessonName = (value: string): value is AbstractLessonNameJa => { - return /((月|火|水|金)(1|2|3|4|5|6|7)|木(1|2|3|4|5|6))/.test(value); -}; - export const plainDateToDate = (date: Temporal.PlainDate | undefined) => (date ? new Date(date.toString()) : undefined); export const dateToPlainDate = (date: Date) => new Temporal.PlainDate(date.getFullYear(), date.getMonth() + 1, date.getDate());