231 lines
12 KiB
Plaintext
231 lines
12 KiB
Plaintext
<div class="space-y-8">
|
|
<!-- Page header -->
|
|
<div class="border-b border-gray-200 pb-5">
|
|
<h1 class="text-3xl font-bold leading-tight tracking-tight text-gray-900">Dashboard</h1>
|
|
<p class="mt-2 text-sm text-gray-600">Welcome back! Here's what's happening with your SMS gateway today.</p>
|
|
</div>
|
|
|
|
<!-- Stats grid -->
|
|
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
|
<!-- Gateways stat -->
|
|
<div class="relative overflow-hidden rounded-xl bg-white px-4 py-5 shadow-sm ring-1 ring-gray-900/5 sm:px-6">
|
|
<dt>
|
|
<div class="absolute rounded-lg bg-blue-500 p-3">
|
|
<i class="fas fa-mobile-alt text-xl text-white"></i>
|
|
</div>
|
|
<p class="ml-16 truncate text-sm font-medium text-gray-500">Gateways</p>
|
|
</dt>
|
|
<dd class="ml-16 flex items-baseline">
|
|
<p class="text-3xl font-semibold text-gray-900"><%= @stats[:total_gateways] %></p>
|
|
<p class="ml-2 flex items-baseline text-sm font-semibold text-green-600">
|
|
<%= @stats[:online_gateways] %> online
|
|
</p>
|
|
</dd>
|
|
</div>
|
|
|
|
<!-- API Keys stat -->
|
|
<div class="relative overflow-hidden rounded-xl bg-white px-4 py-5 shadow-sm ring-1 ring-gray-900/5 sm:px-6">
|
|
<dt>
|
|
<div class="absolute rounded-lg bg-green-500 p-3">
|
|
<i class="fas fa-key text-xl text-white"></i>
|
|
</div>
|
|
<p class="ml-16 truncate text-sm font-medium text-gray-500">API Keys</p>
|
|
</dt>
|
|
<dd class="ml-16 flex items-baseline">
|
|
<p class="text-3xl font-semibold text-gray-900"><%= @stats[:active_api_keys] %></p>
|
|
<p class="ml-2 flex items-baseline text-sm text-gray-600">
|
|
of <%= @stats[:total_api_keys] %> total
|
|
</p>
|
|
</dd>
|
|
</div>
|
|
|
|
<!-- Messages Today stat -->
|
|
<div class="relative overflow-hidden rounded-xl bg-white px-4 py-5 shadow-sm ring-1 ring-gray-900/5 sm:px-6">
|
|
<dt>
|
|
<div class="absolute rounded-lg bg-yellow-500 p-3">
|
|
<i class="fas fa-paper-plane text-xl text-white"></i>
|
|
</div>
|
|
<p class="ml-16 truncate text-sm font-medium text-gray-500">Messages Today</p>
|
|
</dt>
|
|
<dd class="ml-16 flex items-baseline">
|
|
<p class="text-3xl font-semibold text-gray-900"><%= @stats[:messages_today] %></p>
|
|
</dd>
|
|
<div class="ml-16 mt-1 flex items-center gap-3 text-xs">
|
|
<span class="inline-flex items-center gap-1 text-green-600">
|
|
<i class="fas fa-arrow-up"></i> <%= @stats[:messages_sent_today] %> sent
|
|
</span>
|
|
<span class="inline-flex items-center gap-1 text-blue-600">
|
|
<i class="fas fa-arrow-down"></i> <%= @stats[:messages_received_today] %> received
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Failed Messages stat -->
|
|
<div class="relative overflow-hidden rounded-xl bg-white px-4 py-5 shadow-sm ring-1 ring-gray-900/5 sm:px-6">
|
|
<dt>
|
|
<div class="absolute rounded-lg bg-red-500 p-3">
|
|
<i class="fas fa-exclamation-triangle text-xl text-white"></i>
|
|
</div>
|
|
<p class="ml-16 truncate text-sm font-medium text-gray-500">Failed Today</p>
|
|
</dt>
|
|
<dd class="ml-16 flex items-baseline">
|
|
<p class="text-3xl font-semibold text-gray-900"><%= @stats[:failed_messages_today] %></p>
|
|
<p class="ml-2 flex items-baseline text-sm text-gray-600">
|
|
<%= @stats[:pending_messages] %> pending
|
|
</p>
|
|
</dd>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Recent Messages -->
|
|
<div class="rounded-xl bg-white shadow-sm ring-1 ring-gray-900/5">
|
|
<div class="px-4 py-5 sm:px-6 border-b border-gray-200">
|
|
<h3 class="text-lg font-semibold leading-6 text-gray-900">Recent Messages</h3>
|
|
<p class="mt-1 text-sm text-gray-500">Latest SMS activity across all gateways</p>
|
|
</div>
|
|
<div class="overflow-hidden">
|
|
<% if @recent_messages.any? %>
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full divide-y divide-gray-200">
|
|
<thead class="bg-gray-50">
|
|
<tr>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Message ID</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Phone Number</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Direction</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Status</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Gateway</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Created</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-gray-200 bg-white">
|
|
<% @recent_messages.each do |msg| %>
|
|
<tr class="hover:bg-gray-50 transition-colors">
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm">
|
|
<code class="rounded bg-gray-100 px-2 py-1 text-xs font-mono text-gray-800"><%= msg.message_id[0..15] %>...</code>
|
|
</td>
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-900"><%= msg.phone_number %></td>
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm">
|
|
<% if msg.direction == "outbound" %>
|
|
<span class="inline-flex items-center gap-1 rounded-full bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-700/10">
|
|
<i class="fas fa-arrow-up"></i> Outbound
|
|
</span>
|
|
<% else %>
|
|
<span class="inline-flex items-center gap-1 rounded-full bg-green-50 px-2 py-1 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-700/10">
|
|
<i class="fas fa-arrow-down"></i> Inbound
|
|
</span>
|
|
<% end %>
|
|
</td>
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm">
|
|
<% case msg.status %>
|
|
<% when "delivered" %>
|
|
<span class="inline-flex rounded-full bg-green-50 px-2 py-1 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-700/10">Delivered</span>
|
|
<% when "sent" %>
|
|
<span class="inline-flex rounded-full bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-700/10">Sent</span>
|
|
<% when "failed" %>
|
|
<span class="inline-flex rounded-full bg-red-50 px-2 py-1 text-xs font-medium text-red-700 ring-1 ring-inset ring-red-700/10">Failed</span>
|
|
<% when "pending" %>
|
|
<span class="inline-flex rounded-full bg-yellow-50 px-2 py-1 text-xs font-medium text-yellow-700 ring-1 ring-inset ring-yellow-700/10">Pending</span>
|
|
<% else %>
|
|
<span class="inline-flex rounded-full bg-gray-50 px-2 py-1 text-xs font-medium text-gray-700 ring-1 ring-inset ring-gray-700/10"><%= msg.status.titleize %></span>
|
|
<% end %>
|
|
</td>
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-500"><%= msg.gateway&.name || "-" %></td>
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-500"><%= time_ago_in_words(msg.created_at) %> ago</td>
|
|
</tr>
|
|
<% end %>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="border-t border-gray-200 px-6 py-4">
|
|
<%= link_to admin_logs_path, class: "inline-flex items-center gap-2 text-sm font-semibold text-blue-600 hover:text-blue-500" do %>
|
|
View all logs
|
|
<i class="fas fa-arrow-right"></i>
|
|
<% end %>
|
|
</div>
|
|
<% else %>
|
|
<div class="px-6 py-14 text-center">
|
|
<i class="fas fa-inbox text-4xl text-gray-300"></i>
|
|
<p class="mt-4 text-sm text-gray-500">No messages yet</p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Gateway Status -->
|
|
<div class="rounded-xl bg-white shadow-sm ring-1 ring-gray-900/5">
|
|
<div class="px-4 py-5 sm:px-6 border-b border-gray-200">
|
|
<h3 class="text-lg font-semibold leading-6 text-gray-900">Gateway Status</h3>
|
|
<p class="mt-1 text-sm text-gray-500">Active gateway devices and their performance</p>
|
|
</div>
|
|
<div class="overflow-hidden">
|
|
<% if @recent_gateways.any? %>
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full divide-y divide-gray-200">
|
|
<thead class="bg-gray-50">
|
|
<tr>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Name</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Device ID</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Status</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Messages Today</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Last Heartbeat</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-gray-200 bg-white">
|
|
<% @recent_gateways.each do |gateway| %>
|
|
<tr class="hover:bg-gray-50 transition-colors">
|
|
<td class="whitespace-nowrap px-6 py-4">
|
|
<%= link_to gateway.name, admin_gateway_path(gateway), class: "text-sm font-medium text-blue-600 hover:text-blue-500" %>
|
|
</td>
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm">
|
|
<code class="rounded bg-gray-100 px-2 py-1 text-xs font-mono text-gray-800"><%= gateway.device_id %></code>
|
|
</td>
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm">
|
|
<% if gateway.status == "online" %>
|
|
<span class="inline-flex items-center gap-1.5 rounded-full bg-green-50 px-2 py-1 text-xs font-medium text-green-700 ring-1 ring-inset ring-green-700/10">
|
|
<span class="h-1.5 w-1.5 rounded-full bg-green-500"></span>
|
|
Online
|
|
</span>
|
|
<% else %>
|
|
<span class="inline-flex items-center gap-1.5 rounded-full bg-red-50 px-2 py-1 text-xs font-medium text-red-700 ring-1 ring-inset ring-red-700/10">
|
|
<span class="h-1.5 w-1.5 rounded-full bg-red-500"></span>
|
|
Offline
|
|
</span>
|
|
<% end %>
|
|
</td>
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
|
|
<span class="inline-flex items-center gap-1 text-green-600">
|
|
<i class="fas fa-arrow-up text-xs"></i> <%= gateway.messages_sent_today %>
|
|
</span>
|
|
<span class="mx-1 text-gray-300">|</span>
|
|
<span class="inline-flex items-center gap-1 text-blue-600">
|
|
<i class="fas fa-arrow-down text-xs"></i> <%= gateway.messages_received_today %>
|
|
</span>
|
|
</td>
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
|
|
<% if gateway.last_heartbeat_at %>
|
|
<%= time_ago_in_words(gateway.last_heartbeat_at) %> ago
|
|
<% else %>
|
|
Never
|
|
<% end %>
|
|
</td>
|
|
</tr>
|
|
<% end %>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="border-t border-gray-200 px-6 py-4">
|
|
<%= link_to admin_gateways_path, class: "inline-flex items-center gap-2 text-sm font-semibold text-blue-600 hover:text-blue-500" do %>
|
|
View all gateways
|
|
<i class="fas fa-arrow-right"></i>
|
|
<% end %>
|
|
</div>
|
|
<% else %>
|
|
<div class="px-6 py-14 text-center">
|
|
<i class="fas fa-mobile-alt text-4xl text-gray-300"></i>
|
|
<p class="mt-4 text-sm text-gray-500">No gateways registered yet</p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|
|
</div>
|