{% extends 'base.html' %}
{% block title %}Documents โ AgentForms{% endblock %}
{% block head_extra %}
<style nonce="{{ csp_nonce }}">
.page-header {
display: flex; align-items: center; justify-content: space-between;
margin-bottom: 24px; flex-wrap: wrap; gap: 12px;
}
.page-header h1 { font-size: 24px; font-weight: 700; color: #1a1a2e; }
.page-header p { color: #666; font-size: 14px; margin-top: 4px; }
/* Tab bar */
.tab-bar {
display: flex; gap: 0; border-bottom: 2px solid #eee; margin-bottom: 24px;
}
.tab-btn {
padding: 10px 20px; font-size: 14px; font-weight: 600; color: #666;
cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -2px;
background: none; border-top: none; border-left: none; border-right: none;
transition: all 0.15s;
}
.tab-btn:hover { color: #1a1a2e; }
.tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }
/* Status count badges */
.status-bar {
display: flex; gap: 12px; margin-bottom: 20px; flex-wrap: wrap;
}
.status-chip {
display: flex; align-items: center; gap: 8px;
padding: 10px 16px; background: white; border-radius: 8px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1); cursor: pointer;
border: 2px solid transparent; transition: all 0.15s;
}
.status-chip:hover { border-color: var(--accent); }
.status-chip.active { border-color: var(--accent); background: var(--accent-dim); }
.status-chip .chip-count {
font-size: 20px; font-weight: 700; color: #1a1a2e; min-width: 28px; text-align: center;
}
.status-chip .chip-label {
font-size: 13px; color: #666; text-transform: capitalize;
}
/* Status badges in table */
.status-badge {
display: inline-block; padding: 3px 10px; border-radius: 12px;
font-size: 12px; font-weight: 600; text-transform: capitalize;
}
.status-draft { background: #e9ecef; color: #333; }
.status-sent { background: #dbeafe; color: #1e40af; }
.status-viewed { background: #fef3c7; color: #92400e; }
.status-paid { background: #d1fae5; color: #065f46; }
.status-void { background: #fee2e2; color: #991b1b; }
/* Document table */
.doc-table { width: 100%; border-collapse: collapse; }
.doc-table th {
background: #f8f8f8; font-weight: 600; font-size: 12px;
text-transform: uppercase; letter-spacing: 0.05em; color: #666;
padding: 12px; border-bottom: 2px solid #eee;
}
.doc-table td {
padding: 12px; border-bottom: 1px solid #eee; font-size: 14px;
vertical-align: middle;
}
.doc-table tr:hover td { background: #fafafa; }
/* Links */
.doc-link {
color: var(--accent); text-decoration: none; font-weight: 500;
}
.doc-link:hover { text-decoration: underline; }
/* Action buttons */
.doc-actions { display: flex; gap: 6px; align-items: center; }
.action-btn {
display: inline-flex; align-items: center; gap: 4px;
padding: 6px 12px; border: 1px solid #ddd; border-radius: 6px;
background: white; color: #666; font-size: 12px; cursor: pointer;
text-decoration: none; transition: all 0.15s;
}
.action-btn:hover { border-color: var(--accent); color: var(--accent); }
.action-btn.primary {
background: var(--accent); color: white; border-color: var(--accent);
}
.action-btn.primary:hover { background: var(--accent-bright); }
.action-btn.danger { color: #dc3545; border-color: #dc3545; }
.action-btn.danger:hover { background: #fee2e2; }
/* Primary button */
.primary-btn {
display: inline-flex; align-items: center; gap: 6px;
padding: 10px 20px; background: var(--accent); color: white;
border: none; border-radius: 6px; font-size: 14px; font-weight: 600;
cursor: pointer; text-decoration: none; transition: all 0.15s;
font-family: inherit;
}
.primary-btn:hover { background: var(--accent-bright); }
/* Overdue indicator */
.overdue-dot {
display: inline-block; width: 8px; height: 8px;
background: #ef4444; border-radius: 50%; margin-right: 6px;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
/* Empty state */
.empty-state {
text-align: center; padding: 60px 20px; color: #888;
}
.empty-state svg { margin-bottom: 16px; opacity: 0.5; }
.empty-state p { font-size: 14px; margin-bottom: 12px; }
/* Site badge */
.site-badge {
display: inline-block; padding: 2px 8px;
background: var(--accent-dim); border-radius: 4px;
font-size: 12px; color: var(--accent); font-weight: 500;
}
/* Template cards */
.template-grid {
display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px; margin-bottom: 24px;
}
.template-card {
background: white; border: 1px solid #eee; border-radius: 8px;
padding: 20px; display: flex; flex-direction: column; gap: 12px;
transition: all 0.15s;
}
.template-card:hover { border-color: var(--accent); box-shadow: 0 2px 8px rgba(16,185,129,0.1); }
.template-card h4 { font-size: 15px; font-weight: 600; margin: 0; }
.template-card .tpl-type {
display: inline-block; padding: 2px 8px; background: var(--accent-dim);
color: var(--accent); border-radius: 4px; font-size: 11px; font-weight: 600;
}
.template-card .tpl-layout {
font-size: 12px; color: #888;
}
.template-card .tpl-actions {
display: flex; gap: 8px; margin-top: auto;
}
/* Modal */
.modal-overlay {
display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.45);
z-index: 2000; align-items: center; justify-content: center; padding: 20px;
}
.modal-overlay.open { display: flex; }
.modal-box {
background: white; border-radius: 12px; width: 100%; max-width: 560px;
max-height: 85vh; overflow-y: auto; box-shadow: 0 20px 60px rgba(0,0,0,0.15);
}
.modal-header {
display: flex; align-items: center; justify-content: space-between;
padding: 20px 24px 16px; border-bottom: 1px solid #eee;
}
.modal-header h3 { font-size: 17px; font-weight: 600; margin: 0; }
.modal-close {
background: none; border: none; font-size: 22px; cursor: pointer; color: #888;
padding: 4px 8px; border-radius: 4px; line-height: 1;
}
.modal-close:hover { background: #f5f5f5; color: #333; }
.modal-body { padding: 20px 24px; }
.modal-footer {
display: flex; gap: 8px; justify-content: flex-end; padding: 16px 24px;
border-top: 1px solid #eee;
}
/* Form elements */
.form-group { margin-bottom: 16px; }
.form-group label {
display: block; font-size: 13px; font-weight: 500; margin-bottom: 4px; color: #666;
}
.form-group input, .form-group select, .form-group textarea {
width: 100%; padding: 10px 12px; border: 1px solid #ddd;
border-radius: 6px; font-size: 14px; font-family: inherit;
}
.form-group input:focus, .form-group select:focus, .form-group textarea:focus {
outline: none; border-color: var(--accent);
}
.form-hint { font-size: 12px; color: #999; margin-top: 4px; }
/* Line items */
.line-item-row {
display: grid; grid-template-columns: 1fr 60px 100px 32px;
gap: 8px; margin-bottom: 8px; align-items: center;
}
.line-item-row input {
padding: 8px 10px; border: 1px solid #ddd; border-radius: 6px;
font-size: 13px; font-family: inherit;
}
.line-item-row input:focus { outline: none; border-color: var(--accent); }
.line-item-remove {
background: none; border: none; color: #dc3545; cursor: pointer;
font-size: 18px; padding: 4px; border-radius: 4px;
}
.line-item-remove:hover { background: #fee2e2; }
.line-total {
text-align: right; font-size: 14px; font-weight: 600;
padding: 12px 0; border-top: 2px solid #eee; margin-top: 8px;
}
/* PDF Preview Modal */
.preview-overlay {
display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.7);
z-index: 2000; flex-direction: column; align-items: stretch;
}
.preview-overlay.open { display: flex; }
.preview-toolbar {
display: flex; align-items: center; justify-content: space-between;
padding: 10px 20px; background: #1a1a2e; color: white; flex-shrink: 0;
}
.preview-toolbar h3 { font-size: 15px; font-weight: 600; margin: 0; }
.preview-toolbar .preview-actions { display: flex; gap: 8px; }
.preview-toolbar button {
padding: 6px 14px; border: 1px solid rgba(255,255,255,0.3); border-radius: 6px;
background: rgba(255,255,255,0.1); color: white; font-size: 13px; cursor: pointer;
font-family: inherit; transition: all 0.15s;
}
.preview-toolbar button:hover { background: rgba(255,255,255,0.2); }
.preview-toolbar button.primary { background: var(--accent); border-color: var(--accent); }
.preview-toolbar button.primary:hover { background: var(--accent-bright); }
.preview-iframe-wrap {
flex: 1; background: #525659;
}
.preview-iframe-wrap iframe {
width: 100%; height: 100%; border: none;
}
/* Toast notification */
.toast {
position: fixed; bottom: 24px; right: 24px; padding: 12px 20px;
background: #1a1a2e; color: white; border-radius: 8px; font-size: 14px;
box-shadow: 0 4px 12px rgba(0,0,0,0.2); z-index: 2000;
transform: translateY(100px); opacity: 0; transition: all 0.3s;
}
.toast.show { transform: translateY(0); opacity: 1; }
/* Section header */
.section-header {
display: flex; justify-content: space-between; align-items: center;
margin-bottom: 16px;
}
.section-header h2 { font-size: 18px; font-weight: 600; color: #1a1a2e; }
/* Mobile responsive */
@media (max-width: 640px) {
.container { padding: 8px; }
.page-header { flex-direction: column; align-items: flex-start; }
.page-header > div:last-child { width: 100%; display: flex; flex-direction: column; gap: 8px; }
.page-header .primary-btn, .page-header .action-btn { width: 100%; justify-content: center; text-align: center; }
.status-bar { flex-wrap: wrap; gap: 8px; }
.status-chip { flex: 1 1 calc(50% - 4px); min-width: 120px; justify-content: center; padding: 8px 10px; }
.card { padding: 0; overflow: visible; }
.doc-table { display: block; width: 100%; }
.doc-table thead { display: none; }
.doc-table tbody { display: block; width: 100%; }
.doc-table tr {
display: block; width: 100%; background: white; margin-bottom: 12px;
border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); padding: 12px;
box-sizing: border-box;
}
.doc-table td {
display: flex; width: 100%; justify-content: space-between; align-items: center;
border: none; padding: 6px 0; text-align: right; box-sizing: border-box;
}
.doc-table td::before {
content: attr(data-label); font-weight: 600; font-size: 11px;
color: #666; text-transform: uppercase; flex-shrink: 0; margin-right: 8px;
}
.doc-table td:last-child { justify-content: flex-end; margin-top: 8px; padding-top: 8px; border-top: 1px solid #eee; }
.doc-table td:last-child::before { display: none; }
.doc-actions { justify-content: flex-end; margin-top: 0; gap: 4px; }
.action-btn { padding: 6px 8px; font-size: 11px; }
.template-grid { grid-template-columns: 1fr; gap: 12px; }
.line-item-row { grid-template-columns: 1fr 50px 80px 28px; gap: 4px; }
.modal-box { width: 95%; max-width: 95%; margin: 0 auto; }
.toast { bottom: 12px; right: 12px; left: 12px; }
/* Document type badges */
.type-badge {
display: inline-block; padding: 2px 8px; border-radius: 4px;
font-size: 11px; font-weight: 600; text-transform: capitalize;
}
.type-invoice { background: #dbeafe; color: #1d4ed8; }
.type-quote { background: #fef3c7; color: #b45309; }
.type-proposal { background: #e0e7ff; color: #4338ca; }
.type-receipt { background: #d1fae5; color: #047857; }
.type-custom { background: #f3e8ff; color: #7c3aed; }
}
</style>
{% endblock %}
{% block content %}
<div class="page-header">
<div>
<h1>Documents</h1>
<p>All invoices, quotes, proposals, and documents across your sites.</p>
</div>
<div style="display:flex;gap:8px;flex-wrap:wrap;">
<button class="primary-btn" data-onclick="openGenerateModal()">+ New Document</button>
</div>
</div>
<!-- Tab bar -->
<div class="tab-bar">
<button class="tab-btn active" data-onclick="switchTab('documents', this)">Documents</button>
<button class="tab-btn" data-onclick="switchTab('templates', this)">Templates</button>
</div>
<!-- Documents tab -->
<div id="tab-documents">
<!-- Document type filter -->
<div class="status-bar" id="doc-type-filters">
<div class="status-chip active" onclick="filterByType(null, this)">
<span class="chip-count">{{ counts.get('total', 0) }}</span>
<span class="chip-label">All Types</span>
</div>
{% for dtype, dcnt in doc_type_counts %}
<div class="status-chip" onclick="filterByType('{{ dtype }}', this)">
<span class="chip-count">{{ dcnt }}</span>
<span class="chip-label">{{ dtype | capitalize }}</span>
</div>
{% endfor %}
</div>
<!-- Status filter bar -->
<div class="status-bar" id="status-filters">
<div class="status-chip active" data-onclick="filterDocs(null, this)">
<span class="chip-count">{{ counts.get('total', 0) }}</span>
<span class="chip-label">All</span>
</div>
<div class="status-chip" data-onclick="filterDocs('draft', this)">
<span class="chip-count">{{ counts.get('draft', 0) }}</span>
<span class="chip-label">Draft</span>
</div>
<div class="status-chip" data-onclick="filterDocs('sent', this)">
<span class="chip-count">{{ counts.get('sent', 0) }}</span>
<span class="chip-label">Sent</span>
</div>
<div class="status-chip" data-onclick="filterDocs('viewed', this)">
<span class="chip-count">{{ counts.get('viewed', 0) }}</span>
<span class="chip-label">Viewed</span>
</div>
<div class="status-chip" data-onclick="filterDocs('unpaid', this)">
<span class="chip-count">{{ counts.get('unpaid', 0) }}</span>
<span class="chip-label">Unpaid</span>
</div>
<div class="status-chip" data-onclick="filterDocs('paid', this)">
<span class="chip-count">{{ counts.get('paid', 0) }}</span>
<span class="chip-label">Paid</span>
</div>
<div class="status-chip" data-onclick="filterDocs('void', this)">
<span class="chip-count">{{ counts.get('void', 0) }}</span>
<span class="chip-label">Void</span>
</div>
</div>
{% if documents %}
<div class="card" style="padding:0;">
<table class="doc-table" id="doc-table">
<thead>
<tr>
<th>Document</th>
<th>Type</th>
<th>Site</th>
<th>Status</th>
<th>Due Date</th>
<th>Created</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for doc in documents %}
<tr data-status="{{ doc.status }}" data-type="{{ doc.document_type or 'invoice' }}">
<td data-label="Document">
{% if doc.is_overdue %}<span class="overdue-dot"></span>{% endif %}
<a href="/documents/{{ doc.document_id }}/preview" target="_blank" class="doc-link">
{{ doc.data.get('document_number', doc.invoice_number or doc.document_id[:8]) }}
</a>
<div style="font-size:12px;color:#888;margin-top:2px;">
{{ doc.data.get('customer_name', 'No customer') }}
</div>
</td>
<td data-label="Type">
<span class="type-badge type-{{ doc.document_type or 'invoice' }}">{{ doc.document_type or 'invoice' }}</span>
</td>
<td data-label="Site">
{% if doc.site_name %}
<span class="site-badge">{{ doc.site_name }}</span>
{% else %}
<span class="site-badge" style="background:var(--accent-dim);color:var(--accent);">Standalone</span>
{% endif %}
</td>
<td data-label="Status">
<span class="status-badge status-{{ doc.status }}">{{ doc.status }}</span>
</td>
<td data-label="Due Date">
{% if doc.due_date %}
{{ doc.due_date }}
{% if doc.is_overdue %}
<span style="color:#ef4444;font-size:11px;font-weight:600;"> OVERDUE</span>
{% endif %}
{% else %}
<span style="color:#bbb;">โ</span>
{% endif %}
</td>
<td data-label="Created">
{{ doc.created_at[:10] if doc.created_at else 'โ' }}
</td>
<td data-label="Actions">
<div class="doc-actions">
<button class="action-btn" title="Preview PDF" data-onclick="openPreview('{{ doc.document_id }}', '{{ doc.invoice_number or doc.document_id[:8] }}')">๐</button>
<a href="/documents/{{ doc.document_id }}/download" class="action-btn" title="Download PDF">โฌ</a>
{% if doc.status == 'unpaid' %}
<a href="/documents/{{ doc.document_id }}/pay" class="action-btn primary" title="Pay Invoice">Pay</a>
{% endif %}
{% if doc.customer_email %}
<button class="action-btn" title="Copy Portal Link" data-onclick="copyPortalLink('{{ doc.document_id }}', this)">๐</button>
<button class="action-btn" title="Send to Customer" data-onclick="sendInvoice('{{ doc.document_id }}', '{{ doc.customer_email }}', this)">๐ง</button>
{% endif %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="empty-state">
<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="#ccc" stroke-width="1.5">
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
<polyline points="14 2 14 8 20 8"/>
<line x1="16" y1="13" x2="8" y2="13"/>
<line x1="16" y1="17" x2="8" y2="17"/>
<polyline points="10 9 9 9 8 9"/>
</svg>
<p>No documents yet.</p>
<p style="font-size:13px;">Create an invoice, quote, or proposal directly, or set up a template for recurring documents.</p>
<div style="display:flex;gap:8px;justify-content:center;margin-top:16px;flex-wrap:wrap;">
<button class="primary-btn" data-onclick="openGenerateModal()">+ New Document</button>
</div>
</div>
{% endif %}
</div>
<!-- Templates tab -->
<div id="tab-templates" style="display:none;">
<div class="section-header">
<h2>Document Templates</h2>
<button class="primary-btn" data-onclick="openTemplateModal()">+ New Template</button>
</div>
<div id="template-grid" class="template-grid">
<!-- Loaded via JS -->
</div>
</div>
<!-- Generate Document Modal -->
<div id="generate-modal" class="modal-overlay">
<div class="modal-box">
<div class="modal-header">
<h3>Generate Document</h3>
<button class="modal-close" data-onclick="closeGenerateModal()">ร</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Document Type</label>
<select id="gen-doc-type" onchange="toggleDocFields()">
<optgroup label="Billing">
<option value="invoice" selected>Invoice</option>
<option value="quote">Quote</option>
<option value="receipt">Receipt</option>
<option value="statement">Statement</option>
</optgroup>
<optgroup label="Sales">
<option value="proposal">Proposal</option>
<option value="contract">Contract</option>
</optgroup>
<optgroup label="Operations">
<option value="work_order">Work Order</option>
<option value="delivery_note">Delivery Note</option>
</optgroup>
<optgroup label="Other">
<option value="certificate">Certificate</option>
<option value="report">Report</option>
<option value="custom">Custom</option>
</optgroup>
</select>
</div>
<div class="form-group">
<label>Template</label>
<select id="gen-template-select">
<option value="">Select a template...</option>
</select>
<div class="form-hint">Choose a template or generate a standalone document.</div>
</div>
<div class="form-group">
<label>Layout</label>
<select id="gen-layout">
<optgroup label="Dedicated">
<option value="proposal">Proposal</option>
<option value="statement">Statement</option>
<option value="work_order">Work Order</option>
<option value="delivery_note">Delivery Note</option>
<option value="contract">Contract</option>
</optgroup>
<optgroup label="Professional">
<option value="stripe" selected>Stripe</option>
<option value="hubspot">HubSpot</option>
<option value="notion">Notion</option>
<option value="customer_portal">Customer Portal</option>
</optgroup>
<optgroup label="Standard">
<option value="classic">Classic</option>
<option value="professional">Professional</option>
<option value="modern">Modern</option>
<option value="minimal">Minimal</option>
<option value="bold">Bold</option>
<option value="receipt">Receipt</option>
</optgroup>
</select>
<div class="form-hint">Choose the visual layout for this document.</div>
</div>
<div class="form-group">
<label>Primary Color <span style="color:#888;font-weight:normal;">(optional)</span></label>
<div style="display:flex;gap:8px;align-items:center;">
<input type="color" id="gen-primary-color" value="#0f172a" style="width:40px;height:36px;border:none;padding:2px;cursor:pointer;">
<span style="font-size:13px;color:#666;" id="color-preview">#0f172a</span>
</div>
</div>
<div class="form-group">
<label>Customer Name</label>
<input type="text" id="gen-customer-name" placeholder="Acme Corp">
</div>
<div class="form-group">
<label>Customer Email</label>
<input type="email" id="gen-customer-email" placeholder="billing@acme.com">
</div>
<div class="form-group">
<label>Client Address</label>
<input type="text" id="gen-customer_address" placeholder="456 Oak Ave, City, State ZIP">
</div>
<div style="margin: 20px 0 16px; border-top: 2px solid #f0f0f0;"></div>
<div style="display: flex; align-items: center; gap: 8px; margin-bottom: 16px;">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--accent)" stroke-width="2"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
<span style="font-size: 13px; font-weight: 600; color: var(--accent);">YOUR COMPANY</span>
</div>
<div class="form-group">
<label>Company Name</label>
<input type="text" id="gen-from-name" placeholder="Your Company LLC">
</div>
<div class="form-group">
<label>Company Email</label>
<input type="email" id="gen-from-email" placeholder="hello@yourcompany.com">
</div>
<div class="form-group">
<label>Company Address</label>
<input type="text" id="gen-from-address" placeholder="123 Main St, City, State ZIP">
</div>
<div class="form-group">
<label>Company Phone</label>
<input type="text" id="gen-from-phone" placeholder="(555) 123-4567">
</div>
<div style="margin: 20px 0 16px; border-top: 2px solid #f0f0f0;"></div>
<div data-field-group="invoice">
<div class="form-group">
<label>Due Date</label>
<input type="date" id="gen-due-date">
</div>
</div>
<div data-field-group="quote">
<div class="form-group">
<label>Valid Until</label>
<input type="date" id="gen-expiry-date">
</div>
</div>
<div data-field-group="proposal">
<div class="form-group">
<label>Valid Until</label>
<input type="date" id="gen-valid-until">
</div>
</div>
<div data-field-group="receipt">
<div class="form-group">
<label>Receipt Date</label>
<input type="date" id="gen-receipt-date">
</div>
</div>
<div data-field-group="line_items">
<div class="form-group">
<label>Line Items</label>
<div id="line-items-container">
<div class="line-item-row">
<input type="text" placeholder="Description" class="li-desc">
<input type="number" placeholder="Qty" value="1" min="1" class="li-qty" data-oninput="calcTotal()">
<input type="number" placeholder="Price" step="any" class="li-price" data-oninput="calcTotal()">
<button class="line-item-remove" data-onclick="removeLineItem(this)">ร</button>
</div>
</div>
<button class="action-btn" style="margin-top:8px;" data-onclick="addLineItem()">+ Add Item</button>
<div class="line-total">Total: $<span id="line-total">0.00</span></div>
</div>
</div>
<div data-field-group="invoice_quote">
<div class="form-group">
<label>Tax Rate (%)</label>
<input type="number" id="gen-tax-rate" placeholder="0" step="0.01" min="0" value="0">
</div>
</div>
<div data-field-group="invoice">
<div class="form-group">
<label>Payment Link <span style="color:#888;font-weight:normal;">(optional)</span></label>
<input type="url" id="gen-payment-link" placeholder="https://pay.example.com/...">
</div>
<div class="form-group">
<label>Payment Link Text</label>
<input type="text" id="gen-payment-link-text" value="Pay Now">
</div>
<div class="form-group">
<label>Payment Terms</label>
<input type="text" id="gen-payment-terms" placeholder="Net 30">
</div>
</div>
<div data-field-group="proposal">
<div class="form-group">
<label>Scope / Description</label>
<textarea id="gen-scope" rows="4" placeholder="Describe the scope of work, deliverables, timeline..."></textarea>
</div>
</div>
<div data-field-group="proposal receipt custom">
<div class="form-group">
<label>Notes</label>
<textarea id="gen-notes" rows="3" placeholder="Additional notes..."></textarea>
</div>
</div>
<!-- โโ Proposal fields โโ -->
<div data-field-group="proposal" style="display:none;">
<div class="form-group">
<label>Proposal Title</label>
<input type="text" id="gen-title" placeholder="e.g. Website Redesign Proposal">
</div>
<div class="form-group">
<label>Executive Summary</label>
<textarea id="gen-executive_summary" rows="2" placeholder="Brief overview"></textarea>
</div>
<div class="form-group">
<label>Timeline</label>
<input type="text" id="gen-timeline" placeholder="e.g. 4 weeks from kickoff">
</div>
<div class="form-group">
<label>Terms & Conditions</label>
<textarea id="gen-terms" rows="2" placeholder="Terms and conditions"></textarea>
</div>
</div>
<!-- โโ Statement fields โโ -->
<div data-field-group="statement" style="display:none;">
<div class="form-group">
<label>Opening Balance</label>
<input type="number" step="0.01" id="gen-opening_balance" placeholder="0.00">
</div>
<div class="form-group">
<label>Statement Period Start</label>
<input type="date" id="gen-period_start">
</div>
<div class="form-group">
<label>Statement Period End</label>
<input type="date" id="gen-period_end">
</div>
</div>
<!-- โโ Work Order fields โโ -->
<div data-field-group="work_order" style="display:none;">
<div class="form-group">
<label>Work Order Number</label>
<input type="text" id="gen-work_order_number" placeholder="e.g. WO-2026-001">
</div>
<div class="form-group">
<label>Service Address</label>
<input type="text" id="gen-service_address" placeholder="Full service address">
</div>
<div class="form-group">
<label>Scheduled Date</label>
<input type="date" id="gen-scheduled_date">
</div>
</div>
<!-- โโ Delivery Note fields โโ -->
<div data-field-group="delivery_note" style="display:none;">
<div class="form-group">
<label>PO Number</label>
<input type="text" id="gen-po_number" placeholder="e.g. PO-2026-0847">
</div>
<div class="form-group">
<label>Order Number</label>
<input type="text" id="gen-order_number" placeholder="e.g. ORD-9921">
</div>
<div class="form-group">
<label>Carrier</label>
<input type="text" id="gen-carrier" placeholder="e.g. FedEx Ground">
</div>
<div class="form-group">
<label>Tracking Number</label>
<input type="text" id="gen-tracking_number" placeholder="Tracking number">
</div>
<div class="form-group">
<label>Weight</label>
<input type="text" id="gen-weight" placeholder="e.g. 45 lbs">
</div>
</div>
<!-- โโ Contract fields โโ -->
<div data-field-group="contract" style="display:none;">
<div class="form-group">
<label>Contract Title</label>
<input type="text" id="gen-contract_title" placeholder="e.g. Master Service Agreement">
</div>
<div class="form-group">
<label>Effective Date</label>
<input type="date" id="gen-effective_date">
</div>
<div class="form-group">
<label>Preamble</label>
<textarea id="gen-preamble" rows="3" placeholder="Opening paragraph"></textarea>
</div>
<div class="form-group">
<label>Terms & Clauses</label>
<textarea id="gen-terms_sections" rows="5" placeholder="One clause per line, e.g.: 1. Scope of Services 2. Payment Terms - Net 30 3. Confidentiality"></textarea>
</div>
</div>
<div id="gen-error" style="color:#dc3545;font-size:13px;display:none;margin-top:8px;"></div>
</div>
<div class="modal-footer">
<button class="action-btn" data-onclick="closeGenerateModal()">Cancel</button>
<button class="primary-btn" data-onclick="generateInvoice()">Generate</button>
</div>
</div>
</div>
<!-- Proposal specific fields -->
<div id="proposal-fields" style="display:none;">
<div class="form-group">
<label>Proposal Title</label>
<input type="text" id="proposal-title" placeholder="e.g. Website Redesign Proposal">
</div>
<div class="form-group">
<label>Executive Summary</label>
<textarea id="proposal-executive_summary" rows="2" placeholder="Brief overview of the proposal"></textarea>
</div>
<div class="form-group">
<label>Timeline</label>
<input type="text" id="proposal-timeline" placeholder="e.g. 4 weeks from kickoff">
</div>
<div class="form-group">
<label>Terms & Conditions</label>
<textarea id="proposal-terms" rows="2" placeholder="Proposal terms and conditions"></textarea>
</div>
</div>
<!-- Statement specific fields -->
<div id="statement-fields" style="display:none;">
<div class="form-group">
<label>Opening Balance</label>
<input type="number" step="0.01" id="statement-opening_balance" placeholder="0.00">
</div>
<div class="form-group">
<label>Statement Period Start</label>
<input type="date" id="statement-period_start">
</div>
<div class="form-group">
<label>Statement Period End</label>
<input type="date" id="statement-period_end">
</div>
</div>
<!-- Work Order specific fields -->
<div id="work_order-fields" style="display:none;">
<div class="form-group">
<label>Work Order Number</label>
<input type="text" id="work_order-work_order_number" placeholder="e.g. WO-2026-001">
</div>
<div class="form-group">
<label>Service Address</label>
<input type="text" id="work_order-service_address" placeholder="Full service address">
</div>
<div class="form-group">
<label>Scheduled Date</label>
<input type="date" id="work_order-scheduled_date">
</div>
</div>
<!-- Delivery Note specific fields -->
<div id="delivery_note-fields" style="display:none;">
<div class="form-group">
<label>PO Number</label>
<input type="text" id="delivery_note-po_number" placeholder="e.g. PO-2026-0847">
</div>
<div class="form-group">
<label>Order Number</label>
<input type="text" id="delivery_note-order_number" placeholder="e.g. ORD-9921">
</div>
<div class="form-group">
<label>Carrier</label>
<input type="text" id="delivery_note-carrier" placeholder="e.g. FedEx Ground">
</div>
<div class="form-group">
<label>Tracking Number</label>
<input type="text" id="delivery_note-tracking_number" placeholder="Tracking number">
</div>
<div class="form-group">
<label>Weight</label>
<input type="text" id="delivery_note-weight" placeholder="e.g. 45 lbs">
</div>
</div>
<!-- Contract specific fields -->
<div id="contract-fields" style="display:none;">
<div class="form-group">
<label>Contract Title</label>
<input type="text" id="contract-contract_title" placeholder="e.g. Master Service Agreement">
</div>
<div class="form-group">
<label>Effective Date</label>
<input type="date" id="contract-effective_date">
</div>
<div class="form-group">
<label>Preamble</label>
<textarea id="contract-preamble" rows="3" placeholder="Opening paragraph of the agreement"></textarea>
</div>
<div class="form-group">
<label>Terms & Clauses</label>
<textarea id="contract-terms_sections" rows="5" placeholder="One clause per line, e.g.: 1. Scope of Services 2. Payment Terms - Net 30 3. Confidentiality"></textarea>
</div>
</div>
<!-- Create Template Modal -->
<div id="template-modal" class="modal-overlay">
<div class="modal-box">
<div class="modal-header">
<h3>Create Template</h3>
<button class="modal-close" data-onclick="closeTemplateModal()">ร</button>
</div>
<div class="modal-body">
<div class="form-group">
<label>Template Name</label>
<input type="text" id="tpl-name" placeholder="Standard Invoice">
</div>
<div class="form-group">
<label>Document Type</label>
<select id="tpl-doc-type">
<optgroup label="Billing">
<option value="invoice">Invoice</option>
<option value="quote">Quote</option>
<option value="receipt">Receipt</option>
<option value="statement">Statement</option>
</optgroup>
<optgroup label="Sales">
<option value="proposal">Proposal</option>
<option value="contract">Contract</option>
</optgroup>
<optgroup label="Operations">
<option value="work_order">Work Order</option>
<option value="delivery_note">Delivery Note</option>
</optgroup>
<optgroup label="Other">
<option value="certificate">Certificate</option>
<option value="report">Report</option>
<option value="custom">Custom</option>
</optgroup>
</select>
</div>
<div class="form-group">
<label>Layout</label>
<select id="tpl-layout">
<optgroup label="Dedicated">
<option value="proposal">Proposal</option>
<option value="statement">Statement</option>
<option value="work_order">Work Order</option>
<option value="delivery_note">Delivery Note</option>
<option value="contract">Contract</option>
</optgroup>
<optgroup label="Professional">
<option value="stripe">Stripe</option>
<option value="hubspot">HubSpot</option>
<option value="notion">Notion</option>
<option value="customer_portal">Customer Portal</option>
</optgroup>
<optgroup label="Standard">
<option value="classic">Classic</option>
<option value="professional">Professional</option>
<option value="modern">Modern</option>
<option value="minimal">Minimal</option>
<option value="bold">Bold</option>
<option value="receipt">Receipt</option>
</optgroup>
</select>
</div>
<div class="form-group">
<label>Invoice Number Format <span style="color:#888;font-weight:normal;">(optional)</span></label>
<input type="text" id="tpl-inv-format" value="INV-YYYY-####" placeholder="Auto-generated if empty">
<div class="form-hint">Default: INV-YYYY-####. Uses YYYY for year and #### for sequential number. Leave as-is for auto-generated numbers like INV-2026-0001.</div>
</div>
<div id="tpl-error" style="color:#dc3545;font-size:13px;display:none;margin-top:8px;"></div>
</div>
<div class="modal-footer">
<button class="action-btn" data-onclick="closeTemplateModal()">Cancel</button>
<button class="primary-btn" data-onclick="createTemplate()">Create Template</button>
</div>
</div>
</div>
<!-- PDF Preview Modal -->
<div id="preview-modal" class="preview-overlay">
<div class="preview-toolbar">
<h3 id="preview-title">Document Preview</h3>
<div class="preview-actions">
<button id="preview-print" data-onclick="printPreview()" title="Print document">๐จ Print</button>
<a id="preview-fullscreen" href="#" target="_blank" title="Open in new tab for print/email">โคข Full Screen</a>
<a id="preview-download" href="#" class="primary" target="_blank">โฌ Download</a>
<button data-onclick="closePreview()">โ Close</button>
</div>
</div>
<div class="preview-iframe-wrap">
<iframe id="preview-iframe" src=""></iframe>
</div>
</div>
<!-- Toast -->
<div id="toast" class="toast"></div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script src="/static/js/documents-dashboard-inline.js"></script>
{% endblock %}