PHP Classes

File: templates/admin/shoutbox.twig

Recommend this page to a friend!
  Packages of Matthew Asham   Binkterm PHP   templates/admin/shoutbox.twig   Download  
File: templates/admin/shoutbox.twig
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Binkterm PHP
Bulletin board system based on the Web
Author: By
Last change:
Date: 5 days ago
Size: 6,506 bytes
 

Contents

Class file image Download
{% extends "base.twig" %} {% block title %}{{ t('ui.admin.shoutbox.page_title') }}{% endblock %} {% block content %} <div class="container-fluid"> <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> <h1 class="h2">{{ t('ui.admin.shoutbox.heading') }}</h1> </div> <div class="card shadow"> <div class="card-body"> <div class="table-responsive"> <table class="table table-hover" id="shoutboxTable"> <thead class="table-dark"> <tr> <th>{{ t('ui.common.id', {}, locale, ['common']) }}</th> <th>{{ t('ui.admin.shoutbox.user') }}</th> <th>{{ t('ui.admin.shoutbox.message') }}</th> <th>{{ t('ui.admin.shoutbox.status') }}</th> <th>{{ t('ui.admin.shoutbox.created') }}</th> <th>{{ t('ui.admin.shoutbox.actions') }}</th> </tr> </thead> <tbody id="shoutboxTableBody"> <!-- Populated by JavaScript --> </tbody> </table> </div> </div> </div> </div> <script> function uiT(key, fallback, params = {}) { if (window.t) { return window.t(key, params, fallback); } return fallback; } function apiMessage(payload, fallback) { if (window.getApiMessage) { return window.getApiMessage(payload, fallback); } return payload && payload.message ? payload.message : fallback; } function apiError(payload, fallback) { if (window.getApiError) { return window.getApiError(payload, fallback); } if (payload && payload.error) { return String(payload.error); } return fallback; } document.addEventListener('DOMContentLoaded', function() { loadI18nNamespaces(['common', 'errors']).then(function() { loadShouts(); }); }); function loadShouts() { fetch('/admin/api/shoutbox') .then(response => response.json()) .then(data => { displayShouts(data.messages || []); }) .catch(error => { console.error('Error loading shouts:', error); showAlert(uiT('ui.admin.shoutbox.error_loading_shouts', 'Error loading shouts'), 'danger'); }); } function displayShouts(messages) { const tbody = document.getElementById('shoutboxTableBody'); tbody.innerHTML = ''; messages.forEach(msg => { const row = document.createElement('tr'); row.innerHTML = ` <td>${msg.id}</td> <td>${escapeHtml(msg.username)}</td> <td>${escapeHtml(msg.message)}</td> <td> <span class="badge bg-${msg.is_hidden ? 'secondary' : 'success'}"> ${msg.is_hidden ? uiT('ui.admin.shoutbox.hidden', 'Hidden') : uiT('ui.admin.shoutbox.visible', 'Visible')} </span> </td> <td>${new Date(msg.created_at).toLocaleString()}</td> <td> <div class="btn-group btn-group-sm" role="group"> ${msg.is_hidden ? `<button type="button" class="btn btn-outline-success" onclick="toggleShout(${msg.id}, false)" title="${uiT('ui.admin.shoutbox.unhide', 'Unhide')}"> <i class="fas fa-eye"></i> </button>` : `<button type="button" class="btn btn-outline-warning" onclick="toggleShout(${msg.id}, true)" title="${uiT('ui.admin.shoutbox.hide', 'Hide')}"> <i class="fas fa-eye-slash"></i> </button>` } <button type="button" class="btn btn-outline-danger" onclick="deleteShout(${msg.id})" title="${uiT('ui.common.delete', 'Delete')}"> <i class="fas fa-trash"></i> </button> </div> </td> `; tbody.appendChild(row); }); } function toggleShout(id, hide) { const endpoint = hide ? `/admin/api/shoutbox/${id}/hide` : `/admin/api/shoutbox/${id}/unhide`; fetch(endpoint, { method: 'POST' }) .then(response => response.json()) .then(data => { if (data.success) { const fallbackMessage = hide ? uiT('ui.admin.shoutbox.hidden_success', 'Shout hidden successfully') : uiT('ui.admin.shoutbox.unhidden_success', 'Shout unhidden successfully'); showAlert(apiMessage(data, fallbackMessage), 'success'); loadShouts(); } else { showAlert(apiError(data, uiT('ui.admin.shoutbox.failed_to_update', 'Failed to update shout')), 'danger'); } }) .catch(() => showAlert(uiT('ui.admin.shoutbox.failed_to_update', 'Failed to update shout'), 'danger')); } function deleteShout(id) { if (!confirm(uiT('ui.admin.shoutbox.confirm_delete', 'Delete this shout?'))) { return; } fetch(`/admin/api/shoutbox/${id}`, { method: 'DELETE' }) .then(response => response.json()) .then(data => { if (data.success) { showAlert(apiMessage(data, uiT('ui.admin.shoutbox.deleted_success', 'Shout deleted successfully')), 'success'); loadShouts(); } else { showAlert(apiError(data, uiT('ui.admin.shoutbox.failed_to_delete', 'Failed to delete shout')), 'danger'); } }) .catch(() => showAlert(uiT('ui.admin.shoutbox.failed_to_delete', 'Failed to delete shout'), 'danger')); } function escapeHtml(text) { const map = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;' }; return String(text).replace(/[&<>"']/g, function(m) { return map[m]; }); } function showAlert(message, type) { const alertDiv = document.createElement('div'); alertDiv.className = `alert alert-${type} alert-dismissible fade show`; alertDiv.innerHTML = ` ${message} <button type="button" class="btn-close" data-bs-dismiss="alert"></button> `; const container = document.querySelector('.container-fluid'); container.insertBefore(alertDiv, container.firstChild); setTimeout(() => { alertDiv.remove(); }, 5000); } </script> {% endblock %}