From 64b0f5e80f4bd3060b246834875cc39840a2fb81 Mon Sep 17 00:00:00 2001
From: julienrousseau
Date: Sat, 1 Mar 2025 23:32:15 -0500
Subject: [PATCH] added exception dates to calendar
---
packages/common/src/models/activities.ts | 27 +++++++++++--------
packages/web/src/components/Calendar.astro | 31 +++++++++++++++++++++-
packages/web/src/lib/formatters.ts | 2 ++
packages/web/src/pages/horaire.astro | 11 ++++++++
4 files changed, 59 insertions(+), 12 deletions(-)
diff --git a/packages/common/src/models/activities.ts b/packages/common/src/models/activities.ts
index ce9d5e4..2bcc2f8 100644
--- a/packages/common/src/models/activities.ts
+++ b/packages/common/src/models/activities.ts
@@ -1,16 +1,21 @@
import { z } from "zod";
-export const Time = z.object({ hour: z.number(), minute: z.number() })
+export const Time = z.object({ hour: z.number(), minute: z.number() });
export const Activity = z.object({
- type: z.number(),
- title: z.string(),
- subtitle: z.string().optional(),
- time: z.object({ start: Time, end: Time }),
- lessons: z.object({ count: z.number(), first: z.date(), last: z.date() }),
- price: z.number(),
- color: z.string()
-})
+ type: z.number(),
+ title: z.string(),
+ subtitle: z.string().optional(),
+ time: z.object({ start: Time, end: Time }),
+ lessons: z.object({
+ count: z.number(),
+ first: z.date(),
+ last: z.date(),
+ exceptions: z.array(z.date()),
+ }),
+ price: z.number(),
+ color: z.string(),
+});
-export type Time = z.infer
-export type Activity = z.infer
+export type Time = z.infer;
+export type Activity = z.infer;
diff --git a/packages/web/src/components/Calendar.astro b/packages/web/src/components/Calendar.astro
index 1d16a94..ed4df1a 100644
--- a/packages/web/src/components/Calendar.astro
+++ b/packages/web/src/components/Calendar.astro
@@ -2,7 +2,7 @@
import type { Activity, Time } from "common";
import { gcd } from "../lib/maths";
import { cn, dark, contrast } from "../lib/utils";
-import { dateFormatter } from "../lib/formatters";
+import { dateFormatter, listFormatter } from "../lib/formatters";
import { weekdays } from "../lib/constants";
interface Props {
@@ -209,6 +209,14 @@ function shiftWeekday(weekday: number) {
data-amount={activity.price.toFixed(2)}
data-lessons={activity.lessons.count}
data-weekday={weekdays[weekday]}
+ data-except-dates={listFormatter.format(
+ activity.lessons.exceptions
+ .sort((a, b) => a.getTime() - b.getTime())
+ .map(
+ (date) =>
+ `${dateFormatter.format(date)}`,
+ ),
+ )}
>
{formatTime(activity.time.start)} -{" "}
@@ -303,6 +311,19 @@ function shiftWeekday(weekday: number) {
sell
+
+
+ do_not_disturb_on
+
+
+ Hormis ces dates:
+ {"."}
+
+
@@ -321,6 +342,10 @@ function shiftWeekday(weekday: number) {
const time = document.getElementById("dialog-time")!;
const dateRange = document.getElementById("dialog-date-range")!;
const price = document.getElementById("dialog-price")!;
+ const exceptDates = document.getElementById("dialog-except-dates")!;
+ const exceptDatesList = document.getElementById(
+ "dialog-except-dates-list",
+ )!;
const calendar = document.getElementById("calendar")!;
const activities = calendar.querySelectorAll(".activity");
@@ -343,6 +368,10 @@ function shiftWeekday(weekday: number) {
time.innerText = `${dataset.weekday}, de ${dataset.startTime} à ${dataset.endTime}`;
dateRange.innerText = `${dataset.firstLesson} au ${dataset.lastLesson}`;
price.innerText = `${dataset.amount}$ pour ${dataset.lessons} cours`;
+
+ const exceptions = dataset.exceptDates ?? "";
+ exceptDates.dataset.visible = (exceptions.length > 0).toString();
+ exceptDatesList.innerHTML = exceptions;
}
function position(activity: HTMLDivElement, xOffset = 0) {
diff --git a/packages/web/src/lib/formatters.ts b/packages/web/src/lib/formatters.ts
index 15e30e2..70a65f3 100644
--- a/packages/web/src/lib/formatters.ts
+++ b/packages/web/src/lib/formatters.ts
@@ -1,3 +1,5 @@
export const dateFormatter = new Intl.DateTimeFormat("fr-CA", {
dateStyle: "long",
});
+
+export const listFormatter = new Intl.ListFormat("fr-CA");
diff --git a/packages/web/src/pages/horaire.astro b/packages/web/src/pages/horaire.astro
index 3b80ba7..dbc02bc 100644
--- a/packages/web/src/pages/horaire.astro
+++ b/packages/web/src/pages/horaire.astro
@@ -19,6 +19,7 @@ const activities: Activity[][] = [
count: 8,
first: new Date(2025, 1, 6),
last: new Date(2025, 5, 5),
+ exceptions: [],
},
price: 120,
color: "#ff00ff",
@@ -34,6 +35,7 @@ const activities: Activity[][] = [
count: 8,
first: new Date(2025, 1, 6),
last: new Date(2025, 5, 5),
+ exceptions: [],
},
price: 120,
color: "#0ff0ff",
@@ -49,6 +51,7 @@ const activities: Activity[][] = [
count: 8,
first: new Date(2025, 1, 6),
last: new Date(2025, 5, 5),
+ exceptions: [],
},
price: 120,
color: "#f0f0ff",
@@ -67,6 +70,7 @@ const activities: Activity[][] = [
count: 2,
first: new Date(2025, 2, 2),
last: new Date(2025, 3, 4),
+ exceptions: [],
},
price: 28,
color: "#12fa83",
@@ -83,6 +87,7 @@ const activities: Activity[][] = [
count: 2,
first: new Date(2025, 2, 2),
last: new Date(2025, 3, 4),
+ exceptions: [],
},
price: 28,
color: "#fa1283",
@@ -100,6 +105,7 @@ const activities: Activity[][] = [
count: 8,
first: new Date(2025, 1, 6),
last: new Date(2025, 5, 5),
+ exceptions: [],
},
price: 120,
color: "#0f0f00",
@@ -115,6 +121,7 @@ const activities: Activity[][] = [
count: 8,
first: new Date(2025, 1, 6),
last: new Date(2025, 5, 5),
+ exceptions: [],
},
price: 120,
color: "#f0f000",
@@ -130,6 +137,7 @@ const activities: Activity[][] = [
count: 8,
first: new Date(2025, 1, 6),
last: new Date(2025, 5, 5),
+ exceptions: [],
},
price: 120,
color: "#0fff30",
@@ -145,6 +153,7 @@ const activities: Activity[][] = [
count: 8,
first: new Date(2025, 1, 6),
last: new Date(2025, 5, 5),
+ exceptions: [],
},
price: 120,
color: "#ffff00",
@@ -164,6 +173,7 @@ const activities: Activity[][] = [
count: 8,
first: new Date(2025, 1, 6),
last: new Date(2025, 5, 5),
+ exceptions: [new Date(2025, 7, 1), new Date(2025, 6, 24)],
},
price: 120,
color: "#ff0000",
@@ -179,6 +189,7 @@ const activities: Activity[][] = [
count: 8,
first: new Date(2025, 1, 6),
last: new Date(2025, 5, 5),
+ exceptions: [],
},
price: 120,
color: "#0ff000",