Scaffold Gishen Admin: React/Vite shadcn console with role modules, EN/AM i18n, mocks, and backend spec. Co-authored-by: Cursor <cursoragent@cursor.com>
84 lines
3.1 KiB
TypeScript
84 lines
3.1 KiB
TypeScript
import { useState } from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import { toast } from 'sonner'
|
|
import { PageShell } from '@/layouts/PageShell'
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
|
|
import { Badge } from '@/components/ui/badge'
|
|
import { Button } from '@/components/ui/button'
|
|
import { SwitchRow } from '@/pages/finance/SwitchRow'
|
|
import { settlements } from '@/mocks/data'
|
|
import { formatEtb } from '@/lib/utils'
|
|
|
|
const gateways = [
|
|
{ id: 'chapa', label: 'Chapa', enabled: true },
|
|
{ id: 'arifpay', label: 'ArifPay', enabled: true },
|
|
{ id: 'telebirr', label: 'Telebirr', enabled: false },
|
|
{ id: 'mpesa', label: 'M-Pesa', enabled: false },
|
|
]
|
|
|
|
export function FinancePage() {
|
|
const { t } = useTranslation()
|
|
const [gw, setGw] = useState(gateways)
|
|
|
|
return (
|
|
<PageShell title={t('finance.title')} subtitle={t('finance.subtitle')}>
|
|
<div className="grid gap-4 lg:grid-cols-2">
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Daily settlements</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="p-4 pt-0">
|
|
<Table>
|
|
<TableHeader>
|
|
<TableRow>
|
|
<TableHead>Channel</TableHead>
|
|
<TableHead>Date</TableHead>
|
|
<TableHead>Volume</TableHead>
|
|
<TableHead>Status</TableHead>
|
|
</TableRow>
|
|
</TableHeader>
|
|
<TableBody>
|
|
{settlements.map((s) => (
|
|
<TableRow key={s.channel}>
|
|
<TableCell>{s.channel}</TableCell>
|
|
<TableCell>{s.date}</TableCell>
|
|
<TableCell>{formatEtb(s.volumeEtb)}</TableCell>
|
|
<TableCell>
|
|
<Badge variant={s.status === 'reconciled' ? 'success' : 'warning'}>{s.status}</Badge>
|
|
</TableCell>
|
|
</TableRow>
|
|
))}
|
|
</TableBody>
|
|
</Table>
|
|
</CardContent>
|
|
</Card>
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle>Payment gateways</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-3 p-4 pt-0">
|
|
{gw.map((g) => (
|
|
<SwitchRow
|
|
key={g.id}
|
|
label={g.label}
|
|
enabled={g.enabled}
|
|
onToggle={() => {
|
|
setGw((prev) => prev.map((x) => (x.id === g.id ? { ...x, enabled: !x.enabled } : x)))
|
|
toast.success(`${g.label} ${g.enabled ? 'disabled' : 'enabled'} (no code release)`)
|
|
}}
|
|
/>
|
|
))}
|
|
<div className="rounded-xl border bg-muted/40 p-3 text-sm">
|
|
Loyalty points liability (Aug): <strong>{formatEtb(182400)}</strong>
|
|
</div>
|
|
<Button variant="outline" onClick={() => toast.message('Refund queued (mock)')}>
|
|
Process refund
|
|
</Button>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</PageShell>
|
|
)
|
|
}
|