11---
22import dayjs from " dayjs" ;
3+ import { generate } from " ../lib/schedule.ts" ;
34import Article , { type ArticleProps } from " ./Article.astro" ;
45import ArticleBooked from " ./ArticleBooked.astro" ;
56import ArticleSlot from " ./ArticleSlot.astro" ;
@@ -9,38 +10,6 @@ type Props = {
910 articles: Omit <ArticleProps , " firstDay" >[];
1011};
1112
12- /**
13- * トップページに表示する日付を生成する。
14- * 生成規則は以下の通り。
15- *
16- * 開始日: 現在の日付より1ヶ月前
17- * 毎週月曜日・水曜日・金曜日
18- */
19- let initialDay = dayjs ().subtract (1 , " M" );
20-
21- let diff: number ;
22-
23- const _initalDay = initialDay .day ();
24- switch (_initalDay ) {
25- case 0 :
26- case 2 :
27- case 4 :
28- diff = 1 ;
29- break ;
30- case 1 :
31- case 3 :
32- case 5 :
33- diff = 0 ;
34- break ;
35- case 6 :
36- diff = 2 ;
37- break ;
38- default :
39- /* _initalDay は never になるので、exhaustive になる */
40- return _initalDay satisfies never ;
41- }
42-
43- initialDay = initialDay .add (diff , " d" );
4413type ArticleEntry = {
4514 state: " published" | " booked" ;
4615 article: ArticleProps ;
@@ -49,34 +18,50 @@ type ArticleSlotEntry = {
4918 state: " empty" ;
5019 article: ArticleSlotProps ;
5120};
21+
22+ /**
23+ * 以下条件を満たすようにスケジュールを表示する
24+ *
25+ * - 月・水・金曜日のみ表示する
26+ * - 1ヶ月前からの日付を表示する
27+ * - 最低でも5つの空き枠を表示する
28+ * - 最低でも1ヶ月先までは表示する
29+ */
30+ const START_DATE = dayjs ().subtract (1 , " M" );
31+ const LEAST_SLOT_COUNT = 5 ;
32+ const LEAST_DATE = dayjs ().add (1 , " M" );
33+
5234const entries: (ArticleEntry | ArticleSlotEntry )[] = [];
53- let today = initialDay ;
54- let yesterday = initialDay .subtract (1 , " M" );
55- let firstSlot = true ;
56- while (initialDay .add (2 , " M" ) >= today ) {
57- const todayStr = today .format (" YYYY-MM-DD" );
35+ let prevDate: dayjs .Dayjs | null = null ;
36+ let slotCount = 0 ;
37+ for (const date of generate ({
38+ start: START_DATE ,
39+ })) {
40+ const todayStr = date .format (" YYYY-MM-DD" );
5841 const article = Astro .props .articles .find (({ date }) => date === todayStr );
5942 const entry: ArticleEntry | ArticleSlotEntry = article
6043 ? {
61- state: today > dayjs () ? (" booked" as const ) : (" published" as const ),
44+ state: date > dayjs () ? (" booked" as const ) : (" published" as const ),
6245 article: {
6346 ... article ,
6447 date: todayStr ,
65- firstDay: today .month () !== yesterday .month (),
48+ firstDay: prevDate === null || date .month () !== prevDate .month (),
6649 },
6750 }
6851 : {
6952 state: " empty" as const ,
7053 article: {
7154 date: todayStr ,
72- firstDay: today .month () !== yesterday .month (),
73- firstSlot ,
55+ firstDay: prevDate === null || date .month () !== prevDate .month (),
56+ firstSlot: slotCount == 0 ,
7457 },
7558 };
76- firstSlot = firstSlot && entry .state !== " empty" ;
59+ slotCount += entry .state === " empty" ? 1 : 0 ;
7760 entries .push (entry );
78- yesterday = today ;
79- today = today .add (today .day () >= 4 ? 3 : 2 , " d" );
61+ prevDate = date ;
62+ if (date >= LEAST_DATE && slotCount >= LEAST_SLOT_COUNT ) {
63+ break ;
64+ }
8065}
8166---
8267
0 commit comments