Files
delphi-database/templates/documents.html
2025-08-11 10:26:41 -05:00

1215 lines
64 KiB
HTML

{% extends "base.html" %}
{% block title %}Document Management - Delphi Database{% endblock %}
{% block content %}
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-6">
<div class="space-y-6">
<!-- Page Header -->
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
<div class="flex items-center gap-3">
<div class="flex items-center justify-center w-10 h-10 bg-primary-100 dark:bg-primary-900/30 text-primary-600 dark:text-primary-400 rounded-xl">
<i class="fa-regular fa-file-lines text-lg"></i>
</div>
<h1 class="text-2xl font-bold text-neutral-900 dark:text-neutral-100">Document Management</h1>
</div>
<div class="flex items-center gap-3">
<button id="newTemplateBtn" class="flex items-center gap-2 px-4 py-2 bg-success-600 text-white hover:bg-success-700 rounded-lg transition-colors duration-200">
<i class="fa-solid fa-circle-plus"></i>
<span>New Template</span>
<kbd class="hidden sm:inline-block ml-2 px-1.5 py-0.5 bg-success-700 rounded text-xs">Ctrl+N</kbd>
</button>
<button id="generateDocBtn" class="flex items-center gap-2 px-4 py-2 bg-primary-600 text-white hover:bg-primary-700 rounded-lg transition-colors duration-200">
<i class="fa-regular fa-file-lines"></i>
<span>Generate Document</span>
</button>
<button id="newQdroBtn" class="flex items-center gap-2 px-4 py-2 bg-warning-600 text-white hover:bg-warning-700 rounded-lg transition-colors duration-200">
<i class="fa-regular fa-file-lines"></i>
<span>New QDRO</span>
</button>
<button id="statsBtn" class="flex items-center gap-2 px-4 py-2 bg-info-600 text-white hover:bg-info-700 rounded-lg transition-colors duration-200">
<i class="fa-solid fa-chart-line"></i>
<span>Statistics</span>
</button>
</div>
</div>
<!-- Document Management Tabs -->
<div class="bg-white dark:bg-neutral-800 rounded-lg shadow-md overflow-hidden">
<nav class="flex border-b border-neutral-200 dark:border-neutral-700">
<button class="flex-1 py-4 px-6 text-center border-b-2 border-transparent hover:border-blue-500 hover:text-blue-500 dark:hover:text-blue-400 transition duration-300" onclick="openTab(event, 'templates')" id="templates-tab">
<i class="fa-regular fa-file-lines mr-2"></i> Templates
</button>
<button class="flex-1 py-4 px-6 text-center border-b-2 border-transparent hover:border-blue-500 hover:text-blue-500 dark:hover:text-blue-400 transition duration-300" onclick="openTab(event, 'qdros')" id="qdros-tab">
<i class="fa-regular fa-file-lines mr-2"></i> QDROs
</button>
<button class="flex-1 py-4 px-6 text-center border-b-2 border-transparent hover:border-blue-500 hover:text-blue-500 dark:hover:text-blue-400 transition duration-300" onclick="openTab(event, 'generated')" id="generated-tab">
<i class="fa-regular fa-file-pdf mr-2"></i> Generated Documents
</button>
</nav>
<div id="templates" class="tabcontent p-6">
<div class="mt-3 bg-white dark:bg-neutral-800 rounded-xl shadow-soft border border-neutral-200 dark:border-neutral-700">
<div class="px-6 py-4 border-b border-neutral-200 dark:border-neutral-700">
<div class="grid grid-cols-1 md:grid-cols-3 gap-3 items-center">
<div class="md:col-span-2">
<h5 class="mb-0 font-semibold flex items-center gap-2"><i class="fa-regular fa-file-lines"></i> Document Templates</h5>
</div>
<div class="md:col-span-1">
<div class="flex gap-2">
<input type="text" class="w-full px-3 py-2 bg-white dark:bg-neutral-800 border border-neutral-300 dark:border-neutral-600 rounded-lg text-neutral-900 dark:text-neutral-100 placeholder-neutral-400 dark:placeholder-neutral-500 transition-all duration-200" id="templateSearch" placeholder="Search templates...">
<select class="px-3 py-2 bg-white dark:bg-neutral-800 border border-neutral-300 dark:border-neutral-600 rounded-lg text-neutral-900 dark:text-neutral-100 transition-all duration-200" id="categoryFilter">
<option value="">All Categories</option>
</select>
<button class="px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg hover:bg-neutral-100 dark:hover:bg-neutral-700" id="refreshTemplatesBtn"><i class="fa-solid fa-rotate-right"></i></button>
</div>
</div>
</div>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="w-full text-sm text-left border border-neutral-200 dark:border-neutral-700 rounded-lg overflow-hidden" id="templatesTable">
<thead>
<tr>
<th>Template ID</th>
<th>Name</th>
<th>Category</th>
<th>Variables</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="templatesTableBody">
<!-- Templates will be loaded here -->
</tbody>
</table>
</div>
</div>
</div>
</div>
<div id="qdros" class="tabcontent p-6 hidden">
<div class="mt-3 bg-white dark:bg-neutral-800 rounded-xl shadow-soft border border-neutral-200 dark:border-neutral-700">
<div class="px-6 py-4 border-b border-neutral-200 dark:border-neutral-700">
<div class="grid grid-cols-1 md:grid-cols-2 gap-3 items-center">
<div><h5 class="mb-0 font-semibold"><i class="fa-regular fa-file-lines"></i> QDRO Documents</h5></div>
<div>
<div class="flex gap-2">
<input type="text" class="w-full px-3 py-2 bg-white dark:bg-neutral-800 border border-neutral-300 dark:border-neutral-600 rounded-lg text-neutral-900 dark:text-neutral-100 placeholder-neutral-400 dark:placeholder-neutral-500 transition-all duration-200" id="qdroSearch" placeholder="Search QDROs...">
<select class="px-3 py-2 bg-white dark:bg-neutral-800 border border-neutral-300 dark:border-neutral-600 rounded-lg text-neutral-900 dark:text-neutral-100 transition-all duration-200" id="qdroStatusFilter">
<option value="">All Status</option>
<option value="DRAFT">Draft</option>
<option value="APPROVED">Approved</option>
<option value="FILED">Filed</option>
</select>
<button class="px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg hover:bg-neutral-100 dark:hover:bg-neutral-700" id="refreshQdrosBtn"><i class="fa-solid fa-rotate-right"></i></button>
</div>
</div>
</div>
</div>
<div class="p-6">
<div class="overflow-x-auto">
<table class="w-full text-sm text-left border border-neutral-200 dark:border-neutral-700 rounded-lg overflow-hidden" id="qdrosTable">
<thead>
<tr>
<th>File #</th>
<th>Version</th>
<th>Participant</th>
<th>Spouse</th>
<th>Plan Name</th>
<th>Status</th>
<th>Created</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="qdrosTableBody">
<!-- QDROs will be loaded here -->
</tbody>
</table>
</div>
</div>
</div>
</div>
<div id="generated" class="tabcontent p-6 hidden">
<div class="mt-3 bg-white dark:bg-neutral-800 rounded-xl shadow-soft border border-neutral-200 dark:border-neutral-700">
<div class="px-6 py-4 border-b border-neutral-200 dark:border-neutral-700"><h5 class="mb-0 font-semibold"><i class="fa-regular fa-file-pdf"></i> Generated Documents</h5></div>
<div class="p-6"><div id="generatedDocuments"><p class="text-neutral-500">Generated documents will appear here...</p></div></div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Template Editor Modal -->
<div class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4" id="templateModal">
<div class="bg-white dark:bg-neutral-800 rounded-xl shadow-xl max-w-5xl w-full max-h-[90vh] overflow-y-auto">
<div class="flex items-center justify-between px-6 py-4 border-b border-neutral-200 dark:border-neutral-700">
<h5 class="text-lg font-semibold" id="templateModalLabel">Template Editor</h5>
<button type="button" class="text-neutral-400 hover:text-neutral-600 dark:text-neutral-500 dark:hover:text-neutral-300" onclick="closeModal('templateModal')"><i class="fa-solid fa-xmark"></i></button>
</div>
<div class="px-6 py-4">
<form id="templateForm">
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
<div class="md:col-span-1">
<label for="templateId" class="block text-sm font-medium mb-1">Template ID *</label>
<input type="text" class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="templateId" name="form_id" required>
</div>
<div class="md:col-span-1">
<label for="templateName" class="block text-sm font-medium mb-1">Template Name *</label>
<input type="text" class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="templateName" name="form_name" required>
</div>
<div class="md:col-span-2">
<label for="templateCategory" class="block text-sm font-medium mb-1">Category</label>
<select class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="templateCategory" name="category">
<option value="GENERAL">General</option>
<option value="LETTERS">Letters</option>
<option value="CONTRACTS">Contracts</option>
<option value="PLEADINGS">Pleadings</option>
<option value="FORMS">Forms</option>
<option value="NOTICES">Notices</option>
</select>
</div>
<div class="md:col-span-2">
<label for="templateContent" class="block text-sm font-medium mb-1">Template Content</label>
<div class="mb-2">
<small class="text-neutral-500">
Use {{VARIABLE_NAME}} or ^VARIABLE for merge fields. Available variables: FILE_NO, CLIENT_FIRST, CLIENT_LAST, CLIENT_FULL, MATTER, OPENED, ATTORNEY, TODAY
</small>
</div>
<textarea class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="templateContent" name="content" rows="15"
placeholder="Enter your template content here. Use {{CLIENT_FULL}} for client name, {{FILE_NO}} for file number, etc."></textarea>
</div>
<div class="md:col-span-2">
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
<div>
<button type="button" class="px-3 py-1.5 border border-neutral-300 dark:border-neutral-600 rounded text-sm hover:bg-neutral-100 dark:hover:bg-neutral-700" id="insertVariableBtn">
<i class="fa-solid fa-plus"></i> Insert Variable
</button>
<button type="button" class="px-3 py-1.5 border border-info-600 text-info-700 dark:text-info-300 rounded text-sm hover:bg-info-50 dark:hover:bg-info-900/20" id="previewTemplateBtn">
<i class="fa-regular fa-eye"></i> Preview
</button>
</div>
<div class="text-right">
<div id="variableCount" class="text-neutral-500 text-sm">Variables detected: 0</div>
</div>
</div>
</div>
</div>
</form>
</div>
<div class="flex items-center justify-end gap-2 px-6 py-4 border-t border-neutral-200 dark:border-neutral-700">
<button type="button" class="px-4 py-2 bg-neutral-100 dark:bg-neutral-700 text-neutral-700 dark:text-neutral-300 hover:bg-neutral-200 dark:hover:bg-neutral-600 rounded-lg" onclick="closeModal('templateModal')">Cancel</button>
<button type="button" class="px-4 py-2 bg-primary-600 text-white hover:bg-primary-700 rounded-lg" id="saveTemplateBtn"><i class="fa-regular fa-circle-check"></i> Save Template</button>
</div>
</div>
</div>
<!-- Document Generation Modal -->
<div class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4" id="generateModal">
<div class="bg-white dark:bg-neutral-800 rounded-xl shadow-xl max-w-4xl w-full max-h-[90vh] overflow-y-auto">
<div class="flex items-center justify-between px-6 py-4 border-b border-neutral-200 dark:border-neutral-700">
<h5 class="text-lg font-semibold" id="generateModalLabel">Generate Document</h5>
<button type="button" class="text-neutral-400 hover:text-neutral-600 dark:text-neutral-500 dark:hover:text-neutral-300" onclick="closeModal('generateModal')"><i class="fa-solid fa-xmark"></i></button>
</div>
<div class="px-6 py-4">
<form id="generateForm">
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
<div>
<label for="generateTemplate" class="block text-sm font-medium mb-1">Select Template *</label>
<select class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="generateTemplate" name="template_id" required>
<option value="">Choose template...</option>
</select>
</div>
<div>
<label for="generateFile" class="block text-sm font-medium mb-1">File Number *</label>
<div class="flex gap-2">
<input type="text" class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="generateFile" name="file_no" required>
<button class="px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg hover:bg-neutral-100 dark:hover:bg-neutral-700" type="button" id="selectGenerateFileBtn">
<i class="fa-solid fa-magnifying-glass"></i>
</button>
</div>
<div class="text-sm text-neutral-500" id="generateFileInfo">Enter file number or browse to select</div>
</div>
<div>
<label for="outputFormat" class="block text-sm font-medium mb-1">Output Format</label>
<select class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="outputFormat" name="output_format">
<option value="PDF">PDF</option>
<option value="DOCX">Word Document</option>
<option value="HTML">HTML</option>
</select>
</div>
<div>
<div class="mt-6 flex items-center gap-2">
<input class="h-4 w-4 text-primary-600 focus:ring-primary-500 border-neutral-300 rounded" type="checkbox" id="useCustomVars">
<label class="text-sm" for="useCustomVars">
Use custom variables
</label>
</div>
</div>
<div class="md:col-span-2" id="customVariablesSection" style="display: none;">
<label class="block text-sm font-medium mb-1">Custom Variables</label>
<div id="customVariables">
<!-- Custom variables will be added here -->
</div>
<button type="button" class="mt-2 px-3 py-1.5 border border-neutral-300 dark:border-neutral-600 rounded text-sm hover:bg-neutral-100 dark:hover:bg-neutral-700" id="addVariableBtn">
<i class="fa-solid fa-plus"></i> Add Variable
</button>
</div>
<div class="md:col-span-2">
<label for="templatePreview" class="block text-sm font-medium mb-1">Template Preview</label>
<textarea class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="templatePreview" readonly rows="8" placeholder="Select a template to see preview..."></textarea>
</div>
</div>
</form>
</div>
<div class="flex items-center justify-end gap-2 px-6 py-4 border-t border-neutral-200 dark:border-neutral-700">
<button type="button" class="px-4 py-2 bg-neutral-100 dark:bg-neutral-700 text-neutral-700 dark:text-neutral-300 hover:bg-neutral-200 dark:hover:bg-neutral-600 rounded-lg" onclick="closeModal('generateModal')">Cancel</button>
<button type="button" class="px-4 py-2 bg-primary-600 text-white hover:bg-primary-700 rounded-lg" id="generateDocumentBtn"><i class="fa-regular fa-file-lines"></i> Generate Document</button>
</div>
</div>
</div>
<!-- QDRO Modal -->
<div class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4" id="qdroModal">
<div class="bg-white dark:bg-neutral-800 rounded-xl shadow-xl max-w-6xl w-full">
<div class="flex items-center justify-between px-6 py-4 border-b border-neutral-200 dark:border-neutral-700">
<h5 class="text-lg font-semibold" id="qdroModalLabel">QDRO Editor</h5>
<button type="button" class="text-neutral-400 hover:text-neutral-600 dark:text-neutral-500 dark:hover:text-neutral-300" onclick="closeModal('qdroModal')"><i class="fa-solid fa-xmark"></i></button>
</div>
<div class="px-6 py-4">
<form id="qdroForm">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label for="qdroFileNo" class="block text-sm font-medium mb-1">File Number *</label>
<div class="flex gap-2">
<input type="text" class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="qdroFileNo" name="file_no" required>
<button class="px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg hover:bg-neutral-100 dark:hover:bg-neutral-700" type="button" id="selectQdroFileBtn"><i class="fa-solid fa-magnifying-glass"></i></button>
</div>
</div>
<div>
<label for="qdroVersion" class="block text-sm font-medium mb-1">Version</label>
<input type="text" class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="qdroVersion" name="version" value="01">
</div>
<div>
<label for="qdroStatus" class="block text-sm font-medium mb-1">Status</label>
<select class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="qdroStatus" name="status">
<option value="DRAFT">Draft</option>
<option value="APPROVED">Approved</option>
<option value="FILED">Filed</option>
</select>
</div>
<div>
<label for="qdroParticipant" class="block text-sm font-medium mb-1">Participant Name</label>
<input type="text" class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="qdroParticipant" name="participant_name">
</div>
<div>
<label for="qdroSpouse" class="block text-sm font-medium mb-1">Spouse Name</label>
<input type="text" class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="qdroSpouse" name="spouse_name">
</div>
<div>
<label for="qdroPlanName" class="block text-sm font-medium mb-1">Plan Name</label>
<input type="text" class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="qdroPlanName" name="plan_name">
</div>
<div>
<label for="qdroPlanAdmin" class="block text-sm font-medium mb-1">Plan Administrator</label>
<input type="text" class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="qdroPlanAdmin" name="plan_administrator">
</div>
<div>
<label for="qdroCreated" class="block text-sm font-medium mb-1">Created Date</label>
<input type="date" class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="qdroCreated" name="created_date">
</div>
<div>
<label for="qdroApproved" class="block text-sm font-medium mb-1">Approved Date</label>
<input type="date" class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="qdroApproved" name="approved_date">
</div>
<div>
<label for="qdroFiled" class="block text-sm font-medium mb-1">Filed Date</label>
<input type="date" class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="qdroFiled" name="filed_date">
</div>
<div class="md:col-span-2">
<label for="qdroTitle" class="block text-sm font-medium mb-1">QDRO Title</label>
<input type="text" class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="qdroTitle" name="title" placeholder="Enter QDRO title">
</div>
<div class="md:col-span-2">
<label for="qdroContent" class="block text-sm font-medium mb-1">QDRO Content</label>
<textarea class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="qdroContent" name="content" rows="10" placeholder="Enter QDRO content or generate from template..."></textarea>
</div>
<div class="md:col-span-2">
<label for="qdroNotes" class="block text-sm font-medium mb-1">Notes</label>
<textarea class="w-full px-3 py-2 border border-neutral-300 dark:border-neutral-600 rounded-lg" id="qdroNotes" name="notes" rows="3" placeholder="Additional notes..."></textarea>
</div>
</div>
</form>
</div>
<div class="flex items-center justify-end gap-2 px-6 py-4 border-t border-neutral-200 dark:border-neutral-700">
<button type="button" class="px-4 py-2 bg-neutral-100 dark:bg-neutral-700 text-neutral-700 dark:text-neutral-300 hover:bg-neutral-200 dark:hover:bg-neutral-600 rounded-lg" onclick="closeModal('qdroModal')">Cancel</button>
<button type="button" class="px-4 py-2 bg-warning-600 text-white hover:bg-warning-700 rounded-lg" id="generateFromTemplateBtn"><i class="fa-regular fa-file-lines"></i> Generate from Template</button>
<button type="button" class="px-4 py-2 bg-primary-600 text-white hover:bg-primary-700 rounded-lg" id="saveQdroBtn"><i class="fa-regular fa-circle-check"></i> Save QDRO</button>
</div>
</div>
</div>
<!-- Statistics Modal -->
<div class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4" id="statsModal">
<div class="bg-white dark:bg-neutral-800 rounded-xl shadow-xl max-w-3xl w-full max-h-[85vh] overflow-y-auto">
<div class="flex items-center justify-between px-6 py-4 border-b border-neutral-200 dark:border-neutral-700">
<h5 class="text-lg font-semibold" id="statsModalLabel">Document Statistics</h5>
<button type="button" class="text-neutral-400 hover:text-neutral-600 dark:text-neutral-500 dark:hover:text-neutral-300" onclick="closeModal('statsModal')"><i class="fa-solid fa-xmark"></i></button>
</div>
<div class="px-6 py-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
<div>
<div class="rounded-lg shadow-soft bg-primary-600 text-white p-4 text-center">
<div class="text-3xl font-semibold" id="totalTemplatesCount">0</div>
<div class="text-sm opacity-90">Total Templates</div>
</div>
</div>
<div>
<div class="rounded-lg shadow-soft bg-success-600 text-white p-4 text-center">
<div class="text-3xl font-semibold" id="totalQdrosCount">0</div>
<div class="text-sm opacity-90">Total QDROs</div>
</div>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-3 mt-3">
<div>
<div class="bg-white dark:bg-neutral-800 rounded-lg shadow-soft border border-neutral-200 dark:border-neutral-700">
<div class="px-4 py-2 border-b border-neutral-200 dark:border-neutral-700">
<h6 class="font-semibold">Templates by Category</h6>
</div>
<div class="p-4">
<div id="categoriesBreakdown">
<!-- Categories will be loaded here -->
</div>
</div>
</div>
</div>
<div>
<div class="bg-white dark:bg-neutral-800 rounded-lg shadow-soft border border-neutral-200 dark:border-neutral-700">
<div class="px-4 py-2 border-b border-neutral-200 dark:border-neutral-700">
<h6 class="font-semibold">Recent Activity</h6>
</div>
<div class="p-4">
<div id="recentActivity">
<!-- Recent activity will be loaded here -->
</div>
</div>
</div>
</div>
</div>
</div>
<div class="flex items-center justify-end gap-2 px-6 py-4 border-t border-neutral-200 dark:border-neutral-700">
<button type="button" class="px-4 py-2 bg-neutral-100 dark:bg-neutral-700 text-neutral-700 dark:text-neutral-300 hover:bg-neutral-200 dark:hover:bg-neutral-600 rounded-lg" onclick="closeModal('statsModal')">Close</button>
</div>
</div>
</div>
<!-- Variable Selector Modal -->
<div class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4" id="variableModal">
<div class="bg-white dark:bg-neutral-800 rounded-xl shadow-xl max-w-lg w-full max-h-[80vh] overflow-y-auto">
<div class="flex items-center justify-between px-6 py-4 border-b border-neutral-200 dark:border-neutral-700">
<h5 class="text-lg font-semibold" id="variableModalLabel">Insert Variable</h5>
<button type="button" class="text-neutral-400 hover:text-neutral-600 dark:text-neutral-500 dark:hover:text-neutral-300" onclick="closeModal('variableModal')"><i class="fa-solid fa-xmark"></i></button>
</div>
<div class="px-6 py-4">
<div class="grid grid-cols-1 gap-2">
<button type="button" class="px-3 py-2 text-left border rounded hover:bg-neutral-50 dark:hover:bg-neutral-700 variable-item" data-var="FILE_NO"><strong>{{FILE_NO}}</strong> - File Number</button>
<button type="button" class="px-3 py-2 text-left border rounded hover:bg-neutral-50 dark:hover:bg-neutral-700 variable-item" data-var="CLIENT_FULL"><strong>{{CLIENT_FULL}}</strong> - Full Client Name</button>
<button type="button" class="px-3 py-2 text-left border rounded hover:bg-neutral-50 dark:hover:bg-neutral-700 variable-item" data-var="CLIENT_FIRST"><strong>{{CLIENT_FIRST}}</strong> - Client First Name</button>
<button type="button" class="px-3 py-2 text-left border rounded hover:bg-neutral-50 dark:hover:bg-neutral-700 variable-item" data-var="CLIENT_LAST"><strong>{{CLIENT_LAST}}</strong> - Client Last Name</button>
<button type="button" class="px-3 py-2 text-left border rounded hover:bg-neutral-50 dark:hover:bg-neutral-700 variable-item" data-var="MATTER"><strong>{{MATTER}}</strong> - Matter Description</button>
<button type="button" class="px-3 py-2 text-left border rounded hover:bg-neutral-50 dark:hover:bg-neutral-700 variable-item" data-var="OPENED"><strong>{{OPENED}}</strong> - Date File Opened</button>
<button type="button" class="px-3 py-2 text-left border rounded hover:bg-neutral-50 dark:hover:bg-neutral-700 variable-item" data-var="ATTORNEY"><strong>{{ATTORNEY}}</strong> - Attorney/Employee</button>
<button type="button" class="px-3 py-2 text-left border rounded hover:bg-neutral-50 dark:hover:bg-neutral-700 variable-item" data-var="TODAY"><strong>{{TODAY}}</strong> - Today's Date</button>
</div>
</div>
<div class="flex items-center justify-end gap-2 px-6 py-4 border-t border-neutral-200 dark:border-neutral-700">
<button type="button" class="px-4 py-2 bg-neutral-100 dark:bg-neutral-700 text-neutral-700 dark:text-neutral-300 hover:bg-neutral-200 dark:hover:bg-neutral-600 rounded-lg" onclick="closeModal('variableModal')">Cancel</button>
</div>
</div>
</div>
<script>
// Document Management JavaScript
document.addEventListener('DOMContentLoaded', function() {
// Check authentication first
const token = localStorage.getItem('auth_token');
if (!token) {
window.location.href = '/login';
return;
}
// Wait for API helpers to be ready, then initialize
function initializeDocuments() {
if (typeof apiGet === 'function') {
// Ensure API headers are set up with token
if (window.apiHeaders && token) {
window.apiHeaders['Authorization'] = `Bearer ${token}`;
}
// Initialize the first tab as active
document.getElementById('templates-tab').click();
// Load initial data
loadCategories();
// Set up keyboard shortcuts
setupKeyboardShortcuts();
// Set up event handlers
setupEventHandlers();
// Auto-refresh every 30 seconds
setInterval(function() {
const templatesTab = document.querySelector('#templates-tab');
const qdrosTab = document.querySelector('#qdros-tab');
if (templatesTab.classList.contains('text-blue-500')) {
loadTemplates();
} else if (qdrosTab.classList.contains('text-blue-500')) {
loadQdros();
}
}, 30000);
} else {
// API helpers not ready yet, try again in 100ms
setTimeout(initializeDocuments, 100);
}
}
initializeDocuments();
});
function setupKeyboardShortcuts() {
document.addEventListener('keydown', function(e) {
// Ctrl+N for new template
if (e.ctrlKey && e.key === 'n') {
e.preventDefault();
document.getElementById('newTemplateBtn').click();
}
// Ctrl+G for generate document
if (e.ctrlKey && e.key === 'g') {
e.preventDefault();
document.getElementById('generateDocBtn').click();
}
});
}
function setupEventHandlers() {
// New template button
document.getElementById('newTemplateBtn').addEventListener('click', function() {
openTemplateModal();
});
// Generate document button
document.getElementById('generateDocBtn').addEventListener('click', function() {
openGenerateModal();
});
// New QDRO button
document.getElementById('newQdroBtn').addEventListener('click', function() {
openQdroModal();
});
// Statistics button
document.getElementById('statsBtn').addEventListener('click', function() {
loadDocumentStats();
});
// Save template button
document.getElementById('saveTemplateBtn').addEventListener('click', function() {
saveTemplate();
});
// Save QDRO button
document.getElementById('saveQdroBtn').addEventListener('click', function() {
saveQdro();
});
// Generate document button
document.getElementById('generateDocumentBtn').addEventListener('click', function() {
generateDocument();
});
// Insert variable button
document.getElementById('insertVariableBtn').addEventListener('click', function() {
openModal('variableModal');
});
// Variable selector
document.querySelectorAll('.variable-item').forEach(item => {
item.addEventListener('click', function() {
const varName = this.dataset.var;
const textarea = document.getElementById('templateContent');
const cursorPos = textarea.selectionStart;
const textBefore = textarea.value.substring(0, cursorPos);
const textAfter = textarea.value.substring(textarea.selectionEnd, textarea.value.length);
textarea.value = textBefore + '{{' + varName + '}}' + textAfter;
textarea.focus();
textarea.setSelectionRange(cursorPos + varName.length + 4, cursorPos + varName.length + 4);
closeModal('variableModal');
updateVariableCount();
});
});
// Template content change handler
document.getElementById('templateContent').addEventListener('input', function() {
updateVariableCount();
});
// Template selection change for generation
document.getElementById('generateTemplate').addEventListener('change', function() {
const templateId = this.value;
if (templateId) {
loadTemplatePreview(templateId);
} else {
document.getElementById('templatePreview').value = '';
}
});
// Custom variables checkbox
document.getElementById('useCustomVars').addEventListener('change', function() {
const section = document.getElementById('customVariablesSection');
section.style.display = this.checked ? 'block' : 'none';
});
// Add custom variable button
document.getElementById('addVariableBtn').addEventListener('click', function() {
addCustomVariableInput();
});
// Search and filter handlers
document.getElementById('templateSearch').addEventListener('input', debounce(loadTemplates, 300));
document.getElementById('categoryFilter').addEventListener('change', loadTemplates);
document.getElementById('qdroSearch').addEventListener('input', debounce(loadQdros, 300));
document.getElementById('qdroStatusFilter').addEventListener('change', loadQdros);
// Refresh buttons
document.getElementById('refreshTemplatesBtn').addEventListener('click', loadTemplates);
document.getElementById('refreshQdrosBtn').addEventListener('click', loadQdros);
}
// Helper function for authenticated API calls
function getAuthHeaders() {
const token = localStorage.getItem('auth_token');
return {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
};
}
async function loadTemplates() {
try {
console.log('🔍 DEBUG: loadTemplates() called');
const search = document.getElementById('templateSearch').value;
const category = document.getElementById('categoryFilter').value;
let url = '/api/documents/templates/?';
if (search) url += `search=${encodeURIComponent(search)}&`;
if (category) url += `category=${encodeURIComponent(category)}&`;
// Ensure we have auth token for this API call
const token = localStorage.getItem('auth_token');
console.log('🔍 DEBUG: Token exists:', !!token, 'Length:', token?.length);
if (!token) {
console.log('🔍 DEBUG: No token found, redirecting to login');
window.location.href = '/login';
return;
}
console.log('🔍 DEBUG: Making API call to:', url);
const response = await fetch(url, {
headers: getAuthHeaders()
});
console.log('🔍 DEBUG: Response status:', response.status);
if (!response.ok) {
const errorData = await response.json().catch(() => ({ detail: 'Unknown error' }));
throw new Error(errorData.detail || `HTTP ${response.status}`);
}
const templates = await response.json();
console.log('🔍 DEBUG: Templates loaded:', templates.length, 'items');
displayTemplates(templates);
} catch (error) {
console.error('🔍 DEBUG: Error in loadTemplates:', error);
try { logClientError({ message: 'Error loading templates', action: 'loadTemplates', error }); } catch (_) {}
showAlert('Error loading templates: ' + (error && error.message ? error.message : 'Unknown error'), 'danger');
}
}
function displayTemplates(templates) {
const tbody = document.getElementById('templatesTableBody');
tbody.innerHTML = '';
templates.forEach(template => {
const row = createTemplateRow(template);
tbody.appendChild(row);
});
}
function createTemplateRow(template) {
const row = document.createElement('tr');
const variableCount = Object.keys(template.variables || {}).length;
row.innerHTML = `
<td class="px-4 py-2"><code>${template.form_id}</code></td>
<td class="px-4 py-2">${template.form_name}</td>
<td class="px-4 py-2"><span class="inline-block px-2 py-0.5 text-xs rounded bg-neutral-100 text-neutral-700 border border-neutral-300">${template.category}</span></td>
<td class="px-4 py-2"><span class="inline-block px-2 py-0.5 text-xs rounded bg-blue-100 text-blue-700 border border-blue-400">${variableCount} vars</span></td>
<td class="px-4 py-2">
<span class="inline-block px-2 py-0.5 text-xs rounded ${template.active ? 'bg-green-100 text-green-700 border border-green-400' : 'bg-yellow-100 text-yellow-700 border border-yellow-500'}">
${template.active ? 'Active' : 'Inactive'}
</span>
</td>
<td class="px-4 py-2">
<div class="flex items-center gap-2">
<button class="px-2 py-1 border border-primary-600 text-primary-600 rounded hover:bg-blue-100" onclick="editTemplate('${template.form_id}')" title="Edit"><i class="fa-solid fa-pencil"></i></button>
<button class="px-2 py-1 border border-success-600 text-success-600 rounded hover:bg-green-100" onclick="previewTemplate('${template.form_id}')" title="Preview"><i class="fa-regular fa-eye"></i></button>
<button class="px-2 py-1 border border-info-600 text-info-600 rounded hover:bg-blue-100" onclick="generateFromTemplate('${template.form_id}')" title="Generate"><i class="fa-regular fa-file-lines"></i></button>
<button class="px-2 py-1 border border-danger-600 text-danger-600 rounded hover:bg-red-100" onclick="deleteTemplate('${template.form_id}')" title="Delete"><i class="fa-solid fa-trash"></i></button>
</div>
</td>
`;
return row;
}
async function loadQdros() {
try {
const search = document.getElementById('qdroSearch').value;
const status = document.getElementById('qdroStatusFilter').value;
let url = '/api/documents/qdros/?';
if (search) url += `search=${encodeURIComponent(search)}&`;
if (status) url += `status_filter=${encodeURIComponent(status)}&`;
const token = localStorage.getItem('auth_token');
if (!token) {
window.location.href = '/login';
return;
}
const response = await fetch(url, {
headers: getAuthHeaders()
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({ detail: 'Unknown error' }));
throw new Error(errorData.detail || `HTTP ${response.status}`);
}
const qdros = await response.json();
displayQdros(qdros);
} catch (error) {
console.error('Error loading QDROs:', error);
try { logClientError({ message: 'Error loading QDROs', action: 'loadQdros', error }); } catch (_) {}
showAlert('Error loading QDROs: ' + (error && error.message ? error.message : 'Unknown error'), 'danger');
}
}
function displayQdros(qdros) {
const tbody = document.getElementById('qdrosTableBody');
tbody.innerHTML = '';
qdros.forEach(qdro => {
const row = createQdroRow(qdro);
tbody.appendChild(row);
});
}
function createQdroRow(qdro) {
const row = document.createElement('tr');
row.innerHTML = `
<td><code>${qdro.file_no}</code></td>
<td>${qdro.version}</td>
<td>${qdro.participant_name || ''}</td>
<td>${qdro.spouse_name || ''}</td>
<td>${qdro.plan_name || ''}</td>
<td>
<span class="${getStatusBadgeClass(qdro.status)}">
${qdro.status}
</span>
</td>
<td>${qdro.created_date ? new Date(qdro.created_date).toLocaleDateString() : ''}</td>
<td>
<div class="flex items-center gap-2">
<button class="px-2 py-1 border border-blue-600 text-blue-600 rounded hover:bg-blue-100" onclick="editQdro(${qdro.id})" title="Edit"><i class="fa-solid fa-pencil"></i></button>
<button class="px-2 py-1 border border-cyan-600 text-cyan-600 rounded hover:bg-blue-100" onclick="viewQdro(${qdro.id})" title="View"><i class="fa-regular fa-eye"></i></button>
<button class="px-2 py-1 border border-red-600 text-red-600 rounded hover:bg-red-100" onclick="deleteQdro(${qdro.id})" title="Delete"><i class="fa-solid fa-trash"></i></button>
</div>
</td>
`;
return row;
}
function getStatusBadgeClass(status) {
switch (status) {
case 'DRAFT': return 'inline-block px-2 py-0.5 text-xs rounded bg-yellow-100 text-yellow-700 border border-yellow-500';
case 'APPROVED': return 'inline-block px-2 py-0.5 text-xs rounded bg-green-100 text-green-700 border border-green-400';
case 'FILED': return 'inline-block px-2 py-0.5 text-xs rounded bg-blue-100 text-blue-700 border border-blue-400';
default: return 'inline-block px-2 py-0.5 text-xs rounded bg-neutral-100 text-neutral-700 border border-neutral-300';
}
}
async function loadCategories() {
try {
const token = localStorage.getItem('auth_token');
if (!token) {
window.location.href = '/login';
return;
}
const response = await fetch('/api/documents/categories/', {
headers: getAuthHeaders()
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({ detail: 'Unknown error' }));
throw new Error(errorData.detail || `HTTP ${response.status}`);
}
const categories = await response.json();
const select = document.getElementById('categoryFilter');
const templateSelect = document.getElementById('templateCategory');
// Clear existing options except "All Categories"
select.innerHTML = '<option value="">All Categories</option>';
categories.forEach(category => {
const option = document.createElement('option');
option.value = category;
option.textContent = category;
select.appendChild(option);
});
} catch (error) {
console.error('Error loading categories:', error);
try { logClientError({ message: 'Error loading categories', action: 'loadCategories', error }); } catch (_) {}
}
}
function openTemplateModal(templateId = null) {
const form = document.getElementById('templateForm');
// Reset form
form.reset();
document.getElementById('templateModalLabel').textContent = templateId ? 'Edit Template' : 'New Template';
if (templateId) {
loadTemplateForEditing(templateId);
} else {
// Set today's date and generate ID
const today = new Date().toISOString().split('T')[0];
document.getElementById('templateId').value = 'TPL_' + Date.now();
}
openModal('templateModal');
updateVariableCount();
}
async function loadTemplateForEditing(templateId) {
try {
const response = await fetch(`/api/documents/templates/${templateId}`, {
headers: getAuthHeaders()
});
if (!response.ok) throw new Error('Failed to load template');
const template = await response.json();
document.getElementById('templateId').value = template.form_id;
document.getElementById('templateId').disabled = true; // Don't allow editing ID
document.getElementById('templateName').value = template.form_name;
document.getElementById('templateCategory').value = template.category;
document.getElementById('templateContent').value = template.content;
updateVariableCount();
} catch (error) {
console.error('Error loading template:', error);
try { logClientError({ message: 'Error loading template for edit', action: 'loadTemplateForEditing', error, extra: { templateId } }); } catch (_) {}
showAlert('Error loading template: ' + (error && error.message ? error.message : 'Unknown error'), 'danger');
}
}
async function saveTemplate() {
try {
const form = document.getElementById('templateForm');
const formData = new FormData(form);
const templateData = {
form_id: formData.get('form_id'),
form_name: formData.get('form_name'),
category: formData.get('category'),
content: formData.get('content')
};
const isEdit = document.getElementById('templateId').disabled;
const url = isEdit ? `/api/documents/templates/${templateData.form_id}` : '/api/documents/templates/';
const method = isEdit ? 'PUT' : 'POST';
const response = await fetch(url, {
method: method,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(templateData)
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'Failed to save template');
}
showAlert('Template saved successfully', 'success');
closeModal('templateModal');
loadTemplates();
} catch (error) {
console.error('Error saving template:', error);
try { logClientError({ message: 'Error saving template', action: 'saveTemplate', error }); } catch (_) {}
showAlert('Error saving template: ' + (error && error.message ? error.message : 'Unknown error'), 'danger');
}
}
function updateVariableCount() {
const content = document.getElementById('templateContent').value;
const variables = extractVariables(content);
document.getElementById('variableCount').textContent = `Variables detected: ${variables.length}`;
}
function extractVariables(content) {
const regex = /\{\{([^}]+)\}\}/g;
const variables = [];
let match;
while ((match = regex.exec(content)) !== null) {
if (!variables.includes(match[1])) {
variables.push(match[1]);
}
}
return variables;
}
async function loadDocumentStats() {
try {
const response = await fetch('/api/documents/stats/summary', {
headers: getAuthHeaders()
});
if (!response.ok) throw new Error('Failed to load statistics');
const stats = await response.json();
document.getElementById('totalTemplatesCount').textContent = stats.total_templates;
document.getElementById('totalQdrosCount').textContent = stats.total_qdros;
// Display categories breakdown
const categoriesDiv = document.getElementById('categoriesBreakdown');
categoriesDiv.innerHTML = '';
Object.entries(stats.templates_by_category).forEach(([category, count]) => {
const div = document.createElement('div');
div.className = 'flex items-center justify-between mb-1';
div.innerHTML = `<span>${category}</span><span class="inline-block px-2 py-0.5 text-xs rounded bg-neutral-200 text-neutral-700">${count}</span>`;
categoriesDiv.appendChild(div);
});
// Display recent activity
const activityDiv = document.getElementById('recentActivity');
activityDiv.innerHTML = '';
if (stats.recent_activity.length === 0) {
activityDiv.innerHTML = '<p class="text-neutral-500">No recent activity</p>';
} else {
stats.recent_activity.forEach(activity => {
const div = document.createElement('div');
div.className = 'mb-2 p-2 border rounded';
div.innerHTML = `
<small class="text-neutral-500">${activity.type}</small><br>
<strong>File: ${activity.file_no}</strong><br>
<span class="${getStatusBadgeClass(activity.status)}">${activity.status}</span>
`;
activityDiv.appendChild(div);
});
}
openModal('statsModal');
} catch (error) {
console.error('Error loading statistics:', error);
try { logClientError({ message: 'Error loading statistics', action: 'loadDocumentStats', error }); } catch (_) {}
showAlert('Error loading statistics: ' + (error && error.message ? error.message : 'Unknown error'), 'danger');
}
}
// Utility functions
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
function showAlert(message, type = 'info') {
if (window.alerts && typeof window.alerts.show === 'function') {
window.alerts.show(message, type);
} else if (window.showNotification) {
window.showNotification(message, type);
} else {
alert(String(message));
}
}
// Lightweight client error logger specific to Documents page
async function logClientError({ message, action = null, error = null, extra = null }) {
try {
const payload = {
message: String(message || (error && error.message) || 'Unknown error'),
action,
stack: error && error.stack ? String(error.stack) : null,
url: window.location.href,
user_agent: navigator.userAgent,
extra
};
await fetch('/api/documents/client-error', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
} catch (_) {
// swallow
}
}
// Placeholder functions for additional features
async function editTemplate(templateId) {
openTemplateModal(templateId);
}
async function previewTemplate(templateId) {
// Implement template preview
}
async function generateFromTemplate(templateId) {
document.getElementById('generateTemplate').value = templateId;
openGenerateModal();
}
async function deleteTemplate(templateId) {
if (confirm('Are you sure you want to delete this template?')) {
try {
const response = await fetch(`/api/documents/templates/${templateId}`, {
method: 'DELETE',
headers: getAuthHeaders()
});
if (!response.ok) throw new Error('Failed to delete template');
showAlert('Template deleted successfully', 'success');
loadTemplates();
} catch (error) {
console.error('Error deleting template:', error);
try { logClientError({ message: 'Error deleting template', action: 'deleteTemplate', error, extra: { templateId } }); } catch (_) {}
showAlert('Error deleting template: ' + (error && error.message ? error.message : 'Unknown error'), 'danger');
}
}
}
function openGenerateModal() {
loadTemplatesForGeneration();
openModal('generateModal');
}
async function loadTemplatesForGeneration() {
try {
const response = await fetch('/api/documents/templates/', {
headers: getAuthHeaders()
});
if (!response.ok) throw new Error('Failed to load templates');
const templates = await response.json();
const select = document.getElementById('generateTemplate');
select.innerHTML = '<option value="">Choose template...</option>';
templates.forEach(template => {
const option = document.createElement('option');
option.value = template.form_id;
option.textContent = `${template.form_name} (${template.category})`;
select.appendChild(option);
});
} catch (error) {
console.error('Error loading templates:', error);
try { logClientError({ message: 'Error loading templates for generation', action: 'loadTemplatesForGeneration', error }); } catch (_) {}
}
}
async function loadTemplatePreview(templateId) {
try {
const response = await fetch(`/api/documents/templates/${templateId}`, {
headers: getAuthHeaders()
});
if (!response.ok) throw new Error('Failed to load template');
const template = await response.json();
document.getElementById('templatePreview').value = template.content;
} catch (error) {
console.error('Error loading template preview:', error);
try { logClientError({ message: 'Error loading template preview', action: 'loadTemplatePreview', error, extra: { templateId } }); } catch (_) {}
}
}
async function generateDocument() {
try {
const form = document.getElementById('generateForm');
const formData = new FormData(form);
const templateId = formData.get('template_id');
if (!templateId) {
showAlert('Please select a template', 'warning');
return;
}
const requestData = {
template_id: templateId,
file_no: formData.get('file_no'),
output_format: formData.get('output_format'),
variables: {}
};
// Add custom variables if any
if (document.getElementById('useCustomVars').checked) {
const customVarInputs = document.querySelectorAll('#customVariables .custom-var-input');
customVarInputs.forEach(input => {
const name = input.querySelector('.var-name').value;
const value = input.querySelector('.var-value').value;
if (name && value) {
requestData.variables[name] = value;
}
});
}
const response = await fetch(`/api/documents/generate/${templateId}`, {
method: 'POST',
headers: getAuthHeaders(),
body: JSON.stringify(requestData)
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.detail || 'Failed to generate document');
}
const result = await response.json();
showAlert(`Document generated successfully: ${result.file_name}`, 'success');
closeModal('generateModal');
// Optionally trigger download
if (confirm('Document generated successfully. Download now?')) {
window.open(result.file_path, '_blank');
}
} catch (error) {
console.error('Error generating document:', error);
try { logClientError({ message: 'Error generating document', action: 'generateDocument', error, extra: { templateId: (document.getElementById('generateTemplate')?.value || null) } }); } catch (_) {}
showAlert('Error generating document: ' + (error && error.message ? error.message : 'Unknown error'), 'danger');
}
}
function addCustomVariableInput() {
const container = document.getElementById('customVariables');
const div = document.createElement('div');
div.className = 'grid grid-cols-12 gap-2 mb-2 custom-var-input';
div.innerHTML = `
<div class="col-span-12 md:col-span-5">
<input type="text" class="w-full px-3 py-1.5 border border-neutral-300 dark:border-neutral-600 rounded var-name" placeholder="Variable name">
</div>
<div class="col-span-12 md:col-span-5">
<input type="text" class="w-full px-3 py-1.5 border border-neutral-300 dark:border-neutral-600 rounded var-value" placeholder="Variable value">
</div>
<div class="col-span-12 md:col-span-2 flex items-center">
<button type="button" class="px-2 py-1 border border-red-600 text-red-600 rounded hover:bg-red-100 text-sm" onclick="this.closest('.custom-var-input').remove()">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
`;
container.appendChild(div);
}
function openQdroModal(qdroId = null) {
const form = document.getElementById('qdroForm');
form.reset();
document.getElementById('qdroModalLabel').textContent = qdroId ? 'Edit QDRO' : 'New QDRO';
if (!qdroId) {
document.getElementById('qdroCreated').value = new Date().toISOString().split('T')[0];
}
openModal('qdroModal');
}
async function saveQdro() {
// Implement QDRO save functionality
showAlert('QDRO functionality will be implemented in the next phase', 'info');
}
async function editQdro(qdroId) {
openQdroModal(qdroId);
}
async function viewQdro(qdroId) {
// Implement QDRO view functionality
showAlert('QDRO view functionality will be implemented', 'info');
}
async function deleteQdro(qdroId) {
if (confirm('Are you sure you want to delete this QDRO?')) {
// Implement delete functionality
showAlert('QDRO delete functionality will be implemented', 'info');
}
}
// Tab navigation functionality
function openTab(evt, tabName) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].classList.add('hidden');
}
// Get all elements with class="tablinks" and remove the "active" class
tablinks = document.querySelectorAll('nav button');
for (i = 0; i < tablinks.length; i++) {
tablinks[i].classList.remove('border-blue-500', 'text-blue-500', 'dark:text-blue-400');
tablinks[i].classList.add('border-transparent');
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(tabName).classList.remove('hidden');
evt.currentTarget.classList.add('border-blue-500', 'text-blue-500', 'dark:text-blue-400');
evt.currentTarget.classList.remove('border-transparent');
// Load data for the active tab
if (tabName === 'templates') {
loadTemplates();
} else if (tabName === 'qdros') {
loadQdros();
}
}
</script>
{% endblock %}