commit
This commit is contained in:
424
docs/reviews/phase-4-ui-ux-design-system-audit.md
Normal file
424
docs/reviews/phase-4-ui-ux-design-system-audit.md
Normal file
@@ -0,0 +1,424 @@
|
||||
# Phase 4 - UI/UX & Design System Audit
|
||||
|
||||
## Executive Summary
|
||||
|
||||
The dashboard already has a usable shared UI foundation through `PageContainer`, shadcn primitives, shared table utilities, and consistent card-based page composition. Responsive handling is generally better than average for an admin system because many key layouts already use `min-w-0`, wrapping button groups, and scoped table overflow.
|
||||
|
||||
The largest UI/UX problem is not layout instability but system inconsistency. Several feature areas still diverge from the intended design system, especially reports tables, file-upload flows, heading structure, and copy quality. The most visible issue across the entire UI is widespread Thai text encoding corruption, which materially harms readability, trust, and learnability.
|
||||
|
||||
## Screen Inventory
|
||||
|
||||
Primary screens reviewed:
|
||||
|
||||
- Dashboard shell and sidebar
|
||||
- Organization switcher and user menu
|
||||
- Employee directory list
|
||||
- Training records form and review-oriented detail states
|
||||
- Announcements form and detail view
|
||||
- Online lessons form
|
||||
- Reports page
|
||||
- Notifications page
|
||||
- Audit logs table
|
||||
- Shared page header, heading, data table, toolbar, pagination, notification card
|
||||
|
||||
## Layout Assessment
|
||||
|
||||
Strengths:
|
||||
|
||||
- `src/components/layout/page-container.tsx` gives pages a stable shell with responsive spacing and full-width containment.
|
||||
- Shared tables correctly scope horizontal overflow inside the table shell instead of the full page.
|
||||
- Header actions commonly wrap well on small screens.
|
||||
|
||||
Weaknesses:
|
||||
|
||||
- Header patterns are inconsistent. Some pages use `PageContainer` header only, while others inject another local hero/header block inside the page body, creating double-header behavior.
|
||||
- Reports stack multiple large cards and wide tables vertically, which is workable but visually heavy and cognitively dense.
|
||||
- Access fallback inside `PageContainer` is centered plain text rather than a full empty/error-state pattern.
|
||||
|
||||
## Typography Assessment
|
||||
|
||||
Strengths:
|
||||
|
||||
- Core sizes are mostly sensible: large page titles, smaller descriptions, readable card body text.
|
||||
- Tables generally keep compact admin-dashboard typography.
|
||||
|
||||
Weaknesses:
|
||||
|
||||
- Typography hierarchy is semantically inconsistent because `Heading` renders `h2` while feature pages often behave like top-level page titles.
|
||||
- Some screens add their own `h1` under `PageContainer`, producing mixed heading structures across modules.
|
||||
- Thai text corruption appears in navigation, headers, descriptions, pagination labels, and empty states across many files, which is the most serious typography/content issue in the system.
|
||||
- Copy style mixes Thai and English unevenly, for example `PageContainer` access fallback remains English while most feature UI is Thai.
|
||||
|
||||
## Color & Status Assessment
|
||||
|
||||
Strengths:
|
||||
|
||||
- Shared `Badge` usage is established for workflow and report states.
|
||||
- Content approval states appear to reuse shared variants through `content-approval` helpers.
|
||||
|
||||
Weaknesses:
|
||||
|
||||
- Status language is not fully standardized across features. Similar states use different wording such as archive/hide/remove-publish semantics depending on module.
|
||||
- Some feedback and button copy rely on variant differences only, without additional structural separation for risky actions.
|
||||
|
||||
## Button Standard Assessment
|
||||
|
||||
Strengths:
|
||||
|
||||
- Most primary/secondary actions use shared `Button` variants.
|
||||
- Mobile width handling is good in many forms and headers through `w-full sm:w-auto`.
|
||||
- Action ordering is usually reasonable: cancel/back separated from primary submit action.
|
||||
|
||||
Weaknesses:
|
||||
|
||||
- Workflow buttons are not standardized across content modules. Announcements and online lessons use similar but not fully shared action group patterns.
|
||||
- Some significant actions such as publish/archive are triggered directly from detail views without explicit confirmation, which weakens safety and workflow clarity.
|
||||
- Loading labels are inconsistent and often use `...` instead of a consistent loading copy pattern.
|
||||
|
||||
## Table Standard Assessment
|
||||
|
||||
Strengths:
|
||||
|
||||
- Shared `DataTable`, toolbar, and pagination are good system-level primitives.
|
||||
- Canonical table modules like employee directory and audit logs follow the shared pattern well.
|
||||
- Action columns are generally handled in a stable way with pinning and reusable menus.
|
||||
|
||||
Weaknesses:
|
||||
|
||||
- Reports bypass the shared DataTable stack entirely and use manual `Table` cards, so sorting, pagination, column management, and interaction patterns differ from the rest of the app.
|
||||
- Manual report tables rely on horizontal scrolling only and do not offer the stronger affordances already available in the shared table system.
|
||||
- Table empty/loading states are reasonably present, but wording and visual treatment vary by module.
|
||||
|
||||
## Form Standard Assessment
|
||||
|
||||
Strengths:
|
||||
|
||||
- Major forms use TanStack Form wrappers and shared field primitives.
|
||||
- Validation errors are shown inline and `scrollToFirstError()` is used in important flows.
|
||||
- Training records form handles employee vs HRD mode clearly.
|
||||
|
||||
Weaknesses:
|
||||
|
||||
- Required mark style is inconsistent. Some screens use literal `*`, some use styled destructive spans, and some rely on validation only.
|
||||
- Placeholder and helper-text patterns vary widely between modules.
|
||||
- Inputs often omit `name` and `autocomplete` attributes, which is a lower-level accessibility and usability gap against modern form guidelines.
|
||||
- Feature forms mix shared field wrappers with raw HTML elements such as custom `textarea`, creating slightly different spacing and behavior.
|
||||
|
||||
## File Attachment UX Assessment
|
||||
|
||||
Strengths:
|
||||
|
||||
- Training records use a shared `FileUploader` and attachment list, which gives a clearer system pattern.
|
||||
- Content forms usually show current file, replace/remove flows, and post-save expectations.
|
||||
|
||||
Weaknesses:
|
||||
|
||||
- Attachment UX is fragmented across modules:
|
||||
- Training records use shared uploader + attachment list
|
||||
- Announcements use a raw file input
|
||||
- Online lessons use custom `AssetPicker` sections
|
||||
- This creates different expectations for drag-and-drop, file preview, replacement, and removal across similar content workflows.
|
||||
- View-mode attachment presentation is not standardized across modules.
|
||||
|
||||
## Feedback State Assessment
|
||||
|
||||
Strengths:
|
||||
|
||||
- Most reviewed modules include loading, error, and empty states.
|
||||
- Toasts are used consistently for mutation feedback.
|
||||
- Audit logs and notifications have decent empty-state handling.
|
||||
|
||||
Weaknesses:
|
||||
|
||||
- Loading states are inconsistent between skeleton-style, spinner-in-card, and plain text messaging.
|
||||
- `PageContainer` access denial uses a plain centered sentence rather than a richer restricted-state pattern.
|
||||
- Success and error messaging quality varies and is harder to read because of copy encoding issues.
|
||||
|
||||
## Dialog / Sheet / Drawer Assessment
|
||||
|
||||
Observed strengths:
|
||||
|
||||
- Shared dialog/sheet primitives are clearly part of the system.
|
||||
- Content review uses a shared action dialog component rather than ad hoc per-page modal markup.
|
||||
|
||||
Observed gaps:
|
||||
|
||||
- This audit did not fully validate focus trap, escape handling, and mobile height behavior for every dialog/sheet implementation.
|
||||
- Action-safety patterns are not uniform; some important transitions use dialogs while other significant actions run immediately.
|
||||
|
||||
## Workflow UX Assessment
|
||||
|
||||
Strengths:
|
||||
|
||||
- Training records and content modules expose state-aware actions instead of showing every action at once.
|
||||
- Review notes and current status are surfaced in key detail/form views.
|
||||
|
||||
Weaknesses:
|
||||
|
||||
- Reports page is functionally useful but visually dense; it reads like stacked exports rather than a guided reporting workspace.
|
||||
- Content modules blur the line between draft editing, review transition, publish, and archive actions because button patterns are similar but not always grouped by risk or workflow stage.
|
||||
- Employee directory uses an extra local page hero inside `PageContainer`, which makes it feel visually different from other management screens.
|
||||
|
||||
## Responsive Assessment
|
||||
|
||||
Strengths:
|
||||
|
||||
- Shared layouts use `min-w-0`, wrapped actions, and scoped overflow correctly.
|
||||
- Employee directory and shared tables are intentionally built for horizontal table scroll on smaller screens.
|
||||
- Forms generally collapse to a single column well.
|
||||
|
||||
Weaknesses:
|
||||
|
||||
- Reports is the most likely responsive pain point because of multiple wide manual tables on one page.
|
||||
- Some custom card headers and action groups depend on wrapping rather than a stronger mobile-specific layout hierarchy.
|
||||
- Sidebar behavior was not visually runtime-tested in browser during this audit.
|
||||
|
||||
## Accessibility Assessment
|
||||
|
||||
Positive observations:
|
||||
|
||||
- Many interactive controls use semantic elements such as `button`, `Link`, and form labels.
|
||||
- Some icon-only actions already have `aria-label`, for example notification mark-as-read and table pagination buttons.
|
||||
- Inline validation patterns exist in major forms.
|
||||
|
||||
Key gaps:
|
||||
|
||||
- No verified skip-link pattern was found for the dashboard shell.
|
||||
- Decorative icons are widely rendered without explicit `aria-hidden`, which can add noise for assistive tech depending on the icon implementation.
|
||||
- Heading hierarchy is inconsistent at the page level because of mixed `h1`/`h2` usage.
|
||||
- Native form enhancements such as `autocomplete`, input naming consistency, and copy punctuation are not standardized.
|
||||
- Notifications pagination uses `href='#'` plus click interception, which is weaker semantically than true navigation controls.
|
||||
|
||||
## Design System Inconsistencies
|
||||
|
||||
Most important system drifts:
|
||||
|
||||
1. Copy quality and encoding
|
||||
- Thai labels are corrupted across multiple feature surfaces.
|
||||
2. Page header structure
|
||||
- Shared page shell exists, but some modules duplicate internal hero headers.
|
||||
3. Table architecture
|
||||
- Canonical modules use shared DataTable; reports does not.
|
||||
4. File upload pattern
|
||||
- Different modules use different uploader UX for similar tasks.
|
||||
5. Form semantics
|
||||
- Required markers, placeholders, descriptions, and input metadata are inconsistent.
|
||||
6. Workflow action treatment
|
||||
- Some risky actions confirm through dialogs; others execute directly.
|
||||
|
||||
## Findings by Severity
|
||||
|
||||
### [High] Thai UI copy is encoding-corrupted across major navigation, form, table, and feedback surfaces
|
||||
|
||||
**Module:**
|
||||
|
||||
Cross-cutting UI copy
|
||||
|
||||
**Location Found:**
|
||||
|
||||
- `src/config/nav-config.ts`
|
||||
- `src/components/layout/page-container.tsx`
|
||||
- `src/components/ui/table/data-table.tsx`
|
||||
- `src/components/ui/table/data-table-pagination.tsx`
|
||||
- `src/features/employee-directory/components/employee-directory-header.tsx`
|
||||
- `src/features/reports/components/reports-page-content.tsx`
|
||||
- `src/features/notifications/components/notifications-page.tsx`
|
||||
- `src/features/announcements/components/announcement-form.tsx`
|
||||
- `src/features/announcements/components/announcement-view-page.tsx`
|
||||
- `src/features/training-records/components/training-record-form.tsx`
|
||||
- `src/features/online-lessons/components/online-lesson-form.tsx`
|
||||
|
||||
**Details:**
|
||||
|
||||
Large portions of user-facing Thai text render as mojibake-like corrupted strings instead of readable Thai copy.
|
||||
|
||||
**Impact:**
|
||||
|
||||
- Severely damages readability and trust.
|
||||
- Makes workflows harder to learn.
|
||||
- Reduces accessibility because labels and feedback become harder to interpret.
|
||||
|
||||
**Evidence from Code:**
|
||||
|
||||
Corrupted Thai strings appear in page titles, descriptions, nav items, buttons, empty states, and pagination labels.
|
||||
|
||||
**Example Scenario:**
|
||||
|
||||
A user opening navigation, forms, or reports sees broken Thai labels in core actions and status descriptions, making the system feel unreliable even when the workflow itself works.
|
||||
|
||||
**Recommendation:**
|
||||
|
||||
Normalize file encoding and re-validate every user-facing Thai string before expanding UI work.
|
||||
|
||||
**Must Fix Before Production:** Yes
|
||||
|
||||
### [Medium] Heading and page-header patterns are semantically and visually inconsistent across modules
|
||||
|
||||
**Module:**
|
||||
|
||||
Shared layout and page composition
|
||||
|
||||
**Location Found:**
|
||||
|
||||
- `src/components/ui/heading.tsx`
|
||||
- `src/components/layout/page-container.tsx`
|
||||
- `src/features/employee-directory/components/employee-directory-header.tsx`
|
||||
|
||||
**Details:**
|
||||
|
||||
`Heading` renders `h2`, while some screens also introduce their own `h1` inside the page body. Other screens rely entirely on the shared heading component.
|
||||
|
||||
**Impact:**
|
||||
|
||||
- Inconsistent visual rhythm across pages.
|
||||
- Weaker accessibility and document structure.
|
||||
- Makes it harder to standardize page templates.
|
||||
|
||||
**Recommendation:**
|
||||
|
||||
Define one canonical page-title pattern for dashboard screens and apply it uniformly.
|
||||
|
||||
**Must Fix Before Production:** Consider
|
||||
|
||||
### [Medium] Reports UI diverges from the shared table system and creates a noticeably different interaction model
|
||||
|
||||
**Module:**
|
||||
|
||||
Reports
|
||||
|
||||
**Location Found:**
|
||||
|
||||
- `src/features/reports/components/reports-page-content.tsx`
|
||||
- `src/features/reports/components/report-table-card.tsx`
|
||||
|
||||
**Details:**
|
||||
|
||||
Reports use manual tables instead of the shared DataTable stack used elsewhere in the dashboard.
|
||||
|
||||
**Impact:**
|
||||
|
||||
- Table behavior differs from the rest of the product.
|
||||
- Large report cards become dense and harder to scan.
|
||||
- Users lose familiar controls such as unified table toolbars and standardized interaction patterns.
|
||||
|
||||
**Recommendation:**
|
||||
|
||||
Either formally designate reports as a separate reporting presentation pattern, or migrate the module toward shared table conventions where practical.
|
||||
|
||||
**Must Fix Before Production:** Consider
|
||||
|
||||
### [Medium] File attachment UX is fragmented across modules instead of following one reusable pattern
|
||||
|
||||
**Module:**
|
||||
|
||||
Training Records, Announcements, Online Lessons
|
||||
|
||||
**Location Found:**
|
||||
|
||||
- `src/features/training-records/components/training-record-form.tsx`
|
||||
- `src/features/announcements/components/announcement-form.tsx`
|
||||
- `src/features/online-lessons/components/online-lesson-form.tsx`
|
||||
|
||||
**Details:**
|
||||
|
||||
Comparable upload tasks use different components and different interaction rules.
|
||||
|
||||
**Impact:**
|
||||
|
||||
- Increases cognitive load when users move between modules.
|
||||
- Makes future improvements and accessibility hardening harder to apply consistently.
|
||||
|
||||
**Recommendation:**
|
||||
|
||||
Standardize a single attachment/upload UX contract for content and training modules, even if internal storage logic remains feature-specific.
|
||||
|
||||
**Must Fix Before Production:** Consider
|
||||
|
||||
### [Low] Form and pagination semantics miss several modern UX/a11y conventions
|
||||
|
||||
**Module:**
|
||||
|
||||
Shared forms and notifications
|
||||
|
||||
**Location Found:**
|
||||
|
||||
- `src/features/training-records/components/training-record-form.tsx`
|
||||
- `src/features/announcements/components/announcement-form.tsx`
|
||||
- `src/features/online-lessons/components/online-lesson-form.tsx`
|
||||
- `src/features/notifications/components/notifications-page.tsx`
|
||||
|
||||
**Details:**
|
||||
|
||||
Common gaps include missing `autocomplete` conventions, inconsistent input metadata, and pagination links implemented with `href='#'` plus click interception.
|
||||
|
||||
**Impact:**
|
||||
|
||||
- Mostly incremental usability and accessibility debt rather than immediate blockers.
|
||||
|
||||
**Recommendation:**
|
||||
|
||||
Add a lightweight shared checklist for form semantics, link semantics, and icon accessibility before future UI expansion.
|
||||
|
||||
**Must Fix Before Production:** No
|
||||
|
||||
## Recommended UI Standard
|
||||
|
||||
Suggested system rules for this repo:
|
||||
|
||||
1. One dashboard page header pattern
|
||||
- Top-level page title, description, optional info button, optional right-side action area.
|
||||
2. One table family
|
||||
- Use shared DataTable unless a page is intentionally a reporting surface with documented exceptions.
|
||||
3. One attachment pattern
|
||||
- Shared file state, current file preview, replace/remove actions, and empty state wording.
|
||||
4. One required-field style
|
||||
- Same marker, same placement, same helper/error rhythm.
|
||||
5. One workflow action grouping rule
|
||||
- Primary action, secondary action, destructive action, and confirmation behavior defined centrally.
|
||||
6. One language-quality rule
|
||||
- All user-facing Thai strings must be UTF-safe, readable, and consistently localized.
|
||||
|
||||
## Recommended Remediation Order
|
||||
|
||||
1. Fix Thai text encoding across all user-facing surfaces.
|
||||
2. Standardize heading semantics and page-header composition.
|
||||
3. Decide whether reports is an intentional exception or should move closer to the shared table pattern.
|
||||
4. Unify attachment UX across training records, announcements, and online lessons.
|
||||
5. Add a small accessibility/design checklist for forms, icon buttons, and navigation semantics.
|
||||
|
||||
## Files Reviewed
|
||||
|
||||
- `plans/tms-system-full-audit-prompts.md`
|
||||
- `docs/AI_DEVELOPMENT_GUIDE.md`
|
||||
- `docs/PROJECT_ARCHITECTURE.md`
|
||||
- `src/components/layout/page-container.tsx`
|
||||
- `src/components/layout/app-sidebar.tsx`
|
||||
- `src/components/layout/user-nav.tsx`
|
||||
- `src/components/org-switcher.tsx`
|
||||
- `src/components/ui/heading.tsx`
|
||||
- `src/components/ui/notification-card.tsx`
|
||||
- `src/components/ui/table/data-table.tsx`
|
||||
- `src/components/ui/table/data-table-toolbar.tsx`
|
||||
- `src/components/ui/table/data-table-pagination.tsx`
|
||||
- `src/config/nav-config.ts`
|
||||
- `src/features/employee-directory/components/employee-directory-header.tsx`
|
||||
- `src/features/employee-directory/components/employee-directory-table.tsx`
|
||||
- `src/features/training-records/components/training-record-form.tsx`
|
||||
- `src/features/announcements/components/announcement-form.tsx`
|
||||
- `src/features/announcements/components/announcement-view-page.tsx`
|
||||
- `src/features/announcements/components/announcement-status-badge.tsx`
|
||||
- `src/features/online-lessons/components/online-lesson-form.tsx`
|
||||
- `src/features/reports/components/reports-page-content.tsx`
|
||||
- `src/features/reports/components/report-table-card.tsx`
|
||||
- `src/features/notifications/components/notifications-page.tsx`
|
||||
- `src/features/audit-logs/components/audit-log-listing.tsx`
|
||||
- `src/features/audit-logs/components/audit-log-table.tsx`
|
||||
- `src/features/content-approval/components/content-approval-status-badge.tsx`
|
||||
|
||||
## Areas Not Verified
|
||||
|
||||
- Runtime browser validation of focus order, keyboard traversal, and screen-reader output
|
||||
- Visual contrast measurement against rendered theme tokens
|
||||
- All dialogs/sheets/drawers at runtime, including focus trap and mobile height behavior
|
||||
- Full mobile behavior of the sidebar and complex tables in a live viewport
|
||||
- Every feature module in the repo; this review focused on canonical and high-traffic dashboard surfaces
|
||||
Reference in New Issue
Block a user