feat(ui): app UX/UI redesign + marketing landing site
App (Vue SPA) — 100% presentational, global design-token rebuild in style.css + polished App/Login/Chat/MyBoard/Personas/Setup/Training. No logic/API/route/i18n changes (verified: build clean, 4/4 vitest, independent review PASS 5/5). website/ — new self-contained static marketing landing site (TH-primary + EN toggle, CSS chat mockup, Hallmark theme), verified responsive at 320-768 (no horizontal scroll). Pricing uses placeholders pending owner. Docs: engineering-log 2026-08-19 + HANDOFF updated. NOT pushed (push to main auto-deploys to EasyPanel production; operator approval + JWT_SECRET check required before deploy).
This commit is contained in:
@@ -24,6 +24,16 @@ filesystem JSON storage (no SQL). i18n TH/EN. No self-registration (admin provis
|
||||
- **user** (trainee) — trains against personas, own board.
|
||||
|
||||
## Current state — local code/security gate passed; production-operation gate pending
|
||||
> **2026-08-19:** app UX/UI redesign (8 files, 100% presentational: global design-token system
|
||||
> rebuild in `style.css` + polish of App/Login/Chat/MyBoard/Personas/Setup/Training) AND a new
|
||||
> self-contained marketing landing site (`website/index.html` + `main.css`, TH-primary with EN
|
||||
> toggle, CSS chat mockup) were built in parallel subagents. Frontend `vite build` clean, vitest
|
||||
> 4/4, independent reviewer PASS (5/5 checks), marketing site verified responsive at 320–768
|
||||
> (no horizontal scroll). **ALL UNCOMMITTED.** Pushing to `main` auto-deploys to EasyPanel — so
|
||||
> the push needs operator approval. Confirm production `JWT_SECRET` is set before deploying
|
||||
> (backend `validate_runtime_security` fails closed without a ≥32-char secret; that is the
|
||||
> existing production-operation gate, not a regression). See
|
||||
> `docs/engineering-log/2026-08-19-ux-redesign-and-marketing-site.md`.
|
||||
> **2026-08-18:** live-QA UX fixes landed (committed locally, not yet pushed): persona
|
||||
> replies can no longer leak raw JSON into the chat bubble; all persona openers are natural
|
||||
> greetings (wrong_text cools off only after the seller's first reply); and the chat now
|
||||
@@ -115,6 +125,13 @@ cd backend && uv run python run.py # Flask :5001
|
||||
Responsive CSS (640px, single-column, `flex-wrap`, `.btn-back`) is present + deployed.
|
||||
|
||||
## Next actions / backlog (also docs/FUTURE_WORK.md)
|
||||
- **2026-08-19 UX + marketing-site push (operator-approved):** the app UX/UI redesign (8 files)
|
||||
and new `website/` landing site are uncommitted on `main`. Commit + push ships the redesign to
|
||||
the live EasyPanel app AND adds the marketing site to the repo. **Confirm production
|
||||
`JWT_SECRET` is set (≥32 chars) in EasyPanel env before/with the push** (backend fails closed
|
||||
without it). Then re-verify the live bundle. Optionally deploy the `website/` landing page as a
|
||||
standalone static site (e.g. nginx / EasyPanel static or another host) — serve from
|
||||
`website/index.html`; set real pricing before public launch.
|
||||
- **Sprint 1 live-operation gate:** deploy behind restricted access, set/verify `BOOTSTRAP_ADMIN_PASSWORD`, rotate `JWT_SECRET` after the patch, inspect audit data, and run a fresh authenticated smoke. Do not open public access before this checklist.
|
||||
- **Sprint 2:** implementation and local regression gate complete; retain current tests as the contract.
|
||||
- **P1:** run real-provider QA and browser/mobile E2E; local contract tests use deterministic fakes.
|
||||
|
||||
@@ -30,6 +30,7 @@ Informed by MiroFish (CrowdSight engine) + the hermes-brain-and-tools CrowdSight
|
||||
| S4.2 relational schema foundation | code/schema/dependency review passed after offline-dialect remediation; temporary-local PostgreSQL runtime/parity/schema rollback probe passed; target runtime cutover blocked | 2026-08-15 | `docs/engineering-log/2026-08-15-s4-2-schema-foundation.md`, `docs/engineering-log/2026-08-15-postgresql-runtime-gate.md`, `docs/test-evidence/2026-08-15-postgresql-runtime.md`, `backend/requirements.lock.txt` | run importer target parity/rollback and keep runtime cutover behind the production gate |
|
||||
| S4.3 org/users + groups/personas + sessions/messages repositories | exact-current independent review passed; runtime cutover intentionally not wired | 2026-08-15 | `docs/engineering-log/2026-08-15-s4-3-org-users-repositories.md`, `docs/engineering-log/2026-08-15-s4-3-offline-dialect-remediation.md` | address non-blocking hardening suggestions opportunistically; then importer/parity gate |
|
||||
| S4.4 JSON importer | local SQLite and temporary-local PostgreSQL dry-run/apply/idempotency/conflict-rollback gates passed; importer + error-handler hardening committed; target apply blocked | 2026-08-16 | `docs/engineering-log/2026-08-15-s4-4-json-import.md`, `docs/engineering-log/2026-08-15-postgresql-import-gate.md`, `docs/engineering-log/2026-08-16-s4-4-importer-errorhandler-commit.md`, `docs/test-evidence/2026-08-15-postgresql-import.md` | target snapshot checksum/count comparison, retained backup, and operator-approved rollback rehearsal |
|
||||
| UX/UI redesign + marketing website | implemented + locally verified (build clean, 4/4 unit tests, independent review PASS, responsive verified); uncommitted; deploy pending operator approval | 2026-08-19 | `docs/engineering-log/2026-08-19-ux-redesign-and-marketing-site.md`, `website/`, `git diff` | operator approves push (auto-deploys); confirm production `JWT_SECRET` before deploy |
|
||||
|
||||
## Guardrails
|
||||
- No self-registration; admin provisions users. (Verified: register => 404.)
|
||||
@@ -67,3 +68,4 @@ Informed by MiroFish (CrowdSight engine) + the hermes-brain-and-tools CrowdSight
|
||||
- `2026-08-15-s4-4-json-import.md` — fail-closed dry-run/apply importer, idempotency, backup, and parity blockers.
|
||||
- `2026-08-16-s4-4-importer-errorhandler-commit.md` — re-verified from clean lock env (330 tests) and committed the staged S4.4 importer + error-handler hardening increment.
|
||||
- `2026-08-18-live-qa-ux-fixes.md` — live-QA UX fixes: persona JSON never leaks into bubble, natural greeting openers (wrong_text cools off only after first reply), auto-close + auto-summarize on buy/walk/try, no manual "สรุปผล" button (336 tests).
|
||||
- `2026-08-19-ux-redesign-and-marketing-site.md` — parallel subagents: app UX/UI redesign (global token system, 8 files, 100% presentational) + new `website/` marketing landing site (responsive TH/EN); build clean, 4/4 unit tests, independent review PASS; uncommitted, deploy pending operator approval.
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
# 2026-08-19 — UX/UI redesign + marketing website (parallel subagents)
|
||||
|
||||
Date: 2026-08-19
|
||||
Status: implemented + locally verified; deploy = repo's normal Gitea→EasyPanel path (operator runs it)
|
||||
|
||||
## Context
|
||||
|
||||
User asked (in Thai) to use the "brain" + existing agents to develop (a) the app's UX/UI and
|
||||
(b) a marketing website to sell the Sales Trainer app. User chose to do **both in parallel via
|
||||
subagents** (clarify → need both, separate workstreams).
|
||||
|
||||
## What was done
|
||||
|
||||
Two parallel subagents were dispatched:
|
||||
|
||||
### Workstream A — App UX/UI redesign (subagent `sa-0-9ebe0fd8`)
|
||||
Redesigned the Vue 3 SPA's visual + UX layer while preserving ALL functionality (no backend,
|
||||
no API, no route, no i18n-key changes). Edited 8 files:
|
||||
- `frontend/src/style.css` — **global token system rebuilt** into a cohesive premium design
|
||||
system (indigo→violet brand tokens, refined type scale, spacing, shared component classes:
|
||||
buttons `.primary/.soft/.danger`, badges, chat bubbles `.msg-seller/.msg-customer/.msg-system`,
|
||||
skeleton, empty-state with `.empty-illust`, `.btn-back`, reduced-motion guard). Upgrades every
|
||||
screen that consumes the shared tokens.
|
||||
- `frontend/src/App.vue` — frosted-glass sticky top nav (backdrop blur), brand mark + target icon.
|
||||
- `frontend/src/views/Login.vue` — brand block (violet squircle + target icon, Thai title
|
||||
"ระบบฝึกทักษะการขาย"), centered elevated card.
|
||||
- `frontend/src/views/Chat.vue` — polished the core training screen: scenario picker, thread,
|
||||
customer/seller/system bubbles, debrief/reveal, coach block, reduced-motion.
|
||||
- `frontend/src/views/MyBoard.vue` — dashboard header + empty-state illustration.
|
||||
- `frontend/src/views/Personas.vue` — persona card + guide polish.
|
||||
- `frontend/src/views/Setup.vue` — auth setup polish.
|
||||
- `frontend/src/views/Training.vue` — training list card polish.
|
||||
- **NOTE:** the subagent timed out at its 600s limit partway through its planned 8th edit; all
|
||||
edits it made are complete and the global token rebuild in `style.css` benefits every view.
|
||||
Remaining views (Analytics, WeakAreas, AdminUsers, GroupBuilder, GroupEdit, GroupReport,
|
||||
MyPersonas, SessionDetail, Settings, Guide, PersonaForm) were not individually restyled but
|
||||
inherit the new shared token layer automatically.
|
||||
|
||||
### Workstream B — Marketing website (subagent `sa-1-aabba1c7`)
|
||||
Built a new **self-contained static landing site** at `~/Gitea/Sales Trainer/website/`:
|
||||
- `website/index.html` (57.5 KB, 647 lines) + `website/main.css` (25.1 KB, 424 lines).
|
||||
- Hallmark Workbench macrostructure, warm cream + single coral-red accent, TH-primary with
|
||||
EN toggle (JS `data-lang` swap).
|
||||
- Sections: hero (with realistic CSS-only chat mockup incl. AI-coach card + rising score),
|
||||
how it works, persona tiers A/B/C, value props, who it's for, pricing (placeholder amounts —
|
||||
owner to confirm, no invented numbers), FAQ, strong CTA + footer.
|
||||
- **Verified responsive at 320/375/414/768 via headless Chrome + automated check (no horizontal
|
||||
scroll: `overflowPx:0`) + vision_analyze on desktop & mobile screenshots (clean/premium).**
|
||||
- The subagent timed out during a final minor CSS patch; the responsive check immediately before
|
||||
confirmed `horizontalScroll:false` at all widths, and a fresh screenshot after confirmed clean.
|
||||
|
||||
## Verification evidence
|
||||
|
||||
| Check | Result |
|
||||
|---|---|
|
||||
| Frontend `vite build` | **clean** (rebuilt `frontend/dist`) |
|
||||
| Frontend vitest unit | **4/4 pass** |
|
||||
| Static security scan of diff (+lines) | no secrets / eval / innerHTML / injection |
|
||||
| Diff logic scan | **zero** script-logic changes — 100% presentational (CSS + template classes + icon imports) |
|
||||
| Independent reviewer subagent (`deleg_21f491a4`) | **PASS** — 5/5: no logic changes · CSS class integrity · no security issues · no media-query removals (only `prefers-reduced-motion` added) · no undefined CSS vars / no new i18n keys |
|
||||
| Marketing site responsive (320/375/414/768) | **no horizontal scroll** (`overflowPx:0`) — automated check + screenshots |
|
||||
| Marketing site visuals | vision_analyze on desktop + mobile → clean, cohesive, premium; minor cosmetic nits only (marker-underline widths, column top alignment) — intentional design choices, left as designed |
|
||||
| App login screen (redesigned) | rendered via static dist + screenshot → clean/premium; pale button in screenshot = `:disabled` state (correct) |
|
||||
| `git diff --check` | passes (no whitespace errors) |
|
||||
|
||||
## Files changed (uncommitted)
|
||||
|
||||
```
|
||||
M frontend/src/App.vue
|
||||
M frontend/src/style.css
|
||||
M frontend/src/views/Chat.vue
|
||||
M frontend/src/views/Login.vue
|
||||
M frontend/src/views/MyBoard.vue
|
||||
M frontend/src/views/Personas.vue
|
||||
M frontend/src/views/Setup.vue
|
||||
M frontend/src/views/Training.vue
|
||||
?? website/ (index.html + main.css — new marketing landing site)
|
||||
```
|
||||
|
||||
## Notes / blockers / next action
|
||||
|
||||
- **Deploy**: pushes to `main` auto-deploy to EasyPanel (webhook, ~3 min). Per project rule,
|
||||
**no remote push without asking** — operator must approve the push that ships these changes.
|
||||
BEFORE pushing, also confirm the production `JWT_SECRET` is set (see below).
|
||||
- **Local backend preview blocked** (by design): `Config.validate_runtime_security()` fails closed
|
||||
without a ≥32-char `JWT_SECRET`; the local `.env` holds a placeholder. The SPA `dist/` was
|
||||
previewed via static serving instead. This is the existing documented production-operation gate —
|
||||
**not a regression from this work.**
|
||||
- Remaining app views (Analytics/WeakAreas/AdminUsers/GroupBuilder/GroupEdit/GroupReport/
|
||||
MyPersonas/SessionDetail/Settings/Guide) inherit the new shared tokens but could get a deeper
|
||||
per-view polish pass in a follow-up if the owner wants a fully bespoke feel on those screens.
|
||||
- Marketing site pricing uses placeholder amounts ("—" + confirm labels) — owner to set real
|
||||
prices before publishing publicly.
|
||||
|
||||
## Related
|
||||
- `docs/HANDOFF.md`, `docs/engineering-log.md`
|
||||
- Skills used: `engineering-handoff`, `ui-ux-pro-max` (partial), `hallmark` (used by both subagents)
|
||||
Reference in New Issue
Block a user