Sindbad~EG File Manager
<?php
require_once '../includes/functions.php';
// Check if user is logged in and has admin privileges
if (!isLoggedIn()) {
header('Location: ' . BASE_URL . 'login.php');
exit();
}
$user = getCurrentUser();
if (!in_array($user['role'], ['superuser', 'area_admin'])) {
header('Location: ' . BASE_URL . 'dashboard.php');
exit();
}
$db = new CopMadinaDB();
$conn = $db->getConnection();
// Handle delete action
if (isset($_POST['action']) && $_POST['action'] === 'delete' && isset($_POST['table_name'])) {
$tableName = $_POST['table_name'];
try {
// Drop the table
$conn->exec("DROP TABLE IF EXISTS `{$tableName}`");
// Update the event to remove the custom table reference
$stmt = $conn->prepare("UPDATE events SET custom_table_name = NULL WHERE custom_table_name = ?");
$stmt->execute([$tableName]);
$success = "Table '{$tableName}' has been deleted successfully.";
} catch (Exception $e) {
$error = "Error deleting table: " . $e->getMessage();
}
}
// Get all dynamic tables
$dynamicTables = [];
try {
// Get all events with custom tables
$stmt = $conn->prepare("SELECT id, title, custom_table_name FROM events WHERE custom_table_name IS NOT NULL ORDER BY created_at DESC");
$stmt->execute();
$events = $stmt->fetchAll();
foreach ($events as $event) {
$tableName = $event['custom_table_name'];
// Check if table actually exists
$checkStmt = $conn->prepare("SHOW TABLES LIKE ?");
$checkStmt->execute([$tableName]);
if ($checkStmt->rowCount() > 0) {
// Get table info
$countStmt = $conn->prepare("SELECT COUNT(*) as record_count FROM `{$tableName}`");
$countStmt->execute();
$count = $countStmt->fetch()['record_count'];
// Get table structure
$structureStmt = $conn->prepare("DESCRIBE `{$tableName}`");
$structureStmt->execute();
$structure = $structureStmt->fetchAll();
$dynamicTables[] = [
'event_id' => $event['id'],
'event_title' => $event['title'],
'table_name' => $tableName,
'record_count' => $count,
'structure' => $structure
];
}
}
} catch (Exception $e) {
$error = "Error fetching dynamic tables: " . $e->getMessage();
}
$settings = getSettings();
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dynamic Tables - <?php echo htmlspecialchars($settings['site_name'] ?? 'COP Madina'); ?></title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: {
50: '#eff6ff',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8'
}
},
animation: {
'fade-in': 'fadeIn 0.5s ease-out',
'slide-up': 'slideUp 0.6s ease-out',
'scale-in': 'scaleIn 0.3s ease-out'
},
keyframes: {
fadeIn: {
'0%': { opacity: '0', transform: 'translateY(10px)' },
'100%': { opacity: '1', transform: 'translateY(0)' }
},
slideUp: {
'0%': { opacity: '0', transform: 'translateY(20px)' },
'100%': { opacity: '1', transform: 'translateY(0)' }
},
scaleIn: {
'0%': { opacity: '0', transform: 'scale(0.95)' },
'100%': { opacity: '1', transform: 'scale(1)' }
}
}
}
}
}
</script>
</head>
<body class="bg-gradient-to-br from-slate-50 to-blue-50 min-h-screen">
<div id="app" class="flex h-screen">
<!-- Sidebar -->
<?php include 'includes/admin_sidebar.php'; ?>
<!-- Main Content -->
<div class="flex-1 flex flex-col overflow-hidden ml-72">
<!-- Header -->
<?php include 'includes/admin_header.php'; ?>
<!-- Content -->
<main class="flex-1 overflow-y-auto p-8">
<!-- Page Header -->
<div class="mb-8 animate-fade-in">
<div class="flex items-center justify-between">
<div>
<h1 class="text-3xl font-bold bg-gradient-to-r from-slate-800 to-slate-600 bg-clip-text text-transparent">
Dynamic Tables
</h1>
<p class="text-slate-600 mt-2">
Manage event-specific database tables created for custom registration forms
</p>
</div>
<div class="flex items-center space-x-3">
<div class="bg-white/70 backdrop-blur-sm rounded-xl px-4 py-2 border border-slate-200/50">
<span class="text-sm font-medium text-slate-600">Total Tables:</span>
<span class="text-lg font-bold text-slate-800 ml-2"><?php echo count($dynamicTables); ?></span>
</div>
</div>
</div>
</div>
<!-- Messages -->
<?php if (isset($success)): ?>
<div class="bg-green-50/90 backdrop-blur-sm border border-green-200 text-green-800 px-6 py-4 rounded-xl mb-6 animate-fade-in">
<div class="flex items-center">
<i class="fas fa-check-circle text-green-500 mr-3"></i>
<?php echo htmlspecialchars($success); ?>
</div>
</div>
<?php endif; ?>
<?php if (isset($error)): ?>
<div class="bg-red-50/90 backdrop-blur-sm border border-red-200 text-red-800 px-6 py-4 rounded-xl mb-6 animate-fade-in">
<div class="flex items-center">
<i class="fas fa-exclamation-circle text-red-500 mr-3"></i>
<?php echo htmlspecialchars($error); ?>
</div>
</div>
<?php endif; ?>
<!-- Dynamic Tables List -->
<div class="bg-white/70 backdrop-blur-sm rounded-2xl shadow-lg border border-slate-200/50 animate-slide-up">
<?php if (empty($dynamicTables)): ?>
<div class="p-12 text-center">
<div class="w-24 h-24 mx-auto mb-6 bg-gradient-to-br from-slate-100 to-slate-200 rounded-full flex items-center justify-center">
<i class="fas fa-table text-3xl text-slate-400"></i>
</div>
<h3 class="text-xl font-semibold text-slate-800 mb-2">No Dynamic Tables Found</h3>
<p class="text-slate-500 mb-4">Dynamic tables are created automatically when events use custom form templates.</p>
<a href="events.php" class="inline-flex items-center px-4 py-2 bg-gradient-to-r from-blue-500 to-purple-600 text-white font-medium rounded-lg hover:from-blue-600 hover:to-purple-700 transition-all duration-200">
<i class="fas fa-plus mr-2"></i>
Create Event with Custom Form
</a>
</div>
<?php else: ?>
<div class="overflow-x-auto">
<table class="w-full">
<thead class="bg-slate-50/50">
<tr>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Event</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Table Name</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Records</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Structure</th>
<th class="px-6 py-4 text-left text-xs font-medium text-slate-500 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-200/50">
<?php foreach ($dynamicTables as $index => $table): ?>
<tr class="hover:bg-slate-50/50 transition-colors animate-fade-in" style="animation-delay: <?php echo $index * 0.1; ?>s">
<td class="px-6 py-4">
<div class="flex items-center">
<div class="flex-shrink-0 h-10 w-10">
<div class="h-10 w-10 rounded-full bg-gradient-to-br from-blue-400 to-purple-500 flex items-center justify-center text-white font-medium">
<i class="fas fa-calendar-alt"></i>
</div>
</div>
<div class="ml-4">
<div class="text-sm font-medium text-slate-900">
<?php echo htmlspecialchars($table['event_title']); ?>
</div>
<div class="text-sm text-slate-500">Event ID: <?php echo $table['event_id']; ?></div>
</div>
</div>
</td>
<td class="px-6 py-4">
<code class="bg-slate-100 px-3 py-1 rounded-lg text-sm font-mono text-slate-800">
<?php echo htmlspecialchars($table['table_name']); ?>
</code>
</td>
<td class="px-6 py-4">
<span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-blue-100 text-blue-800">
<i class="fas fa-database mr-2"></i>
<?php echo number_format($table['record_count']); ?> records
</span>
</td>
<td class="px-6 py-4">
<div class="text-sm text-slate-900 mb-2">
<span class="font-medium"><?php echo count($table['structure']); ?></span> columns
</div>
<div class="flex flex-wrap gap-1">
<?php foreach (array_slice($table['structure'], 0, 3) as $column): ?>
<span class="inline-block bg-slate-200 rounded-full px-2 py-1 text-xs text-slate-700">
<?php echo htmlspecialchars($column['Field']); ?>
</span>
<?php endforeach; ?>
<?php if (count($table['structure']) > 3): ?>
<span class="inline-block bg-slate-100 rounded-full px-2 py-1 text-xs text-slate-500">
+<?php echo count($table['structure']) - 3; ?> more
</span>
<?php endif; ?>
</div>
</td>
<td class="px-6 py-4">
<div class="flex items-center space-x-3">
<button @click="viewTable('<?php echo htmlspecialchars($table['table_name']); ?>')"
class="inline-flex items-center px-3 py-1 bg-blue-100 hover:bg-blue-200 text-blue-700 text-sm font-medium rounded-lg transition-colors">
<i class="fas fa-eye mr-1"></i>
View
</button>
<button @click="confirmDelete('<?php echo htmlspecialchars($table['table_name']); ?>', '<?php echo htmlspecialchars($table['event_title']); ?>')"
class="inline-flex items-center px-3 py-1 bg-red-100 hover:bg-red-200 text-red-700 text-sm font-medium rounded-lg transition-colors">
<i class="fas fa-trash mr-1"></i>
Delete
</button>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</main>
</div>
</div>
<!-- Delete Confirmation Modal -->
<div v-show="showDeleteModal" class="fixed inset-0 bg-black/50 backdrop-blur-sm z-50 flex items-center justify-center p-4">
<div class="bg-white rounded-2xl shadow-2xl max-w-md w-full animate-scale-in">
<div class="p-6">
<div class="flex items-center mb-4">
<div class="w-12 h-12 bg-red-100 rounded-full flex items-center justify-center mr-4">
<i class="fas fa-exclamation-triangle text-red-600 text-xl"></i>
</div>
<h3 class="text-lg font-semibold text-slate-900">Confirm Delete</h3>
</div>
<p class="text-slate-600 mb-6">
Are you sure you want to delete the dynamic table for event "<strong>{{ eventToDelete }}</strong>"?
This action cannot be undone and all data in the table will be lost.
</p>
<div class="flex justify-end space-x-3">
<button @click="closeDeleteModal()"
class="px-4 py-2 bg-slate-200 hover:bg-slate-300 text-slate-800 font-medium rounded-lg transition-colors">
Cancel
</button>
<button @click="submitDelete"
class="px-4 py-2 bg-red-600 hover:bg-red-700 text-white font-medium rounded-lg transition-colors">
Delete Table
</button>
</div>
</div>
</div>
</div>
<script>
const { createApp } = Vue;
createApp({
data() {
return {
showDeleteModal: false,
tableToDelete: '',
eventToDelete: ''
}
},
methods: {
confirmDelete(tableName, eventTitle) {
this.tableToDelete = tableName;
this.eventToDelete = eventTitle;
this.showDeleteModal = true;
},
closeDeleteModal() {
this.showDeleteModal = false;
this.tableToDelete = '';
this.eventToDelete = '';
},
submitDelete() {
// Create and submit form programmatically
const form = document.createElement('form');
form.method = 'POST';
form.style.display = 'none';
const actionInput = document.createElement('input');
actionInput.type = 'hidden';
actionInput.name = 'action';
actionInput.value = 'delete';
const tableInput = document.createElement('input');
tableInput.type = 'hidden';
tableInput.name = 'table_name';
tableInput.value = this.tableToDelete;
form.appendChild(actionInput);
form.appendChild(tableInput);
document.body.appendChild(form);
this.closeDeleteModal();
form.submit();
},
viewTable(tableName) {
// For now, just show an alert. In a full implementation,
// you might open a modal or navigate to a detailed view
alert('Viewing table: ' + tableName + '\n\nThis feature can be extended to show table contents in a modal or separate page.');
}
}
}).mount('#app');
</script>
</body>
</html>
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists