169 lines
9.3 KiB
Plaintext
169 lines
9.3 KiB
Plaintext
<div class="space-y-6">
|
|
<!-- Page header -->
|
|
<div class="sm:flex sm:items-center sm:justify-between">
|
|
<div>
|
|
<h1 class="text-3xl font-bold leading-tight tracking-tight text-gray-900">Gateways</h1>
|
|
<p class="mt-2 text-sm text-gray-600">Manage your SMS gateway devices and monitor their status.</p>
|
|
</div>
|
|
<%= link_to new_admin_gateway_path, class: "mt-4 sm:mt-0 inline-flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-all" do %>
|
|
<i class="fas fa-plus"></i>
|
|
Register New Gateway
|
|
<% end %>
|
|
</div>
|
|
|
|
<!-- Gateways table card -->
|
|
<div class="rounded-xl bg-white shadow-sm ring-1 ring-gray-900/5 overflow-hidden">
|
|
<% if @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">Active</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Priority</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Today</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Total</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Last Heartbeat</th>
|
|
<th scope="col" class="px-6 py-3 text-left text-xs font-medium uppercase tracking-wide text-gray-500">Created</th>
|
|
<th scope="col" class="px-6 py-3 text-center text-xs font-medium uppercase tracking-wide text-gray-500">Actions</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y divide-gray-200 bg-white">
|
|
<% @gateways.each do |gateway| %>
|
|
<tr class="hover:bg-gray-50 transition-colors">
|
|
<!-- Name -->
|
|
<td class="whitespace-nowrap px-6 py-4">
|
|
<%= link_to gateway.name, admin_gateway_path(gateway),
|
|
class: "text-sm font-semibold text-blue-600 hover:text-blue-500 transition-colors" %>
|
|
</td>
|
|
|
|
<!-- Device ID -->
|
|
<td class="whitespace-nowrap px-6 py-4">
|
|
<code class="rounded bg-gray-100 px-2 py-1 text-xs font-mono text-gray-800"><%= gateway.device_id %></code>
|
|
</td>
|
|
|
|
<!-- Status with pulse indicator -->
|
|
<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="relative flex h-2 w-2">
|
|
<span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"></span>
|
|
<span class="relative inline-flex rounded-full h-2 w-2 bg-green-500"></span>
|
|
</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-2 w-2 rounded-full bg-red-500"></span>
|
|
Offline
|
|
</span>
|
|
<% end %>
|
|
</td>
|
|
|
|
<!-- Active badge -->
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm">
|
|
<% if gateway.active %>
|
|
<span class="inline-flex items-center 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-check mr-1"></i> Active
|
|
</span>
|
|
<% else %>
|
|
<span class="inline-flex items-center rounded-full bg-gray-50 px-2 py-1 text-xs font-medium text-gray-700 ring-1 ring-inset ring-gray-700/10">
|
|
<i class="fas fa-times mr-1"></i> Inactive
|
|
</span>
|
|
<% end %>
|
|
</td>
|
|
|
|
<!-- Priority -->
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-900 font-medium text-center">
|
|
<%= gateway.priority %>
|
|
</td>
|
|
|
|
<!-- Messages Today -->
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm">
|
|
<div class="flex items-center gap-2">
|
|
<span class="inline-flex items-center gap-1 text-green-600">
|
|
<i class="fas fa-arrow-up text-xs"></i>
|
|
<span class="font-medium"><%= gateway.messages_sent_today %></span>
|
|
</span>
|
|
<span class="text-gray-300">|</span>
|
|
<span class="inline-flex items-center gap-1 text-blue-600">
|
|
<i class="fas fa-arrow-down text-xs"></i>
|
|
<span class="font-medium"><%= gateway.messages_received_today %></span>
|
|
</span>
|
|
</div>
|
|
</td>
|
|
|
|
<!-- Total Messages -->
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
|
|
<div class="flex items-center gap-2">
|
|
<span class="inline-flex items-center gap-1 text-green-600">
|
|
<i class="fas fa-arrow-up text-xs"></i>
|
|
<span><%= gateway.total_messages_sent %></span>
|
|
</span>
|
|
<span class="text-gray-300">|</span>
|
|
<span class="inline-flex items-center gap-1 text-blue-600">
|
|
<i class="fas fa-arrow-down text-xs"></i>
|
|
<span><%= gateway.total_messages_received %></span>
|
|
</span>
|
|
</div>
|
|
</td>
|
|
|
|
<!-- Last Heartbeat -->
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
|
|
<% if gateway.last_heartbeat_at %>
|
|
<div class="flex flex-col">
|
|
<span class="font-medium text-gray-900"><%= time_ago_in_words(gateway.last_heartbeat_at) %> ago</span>
|
|
<span class="text-xs text-gray-400"><%= gateway.last_heartbeat_at.strftime("%m/%d/%y %H:%M") %></span>
|
|
</div>
|
|
<% else %>
|
|
<span class="text-gray-400 italic">Never</span>
|
|
<% end %>
|
|
</td>
|
|
|
|
<!-- Created -->
|
|
<td class="whitespace-nowrap px-6 py-4 text-sm text-gray-500">
|
|
<%= gateway.created_at.strftime("%m/%d/%y") %>
|
|
</td>
|
|
|
|
<!-- Actions -->
|
|
<td class="whitespace-nowrap px-6 py-4 text-center">
|
|
<div class="flex items-center justify-center gap-2">
|
|
<%= link_to test_admin_gateway_path(gateway),
|
|
class: "inline-flex items-center gap-1 rounded-lg bg-blue-600 px-3 py-1.5 text-xs font-semibold text-white shadow-sm hover:bg-blue-500 transition-all duration-200" do %>
|
|
<i class="fas fa-vial"></i>
|
|
Test
|
|
<% end %>
|
|
<%= button_to toggle_admin_gateway_path(gateway), method: :post,
|
|
class: gateway.active ?
|
|
"inline-flex items-center gap-2 rounded-lg bg-red-600 px-3 py-1.5 text-xs font-semibold text-white shadow-sm hover:bg-red-500 transition-all duration-200" :
|
|
"inline-flex items-center gap-2 rounded-lg bg-green-600 px-3 py-1.5 text-xs font-semibold text-white shadow-sm hover:bg-green-500 transition-all duration-200" do %>
|
|
<% if gateway.active %>
|
|
<i class="fas fa-ban"></i>
|
|
Deactivate
|
|
<% else %>
|
|
<i class="fas fa-check"></i>
|
|
Activate
|
|
<% end %>
|
|
<% end %>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
<% end %>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<% else %>
|
|
<!-- Empty state -->
|
|
<div class="px-6 py-14 text-center">
|
|
<div class="mx-auto h-20 w-20 flex items-center justify-center rounded-full bg-gray-100">
|
|
<i class="fas fa-mobile-alt text-3xl text-gray-400"></i>
|
|
</div>
|
|
<p class="mt-4 text-base font-medium text-gray-900">No gateways registered yet</p>
|
|
<p class="mt-2 text-sm text-gray-500">Gateway devices will appear here once they connect via the API.</p>
|
|
</div>
|
|
<% end %>
|
|
</div>
|
|
</div>
|