added income by category feature#175
Conversation
✅ Deploy Preview for paisable ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull Request Overview
This PR adds an "Income by Category" chart to the Dashboard, allowing users to toggle between viewing expense and income category breakdowns using a reusable pie chart component.
Key Changes:
- Added backend aggregation for income grouped by category
- Implemented frontend toggle to switch between expense and income views
- Enhanced CategoryPieChart component to accept dynamic labels
Reviewed Changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| backend/controllers/transactionController.js | Added income by category aggregation query and included it in the chart data response |
| frontend/src/components/CategoryPieChart.jsx | Made the chart label configurable via props to support both expense and income views |
| frontend/src/pages/DashboardPage.jsx | Added toggle UI and state management to switch between expense and income category charts |
Files not reviewed (1)
- backend/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Brother have you checked it , either accept it or tell if some changes are required |
…perf: add indexes for common queries
|
i have made the required changes , now you can proceed with merging. |
There was a problem hiding this comment.
Pull Request Overview
Copilot reviewed 4 out of 5 changed files in this pull request and generated 4 comments.
Files not reviewed (1)
- backend/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Data for Expenses by Category (Pie Chart) | ||
| const expensesByCategory = await IncomeExpense.aggregate([ | ||
| { $match: { user: userId, isIncome: false, isDeleted: false } }, | ||
| { $match: { user: userId, isIncome: false, isDeleted: false, ...(dateMatch.addedOn ? { addedOn: dateMatch.addedOn } : {}) } }, |
There was a problem hiding this comment.
The spread operator pattern ...(dateMatch.addedOn ? { addedOn: dateMatch.addedOn } : {}) adds complexity and could be simplified. Consider restructuring to build the match object conditionally before the aggregation, which improves readability and maintainability.
|
|
||
| // Data for Income by Category (Pie Chart) | ||
| const incomeByCategory = await IncomeExpense.aggregate([ | ||
| { $match: { user: userId, isIncome: true, isDeleted: false, ...(dateMatch.addedOn ? { addedOn: dateMatch.addedOn } : {}) } }, |
There was a problem hiding this comment.
The spread operator pattern ...(dateMatch.addedOn ? { addedOn: dateMatch.addedOn } : {}) adds complexity and could be simplified. Consider restructuring to build the match object conditionally before the aggregation, which improves readability and maintainability.
| </button> | ||
| <button | ||
| type="button" | ||
| className={`px-3 py-1 text-sm font-medium border-t border-b rounded-r-md ${categoryView === 'income' ? 'bg-green-600 text-white border-green-600' : 'bg-transparent text-gray-700 dark:text-gray-200 border-gray-300 dark:border-gray-600'}`} |
There was a problem hiding this comment.
Long className string with complex conditional logic reduces readability. Consider extracting the className logic into a helper function or using a library like classnames to improve maintainability.
| <div className="inline-flex rounded-md shadow-sm" role="group" aria-label="Toggle category view"> | ||
| <button | ||
| type="button" | ||
| className={`px-3 py-1 text-sm font-medium border rounded-l-md ${categoryView === 'expense' ? 'bg-blue-600 text-white border-blue-600' : 'bg-transparent text-gray-700 dark:text-gray-200 border-gray-300 dark:border-gray-600'}`} |
There was a problem hiding this comment.
Long className string with complex conditional logic reduces readability. Consider extracting the className logic into a helper function or using a library like classnames to improve maintainability.

Description
Adds an “Income by Category” chart to the Dashboard and a toggle to switch between Expense and Income category views. The backend now returns grouped income data, and the frontend reuses the pie chart component for both types.
Related Issue
Fixes #148
Motivation and Context
Provides users with a clear breakdown of income sources by category, matching the existing expense visualization for consistency and better financial planning.
Types of Changes
-New Feature
How Has This Been Tested?
/api/transactions/chartsreturnsincomeByCategory.Screenshots (if applicable):
Checklist