feat(projects): wire Projects list + create to the backend (MAPPS-126) #88

Merged
longjacksonle merged 1 commit from feat/mapps-126-wire-projects into main 2026-06-07 04:08:50 +02:00

What

Wires the Projects page (src/pages/projects.rs) to the live projects API (PMS-51). It was hardcoded template: ProjectListPage rendered six fixed cards with fake progress bars + hardcoded stat cards, and ProjectNewPage was a decorative mock submit (the P1-04 1s timeout that never POSTed, with a hardcoded company dropdown).

Closes MAPPS-126.

How

  • List: fetches GET /api/v1/projects and resolves company names from GET /api/v1/contacts/companies. Each card shows the real status badge, a budget-utilization bar (actual_amount / budget_amount - the actuals PMS-51 now computes), target end date, and budget. The four stat cards (active / on hold / completed counts, total budget) are computed from the data; search + status filters run client-side. Loading / empty (no projects vs no matches) / load-failed states.
  • Create: ProjectNewPage now does a real POST /api/v1/projects with a company picker from the live companies list, name validation, an error banner, and navigation to the list on success. Company is optional (omits company_id when unset), matching the server.
  • Server Decimal fields come over the wire as JSON strings (verified: budget_amount = "5000.00"), so money fields decode through a number-or-string-tolerant deserializer instead of a plain f64.
  • Removed the dead ProjectCard component and the gloo_timers mock-submit path.

Verification

  • cargo fmt --check clean; cargo clippy --target wasm32-unknown-unknown --all-targets -- -D warnings clean.
  • Against the live dev-sso stack with a real token: GET /contacts/companies 200, POST /projects 200 (created + visible in GET /projects), confirming the decimal-as-string wire form. Test project cleaned up afterwards.

Follow-up (not in this PR)

ProjectDetailPage and ProjectTasksPage are still hardcoded; wire them against GET /api/v1/projects/:id, /projects/:id/tasks, /projects/:id/phases separately.

🤖 Generated with Claude Code

## What Wires the Projects page (`src/pages/projects.rs`) to the live projects API (PMS-51). It was hardcoded template: `ProjectListPage` rendered six fixed cards with fake progress bars + hardcoded stat cards, and `ProjectNewPage` was a decorative mock submit (the `P1-04` 1s timeout that never POSTed, with a hardcoded company dropdown). Closes MAPPS-126. ## How - **List:** fetches `GET /api/v1/projects` and resolves company names from `GET /api/v1/contacts/companies`. Each card shows the real status badge, a budget-utilization bar (`actual_amount / budget_amount` - the actuals PMS-51 now computes), target end date, and budget. The four stat cards (active / on hold / completed counts, total budget) are computed from the data; search + status filters run client-side. Loading / empty (no projects vs no matches) / load-failed states. - **Create:** `ProjectNewPage` now does a real `POST /api/v1/projects` with a company picker from the live companies list, name validation, an error banner, and navigation to the list on success. Company is optional (omits `company_id` when unset), matching the server. - Server `Decimal` fields come over the wire as JSON strings (verified: `budget_amount` = `"5000.00"`), so money fields decode through a number-or-string-tolerant deserializer instead of a plain `f64`. - Removed the dead `ProjectCard` component and the `gloo_timers` mock-submit path. ## Verification - `cargo fmt --check` clean; `cargo clippy --target wasm32-unknown-unknown --all-targets -- -D warnings` clean. - Against the live dev-sso stack with a real token: `GET /contacts/companies` 200, `POST /projects` 200 (created + visible in `GET /projects`), confirming the decimal-as-string wire form. Test project cleaned up afterwards. ## Follow-up (not in this PR) `ProjectDetailPage` and `ProjectTasksPage` are still hardcoded; wire them against `GET /api/v1/projects/:id`, `/projects/:id/tasks`, `/projects/:id/phases` separately. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(projects): wire Projects list + create to the backend (MAPPS-126)
All checks were successful
Check / clippy + fmt + tests (pull_request) Successful in 42s
Create release / Create release from merged PR (pull_request) Has been skipped
202b603b5d
The Projects page was hardcoded template: ProjectListPage rendered six fixed ProjectCards with fake progress bars and hardcoded stat cards, and ProjectNewPage was a decorative mock submit (the P1-04 1s timeout that never POSTed, with a hardcoded company dropdown). The backend projects API is live (PMS-51), so both are now wired.

ProjectListPage fetches GET /api/v1/projects and resolves company names from GET /api/v1/contacts/companies, rendering a card per project with its real status badge, budget-utilization bar (actual_amount / budget_amount, the actuals PMS-51 now computes), target end date, and budget. The four stat cards (active / on hold / completed counts and total budget) are computed from the fetched data, and the search + status filters run client-side over it. Loading, empty (no projects vs no matches), and load-failed states replace the always-on demo grid.

ProjectNewPage replaces the mock submit with a real POST /api/v1/projects: a company picker populated from the live companies list, name validation, an error banner, and navigation to the list on success. Company is optional (the request omits company_id when none is picked), matching the server's optional field.

Server Decimal fields arrive as JSON strings (e.g. "5000.00"), so the money/hours fields decode through a number-or-string-tolerant deserializer rather than a plain f64. Removed the now-unused ProjectCard component and the gloo_timers mock-submit path.

ProjectDetailPage and ProjectTasksPage remain hardcoded and are a separate follow-up (they need GET /projects/:id, /projects/:id/tasks, /projects/:id/phases).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
longjacksonle deleted branch feat/mapps-126-wire-projects 2026-06-07 04:08:50 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/mokosh-apps!88
No description provided.