import { createFileRoute } from '@tanstack/react-router' import { useState } from 'react' import { Text, Card, Group, Stack, Badge, Button, Loader, Center, Drawer, TextInput, NumberInput, Select, ActionIcon, Tooltip, Textarea, SimpleGrid, Table, } from '@pikku/mantine/core' import { DollarSign, Plus, Pencil, Link2 } from 'lucide-react' import { asI18n } from '@pikku/react' import { useQueryClient } from '@tanstack/react-query' import { notifications } from '@mantine/notifications' import { usePikkuQuery, usePikkuMutation } from '@perauset/functions-sdk/pikku/api.gen' import { usePermission } from '@/lib/permissions' import { PageHeader } from '@perauset/components' import { DataTable, type Column } from '@perauset/components' import { m } from '@/i18n/messages' import { useLocale } from '@/i18n/config' export const Route = createFileRoute('/_authenticated/finance')({ component: FinancePage, }) interface FinanceRecord { financeId: string name: string description: string | null amount: number amountEgp: number | null currency: string recordType: string purchasedByUserId: string | null purchasedAt: string category: string createdByUserId: string } interface FinanceLink { linkId: string financeId: string entityType: string entityId: string notes: string | null } const RECORD_TYPES = [ { value: 'expense', label: 'Expense' }, { value: 'income', label: 'Income' }, { value: 'reimbursement', label: 'Reimbursement' }, ] const CATEGORIES = [ { value: 'operations', label: 'Operations' }, { value: 'kitchen', label: 'Kitchen' }, { value: 'maintenance', label: 'Maintenance' }, { value: 'transport', label: 'Transport' }, { value: 'retreat', label: 'Retreat' }, { value: 'housekeeping', label: 'Housekeeping' }, { value: 'other', label: 'Other' }, ] const ENTITY_TYPES = [ { value: 'inventory_item', label: 'Inventory Item' }, { value: 'stay', label: 'Stay' }, { value: 'boat_trip', label: 'Boat Trip' }, { value: 'retreat', label: 'Retreat' }, { value: 'task', label: 'Task' }, ] const recordTypeBadgeColor: Record = { expense: 'red', income: 'green', reimbursement: 'blue', } const entityTypeBadgeColor: Record = { inventory_item: 'orange', stay: 'blue', boat_trip: 'cyan', retreat: 'grape', task: 'teal', } type Currency = 'EUR' | 'USD' | 'GBP' | 'EGP' const CURRENCY_OPTIONS = [ { value: 'EUR', label: 'EUR (€)' }, { value: 'USD', label: 'USD ($)' }, { value: 'GBP', label: 'GBP (£)' }, { value: 'EGP', label: 'EGP (ج.م)' }, ] function AddRecordDrawer({ opened, onClose }: { opened: boolean; onClose: () => void }) { const queryClient = useQueryClient() const [name, setName] = useState('') const [description, setDescription] = useState('') const [amount, setAmount] = useState(0) const [currency, setCurrency] = useState('EUR') const [recordType, setRecordType] = useState('expense') const [category, setCategory] = useState('operations') const resetForm = () => { setName('') setDescription('') setAmount(0) setCurrency('EUR') setRecordType('expense') setCategory('operations') } const mutation = usePikkuMutation('createFinanceRecord', { onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['listFinanceRecords'] }) queryClient.invalidateQueries({ queryKey: ['getFinanceSummary'] }) notifications.show({ title: 'Record created', message: 'Finance record has been added.', color: 'green', }) resetForm() onClose() }, onError: (err) => { notifications.show({ title: 'Error', message: err.message || 'Failed to create record.', color: 'red', }) }, }) const handleSubmit = (e: React.FormEvent) => { e.preventDefault() if (!name || !amount) { notifications.show({ title: 'Missing fields', message: 'Name and amount are required.', color: 'red', }) return } mutation.mutate({ name, description: description || undefined, amount, currency, recordType: recordType as 'expense' | 'income' | 'reimbursement', category: category as | 'operations' | 'kitchen' | 'maintenance' | 'transport' | 'retreat' | 'housekeeping' | 'other', }) } return (
setName(e.currentTarget.value)} required />