feat: Audited all 9 public-facing pages at 375px and 768px viewports —…
- "frontend/src/App.css" GSD-Task: S02/T01
This commit is contained in:
parent
cb3a6c919c
commit
b893abead1
13 changed files with 813 additions and 3 deletions
|
|
@ -50,3 +50,4 @@
|
|||
| D042 | M023/S01 | architecture | Rich text editor for creator posts | Tiptap (headless, React) with StarterKit + Link + Placeholder extensions. Store Tiptap JSON as canonical format in JSONB column, render client-side via @tiptap/html. | Headless architecture fits dark theme customization. Large ecosystem, well-maintained. JSON storage is lossless and enables future server-side rendering. No HTML sanitization needed since canonical format is structured JSON. | Yes | agent |
|
||||
| D043 | M023/S02 | architecture | Personality weight → system prompt modulation strategy | 3-tier intensity (<0.4 subtle reference, 0.4-0.8 adopt voice, ≥0.8 fully embody) with temperature scaling 0.3–0.5 linear on weight | Stepped intensity prevents jarring persona at low weights while allowing full creator voice at high values. Temperature stays in 0.3-0.5 range to keep responses factually grounded even at maximum personality — wider ranges risk hallucination in a knowledge-base context. | Yes | agent |
|
||||
| D044 | M023/S04 | architecture | Personality weight → system prompt modulation strategy (revision) | 5-tier continuous interpolation replacing 3-tier step function. Progressive field inclusion: weight < 0.2 = no personality block; 0.2+ adds basic tone; 0.4+ adds descriptors/explanation approach; 0.6+ adds signature phrases (count scaled with weight); 0.8+ adds full vocabulary/style markers; 0.9+ adds summary paragraph. Temperature scaling unchanged (0.3 + weight * 0.2). | 3-tier step function had jarring transitions at 0.4 and 0.8 boundaries. Continuous interpolation with progressive field inclusion gives finer control — encyclopedic responses stay clean at low weights while high weights pull in the full personality profile gradually. The 0.0-0.19 dead zone ensures purely encyclopedic mode remains truly encyclopedic with zero personality artifacts. | Yes | agent |
|
||||
| D045 | M025/S01 | library | Signed unsubscribe token library for email digests | PyJWT instead of itsdangerous | PyJWT was already a dependency (used for auth tokens). Avoids adding itsdangerous as a new package. JWT exp claim provides built-in expiry handling for the 30-day token validity. | Yes | agent |
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ Production hardening, mobile polish, creator onboarding, and formal validation.
|
|||
## Slice Overview
|
||||
| ID | Slice | Risk | Depends | Done | After this |
|
||||
|----|-------|------|---------|------|------------|
|
||||
| S01 | [A] Notification System (Email Digests) | medium | — | ⬜ | Followers receive email digests when followed creators post new content |
|
||||
| S01 | [A] Notification System (Email Digests) | medium | — | ✅ | Followers receive email digests when followed creators post new content |
|
||||
| S02 | [A] Mobile Responsiveness Pass | medium | — | ⬜ | All new Phase 2 UI surfaces pass visual check at 375px and 768px |
|
||||
| S03 | [A] Creator Onboarding Flow | low | — | ⬜ | New creator signs up, follows guided upload, sets consent, sees dashboard tour |
|
||||
| S04 | [B] Rate Limiting + Cost Management | low | — | ⬜ | Chat requests limited per-user and per-creator. Token usage dashboard in admin. |
|
||||
|
|
|
|||
118
.gsd/milestones/M025/slices/S01/S01-SUMMARY.md
Normal file
118
.gsd/milestones/M025/slices/S01/S01-SUMMARY.md
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
---
|
||||
id: S01
|
||||
parent: M025
|
||||
milestone: M025
|
||||
provides:
|
||||
- Email digest pipeline (Celery task + Beat schedule + email service)
|
||||
- Notification preferences API (GET/PUT with auth)
|
||||
- Signed unsubscribe endpoint (no auth, JWT token)
|
||||
- Frontend notification settings UI in CreatorSettings
|
||||
requires:
|
||||
[]
|
||||
affects:
|
||||
- S11
|
||||
key_files:
|
||||
- backend/config.py
|
||||
- backend/models.py
|
||||
- backend/schemas.py
|
||||
- backend/services/email.py
|
||||
- backend/tasks/notifications.py
|
||||
- backend/worker.py
|
||||
- backend/routers/notifications.py
|
||||
- backend/main.py
|
||||
- backend/tests/notifications/test_notifications.py
|
||||
- frontend/src/api/notifications.ts
|
||||
- frontend/src/pages/CreatorSettings.tsx
|
||||
- alembic/versions/029_add_email_digest.py
|
||||
- docker-compose.yml
|
||||
key_decisions:
|
||||
- D045: Used PyJWT for signed unsubscribe tokens instead of itsdangerous — already a dependency
|
||||
- Standalone ASGI test client pattern for notification tests to avoid container compatibility issues
|
||||
- OSError catch alongside SMTPException in send_email to handle DNS/network failures from socket layer
|
||||
patterns_established:
|
||||
- Email service module pattern: compose function (returns HTML) + send function (returns bool) + config gate (is_configured)
|
||||
- Signed token pattern for unauthenticated endpoints: PyJWT with exp claim for self-expiring tokens
|
||||
- Celery Beat schedule collocated with worker.py celery_app config
|
||||
observability_surfaces:
|
||||
- EmailDigestLog table tracks every successful send with content_summary JSONB
|
||||
- Structured logging in digest task: start, per-user result, completion count
|
||||
- SMTP unconfigured logged as warning (graceful no-op)
|
||||
drill_down_paths:
|
||||
- .gsd/milestones/M025/slices/S01/tasks/T01-SUMMARY.md
|
||||
- .gsd/milestones/M025/slices/S01/tasks/T02-SUMMARY.md
|
||||
- .gsd/milestones/M025/slices/S01/tasks/T03-SUMMARY.md
|
||||
duration: ""
|
||||
verification_result: passed
|
||||
completed_at: 2026-04-04T12:29:14.844Z
|
||||
blocker_discovered: false
|
||||
---
|
||||
|
||||
# S01: [A] Notification System (Email Digests)
|
||||
|
||||
**Followers receive batched email digests when followed creators publish new content, with daily Celery Beat scheduling, per-user preference controls, and signed-token unsubscribe.**
|
||||
|
||||
## What Happened
|
||||
|
||||
Built the full email digest notification pipeline across three tasks. T01 laid the foundation: SMTP configuration with safe empty defaults in config.py, notification_preferences JSONB column on User model, EmailDigestLog model for deduplication tracking, Alembic migration 029, and the email service module (HTML composer with inline CSS grouped by creator, smtplib sender with 10s timeout, and SMTP configuration gate).
|
||||
|
||||
T02 built the Celery orchestration: send_digest_emails task that queries users with digests enabled, finds last digest timestamp from EmailDigestLog, resolves followed creators via CreatorFollow, queries new Posts and TechniquePages since last digest, groups content by creator, composes HTML, and sends. EmailDigestLog is written only on successful send for deduplication. Celery Beat schedule set to daily at 09:00 UTC. Docker worker command updated with --beat flag. Used PyJWT (already a dependency) for signed unsubscribe tokens instead of adding itsdangerous.
|
||||
|
||||
T03 wired user-facing surfaces: GET/PUT notification preferences endpoints with auth, public unsubscribe endpoint using JWT verification (returns styled HTML success/error pages), frontend API client, and email notification toggle + frequency selector in CreatorSettings with optimistic updates. Created 12-test integration suite using standalone ASGI app pattern, covering preferences CRUD, auth enforcement, unsubscribe with valid/expired/tampered tokens, digest task happy path with mocked SMTP, no-content skip, and SMTP-unconfigured no-op.
|
||||
|
||||
## Verification
|
||||
|
||||
Slice-level verification passed all checks:
|
||||
1. Models import: EmailDigestLog, User with notification_preferences — OK
|
||||
2. Email service: compose_digest_html, send_email, is_smtp_configured all import and work — OK
|
||||
3. is_smtp_configured returns False with default empty settings — OK
|
||||
4. Celery task imports and Beat schedule registered at crontab 0 9 * * * — OK
|
||||
5. Docker --beat flag present in docker-compose.yml — OK
|
||||
6. Router exposes GET/PUT /notifications/preferences and GET /notifications/unsubscribe — OK
|
||||
7. Alembic migration 029 module loads — OK
|
||||
8. Frontend TypeScript compiles cleanly (npx tsc --noEmit) — OK
|
||||
9. 12 integration tests pass in Docker container on ub01 — OK (per T03 evidence)
|
||||
|
||||
## Requirements Advanced
|
||||
|
||||
None.
|
||||
|
||||
## Requirements Validated
|
||||
|
||||
None.
|
||||
|
||||
## New Requirements Surfaced
|
||||
|
||||
None.
|
||||
|
||||
## Requirements Invalidated or Re-scoped
|
||||
|
||||
None.
|
||||
|
||||
## Deviations
|
||||
|
||||
Used PyJWT for signed unsubscribe tokens instead of itsdangerous (plan specified itsdangerous). PyJWT was already a dependency — avoids adding a new package. Used standalone ASGI test app for integration tests instead of shared conftest, since the container image may lack newer routers.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
base_url for content links and unsubscribe URL is hardcoded to http://localhost:8096. Should be configurable via settings for production. PyJWT warns about default app_secret_key being under 32 bytes — production should use a longer secret.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
Make base_url configurable in settings for production deployment. Ensure app_secret_key is at least 32 bytes in production config. At 500+ users, batch SMTP connections instead of one-per-email.
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `backend/config.py` — Added 6 SMTP fields with safe empty defaults
|
||||
- `backend/models.py` — Added notification_preferences JSONB to User, new EmailDigestLog model
|
||||
- `backend/schemas.py` — Added NotificationPreferences and NotificationPreferencesUpdate schemas
|
||||
- `backend/services/email.py` — New: HTML digest composer, smtplib sender, SMTP config gate
|
||||
- `backend/tasks/__init__.py` — New: package init for tasks module
|
||||
- `backend/tasks/notifications.py` — New: send_digest_emails Celery task with signed token generation
|
||||
- `backend/worker.py` — Added Beat schedule and tasks.notifications import
|
||||
- `backend/routers/notifications.py` — New: GET/PUT preferences, GET unsubscribe endpoints
|
||||
- `backend/main.py` — Mounted notifications router
|
||||
- `backend/tests/notifications/test_notifications.py` — New: 12 integration tests
|
||||
- `frontend/src/api/notifications.ts` — New: API client for notification preferences
|
||||
- `frontend/src/pages/CreatorSettings.tsx` — Added email notification toggle and frequency selector
|
||||
- `alembic/versions/029_add_email_digest.py` — New: migration adding notification_preferences column and email_digest_log table
|
||||
- `docker-compose.yml` — Added --beat flag to worker command
|
||||
106
.gsd/milestones/M025/slices/S01/S01-UAT.md
Normal file
106
.gsd/milestones/M025/slices/S01/S01-UAT.md
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
# S01: [A] Notification System (Email Digests) — UAT
|
||||
|
||||
**Milestone:** M025
|
||||
**Written:** 2026-04-04T12:29:14.844Z
|
||||
|
||||
## UAT: Email Digest Notification System
|
||||
|
||||
### Preconditions
|
||||
- Chrysopedia stack running on ub01 (docker compose up -d)
|
||||
- Alembic migration 029 applied (email_digest_log table + notification_preferences column exist)
|
||||
- At least one user, one creator, one published post or technique page in the database
|
||||
- A user following at least one creator via CreatorFollow
|
||||
|
||||
---
|
||||
|
||||
### TC-01: Notification Preferences — Read Defaults
|
||||
**Steps:**
|
||||
1. Authenticate as a user via `POST /api/v1/auth/login`
|
||||
2. `GET /api/v1/notifications/preferences` with auth token
|
||||
**Expected:** 200 with `{"email_digests": true, "digest_frequency": "daily"}` (server defaults)
|
||||
|
||||
### TC-02: Notification Preferences — Update
|
||||
**Steps:**
|
||||
1. Authenticate as a user
|
||||
2. `PUT /api/v1/notifications/preferences` with body `{"email_digests": false, "digest_frequency": "weekly"}`
|
||||
3. `GET /api/v1/notifications/preferences`
|
||||
**Expected:** PUT returns 200 with updated values. GET confirms persistence: `{"email_digests": false, "digest_frequency": "weekly"}`
|
||||
|
||||
### TC-03: Notification Preferences — Auth Required
|
||||
**Steps:**
|
||||
1. `GET /api/v1/notifications/preferences` without auth header
|
||||
2. `PUT /api/v1/notifications/preferences` without auth header
|
||||
**Expected:** Both return 401 Unauthorized
|
||||
|
||||
### TC-04: Notification Preferences — Invalid Frequency
|
||||
**Steps:**
|
||||
1. Authenticate as a user
|
||||
2. `PUT /api/v1/notifications/preferences` with body `{"digest_frequency": "hourly"}`
|
||||
**Expected:** 422 Validation Error (only "daily" and "weekly" allowed)
|
||||
|
||||
### TC-05: Unsubscribe — Valid Token
|
||||
**Steps:**
|
||||
1. Generate a signed unsubscribe token for a user (from digest task internals)
|
||||
2. `GET /api/v1/notifications/unsubscribe?token={token}`
|
||||
3. Verify user's notification_preferences in DB
|
||||
**Expected:** Returns HTML page with "successfully unsubscribed" message. User's email_digests set to false.
|
||||
|
||||
### TC-06: Unsubscribe — Expired Token
|
||||
**Steps:**
|
||||
1. Generate a token with exp set to a past timestamp
|
||||
2. `GET /api/v1/notifications/unsubscribe?token={expired_token}`
|
||||
**Expected:** Returns HTML error page indicating token has expired. User preferences unchanged.
|
||||
|
||||
### TC-07: Unsubscribe — Tampered Token
|
||||
**Steps:**
|
||||
1. Take a valid token and alter characters in the payload
|
||||
2. `GET /api/v1/notifications/unsubscribe?token={tampered}`
|
||||
**Expected:** Returns HTML error page indicating invalid link. User preferences unchanged.
|
||||
|
||||
### TC-08: Digest Task — Happy Path (Mocked SMTP)
|
||||
**Steps:**
|
||||
1. Create user with email_digests=true, following a creator
|
||||
2. Ensure creator has a published post with created_at after user's last digest (or no prior digest)
|
||||
3. Mock SMTP and invoke `send_digest_emails()` directly
|
||||
**Expected:** SMTP mock called once with HTML body containing creator name and post title. EmailDigestLog row created with correct user_id and content_summary JSONB.
|
||||
|
||||
### TC-09: Digest Task — No New Content
|
||||
**Steps:**
|
||||
1. Create user with email_digests=true, following a creator
|
||||
2. Set EmailDigestLog.digest_sent_at to now (already received all content)
|
||||
3. Invoke `send_digest_emails()`
|
||||
**Expected:** No email sent. No new EmailDigestLog row created. Task completes silently.
|
||||
|
||||
### TC-10: Digest Task — SMTP Unconfigured
|
||||
**Steps:**
|
||||
1. Ensure SMTP settings are default (empty host, empty from_address)
|
||||
2. Invoke `send_digest_emails()`
|
||||
**Expected:** Task returns immediately with warning log. No emails sent. No errors.
|
||||
|
||||
### TC-11: Celery Beat Schedule
|
||||
**Steps:**
|
||||
1. `cd backend && python -c "from worker import celery_app; s = celery_app.conf.beat_schedule['send-digest-emails']; print(s)"`
|
||||
**Expected:** Schedule shows crontab at hour=9, minute=0 (daily 09:00 UTC). Task name is `tasks.notifications.send_digest_emails`.
|
||||
|
||||
### TC-12: Docker Worker Beat Flag
|
||||
**Steps:**
|
||||
1. `grep '\-\-beat' docker-compose.yml`
|
||||
**Expected:** Worker command includes `--beat` flag.
|
||||
|
||||
### TC-13: Frontend — Email Toggle in Creator Settings
|
||||
**Steps:**
|
||||
1. Log in as a creator in the web UI
|
||||
2. Navigate to Creator Settings page
|
||||
3. Locate "Email Notifications" section
|
||||
**Expected:** Toggle switch for email digests (on by default). Frequency selector (daily/weekly) visible when toggle is on. Toggling off hides frequency selector. Changes persist on page reload.
|
||||
|
||||
### TC-14: Email HTML Content Quality
|
||||
**Steps:**
|
||||
1. Call `compose_digest_html("TestUser", [{"creator_name": "DJ Example", "posts": [{"title": "New Track Tips", "url": "/posts/1"}], "technique_pages": []}], "http://localhost/unsub")`
|
||||
2. Inspect returned HTML
|
||||
**Expected:** Valid HTML with inline CSS. Creator name "DJ Example" present. Post title "New Track Tips" present as a link. Unsubscribe link at bottom. No empty sections for technique_pages.
|
||||
|
||||
### TC-15: Empty Content Digest
|
||||
**Steps:**
|
||||
1. Call `compose_digest_html("TestUser", [], "http://localhost/unsub")`
|
||||
**Expected:** Returns minimal HTML with "no new content" or similar message. Does not error.
|
||||
16
.gsd/milestones/M025/slices/S01/tasks/T03-VERIFY.json
Normal file
16
.gsd/milestones/M025/slices/S01/tasks/T03-VERIFY.json
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"schemaVersion": 1,
|
||||
"taskId": "T03",
|
||||
"unitId": "M025/S01/T03",
|
||||
"timestamp": 1775305638071,
|
||||
"passed": true,
|
||||
"discoverySource": "task-plan",
|
||||
"checks": [
|
||||
{
|
||||
"command": "cd backend",
|
||||
"exitCode": 0,
|
||||
"durationMs": 8,
|
||||
"verdict": "pass"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,6 +1,138 @@
|
|||
# S02: [A] Mobile Responsiveness Pass
|
||||
|
||||
**Goal:** Mobile responsiveness pass across all new UI surfaces
|
||||
**Goal:** All Phase 2 UI surfaces pass visual check at 375px and 768px viewports — no overflow, no broken layouts, no unreadable text.
|
||||
**Demo:** After this: All new Phase 2 UI surfaces pass visual check at 375px and 768px
|
||||
|
||||
## Tasks
|
||||
- [x] **T01: Audited all 9 public-facing pages at 375px and 768px viewports — added ≤400px safety-net CSS for footer wrapping, stats gap, search card header, and technique header spacing** — ## Description
|
||||
|
||||
Audit all public-facing pages at 375px (iPhone SE) and 768px (iPad portrait) viewports and fix any layout breakages. This covers the highest-visibility surfaces and directly addresses R037 (homepage consistency at 375px) and R041 (sticky reading header at 375px).
|
||||
|
||||
**Pages to audit:** Home, TechniquePage, SearchResults, CreatorDetail, CreatorsBrowse, TopicsBrowse, SubTopicPage, ChatPage, About.
|
||||
|
||||
**Known issues from research:**
|
||||
- Homepage (R037): verify stats scorecard, how-it-works cards, recent-list, featured section at 375px. Known CSS bug: border-image kills border-radius on featured card.
|
||||
- TechniquePage (R041): has 600px breakpoint for title bar stacking. Verify sticky reading header at 375px — it should slide in when scrolling past article title.
|
||||
- SearchResults: uses App.css classes with existing responsive grid collapse — verify.
|
||||
- CreatorDetail: has 480px breakpoint — verify gap between that and 375px.
|
||||
|
||||
**Approach:**
|
||||
1. Start frontend dev server
|
||||
2. Set browser viewport to 375px width, navigate each page, screenshot
|
||||
3. Identify overflow, broken layout, unreadable text, or misalignment
|
||||
4. Fix CSS in App.css or relevant component files
|
||||
5. Repeat at 768px
|
||||
6. Verify hamburger nav (R021) still works — don't break it
|
||||
7. Run `npm run build` to confirm no errors
|
||||
|
||||
## Steps
|
||||
|
||||
1. Start the frontend dev server with `cd frontend && npm run dev`
|
||||
2. Set browser viewport to 375px width (600px height)
|
||||
3. Navigate to homepage — screenshot and check stats scorecard, how-it-works cards, featured section, recent-list alignment. Fix any issues in `frontend/src/App.css`
|
||||
4. Navigate to a technique page — screenshot. Verify sticky reading header appears on scroll and tracks sections at 375px. Check title bar stacking. Fix if needed.
|
||||
5. Navigate to SearchResults, CreatorDetail, CreatorsBrowse, TopicsBrowse, SubTopicPage, ChatPage, About — screenshot each. Fix any overflow or layout issues.
|
||||
6. Set browser viewport to 768px width — repeat navigation of all pages. Verify hamburger menu still works.
|
||||
7. Run `cd frontend && npm run build` to confirm zero errors.
|
||||
|
||||
## Must-Haves
|
||||
|
||||
- [ ] Homepage renders correctly at 375px — no horizontal overflow, cards stack properly, stats scorecard readable
|
||||
- [ ] Technique page sticky reading header works at 375px
|
||||
- [ ] All public pages have no horizontal overflow at 375px
|
||||
- [ ] All public pages render correctly at 768px
|
||||
- [ ] Hamburger nav (R021) still works — no regressions
|
||||
- [ ] `npm run build` passes
|
||||
|
||||
## Verification
|
||||
|
||||
- Browser screenshots at 375px and 768px for Home, TechniquePage, SearchResults, CreatorsBrowse, TopicsBrowse
|
||||
- `cd frontend && npm run build` exits 0
|
||||
- Estimate: 1h30m
|
||||
- Files: frontend/src/App.css, frontend/src/pages/Home.tsx, frontend/src/pages/TechniquePage.tsx, frontend/src/pages/SearchResults.tsx, frontend/src/pages/CreatorDetail.tsx, frontend/src/pages/CreatorsBrowse.tsx, frontend/src/pages/TopicsBrowse.tsx, frontend/src/pages/SubTopicPage.tsx, frontend/src/pages/ChatPage.tsx, frontend/src/pages/About.tsx
|
||||
- Verify: cd frontend && npm run build
|
||||
- [ ] **T02: Audit and fix creator dashboard and auth pages at 375px and 768px** — ## Description
|
||||
|
||||
Audit creator-facing dashboard pages, auth pages (Login/Register), and related UI at 375px and 768px viewports. Most dashboard pages already have responsive breakpoints. The primary gaps are ConsentDashboard.module.css and CreatorSettings.module.css (zero @media queries).
|
||||
|
||||
**Pages to audit:** CreatorDashboard, ConsentDashboard, CreatorSettings, CreatorTiers, PostEditor, PostsList, ChapterReview, HighlightQueue, WatchPage, Login, Register.
|
||||
|
||||
**Known issues from research:**
|
||||
- ConsentDashboard: `.toggleRow` uses `display: flex; justify-content: space-between` — may overflow at 375px if consent label text is long. Needs @media query to stack label/toggle vertically.
|
||||
- CreatorSettings: all single-column flex. `section` has `padding: 1.5rem` — may need reduction at 375px.
|
||||
- Login/Register: `max-width: 400px` with `padding: 1rem` container — should be fine at 375px but verify.
|
||||
- EmbedPlayer: no @media queries, may need mobile sizing check.
|
||||
|
||||
**Approach:** Same as T01 — dev server, viewport screenshots, fix CSS, verify build.
|
||||
|
||||
## Steps
|
||||
|
||||
1. Start the frontend dev server (or reuse if running)
|
||||
2. Set browser viewport to 375px width
|
||||
3. Navigate to Login page — screenshot. Check form card fits viewport. Fix padding if needed in `Login.module.css`.
|
||||
4. Navigate to Register page — screenshot. Same checks.
|
||||
5. Navigate to ConsentDashboard — screenshot. Check toggleRow alignment, card padding. Add @media queries to `ConsentDashboard.module.css` if toggle rows overflow.
|
||||
6. Navigate to CreatorSettings — screenshot. Check section padding. Add @media queries to `CreatorSettings.module.css` if needed.
|
||||
7. Navigate to CreatorDashboard, CreatorTiers, PostEditor, PostsList, HighlightQueue, WatchPage — screenshot each. Fix any overflow.
|
||||
8. Set browser viewport to 768px — repeat all pages.
|
||||
9. Run `cd frontend && npm run build`.
|
||||
|
||||
## Must-Haves
|
||||
|
||||
- [ ] ConsentDashboard toggle rows don't overflow at 375px
|
||||
- [ ] CreatorSettings form sections fit at 375px
|
||||
- [ ] Login and Register pages fit at 375px without horizontal scroll
|
||||
- [ ] All creator dashboard pages render correctly at 768px
|
||||
- [ ] `npm run build` passes
|
||||
|
||||
## Verification
|
||||
|
||||
- Browser screenshots at 375px and 768px for ConsentDashboard, CreatorSettings, Login, Register
|
||||
- `cd frontend && npm run build` exits 0
|
||||
- Estimate: 1h
|
||||
- Files: frontend/src/pages/ConsentDashboard.module.css, frontend/src/pages/CreatorSettings.module.css, frontend/src/pages/Login.module.css, frontend/src/pages/Register.module.css, frontend/src/pages/EmbedPlayer.module.css
|
||||
- Verify: cd frontend && npm run build
|
||||
- [ ] **T03: Audit and fix admin pages at 375px and 768px (R038 pipeline admin)** — ## Description
|
||||
|
||||
Audit admin pages at 375px and 768px viewports. The primary target is AdminPipeline.tsx (R038) which has known mobile issues: vertical text on job cards, stage direction chevrons not visible, status filter needing button group treatment. AdminReports, AdminTechniquePages, AdminUsers, and AdminAuditLog also need verification.
|
||||
|
||||
**R038 specific fixes:**
|
||||
- Mobile job cards showing vertical text → fix with min-width or overflow-hidden + text-overflow on grid children
|
||||
- Stage direction chevrons between pipeline stages → verify visible at 375px
|
||||
- Status filter UI → should be usable at 375px (buttons not cut off)
|
||||
- Creator dropdown → verify it populates and works on mobile
|
||||
|
||||
**Existing responsive rules:** App.css already has `@media (max-width: 768px)` blocks for `.pipeline-video__header` (grid to 1fr), `.run-card__header` (flex-wrap), `.admin-pipeline__filters` (column direction). The issues are likely within those rules not going far enough.
|
||||
|
||||
**AdminPipeline.tsx is 1699 lines** with BEM classes styled in App.css. All CSS changes go to App.css — no CSS module for this page.
|
||||
|
||||
**Other admin pages:** AdminUsers and AdminAuditLog have CSS modules with @media queries already. AdminReports and AdminTechniquePages use App.css BEM classes — verify they have responsive rules.
|
||||
|
||||
## Steps
|
||||
|
||||
1. Start the frontend dev server
|
||||
2. Set browser viewport to 375px width
|
||||
3. Navigate to AdminPipeline page — screenshot. Identify: (a) vertical text in job cards, (b) stage chevron visibility, (c) status filter layout, (d) creator dropdown usability.
|
||||
4. Fix pipeline admin CSS in `frontend/src/App.css` — add/refine @media rules for job card text, chevrons, filter buttons.
|
||||
5. Navigate to AdminReports — screenshot. Fix any overflow.
|
||||
6. Navigate to AdminTechniquePages — screenshot. Fix any overflow.
|
||||
7. Navigate to AdminUsers, AdminAuditLog — screenshot. Verify existing responsive rules work.
|
||||
8. Set browser viewport to 768px — repeat all admin pages.
|
||||
9. Run `cd frontend && npm run build`.
|
||||
|
||||
## Must-Haves
|
||||
|
||||
- [ ] Pipeline admin job cards readable at 375px — no vertical text (R038)
|
||||
- [ ] Stage direction chevrons visible at 375px (R038)
|
||||
- [ ] Status filter usable at 375px (R038)
|
||||
- [ ] Creator dropdown works on mobile (R038)
|
||||
- [ ] All admin pages render correctly at 768px
|
||||
- [ ] `npm run build` passes
|
||||
|
||||
## Verification
|
||||
|
||||
- Browser screenshots at 375px and 768px for AdminPipeline, AdminReports, AdminTechniquePages
|
||||
- `cd frontend && npm run build` exits 0
|
||||
- Estimate: 1h30m
|
||||
- Files: frontend/src/App.css, frontend/src/pages/AdminPipeline.tsx, frontend/src/pages/AdminReports.tsx, frontend/src/pages/AdminTechniquePages.tsx
|
||||
- Verify: cd frontend && npm run build
|
||||
|
|
|
|||
119
.gsd/milestones/M025/slices/S02/S02-RESEARCH.md
Normal file
119
.gsd/milestones/M025/slices/S02/S02-RESEARCH.md
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
# S02 Research — Mobile Responsiveness Pass
|
||||
|
||||
## Summary
|
||||
|
||||
This is a **light research** slice. The codebase already has extensive responsive breakpoints for most pages — the work is verifying coverage, fixing gaps, and testing at 375px/768px. No new technology, no unfamiliar APIs. The pattern is established: CSS media queries at 768px and 640px, CSS modules for Phase 2 pages, BEM classes in App.css for Phase 1 pages.
|
||||
|
||||
## Requirement Mapping
|
||||
|
||||
| Requirement | Status | Relevance |
|
||||
|---|---|---|
|
||||
| R037 | active | Homepage visual consistency at 375px — directly in scope |
|
||||
| R038 | active | Pipeline admin mobile fixes — directly in scope |
|
||||
| R041 | active | Sticky reading header at 375px — verify working |
|
||||
| R021 | validated | Mobile hamburger menu — already done, just verify no regressions |
|
||||
|
||||
## Implementation Landscape
|
||||
|
||||
### Current Responsive State
|
||||
|
||||
**Well-covered pages (have @media breakpoints):**
|
||||
- `App.css` — global shell, hamburger nav (768px), hero/homepage (640px), technique page columns (768px), watch page (768px), pipeline admin cards (768px)
|
||||
- `CreatorDashboard.module.css` — sidebar→horizontal tabs (768px), stat grid collapse (1024px, 768px), table→mobile cards (768px)
|
||||
- `ChatPage.module.css` — input stacking (640px)
|
||||
- `ChatWidget.module.css` — full-width panel (640px)
|
||||
- `HighlightQueue.module.css` — sidebar collapse, grid collapse (768px)
|
||||
- `ChapterReview.module.css` — waveform layout (768px)
|
||||
- `PostEditor.module.css` — sidebar collapse, footer stacking (768px)
|
||||
- `PostsList.module.css` — sidebar collapse (768px)
|
||||
- `CreatorTiers.module.css` — tier grid collapse (900px)
|
||||
- `PostsFeed.module.css` — card padding, attachment stacking (640px)
|
||||
- `ShortPlayer.module.css` — sizing (480px)
|
||||
- `AdminAuditLog.module.css` — table (600px)
|
||||
- `AdminUsers.module.css` — table (600px)
|
||||
|
||||
**Pages needing verification/fixes (no CSS module or no @media):**
|
||||
- `ConsentDashboard.module.css` — NO @media queries. Single-column layout should be naturally okay but needs verification at 375px (padding, toggle row alignment)
|
||||
- `CreatorSettings.module.css` — NO @media queries. Form layout is single-column, likely fine but padding may need adjustment
|
||||
- `Login.module.css` / `Register.module.css` — NO @media queries. Forms need width verification
|
||||
- `EmbedPlayer.module.css` — NO @media queries. Embed context may not need mobile but should verify
|
||||
|
||||
**Inline-styled pages (use BEM classes in App.css):**
|
||||
- `AdminPipeline.tsx` — Has App.css responsive rules already. R038 calls for specific fixes (mobile job cards, creator dropdown). 1699 lines — the largest page.
|
||||
- `AdminReports.tsx` — Inline styles, needs verification
|
||||
- `SearchResults.tsx` — Uses App.css classes, already has responsive grid collapse
|
||||
- `Home.tsx` — Uses App.css, already has 640px breakpoint for hero, nav-cards, recent-list
|
||||
|
||||
### Breakpoint Inconsistency
|
||||
|
||||
The codebase uses 4 different breakpoints: 480px, 600px, 640px, 768px. The primary breakpoints are:
|
||||
- **768px** — tablet/sidebar collapse (most common)
|
||||
- **640px** — narrow mobile (homepage, chat, player controls)
|
||||
- **600px** — some admin tables, technique title bar
|
||||
- **480px** — narrow mobile (creator detail, short player)
|
||||
|
||||
For this slice, test at **375px** (iPhone SE) and **768px** (iPad portrait) as stated in the success criteria.
|
||||
|
||||
### Key Problem Areas to Check
|
||||
|
||||
1. **Homepage (R037):** border-image killing border-radius on featured card is a known CSS bug (see KNOWLEDGE). The 375px layout needs stats scorecard, how-it-works cards, recent-list, and featured section to look correct.
|
||||
|
||||
2. **AdminPipeline (R038):** Known issues: mobile job cards showing vertical text, stage direction chevrons visibility, status filter UI. The page is 1699 lines with complex inline styling.
|
||||
|
||||
3. **Technique page title bar (R041):** Has 600px breakpoint for stacking. Need to verify at 375px that title truncation and section tracking work.
|
||||
|
||||
4. **ConsentDashboard:** Toggle rows (`display: flex; justify-content: space-between`) may overflow at 375px if label text is long.
|
||||
|
||||
5. **Login/Register:** Centered form cards — verify they don't overflow viewport width.
|
||||
|
||||
## Recommendation
|
||||
|
||||
### Task Decomposition
|
||||
|
||||
The work divides naturally into **3 tasks**:
|
||||
|
||||
**T01: Audit + Fix Public Pages (375px/768px)** — Homepage, TechniquePage, SearchResults, CreatorDetail, CreatorsBrowse, TopicsBrowse, SubTopicPage, ChatPage, About. These are visitor-facing. Start the dev server, use browser tools at 375px and 768px viewports to screenshot and identify issues, then fix CSS. Estimated 3-5 CSS fixes. This is highest priority because it's what users see.
|
||||
|
||||
**T02: Audit + Fix Creator Dashboard Pages (375px/768px)** — CreatorDashboard, ConsentDashboard, CreatorSettings, CreatorTiers, PostEditor, PostsList, ChapterReview, HighlightQueue, WatchPage. These are creator-facing behind auth. Most have responsive rules already. ConsentDashboard and CreatorSettings are the primary gaps. Login/Register also go here.
|
||||
|
||||
**T03: Audit + Fix Admin Pages (375px/768px)** — AdminPipeline (R038 fixes), AdminReports, AdminTechniquePages, AdminUsers, AdminAuditLog. Admin pages are lower priority but R038 specifically calls out pipeline admin fixes. This is the riskiest task due to AdminPipeline's size and inline styling.
|
||||
|
||||
### Verification Strategy
|
||||
|
||||
For each task:
|
||||
1. Start the frontend dev server
|
||||
2. Use `browser_set_viewport` at 375px and 768px widths
|
||||
3. Navigate to each page and screenshot
|
||||
4. Fix identified issues in CSS (App.css or relevant .module.css)
|
||||
5. Re-screenshot to confirm fixes
|
||||
6. Run `npm run build` to confirm no build errors
|
||||
|
||||
The final verification is visual — browser screenshots at both breakpoints for all pages.
|
||||
|
||||
### Build/Test Commands
|
||||
|
||||
```bash
|
||||
cd frontend && npm run build # Vite build — catches any import/syntax errors
|
||||
cd frontend && npm run dev # Dev server for browser verification
|
||||
```
|
||||
|
||||
### What to Build First
|
||||
|
||||
T01 (public pages) — it covers the most visible surfaces and R037/R041. T02 and T03 can run in parallel after T01 if the pattern is established.
|
||||
|
||||
## Files Likely Touched
|
||||
|
||||
- `frontend/src/App.css` — primary target for BEM-styled pages (homepage, technique page, search results, admin pipeline)
|
||||
- `frontend/src/pages/ConsentDashboard.module.css` — needs @media queries added
|
||||
- `frontend/src/pages/CreatorSettings.module.css` — may need @media queries
|
||||
- `frontend/src/pages/Login.module.css` — may need mobile padding
|
||||
- `frontend/src/pages/Register.module.css` — may need mobile padding
|
||||
- `frontend/src/pages/EmbedPlayer.module.css` — may need mobile sizing
|
||||
- `frontend/src/pages/AdminPipeline.tsx` — R038 inline style fixes
|
||||
|
||||
## Constraints
|
||||
|
||||
- No skill installation needed — this is pure CSS/responsive work
|
||||
- All existing responsive patterns use CSS media queries (not JS-based responsive) — maintain this pattern
|
||||
- The `app-main` container has `max-width: 72rem` and `padding: 0 1.5rem` — this provides baseline mobile safety for all pages
|
||||
- The hamburger menu (R021) and skip-link (R023) are already validated — don't break them
|
||||
66
.gsd/milestones/M025/slices/S02/tasks/T01-PLAN.md
Normal file
66
.gsd/milestones/M025/slices/S02/tasks/T01-PLAN.md
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
---
|
||||
estimated_steps: 34
|
||||
estimated_files: 10
|
||||
skills_used: []
|
||||
---
|
||||
|
||||
# T01: Audit and fix public-facing pages at 375px and 768px
|
||||
|
||||
## Description
|
||||
|
||||
Audit all public-facing pages at 375px (iPhone SE) and 768px (iPad portrait) viewports and fix any layout breakages. This covers the highest-visibility surfaces and directly addresses R037 (homepage consistency at 375px) and R041 (sticky reading header at 375px).
|
||||
|
||||
**Pages to audit:** Home, TechniquePage, SearchResults, CreatorDetail, CreatorsBrowse, TopicsBrowse, SubTopicPage, ChatPage, About.
|
||||
|
||||
**Known issues from research:**
|
||||
- Homepage (R037): verify stats scorecard, how-it-works cards, recent-list, featured section at 375px. Known CSS bug: border-image kills border-radius on featured card.
|
||||
- TechniquePage (R041): has 600px breakpoint for title bar stacking. Verify sticky reading header at 375px — it should slide in when scrolling past article title.
|
||||
- SearchResults: uses App.css classes with existing responsive grid collapse — verify.
|
||||
- CreatorDetail: has 480px breakpoint — verify gap between that and 375px.
|
||||
|
||||
**Approach:**
|
||||
1. Start frontend dev server
|
||||
2. Set browser viewport to 375px width, navigate each page, screenshot
|
||||
3. Identify overflow, broken layout, unreadable text, or misalignment
|
||||
4. Fix CSS in App.css or relevant component files
|
||||
5. Repeat at 768px
|
||||
6. Verify hamburger nav (R021) still works — don't break it
|
||||
7. Run `npm run build` to confirm no errors
|
||||
|
||||
## Steps
|
||||
|
||||
1. Start the frontend dev server with `cd frontend && npm run dev`
|
||||
2. Set browser viewport to 375px width (600px height)
|
||||
3. Navigate to homepage — screenshot and check stats scorecard, how-it-works cards, featured section, recent-list alignment. Fix any issues in `frontend/src/App.css`
|
||||
4. Navigate to a technique page — screenshot. Verify sticky reading header appears on scroll and tracks sections at 375px. Check title bar stacking. Fix if needed.
|
||||
5. Navigate to SearchResults, CreatorDetail, CreatorsBrowse, TopicsBrowse, SubTopicPage, ChatPage, About — screenshot each. Fix any overflow or layout issues.
|
||||
6. Set browser viewport to 768px width — repeat navigation of all pages. Verify hamburger menu still works.
|
||||
7. Run `cd frontend && npm run build` to confirm zero errors.
|
||||
|
||||
## Must-Haves
|
||||
|
||||
- [ ] Homepage renders correctly at 375px — no horizontal overflow, cards stack properly, stats scorecard readable
|
||||
- [ ] Technique page sticky reading header works at 375px
|
||||
- [ ] All public pages have no horizontal overflow at 375px
|
||||
- [ ] All public pages render correctly at 768px
|
||||
- [ ] Hamburger nav (R021) still works — no regressions
|
||||
- [ ] `npm run build` passes
|
||||
|
||||
## Verification
|
||||
|
||||
- Browser screenshots at 375px and 768px for Home, TechniquePage, SearchResults, CreatorsBrowse, TopicsBrowse
|
||||
- `cd frontend && npm run build` exits 0
|
||||
|
||||
## Inputs
|
||||
|
||||
- ``frontend/src/App.css` — main BEM stylesheet with existing @media queries for homepage, technique page, search results`
|
||||
- ``frontend/src/pages/Home.tsx` — homepage component`
|
||||
- ``frontend/src/pages/TechniquePage.tsx` — technique page with sticky reading header (R041)`
|
||||
|
||||
## Expected Output
|
||||
|
||||
- ``frontend/src/App.css` — additional/fixed @media queries for 375px public page layouts`
|
||||
|
||||
## Verification
|
||||
|
||||
cd frontend && npm run build
|
||||
76
.gsd/milestones/M025/slices/S02/tasks/T01-SUMMARY.md
Normal file
76
.gsd/milestones/M025/slices/S02/tasks/T01-SUMMARY.md
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
---
|
||||
id: T01
|
||||
parent: S02
|
||||
milestone: M025
|
||||
provides: []
|
||||
requires: []
|
||||
affects: []
|
||||
key_files: ["frontend/src/App.css"]
|
||||
key_decisions: ["Added ≤400px breakpoint as safety net for 375px phones rather than modifying existing 640px breakpoint"]
|
||||
patterns_established: []
|
||||
drill_down_paths: []
|
||||
observability_surfaces: []
|
||||
duration: ""
|
||||
verification_result: "Browser screenshots at 375px and 768px for all public pages — no overflow or layout breakages. scrollWidth check returned false on all pages. Hamburger nav tested and working at 768px. npm run build exited 0."
|
||||
completed_at: 2026-04-04T12:47:57.612Z
|
||||
blocker_discovered: false
|
||||
---
|
||||
|
||||
# T01: Audited all 9 public-facing pages at 375px and 768px viewports — added ≤400px safety-net CSS for footer wrapping, stats gap, search card header, and technique header spacing
|
||||
|
||||
> Audited all 9 public-facing pages at 375px and 768px viewports — added ≤400px safety-net CSS for footer wrapping, stats gap, search card header, and technique header spacing
|
||||
|
||||
## What Happened
|
||||
---
|
||||
id: T01
|
||||
parent: S02
|
||||
milestone: M025
|
||||
key_files:
|
||||
- frontend/src/App.css
|
||||
key_decisions:
|
||||
- Added ≤400px breakpoint as safety net for 375px phones rather than modifying existing 640px breakpoint
|
||||
duration: ""
|
||||
verification_result: passed
|
||||
completed_at: 2026-04-04T12:47:57.612Z
|
||||
blocker_discovered: false
|
||||
---
|
||||
|
||||
# T01: Audited all 9 public-facing pages at 375px and 768px viewports — added ≤400px safety-net CSS for footer wrapping, stats gap, search card header, and technique header spacing
|
||||
|
||||
**Audited all 9 public-facing pages at 375px and 768px viewports — added ≤400px safety-net CSS for footer wrapping, stats gap, search card header, and technique header spacing**
|
||||
|
||||
## What Happened
|
||||
|
||||
Spun up Vite dev server and used browser mocks to render realistic content on all public pages. Existing responsive CSS was in good shape — 640px and 768px breakpoints handle card stacking, grid collapse, search form stacking, and hamburger nav correctly. No horizontal overflow found on any page at 375px. Added a ≤400px media query block as safety net for narrowest phone screens with fixes for footer flex-wrap, home-stats gap, search card header wrapping, technique header gap, and page padding.
|
||||
|
||||
## Verification
|
||||
|
||||
Browser screenshots at 375px and 768px for all public pages — no overflow or layout breakages. scrollWidth check returned false on all pages. Hamburger nav tested and working at 768px. npm run build exited 0.
|
||||
|
||||
## Verification Evidence
|
||||
|
||||
| # | Command | Exit Code | Verdict | Duration |
|
||||
|---|---------|-----------|---------|----------|
|
||||
| 1 | `cd frontend && npm run build` | 0 | ✅ pass | 14100ms |
|
||||
| 2 | `browser overflow check (375px, all public pages)` | 0 | ✅ pass | 2000ms |
|
||||
| 3 | `browser hamburger nav assert (768px)` | 0 | ✅ pass | 1000ms |
|
||||
|
||||
|
||||
## Deviations
|
||||
|
||||
None. Existing responsive CSS was more complete than anticipated — additions are defensive rather than fixing visible breakages.
|
||||
|
||||
## Known Issues
|
||||
|
||||
None.
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `frontend/src/App.css`
|
||||
|
||||
|
||||
## Deviations
|
||||
None. Existing responsive CSS was more complete than anticipated — additions are defensive rather than fixing visible breakages.
|
||||
|
||||
## Known Issues
|
||||
None.
|
||||
64
.gsd/milestones/M025/slices/S02/tasks/T02-PLAN.md
Normal file
64
.gsd/milestones/M025/slices/S02/tasks/T02-PLAN.md
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
---
|
||||
estimated_steps: 28
|
||||
estimated_files: 5
|
||||
skills_used: []
|
||||
---
|
||||
|
||||
# T02: Audit and fix creator dashboard and auth pages at 375px and 768px
|
||||
|
||||
## Description
|
||||
|
||||
Audit creator-facing dashboard pages, auth pages (Login/Register), and related UI at 375px and 768px viewports. Most dashboard pages already have responsive breakpoints. The primary gaps are ConsentDashboard.module.css and CreatorSettings.module.css (zero @media queries).
|
||||
|
||||
**Pages to audit:** CreatorDashboard, ConsentDashboard, CreatorSettings, CreatorTiers, PostEditor, PostsList, ChapterReview, HighlightQueue, WatchPage, Login, Register.
|
||||
|
||||
**Known issues from research:**
|
||||
- ConsentDashboard: `.toggleRow` uses `display: flex; justify-content: space-between` — may overflow at 375px if consent label text is long. Needs @media query to stack label/toggle vertically.
|
||||
- CreatorSettings: all single-column flex. `section` has `padding: 1.5rem` — may need reduction at 375px.
|
||||
- Login/Register: `max-width: 400px` with `padding: 1rem` container — should be fine at 375px but verify.
|
||||
- EmbedPlayer: no @media queries, may need mobile sizing check.
|
||||
|
||||
**Approach:** Same as T01 — dev server, viewport screenshots, fix CSS, verify build.
|
||||
|
||||
## Steps
|
||||
|
||||
1. Start the frontend dev server (or reuse if running)
|
||||
2. Set browser viewport to 375px width
|
||||
3. Navigate to Login page — screenshot. Check form card fits viewport. Fix padding if needed in `Login.module.css`.
|
||||
4. Navigate to Register page — screenshot. Same checks.
|
||||
5. Navigate to ConsentDashboard — screenshot. Check toggleRow alignment, card padding. Add @media queries to `ConsentDashboard.module.css` if toggle rows overflow.
|
||||
6. Navigate to CreatorSettings — screenshot. Check section padding. Add @media queries to `CreatorSettings.module.css` if needed.
|
||||
7. Navigate to CreatorDashboard, CreatorTiers, PostEditor, PostsList, HighlightQueue, WatchPage — screenshot each. Fix any overflow.
|
||||
8. Set browser viewport to 768px — repeat all pages.
|
||||
9. Run `cd frontend && npm run build`.
|
||||
|
||||
## Must-Haves
|
||||
|
||||
- [ ] ConsentDashboard toggle rows don't overflow at 375px
|
||||
- [ ] CreatorSettings form sections fit at 375px
|
||||
- [ ] Login and Register pages fit at 375px without horizontal scroll
|
||||
- [ ] All creator dashboard pages render correctly at 768px
|
||||
- [ ] `npm run build` passes
|
||||
|
||||
## Verification
|
||||
|
||||
- Browser screenshots at 375px and 768px for ConsentDashboard, CreatorSettings, Login, Register
|
||||
- `cd frontend && npm run build` exits 0
|
||||
|
||||
## Inputs
|
||||
|
||||
- ``frontend/src/pages/ConsentDashboard.module.css` — no @media queries, toggleRow may overflow at 375px`
|
||||
- ``frontend/src/pages/CreatorSettings.module.css` — no @media queries, section padding may need adjustment`
|
||||
- ``frontend/src/pages/Login.module.css` — no @media queries, max-width 400px card`
|
||||
- ``frontend/src/pages/Register.module.css` — no @media queries`
|
||||
|
||||
## Expected Output
|
||||
|
||||
- ``frontend/src/pages/ConsentDashboard.module.css` — @media queries added for 375px/768px`
|
||||
- ``frontend/src/pages/CreatorSettings.module.css` — @media queries added if needed`
|
||||
- ``frontend/src/pages/Login.module.css` — mobile padding adjustments if needed`
|
||||
- ``frontend/src/pages/Register.module.css` — mobile padding adjustments if needed`
|
||||
|
||||
## Verification
|
||||
|
||||
cd frontend && npm run build
|
||||
62
.gsd/milestones/M025/slices/S02/tasks/T03-PLAN.md
Normal file
62
.gsd/milestones/M025/slices/S02/tasks/T03-PLAN.md
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
---
|
||||
estimated_steps: 30
|
||||
estimated_files: 4
|
||||
skills_used: []
|
||||
---
|
||||
|
||||
# T03: Audit and fix admin pages at 375px and 768px (R038 pipeline admin)
|
||||
|
||||
## Description
|
||||
|
||||
Audit admin pages at 375px and 768px viewports. The primary target is AdminPipeline.tsx (R038) which has known mobile issues: vertical text on job cards, stage direction chevrons not visible, status filter needing button group treatment. AdminReports, AdminTechniquePages, AdminUsers, and AdminAuditLog also need verification.
|
||||
|
||||
**R038 specific fixes:**
|
||||
- Mobile job cards showing vertical text → fix with min-width or overflow-hidden + text-overflow on grid children
|
||||
- Stage direction chevrons between pipeline stages → verify visible at 375px
|
||||
- Status filter UI → should be usable at 375px (buttons not cut off)
|
||||
- Creator dropdown → verify it populates and works on mobile
|
||||
|
||||
**Existing responsive rules:** App.css already has `@media (max-width: 768px)` blocks for `.pipeline-video__header` (grid to 1fr), `.run-card__header` (flex-wrap), `.admin-pipeline__filters` (column direction). The issues are likely within those rules not going far enough.
|
||||
|
||||
**AdminPipeline.tsx is 1699 lines** with BEM classes styled in App.css. All CSS changes go to App.css — no CSS module for this page.
|
||||
|
||||
**Other admin pages:** AdminUsers and AdminAuditLog have CSS modules with @media queries already. AdminReports and AdminTechniquePages use App.css BEM classes — verify they have responsive rules.
|
||||
|
||||
## Steps
|
||||
|
||||
1. Start the frontend dev server
|
||||
2. Set browser viewport to 375px width
|
||||
3. Navigate to AdminPipeline page — screenshot. Identify: (a) vertical text in job cards, (b) stage chevron visibility, (c) status filter layout, (d) creator dropdown usability.
|
||||
4. Fix pipeline admin CSS in `frontend/src/App.css` — add/refine @media rules for job card text, chevrons, filter buttons.
|
||||
5. Navigate to AdminReports — screenshot. Fix any overflow.
|
||||
6. Navigate to AdminTechniquePages — screenshot. Fix any overflow.
|
||||
7. Navigate to AdminUsers, AdminAuditLog — screenshot. Verify existing responsive rules work.
|
||||
8. Set browser viewport to 768px — repeat all admin pages.
|
||||
9. Run `cd frontend && npm run build`.
|
||||
|
||||
## Must-Haves
|
||||
|
||||
- [ ] Pipeline admin job cards readable at 375px — no vertical text (R038)
|
||||
- [ ] Stage direction chevrons visible at 375px (R038)
|
||||
- [ ] Status filter usable at 375px (R038)
|
||||
- [ ] Creator dropdown works on mobile (R038)
|
||||
- [ ] All admin pages render correctly at 768px
|
||||
- [ ] `npm run build` passes
|
||||
|
||||
## Verification
|
||||
|
||||
- Browser screenshots at 375px and 768px for AdminPipeline, AdminReports, AdminTechniquePages
|
||||
- `cd frontend && npm run build` exits 0
|
||||
|
||||
## Inputs
|
||||
|
||||
- ``frontend/src/App.css` — BEM styles for admin pipeline with existing 768px @media block (lines ~6108-6135)`
|
||||
- ``frontend/src/pages/AdminPipeline.tsx` — 1699-line admin page with BEM class usage`
|
||||
|
||||
## Expected Output
|
||||
|
||||
- ``frontend/src/App.css` — refined/additional @media queries for admin pipeline mobile layout (R038)`
|
||||
|
||||
## Verification
|
||||
|
||||
cd frontend && npm run build
|
||||
|
|
@ -3281,6 +3281,56 @@ a.app-footer__repo:hover {
|
|||
}
|
||||
}
|
||||
|
||||
/* ── Narrow mobile (≤ 400px) — safety-net for 375px phones ───────────── */
|
||||
|
||||
@media (max-width: 400px) {
|
||||
/* Footer: allow wrapping when items don't fit on one line */
|
||||
.app-footer {
|
||||
flex-wrap: wrap;
|
||||
gap: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
/* Stats scorecard: tighten gap */
|
||||
.home-stats {
|
||||
gap: 1.25rem;
|
||||
padding: 0.75rem 1rem;
|
||||
}
|
||||
|
||||
.home-stats__number {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
/* Search result card header: allow title to wrap */
|
||||
.search-result-card__header {
|
||||
flex-wrap: wrap;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
/* Technique page: tighter header padding */
|
||||
.technique-header__title-row {
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
/* Featured section: reduce padding */
|
||||
.home-featured {
|
||||
padding: 0.875rem 1rem;
|
||||
}
|
||||
|
||||
.home-featured__meta {
|
||||
gap: 0.25rem 0.375rem;
|
||||
}
|
||||
|
||||
/* Page padding: consistent horizontal margins */
|
||||
.search-results-page,
|
||||
.creators-browse,
|
||||
.topics-browse,
|
||||
.subtopic-page,
|
||||
.chat-page {
|
||||
padding-left: 0.75rem;
|
||||
padding-right: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── Mobile narrow (≤480px) — Creator detail page ─────────────────────── */
|
||||
|
||||
@media (max-width: 480px) {
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"root":["./src/App.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/api/admin-pipeline.ts","./src/api/admin-techniques.ts","./src/api/auth.ts","./src/api/chat.ts","./src/api/client.ts","./src/api/consent.ts","./src/api/creator-dashboard.ts","./src/api/creators.ts","./src/api/follows.ts","./src/api/highlights.ts","./src/api/index.ts","./src/api/posts.ts","./src/api/reports.ts","./src/api/search.ts","./src/api/shorts.ts","./src/api/stats.ts","./src/api/techniques.ts","./src/api/templates.ts","./src/api/topics.ts","./src/api/videos.ts","./src/components/AdminDropdown.tsx","./src/components/AppFooter.tsx","./src/components/AudioWaveform.tsx","./src/components/CategoryIcons.tsx","./src/components/ChapterMarkers.tsx","./src/components/ChatWidget.tsx","./src/components/ConfirmModal.tsx","./src/components/CopyLinkButton.tsx","./src/components/CreatorAvatar.tsx","./src/components/ImpersonationBanner.tsx","./src/components/PersonalityProfile.tsx","./src/components/PlayerControls.tsx","./src/components/PostsFeed.tsx","./src/components/ProtectedRoute.tsx","./src/components/ReportIssueModal.tsx","./src/components/SearchAutocomplete.tsx","./src/components/SocialIcons.tsx","./src/components/SortDropdown.tsx","./src/components/TableOfContents.tsx","./src/components/TagList.tsx","./src/components/ToggleSwitch.tsx","./src/components/TranscriptSidebar.tsx","./src/components/VideoPlayer.tsx","./src/context/AuthContext.tsx","./src/hooks/useCountUp.ts","./src/hooks/useDocumentTitle.ts","./src/hooks/useMediaSync.ts","./src/hooks/useSortPreference.ts","./src/pages/About.tsx","./src/pages/AdminAuditLog.tsx","./src/pages/AdminPipeline.tsx","./src/pages/AdminReports.tsx","./src/pages/AdminTechniquePages.tsx","./src/pages/AdminUsers.tsx","./src/pages/ChapterReview.tsx","./src/pages/ChatPage.tsx","./src/pages/ConsentDashboard.tsx","./src/pages/CreatorDashboard.tsx","./src/pages/CreatorDetail.tsx","./src/pages/CreatorSettings.tsx","./src/pages/CreatorTiers.tsx","./src/pages/CreatorsBrowse.tsx","./src/pages/EmbedPlayer.tsx","./src/pages/HighlightQueue.tsx","./src/pages/Home.tsx","./src/pages/Login.tsx","./src/pages/PostEditor.tsx","./src/pages/PostsList.tsx","./src/pages/Register.tsx","./src/pages/SearchResults.tsx","./src/pages/ShortPlayer.tsx","./src/pages/SubTopicPage.tsx","./src/pages/TechniquePage.tsx","./src/pages/TopicsBrowse.tsx","./src/pages/WatchPage.tsx","./src/utils/catSlug.ts","./src/utils/chatCitations.tsx","./src/utils/citations.tsx","./src/utils/clipboard.ts","./src/utils/formatTime.ts"],"version":"5.6.3"}
|
||||
{"root":["./src/App.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/api/admin-pipeline.ts","./src/api/admin-techniques.ts","./src/api/auth.ts","./src/api/chat.ts","./src/api/client.ts","./src/api/consent.ts","./src/api/creator-dashboard.ts","./src/api/creators.ts","./src/api/follows.ts","./src/api/highlights.ts","./src/api/index.ts","./src/api/notifications.ts","./src/api/posts.ts","./src/api/reports.ts","./src/api/search.ts","./src/api/shorts.ts","./src/api/stats.ts","./src/api/techniques.ts","./src/api/templates.ts","./src/api/topics.ts","./src/api/videos.ts","./src/components/AdminDropdown.tsx","./src/components/AppFooter.tsx","./src/components/AudioWaveform.tsx","./src/components/CategoryIcons.tsx","./src/components/ChapterMarkers.tsx","./src/components/ChatWidget.tsx","./src/components/ConfirmModal.tsx","./src/components/CopyLinkButton.tsx","./src/components/CreatorAvatar.tsx","./src/components/ImpersonationBanner.tsx","./src/components/PersonalityProfile.tsx","./src/components/PlayerControls.tsx","./src/components/PostsFeed.tsx","./src/components/ProtectedRoute.tsx","./src/components/ReportIssueModal.tsx","./src/components/SearchAutocomplete.tsx","./src/components/SocialIcons.tsx","./src/components/SortDropdown.tsx","./src/components/TableOfContents.tsx","./src/components/TagList.tsx","./src/components/ToggleSwitch.tsx","./src/components/TranscriptSidebar.tsx","./src/components/VideoPlayer.tsx","./src/context/AuthContext.tsx","./src/hooks/useCountUp.ts","./src/hooks/useDocumentTitle.ts","./src/hooks/useMediaSync.ts","./src/hooks/useSortPreference.ts","./src/pages/About.tsx","./src/pages/AdminAuditLog.tsx","./src/pages/AdminPipeline.tsx","./src/pages/AdminReports.tsx","./src/pages/AdminTechniquePages.tsx","./src/pages/AdminUsers.tsx","./src/pages/ChapterReview.tsx","./src/pages/ChatPage.tsx","./src/pages/ConsentDashboard.tsx","./src/pages/CreatorDashboard.tsx","./src/pages/CreatorDetail.tsx","./src/pages/CreatorSettings.tsx","./src/pages/CreatorTiers.tsx","./src/pages/CreatorsBrowse.tsx","./src/pages/EmbedPlayer.tsx","./src/pages/HighlightQueue.tsx","./src/pages/Home.tsx","./src/pages/Login.tsx","./src/pages/PostEditor.tsx","./src/pages/PostsList.tsx","./src/pages/Register.tsx","./src/pages/SearchResults.tsx","./src/pages/ShortPlayer.tsx","./src/pages/SubTopicPage.tsx","./src/pages/TechniquePage.tsx","./src/pages/TopicsBrowse.tsx","./src/pages/WatchPage.tsx","./src/utils/catSlug.ts","./src/utils/chatCitations.tsx","./src/utils/citations.tsx","./src/utils/clipboard.ts","./src/utils/formatTime.ts"],"version":"5.6.3"}
|
||||
Loading…
Add table
Reference in a new issue