- Clear searchQuery after project creation so newly created projects
are visible even when a search filter is active
- Disable refresh button while loading to prevent overlapping fetches
- Fix loadProjects referenced-before-declaration lint error by moving
it to useCallback declared before useEffect; suppress
react-hooks/set-state-in-effect for the intentional async data-fetch
pattern (same pattern used in ProjectDetailPage)
- Add TDD tests first: 'clears search filter after creation' and
'disables refresh button while loading'; verified failing before impl,
passing after; all 13 tests pass with no lint errors on this file
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add KPI overview section (项目总览) with project count, account total, and latest project cards
- Add toolbar with search input and refresh button above the project table
- Extract 'new project' button into the overview heading for better hierarchy
- Add admin-overview, admin-kpi-grid, admin-kpi-card, admin-table-section, admin-toolbar CSS classes
- Extend Project type with optional user_count field
- Convert it.fails placeholder to passing overview test
- Fix modal test to use role-based selector (avoids duplicate text in KPI card + table)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace placeholder AppLayout with dark sidebar nav, semantic header/content zones
- Add CSS design tokens and shell utility classes to global.css
- Add shell-aware test expectation for 项目总览 (fails until Task 2 implements it)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add user repository functions for project user CRUD
- Create platform-user-service for project user management
- Add GET /v1/platform/projects/:id/users endpoint
- Add POST /v1/platform/projects/:id/users endpoint
- Support project_admin and manager roles
- Validate username uniqueness and project existence
- Normalize real_name and phone inputs
- Add comprehensive test coverage (13 tests)
- Fix test isolation issue in platform-projects cleanup
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add timing-attack mitigation by always verifying passwords against real or dummy hash
- Add comprehensive negative-path tests for platform login (wrong password, non-existent user, project user rejection, invalid body)
- Add focused middleware tests for requirePlatformAuth covering auth header validation and user type enforcement
- All 60 tests passing
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
After Task 1 changed AuthUser.project_id from number to number | null, getProjectId now explicitly checks for null values and throws an error for platform users attempting to access project resources.
This fix:
- Adds null check to reject platform users (project_id === null)
- Maintains type safety by ensuring return type is always number
- Includes comprehensive unit tests for all scenarios
- Preserves existing project-side behavior for valid project users
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The old static HTML/CSS/JS prototype in h5/ is superseded by the
React + Ant Design Mobile app in h5-app/. Removing to avoid confusion.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The feature/h5-design-polish branch brings in a complete React + Ant Design
Mobile rebuild of the H5 client (in h5-app/), replacing the old static
prototype in h5/.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add MOCK_ACCOUNTS with admin/123456 and worker/123456 as fallback
when real backend is unavailable
- apiLogin tries real backend first; falls through to mock only on failure
- Supports real JWT token flow when backend (port 3201) is available
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- apiGetReports: use mock data instead of real API (no backend available)
- reports.html: add mock.js script include
- Fix date display: was concatenating dateStr+timeStr causing duplication
- Fix severity badge: map Chinese mock values to backend enum keys
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add LogsPage.tsx re-export alias pointing to LogListPage
- Add src/tests/log-ui-model.test.ts with 26 targeted tests for log
UI-model and helper semantics (getLogStatusMeta, findTodayLog
integration, format helpers, equipment labels, truncate,
getTodayDateString, WEATHER_OPTIONS)
- Refactor LogFormPage to use ADM Form/Form.Item/Form.Header for
section layout, ADM Input for text fields, ADM Stepper for worker
count; remove hand-rolled FieldLabel and RequiredMark helpers
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Make date field editable (initialized to today)
- Rename remark → note to match legacy h5/log.html semantics
- Add photo upload field to LogFormPage
- Move weather to optional (was incorrectly required)
- LogDetailPage: render note, photo gallery, author+created_at footer
- Weather block is now conditional (not forced)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix upload-token API: backend returns { uploadUrl, objectKey } directly
(camelCase, no ApiResponse wrapper); update UploadTokenResult interface
and remove incorrect res.data access
- Fix confirm API: backend returns { fileId, objectKey } directly (no url,
no ApiResponse wrapper); update ConfirmResult interface accordingly
- uploadPhoto now returns { url: blobUrl, extra: { objectKey } } so the
ImageUploader can show a local preview while HazardReportPage submits
the confirmed objectKey (via extra) rather than the ephemeral blob URL
- Fix geolocation: getCurrentPosition returns void, not a watch ID;
remove the incorrect cast and clearWatch cleanup call; drop unused gpsWatchId ref
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- vite.config.ts: use loadEnv() to read VITE_BASE (base path) and
DEV_API_TARGET (proxy target) from .env; falls back to '/' and
http://127.0.0.1:3201 so local dev is unchanged
- App.tsx: pass basename={import.meta.env.BASE_URL} to BrowserRouter
so router paths align with the Vite base at runtime
- global.css: change #root overflow from hidden to auto so page
content is scrollable
- .env: document VITE_BASE, VITE_API_BASE, DEV_API_TARGET defaults
- src/config.ts: expose apiBase helper for runtime API prefix
- tsconfig.json: add vite/client types so import.meta.env is typed
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Consolidate page-local styles into shared CSS files
- Move login, home, reports, and detail page styles to style.css
- Add shared section headers and status pills to task-ui.css
- Remove duplicate <style> blocks from HTML files
- All in-scope pages now use consistent shared styling
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>