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
+40
View File
@@ -0,0 +1,40 @@
# Task 11 — `DateTimePicker` 2-col + month calendar + Mañana/Tarde grouping
## File changed
- `src/pages/public/BookingPage.tsx`
- Added `import { MonthCalendar } from "../../components/MonthCalendar";` (line 28).
- Rewrote `DateTimePicker` (now lines 556639): 2-column grid on `md+`, vertical stack below `md`, new optional `max?: string` prop, slots grouped via new `SlotGroup` subcomponent.
- Added new `SlotGroup` helper (lines 641681).
## Verification results
### `npm run typecheck`
```
> tsc -b --noEmit
```
**0 errors.** The existing caller of `DateTimePicker` (in `BookingPage`) does not pass `max` — confirms `max` is optional and not breaking the caller.
### `npm run build`
```
✓ 2461 modules transformed.
✓ built in 4.98s
```
**Succeeds.** Production bundle emitted.
### Visual smoke
Not executed interactively (subagent has no browser). Validated indirectly via successful `vite build` (2461 modules transformed, including the rewritten `BookingPage` and the imported `MonthCalendar`). Task 12 is responsible for wiring `max`/`employeeId` end-to-end and for any final interactive smoke; the unit of work in this task compiles and type-checks cleanly against the rest of the project.
## Self-review
| Check | Result |
|---|---|
| 2-col layout only on `md+` | ✅ Outer wrapper uses `md:grid md:grid-cols-[minmax(0,1fr)_minmax(0,1.1fr)] md:items-start md:gap-8`. Below `md` no grid is applied. |
| Mobile stacked vertically | ✅ Right column wrapper has `mt-4 md:mt-0` so on mobile the calendar card is followed by the slots card with vertical spacing; the outer div is a plain block (no `flex`/`grid`) below `md`. |
| Slot button markup unchanged | ✅ Identical classes (`grid grid-cols-3 gap-2 sm:grid-cols-4`; button `rounded-xl border px-2 py-2.5 text-sm font-bold transition-all`; active `border-brand-500 bg-brand-500 text-white shadow-soft`; inactive `border-slate-200 bg-white text-slate-700 hover:border-brand-400 hover:bg-brand-50`), same `key={`${slot.iso}-${slot.employee_id}`}`, same `onClick={() => onPick(slot)}`. Only the grouping wrapper (`SlotGroup`) is new. |
| Morning/afternoon split correct, incl. 12 PM boundary | ✅ Algorithm: parse `(\d{1,2}):(\d{2})``h`; `pm = /PM/i`; `hour24 = pm && h!==12 ? h+12 : !pm && h===12 ? 0 : h`; bucket by `hour24 < 12`. Verified cases: `12:00 AM` → h=12, !pm, h===12 → 0 → **Mañana**. `11:30 AM` → 11 → **Mañana**. `12:00 PM` → h=12, pm, h===12 (no +12) → 12 → **Tarde**. `12:30 PM` → 12 → **Tarde**. `1:00 PM` → 13 → **Tarde**. `11:59 PM` → 23 → **Tarde**. Boundary at noon is correct (12:00 PM is the first Tarde slot). |
| `max` is optional | ✅ Declared `max?: string`. Typecheck with caller that omits `max` passes. |
| No commit performed | ✅ No `git commit` run. |
| Scope respected (only `BookingPage.tsx`, only `DateTimePicker` + import + `SlotGroup`) | ✅ No other functions touched (`TopBar`, `ActionBar`, `Confirmation`, `EmployeeList`, `ServiceGrid`, `DetailsForm` unchanged; Task 8's `pl-10` untouched). |
## Concerns
- None. Implementation matches the plan verbatim. Interactive browser smoke deferred to the orchestrator / Task 12 (which will also pass `max` and `employeeId` to the picker and exercise the full wizard).