Add payment categories with emoji icons and image upload support
- Add comprehensive category system: Groceries 🛒, Shopping 🛍️, Travel 🚆, Restaurant 🍽️, Utilities ⚡, Fun 🎉 - Create category utility functions with emoji and display name helpers - Update Payment model and API validation to support categories - Add category selectors to payment creation and edit forms - Display category emojis prominently across all UI components: - Dashboard recent activities with category icons and names - Payment cards showing category in metadata - Payment modals and view pages with category information - Add image upload/removal functionality to payment edit form - Maintain responsive design and consistent styling across all components 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import ProfilePicture from './ProfilePicture.svelte';
|
||||
import { getCategoryEmoji, getCategoryName } from '$lib/utils/categories';
|
||||
|
||||
export let paymentId;
|
||||
|
||||
@@ -104,7 +105,10 @@
|
||||
<div class="payment-details">
|
||||
<div class="payment-header">
|
||||
<div class="title-section">
|
||||
<h1>{payment.title}</h1>
|
||||
<div class="title-with-category">
|
||||
<span class="category-emoji">{getCategoryEmoji(payment.category || 'groceries')}</span>
|
||||
<h1>{payment.title}</h1>
|
||||
</div>
|
||||
<div class="payment-amount">
|
||||
{formatCurrency(payment.amount)}
|
||||
</div>
|
||||
@@ -130,6 +134,10 @@
|
||||
<span class="label">Created by:</span>
|
||||
<span class="value">{payment.createdBy}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="label">Category:</span>
|
||||
<span class="value">{getCategoryName(payment.category || 'groceries')}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="label">Split method:</span>
|
||||
<span class="value">{getSplitDescription(payment)}</span>
|
||||
@@ -255,8 +263,20 @@
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
.title-with-category {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.title-with-category .category-emoji {
|
||||
font-size: 1.8rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.title-section h1 {
|
||||
margin: 0 0 0.5rem 0;
|
||||
margin: 0;
|
||||
color: #333;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
@@ -1,14 +0,0 @@
|
||||
import mongoose from 'mongoose';
|
||||
|
||||
const paymentSchema = new mongoose.Schema({
|
||||
paid_by: { type: String, required: true },
|
||||
total_amount: { type: Number, required: true },
|
||||
for_self: { type: Number, default: 0 },
|
||||
for_other: { type: Number, default: 0 },
|
||||
currency: { type: String, default: 'CHF' },
|
||||
description: String,
|
||||
date: { type: Date, default: Date.now },
|
||||
receipt_image: String
|
||||
});
|
||||
|
||||
export const Payment = mongoose.models.Payment || mongoose.model('Payment', paymentSchema);
|
49
src/lib/utils/categories.ts
Normal file
49
src/lib/utils/categories.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
export const PAYMENT_CATEGORIES = {
|
||||
groceries: {
|
||||
name: 'Groceries',
|
||||
emoji: '🛒'
|
||||
},
|
||||
shopping: {
|
||||
name: 'Shopping',
|
||||
emoji: '🛍️'
|
||||
},
|
||||
travel: {
|
||||
name: 'Travel',
|
||||
emoji: '🚆'
|
||||
},
|
||||
restaurant: {
|
||||
name: 'Restaurant',
|
||||
emoji: '🍽️'
|
||||
},
|
||||
utilities: {
|
||||
name: 'Utilities',
|
||||
emoji: '⚡'
|
||||
},
|
||||
fun: {
|
||||
name: 'Fun',
|
||||
emoji: '🎉'
|
||||
}
|
||||
} as const;
|
||||
|
||||
export type PaymentCategory = keyof typeof PAYMENT_CATEGORIES;
|
||||
|
||||
export function getCategoryInfo(category: PaymentCategory) {
|
||||
return PAYMENT_CATEGORIES[category] || PAYMENT_CATEGORIES.groceries;
|
||||
}
|
||||
|
||||
export function getCategoryEmoji(category: PaymentCategory) {
|
||||
return getCategoryInfo(category).emoji;
|
||||
}
|
||||
|
||||
export function getCategoryName(category: PaymentCategory) {
|
||||
return getCategoryInfo(category).name;
|
||||
}
|
||||
|
||||
export function getCategoryOptions() {
|
||||
return Object.entries(PAYMENT_CATEGORIES).map(([key, value]) => ({
|
||||
value: key as PaymentCategory,
|
||||
label: `${value.emoji} ${value.name}`,
|
||||
emoji: value.emoji,
|
||||
name: value.name
|
||||
}));
|
||||
}
|
Reference in New Issue
Block a user