-
Notifications
You must be signed in to change notification settings - Fork 3
fix: make the dashboard show total by currency #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThis change refactors several components and modules to centralize and standardize currency aggregation and formatting logic using new helper functions. Multiple files update their import paths to use these helpers, and dashboard components now support multi-currency totals using the new Changes
Sequence Diagram(s)sequenceDiagram
participant Component
participant Helpers
participant ethers
Component->>Helpers: calculateTotalsByCurrency(items)
Helpers->>ethers: parseUnits(amount, 18) for each item
Helpers->>Helpers: Sum amounts per currency
Helpers->>ethers: formatUnits(total, 18) per currency
Helpers-->>Component: Record<currency, totalString>
Component->>Helpers: formatCurrencyTotals(totals)
Helpers-->>Component: Array<{amount, currency}> (filtered, formatted)
Component->>UI: Render MultiCurrencyStatCard(values)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~15–25 minutes Possibly related issues
Possibly related PRs
Suggested reviewers
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. ✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/components/dashboard/invoices-received.tsx (1)
209-213
: Consider updating batch payment selection display for multi-currency consistency.The selected invoices total still uses a simple sum with a hardcoded dollar sign, which may not accurately represent multi-currency selections. Consider updating this to use the same currency helper functions for consistency.
- <p className="text-sm text-zinc-600"> - Total: $ - {selectedInvoices - .reduce((sum, invoice) => sum + Number(invoice.amount), 0) - .toLocaleString()} - </p> + {(() => { + const selectedItems = selectedInvoices.map(invoice => ({ + amount: invoice.amount, + currency: invoice.paymentCurrency + })); + const totals = calculateTotalsByCurrency(selectedItems); + const values = formatCurrencyTotals(totals); + return ( + <div className="text-sm text-zinc-600"> + Total: {values.map(({amount, currency}) => + `${amount} ${currency}` + ).join(' + ')} + </div> + ); + })()}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
src/app/api/webhook/route.ts
(1 hunks)src/app/i/[id]/page.tsx
(1 hunks)src/app/invoices/create/page.tsx
(1 hunks)src/components/batch-payout.tsx
(1 hunks)src/components/dashboard/invoices-received.tsx
(4 hunks)src/components/dashboard/invoices-sent.tsx
(3 hunks)src/components/dashboard/subscriptions.tsx
(2 hunks)src/components/invoice-creator.tsx
(1 hunks)src/components/subscription-plans/blocks/payments-table.tsx
(2 hunks)src/components/subscription-plans/blocks/subscribers-table.tsx
(2 hunks)src/lib/helpers/currency.ts
(1 hunks)
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: bassgeta
PR: RequestNetwork/easy-invoice#83
File: src/components/create-recurring-payment/blocks/create-recurring-payment-form.tsx:127-138
Timestamp: 2025-06-23T09:14:42.979Z
Learning: In the RequestNetwork/easy-invoice codebase, when suggesting improvements like error handling for transaction approvals, the user bassgeta prefers consistency over isolated improvements. They prefer not to implement error handling in one place unless it's done consistently across all similar transaction flows in the codebase.
Learnt from: bassgeta
PR: RequestNetwork/easy-invoice#91
File: drizzle/0007_messy_silver_fox.sql:1-12
Timestamp: 2025-07-14T14:17:05.340Z
Learning: In the RequestNetwork/easy-invoice codebase, monetary amounts are stored as text in the database schema rather than numeric types. This is a deliberate architectural decision to maintain consistency across all amount fields in the system.
Learnt from: aimensahnoun
PR: RequestNetwork/easy-invoice#21
File: src/app/invoices/[ID]/page.tsx:113-148
Timestamp: 2025-02-20T10:27:02.993Z
Learning: The easy-invoice project prefers simpler, direct implementations over abstract utilities. For example, using `.toFixed(2)` directly instead of creating separate number formatting utilities.
📚 Learning: the handleformsubmit function in src/components/invoice-form.tsx correctly uses data.clientemail fro...
Learnt from: rodrigopavezi
PR: RequestNetwork/easy-invoice#45
File: src/components/invoice-form.tsx:316-319
Timestamp: 2025-05-19T13:00:48.790Z
Learning: The handleFormSubmit function in src/components/invoice-form.tsx correctly uses data.clientEmail from the form submission data to find matching payers, which is the proper implementation.
Applied to files:
src/app/invoices/create/page.tsx
src/app/i/[id]/page.tsx
src/app/api/webhook/route.ts
src/components/batch-payout.tsx
src/components/invoice-creator.tsx
src/components/dashboard/invoices-sent.tsx
src/components/dashboard/invoices-received.tsx
src/components/subscription-plans/blocks/payments-table.tsx
📚 Learning: the easy-invoice project prefers simpler, direct implementations over abstract utilities. for exampl...
Learnt from: aimensahnoun
PR: RequestNetwork/easy-invoice#21
File: src/app/invoices/[ID]/page.tsx:113-148
Timestamp: 2025-02-20T10:27:02.993Z
Learning: The easy-invoice project prefers simpler, direct implementations over abstract utilities. For example, using `.toFixed(2)` directly instead of creating separate number formatting utilities.
Applied to files:
src/app/invoices/create/page.tsx
src/components/subscription-plans/blocks/subscribers-table.tsx
src/app/i/[id]/page.tsx
src/components/invoice-creator.tsx
src/components/dashboard/invoices-sent.tsx
src/lib/helpers/currency.ts
src/components/dashboard/invoices-received.tsx
src/components/dashboard/subscriptions.tsx
src/components/subscription-plans/blocks/payments-table.tsx
📚 Learning: the payrequest endpoint in src/server/routers/invoice.ts is intentionally kept public (using publicp...
Learnt from: aimensahnoun
PR: RequestNetwork/easy-invoice#2
File: src/server/routers/invoice.ts:88-109
Timestamp: 2025-02-12T12:40:14.742Z
Learning: The payRequest endpoint in src/server/routers/invoice.ts is intentionally kept public (using publicProcedure) to allow invoice sharing and payment by anyone with the payment reference, similar to how payment links work in other payment systems.
Applied to files:
src/app/invoices/create/page.tsx
src/app/i/[id]/page.tsx
src/app/api/webhook/route.ts
src/components/batch-payout.tsx
src/components/dashboard/invoices-received.tsx
📚 Learning: the `payrequest` function in the invoice router retrieves payment transactions calldata from the req...
Learnt from: aimensahnoun
PR: RequestNetwork/easy-invoice#2
File: src/server/routers/invoice.ts:0-0
Timestamp: 2025-02-12T13:04:46.135Z
Learning: The `payRequest` function in the invoice router retrieves payment transactions calldata from the Request API and does not process the payment itself. The actual payment status update happens through the webhook handler.
Applied to files:
src/app/api/webhook/route.ts
📚 Learning: in the easy-invoice codebase, error handling for trpc queries is not required at the component level...
Learnt from: aimensahnoun
PR: RequestNetwork/easy-invoice#8
File: src/app/invoice-me/page.tsx:21-21
Timestamp: 2025-02-14T12:48:42.125Z
Learning: In the easy-invoice codebase, error handling for TRPC queries is not required at the component level as confirmed by the maintainer.
Applied to files:
src/app/api/webhook/route.ts
📚 Learning: in `src/server/routers/payment.ts`, the batchpay input validation already handles empty arrays corre...
Learnt from: aimensahnoun
PR: RequestNetwork/easy-invoice#67
File: src/server/routers/payment.ts:47-49
Timestamp: 2025-06-04T12:02:39.411Z
Learning: In `src/server/routers/payment.ts`, the batchPay input validation already handles empty arrays correctly. The `batchPaymentFormSchema.shape.payouts.optional()` inherits the `.min(1, "At least one payment is required")` validation from the original schema, so empty payouts arrays are automatically rejected even when the field is made optional.
Applied to files:
src/components/batch-payout.tsx
src/components/dashboard/invoices-received.tsx
📚 Learning: in src/components/batch-payout.tsx, the user prefers to keep the simple 2-second timeout for appkit ...
Learnt from: aimensahnoun
PR: RequestNetwork/easy-invoice#64
File: src/components/batch-payout.tsx:100-106
Timestamp: 2025-06-04T10:08:40.123Z
Learning: In src/components/batch-payout.tsx, the user prefers to keep the simple 2-second timeout for AppKit initialization over more complex polling mechanisms when the current approach is working adequately. They favor simplicity over potentially more robust but complex solutions.
Applied to files:
src/components/batch-payout.tsx
📚 Learning: invoice items are validated at creation time through the schema validation in src/lib/schemas/invoic...
Learnt from: aimensahnoun
PR: RequestNetwork/easy-invoice#2
File: src/app/invoices/[ID]/page.tsx:160-175
Timestamp: 2025-02-12T12:42:40.076Z
Learning: Invoice items are validated at creation time through the schema validation in src/lib/schemas/invoice.ts, ensuring that items array is non-empty and each item has required description, quantity, and price fields. Runtime validation in display components is not necessary.
Applied to files:
src/components/invoice-creator.tsx
🧬 Code Graph Analysis (5)
src/components/subscription-plans/blocks/subscribers-table.tsx (1)
src/lib/helpers/currency.ts (2)
calculateTotalsByCurrency
(8-35)formatCurrencyTotals
(37-49)
src/components/dashboard/invoices-sent.tsx (2)
src/lib/helpers/currency.ts (2)
calculateTotalsByCurrency
(8-35)formatCurrencyTotals
(37-49)src/components/multi-currency-stat-card.tsx (1)
MultiCurrencyStatCard
(12-39)
src/components/dashboard/invoices-received.tsx (2)
src/lib/helpers/currency.ts (2)
calculateTotalsByCurrency
(8-35)formatCurrencyTotals
(37-49)src/components/multi-currency-stat-card.tsx (1)
MultiCurrencyStatCard
(12-39)
src/components/dashboard/subscriptions.tsx (1)
src/lib/helpers/currency.ts (2)
calculateTotalsByCurrency
(8-35)formatCurrencyTotals
(37-49)
src/components/subscription-plans/blocks/payments-table.tsx (1)
src/lib/helpers/currency.ts (2)
calculateTotalsByCurrency
(8-35)formatCurrencyTotals
(37-49)
🔇 Additional comments (18)
src/components/invoice-creator.tsx (1)
6-6
: LGTM! Clean import path refactoring.The import path update aligns with the broader refactoring to centralize helper functions in the
@/lib/helpers
directory.src/lib/helpers/currency.ts (2)
8-35
: Well-implemented currency aggregation with proper BigNumber handling.The function correctly uses BigNumber arithmetic to maintain precision when aggregating amounts across currencies. The error handling ensures graceful degradation when invalid amounts are encountered.
37-49
: Good filtering logic for valid currency totals.The function properly filters out zero amounts and handles parsing errors gracefully. The use of
gt(0)
ensures only positive amounts are included in the final output.src/app/invoices/create/page.tsx (1)
5-5
: LGTM! Consistent import path refactoring.The import path update is consistent with the broader effort to organize helper functions in the
@/lib/helpers
directory.src/app/i/[id]/page.tsx (1)
5-5
: LGTM! Consistent with the helper function reorganization.The import path update maintains consistency across the codebase while improving module organization.
src/components/batch-payout.tsx (1)
58-58
: LGTM! Import path update aligns with helper function refactoring.The import path change is consistent with the broader effort to organize helper functions in the
@/lib/helpers
directory.src/app/api/webhook/route.ts (1)
3-4
: LGTM! Clean import path refactoring.The import paths have been correctly updated to reflect the reorganization of helper functions into the
@/lib/helpers
directory, which improves code organization and modularity.src/components/subscription-plans/blocks/subscribers-table.tsx (2)
24-27
: LGTM! Clean import of standardized currency helpers.The new imports bring in centralized currency calculation and formatting utilities, which will improve consistency across the application.
Also applies to: 32-32
185-195
: Excellent refactoring to use centralized currency helpers.The replacement of manual BigNumber arithmetic with standardized helper functions improves code maintainability and consistency. The new approach is cleaner and delegates error handling to the helper functions, making this component more focused on its primary responsibility.
src/components/dashboard/subscriptions.tsx (2)
25-28
: LGTM! Import of centralized currency utilities.The new imports align with the broader refactoring effort to standardize currency calculations across the application.
212-232
: Excellent refactoring for multi-currency support.The replacement of manual BigNumber operations with centralized helper functions significantly improves code maintainability. The separation of commitment and spent calculations is logical and the use of helper functions ensures consistent currency handling across the application.
src/components/dashboard/invoices-received.tsx (2)
14-14
: LGTM! Clean import updates for currency helpers and batch payment.The import path updates align with the modularization effort, bringing in the new currency calculation utilities and MultiCurrencyStatCard component.
Also applies to: 15-18, 31-31
85-92
: Excellent multi-currency refactoring.The replacement of manual calculations with centralized helper functions and the switch to
MultiCurrencyStatCard
properly supports multi-currency totals, aligning with the PR objective to display totals by currency.Also applies to: 237-241
src/components/dashboard/invoices-sent.tsx (2)
12-15
: LGTM! Consistent import of currency utilities.The new imports align with the multi-currency refactoring pattern used across other dashboard components.
Also applies to: 21-21
57-64
: Excellent multi-currency implementation.The refactoring to use centralized currency helpers and
MultiCurrencyStatCard
perfectly aligns with the PR objective to display totals by currency. The implementation is consistent with other dashboard components and eliminates manual BigNumber operations.Also applies to: 82-86
src/components/subscription-plans/blocks/payments-table.tsx (3)
22-25
: LGTM! Clean import structure for currency helpers.The import of
calculateTotalsByCurrency
andformatCurrencyTotals
from the centralized currency helper module aligns well with the PR objective to standardize currency handling across dashboard components.
30-30
: Verify the continued need for ethers utils import.The
utils
import from ethers is still being used in thePaymentRow
component (lines 64-65) for individual payment amount formatting, so this import remains necessary.
155-161
: Excellent refactoring to centralize currency calculations.The refactoring successfully replaces complex inline BigNumber operations with clean, reusable helper functions. This change:
- Improves maintainability - Currency calculation logic is now centralized in
src/lib/helpers/currency.ts
- Reduces complexity - Eliminates manual BigNumber aggregation and error handling in the component
- Enhances consistency - Uses the same pattern as other dashboard components mentioned in the AI summary
The transformation from manual aggregation to helper functions is clean and the data flow remains clear: filtered payments → simplified payment items → currency totals → formatted values.
Problem
The invoices sent and received just put together the totals and "converted" the value to dollars.
Solution
Display the values by currency instead.
Changes
lib/invoice
intolib/helpers
and renamed the index file toinvoice.ts
.currency
helper file which receives an array of "payments" and groups them by currency.Testing