|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>NexusDial - Advanced Cloud Dialer</title> |
|
|
<script src="https://cdn.tailwindcss.com"></script> |
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
|
<script> |
|
|
tailwind.config = { |
|
|
theme: { |
|
|
extend: { |
|
|
colors: { |
|
|
primary: '#4f46e5', |
|
|
secondary: '#10b981', |
|
|
accent: '#f59e0b', |
|
|
dark: '#1e293b', |
|
|
light: '#f8fafc' |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
</script> |
|
|
<style> |
|
|
@keyframes pulse { |
|
|
0%, 100% { opacity: 1; } |
|
|
50% { opacity: 0.5; } |
|
|
} |
|
|
.pulse-animation { |
|
|
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; |
|
|
} |
|
|
.agent-card:hover { |
|
|
transform: translateY(-2px); |
|
|
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); |
|
|
} |
|
|
.call-animation { |
|
|
animation: ring 1.5s ease infinite; |
|
|
} |
|
|
@keyframes ring { |
|
|
0% { transform: rotate(0); } |
|
|
10% { transform: rotate(-5deg); } |
|
|
20% { transform: rotate(5deg); } |
|
|
30% { transform: rotate(-5deg); } |
|
|
40% { transform: rotate(5deg); } |
|
|
50% { transform: rotate(0); } |
|
|
100% { transform: rotate(0); } |
|
|
} |
|
|
.sidebar { |
|
|
scrollbar-width: thin; |
|
|
scrollbar-color: #4f46e5 #e2e8f0; |
|
|
} |
|
|
.sidebar::-webkit-scrollbar { |
|
|
width: 6px; |
|
|
} |
|
|
.sidebar::-webkit-scrollbar-track { |
|
|
background: #e2e8f0; |
|
|
} |
|
|
.sidebar::-webkit-scrollbar-thumb { |
|
|
background-color: #4f46e5; |
|
|
border-radius: 3px; |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body class="bg-gray-50 font-sans antialiased"> |
|
|
<div class="flex h-screen overflow-hidden"> |
|
|
|
|
|
<div class="hidden md:flex md:flex-shrink-0"> |
|
|
<div class="flex flex-col w-64 bg-white border-r border-gray-200"> |
|
|
<div class="flex items-center justify-center h-16 px-4 bg-primary text-white"> |
|
|
<div class="flex items-center"> |
|
|
<i class="fas fa-phone-alt mr-2"></i> |
|
|
<span class="text-xl font-semibold">NexusDial</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="flex flex-col flex-grow overflow-y-auto sidebar"> |
|
|
<nav class="flex-1 px-2 py-4 space-y-1"> |
|
|
<a href="#" class="flex items-center px-2 py-2 text-sm font-medium rounded-md bg-indigo-100 text-primary"> |
|
|
<i class="fas fa-tachometer-alt mr-3"></i> |
|
|
Dashboard |
|
|
</a> |
|
|
<a href="#" class="flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-600 hover:bg-gray-100 hover:text-gray-900"> |
|
|
<i class="fas fa-users mr-3"></i> |
|
|
Contacts |
|
|
</a> |
|
|
<a href="#" class="flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-600 hover:bg-gray-100 hover:text-gray-900"> |
|
|
<i class="fas fa-chart-line mr-3"></i> |
|
|
Analytics |
|
|
</a> |
|
|
<a href="#" class="flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-600 hover:bg-gray-100 hover:text-gray-900"> |
|
|
<i class="fas fa-cog mr-3"></i> |
|
|
Settings |
|
|
</a> |
|
|
<a href="#" class="flex items-center px-2 py-2 text-sm font-medium rounded-md text-gray-600 hover:bg-gray-100 hover:text-gray-900"> |
|
|
<i class="fas fa-question-circle mr-3"></i> |
|
|
Help |
|
|
</a> |
|
|
</nav> |
|
|
<div class="px-4 py-4 border-t border-gray-200"> |
|
|
<div class="flex items-center"> |
|
|
<img class="w-10 h-10 rounded-full" src="https://randomuser.me/api/portraits/women/44.jpg" alt="User profile"> |
|
|
<div class="ml-3"> |
|
|
<p class="text-sm font-medium text-gray-700">Sarah Johnson</p> |
|
|
<p class="text-xs font-medium text-gray-500">Admin</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="flex flex-col flex-1 overflow-hidden"> |
|
|
|
|
|
<div class="flex items-center justify-between h-16 px-4 bg-white border-b border-gray-200"> |
|
|
<div class="flex items-center"> |
|
|
<button class="md:hidden text-gray-500 focus:outline-none"> |
|
|
<i class="fas fa-bars"></i> |
|
|
</button> |
|
|
<h1 class="ml-4 text-lg font-semibold text-gray-800">Dialer Dashboard</h1> |
|
|
</div> |
|
|
<div class="flex items-center space-x-4"> |
|
|
<button class="p-1 text-gray-400 rounded-full hover:text-gray-500 focus:outline-none"> |
|
|
<i class="fas fa-bell"></i> |
|
|
</button> |
|
|
<button class="p-1 text-gray-400 rounded-full hover:text-gray-500 focus:outline-none"> |
|
|
<i class="fas fa-envelope"></i> |
|
|
</button> |
|
|
<div class="relative"> |
|
|
<button class="flex items-center text-sm text-gray-700 focus:outline-none"> |
|
|
<span class="sr-only">Open user menu</span> |
|
|
<img class="w-8 h-8 rounded-full" src="https://randomuser.me/api/portraits/women/44.jpg" alt="User profile"> |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="flex-1 overflow-auto p-4"> |
|
|
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> |
|
|
|
|
|
<div class="lg:col-span-2 space-y-6"> |
|
|
|
|
|
<div class="bg-white rounded-lg shadow p-6"> |
|
|
<div class="flex justify-between items-center mb-4"> |
|
|
<h2 class="text-lg font-semibold text-gray-800">Campaign Performance</h2> |
|
|
<div class="flex space-x-2"> |
|
|
<button class="px-3 py-1 text-xs bg-primary text-white rounded-md">Today</button> |
|
|
<button class="px-3 py-1 text-xs bg-gray-200 text-gray-700 rounded-md">Week</button> |
|
|
<button class="px-3 py-1 text-xs bg-gray-200 text-gray-700 rounded-md">Month</button> |
|
|
</div> |
|
|
</div> |
|
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4"> |
|
|
<div class="bg-indigo-50 p-4 rounded-lg"> |
|
|
<div class="text-sm font-medium text-indigo-600">Total Calls</div> |
|
|
<div class="mt-1 text-2xl font-semibold text-gray-900">1,248</div> |
|
|
<div class="text-xs text-green-600 flex items-center"> |
|
|
<i class="fas fa-arrow-up mr-1"></i> 12% from yesterday |
|
|
</div> |
|
|
</div> |
|
|
<div class="bg-green-50 p-4 rounded-lg"> |
|
|
<div class="text-sm font-medium text-green-600">Connected</div> |
|
|
<div class="mt-1 text-2xl font-semibold text-gray-900">842</div> |
|
|
<div class="text-xs text-green-600 flex items-center"> |
|
|
<i class="fas fa-arrow-up mr-1"></i> 8% from yesterday |
|
|
</div> |
|
|
</div> |
|
|
<div class="bg-yellow-50 p-4 rounded-lg"> |
|
|
<div class="text-sm font-medium text-yellow-600">Conversion</div> |
|
|
<div class="mt-1 text-2xl font-semibold text-gray-900">312</div> |
|
|
<div class="text-xs text-red-600 flex items-center"> |
|
|
<i class="fas fa-arrow-down mr-1"></i> 3% from yesterday |
|
|
</div> |
|
|
</div> |
|
|
<div class="bg-red-50 p-4 rounded-lg"> |
|
|
<div class="text-sm font-medium text-red-600">DNC Hits</div> |
|
|
<div class="mt-1 text-2xl font-semibold text-gray-900">24</div> |
|
|
<div class="text-xs text-green-600 flex items-center"> |
|
|
<i class="fas fa-arrow-down mr-1"></i> 5% from yesterday |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-white rounded-lg shadow p-6"> |
|
|
<h2 class="text-lg font-semibold text-gray-800 mb-4">Dialer Controls</h2> |
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
|
|
<div> |
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Load Contacts</label> |
|
|
<div class="flex space-x-2 mb-4"> |
|
|
<label class="flex-1"> |
|
|
<div class="flex items-center justify-center px-4 py-2 bg-white border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 cursor-pointer"> |
|
|
<i class="fas fa-file-upload mr-2"></i> Upload CSV |
|
|
<input type="file" class="hidden" id="csv-upload" accept=".csv,.txt"> |
|
|
</div> |
|
|
</label> |
|
|
<button class="px-4 py-2 bg-primary text-white rounded-md shadow-sm text-sm font-medium hover:bg-indigo-700 focus:outline-none"> |
|
|
<i class="fas fa-database mr-2"></i> From CRM |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Or paste numbers</label> |
|
|
<textarea id="paste-list" rows="4" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary" placeholder="Enter phone numbers, one per line..."></textarea> |
|
|
|
|
|
<div class="flex justify-between mt-2"> |
|
|
<span id="queue-count" class="text-sm text-gray-500">0 numbers in queue</span> |
|
|
<button id="clear-queue" class="text-sm text-red-500 hover:text-red-700"> |
|
|
<i class="fas fa-trash-alt mr-1"></i> Clear |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Dialer Settings</label> |
|
|
<div class="space-y-3"> |
|
|
<div> |
|
|
<label class="block text-xs text-gray-500 mb-1">Dial Mode</label> |
|
|
<select class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary text-sm"> |
|
|
<option>Predictive (Auto)</option> |
|
|
<option>Progressive</option> |
|
|
<option>Preview</option> |
|
|
<option>Manual</option> |
|
|
</select> |
|
|
</div> |
|
|
|
|
|
<div class="grid grid-cols-2 gap-3"> |
|
|
<div> |
|
|
<label class="block text-xs text-gray-500 mb-1">Max Calls/Hour</label> |
|
|
<input type="number" value="60" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary text-sm"> |
|
|
</div> |
|
|
<div> |
|
|
<label class="block text-xs text-gray-500 mb-1">Call Timeout</label> |
|
|
<input type="number" value="30" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary text-sm"> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div class="flex items-center"> |
|
|
<input id="enable-recording" type="checkbox" checked class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded"> |
|
|
<label for="enable-recording" class="ml-2 block text-sm text-gray-700">Record calls</label> |
|
|
</div> |
|
|
|
|
|
<div class="flex space-x-2 pt-2"> |
|
|
<button id="start-dialer" class="flex-1 px-4 py-2 bg-green-600 text-white rounded-md shadow-sm text-sm font-medium hover:bg-green-700 focus:outline-none"> |
|
|
<i class="fas fa-play mr-2"></i> Start Dialing |
|
|
</button> |
|
|
<button id="pause-dialer" class="flex-1 px-4 py-2 bg-yellow-500 text-white rounded-md shadow-sm text-sm font-medium hover:bg-yellow-600 focus:outline-none"> |
|
|
<i class="fas fa-pause mr-2"></i> Pause |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-white rounded-lg shadow overflow-hidden"> |
|
|
<div class="px-6 py-4 border-b border-gray-200"> |
|
|
<h2 class="text-lg font-semibold text-gray-800">Active Calls</h2> |
|
|
</div> |
|
|
<div class="divide-y divide-gray-200"> |
|
|
<div class="p-4 hover:bg-gray-50"> |
|
|
<div class="flex items-center"> |
|
|
<div class="flex-shrink-0"> |
|
|
<div class="h-10 w-10 rounded-full bg-green-100 flex items-center justify-center text-green-600"> |
|
|
<i class="fas fa-phone-alt call-animation"></i> |
|
|
</div> |
|
|
</div> |
|
|
<div class="ml-4 flex-1"> |
|
|
<div class="flex items-center justify-between"> |
|
|
<p class="text-sm font-medium text-gray-900">+1 (555) 123-4567</p> |
|
|
<p class="text-xs text-gray-500">02:34</p> |
|
|
</div> |
|
|
<div class="flex items-center justify-between mt-1"> |
|
|
<p class="text-xs text-gray-500">Agent: Michael Scott</p> |
|
|
<span class="px-2 py-1 text-xs rounded-full bg-green-100 text-green-800">Connected</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="p-4 hover:bg-gray-50"> |
|
|
<div class="flex items-center"> |
|
|
<div class="flex-shrink-0"> |
|
|
<div class="h-10 w-10 rounded-full bg-blue-100 flex items-center justify-center text-blue-600"> |
|
|
<i class="fas fa-phone-alt call-animation"></i> |
|
|
</div> |
|
|
</div> |
|
|
<div class="ml-4 flex-1"> |
|
|
<div class="flex items-center justify-between"> |
|
|
<p class="text-sm font-medium text-gray-900">+1 (555) 987-6543</p> |
|
|
<p class="text-xs text-gray-500">01:12</p> |
|
|
</div> |
|
|
<div class="flex items-center justify-between mt-1"> |
|
|
<p class="text-xs text-gray-500">Agent: Dwight Schrute</p> |
|
|
<span class="px-2 py-1 text-xs rounded-full bg-blue-100 text-blue-800">Ringing</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="p-4 hover:bg-gray-50"> |
|
|
<div class="flex items-center"> |
|
|
<div class="flex-shrink-0"> |
|
|
<div class="h-10 w-10 rounded-full bg-yellow-100 flex items-center justify-center text-yellow-600"> |
|
|
<i class="fas fa-phone-alt"></i> |
|
|
</div> |
|
|
</div> |
|
|
<div class="ml-4 flex-1"> |
|
|
<div class="flex items-center justify-between"> |
|
|
<p class="text-sm font-medium text-gray-900">+1 (555) 456-7890</p> |
|
|
<p class="text-xs text-gray-500">00:45</p> |
|
|
</div> |
|
|
<div class="flex items-center justify-between mt-1"> |
|
|
<p class="text-xs text-gray-500">Agent: Jim Halpert</p> |
|
|
<span class="px-2 py-1 text-xs rounded-full bg-yellow-100 text-yellow-800">On Hold</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="space-y-6"> |
|
|
|
|
|
<div class="bg-white rounded-lg shadow overflow-hidden"> |
|
|
<div class="px-6 py-4 border-b border-gray-200"> |
|
|
<div class="flex items-center justify-between"> |
|
|
<h2 class="text-lg font-semibold text-gray-800">Agent Status</h2> |
|
|
<span class="text-xs bg-primary text-white px-2 py-1 rounded-full">10 Agents</span> |
|
|
</div> |
|
|
</div> |
|
|
<div class="divide-y divide-gray-200"> |
|
|
<div class="p-4 hover:bg-gray-50"> |
|
|
<div class="flex items-center"> |
|
|
<div class="flex-shrink-0"> |
|
|
<img class="h-10 w-10 rounded-full" src="https://randomuser.me/api/portraits/men/32.jpg" alt="Agent"> |
|
|
</div> |
|
|
<div class="ml-4 flex-1"> |
|
|
<div class="flex items-center justify-between"> |
|
|
<p class="text-sm font-medium text-gray-900">Michael Scott</p> |
|
|
<span class="px-2 py-1 text-xs rounded-full bg-green-100 text-green-800">On Call</span> |
|
|
</div> |
|
|
<div class="mt-1"> |
|
|
<p class="text-xs text-gray-500">+1 (555) 123-4567 (02:34)</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="p-4 hover:bg-gray-50"> |
|
|
<div class="flex items-center"> |
|
|
<div class="flex-shrink-0"> |
|
|
<img class="h-10 w-10 rounded-full" src="https://randomuser.me/api/portraits/men/44.jpg" alt="Agent"> |
|
|
</div> |
|
|
<div class="ml-4 flex-1"> |
|
|
<div class="flex items-center justify-between"> |
|
|
<p class="text-sm font-medium text-gray-900">Dwight Schrute</p> |
|
|
<span class="px-2 py-1 text-xs rounded-full bg-blue-100 text-blue-800">Ringing</span> |
|
|
</div> |
|
|
<div class="mt-1"> |
|
|
<p class="text-xs text-gray-500">+1 (555) 987-6543 (01:12)</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="p-4 hover:bg-gray-50"> |
|
|
<div class="flex items-center"> |
|
|
<div class="flex-shrink-0"> |
|
|
<img class="h-10 w-10 rounded-full" src="https://randomuser.me/api/portraits/men/22.jpg" alt="Agent"> |
|
|
</div> |
|
|
<div class="ml-4 flex-1"> |
|
|
<div class="flex items-center justify-between"> |
|
|
<p class="text-sm font-medium text-gray-900">Jim Halpert</p> |
|
|
<span class="px-2 py-1 text-xs rounded-full bg-yellow-100 text-yellow-800">On Hold</span> |
|
|
</div> |
|
|
<div class="mt-1"> |
|
|
<p class="text-xs text-gray-500">+1 (555) 456-7890 (00:45)</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="p-4 hover:bg-gray-50"> |
|
|
<div class="flex items-center"> |
|
|
<div class="flex-shrink-0"> |
|
|
<img class="h-10 w-10 rounded-full" src="https://randomuser.me/api/portraits/women/63.jpg" alt="Agent"> |
|
|
</div> |
|
|
<div class="ml-4 flex-1"> |
|
|
<div class="flex items-center justify-between"> |
|
|
<p class="text-sm font-medium text-gray-900">Pam Beesly</p> |
|
|
<span class="px-2 py-1 text-xs rounded-full bg-gray-100 text-gray-800">Available</span> |
|
|
</div> |
|
|
<div class="mt-1"> |
|
|
<p class="text-xs text-gray-500">Ready for next call</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="px-6 py-3 bg-gray-50 text-center"> |
|
|
<button class="text-sm text-primary hover:text-indigo-700 font-medium"> |
|
|
<i class="fas fa-plus mr-1"></i> Add Agent |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-white rounded-lg shadow p-6"> |
|
|
<h2 class="text-lg font-semibold text-gray-800 mb-4">Call Disposition</h2> |
|
|
<div class="space-y-4"> |
|
|
<div> |
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Status</label> |
|
|
<select class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary text-sm"> |
|
|
<option>Interested - Follow up needed</option> |
|
|
<option>Not Interested</option> |
|
|
<option>Call Back Later</option> |
|
|
<option>Do Not Call</option> |
|
|
<option>Wrong Number</option> |
|
|
<option>No Answer</option> |
|
|
<option>Busy</option> |
|
|
</select> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Notes</label> |
|
|
<textarea rows="3" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary text-sm" placeholder="Add call notes..."></textarea> |
|
|
</div> |
|
|
|
|
|
<div> |
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Next Action</label> |
|
|
<select class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary text-sm"> |
|
|
<option>None</option> |
|
|
<option>Schedule Call Back</option> |
|
|
<option>Send Email</option> |
|
|
<option>Send SMS</option> |
|
|
<option>Create Task</option> |
|
|
</select> |
|
|
</div> |
|
|
|
|
|
<div id="callback-container" class="hidden"> |
|
|
<label class="block text-sm font-medium text-gray-700 mb-1">Callback Date/Time</label> |
|
|
<input type="datetime-local" class="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-primary focus:border-primary text-sm"> |
|
|
</div> |
|
|
|
|
|
<button class="w-full px-4 py-2 bg-primary text-white rounded-md shadow-sm text-sm font-medium hover:bg-indigo-700 focus:outline-none"> |
|
|
<i class="fas fa-save mr-2"></i> Save Disposition |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="bg-white rounded-lg shadow p-6"> |
|
|
<h2 class="text-lg font-semibold text-gray-800 mb-4">Quick Stats</h2> |
|
|
<div class="space-y-3"> |
|
|
<div class="flex justify-between"> |
|
|
<span class="text-sm text-gray-600">Calls Today</span> |
|
|
<span class="text-sm font-medium">124</span> |
|
|
</div> |
|
|
<div class="flex justify-between"> |
|
|
<span class="text-sm text-gray-600">Connect Rate</span> |
|
|
<span class="text-sm font-medium">67%</span> |
|
|
</div> |
|
|
<div class="flex justify-between"> |
|
|
<span class="text-sm text-gray-600">Avg Talk Time</span> |
|
|
<span class="text-sm font-medium">2:34</span> |
|
|
</div> |
|
|
<div class="flex justify-between"> |
|
|
<span class="text-sm text-gray-600">Conversion Rate</span> |
|
|
<span class="text-sm font-medium">25%</span> |
|
|
</div> |
|
|
<div class="flex justify-between"> |
|
|
<span class="text-sm text-gray-600">DNC Hits</span> |
|
|
<span class="text-sm font-medium">3</span> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div id="call-modal" class="fixed inset-0 z-50 hidden overflow-y-auto"> |
|
|
<div class="flex items-center justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"> |
|
|
<div class="fixed inset-0 transition-opacity" aria-hidden="true"> |
|
|
<div class="absolute inset-0 bg-gray-500 opacity-75"></div> |
|
|
</div> |
|
|
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span> |
|
|
<div class="inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-sm sm:w-full sm:p-6"> |
|
|
<div> |
|
|
<div class="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100"> |
|
|
<i class="fas fa-phone-alt text-green-600 call-animation"></i> |
|
|
</div> |
|
|
<div class="mt-3 text-center sm:mt-5"> |
|
|
<h3 class="text-lg leading-6 font-medium text-gray-900" id="modal-title">Incoming Call</h3> |
|
|
<div class="mt-2"> |
|
|
<p class="text-sm text-gray-500" id="caller-number">+1 (555) 123-4567</p> |
|
|
<p class="text-xs text-gray-400 mt-1">John Smith • Acme Corp</p> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="mt-5 sm:mt-6 grid grid-cols-2 gap-3"> |
|
|
<button type="button" class="inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 bg-green-600 text-base font-medium text-white hover:bg-green-700 focus:outline-none sm:text-sm"> |
|
|
<i class="fas fa-phone mr-2"></i> Answer |
|
|
</button> |
|
|
<button type="button" class="inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none sm:text-sm"> |
|
|
<i class="fas fa-phone-slash mr-2"></i> Decline |
|
|
</button> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
|
|
|
let callQueue = []; |
|
|
let isPaused = false; |
|
|
let agents = [ |
|
|
{ id: 1, name: "Michael Scott", status: "on-call", avatar: "https://randomuser.me/api/portraits/men/32.jpg", currentCall: "+1 (555) 123-4567", callDuration: "02:34" }, |
|
|
{ id: 2, name: "Dwight Schrute", status: "ringing", avatar: "https://randomuser.me/api/portraits/men/44.jpg", currentCall: "+1 (555) 987-6543", callDuration: "01:12" }, |
|
|
{ id: 3, name: "Jim Halpert", status: "on-hold", avatar: "https://randomuser.me/api/portraits/men/22.jpg", currentCall: "+1 (555) 456-7890", callDuration: "00:45" }, |
|
|
{ id: 4, name: "Pam Beesly", status: "available", avatar: "https://randomuser.me/api/portraits/women/63.jpg", currentCall: null, callDuration: null }, |
|
|
{ id: 5, name: "Stanley Hudson", status: "available", avatar: "https://randomuser.me/api/portraits/men/12.jpg", currentCall: null, callDuration: null }, |
|
|
{ id: 6, name: "Phyllis Vance", status: "available", avatar: "https://randomuser.me/api/portraits/women/45.jpg", currentCall: null, callDuration: null }, |
|
|
{ id: 7, name: "Kevin Malone", status: "break", avatar: "https://randomuser.me/api/portraits/men/65.jpg", currentCall: null, callDuration: null }, |
|
|
{ id: 8, name: "Angela Martin", status: "break", avatar: "https://randomuser.me/api/portraits/women/33.jpg", currentCall: null, callDuration: null }, |
|
|
{ id: 9, name: "Oscar Martinez", status: "training", avatar: "https://randomuser.me/api/portraits/men/76.jpg", currentCall: null, callDuration: null }, |
|
|
{ id: 10, name: "Kelly Kapoor", status: "wrap-up", avatar: "https://randomuser.me/api/portraits/women/22.jpg", currentCall: null, callDuration: null } |
|
|
]; |
|
|
|
|
|
|
|
|
const csvUpload = document.getElementById('csv-upload'); |
|
|
const pasteList = document.getElementById('paste-list'); |
|
|
const queueCount = document.getElementById('queue-count'); |
|
|
const clearQueueBtn = document.getElementById('clear-queue'); |
|
|
const startDialerBtn = document.getElementById('start-dialer'); |
|
|
const pauseDialerBtn = document.getElementById('pause-dialer'); |
|
|
const callModal = document.getElementById('call-modal'); |
|
|
|
|
|
|
|
|
csvUpload.addEventListener('change', handleCSVUpload); |
|
|
pasteList.addEventListener('input', autoLoadPasteList); |
|
|
clearQueueBtn.addEventListener('click', clearQueue); |
|
|
startDialerBtn.addEventListener('click', startAutoDialing); |
|
|
pauseDialerBtn.addEventListener('click', togglePauseDialer); |
|
|
|
|
|
|
|
|
function updateQueueCount() { |
|
|
const count = callQueue.length; |
|
|
queueCount.textContent = `${count} number${count !== 1 ? 's' : ''} in queue`; |
|
|
} |
|
|
|
|
|
function handleCSVUpload(event) { |
|
|
const file = event.target.files[0]; |
|
|
if (!file) return; |
|
|
|
|
|
const reader = new FileReader(); |
|
|
reader.onload = function(e) { |
|
|
const content = e.target.result; |
|
|
callQueue = content.split('\n') |
|
|
.map(line => line.trim()) |
|
|
.filter(line => line !== ''); |
|
|
|
|
|
updateQueueCount(); |
|
|
showNotification(`Successfully loaded ${callQueue.length} numbers from CSV`); |
|
|
}; |
|
|
reader.readAsText(file); |
|
|
} |
|
|
|
|
|
function autoLoadPasteList() { |
|
|
const inputText = pasteList.value; |
|
|
callQueue = inputText.split('\n') |
|
|
.map(line => line.trim()) |
|
|
.filter(line => line !== ''); |
|
|
|
|
|
updateQueueCount(); |
|
|
} |
|
|
|
|
|
function clearQueue() { |
|
|
callQueue = []; |
|
|
pasteList.value = ''; |
|
|
updateQueueCount(); |
|
|
showNotification('Call queue has been cleared', 'info'); |
|
|
} |
|
|
|
|
|
function startAutoDialing() { |
|
|
if (callQueue.length === 0) { |
|
|
showNotification('Please add numbers to the queue first', 'warning'); |
|
|
return; |
|
|
} |
|
|
|
|
|
showNotification('Dialer started successfully', 'success'); |
|
|
isPaused = false; |
|
|
startDialerBtn.disabled = true; |
|
|
pauseDialerBtn.disabled = false; |
|
|
|
|
|
|
|
|
simulateCalls(); |
|
|
} |
|
|
|
|
|
function togglePauseDialer() { |
|
|
isPaused = !isPaused; |
|
|
if (isPaused) { |
|
|
pauseDialerBtn.innerHTML = '<i class="fas fa-play mr-2"></i> Resume'; |
|
|
showNotification('Dialer paused', 'info'); |
|
|
} else { |
|
|
pauseDialerBtn.innerHTML = '<i class="fas fa-pause mr-2"></i> Pause'; |
|
|
showNotification('Dialer resumed', 'success'); |
|
|
simulateCalls(); |
|
|
} |
|
|
} |
|
|
|
|
|
function simulateCalls() { |
|
|
if (isPaused || callQueue.length === 0) return; |
|
|
|
|
|
|
|
|
const availableAgents = agents.filter(agent => agent.status === 'available'); |
|
|
if (availableAgents.length === 0) { |
|
|
setTimeout(simulateCalls, 2000); |
|
|
return; |
|
|
} |
|
|
|
|
|
|
|
|
availableAgents.slice(0, Math.min(availableAgents.length, callQueue.length)).forEach(agent => { |
|
|
if (callQueue.length === 0) return; |
|
|
|
|
|
const number = callQueue.shift(); |
|
|
updateQueueCount(); |
|
|
|
|
|
|
|
|
agent.status = 'ringing'; |
|
|
agent.currentCall = number; |
|
|
agent.callDuration = '00:00'; |
|
|
|
|
|
|
|
|
showCallModal(number); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
agent.status = 'on-call'; |
|
|
updateAgentUI(agent); |
|
|
|
|
|
|
|
|
const callDuration = Math.floor(Math.random() * 120) + 30; |
|
|
setTimeout(() => { |
|
|
agent.status = 'wrap-up'; |
|
|
agent.callDuration = null; |
|
|
updateAgentUI(agent); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
agent.status = 'available'; |
|
|
agent.currentCall = null; |
|
|
updateAgentUI(agent); |
|
|
simulateCalls(); |
|
|
}, 5000); |
|
|
}, callDuration * 1000); |
|
|
}, 3000); |
|
|
}); |
|
|
|
|
|
|
|
|
setTimeout(simulateCalls, 2000); |
|
|
} |
|
|
|
|
|
function updateAgentUI(agent) { |
|
|
|
|
|
console.log(`Agent ${agent.name} status updated to ${agent.status}`); |
|
|
} |
|
|
|
|
|
function showCallModal(number) { |
|
|
document.getElementById('caller-number').textContent = number; |
|
|
callModal.classList.remove('hidden'); |
|
|
|
|
|
|
|
|
setTimeout(() => { |
|
|
if (!callModal.classList.contains('hidden')) { |
|
|
callModal.classList.add('hidden'); |
|
|
} |
|
|
}, 10000); |
|
|
} |
|
|
|
|
|
function showNotification(message, type = 'success') { |
|
|
|
|
|
console.log(`Notification (${type}): ${message}`); |
|
|
} |
|
|
|
|
|
|
|
|
updateQueueCount(); |
|
|
|
|
|
|
|
|
window.addEventListener('click', (event) => { |
|
|
if (event.target === callModal) { |
|
|
callModal.classList.add('hidden'); |
|
|
} |
|
|
}); |
|
|
|
|
|
|
|
|
document.querySelector('select').addEventListener('change', function() { |
|
|
const callbackContainer = document.getElementById('callback-container'); |
|
|
if (this.value === 'Schedule Call Back') { |
|
|
callbackContainer.classList.remove('hidden'); |
|
|
} else { |
|
|
callbackContainer.classList.add('hidden'); |
|
|
} |
|
|
}); |
|
|
</script> |
|
|
</body> |
|
|
</html> |