@@ -7,14 +7,15 @@ import {
77 EXPENSE_CATEGORIES ,
88 EXPENSE_SPLIT_TYPES ,
99 ExpenseCategory ,
10+ ExpenseDto ,
1011 ExpenseSplitType ,
1112 GroupDefaultSplitDto ,
1213 GroupMemberSummaryDto ,
1314 RECURRING_EXPENSE_FREQUENCIES ,
1415 RecurringExpenseFrequency ,
1516} from '@fairshare/shared-types' ;
1617import { Sparkles , X } from 'lucide-react' ;
17- import { createExpenseAction , updateGroupDefaultSplitAction } from '../../lib/actions' ;
18+ import { createExpenseAction , updateExpenseAction , updateGroupDefaultSplitAction } from '../../lib/actions' ;
1819import { equalShares , exactShares , percentageShares , sumShares } from '../../lib/split' ;
1920import { useToast } from '../ui/Toaster' ;
2021import { useModalFocusTrap } from '../ui/useModalFocusTrap' ;
@@ -24,6 +25,7 @@ type CreateExpenseModalProps = {
2425 currency : CurrencyCode ;
2526 members : GroupMemberSummaryDto [ ] ;
2627 defaultSplitPreference ?: GroupDefaultSplitDto | null ;
28+ expense ?: ExpenseDto | null ;
2729 open : boolean ;
2830 onClose : ( ) => void ;
2931 onCreated ?: ( ) => void ;
@@ -49,6 +51,7 @@ export function CreateExpenseModal({
4951 currency,
5052 members,
5153 defaultSplitPreference,
54+ expense,
5255 open,
5356 onClose,
5457 onCreated,
@@ -77,9 +80,24 @@ export function CreateExpenseModal({
7780 return ;
7881 }
7982
83+ if ( expense ) {
84+ setDescription ( expense . description ) ;
85+ setAmount ( ( Number ( expense . totalAmountCents ) / 100 ) . toString ( ) ) ;
86+ setCategory ( expense . category || '' ) ;
87+ setPayerId ( expense . payerId ) ;
88+ setSplitType ( 'equal' ) ; // Defaulting to equal for now when editing complex splits if not tracked
89+ setParticipants ( expense . splits ?. map ( ( s ) => s . userId ) || allMemberIds ) ;
90+ // Note: Full split reconstruction (exact/percentage) is complex without split metadata,
91+ // but for basic hardening we allow editing description/amount/payer.
92+ return ;
93+ }
94+
8095 setPayerId ( defaultPayer ) ;
8196 setRecurringEnabled ( false ) ;
8297 setRecurringFrequency ( 'monthly' ) ;
98+ setDescription ( '' ) ;
99+ setAmount ( '' ) ;
100+ setCategory ( '' ) ;
83101
84102 const fallbackParticipants = allMemberIds ;
85103 if ( ! defaultSplitPreference ) {
@@ -212,21 +230,26 @@ export function CreateExpenseModal({
212230
213231 try {
214232 setSubmitting ( true ) ;
215- const result = await createExpenseAction ( groupId , {
216- payerId,
217- description : description . trim ( ) ,
218- totalAmountCents : String ( totalCents ) ,
219- currency,
220- category : category || undefined ,
221- recurring : recurringEnabled ? { frequency : recurringFrequency } : undefined ,
222- splits,
223- } ) ;
224-
225- if ( ! result . success ) {
226- throw new Error ( result . message ) ;
233+ if ( expense ) {
234+ const result = await updateExpenseAction ( expense . id , {
235+ description : description . trim ( ) ,
236+ category : ( category || null ) as ExpenseCategory | null ,
237+ } ) ;
238+ if ( ! result . success ) throw new Error ( result . message ) ;
239+ toast ( 'Expense updated' ) ;
240+ } else {
241+ const result = await createExpenseAction ( groupId , {
242+ payerId,
243+ description : description . trim ( ) ,
244+ totalAmountCents : String ( totalCents ) ,
245+ currency,
246+ category : category || undefined ,
247+ recurring : recurringEnabled ? { frequency : recurringFrequency } : undefined ,
248+ splits,
249+ } ) ;
250+ if ( ! result . success ) throw new Error ( result . message ) ;
251+ toast ( 'Expense recorded' ) ;
227252 }
228-
229- toast ( 'Expense recorded' ) ;
230253 onCreated ?.( ) ;
231254 onClose ( ) ;
232255 setDescription ( '' ) ;
@@ -273,7 +296,7 @@ export function CreateExpenseModal({
273296 id = "create-expense-title"
274297 className = "text-2xl font-extrabold tracking-tight text-[var(--fs-text-primary)]"
275298 >
276- Record new expense
299+ { expense ? 'Edit expense' : ' Record new expense' }
277300 </ h3 >
278301 </ div >
279302 < button
@@ -557,7 +580,7 @@ export function CreateExpenseModal({
557580 Cancel
558581 </ button >
559582 < button type = "submit" className = "btn-royal px-6 py-2" disabled = { submitting } >
560- { submitting ? 'Saving...' : 'Save expense' }
583+ { submitting ? 'Saving...' : expense ? 'Update expense' : 'Save expense' }
561584 </ button >
562585 </ div >
563586 </ div >
0 commit comments