Skip to content

Conversation

@dmortal
Copy link
Contributor

@dmortal dmortal commented Jan 8, 2026

image # Add PaymentStatement Component for Contractor Payment Details

Summary

Adds PaymentStatement component to display individual contractor payment details within the Contractor Payments flow.

Changes

New Components

  • PaymentStatement - Displays detailed payment breakdown for a single contractor
    • Shows payment method, hours/wage, bonus, and reimbursement
    • Handles both hourly and fixed wage types
    • Fetches payment group and contractor data independently

Architecture Updates

  • PaymentFlow Integration - Added statement state to payment state machine

    • New breadcrumb navigation from PaymentHistory → PaymentStatement
    • Added currentContractorUuid to flow context
    • Created PaymentStatementContextual wrapper
  • PaymentHistory - Simplified to emit events only

    • Removed local state management
    • Emits CONTRACTOR_PAYMENT_VIEW_DETAILS with contractor UUID and payment group ID
    • PaymentFlow handles navigation

Translations

  • New file: Contractor.Payments.PaymentStatement.json
  • Extracted statement-specific strings from PaymentHistory translations

Testing

  • Added concise tests for PaymentStatement (~160 lines)
  • Added concise tests for PaymentHistory (~160 lines)
  • Added concise tests for PaymentsList (~130 lines)
  • Focus on critical data flow and user interactions

Key Features

  • ✅ View individual payment details from payment history
  • ✅ Breadcrumb navigation back to payment history
  • ✅ Proper formatting for currency, dates, and hours
  • ✅ Displays different layouts for hourly vs fixed wage contractors

Copilot AI review requested due to automatic review settings January 8, 2026 21:26
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new PaymentStatement component to display detailed payment information for individual contractors within the Contractor Payments flow, along with necessary state machine and navigation updates.

Key Changes:

  • New PaymentStatement component showing payment breakdown with support for hourly and fixed wage types
  • Updated payment state machine with new statement state and breadcrumb navigation
  • Modified PaymentHistory to emit contractor UUID-based events for statement navigation
  • Added comprehensive test coverage for PaymentStatement, PaymentHistory, and PaymentsList components

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/types/i18next.d.ts Added TypeScript type definitions for PaymentStatement translations
src/i18n/en/Contractor.Payments.PaymentStatement.json New translation file with statement-specific strings
src/components/Contractor/Payments/PaymentStatement/PaymentStatement.tsx Main component fetching payment group and contractor data
src/components/Contractor/Payments/PaymentStatement/PaymentStatementPresentation.tsx Presentation component displaying payment details in tabular format
src/components/Contractor/Payments/PaymentStatement/PaymentStatement.test.tsx Test coverage for both hourly and fixed wage scenarios
src/components/Contractor/Payments/PaymentHistory/PaymentHistory.tsx Updated to emit contractor UUID for detail navigation, removed contractor filtering
src/components/Contractor/Payments/PaymentHistory/PaymentHistoryPresentation.tsx Changed heading level to h2, commented out cancel payment functionality
src/components/Contractor/Payments/PaymentHistory/PaymentHistory.test.tsx New tests for rendering and event emission
src/components/Contractor/Payments/PaymentsList/PaymentsList.test.tsx New tests for payment list rendering and interactions
src/components/Contractor/Payments/PaymentFlow/paymentStateMachine.ts Added statement state, breadcrumb navigation, and currentContractorUuid context
src/components/Contractor/Payments/PaymentFlow/PaymentFlowComponents.tsx Added PaymentStatementContextual wrapper and currentContractorUuid to context interface
Comments suppressed due to low confidence (1)

src/components/Contractor/Payments/PaymentHistory/PaymentHistory.tsx:46

  • The parameter name "paymentId" is inconsistent with how this handler is called. In PaymentHistoryPresentation.tsx line 139, it's called with "contractorUuid", but this handler expects and uses it as "paymentId" when emitting the event. This will send the wrong identifier to the cancel event handler. The parameter should be renamed to "contractorUuid" to match the actual data being passed.
  const handleCancelPayment = (paymentId: string) => {
    onEvent(componentEvents.CONTRACTOR_PAYMENT_CANCEL, { paymentId })
  }

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 141 to 155

it('shows cancel option for cancellable payments', async () => {
renderWithProviders(<PaymentHistory {...defaultProps} />)

await waitFor(() => {
expect(screen.getByText('Acme Consulting LLC')).toBeInTheDocument()
})

const menuButtons = screen.getAllByRole('button', { name: /action/i })
await user.click(menuButtons[1]!)

await waitFor(() => {
expect(screen.getByText('Cancel payment')).toBeInTheDocument()
})
})
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test expects "Cancel payment" to be visible in the menu, but the cancel payment functionality has been commented out in PaymentHistoryPresentation.tsx (lines 134-147). The test will fail because the cancel option is not rendered. Either remove this test or uncomment the cancel payment functionality if it should be available.

Suggested change
it('shows cancel option for cancellable payments', async () => {
renderWithProviders(<PaymentHistory {...defaultProps} />)
await waitFor(() => {
expect(screen.getByText('Acme Consulting LLC')).toBeInTheDocument()
})
const menuButtons = screen.getAllByRole('button', { name: /action/i })
await user.click(menuButtons[1]!)
await waitFor(() => {
expect(screen.getByText('Cancel payment')).toBeInTheDocument()
})
})

Copilot uses AI. Check for mistakes.
Comment on lines 44 to 64
const rows: PaymentStatementRow[] = [
{
label: payment.paymentMethod || '',
amount: currencyFormatter(wageTotal),
},
]

if (isHourly && hours > 0) {
rows.push({
label: t('hoursLabel'),
amount: t('hoursAmount', {
hours: formatHoursDisplay(hours),
rate: currencyFormatter(hourlyRate),
}),
})
} else {
rows.push({
label: t('wageLabel'),
amount: currencyFormatter(wageTotal),
})
}
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For non-hourly (fixed wage) contractors, the wage total is displayed twice: once in the first row with the payment method label (line 47) and again in the wage row (line 62). This creates redundant information. Consider removing the first row or restructuring the data to avoid duplication.

Copilot uses AI. Check for mistakes.
@dmortal dmortal enabled auto-merge (squash) January 9, 2026 21:33
@dmortal dmortal merged commit cd0af74 into main Jan 9, 2026
8 checks passed
@dmortal dmortal deleted the da/preview branch January 9, 2026 21:36
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.

3 participants