mirror of
https://github.com/escalante29/WealthySmart.git
synced 2026-05-19 08:48:48 +02:00
All checks were successful
Deploy to VPS / deploy (push) Successful in 28s
Replace custom markup across all pages and components with shadcn/ui primitives (Dialog, Sheet, Select, Card, Tabs, etc.). Add reusable DataTable component powered by @tanstack/react-table with sortable column headers and client-side pagination. Introduce TransactionList with responsive mobile cards and desktop DataTable, dashboard section customization (DashboardSection, SectionConfigDialog), and settings API types. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
66 lines
2.2 KiB
TypeScript
66 lines
2.2 KiB
TypeScript
import { useEffect, useState, useCallback } from 'react';
|
|
import { ArrowLeftRight } from 'lucide-react';
|
|
|
|
import api, { type Transaction } from '../api';
|
|
import TransactionList from '../components/TransactionList';
|
|
import { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';
|
|
|
|
type SourceTab = 'CASH' | 'TRANSFER';
|
|
|
|
export default function Transfers() {
|
|
const [transactions, setTransactions] = useState<Transaction[]>([]);
|
|
const [search, setSearch] = useState('');
|
|
const [sourceTab, setSourceTab] = useState<SourceTab>('CASH');
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
const fetchTransactions = useCallback(async () => {
|
|
setLoading(true);
|
|
try {
|
|
const params: Record<string, string> = { source: sourceTab, limit: '200' };
|
|
if (search) params.search = search;
|
|
const { data } = await api.get('/transactions/', { params });
|
|
setTransactions(data);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, [search, sourceTab]);
|
|
|
|
useEffect(() => {
|
|
const timer = setTimeout(fetchTransactions, 300);
|
|
return () => clearTimeout(timer);
|
|
}, [fetchTransactions]);
|
|
|
|
return (
|
|
<div className="space-y-5">
|
|
<div>
|
|
<h1 className="text-2xl font-bold font-heading">Cash & Transfers</h1>
|
|
<p className="text-sm text-muted-foreground mt-1">
|
|
Track non-credit-card expenses
|
|
</p>
|
|
</div>
|
|
|
|
<Tabs value={sourceTab} onValueChange={(v) => setSourceTab(v as SourceTab)}>
|
|
<TabsList>
|
|
<TabsTrigger value="CASH">Cash</TabsTrigger>
|
|
<TabsTrigger value="TRANSFER">Transfers</TabsTrigger>
|
|
</TabsList>
|
|
|
|
<TabsContent value={sourceTab} className="mt-5 space-y-5">
|
|
<TransactionList
|
|
transactions={transactions}
|
|
loading={loading}
|
|
source={sourceTab}
|
|
search={search}
|
|
onSearchChange={setSearch}
|
|
onRefresh={fetchTransactions}
|
|
showCategory={false}
|
|
addLabel={sourceTab === 'CASH' ? 'Add Cash Expense' : 'Add Transfer'}
|
|
emptyIcon={<ArrowLeftRight className="w-8 h-8 mx-auto mb-3 text-muted-foreground/50" />}
|
|
emptyMessage={`No ${sourceTab.toLowerCase()} transactions yet`}
|
|
/>
|
|
</TabsContent>
|
|
</Tabs>
|
|
</div>
|
|
);
|
|
}
|