--- import DashboardLayout from '../../../layouts/DashboardLayout.astro'; import { Icon } from 'astro-icon/components'; import { db } from '../../../db'; import { invoices, clients, members } from '../../../db/schema'; import { eq, desc, and } from 'drizzle-orm'; const user = Astro.locals.user; if (!user) return Astro.redirect('/login'); // Get current team from cookie const currentTeamId = Astro.cookies.get('currentTeamId')?.value; const userMemberships = await db.select() .from(members) .where(eq(members.userId, user.id)) .all(); if (userMemberships.length === 0) return Astro.redirect('/dashboard'); // Use current team or fallback to first membership const userMembership = currentTeamId ? userMemberships.find(m => m.organizationId === currentTeamId) || userMemberships[0] : userMemberships[0]; const currentTeamIdResolved = userMembership.organizationId; // Fetch invoices and quotes const allInvoices = await db.select({ invoice: invoices, client: clients, }) .from(invoices) .leftJoin(clients, eq(invoices.clientId, clients.id)) .where(eq(invoices.organizationId, currentTeamIdResolved)) .orderBy(desc(invoices.issueDate)) .all(); const formatCurrency = (amount: number, currency: string) => { return new Intl.NumberFormat('en-US', { style: 'currency', currency: currency, }).format(amount / 100); }; const getStatusColor = (status: string) => { switch (status) { case 'paid': return 'badge-success'; case 'accepted': return 'badge-success'; case 'sent': return 'badge-info'; case 'draft': return 'badge-ghost'; case 'void': return 'badge-error'; case 'declined': return 'badge-error'; default: return 'badge-ghost'; } }; ---

Invoices & Quotes

Manage your billing and estimates

Create New
Total Invoices
{allInvoices.filter(i => i.invoice.type === 'invoice').length}
All time
Open Quotes
{allInvoices.filter(i => i.invoice.type === 'quote' && i.invoice.status === 'sent').length}
Waiting for approval
Total Revenue
{formatCurrency(allInvoices .filter(i => i.invoice.type === 'invoice' && i.invoice.status === 'paid') .reduce((acc, curr) => acc + curr.invoice.total, 0), 'USD')}
Paid invoices
{allInvoices.length === 0 ? ( ) : ( allInvoices.map(({ invoice, client }) => ( )) )}
Number Client Date Due Date Amount Status Type
No invoices or quotes found. Create one to get started.
{invoice.number} {client ? (
{client.name}
) : ( Deleted Client )}
{invoice.issueDate.toLocaleDateString()} {invoice.dueDate.toLocaleDateString()} {formatCurrency(invoice.total, invoice.currency)}
{invoice.status}
{invoice.type}