import type { ReactNode } from 'react'; import { Link } from 'react-router'; import { Icon } from '../design/Icon'; import { useI18n } from '../i18n/useI18n'; import type { ExpenseEffect } from '../lib/effect'; import { formatMoney } from '../lib/money'; import styles from './LedgerRow.module.css'; import { Money } from './Money'; interface Common { /** Route to open (rendered as a link), or a click handler (rendered as a button); neither = static row. */ to?: string; onClick?: () => void; /** Date text in the row meta ("16 okt.", SPEC §9.8). */ date: string; } export type LedgerRowProps = Common & ( | { kind: 'expense'; /** The CategoryIcon tile (size 40, solid). */ leading: ReactNode; description: string; amountOre: number; effect: ExpenseEffect; } | { kind: 'settlement'; /** "Anna betalade dig 800,00 kr" (`ledger_settlement_*`), already formatted. */ title: string; accountCount: number; } ); function EffectText({ effect }: { effect: ExpenseEffect }) { const { t, language } = useI18n(); switch (effect.kind) { case 'lent': return {t('effect_lent', formatMoney(effect.ore, language))}; case 'borrowed': return {t('effect_borrowed', formatMoney(effect.ore, language))}; case 'not_involved': return {t('effect_not_involved')}; case 'paid_for_yourself': return {t('effect_paid_for_yourself')}; } } /** * design-spec §3.5 ledger rows (S-5, S-12, search): an expense (category tile, description, effect line, amount, date) * or a settlement (handshake tile on the settlement tint, title, "Betalning", date). Items of a SegmentedGroup. */ export function LedgerRow(props: LedgerRowProps) { const { t, tp } = useI18n(); const content = props.kind === 'expense' ? ( <> {props.leading} {props.description} {props.date} ) : ( <> {props.title} {props.accountCount > 1 ? `${t('common_separator_dot')}${tp('ledger_settlement_accounts', props.accountCount)}` : ''} {t('ledger_settlement_label')} {props.date} ); const className = [styles.row, props.kind === 'settlement' ? styles.settlement : undefined].filter(Boolean).join(' '); if (props.to !== undefined) { return ( {content} ); } if (props.onClick !== undefined) { return ( ); } return
{content}
; } /** design-spec §3.5 `SegmentedGroup`: items 3 px apart, outer corners 24, inner 8, one card shadow. */ export function SegmentedGroup({ children, label }: { children: ReactNode; label?: string }) { return (
{children}
); } export function SegmentedItem({ children }: { children: ReactNode }) { return (
{children}
); }