From cf89ee7cd2607bb1fcdf14f37a8860d180d8240b Mon Sep 17 00:00:00 2001 From: myrmidex Date: Sat, 21 Mar 2026 17:48:58 +0100 Subject: [PATCH] 16 - Update frontend for cents-based API --- .../components/IncomeDistributionPreview.tsx | 10 ++--- resources/js/pages/Scenarios/Show.tsx | 38 +++++++++++++------ 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/resources/js/components/IncomeDistributionPreview.tsx b/resources/js/components/IncomeDistributionPreview.tsx index fd42012..1a576dd 100644 --- a/resources/js/components/IncomeDistributionPreview.tsx +++ b/resources/js/components/IncomeDistributionPreview.tsx @@ -54,7 +54,7 @@ export default function IncomeDistributionPreview({ scenarioId }: IncomeDistribu 'Content-Type': 'application/json', 'X-CSRF-TOKEN': csrfToken(), }, - body: JSON.stringify({ amount: parsed }), + body: JSON.stringify({ amount: Math.round(parsed * 100) }), }); if (!response.ok) { @@ -126,11 +126,11 @@ export default function IncomeDistributionPreview({ scenarioId }: IncomeDistribu
- ${allocation.allocated_amount.toFixed(2)} + ${(allocation.allocated_amount / 100).toFixed(2)} {allocation.remaining_capacity !== null && ( - (${allocation.remaining_capacity.toFixed(2)} remaining) + (${(allocation.remaining_capacity / 100).toFixed(2)} remaining) )}
@@ -143,13 +143,13 @@ export default function IncomeDistributionPreview({ scenarioId }: IncomeDistribu
Total Allocated - ${preview.total_allocated.toFixed(2)} + ${(preview.total_allocated / 100).toFixed(2)}
{preview.unallocated > 0 && (
Unallocated - ${preview.unallocated.toFixed(2)} + ${(preview.unallocated / 100).toFixed(2)}
)} diff --git a/resources/js/pages/Scenarios/Show.tsx b/resources/js/pages/Scenarios/Show.tsx index 8f59f2e..c868eec 100644 --- a/resources/js/pages/Scenarios/Show.tsx +++ b/resources/js/pages/Scenarios/Show.tsx @@ -24,11 +24,11 @@ interface Bucket { allocation_value: number | null; allocation_type_label: string; buffer_multiplier: number; - effective_capacity: number; + effective_capacity: number | null; starting_amount: number; current_balance: number; has_available_space: boolean; - available_space: number; + available_space: number | null; } interface Stream { @@ -76,11 +76,23 @@ const bucketTypeOptions = [ { value: 'want', label: 'Want' }, ]; +/** Convert cents to dollars for display */ +const centsToDollars = (cents: number): number => cents / 100; + +/** Convert dollars to cents for storage */ +const dollarsToCents = (dollars: number): number => Math.round(dollars * 100); + +/** Convert basis points to percent for display */ +const basisPointsToPercent = (bp: number): number => bp / 100; + +/** Convert percent to basis points for storage */ +const percentToBasisPoints = (pct: number): number => Math.round(pct * 100); + const formatAllocationValue = (bucket: Bucket): string => { if (bucket.allocation_type === 'unlimited') return 'All remaining'; if (bucket.allocation_value === null) return '--'; - if (bucket.allocation_type === 'percentage') return `${Number(bucket.allocation_value).toFixed(2)}%`; - return `$${Number(bucket.allocation_value).toFixed(2)}`; + if (bucket.allocation_type === 'percentage') return `${basisPointsToPercent(bucket.allocation_value).toFixed(2)}%`; + return `$${centsToDollars(bucket.allocation_value).toFixed(2)}`; }; const csrfToken = () => @@ -158,7 +170,11 @@ export default function Show({ scenario, buckets, streams = { data: [] }, stream name: formData.name, type: formData.type, allocation_type: formData.allocation_type, - allocation_value: formData.allocation_value ? parseFloat(formData.allocation_value) : null, + allocation_value: formData.allocation_value + ? (formData.allocation_type === 'percentage' + ? percentToBasisPoints(parseFloat(formData.allocation_value)) + : dollarsToCents(parseFloat(formData.allocation_value))) + : null, buffer_multiplier: formData.allocation_type === 'fixed_limit' ? parseFloat(formData.buffer_multiplier) || 0 : 0, }), }); @@ -306,11 +322,11 @@ export default function Show({ scenario, buckets, streams = { data: [] }, stream
Current Filling patchBucket(bucket.id, { starting_amount: val })} + value={centsToDollars(bucket.starting_amount)} + onSave={(val) => patchBucket(bucket.id, { starting_amount: dollarsToCents(val) })} formatDisplay={(v) => `$${v.toFixed(2)}`} min={0} - step="1" + step="0.01" className="text-lg font-semibold text-gray-900" />
@@ -329,8 +345,8 @@ export default function Show({ scenario, buckets, streams = { data: [] }, stream min={0} step="0.01" /> - {bucket.buffer_multiplier > 0 && ( - <> = ${bucket.effective_capacity.toFixed(2)} effective + {bucket.buffer_multiplier > 0 && bucket.effective_capacity !== null && ( + <> = ${centsToDollars(bucket.effective_capacity).toFixed(2)} effective )} ) @@ -342,7 +358,7 @@ export default function Show({ scenario, buckets, streams = { data: [] }, stream
Progress - ${bucket.current_balance.toFixed(2)} / ${bucket.effective_capacity.toFixed(2)} + ${centsToDollars(bucket.current_balance).toFixed(2)} / ${bucket.effective_capacity !== null ? centsToDollars(bucket.effective_capacity).toFixed(2) : '∞'}