feat(bm-dashboard): Add Cost Breakdown by Category donut chart to Financials#4821
Open
Aditya-gam wants to merge 4 commits intodevelopmentfrom
Open
feat(bm-dashboard): Add Cost Breakdown by Category donut chart to Financials#4821Aditya-gam wants to merge 4 commits intodevelopmentfrom
Aditya-gam wants to merge 4 commits intodevelopmentfrom
Conversation
Add interactive Recharts donut chart to the Financials section of the Phase 2 Summary Dashboard, replacing the placeholder Big Card. The chart visualizes cost distribution across Labor, Materials, and Equipment categories with project/date filters, hover tooltips, click drill-down for per-project detail, responsive layout, and dark mode support. New files: - Redux constants, actions, and reducer for cost breakdown state - CostBreakDown component with CSS module styling Modified files: - URL.js: add BM_COST_BREAKDOWN endpoint builder - reducers/index.js: register costBreakdownReducer - WeeklyProjectSummary.jsx: render CostBreakDown in financials grid
Long project names overflowed the donut hole. Add fitLabelInDonut() that dynamically calculates font size and word-wraps into SVG tspan elements based on available inner radius width.
…elect Add color-scheme: dark to filter inputs and selects in dark mode so the browser renders native date calendar popups and select dropdowns with dark theme colors.
✅ Deploy Preview for highestgoodnetwork-dev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Show a Clear Filters button when any filter is active that resets project, start date, and end date in a single click and dismisses any open drill-down panel.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Description
Restores and implements the Cost Breakdown by Category donut chart in the Financials section of the Phase 2 Summary Dashboard. The chart was not rendering because the frontend had no integration with the cost breakdown API.

This PR adds full frontend integration: Redux state, API calls to
GET /api/costs/breakdown, and an interactive Recharts donut chart with project/date filters, hover tooltips (dollar amount and percentage), click-to-drill-down by category, dynamic center label (e.g. "All Projects" vs selected project name), responsive layout, and dark mode support. Color mapping is consistent with the spec: Labor – Purple, Materials – Green, Equipment – Yellow.Related PRs (if any):
routes.js.Main changes explained:
Created/Updated Files:
src/constants/bmdashboard/costBreakdownConstants.jsFETCH_COST_BREAKDOWN_START/SUCCESS/ERROR,FETCH_COST_DETAIL_START/SUCCESS/ERROR,CLEAR_COST_DETAIL.src/actions/bmdashboard/costBreakdownActions.jsfetchCostBreakdown({ projectId, startDate, endDate })— callsGET /api/costs/breakdownwith optional query params for chart data.fetchCostDetail({ projectId, startDate, endDate })— same endpoint withcategoryDetail=truefor per-project breakdown on slice click.clearCostDetail()— resets drill-down state.ENDPOINTS.BM_COST_BREAKDOWN()fromURL.js; errors surfaceerror.response?.data?.erroror fallback message.src/reducers/bmdashboard/costBreakdownReducer.jsloading,data,error(main breakdown);detailLoading,detailData,detailError(drill-down).src/components/BMDashboard/WeeklyProjectSummary/Financials/CostBreakDown/CostBreakDown.jsxPieChart,Pie,Cell,Tooltip,ResponsiveContainer.GET /bm/projectsNames), From/To date inputs; 500 ms debounce before refetch.data.project) + total cost; usesfitLabelInDonut()to size and wrap text (max 2 lines, ellipsis if needed) to prevent overflow.formatCurrency), and percentage share.categoryDetail=truepopulates per-project breakdown (name, amount, %).state.theme.darkModeto apply.wrapperDark; tooltip and detail panel use CSS variables.src/components/BMDashboard/WeeklyProjectSummary/Financials/CostBreakDown/CostBreakDown.module.css--cb-text-color,--cb-input-bg,--cb-input-border,--cb-tooltip-bg,--cb-detail-bg..wrapperDarkoverrides for the Financials card in dark mode.color-scheme: darkon filter container so native date picker and<select>render in dark theme.prefers-reduced-motionandprefers-contrast: highwhere applicable.src/utils/URL.jsBM_COST_BREAKDOWN(projectId, startDate, endDate, categoryDetail)— buildsGET ${APIEndpoint}/costs/breakdownwith optionalprojectId,startDate,endDate,categoryDetail=true.src/reducers/index.jscostBreakdownReducerascostBreakdowninlocalReducers; state atstate.costBreakdown.src/components/BMDashboard/WeeklyProjectSummary/WeeklyProjectSummary.jsxCostBreakDown; replace Financials “Big Card” placeholder with<CostBreakDown />in thefinancial-biggrid cell.Key Implementation Details:
fitLabelInDonut(text, availableWidth, maxFontSize, minFontSize)computes usable width from inner radius, tries font sizes 7–14px, word-wraps into up to 2 lines with SVG<tspan>, and truncates with ellipsis at min size so long names (e.g. “Commercial Test - Project”) stay inside the donut.CATEGORY_CONFIGmaps API category names to short labels and hex colors: Labor#9333EA, Materials#22C55E, Equipment#EAB308.fetchCostBreakdownafter 500 ms; cleanup on unmount or next effect cancels pending timeout.selectedCategoryand dispatchesfetchCostDetail; responsebreakdown[].projectBreakdownis rendered in the detail panel; same slice/legend click clears selection andclearCostDetail.color-scheme: darkin the wrapper ensures<input type="date">and<select>use dark styling without extra JS.How to test:
Aditya-feature/cost-breakdown-donut-chart-wipyarn install(ornpm install) to install dependencies.REACT_APP_APIENDPOINT(defaulthttp://localhost:4500/api).npm run start:local(or project’s frontend start command).Screenshots or videos of changes:
Donut chart (All Projects, with legend):


Single project selected (center label shows project name):


Drill-down panel opens after clicking a category:


All Filters + Category Panel (chart + date picker):


Test Video:
Test.Video.mov
Note:
isAnimationActive={false}for stable rendering. Detail is fetched only when a category is selected.GET /api/costs/breakdown(and optionalcategoryDetail=true) is available.role="img"andaria-label; loading usesaria-live="polite"andaria-busy; errors userole="alert"; form controls have associated<label>; legend items are buttons witharia-labelincluding value; detail panel hasrole="region"andaria-label.