/* @component-map * App — Main container, tab navigation [app.jsx] * InvoiceForm — Client details, line items, tax, notes input [components/InvoiceForm.jsx] * InvoicePreview — Professional invoice preview with PDF export [components/InvoicePreview.jsx] * InvoiceHistory — Saved invoices list [components/InvoiceHistory.jsx] * @end-component-map */ // DEPLOY_CONFIG: {"triggers": [{"name": "invoice_marked_sent_email", "on": "collection.update", "collection": "invoices", "actions": [{"type": "email", "to": "{{record.customer_email}}", "subject": "Your invoice is ready", "body": "Your invoice has been marked as sent. View it here: {{client_access_link}}"}]}], "cron": [{"name": "overdue_invoice_reminder", "schedule": "0 9 * * 1-5", "action": "event", "config": {"event_type": "invoice_overdue_reminder"}}]} import { useState } from 'react'; import { useAuth, useCollection } from '@deplixo/sdk'; import { InvoiceForm } from './components/InvoiceForm.jsx'; import { InvoicePreview } from './components/InvoicePreview.jsx'; import { InvoiceHistory } from './components/InvoiceHistory.jsx'; function App() { const { user, loading, login, logout } = useAuth(); const [activeTab, setActiveTab] = useState('create'); const [previewData, setPreviewData] = useState(null); const [editingInvoice, setEditingInvoice] = useState(null); const [statusFilter, setStatusFilter] = useState('all'); const [historySearch, setHistorySearch] = useState(''); const { items: invoiceRecords, loading: invoicesLoading, add, update, remove, search } = useCollection('invoices'); const handlePreview = (data) => { setPreviewData(data); setActiveTab('preview'); }; const handleEditFromHistory = (invoice) => { setEditingInvoice(invoice); setActiveTab('create'); }; const handleBackToCreate = () => { setActiveTab('create'); }; const handleSignIn = () => { login('google'); }; const handleSaveInvoice = async (invoiceData) => { const status = invoiceData?.status || 'draft'; const payload = { ...invoiceData, status, updatedAt: new Date().toISOString(), createdAt: invoiceData?.createdAt || new Date().toISOString() }; if (invoiceData?.id) { return await update(invoiceData.id, payload); } return await add(payload); }; const handleSearchHistory = async (query) => { setHistorySearch(query); if (!query?.trim()) return; await search(query); }; const tabs = [ { id: 'create', label: '✏️ Create', icon: '' }, { id: 'preview', label: '👁️ Preview', icon: '' }, { id: 'history', label: '📋 History', icon: '' } ]; if (loading) return
Signing in...
; if (!user) { return (

Invoice Generator

Create professional invoices in seconds

🔐

Sign in to continue

Use Google authentication to save invoices, access your history, and manage drafts securely.

); } const filteredInvoices = invoiceRecords .filter((invoice) => (statusFilter === 'all' ? true : invoice?.status === statusFilter)) .filter((invoice) => { if (!historySearch?.trim()) return true; const q = historySearch.toLowerCase(); return ( (invoice?.clientName || '').toLowerCase().includes(q) || (invoice?.clientEmail || '').toLowerCase().includes(q) || (invoice?.invoiceNumber || '').toLowerCase().includes(q) || (invoice?.notes || '').toLowerCase().includes(q) ); }); return (

Invoice Generator

Create professional invoices in seconds

{user.avatar ? {user.name} : null} {user.name}
{activeTab === 'create' && ( setEditingInvoice(null)} /> )} {activeTab === 'preview' && previewData && ( )} {activeTab === 'history' && ( )}
); } ReactDOM.createRoot(document.getElementById('root')).render();