Added payments card to dashboard
X-Lovable-Edit-ID: edt-9dc8dc91-3e69-4d72-9380-a9a56bd758e8 Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
+38
-2
@@ -9,7 +9,7 @@ import { supabase } from "@/integrations/supabase/client";
|
||||
import { useAuth } from "@/lib/auth";
|
||||
import {
|
||||
Briefcase, Receipt, Clock, ArrowRight, CalendarDays, FileText,
|
||||
CheckSquare, UserPlus, DollarSign, Wallet, AlertCircle,
|
||||
CheckSquare, UserPlus, DollarSign, Wallet, AlertCircle, CreditCard,
|
||||
} from "lucide-react";
|
||||
import { formatCurrency, formatDate, statusBadgeClass } from "@/lib/format";
|
||||
import { format, startOfDay, startOfMonth, endOfMonth, subDays } from "date-fns";
|
||||
@@ -47,6 +47,7 @@ function Dashboard() {
|
||||
const [todaysEvents, setTodaysEvents] = useState<any[]>([]);
|
||||
const [recentCases, setRecentCases] = useState<any[]>([]);
|
||||
const [recentInvoices, setRecentInvoices] = useState<any[]>([]);
|
||||
const [recentPayments, setRecentPayments] = useState<any[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -64,7 +65,7 @@ function Dashboard() {
|
||||
myAssigneeRes,
|
||||
openCasesRes, newCasesRes, closedCasesRes,
|
||||
tasksTodayRes, hearingsTodayRes,
|
||||
recentCasesRes, recentInvRes,
|
||||
recentCasesRes, recentInvRes, recentPayRes,
|
||||
] = await Promise.all([
|
||||
supabase.from("trust_ledger_entries").select("entry_type, amount"),
|
||||
supabase.from("invoice_payments").select("amount, paid_on").gte("paid_on", monthStart).lte("paid_on", monthEnd),
|
||||
@@ -77,6 +78,7 @@ function Dashboard() {
|
||||
supabase.from("cases").select("id, title, case_number, next_hearing_date, next_hearing_notes").eq("next_hearing_date", todayStr),
|
||||
supabase.from("cases").select("id, case_number, title, status, updated_at, client:clients(name)").order("updated_at", { ascending: false }).limit(5),
|
||||
supabase.from("invoices").select("id, invoice_number, total, status, issue_date, client:clients(name)").order("created_at", { ascending: false }).limit(5),
|
||||
supabase.from("payment_requests").select("id, recipient_name, description, total_amount_cents, status, created_at, paid_at").order("created_at", { ascending: false }).limit(5),
|
||||
]);
|
||||
|
||||
// Trust balance
|
||||
@@ -132,6 +134,7 @@ function Dashboard() {
|
||||
setTodaysEvents(evts);
|
||||
setRecentCases(recentCasesRes.data ?? []);
|
||||
setRecentInvoices(recentInvRes.data ?? []);
|
||||
setRecentPayments(recentPayRes.data ?? []);
|
||||
setLoading(false);
|
||||
})();
|
||||
}, [user?.id]);
|
||||
@@ -313,6 +316,39 @@ function Dashboard() {
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Recent payments */}
|
||||
<div className="grid lg:grid-cols-2 gap-6 mt-6">
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center justify-between">
|
||||
<CardTitle className="text-base flex items-center gap-2">
|
||||
<CreditCard className="h-4 w-4" />
|
||||
Recent payments
|
||||
</CardTitle>
|
||||
<Button asChild variant="ghost" size="sm">
|
||||
<Link to="/payments">View all <ArrowRight className="h-3 w-3 ml-1" /></Link>
|
||||
</Button>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-1">
|
||||
{recentPayments.length === 0 && <p className="text-sm text-muted-foreground">No payment requests yet.</p>}
|
||||
{recentPayments.map((p) => (
|
||||
<Link key={p.id} to="/pay/$id" params={{ id: p.id }}
|
||||
className="flex items-center justify-between py-2.5 px-2 rounded-md hover:bg-muted/60 -mx-2">
|
||||
<div className="min-w-0">
|
||||
<div className="text-sm font-medium truncate">{p.recipient_name}</div>
|
||||
<div className="text-xs text-muted-foreground truncate">
|
||||
{p.description || "Payment request"} · {formatDate(p.paid_at || p.created_at)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-sm font-medium">{formatCurrency((p.total_amount_cents ?? 0) / 100)}</span>
|
||||
<Badge variant="outline" className={statusBadgeClass(p.status)}>{p.status}</Badge>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</PageContainer>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user