feat: public landing page with magic login, brand palette and demo build flag
Adds a public funnel landing at `/` and moves the login to `/login`, rebuilt around the panel's own colors instead of an invented palette. Landing (`src/components/landing/`, one section per file, no props): - Seven funnel sections composed by `LandingPage`. The hero's eight swatches are literally `PIE_COLORS` from `DashboardPage`, the same hex values the seed hands to avatars and services, so "your colors become your numbers" is literal. - `BrandMark` becomes the single source for the logo, replicating `public/favicon.svg`. Blue is the action surface, orange only ever marks. - `NotebookVisual` is the one deliberate exception to the palette: it is what the product replaces. - Copy drops all system vocabulary; motion comes from `src/lib/motion.ts` with a single easing, and reduced-motion resolves `initial` to the final state so a never-firing `whileInView` cannot leave a section invisible forever. Routing and bundle: - `homePathFor` is the single definition of each role's destination. - Landing, login, dashboard and calendar load lazily. Eager, the login dragged framer-motion (~40 KB gz) into every panel load and the landing downloaded recharts + FullCalendar (~187 KB gz) without charting anything. `clsx` is pinned to the `react` chunk because Rollup otherwise assigns it to `charts`, making the entry import 111 KB gz for a 200-byte utility. Responsiveness (iPhone/iPad), verified with `npm run audit:responsive`: - No touch form field below 16px, `dvh` height utilities, safe-area insets, and 40px touch targets keyed off `pointer: coarse` rather than `sm:`. - New `.ld-gutter`: `.safe-x` lives outside `@layer` and beats Tailwind's `px-*`, so it left the login's side padding at 0 on anything but an iPhone in landscape. No overflow check could see it — there was no overflow, just zero margin. The audit now guards it with a `gutter` check. - `shell-height` no longer fires on pages that legitimately scroll; the static `raw-viewport-unit` scan covers those instead. Production build: - The Dockerfile now sets `VITE_DEMO_UI=1` as a build arg. `DEMO` is a build-time constant, so without it Vite eliminated the magic login and the "Ver como…" switcher: the deployed landing promised "no registration" and led to an empty form. Verified by building both ways and diffing the bundle. - Service worker cache bumped to v2 so the orphaned pre-landing chunks get purged from returning visitors' caches. Verified: typecheck clean; unit 39/39, e2e 33/33, admin 17/17, booking 12/12, landing 13/13 (WebKit), PWA passed against the real production build. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
0b466f33f3
commit
4c19244df9
@@ -1,74 +1,37 @@
|
||||
# Task 1 Report - AgendaMax demo access references
|
||||
# Task 1 Implementation Report
|
||||
|
||||
## Status
|
||||
## Scope
|
||||
|
||||
Complete for the source and documentation layer. Local and production SQLite data were not touched.
|
||||
Implemented only the static AgendaMax PWA contract from Task 1. Existing worktree changes and graphify outputs were not modified.
|
||||
|
||||
## Changed files
|
||||
## Changed Files
|
||||
|
||||
Implementation commit `6355d18a07b5bef6fd3515b80a0f768b0ae1050b` (`docs: standardize AgendaMax demo access`) changed:
|
||||
- `scripts/generate-pwa-icons.mjs`: reproducible Playwright generator using the existing `public/favicon.svg` as a base64 data URL.
|
||||
- `public/icon-192.png`: generated 192x192 PNG install icon.
|
||||
- `public/icon-512.png`: generated 512x512 PNG install icon.
|
||||
- `public/manifest.webmanifest`: exact AgendaMax manifest metadata and icon declarations.
|
||||
- `index.html`: manifest link, Apple install metadata, and `viewport-fit=cover`; existing favicon, theme, and description preserved.
|
||||
- `package.json`: added `generate:pwa-icons` and `test:pwa` scripts.
|
||||
|
||||
- `README.md` - added an explicit `Contraseña` column with `demo1234` for all eight demo accounts; changed only Admin and Dueño to `@agendamax.demo`.
|
||||
- `server/index.ts` - changed the fresh default owner email.
|
||||
- `server/scripts/seed.ts` - changed fresh admin and owner emails; retained `demo1234`.
|
||||
- `src/pages/LoginPage.tsx` - changed only the development default owner email.
|
||||
- `admin-test.mjs`, `e2e-test.mjs`, `e2e-full.mjs`, `server/scripts/booking-e2e.mjs`, `visual-audit.mjs` - aligned active platform login fixtures and assertions.
|
||||
- `docs/superpowers/plans/2026-07-26-auto-assign-specialist-booking-redesign.md` - aligned its copy-pasteable booking login example.
|
||||
## Verification
|
||||
|
||||
The current untracked Task 1 brief, design, and migration plan were not modified or staged. The completed Task 5 report was classified as historical and was not modified. No employee email domain or password was changed.
|
||||
- `node scripts/generate-pwa-icons.mjs`: exit 0, no output.
|
||||
- PNG signature/dimensions Node check: passed; `public/icon-192.png` is PNG 192x192 and `public/icon-512.png` is PNG 512x512.
|
||||
- Reproducibility check: passed. SHA256 values remained stable across regeneration:
|
||||
- 192 icon: `A5073D1EA7662F7E90D4E8E1DF12FF563A6DCC161FFCF6C4591D7C5F2695F6FE`
|
||||
- 512 icon: `19914C9D4C3F626782C85920DAD9E16B069809B5D876A903BF88695E1F9F045F`
|
||||
- `npm.cmd run typecheck`: exit 0.
|
||||
- `npm.cmd run build`: exit 0; Vite transformed 2463 modules and emitted the production bundle.
|
||||
- Dist asset/manifest check: passed; `dist/manifest.webmanifest`, `dist/icon-192.png`, and `dist/icon-512.png` exist and the manifest contract is valid.
|
||||
- `git diff --check`: no whitespace errors. Git emitted only existing line-ending normalization warnings.
|
||||
|
||||
## TDD evidence
|
||||
## Self-Review
|
||||
|
||||
### RED
|
||||
|
||||
The five executable login fixtures were updated before the source constants. A read-only source assertion was then run against `server/index.ts`, `server/scripts/seed.ts`, and `src/pages/LoginPage.tsx`. It failed as expected with `AssertionError` because `owner@agendamax.demo` and `[email protected]` were not yet present while the old source constants remained.
|
||||
|
||||
The focused runtime visual check was also attempted before source changes:
|
||||
|
||||
```text
|
||||
npm run audit:visual
|
||||
page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:5173/
|
||||
```
|
||||
|
||||
This did not reach the application and did not touch the database.
|
||||
|
||||
### GREEN
|
||||
|
||||
After the minimal source and README edits, the corrected read-only assertion passed:
|
||||
|
||||
```text
|
||||
source and active login fixtures: PASS
|
||||
```
|
||||
|
||||
The final active-reference and README credential assertion also passed:
|
||||
|
||||
```text
|
||||
active references and README credentials: PASS
|
||||
```
|
||||
|
||||
## Tests and outputs
|
||||
|
||||
- `npm run typecheck` - passed, exit code 0; `tsc -b --noEmit` reported no errors.
|
||||
- `npm run build` - passed, exit code 0; Vite transformed 2463 modules and built in 5.63s.
|
||||
- `npm run test:unit` - passed: 39 tests, 39 pass, 0 fail.
|
||||
- `npm run audit:visual` - unavailable: no server was listening on `localhost:5173` (`ERR_CONNECTION_REFUSED`).
|
||||
- `npm run lint` - unavailable: ESLint 9.39.5 could not find `eslint.config.js`, `eslint.config.mjs`, or `eslint.config.cjs`.
|
||||
- `rg -n ...` - unavailable because `rg` is not installed/on PATH in this environment. The equivalent scoped repository search found no old domain in active application, README, fixture, or executable plan references.
|
||||
- `git diff --cached --check` - passed before the implementation commit.
|
||||
|
||||
The database-mutating API suites (`test:e2e`, `test:admin`, and `test:booking`) were not run because this task explicitly forbids touching the ignored local database. They remain for the post-migration verification task.
|
||||
|
||||
## Self-review
|
||||
|
||||
- The quick-login behavior is unchanged: `LoginPage` still loads `/api/auth/demo-users`, and the existing password and account-switching logic remain intact.
|
||||
- Only platform-owned Admin and Dueño domains changed to `@agendamax.demo`; all employee domains remain on their existing business domains.
|
||||
- All documented demo rows explicitly show `demo1234`, including every employee row.
|
||||
- No migration, abstraction, production command, local database command, `.env.local.ps1`, or `data/` file was added or changed.
|
||||
- The implementation commit contains exactly the ten intended Task 1 files and excludes the supplied untracked design/plan files.
|
||||
- Remaining `@agendapro.demo` matches are intentional migration/history references in the new migration plan/spec and the completed Task 5 report.
|
||||
- The browser-tab icon remains `/favicon.svg`.
|
||||
- The manifest uses `/` for both `start_url` and `scope`, standalone display, portrait-primary orientation, the requested colors, and PNG icon declarations.
|
||||
- The generator resolves paths from its own module location, closes pages and the browser, and produces deterministic 1x screenshots.
|
||||
- No unrelated tracked or untracked worktree files were staged.
|
||||
|
||||
## Concerns
|
||||
|
||||
- Live/API and visual login verification is pending a running dev server and the later SQLite migration; those prerequisites were intentionally not started in this task.
|
||||
- Lint remains unavailable until the repository ESLint 9 configuration is supplied or the project pins a compatible ESLint setup.
|
||||
- The exact `rg` inventory command cannot be reproduced until ripgrep is installed/on PATH.
|
||||
- `npm.cmd run test:pwa` was not run because `pwa-e2e.mjs` is intentionally a Task 4 deliverable and does not exist at this task boundary. The script is present as required for the later task.
|
||||
|
||||
Reference in New Issue
Block a user