feat(projects): add the Projects CRM module #32

Merged
Mayur7887 merged 3 commits from feat/projects into goutamnextflow 2026-07-24 15:10:24 +00:00
Collaborator

Summary

Adds the Projects module to the CRM dashboard — a Construction jobs + Pipeline Leads screen, following DEV_GUIDE_PROJECTS_MODULE.md's backend-already-built pattern (mirrors team-api.ts / team-management.tsx).

What's in this PR

Data layer (src/lib/projects-api.ts)

  • useProjectsData() — live (crm.project.* via be-crm) or local mock, picked by isShellConfigured(), same pattern as useTeamData().
  • Live mode maps be-crm's actual Project model (name/status/value/owner/address/dates) and resolves ownerPrincipalId → a real name via crm.team.member.search.
  • Money conversion (minor units ↔ dollars), and a UiProjectStatus mapping between the mock's 4 statuses (Active/Complete/Stuck/Follow-up) and be-crm's 6 (lead/active/on_hold/won/lost/archived).
  • Verified end-to-end against a locally running be-crm: list/create/setStatus/remove, address round-trip, owner-name resolution.

Mock data (src/components/dashboard/projects-data.ts)

  • 15 construction leads (first 8 match the reference design) totaling exactly $379,200, plus 45 deterministically-generated pipeline leads.
  • A deterministic 3-installment payment schedule generator (collectionsFor) per construction job, backing the collections ledger below.

View (src/components/dashboard/projects.tsx)

  • Construction / Pipeline Leads tabs, search, and quick status filters (All/Active/Complete/Stuck/Follow-up) — all on one row.
  • Table columns adapt to context: full mock columns (Lead/Status/Stage/Job Type/Agent/Progress/Health) vs. a leaner live column set (Lead/Status/Owner/Value/Due date) — live mode only renders fields be-crm actually stores, nothing fabricated.
  • Total Collected Details modal (eye icon per row): a payment ledger (Name/Project, Reference ID, Date, Type, Status, Amount) with in-modal search, CSV download, and a Net Total footer. Gracefully empty for pipeline leads / live projects (no billing backend yet) instead of showing fake data.

Wiring

  • Registered in dashboard.tsx's view switch and gated on the pipeline.manage permission in sidebar.tsx (matches how be-crm gates every crm.project.* action server-side).
  • Extended the shared Modal component (ui.tsx) with an optional headerExtra slot and an xl size to support the collections modal.

Test plan

  • tsc --noEmit and eslint clean
  • Full crm.project.* CRUD chain exercised directly against a local be-crm instance (list/create/setStatus/remove), then cleaned up
  • Mock-mode UI driven end-to-end via Playwright (tabs, search, filters, Collected Details modal + search + CSV download, empty states) — zero console errors
  • Manual smoke test against the real Shell BFF once it's deployed (not reachable from this environment)
## Summary Adds the **Projects** module to the CRM dashboard — a Construction jobs + Pipeline Leads screen, following `DEV_GUIDE_PROJECTS_MODULE.md`'s backend-already-built pattern (mirrors `team-api.ts` / `team-management.tsx`). ## What's in this PR **Data layer** (`src/lib/projects-api.ts`) - `useProjectsData()` — live (`crm.project.*` via be-crm) or local mock, picked by `isShellConfigured()`, same pattern as `useTeamData()`. - Live mode maps be-crm's actual `Project` model (`name/status/value/owner/address/dates`) and resolves `ownerPrincipalId` → a real name via `crm.team.member.search`. - Money conversion (minor units ↔ dollars), and a `UiProjectStatus` mapping between the mock's 4 statuses (Active/Complete/Stuck/Follow-up) and be-crm's 6 (`lead/active/on_hold/won/lost/archived`). - Verified end-to-end against a locally running be-crm: list/create/setStatus/remove, address round-trip, owner-name resolution. **Mock data** (`src/components/dashboard/projects-data.ts`) - 15 construction leads (first 8 match the reference design) totaling exactly $379,200, plus 45 deterministically-generated pipeline leads. - A deterministic 3-installment payment schedule generator (`collectionsFor`) per construction job, backing the collections ledger below. **View** (`src/components/dashboard/projects.tsx`) - Construction / Pipeline Leads tabs, search, and quick status filters (All/Active/Complete/Stuck/Follow-up) — all on one row. - Table columns adapt to context: full mock columns (Lead/Status/Stage/Job Type/Agent/Progress/Health) vs. a leaner live column set (Lead/Status/Owner/Value/Due date) — live mode only renders fields be-crm actually stores, nothing fabricated. - **Total Collected Details** modal (eye icon per row): a payment ledger (Name/Project, Reference ID, Date, Type, Status, Amount) with in-modal search, CSV download, and a Net Total footer. Gracefully empty for pipeline leads / live projects (no billing backend yet) instead of showing fake data. **Wiring** - Registered in `dashboard.tsx`'s view switch and gated on the `pipeline.manage` permission in `sidebar.tsx` (matches how be-crm gates every `crm.project.*` action server-side). - Extended the shared `Modal` component (`ui.tsx`) with an optional `headerExtra` slot and an `xl` size to support the collections modal. ## Test plan - [x] `tsc --noEmit` and `eslint` clean - [x] Full `crm.project.*` CRUD chain exercised directly against a local be-crm instance (list/create/setStatus/remove), then cleaned up - [x] Mock-mode UI driven end-to-end via Playwright (tabs, search, filters, Collected Details modal + search + CSV download, empty states) — zero console errors - [ ] Manual smoke test against the real Shell BFF once it's deployed (not reachable from this environment)
abhinav added 1 commit 2026-07-22 21:22:49 +00:00
abhinav added 1 commit 2026-07-22 21:26:59 +00:00
# Conflicts:
#	src/app/dashboard/dashboard.css
#	src/components/dashboard/dashboard.tsx
abhinav requested review from tanweer919 2026-07-22 21:28:21 +00:00
abhinav added 1 commit 2026-07-23 17:00:13 +00:00
# Conflicts:
#	src/app/dashboard/dashboard.css
#	src/components/dashboard/dashboard.tsx
#	src/components/dashboard/ui.tsx
Mayur7887 merged commit 0c7adece3c into goutamnextflow 2026-07-24 15:10:24 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Goutam/lynkeduppro-crm#32