# Frontend React / Vite / Design ## Source Of Truth Frontend visual and interaction design uses the installed `frontend-design` skill as the primary design authority. `docs/产品设计规则.md` remains a product, brand and historical fact source, not the final aesthetic tie-breaker. For PC/mobile/WeCom pages, add Playwright or visual verification when reasonable. ## Rules - Use existing React/Vite/Tailwind patterns and shared components before adding page-local UI systems. - When `frontend-design` and older project visual rules conflict, follow `frontend-design` for visual direction while preserving security, privacy, Trellis, deployment and business data boundaries. - PC pages should keep dense but orderly OA layouts: clear header, filters, table/list, status, details and predictable actions. - Mobile pages must use the unified mobile shell, card/list rows, safe-area and sticky action patterns from the design rules. - Do not add decorative landing-page styling to operational OA pages. - Run `cd client && npm run typecheck && npm run build` for frontend changes. ## Frozen / Boundary Items Frozen modules and Enterprise WeChat-owned HR/attendance entries must be labeled or hidden according to the active Issue; do not silently re-enable them. - Use the shared `WorkspaceNotice` pattern for trial boundaries, safety notes, and post-trial capabilities instead of page-local warning blocks. - Trial-facing PC lists must hide obvious TEST/SMOKE records by default when a page-level toggle exists; the toggle may reveal them for troubleshooting. ## Scenario: Auth Pages And PWA Updates ### 1. Scope / Trigger - Trigger: login, password change, password recovery or other unauthenticated forms are active while the PWA service worker finds a new frontend version. - Applies to `client/src/pwa.ts`, `client/src/layouts/AuthLayout.tsx`, and auth routes such as `/login`, `/change-password`, `/forgot-password`, and future reset-password pages. ### 2. Signatures - Event name: `hyb-oa:pwa-update-ready`. - Event detail: `{ applyUpdate?: () => void | Promise }`. - Route predicate: auth input pages must be checked by pathname before calling `updateServiceWorker(true)`. ### 3. Contracts - Auth input pages must not auto-reload when `onNeedRefresh()` fires. - Auth input pages must show an explicit update prompt with a user-triggered refresh action. - Non-auth pages may keep automatic service-worker update behavior when the task does not change broader runtime policy. - Passwords and verification codes must stay only in React component state; do not write them to `localStorage`, `sessionStorage`, URL params, reports, or Trellis task evidence. - Password visibility controls must use icon buttons with accessible labels and preserve the current input value. ### 4. Validation & Error Matrix - PWA update on `/login` -> dispatch update-ready event and keep form state. - PWA update on `/forgot-password` -> dispatch update-ready event and keep email/code/password fields in memory. - User clicks refresh in the prompt -> run the captured update handler. - User dismisses prompt -> no reload and no form reset. - Password reset request returns success for any email -> show generic sent message; do not reveal whether the account exists. ### 5. Good/Base/Bad Cases - Good: user is typing a password, update prompt appears, typed values remain. - Base: user is on a normal portal page, PWA update can refresh per existing runtime behavior. - Bad: service-worker update auto-refreshes an auth form and clears credentials. - Bad: tests use real-looking personal email addresses or persist example passwords outside the test file. ### 6. Tests Required - Frontend typecheck and build. - Focused Playwright auth UX test asserting: - login password can be shown/hidden without losing value; - forgot-password flow calls request-code and reset endpoints; - auth-page PWA update prompt appears without clearing inputs. - UI design rules check when auth page layout changes. ### 7. Wrong vs Correct #### Wrong ```ts onNeedRefresh() { void updateServiceWorker?.(true); } ``` #### Correct ```ts onNeedRefresh() { if (isAuthInputPath(window.location.pathname)) { window.dispatchEvent(new CustomEvent(PWA_UPDATE_READY_EVENT, { detail: { applyUpdate } })); return; } applyUpdate(); } ``` ## Scenario: Auth Page Layout And Login Entry Hierarchy ### 1. Scope / Trigger - Trigger: login, password recovery, forced password change or future unauthenticated auth forms need layout changes. - Applies to `client/src/layouts/AuthLayout.tsx`, shared auth components under `client/src/components/auth/`, and auth routes such as `/login`, `/forgot-password` and `/change-password`. ### 2. Component Contract - Auth routes should use one shared auth panel for brand, page title, subtitle, content and optional footer links. - `AuthLayout` owns only the auth page shell: background, width constraint, centering, PWA update prompt and route outlet. - Page implementations own only their form fields, submit actions, validation messages and route-specific login-entry choices. ### 3. Visual Contracts - Do not nest a form card inside another login card. - Put the brand block inside the auth panel so logo, system name, title and form share one visual axis. - Keep the panel width stable around the current auth-shell width; auth pages should feel like an OA workstation entry, not a marketing split hero. - Place `忘记密码?` beside the password label or directly below the password input on the right; do not bury it in help text or page footer. - Use password visibility icon buttons with accessible labels and preserve the current input value. ### 4. Login Entry Hierarchy - Normal browser: account/password login is primary; Enterprise WeChat and OIDC entries belong below the primary submit button as secondary methods. - Enterprise WeChat WebView: Enterprise WeChat one-click entry is primary; account/password login remains available as the fallback path. - Enterprise WeChat entry changes must remain frontend entry hierarchy changes unless the task explicitly approves backend OAuth, binding or WeCom API work. - Email verification-code login is a separate login mode. Do not infer it from password-recovery verification-code flows without a backend login-code contract and abuse-control plan. ### 5. Tests Required - Frontend typecheck and build. - Focused auth E2E covering: - password visibility and forgot-password navigation on `/login`; - password recovery request-code and reset flow on `/forgot-password`; - normal-browser Enterprise WeChat entry as secondary CTA; - WeCom WebView Enterprise WeChat entry as primary CTA with password fallback. - UI design rules check and Playwright screenshot evidence when the auth layout changes visibly. ### 6. Wrong vs Correct #### Wrong ```tsx ``` #### Correct ```tsx ```