Skip to content

Commit 15883cc

Browse files
committed
fix(top): スケジュールに空き枠を表示する
1 parent 8402475 commit 15883cc

File tree

1 file changed

+29
-44
lines changed

1 file changed

+29
-44
lines changed

src/components/Articles.astro

+29-44
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
import dayjs from "dayjs";
3+
import { generate } from "../lib/schedule.ts";
34
import Article, { type ArticleProps } from "./Article.astro";
45
import ArticleBooked from "./ArticleBooked.astro";
56
import 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");
4413
type 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+
5234
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");
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

Comments
 (0)