Legal Billing Software
Manage clients, track time, and generate invoices seamlessly.
Billing Dashboard
Total Hours Logged (All Time)
0.00
Total Unbilled Amount
$0.00
Active Cases
0
Manage Clients & Cases
Add a New Client
Add a New Case
Existing Clients and Cases
No clients added yet.
Log Time or Expense
Generate Invoice
Your generated invoice will appear here.
Firm & Billing Configuration
Total Due: ${formatCurrency(totalAmount)}
${invoiceEntries.length} entries found. Click "Download PDF" for a detailed breakdown.
`; document.getElementById('invoice-preview-container').innerHTML = previewHTML; document.getElementById('download-btn-container').style.display = 'block'; } async function handlePdfDownload() { if (!currentInvoiceData) return; const { firm, client, timeEntries, expenseEntries, timeSubtotal, expenseSubtotal, totalAmount, invoiceDate, invoiceNumber } = currentInvoiceData; const contentHTML = `INVOICE
Invoice #: ${invoiceNumber}
Date: ${invoiceDate}
${firm.firmName}
${firm.firmAddress.replace(/\n/g, '
')}
${firm.firmEmail}
${firm.firmPhone}
${firm.firmAddress.replace(/\n/g, '
')}
${firm.firmEmail}
${firm.firmPhone}
BILL TO:
${client.name}
${client.contact}
${client.email}
${client.name}
${client.contact}
${client.email}
Total Amount Due:
${formatCurrency(totalAmount)}
Professional Services
| Date | Description | Hours | Rate | Amount |
|---|---|---|---|---|
| ${e.date} | ${e.description} | ${e.hours.toFixed(2)} | ${formatCurrency(firm.defaultRate)} | ${formatCurrency(e.hours * firm.defaultRate)} |
| Subtotal | ${formatCurrency(timeSubtotal)} | |||
Expenses
| Date | Description | Amount | |
|---|---|---|---|
| ${e.date} | ${e.description} | ${formatCurrency(e.amount)} | |
| Subtotal | ${formatCurrency(expenseSubtotal)} | ||
| Services Total | ${formatCurrency(timeSubtotal)} |
|---|---|
| Expenses Total | ${formatCurrency(expenseSubtotal)} |
| TOTAL DUE | ${formatCurrency(totalAmount)} |
Notes: Please make payment within 30 days. Thank you for your business.
Invoice has been processed. Generate a new one.
`; document.getElementById('download-btn-container').style.display = 'none'; currentInvoiceData = null; } } // --- INITIALIZATION --- nextBtn.addEventListener('click', () => changeTab(currentTab + 1)); prevBtn.addEventListener('click', () => changeTab(currentTab - 1)); tabButtons.forEach(button => button.addEventListener('click', () => changeTab(parseInt(button.dataset.tab)))); renderAll(); renderConfigForm(); // Populate config form on load updateTabDisplay(); });