completed SMS gateway project

This commit is contained in:
Min Zeya Phyo
2025-10-22 17:22:17 +08:00
commit c883fa7128
190 changed files with 16294 additions and 0 deletions

View File

@@ -0,0 +1,565 @@
<div class="space-y-6">
<!-- Back link -->
<div class="flex items-center gap-4">
<%= link_to admin_gateways_path, class: "inline-flex items-center gap-2 text-sm font-medium text-gray-600 hover:text-gray-900 transition-colors" do %>
<i class="fas fa-arrow-left"></i>
Back to Gateways
<% end %>
</div>
<% if @is_new && @raw_key.present? %>
<!-- New gateway created - show API key -->
<div class="border-b border-gray-200 pb-5">
<h1 class="text-3xl font-bold leading-tight tracking-tight text-gray-900">Gateway Created Successfully!</h1>
<p class="mt-2 text-sm text-gray-600">Your new gateway has been registered and is ready to connect.</p>
</div>
<!-- Warning alert -->
<div class="rounded-lg bg-yellow-50 px-4 py-4 ring-1 ring-yellow-600/10">
<div class="flex items-start gap-3">
<div class="flex-shrink-0">
<i class="fas fa-exclamation-triangle text-yellow-600 text-xl"></i>
</div>
<div>
<h3 class="text-sm font-semibold text-yellow-800">Important: Save this API key now!</h3>
<p class="mt-1 text-sm text-yellow-700">
This is the only time you'll be able to see the full API key. You need to configure this key in your Android gateway app to connect it to the system.
</p>
</div>
</div>
</div>
<!-- QR Code and API Key display -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- QR Code Card -->
<div class="rounded-xl bg-white shadow-sm ring-1 ring-gray-900/5 px-6 py-6">
<div class="text-center">
<h3 class="text-lg font-semibold text-gray-900 mb-4">Scan QR Code</h3>
<p class="text-sm text-gray-600 mb-6">Scan this QR code with your Android gateway app to auto-configure</p>
<div class="flex justify-center mb-4">
<div class="bg-white p-4 rounded-lg shadow-inner border-2 border-gray-200">
<%= @qr_code_data.html_safe %>
</div>
</div>
<div class="rounded-lg bg-blue-50 px-4 py-3 ring-1 ring-blue-600/10">
<p class="text-xs text-blue-700">
<i class="fas fa-info-circle"></i>
QR code contains API key, API base URL, and WebSocket URL
</p>
</div>
</div>
</div>
<!-- API Key Manual Entry Card -->
<div class="rounded-xl bg-white shadow-sm ring-1 ring-gray-900/5 px-6 py-6">
<div class="mb-6">
<div class="flex items-center justify-between mb-3">
<h3 class="text-lg font-semibold text-gray-900">Manual Configuration</h3>
<button
onclick="copyAllConfig()"
class="inline-flex items-center gap-2 rounded-lg bg-gray-600 px-3 py-1.5 text-xs font-semibold text-white shadow-sm hover:bg-gray-500 transition-all duration-200">
<i class="fas fa-copy"></i>
Copy All
</button>
</div>
<p class="text-sm text-gray-600">Or manually enter these details if QR scanning is unavailable</p>
</div>
<div class="space-y-4">
<!-- API Base URL -->
<div>
<label class="block text-xs font-medium text-gray-700 mb-1">API Base URL</label>
<div class="flex items-center gap-2">
<div class="flex-1 relative rounded-lg bg-gray-50 px-3 py-2 border border-gray-200">
<code class="text-xs font-mono text-gray-800 break-all" id="api-base-url"><%= request.base_url %></code>
</div>
<button
onclick="copyField('api-base-url')"
class="flex-shrink-0 inline-flex items-center gap-1 rounded-lg bg-blue-600 px-3 py-2 text-xs font-semibold text-white hover:bg-blue-500">
<i class="fas fa-copy"></i>
</button>
</div>
</div>
<!-- WebSocket URL -->
<div>
<label class="block text-xs font-medium text-gray-700 mb-1">WebSocket URL</label>
<div class="flex items-center gap-2">
<div class="flex-1 relative rounded-lg bg-gray-50 px-3 py-2 border border-gray-200">
<code class="text-xs font-mono text-gray-800 break-all" id="ws-url"><%= request.base_url.sub(/^http/, 'ws') %>/cable</code>
</div>
<button
onclick="copyField('ws-url')"
class="flex-shrink-0 inline-flex items-center gap-1 rounded-lg bg-blue-600 px-3 py-2 text-xs font-semibold text-white hover:bg-blue-500">
<i class="fas fa-copy"></i>
</button>
</div>
</div>
<!-- API Key -->
<div>
<label class="block text-xs font-medium text-gray-700 mb-1">API Key</label>
<div class="flex items-center gap-2">
<div class="flex-1 relative rounded-lg bg-gray-900 px-3 py-2">
<code class="text-xs font-mono text-green-400 break-all" id="api-key"><%= @raw_key %></code>
</div>
<button
onclick="copyField('api-key')"
class="flex-shrink-0 inline-flex items-center gap-1 rounded-lg bg-blue-600 px-3 py-2 text-xs font-semibold text-white hover:bg-blue-500">
<i class="fas fa-copy"></i>
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Gateway Details card -->
<div class="rounded-xl bg-white shadow-sm ring-1 ring-gray-900/5 px-6 py-6">
<h3 class="text-lg font-semibold text-gray-900 mb-4">Gateway Details</h3>
<dl class="divide-y divide-gray-100">
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Device ID</dt>
<dd class="mt-1 text-sm sm:col-span-2 sm:mt-0">
<code class="rounded bg-gray-100 px-2 py-1 text-xs font-mono text-gray-800"><%= @gateway.device_id %></code>
</dd>
</div>
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Name</dt>
<dd class="mt-1 text-sm text-gray-700 sm:col-span-2 sm:mt-0"><%= @gateway.name %></dd>
</div>
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Priority</dt>
<dd class="mt-1 text-sm sm:col-span-2 sm:mt-0">
<span class="inline-flex items-center rounded-full bg-purple-50 px-3 py-1 text-sm font-medium text-purple-700 ring-1 ring-inset ring-purple-700/10">
<%= @gateway.priority %>
</span>
</dd>
</div>
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Status</dt>
<dd class="mt-1 text-sm sm:col-span-2 sm:mt-0">
<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 (Waiting for connection)
</span>
</dd>
</div>
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Created</dt>
<dd class="mt-1 text-sm text-gray-700 sm:col-span-2 sm:mt-0">
<%= @gateway.created_at.strftime("%B %d, %Y at %l:%M %p") %>
</dd>
</div>
</dl>
</div>
<!-- Next steps card -->
<div class="rounded-lg bg-blue-50 px-6 py-6 ring-1 ring-blue-600/10">
<h3 class="text-sm font-semibold text-blue-800 mb-3">Quick Setup Guide</h3>
<div class="mb-4">
<h4 class="text-xs font-semibold text-blue-800 mb-2">Option 1: QR Code (Recommended)</h4>
<ol class="list-decimal list-inside space-y-1.5 text-xs text-blue-700 ml-2">
<li>Install the Android SMS Gateway app on your device</li>
<li>Open the app and look for "Scan QR Code" option</li>
<li>Scan the QR code above - configuration will be applied automatically</li>
<li>Start the gateway service in the app</li>
</ol>
</div>
<div>
<h4 class="text-xs font-semibold text-blue-800 mb-2">Option 2: Manual Entry</h4>
<ol class="list-decimal list-inside space-y-1.5 text-xs text-blue-700 ml-2">
<li>Install the Android SMS Gateway app on your device</li>
<li>Open the app and navigate to Settings</li>
<li>Copy and paste each field from the "Manual Configuration" section above</li>
<li>Save the configuration and start the gateway service</li>
</ol>
</div>
<div class="mt-4 pt-4 border-t border-blue-200">
<p class="text-xs text-blue-700">
<i class="fas fa-info-circle"></i>
The gateway will appear as <span class="font-semibold">"Online"</span> once it successfully connects to the server.
</p>
</div>
</div>
<script>
function copyField(elementId) {
const element = document.getElementById(elementId);
const text = element.textContent;
navigator.clipboard.writeText(text).then(function() {
const button = event.target.closest('button');
const originalHTML = button.innerHTML;
button.innerHTML = '<i class="fas fa-check"></i>';
button.classList.add('bg-green-600', 'hover:bg-green-500');
button.classList.remove('bg-blue-600', 'hover:bg-blue-500');
setTimeout(function() {
button.innerHTML = originalHTML;
button.classList.remove('bg-green-600', 'hover:bg-green-500');
button.classList.add('bg-blue-600', 'hover:bg-blue-500');
}, 2000);
}, function(err) {
alert('Failed to copy: ' + err);
});
}
function copyAllConfig() {
const apiBaseUrl = document.getElementById('api-base-url').textContent;
const wsUrl = document.getElementById('ws-url').textContent;
const apiKey = document.getElementById('api-key').textContent;
const configText = `API Base URL: ${apiBaseUrl}\nWebSocket URL: ${wsUrl}\nAPI Key: ${apiKey}`;
navigator.clipboard.writeText(configText).then(function() {
const button = event.target.closest('button');
const originalHTML = button.innerHTML;
button.innerHTML = '<i class="fas fa-check"></i> Copied!';
button.classList.add('bg-green-600', 'hover:bg-green-500');
button.classList.remove('bg-gray-600', 'hover:bg-gray-500');
setTimeout(function() {
button.innerHTML = originalHTML;
button.classList.remove('bg-green-600', 'hover:bg-green-500');
button.classList.add('bg-gray-600', 'hover:bg-gray-500');
}, 2000);
}, function(err) {
alert('Failed to copy: ' + err);
});
}
</script>
<% else %>
<!-- Existing gateway view -->
<!-- Page header -->
<div class="border-b border-gray-200 pb-5">
<div class="flex items-center justify-between">
<div>
<h1 class="text-3xl font-bold leading-tight tracking-tight text-gray-900"><%= @gateway.name %></h1>
<p class="mt-2 text-sm text-gray-600">Gateway device details and statistics</p>
</div>
<!-- Status indicator -->
<div>
<% if @gateway.status == "online" %>
<span class="inline-flex items-center gap-2 rounded-full bg-green-50 px-4 py-2 text-sm font-medium text-green-700 ring-2 ring-inset ring-green-700/20">
<span class="relative flex h-3 w-3">
<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-3 w-3 bg-green-500"></span>
</span>
Online
</span>
<% else %>
<span class="inline-flex items-center gap-2 rounded-full bg-red-50 px-4 py-2 text-sm font-medium text-red-700 ring-2 ring-inset ring-red-700/20">
<span class="h-3 w-3 rounded-full bg-red-500"></span>
Offline
</span>
<% end %>
</div>
</div>
</div>
<!-- Stats grid -->
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
<!-- Status card -->
<div class="relative overflow-hidden rounded-xl <%= @gateway.status == 'online' ? 'bg-green-500' : 'bg-red-500' %> px-4 py-5 shadow-sm sm:px-6">
<dt>
<div class="absolute rounded-lg bg-white/20 p-3">
<i class="fas fa-signal text-xl text-white"></i>
</div>
<p class="ml-16 truncate text-sm font-medium text-white/90">Connection Status</p>
</dt>
<dd class="ml-16 flex items-baseline">
<p class="text-2xl font-semibold text-white"><%= @gateway.status.titleize %></p>
</dd>
</div>
<!-- Active status card -->
<div class="relative overflow-hidden rounded-xl <%= @gateway.active ? 'bg-blue-500' : 'bg-gray-400' %> px-4 py-5 shadow-sm sm:px-6">
<dt>
<div class="absolute rounded-lg bg-white/20 p-3">
<i class="fas fa-power-off text-xl text-white"></i>
</div>
<p class="ml-16 truncate text-sm font-medium text-white/90">Active Status</p>
</dt>
<dd class="ml-16 flex items-baseline">
<p class="text-2xl font-semibold text-white"><%= @gateway.active ? 'Active' : 'Inactive' %></p>
</dd>
</div>
<!-- Priority card -->
<div class="relative overflow-hidden rounded-xl bg-purple-500 px-4 py-5 shadow-sm sm:px-6">
<dt>
<div class="absolute rounded-lg bg-white/20 p-3">
<i class="fas fa-sort-amount-up text-xl text-white"></i>
</div>
<p class="ml-16 truncate text-sm font-medium text-white/90">Priority Level</p>
</dt>
<dd class="ml-16 flex items-baseline">
<p class="text-2xl font-semibold text-white"><%= @gateway.priority %></p>
</dd>
</div>
<!-- Messages sent today -->
<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-arrow-up text-xl text-white"></i>
</div>
<p class="ml-16 truncate text-sm font-medium text-gray-500">Messages Sent Today</p>
</dt>
<dd class="ml-16 flex items-baseline">
<p class="text-2xl font-semibold text-gray-900"><%= @gateway.messages_sent_today %></p>
</dd>
</div>
<!-- Messages received today -->
<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-arrow-down text-xl text-white"></i>
</div>
<p class="ml-16 truncate text-sm font-medium text-gray-500">Messages Received Today</p>
</dt>
<dd class="ml-16 flex items-baseline">
<p class="text-2xl font-semibold text-gray-900"><%= @gateway.messages_received_today %></p>
</dd>
</div>
<!-- Total messages -->
<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">Total Messages</p>
</dt>
<dd class="ml-16 flex items-baseline">
<p class="text-2xl font-semibold text-gray-900"><%= @gateway.total_messages_sent + @gateway.total_messages_received %></p>
</dd>
</div>
</div>
<!-- Details card -->
<div class="rounded-xl bg-white shadow-sm ring-1 ring-gray-900/5 px-6 py-6">
<h3 class="text-lg font-semibold text-gray-900 mb-4">Gateway Details</h3>
<dl class="divide-y divide-gray-100">
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Device ID</dt>
<dd class="mt-1 text-sm sm:col-span-2 sm:mt-0">
<code class="rounded bg-gray-100 px-3 py-1.5 text-sm font-mono text-gray-800"><%= @gateway.device_id %></code>
</dd>
</div>
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Name</dt>
<dd class="mt-1 text-sm text-gray-700 sm:col-span-2 sm:mt-0"><%= @gateway.name %></dd>
</div>
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Status</dt>
<dd class="mt-1 text-sm sm:col-span-2 sm:mt-0">
<% 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 %>
</dd>
</div>
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Active</dt>
<dd class="mt-1 text-sm sm:col-span-2 sm:mt-0">
<% if @gateway.active %>
<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-check"></i> Active
</span>
<% else %>
<span class="inline-flex items-center gap-1 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"></i> Inactive
</span>
<% end %>
</dd>
</div>
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Priority</dt>
<dd class="mt-1 text-sm text-gray-700 sm:col-span-2 sm:mt-0">
<span class="inline-flex items-center rounded-full bg-purple-50 px-3 py-1 text-sm font-medium text-purple-700 ring-1 ring-inset ring-purple-700/10">
<%= @gateway.priority %>
</span>
</dd>
</div>
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Last Heartbeat</dt>
<dd class="mt-1 text-sm text-gray-700 sm:col-span-2 sm:mt-0">
<% if @gateway.last_heartbeat_at %>
<div class="flex items-center gap-2">
<i class="fas fa-heartbeat text-red-500"></i>
<span><%= @gateway.last_heartbeat_at.strftime("%B %d, %Y at %l:%M:%S %p") %></span>
<span class="text-gray-500">(<%= time_ago_in_words(@gateway.last_heartbeat_at) %> ago)</span>
</div>
<% else %>
<span class="text-gray-400 italic">Never</span>
<% end %>
</dd>
</div>
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Total Messages Sent</dt>
<dd class="mt-1 text-sm text-gray-700 sm:col-span-2 sm:mt-0">
<span class="inline-flex items-center gap-1 text-green-600 font-semibold">
<i class="fas fa-arrow-up"></i>
<%= @gateway.total_messages_sent %>
</span>
</dd>
</div>
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Total Messages Received</dt>
<dd class="mt-1 text-sm text-gray-700 sm:col-span-2 sm:mt-0">
<span class="inline-flex items-center gap-1 text-blue-600 font-semibold">
<i class="fas fa-arrow-down"></i>
<%= @gateway.total_messages_received %>
</span>
</dd>
</div>
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Created</dt>
<dd class="mt-1 text-sm text-gray-700 sm:col-span-2 sm:mt-0">
<%= @gateway.created_at.strftime("%B %d, %Y at %l:%M %p") %>
</dd>
</div>
<div class="px-4 py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium text-gray-900">Last Updated</dt>
<dd class="mt-1 text-sm text-gray-700 sm:col-span-2 sm:mt-0">
<%= @gateway.updated_at.strftime("%B %d, %Y at %l:%M %p") %>
</dd>
</div>
</dl>
<!-- Metadata section -->
<% if @gateway.metadata.present? %>
<div class="mt-6 pt-6 border-t border-gray-200">
<h4 class="text-sm font-semibold text-gray-900 mb-3">Device Metadata</h4>
<div class="rounded-lg bg-gray-900 px-4 py-4 overflow-x-auto">
<pre class="text-xs font-mono text-green-400"><%= JSON.pretty_generate(@gateway.metadata) %></pre>
</div>
</div>
<% end %>
<!-- Action buttons -->
<div class="mt-6 pt-6 border-t border-gray-200">
<div class="flex items-center gap-3">
<%= link_to test_admin_gateway_path(@gateway),
class: "inline-flex items-center gap-2 rounded-lg bg-blue-600 px-6 py-3 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 transition-all duration-200" do %>
<i class="fas fa-vial"></i>
Test Gateway
<% 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-6 py-3 text-sm 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-6 py-3 text-sm 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 Gateway
<% else %>
<i class="fas fa-check"></i>
Activate Gateway
<% end %>
<% end %>
</div>
</div>
</div>
<!-- Recent messages card -->
<div class="rounded-xl bg-white shadow-sm ring-1 ring-gray-900/5 overflow-hidden">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-semibold text-gray-900">Recent Messages</h3>
<p class="mt-1 text-sm text-gray-500">Last <%= @recent_messages.size %> messages from this gateway</p>
</div>
<% 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">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 font-medium 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.created_at.strftime("%m/%d/%y %H:%M") %>
</td>
</tr>
<% end %>
</tbody>
</table>
</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 font-medium text-gray-900">No messages yet</p>
<p class="mt-2 text-sm text-gray-500">Messages will appear here once this gateway starts processing SMS.</p>
</div>
<% end %>
</div>
<% end %>
</div>