tractatus/public/admin/unified-inbox.html
TheFlow edb1540631 feat(crm): complete Phase 3 multi-project CRM + critical bug fixes
Phase 3 Multi-Project CRM Implementation:
- Add UnifiedContact model for cross-project contact linking
- Add Organization model with domain-based auto-detection
- Add ActivityTimeline model for comprehensive interaction tracking
- Add SLATracking model for 24-hour response commitment
- Add ResponseTemplate model with variable substitution
- Add CRM controller with 8 API endpoints
- Add Inbox controller for unified communications
- Add CRM dashboard frontend with tabs (Contacts, Orgs, SLA, Templates)
- Add Contact Management interface (Phase 1)
- Add Unified Inbox interface (Phase 2)
- Integrate CRM routes into main API

Critical Bug Fixes:
- Fix newsletter DELETE button (event handler context issue)
- Fix case submission invisible button (invalid CSS class)
- Fix Chart.js CSP violation (add cdn.jsdelivr.net to policy)
- Fix Chart.js SRI integrity hash mismatch

Technical Details:
- Email-based contact deduplication across projects
- Automatic organization linking via email domain
- Cross-project activity timeline aggregation
- SLA breach detection and alerting system
- Template rendering with {placeholder} substitution

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 18:10:14 +13:00

116 lines
4.9 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Unified Inbox | Tractatus Admin</title>
<link rel="stylesheet" href="/css/tailwind.css?v=0.1.0.1729786000000">
<link rel="stylesheet" href="/css/tractatus-theme.min.css?v=0.1.0.1729786000000">
<script defer src="/js/admin/auth-check.js?v=0.1.0.1729786000000"></script>
</head>
<body class="bg-gray-50">
<div id="admin-navbar" data-page-title="Unified Inbox" data-page-icon="default"></div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<!-- Header -->
<div class="mb-8">
<h1 class="text-3xl font-bold text-gray-900">Unified Inbox</h1>
<p class="mt-2 text-gray-600">All communications in one place: contacts, media inquiries, and case submissions</p>
</div>
<!-- Stats Overview -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
<div class="bg-white rounded-lg shadow p-6">
<div class="text-sm font-medium text-gray-500">Total Items</div>
<div class="mt-2 text-3xl font-semibold text-gray-900" id="stat-total">-</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="text-sm font-medium text-gray-500">New / Pending</div>
<div class="mt-2 text-3xl font-semibold text-orange-600" id="stat-new">-</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="text-sm font-medium text-gray-500">Assigned / Triaged</div>
<div class="mt-2 text-3xl font-semibold text-blue-600" id="stat-assigned">-</div>
</div>
<div class="bg-white rounded-lg shadow p-6">
<div class="text-sm font-medium text-gray-500">Responded</div>
<div class="mt-2 text-3xl font-semibold text-green-600" id="stat-responded">-</div>
</div>
</div>
<!-- Filters -->
<div class="bg-white rounded-lg shadow p-6 mb-8">
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Type</label>
<select id="filter-type" class="w-full border border-gray-300 rounded px-3 py-2">
<option value="all" selected>All Types</option>
<option value="contact">Contacts</option>
<option value="media">Media Inquiries</option>
<option value="case">Case Submissions</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Status</label>
<select id="filter-status" class="w-full border border-gray-300 rounded px-3 py-2">
<option value="">All Statuses</option>
<option value="new" selected>New / Pending</option>
<option value="assigned">Assigned / Triaged</option>
<option value="responded">Responded</option>
<option value="closed">Closed</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Priority</label>
<select id="filter-priority" class="w-full border border-gray-300 rounded px-3 py-2">
<option value="">All Priorities</option>
<option value="high">High</option>
<option value="normal">Normal</option>
<option value="low">Low</option>
</select>
</div>
<div class="flex items-end">
<button id="refresh-btn" class="w-full px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
Refresh
</button>
</div>
</div>
</div>
<!-- Inbox List -->
<div class="bg-white rounded-lg shadow">
<div class="px-6 py-4 border-b border-gray-200">
<h2 class="text-lg font-semibold text-gray-900">Inbox Items</h2>
</div>
<div id="inbox-container" class="divide-y divide-gray-200">
<!-- Will be populated by JS -->
</div>
</div>
</div>
<!-- Item Detail Modal -->
<div id="item-detail-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden">
<div class="bg-white rounded-lg shadow-xl max-w-4xl w-full mx-4 max-h-[90vh] overflow-y-auto">
<div class="p-6">
<div class="flex items-center justify-between mb-6">
<h2 class="text-2xl font-bold text-gray-900">Item Details</h2>
<button id="close-detail-modal" class="text-gray-400 hover:text-gray-600 text-2xl leading-none">&times;</button>
</div>
<div id="item-detail-content">
<!-- Will be populated dynamically -->
</div>
<div class="flex items-center justify-end gap-3 mt-6 pt-6 border-t">
<button id="close-detail-btn" class="px-4 py-2 border border-gray-300 rounded text-gray-700 hover:bg-gray-50">Close</button>
</div>
</div>
</div>
</div>
<script src="/js/components/navbar-admin.js?v=0.1.0.1729786000000"></script>
<script src="/js/admin/unified-inbox.js?v=0.1.0.1729786000000"></script>
</body>
</html>