1
1
---
2
2
import dayjs from " dayjs" ;
3
+ import { generate } from " ../lib/schedule.ts" ;
3
4
import Article , { type ArticleProps } from " ./Article.astro" ;
4
5
import ArticleBooked from " ./ArticleBooked.astro" ;
5
6
import ArticleSlot from " ./ArticleSlot.astro" ;
@@ -9,38 +10,6 @@ type Props = {
9
10
articles: Omit <ArticleProps , " firstDay" >[];
10
11
};
11
12
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" );
44
13
type ArticleEntry = {
45
14
state: " published" | " booked" ;
46
15
article: ArticleProps ;
@@ -49,34 +18,50 @@ type ArticleSlotEntry = {
49
18
state: " empty" ;
50
19
article: ArticleSlotProps ;
51
20
};
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
+
52
34
const 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" );
58
41
const article = Astro .props .articles .find (({ date }) => date === todayStr );
59
42
const entry: ArticleEntry | ArticleSlotEntry = article
60
43
? {
61
- state: today > dayjs () ? (" booked" as const ) : (" published" as const ),
44
+ state: date > dayjs () ? (" booked" as const ) : (" published" as const ),
62
45
article: {
63
46
... article ,
64
47
date: todayStr ,
65
- firstDay: today .month () !== yesterday .month (),
48
+ firstDay: prevDate === null || date .month () !== prevDate .month (),
66
49
},
67
50
}
68
51
: {
69
52
state: " empty" as const ,
70
53
article: {
71
54
date: todayStr ,
72
- firstDay: today .month () !== yesterday .month (),
73
- firstSlot ,
55
+ firstDay: prevDate === null || date .month () !== prevDate .month (),
56
+ firstSlot: slotCount == 0 ,
74
57
},
75
58
};
76
- firstSlot = firstSlot && entry .state !== " empty" ;
59
+ slotCount += entry .state === " empty" ? 1 : 0 ;
77
60
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
+ }
80
65
}
81
66
---
82
67
0 commit comments