campaign_connector/src/templates/dashboard_clean.html
2025-08-25 09:41:16 -06:00

312 lines
18 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SMS Campaign Manager</title>
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.socket.io/4.7.2/socket.io.min.js"></script>
<link rel="stylesheet" href="/static/css/dashboard.css">
</head>
<body class="bg-gray-50">
<div x-data="campaignApp()" x-init="init()" x-cloak class="container mx-auto px-4 py-8 max-w-7xl">
<!-- Header with Connection Status -->
<div class="bg-white rounded-lg shadow-sm p-6 mb-6">
<div class="flex justify-between items-center">
<div>
<h1 class="text-3xl font-bold text-gray-800">📱 SMS Campaign Manager</h1>
<p class="text-gray-600 mt-1">Homelab Campaign Management Interface</p>
</div>
<div class="flex flex-col space-y-2">
<!-- Termux API Status -->
<div class="flex items-center">
<span class="text-sm font-medium text-gray-600 mr-2 w-20">Termux:</span>
<span x-show="phoneStatus.termux_connected" class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
🟢 Online
</span>
<span x-show="!phoneStatus.termux_connected" class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
🔴 Offline
</span>
</div>
<!-- ADB Status -->
<div class="flex items-center">
<span class="text-sm font-medium text-gray-600 mr-2 w-20">ADB:</span>
<span x-show="phoneStatus.adb_connected" class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
🟢 Online
</span>
<span x-show="!phoneStatus.adb_connected" class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
🔴 Offline
</span>
</div>
</div>
</div>
</div>
<!-- Tab Navigation -->
<div class="bg-white rounded-t-lg shadow-sm border-b">
<nav class="flex space-x-1 p-1">
<button @click="activeTab = 'campaigns'"
:class="activeTab === 'campaigns' ? 'bg-blue-500 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200'"
class="px-4 py-2 rounded-lg font-medium transition-colors">
📋 Campaigns
</button>
<button @click="activeTab = 'conversations'; loadConversations()"
:class="activeTab === 'conversations' ? 'bg-blue-500 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200'"
class="px-4 py-2 rounded-lg font-medium transition-colors">
💬 Conversations
</button>
<button @click="activeTab = 'testing'"
:class="activeTab === 'testing' ? 'bg-blue-500 text-white' : 'bg-gray-100 text-gray-700 hover:bg-gray-200'"
class="px-4 py-2 rounded-lg font-medium transition-colors">
🧪 System Testing
</button>
</nav>
</div>
<!-- Tab Content -->
<div class="bg-white rounded-b-lg shadow-sm min-h-[600px]">
<!-- Campaigns Tab (Preserving existing functionality) -->
<div x-show="activeTab === 'campaigns'" class="p-6">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Create Campaign Section -->
<div class="border rounded-lg p-4">
<h2 class="text-xl font-semibold mb-4">Create Campaign</h2>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Campaign Name</label>
<input type="text" x-model="campaignName"
placeholder="e.g., Weekend Volunteer Outreach"
class="w-full px-3 py-2 border rounded-lg">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">
Message Template <span class="text-gray-500">(Use {name}, {phone}, {date}, {time} for variables)</span>
</label>
<textarea x-model="messageTemplate"
placeholder="Hi {name}! Hope all is well. I am wondering if you got my last email..."
class="w-full px-3 py-2 border rounded-lg h-24"></textarea>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Recipients CSV</label>
<input type="file" @change="handleFileUpload($event)"
accept=".csv"
class="w-full px-3 py-2 border rounded-lg">
<div x-show="uploadedFile" class="mt-2 text-sm text-green-600">
<span x-text="uploadedFile"></span>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Use Saved List</label>
<select x-model="selectedList" class="w-full px-3 py-2 border rounded-lg">
<option value="">-- Select a saved list --</option>
<template x-for="list in savedLists" :key="list.id">
<option :value="list.id" x-text="`${list.name} (${list.count} contacts)`"></option>
</template>
</select>
</div>
<div class="flex gap-2">
<button @click="saveTemplate()"
class="bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600">
Save Template
</button>
<button @click="testSMS()"
class="bg-yellow-500 text-white px-4 py-2 rounded hover:bg-yellow-600">
Test SMS
</button>
<button @click="startCampaign()"
:disabled="!campaignReady"
class="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600 disabled:opacity-50">
Start Campaign
</button>
</div>
</div>
</div>
<!-- Campaign Status Section -->
<div class="space-y-4">
<!-- Analytics -->
<div class="border rounded-lg p-4">
<h3 class="font-semibold mb-3">Campaign Analytics</h3>
<div class="grid grid-cols-2 gap-4">
<div class="text-center">
<div class="text-2xl font-bold text-blue-600" x-text="analytics.total_sent || 0"></div>
<div class="text-sm text-gray-600">Total Sent</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-green-600" x-text="analytics.responses || 0"></div>
<div class="text-sm text-gray-600">Responses</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-yellow-600" x-text="analytics.follow_ups || 0"></div>
<div class="text-sm text-gray-600">Follow-ups Needed</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-purple-600" x-text="analytics.opt_outs || 0"></div>
<div class="text-sm text-gray-600">Opt-outs</div>
</div>
</div>
</div>
<!-- Response Types -->
<div class="border rounded-lg p-4">
<h3 class="font-semibold mb-3">Response Types</h3>
<div x-show="!responseTypes.length" class="text-gray-500 text-sm">
No responses yet
</div>
<div class="space-y-2">
<template x-for="type in responseTypes" :key="type.type">
<div class="flex justify-between items-center">
<span x-text="type.type" class="text-sm"></span>
<span x-text="type.count" class="font-medium"></span>
</div>
</template>
</div>
</div>
<!-- Recent Campaigns -->
<div class="border rounded-lg p-4">
<h3 class="font-semibold mb-3">Recent Campaigns</h3>
<div x-show="!recentCampaigns.length" class="text-gray-500 text-sm">
No recent campaigns
</div>
<div class="space-y-2">
<template x-for="campaign in recentCampaigns" :key="campaign.id">
<div class="border-b pb-2">
<div class="font-medium" x-text="campaign.name"></div>
<div class="text-sm text-gray-600">
<span x-text="campaign.sent_count"></span> sent •
<span x-text="formatDate(campaign.created_at)"></span>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
<!-- Conversations Tab -->
<div x-show="activeTab === 'conversations'" class="p-6">
<div id="conversations-container">
<!-- Enhanced conversations component will be loaded here -->
<include src="conversations_enhanced_component.html"></include>
</div>
</div>
<!-- System Testing Tab -->
<div x-show="activeTab === 'testing'" class="p-6">
<h2 class="text-xl font-semibold mb-4">🧪 System Testing & Diagnostics</h2>
<!-- Connection Tests -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
<!-- Termux API Test -->
<div class="border rounded-lg p-4">
<h3 class="font-medium mb-3">📡 Termux API Test</h3>
<div class="text-sm text-gray-600 mb-3">
Endpoint: <code class="bg-gray-100 px-1">http://{{ phoneIP }}:5001</code>
</div>
<button @click="testTermuxConnection()"
:disabled="testingTermux"
class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600 disabled:opacity-50 transition-colors">
<span x-show="!testingTermux">Test Termux API</span>
<span x-show="testingTermux">Testing...</span>
</button>
<div x-show="termuxTestResult" class="mt-3 p-3 rounded text-sm"
:class="termuxTestResult?.success ? 'bg-green-50 text-green-700' : 'bg-red-50 text-red-700'">
<pre x-text="JSON.stringify(termuxTestResult, null, 2)"></pre>
</div>
</div>
<!-- ADB Connection Test -->
<div class="border rounded-lg p-4">
<h3 class="font-medium mb-3">🔌 ADB Connection Test</h3>
<div class="text-sm text-gray-600 mb-3">
Device: <code class="bg-gray-100 px-1">{{ phoneIP }}:5555</code>
</div>
<button @click="testAdbConnection()"
:disabled="testingAdb"
class="bg-purple-500 text-white px-4 py-2 rounded hover:bg-purple-600 disabled:opacity-50 transition-colors">
<span x-show="!testingAdb">Test ADB</span>
<span x-show="testingAdb">Testing...</span>
</button>
<div x-show="adbTestResult" class="mt-3 p-3 rounded text-sm"
:class="adbTestResult?.success ? 'bg-green-50 text-green-700' : 'bg-red-50 text-red-700'">
<pre x-text="JSON.stringify(adbTestResult, null, 2)"></pre>
</div>
</div>
</div>
<!-- Test SMS Send -->
<div class="border rounded-lg p-4 mb-6">
<h3 class="font-medium mb-3">📨 Test SMS Send</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<input type="tel" x-model="testPhone"
placeholder="Phone number (e.g., 7801234567)"
class="border rounded px-3 py-2">
<input type="text" x-model="testMessage"
placeholder="Test message"
class="border rounded px-3 py-2">
</div>
<div class="mt-4 flex gap-2">
<button @click="sendTestSms('termux')"
:disabled="!testPhone || sendingTest"
class="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600 disabled:opacity-50 transition-colors">
Send via Termux
</button>
<button @click="sendTestSms('adb')"
:disabled="!testPhone || sendingTest"
class="bg-purple-500 text-white px-4 py-2 rounded hover:bg-purple-600 disabled:opacity-50 transition-colors">
Send via ADB
</button>
<button @click="sendTestSms('auto')"
:disabled="!testPhone || sendingTest"
class="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600 disabled:opacity-50 transition-colors">
Auto (Best Available)
</button>
</div>
<div x-show="testSmsResult" class="mt-3 p-3 rounded text-sm"
:class="testSmsResult?.success ? 'bg-green-50 text-green-700' : 'bg-red-50 text-red-700'">
<pre x-text="JSON.stringify(testSmsResult, null, 2)"></pre>
</div>
</div>
<!-- System Information -->
<div class="border rounded-lg p-4">
<h3 class="font-medium mb-3"> System Information</h3>
<div class="grid grid-cols-2 gap-4 text-sm">
<div>
<span class="font-medium">Phone IP:</span>
<span x-text="phoneIP"></span>
</div>
<div>
<span class="font-medium">Preferred Method:</span>
<span x-text="phoneStatus.prefer_termux ? 'Termux API' : 'ADB'"></span>
</div>
<div>
<span class="font-medium">Last Check:</span>
<span x-text="formatTime(phoneStatus.last_check)"></span>
</div>
<div>
<span class="font-medium">Active Connection:</span>
<span x-text="phoneStatus.termux_connected ? 'Termux' : (phoneStatus.adb_connected ? 'ADB' : 'None')"></span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Load JavaScript files -->
<script src="/static/js/dashboard.js"></script>
<script src="/static/js/lists.js"></script>
<script src="/static/js/conversations_enhanced.js"></script>
</body>
</html>