feat: rebrand AgendaPro -> AgendaMax + calendar fixes + current-week demo seed

- Rebrand all user-facing text to AgendaMax
- Fix sidebar scrolling: card container no longer overflows html (flex h-full min-h-0)
- Fix calendar toolbar hover: active buttons keep readable contrast
- Sticky calendar toolbar (month/week/day always visible on scroll)
- Seed guarantees 2-4 appointments per day for current week (Mon-Sat)
This commit is contained in:
AgendaPro Dev
2026-07-27 10:11:16 -06:00
parent 4227db0c8b
commit d796538fd9
57 changed files with 2477 additions and 322 deletions
+81
View File
@@ -0,0 +1,81 @@
// server/lib/time.test.ts
import { test } from "node:test";
import assert from "node:assert/strict";
import {
bizDateISO,
bizTodayISO,
bizDayBoundsSqlite,
bizDayBoundsIso,
wallToUtcISO,
wallToUtcDate,
toSqliteUtc,
toIsoUtc,
} from "./time.ts";
const MX = "America/Mexico_City"; // UTC-6 (no DST since 2023)
const BA = "America/Buenos_Aires"; // UTC-3
test("bizTodayISO: UTC instant just past midnight (00:30Z) is still the previous day in MX", () => {
// 2026-07-27T00:30:00Z == 2026-07-26T18:30 local → still the 26th
assert.equal(bizTodayISO(MX, new Date("2026-07-27T00:30:00Z")), "2026-07-26");
});
test("bizTodayISO: late afternoon UTC (17:00Z) is same biz day in MX", () => {
assert.equal(bizTodayISO(MX, new Date("2026-07-26T17:00:00Z")), "2026-07-26");
});
test("bizDateISO: Buenos Aires UTC-3 midday stays same day", () => {
// 17:00Z == 14:00 local
assert.equal(bizDateISO(new Date("2026-07-26T17:00:00Z"), BA), "2026-07-26");
});
test("bizDateISO: Buenos Aires UTC-3 evening stays same day", () => {
// 23:00Z == 20:00 local
assert.equal(bizDateISO(new Date("2026-07-26T23:00:00Z"), BA), "2026-07-26");
});
test("bizDateISO: UTC instant rolls to next local day", () => {
// 2026-07-27T05:00:00Z == 2026-07-26T23:00 in MX → still 26th
assert.equal(bizDateISO(new Date("2026-07-27T05:00:00Z"), MX), "2026-07-26");
// 2026-07-27T06:30:00Z == 2026-07-27T00:30 in MX → now 27th
assert.equal(bizDateISO(new Date("2026-07-27T06:30:00Z"), MX), "2026-07-27");
});
test("wallToUtcISO: MX wall 18:00 → UTC next-day 00:00", () => {
assert.equal(wallToUtcISO(MX, 2026, 7, 26, 18, 0, 0), "2026-07-27T00:00:00.000Z");
});
test("wallToUtcISO: MX wall 00:00 → UTC 06:00 same date", () => {
assert.equal(wallToUtcISO(MX, 2026, 7, 26, 0, 0, 0), "2026-07-26T06:00:00.000Z");
});
test("wallToUtcDate: round-trip via bizDateISO stays on the wall day", () => {
const utc = wallToUtcDate(MX, 2026, 7, 26, 18, 0, 0);
assert.equal(bizDateISO(utc, MX), "2026-07-26");
});
test("bizDayBoundsSqlite: today bounds capture the evening rush (UTC-6)", () => {
// "now" is 2026-07-26T23:30:00Z == 2026-07-26T17:30 local MX → biz day 2026-07-26
const b = bizDayBoundsSqlite(MX, 0, new Date("2026-07-26T23:30:00Z"));
// biz-local midnight 2026-07-26 in MX == 06:00Z; end of day 23:59:59 == 2026-07-27T05:59:59Z
assert.equal(b.start, "2026-07-26 06:00:00");
assert.equal(b.end, "2026-07-27 05:59:59");
});
test("bizDayBoundsIso: ISO-Z bounds for start_at comparisons", () => {
const b = bizDayBoundsIso(MX, 0, new Date("2026-07-26T23:30:00Z"));
assert.equal(b.start, "2026-07-26T06:00:00Z");
assert.equal(b.end, "2026-07-27T05:59:59Z");
});
test("bizDayBoundsSqlite: negative offset reaches into the past", () => {
// 30 days before biz day 2026-07-26 → 2026-06-26, midnight MX == 06:00Z
const b = bizDayBoundsSqlite(MX, -30, new Date("2026-07-26T23:30:00Z"));
assert.equal(b.start, "2026-06-26 06:00:00");
});
test("toSqliteUtc / toIsoUtc format helpers", () => {
const d = new Date("2026-07-27T00:00:00.000Z");
assert.equal(toSqliteUtc(d), "2026-07-27 00:00:00");
assert.equal(toIsoUtc(d), "2026-07-27T00:00:00Z");
});