mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-21 14:21:46 +00:00
Budget: per-person expense tracking with member chips
- New budget_item_members junction table (migration 27) - Assign trip members to budget items via avatar chips in Persons column - Per-person split auto-calculated from assigned member count - Per-person summary integrated into total budget card - Member chips rendered via portal dropdown (no overflow clipping) - Mobile: larger touch-friendly chips (30px) under item name - Desktop: compact chips (20px) in Persons column - Custom NOMAD-style tooltips on chips - WebSocket live sync for all member operations - Fix invite button text color in dark mode - Widen budget layout to 1800px max-width - Shorten "Per Person/Day" column header
This commit is contained in:
@@ -201,6 +201,20 @@ export const useTripStore = create((set, get) => ({
|
||||
return {
|
||||
budgetItems: state.budgetItems.filter(i => i.id !== payload.itemId),
|
||||
}
|
||||
case 'budget:members-updated':
|
||||
return {
|
||||
budgetItems: state.budgetItems.map(i =>
|
||||
i.id === payload.itemId ? { ...i, members: payload.members, persons: payload.persons } : i
|
||||
),
|
||||
}
|
||||
case 'budget:member-paid-updated':
|
||||
return {
|
||||
budgetItems: state.budgetItems.map(i =>
|
||||
i.id === payload.itemId
|
||||
? { ...i, members: (i.members || []).map(m => m.user_id === payload.userId ? { ...m, paid: payload.paid } : m) }
|
||||
: i
|
||||
),
|
||||
}
|
||||
|
||||
// Reservations
|
||||
case 'reservation:created':
|
||||
@@ -683,6 +697,27 @@ export const useTripStore = create((set, get) => ({
|
||||
}
|
||||
},
|
||||
|
||||
setBudgetItemMembers: async (tripId, itemId, userIds) => {
|
||||
const result = await budgetApi.setMembers(tripId, itemId, userIds);
|
||||
set(state => ({
|
||||
budgetItems: state.budgetItems.map(item =>
|
||||
item.id === itemId ? { ...item, members: result.members, persons: result.item.persons } : item
|
||||
)
|
||||
}));
|
||||
return result;
|
||||
},
|
||||
|
||||
toggleBudgetMemberPaid: async (tripId, itemId, userId, paid) => {
|
||||
await budgetApi.togglePaid(tripId, itemId, userId, paid);
|
||||
set(state => ({
|
||||
budgetItems: state.budgetItems.map(item =>
|
||||
item.id === itemId
|
||||
? { ...item, members: (item.members || []).map(m => m.user_id === userId ? { ...m, paid } : m) }
|
||||
: item
|
||||
)
|
||||
}));
|
||||
},
|
||||
|
||||
loadFiles: async (tripId) => {
|
||||
try {
|
||||
const data = await filesApi.list(tripId)
|
||||
|
||||
Reference in New Issue
Block a user