Invoice Creator Demo App
A modern, web-based invoice creation tool built entirely with PAN components. Create, manage, and export professional invoices with an intuitive contenteditable interface.
Features
๐จ Modern UI
- Clean, professional design with automatic light/dark mode
- Contenteditable fields for natural, app-like editing
- No forms - just click and type
- Responsive layout for desktop and mobile
๐ Invoice Management
- Create unlimited invoices
- Auto-save as you type
- Switch between invoices instantly
- Delete unwanted invoices
- Persistent localStorage storage
โ๏ธ Inline Editing
- Click-to-edit fields throughout
- No "edit mode" needed
- Natural contenteditable experience
- Tab between fields
- Enter to confirm and move to next field
๐ Line Items Grid
- Click "+" to add line items
- Contenteditable cells for description, hours, rate
- Auto-calculate line totals (hours ร rate)
- Auto-calculate invoice subtotal
- Delete rows with ร button
- Date field with placeholder format
๐ฐ Automatic Calculations
- Real-time subtotal calculation
- Adjustable tax rate
- Automatic tax calculation
- Prominent total display
- Notes/payment terms section
๐พ Data Management
- Auto-save on every change (1-second debounce)
- Manual save option
- Export single invoice to JSON
- Import invoices from JSON
- All data stored in localStorage
- No server required - fully offline capable
๐จ๏ธ Print & Export
- Print-optimized layout
- Clean print view (hides UI elements)
- Export to JSON for backup
- Import/Export for data portability
โจ๏ธ Keyboard Shortcuts
Ctrl/Cmd + S: Save invoiceCtrl/Cmd + P: Print invoiceCtrl/Cmd + N: New invoiceEnter: Confirm field and move to nextTab: Navigate between fields
Components
The app is built from 4 custom PAN components:
1.
Manages invoice header with from/to customer information.
Features:
- Contenteditable from/to sections
- Invoice number, date, due date fields
- Integration point for contact selection
- Broadcasts changes via PAN
- Publishes:
invoice.header.changed - Subscribes:
invoice.load,invoice.clear,contact.selected
2.
Editable grid for invoice line items.
Features:
- Click to add new rows
- Contenteditable cells (date, description, hours, rate)
- Auto-calculate line totals
- Delete rows
- Tab/Enter navigation
- Publishes:
invoice.items.changed,invoice.totals.changed - Subscribes:
invoice.load,invoice.clear
3.
Displays and calculates invoice totals.
Features:
- Auto-updates from line items
- Editable tax rate
- Subtotal, tax, total calculations
- Notes/payment terms field
- Large, prominent total display
- Publishes:
invoice.total.calculated - Subscribes:
invoice.totals.changed,invoice.load,invoice.clear
4.
Centralized state management and persistence.
Features:
- localStorage persistence
- Multiple invoice management
- Auto-save with debouncing
- Import/Export JSON
- Coordinates all components via PAN
- Publishes:
invoice.load,invoice.saved,invoice.list-updated,invoice.current-changed - Subscribes:
invoice.*(all invoice commands)
Architecture
State Flow
User Edit โ Component โ PAN Event โ Store โ localStorage
โ โ
UI Update โ PAN Event โ Store
Data Model
interface Invoice {
id: string;
created: string; // ISO date
modified: string; // ISO date
header: {
from: ContactInfo;
to: ContactInfo;
invoiceNumber: string;
invoiceDate: string;
dueDate: string;
};
items: LineItem[];
totals: {
subtotal: number;
tax: number;
taxRate: number;
total: number;
notes: string;
};
}
interface ContactInfo {
name: string;
address: string;
city: string;
phone: string;
email: string;
}
interface LineItem {
id: number;
date: string;
description: string;
hours: string;
rate: string;
total: number;
}
Usage
Basic Usage
demo-apps/invoice.htmlCreating Your First Invoice
Managing Multiple Invoices
- Use the dropdown to switch between invoices
- Click "New" to create a new invoice
- Previous invoice auto-saves before switching
- "Delete" removes current invoice (with confirmation)
Importing/Exporting
Export single invoice:- Single invoice:
{ id, created, modified, header, items, totals } - Multiple invoices:
[ invoice1, invoice2, ... ]
Integration
Adding Contact Selection
The invoice app is designed to integrate with a contact management system:
// Listen for contact selector request
bus.subscribe('invoice.open-contact-selector', () => {
// Show your contact selector UI
showContactModal();
});
// Send selected contact
function selectContact(contact) {
bus.publish('contact.selected', {
name: contact.name,
address: contact.address,
city: contact.city,
phone: contact.phone,
email: contact.email
});
}
Custom Branding
Override CSS variables in your theme:
:root {
--color-primary: #your-brand-color;
}
Adding PDF Export
The app currently exports to JSON. To add PDF export:
// Using html2pdf.js or similar
document.getElementById('btn-pdf').addEventListener('click', async () => {
const element = document.querySelector('.main-content');
await html2pdf().from(element).save('invoice.pdf');
});
Extending
Adding New Fields
pan-invoice-store.mjsExample - Adding a "PO Number" field:
// In pan-invoice-header.mjs
<div class="field">
<div class="field-label">PO Number</div>
<div class="field-value"
contenteditable="true"
data-field="poNumber"
data-placeholder="PO-12345">
${this._data.poNumber || ''}
</div>
</div>
Custom Line Item Types
Extend pan-invoice-items to support different item types:
// Add item type column
<th class="col-type">Type</th>
// Add select or contenteditable for type
<td contenteditable="true" data-field="type">
${item.type || 'Service'}
</td>
Advanced Calculations
Add discounts, fees, or complex calculations in pan-invoice-totals:
_calculate() {
const discount = this._subtotal * (this._discountRate / 100);
this._subtotal = this._subtotal - discount;
this._tax = this._subtotal * (this._taxRate / 100);
this._total = this._subtotal + this._tax + this._fees;
}
Browser Support
- โ Chrome 90+
- โ Firefox 88+
- โ Safari 14+
- โ Edge 90+
- ES6 Modules
- Web Components
- localStorage
- contenteditable
- CSS Custom Properties
Offline Usage
The app works completely offline:
- No external dependencies
- All data stored locally
- No network requests
- Can be saved as standalone HTML
Security & Privacy
- All data stays local - stored only in browser localStorage
- No server communication - fully client-side
- No tracking - zero analytics or external calls
- Export for backup - never lose your data
- Clear data - clear localStorage to remove all invoices
Performance
- Fast - No server round-trips
- Instant switching - Invoices load from localStorage
- Auto-save - Debounced to prevent excessive writes
- Lightweight - < 50KB total (all components)
License
Part of the PAN (Page Area Network) project - MIT License
Acknowledgments
Inspired by the classic contenteditable invoice tool, modernized with web components and the PAN architecture.