Files
MySMSAPio/app/views/admin/gateways/test.html.erb
2025-10-22 17:22:17 +08:00

354 lines
14 KiB
Plaintext

<% if @gateway.nil? %>
<div class="rounded-lg bg-red-50 px-4 py-4 ring-1 ring-red-600/10">
<p class="text-red-800">Error: Gateway not found</p>
<%= link_to "Back to Gateways", admin_gateways_path, class: "text-red-600 underline" %>
</div>
<% else %>
<div class="space-y-6">
<!-- Back link -->
<div class="flex items-center gap-4">
<%= link_to admin_gateway_path(@gateway), 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 Gateway Details
<% end %>
</div>
<!-- Page header -->
<div class="border-b border-gray-200 pb-5">
<h1 class="text-3xl font-bold leading-tight tracking-tight text-gray-900">Test Gateway: <%= @gateway.name %></h1>
<p class="mt-2 text-sm text-gray-600">Test connection and send test SMS messages to verify gateway functionality.</p>
</div>
<!-- Gateway Status Card -->
<div class="rounded-xl bg-white shadow-sm ring-1 ring-gray-900/5 px-6 py-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold text-gray-900">Gateway Status</h3>
<button
onclick="checkConnection()"
class="inline-flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-blue-500 transition-all duration-200">
<i class="fas fa-sync-alt"></i>
Refresh Status
</button>
</div>
<div id="status-container" class="space-y-4">
<!-- Status will be loaded here -->
<div class="flex items-center justify-center py-8">
<div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
</div>
</div>
</div>
<!-- Connection Information 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">Connection Information</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">Gateway 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">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-red-50 px-2 py-1 text-xs font-medium text-red-700 ring-1 ring-inset ring-red-700/10">
<i class="fas fa-times"></i> Inactive
</span>
<% end %>
</dd>
</div>
</dl>
</div>
<!-- Send Test SMS 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">Send Test SMS</h3>
<p class="text-sm text-gray-600 mb-6">Send a test SMS message through this gateway to verify it's working correctly.</p>
<form id="test-sms-form" class="space-y-6">
<!-- Phone Number -->
<div>
<label for="phone_number" class="block text-sm font-medium text-gray-700">Phone Number</label>
<div class="mt-1 relative">
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
<i class="fas fa-phone text-gray-400"></i>
</div>
<input
type="tel"
id="phone_number"
name="phone_number"
class="block w-full pl-10 rounded-lg border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm py-3"
placeholder="+959123456789"
required>
</div>
<p class="mt-1 text-sm text-gray-500">Enter phone number with country code (e.g., +959123456789)</p>
</div>
<!-- Message Body -->
<div>
<label for="message_body" class="block text-sm font-medium text-gray-700">Message</label>
<div class="mt-1">
<textarea
id="message_body"
name="message_body"
rows="4"
class="block w-full rounded-lg border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 sm:text-sm py-3"
placeholder="This is a test message from the admin interface."
required>This is a test message from MySMSAPio admin interface. Gateway: <%= @gateway.name %></textarea>
</div>
<p class="mt-1 text-sm text-gray-500" id="char-count">160 characters remaining</p>
</div>
<!-- Result Display -->
<div id="sms-result" class="hidden">
<!-- Success/Error message will be displayed here -->
</div>
<!-- Submit Button -->
<div class="flex items-center gap-3">
<button
type="submit"
class="inline-flex justify-center 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 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-all duration-200">
<i class="fas fa-paper-plane"></i>
<span id="submit-text">Send Test SMS</span>
</button>
<button
type="button"
onclick="resetForm()"
class="inline-flex justify-center items-center gap-2 rounded-lg bg-gray-100 px-6 py-3 text-sm font-semibold text-gray-700 hover:bg-gray-200 transition-all duration-200">
<i class="fas fa-redo"></i>
Reset Form
</button>
</div>
</form>
</div>
<!-- Warning Card -->
<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 Notes</h3>
<ul class="mt-2 text-sm text-yellow-700 list-disc list-inside space-y-1">
<li>Test SMS messages will be sent to real phone numbers</li>
<li>Ensure the gateway is online and connected before testing</li>
<li>Standard SMS charges may apply to the recipient</li>
<li>Test messages are marked with metadata for identification</li>
</ul>
</div>
</div>
</div>
</div>
<script>
// Check connection on page load
document.addEventListener('DOMContentLoaded', function() {
checkConnection();
updateCharCount();
});
// Update character count
const messageBody = document.getElementById('message_body');
messageBody.addEventListener('input', updateCharCount);
function updateCharCount() {
const length = messageBody.value.length;
const remaining = 160 - length;
const charCount = document.getElementById('char-count');
if (remaining < 0) {
charCount.textContent = `${Math.abs(remaining)} characters over limit (message will be split into ${Math.ceil(length / 160)} parts)`;
charCount.classList.add('text-red-600');
charCount.classList.remove('text-gray-500');
} else {
charCount.textContent = `${remaining} characters remaining`;
charCount.classList.remove('text-red-600');
charCount.classList.add('text-gray-500');
}
}
// Check gateway connection
async function checkConnection() {
const container = document.getElementById('status-container');
container.innerHTML = '<div class="flex items-center justify-center py-8"><div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div></div>';
try {
const response = await fetch('<%= check_connection_admin_gateway_path(@gateway) %>', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': document.querySelector('[name="csrf-token"]').content
}
});
const data = await response.json();
if (data.status === 'success') {
container.innerHTML = `
<div class="rounded-lg bg-green-50 px-4 py-4 ring-1 ring-green-600/10">
<div class="flex items-start gap-3">
<div class="flex-shrink-0">
<i class="fas fa-check-circle text-green-600 text-2xl"></i>
</div>
<div class="flex-1">
<h3 class="text-sm font-semibold text-green-800">Gateway is Online</h3>
<p class="mt-1 text-sm text-green-700">
Last heartbeat: ${data.time_ago} ago
</p>
<p class="mt-1 text-xs text-green-600">
${data.last_heartbeat}
</p>
</div>
</div>
</div>
`;
} else {
container.innerHTML = `
<div class="rounded-lg bg-red-50 px-4 py-4 ring-1 ring-red-600/10">
<div class="flex items-start gap-3">
<div class="flex-shrink-0">
<i class="fas fa-times-circle text-red-600 text-2xl"></i>
</div>
<div class="flex-1">
<h3 class="text-sm font-semibold text-red-800">Gateway is Offline</h3>
<p class="mt-1 text-sm text-red-700">
${data.message}
</p>
${data.last_heartbeat ? `<p class="mt-1 text-xs text-red-600">Last seen: ${data.time_ago} ago</p>` : '<p class="mt-1 text-xs text-red-600">Never connected</p>'}
</div>
</div>
</div>
`;
}
} catch (error) {
container.innerHTML = `
<div class="rounded-lg bg-red-50 px-4 py-4 ring-1 ring-red-600/10">
<div class="flex items-start gap-3">
<div class="flex-shrink-0">
<i class="fas fa-exclamation-circle text-red-600 text-2xl"></i>
</div>
<div class="flex-1">
<h3 class="text-sm font-semibold text-red-800">Error Checking Status</h3>
<p class="mt-1 text-sm text-red-700">${error.message}</p>
</div>
</div>
</div>
`;
}
}
// Handle form submission
document.getElementById('test-sms-form').addEventListener('submit', async function(e) {
e.preventDefault();
const submitButton = e.target.querySelector('button[type="submit"]');
const submitText = document.getElementById('submit-text');
const resultDiv = document.getElementById('sms-result');
// Disable button and show loading
submitButton.disabled = true;
submitText.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Sending...';
const formData = {
phone_number: document.getElementById('phone_number').value,
message_body: document.getElementById('message_body').value
};
try {
const response = await fetch('<%= send_test_sms_admin_gateway_path(@gateway) %>', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': document.querySelector('[name="csrf-token"]').content
},
body: JSON.stringify(formData)
});
const data = await response.json();
if (data.status === 'success') {
resultDiv.className = 'rounded-lg bg-green-50 px-4 py-4 ring-1 ring-green-600/10';
resultDiv.innerHTML = `
<div class="flex items-start gap-3">
<div class="flex-shrink-0">
<i class="fas fa-check-circle text-green-600 text-xl"></i>
</div>
<div class="flex-1">
<h3 class="text-sm font-semibold text-green-800">Test SMS Sent Successfully!</h3>
<p class="mt-1 text-sm text-green-700">${data.message}</p>
<div class="mt-2 text-xs text-green-600">
<p>Message ID: <code class="bg-green-100 px-2 py-1 rounded">${data.message_id}</code></p>
<p class="mt-1">Status: <span class="font-semibold">${data.sms_status}</span></p>
</div>
</div>
</div>
`;
} else {
resultDiv.className = 'rounded-lg bg-red-50 px-4 py-4 ring-1 ring-red-600/10';
resultDiv.innerHTML = `
<div class="flex items-start gap-3">
<div class="flex-shrink-0">
<i class="fas fa-times-circle text-red-600 text-xl"></i>
</div>
<div class="flex-1">
<h3 class="text-sm font-semibold text-red-800">Failed to Send Test SMS</h3>
<p class="mt-1 text-sm text-red-700">${data.message}</p>
</div>
</div>
`;
}
resultDiv.classList.remove('hidden');
} catch (error) {
resultDiv.className = 'rounded-lg bg-red-50 px-4 py-4 ring-1 ring-red-600/10';
resultDiv.innerHTML = `
<div class="flex items-start gap-3">
<div class="flex-shrink-0">
<i class="fas fa-exclamation-circle text-red-600 text-xl"></i>
</div>
<div class="flex-1">
<h3 class="text-sm font-semibold text-red-800">Error</h3>
<p class="mt-1 text-sm text-red-700">${error.message}</p>
</div>
</div>
`;
resultDiv.classList.remove('hidden');
} finally {
// Re-enable button
submitButton.disabled = false;
submitText.innerHTML = '<i class="fas fa-paper-plane"></i> Send Test SMS';
}
});
function resetForm() {
document.getElementById('test-sms-form').reset();
document.getElementById('sms-result').classList.add('hidden');
updateCharCount();
}
</script>
<% end %>