Refactored a bunch of shit
All checks were successful
Docker Deploy / build-and-push (push) Successful in 3m57s

This commit is contained in:
2026-02-09 01:49:19 -07:00
parent c39865031a
commit 12d59bb42f
40 changed files with 844 additions and 678 deletions

View File

@@ -1,27 +1,18 @@
---
import DashboardLayout from '../../../layouts/DashboardLayout.astro';
import { Icon } from 'astro-icon/components';
import StatCard from '../../../components/StatCard.astro';
import { db } from '../../../db';
import { invoices, clients, members } from '../../../db/schema';
import { invoices, clients } from '../../../db/schema';
import { eq, desc, and, gte, lte, sql } from 'drizzle-orm';
import { getCurrentTeam } from '../../../lib/getCurrentTeam';
import { formatCurrency } from '../../../lib/formatTime';
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 userMembership = await getCurrentTeam(user, Astro.cookies.get('currentTeamId')?.value);
if (!userMembership) return Astro.redirect('/dashboard');
const currentTeamIdResolved = userMembership.organizationId;
@@ -96,13 +87,6 @@ const yearInvoices = allInvoicesRaw.filter(i => {
return issueDate >= yearStart && issueDate <= yearEnd;
});
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';
@@ -130,40 +114,35 @@ const getStatusColor = (status: string) => {
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div class="stats shadow bg-base-100 border border-base-200">
<div class="stat">
<div class="stat-figure text-primary">
<Icon name="heroicons:document-text" class="w-8 h-8" />
</div>
<div class="stat-title">Total Invoices</div>
<div class="stat-value text-primary">{yearInvoices.filter(i => i.invoice.type === 'invoice').length}</div>
<div class="stat-desc">{selectedYear === 'current' ? `${currentYear} (YTD)` : selectedYear}</div>
</div>
<StatCard
title="Total Invoices"
value={String(yearInvoices.filter(i => i.invoice.type === 'invoice').length)}
description={selectedYear === 'current' ? `${currentYear} (YTD)` : selectedYear}
icon="heroicons:document-text"
color="text-primary"
/>
</div>
<div class="stats shadow bg-base-100 border border-base-200">
<div class="stat">
<div class="stat-figure text-secondary">
<Icon name="heroicons:clipboard-document-list" class="w-8 h-8" />
</div>
<div class="stat-title">Open Quotes</div>
<div class="stat-value text-secondary">{yearInvoices.filter(i => i.invoice.type === 'quote' && i.invoice.status === 'sent').length}</div>
<div class="stat-desc">Waiting for approval</div>
</div>
<StatCard
title="Open Quotes"
value={String(yearInvoices.filter(i => i.invoice.type === 'quote' && i.invoice.status === 'sent').length)}
description="Waiting for approval"
icon="heroicons:clipboard-document-list"
color="text-secondary"
/>
</div>
<div class="stats shadow bg-base-100 border border-base-200">
<div class="stat">
<div class="stat-figure text-success">
<Icon name="heroicons:currency-dollar" class="w-8 h-8" />
</div>
<div class="stat-title">Total Revenue</div>
<div class="stat-value text-success">
{formatCurrency(yearInvoices
.filter(i => i.invoice.type === 'invoice' && i.invoice.status === 'paid')
.reduce((acc, curr) => acc + curr.invoice.total, 0), 'USD')}
</div>
<div class="stat-desc">Paid invoices ({selectedYear === 'current' ? `${currentYear} YTD` : selectedYear})</div>
</div>
<StatCard
title="Total Revenue"
value={formatCurrency(yearInvoices
.filter(i => i.invoice.type === 'invoice' && i.invoice.status === 'paid')
.reduce((acc, curr) => acc + curr.invoice.total, 0), 'USD')}
description={`Paid invoices (${selectedYear === 'current' ? `${currentYear} YTD` : selectedYear})`}
icon="heroicons:currency-dollar"
color="text-success"
/>
</div>
</div>