Add business Finance hub with invoices and templates.

Ship invoice issue/list/templates under Finance, fix tenant theme reset and owner role badge, and show customers-joined charts by Persian months.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Alireza Hassani
2026-08-11 15:17:03 +03:30
co-authored by Cursor
parent 722933dda9
commit 917b840ee5
44 changed files with 5136 additions and 105 deletions
@@ -6,9 +6,9 @@
position: sticky;
top: 0;
z-index: 50;
background: var(--glass-bg);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
background: var(--header-bg, var(--glass-bg-strong, var(--glass-bg)));
backdrop-filter: blur(20px) saturate(150%);
-webkit-backdrop-filter: blur(20px) saturate(150%);
border-bottom: 1px solid var(--glass-border);
isolation: isolate;
transform: translateZ(0);
+5
View File
@@ -12,6 +12,11 @@
--bg-gradient-end: #f4f7ff;
--glass-bg: rgba(255, 255, 255, 0.42);
--glass-bg-strong: rgba(255, 255, 255, 0.62);
--header-bg: color-mix(
in srgb,
color-mix(in srgb, var(--primary-light) 42%, #ffffff) 90%,
transparent
);
--glass-border: rgba(255, 255, 255, 0.75);
--glass-shadow: 0 8px 32px rgba(30, 58, 138, 0.1);
--primary: #0a1628;
@@ -193,6 +193,7 @@ export function BusinessInvoicesPage() {
<thead>
<tr>
<th className={tableStyles.th}>Name</th>
<th className={tableStyles.th}>Billed user</th>
<th className={tableStyles.th}>Issued</th>
<th className={tableStyles.th}>Status</th>
<th className={tableStyles.th}>Total</th>
@@ -203,7 +204,7 @@ export function BusinessInvoicesPage() {
<tbody>
{!loading && invoices.length === 0 ? (
<tr>
<td className={tableStyles.td} colSpan={6}>
<td className={tableStyles.td} colSpan={7}>
No invoices yet for this business.
</td>
</tr>
@@ -216,6 +217,15 @@ export function BusinessInvoicesPage() {
{invoice.items?.length ?? 0} item{(invoice.items?.length ?? 0) === 1 ? '' : 's'}
</div>
</td>
<td className={tableStyles.td}>
{invoice.user
? [invoice.user.firstName, invoice.user.lastName].filter(Boolean).join(' ') ||
invoice.user.cell
: '—'}
{invoice.user?.cell ? (
<div className={tableStyles.subText}>{invoice.user.cell}</div>
) : null}
</td>
<td className={tableStyles.td}>{formatDate(invoice.issuedAt)}</td>
<td className={tableStyles.td}>
<button
+13
View File
@@ -48,6 +48,7 @@ export interface Invoice {
id: string
publicId: string
businessId: string
userId: string
ownerScope: 'platform' | 'business'
issuerBusinessId: string | null
status: InvoiceStatus
@@ -65,6 +66,12 @@ export interface Invoice {
name: string
nameFa: string | null
}
user?: {
id: string
firstName: string | null
lastName: string | null
cell: string
}
issuer?: {
id: string
firstName: string | null
@@ -85,6 +92,10 @@ export type PublicInvoice = {
topText: string | null
issuedAt: string
business?: Invoice['business']
user?: {
firstName: string | null
lastName: string | null
}
items?: InvoiceItem[]
keyPoints?: InvoiceKeyPoint[]
accounts?: InvoiceAccount[]
@@ -115,6 +126,7 @@ export interface InvoiceAccountInput {
}
export interface CreateInvoicePayload {
userId?: string
items: InvoiceItemInput[]
name?: string
topText?: string
@@ -126,6 +138,7 @@ export interface CreateInvoicePayload {
}
export type UpdateInvoicePayload = {
userId?: string
items: InvoiceItemInput[]
name?: string | null
topText?: string | null