customized_farm_planner / templates /admin_sms_logs.html
pranit144's picture
Upload 56 files
429a26d verified
{% extends "base.html" %}
{% block title %}SMS Logs - Admin Portal{% endblock %}
{% block content %}
<div class="container-fluid py-4">
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center mb-4">
<h2><i class="fas fa-sms text-success me-3"></i>SMS Logs</h2>
<div>
<a href="{{ url_for('admin_dashboard') }}" class="btn btn-outline-secondary me-2">
<i class="fas fa-arrow-left me-2"></i>Back to Dashboard
</a>
<button class="btn btn-success" onclick="sendTestSMS()">
<i class="fas fa-paper-plane me-2"></i>Send Test SMS
</button>
</div>
</div>
</div>
</div>
<!-- SMS Statistics -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card bg-primary text-white">
<div class="card-body text-center">
<h3>{{ total_sms }}</h3>
<p class="mb-0">Total SMS Sent</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-success text-white">
<div class="card-body text-center">
<h3>{{ delivered_sms }}</h3>
<p class="mb-0">Delivered</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-warning text-white">
<div class="card-body text-center">
<h3>{{ pending_sms }}</h3>
<p class="mb-0">Pending</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-danger text-white">
<div class="card-body text-center">
<h3>{{ failed_sms }}</h3>
<p class="mb-0">Failed</p>
</div>
</div>
</div>
</div>
<!-- SMS Logs Table -->
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-header bg-success text-white">
<h5 class="mb-0"><i class="fas fa-list me-2"></i>SMS History</h5>
</div>
<div class="card-body">
<!-- Filter Controls -->
<div class="row mb-3">
<div class="col-md-3">
<select class="form-select" id="statusFilter">
<option value="">All Status</option>
<option value="sent">Sent</option>
<option value="delivered">Delivered</option>
<option value="failed">Failed</option>
<option value="pending">Pending</option>
</select>
</div>
<div class="col-md-3">
<input type="date" class="form-control" id="dateFilter" placeholder="Filter by date">
</div>
<div class="col-md-4">
<input type="text" class="form-control" id="phoneFilter" placeholder="Search by phone number">
</div>
<div class="col-md-2">
<button class="btn btn-primary" onclick="applyFilters()">
<i class="fas fa-filter me-2"></i>Filter
</button>
</div>
</div>
<div class="table-responsive">
<table class="table table-striped" id="smsLogsTable">
<thead>
<tr>
<th>ID</th>
<th>Farmer</th>
<th>Phone</th>
<th>Message Type</th>
<th>Content</th>
<th>Status</th>
<th>Sent At</th>
<th>Delivered At</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for sms in sms_logs %}
<tr>
<td>{{ sms.id }}</td>
<td>{{ sms.farmer.name if sms.farmer else 'N/A' }}</td>
<td>{{ sms.phone_number }}</td>
<td>
<span class="badge bg-info">{{ sms.message_type }}</span>
</td>
<td>
<div class="text-truncate" style="max-width: 200px;" title="{{ sms.message_content }}">
{{ sms.message_content }}
</div>
</td>
<td>
{% if sms.delivery_status == 'delivered' %}
<span class="badge bg-success">Delivered</span>
{% elif sms.delivery_status == 'failed' %}
<span class="badge bg-danger">Failed</span>
{% elif sms.delivery_status == 'pending' %}
<span class="badge bg-warning">Pending</span>
{% else %}
<span class="badge bg-primary">Sent</span>
{% endif %}
</td>
<td>{{ sms.sent_at.strftime('%Y-%m-%d %H:%M') if sms.sent_at else 'N/A' }}</td>
<td>{{ sms.delivered_at.strftime('%Y-%m-%d %H:%M') if sms.delivered_at else 'N/A' }}</td>
<td>
<div class="btn-group" role="group">
<button class="btn btn-sm btn-primary" onclick="viewSMS({{ sms.id }})">
<i class="fas fa-eye"></i>
</button>
{% if sms.delivery_status in ['failed', 'pending'] %}
<button class="btn btn-sm btn-warning" onclick="retrySMS({{ sms.id }})">
<i class="fas fa-redo"></i>
</button>
{% endif %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- View SMS Modal -->
<div class="modal fade" id="viewSMSModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="fas fa-sms me-2"></i>SMS Details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body" id="smsDetailsContent">
<!-- SMS details will be loaded here -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Send Test SMS Modal -->
<div class="modal fade" id="testSMSModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><i class="fas fa-paper-plane me-2"></i>Send Test SMS</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form id="testSMSForm">
<div class="modal-body">
<div class="mb-3">
<label for="testPhone" class="form-label">Phone Number *</label>
<input type="tel" class="form-control" id="testPhone" required>
</div>
<div class="mb-3">
<label for="testMessage" class="form-label">Message *</label>
<textarea class="form-control" id="testMessage" rows="4" maxlength="160" required placeholder="Enter your test message here..."></textarea>
<div class="form-text">
<span id="charCount">0</span>/160 characters
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-success">
<i class="fas fa-paper-plane me-2"></i>Send SMS
</button>
</div>
</form>
</div>
</div>
</div>
<script>
// Initialize DataTable
$(document).ready(function() {
$('#smsLogsTable').DataTable({
order: [[0, 'desc']],
pageLength: 25,
responsive: true
});
// Character counter for test message
$('#testMessage').on('input', function() {
const length = $(this).val().length;
$('#charCount').text(length);
if (length > 160) {
$('#charCount').addClass('text-danger');
} else {
$('#charCount').removeClass('text-danger');
}
});
});
// Apply filters
function applyFilters() {
const status = $('#statusFilter').val();
const date = $('#dateFilter').val();
const phone = $('#phoneFilter').val();
const params = new URLSearchParams();
if (status) params.append('status', status);
if (date) params.append('date', date);
if (phone) params.append('phone', phone);
window.location.href = `{{ url_for('admin_sms_logs') }}?${params.toString()}`;
}
// View SMS Details
function viewSMS(smsId) {
$.ajax({
url: `/admin/sms/${smsId}`,
method: 'GET',
success: function(sms) {
const content = `
<div class="row">
<div class="col-md-6">
<h6>Message Information</h6>
<p><strong>ID:</strong> ${sms.id}</p>
<p><strong>Type:</strong> ${sms.message_type}</p>
<p><strong>Phone:</strong> ${sms.phone_number}</p>
<p><strong>Farmer:</strong> ${sms.farmer ? sms.farmer.name : 'N/A'}</p>
</div>
<div class="col-md-6">
<h6>Delivery Status</h6>
<p><strong>Status:</strong>
<span class="badge bg-${sms.delivery_status === 'delivered' ? 'success' :
sms.delivery_status === 'failed' ? 'danger' :
sms.delivery_status === 'pending' ? 'warning' : 'primary'}">
${sms.delivery_status}
</span>
</p>
<p><strong>Sent At:</strong> ${sms.sent_at ? new Date(sms.sent_at).toLocaleString() : 'N/A'}</p>
<p><strong>Delivered At:</strong> ${sms.delivered_at ? new Date(sms.delivered_at).toLocaleString() : 'N/A'}</p>
<p><strong>Error Message:</strong> ${sms.error_message || 'None'}</p>
</div>
</div>
<hr>
<h6>Message Content</h6>
<div class="bg-light p-3 rounded">
${sms.message_content}
</div>
`;
$('#smsDetailsContent').html(content);
$('#viewSMSModal').modal('show');
},
error: function() {
showToast('Error loading SMS details', 'error');
}
});
}
// Retry SMS
function retrySMS(smsId) {
if (confirm('Are you sure you want to retry sending this SMS?')) {
$.ajax({
url: `/admin/sms/${smsId}/retry`,
method: 'POST',
success: function(response) {
if (response.success) {
showToast('SMS retry initiated successfully!', 'success');
location.reload();
} else {
showToast(response.message || 'Error retrying SMS', 'error');
}
},
error: function() {
showToast('Error retrying SMS', 'error');
}
});
}
}
// Send Test SMS
function sendTestSMS() {
$('#testSMSModal').modal('show');
}
// Test SMS Form
$('#testSMSForm').on('submit', function(e) {
e.preventDefault();
const formData = {
phone_number: $('#testPhone').val(),
message: $('#testMessage').val()
};
$.ajax({
url: '/admin/send_test_sms',
method: 'POST',
contentType: 'application/json',
data: JSON.stringify(formData),
success: function(response) {
if (response.success) {
showToast('Test SMS sent successfully!', 'success');
$('#testSMSModal').modal('hide');
$('#testSMSForm')[0].reset();
$('#charCount').text('0');
setTimeout(() => location.reload(), 2000);
} else {
showToast(response.message || 'Error sending test SMS', 'error');
}
},
error: function() {
showToast('Error sending test SMS', 'error');
}
});
});
// Toast notification function
function showToast(message, type) {
const toast = document.createElement('div');
toast.className = `alert alert-${type === 'success' ? 'success' : type === 'error' ? 'danger' : 'info'} alert-dismissible fade show position-fixed`;
toast.style.top = '20px';
toast.style.right = '20px';
toast.style.zIndex = '9999';
toast.innerHTML = `
${message}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
`;
document.body.appendChild(toast);
setTimeout(() => {
toast.remove();
}, 5000);
}
</script>
{% endblock %}