Add daily expense tracking with sort/split and CSV export
Standalone expenses (date, description, category, amount) with the same equal/own/payer split machinery as entry costs, merged into the costs panel and settle-up as a single expense bucket. Self-fetching card with per-day grouping, client-side sorting, and quick-add. CSV export interleaves expenses with priced entries, one share column per member (UTF-8 BOM, RFC 4180, formula-injection guard on text cells). Also fixes trip deletion, which hit a foreign-key violation and rolled back for any trip with checklist items.
This commit is contained in:
@@ -43,6 +43,28 @@ export function entryIcon(entry) {
|
||||
return typeInfo(entry && entry.type).icon;
|
||||
}
|
||||
|
||||
// Expense categories (daily spending log) — fixed enum, see docs/API.md.
|
||||
// Display metadata lives here per the API contract ("Display metadata (icon +
|
||||
// label + colour) lives in the frontend ... not the API").
|
||||
export const EXPENSE_CATEGORIES = {
|
||||
food: { label: 'Food', icon: '🍽️', color: '#059669' },
|
||||
drinks: { label: 'Drinks', icon: '🍹', color: '#0891b2' },
|
||||
transport: { label: 'Transport', icon: '🚕', color: '#d97706' },
|
||||
activities: { label: 'Activities', icon: '🎟️', color: '#2563eb' },
|
||||
shopping: { label: 'Shopping', icon: '🛍️', color: '#db2777' },
|
||||
accommodation: { label: 'Accommodation', icon: '🏨', color: '#f59e0b' },
|
||||
other: { label: 'Other', icon: '💸', color: '#64748b' },
|
||||
};
|
||||
|
||||
export const EXPENSE_CATEGORY_LIST = Object.entries(EXPENSE_CATEGORIES).map(([value, meta]) => ({
|
||||
value,
|
||||
...meta,
|
||||
}));
|
||||
|
||||
export function expenseCategoryInfo(category) {
|
||||
return EXPENSE_CATEGORIES[category] || EXPENSE_CATEGORIES.other;
|
||||
}
|
||||
|
||||
// Split modes with the human labels the day-editor select shows.
|
||||
export const SPLIT_MODES = [
|
||||
{ value: 'equal', label: 'Split equally' },
|
||||
|
||||
Reference in New Issue
Block a user