Skip to content

feat(frontend): fill project cards from the dashboard API - #305

Draft
nourshoreibah wants to merge 1 commit into
feat/dashboard-scoped-to-membersfrom
feat/project-cards-real-data
Draft

feat(frontend): fill project cards from the dashboard API#305
nourshoreibah wants to merge 1 commit into
feat/dashboard-scoped-to-membersfrom
feat/project-cards-real-data

Conversation

@nourshoreibah

Copy link
Copy Markdown
Collaborator

ℹ️ Issue

Part of replacing the frontend's placeholder data with real APIs. Stacked on #304base that branch, not main.

📝 Description

ProjectCard on /dashboard and /projects was rendered with budget_used={0} members={0} for every project, so the budget bar sat at 0% and every card read "0 members" no matter the data. That was the last of the hardcoded placeholder data outside the pages #303 already touches.

  1. Both pages now read GET /projects/dashboard instead of GET /projects. It returns the same caller-scoped set of projects, already carrying spent and staff_count — so there is nothing to aggregate client-side, and no second round trip.
  2. ProjectSummary / Dashboard added to @/types (alongside the other extracted types from 252 extract duplicated inline types #288) rather than re-declaring a local ProjectRow in each page, as both pages had been doing.
  3. ProjectCard now guards the budget division. With a hardcoded budget_used of 0 the 0/0 was a harmless NaN; with real spend, a project with no budget set produces Infinity% straight into the bar's inline width. Overspend still reports honestly (200%) but the bar is clamped to the track.

✔️ Verification

In apps/frontend, all green:

  • npm run typecheck — clean
  • npm run lint — clean
  • npx jest260 passed, 2 skipped, 25 suites
  • npm run build — static export succeeds, all 12 routes emitted

New coverage in test/components/ProjectsPage.test.tsx runs against both pages via describe.each: asserts the card data comes from /projects/dashboard and that /projects is not called, that real spend/staff render instead of zeros, the no-budget case renders 0%, and that a rejected request surfaces the error rather than empty cards. ProjectCard.test.tsx gains the zero-budget, no-budget-with-spend, and overspend-clamp cases.

🏕️ (Optional) Future Work / Notes

🤖 Generated with Claude Code

Every ProjectCard on /dashboard and /projects was rendered with
budget_used={0} members={0}, so the budget bar sat at 0% and the staff count
read "0 members" for every project regardless of the data.

Both pages now read GET /projects/dashboard, which returns the same
caller-scoped set of projects already carrying `spent` and `staff_count`, so
there is nothing left to aggregate client-side. That endpoint is admin-only on
main; the branch this is stacked on scopes it to the caller's projects.

ProjectCard guarded against a zero budget while here: with a hardcoded
budget_used of 0 the division was a harmless 0/0, but with real spend a project
with no budget set yields Infinity% straight into the bar width.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@nourshoreibah

Copy link
Copy Markdown
Collaborator Author

⚠️ No CI will run on this PR while it is stacked. The workflows trigger on pull_request: branches: [main, develop], which matches the base branch — so a PR based on a feature branch gets no checks at all, including the frontend-ci / lambda-tests / terraform-plan-summary that branch protection requires.

GitHub retargets this to main automatically once the parent merges and its branch is deleted; CI runs from that point. Until then the verification in the description is local only (typecheck, lint, full jest suite, production build — all green).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant