Sindbad~EG File Manager
<?php
require_once '../config/config.php';
// Check if user is logged in and has admin or superuser role
if (!isLoggedIn() || (!hasRole('admin') && !hasRole('superuser'))) {
redirect('login.php');
}
$db = new Database();
$conn = $db->getConnection();
$success_message = '';
$error_message = '';
// Handle form submissions
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (!validateCSRFToken($_POST['csrf_token'] ?? '')) {
$error_message = 'Invalid security token. Please try again.';
} else {
$action = $_POST['action'] ?? '';
if ($action === 'update_general') {
$site_title = sanitizeInput($_POST['site_title'] ?? '');
$footer_title = sanitizeInput($_POST['footer_title'] ?? '');
$maintenance_mode = isset($_POST['maintenance_mode']) ? '1' : '0';
$timezone = $_POST['timezone'] ?? 'UTC';
try {
$settings = [
'site_title' => $site_title,
'footer_title' => $footer_title,
'maintenance_mode' => $maintenance_mode,
'timezone' => $timezone,
'theme_primary_color' => sanitizeInput($_POST['theme_primary_color'] ?? '#3B82F6'),
'theme_secondary_color' => sanitizeInput($_POST['theme_secondary_color'] ?? '#F59E0B')
];
// Handle logo upload
if (isset($_FILES['site_logo']) && $_FILES['site_logo']['error'] === UPLOAD_ERR_OK) {
$upload_result = handleLogoUpload($_FILES['site_logo']);
if ($upload_result['success']) {
$settings['site_logo'] = $upload_result['filename'];
logActivity($_SESSION['user_id'], 'update_settings', 'Uploaded new site logo: ' . $upload_result['filename']);
} else {
$error_message = $upload_result['error'];
}
}
if (empty($error_message)) {
foreach ($settings as $key => $value) {
$query = "UPDATE settings SET setting_value = ?, updated_by = ?, updated_at = NOW()
WHERE setting_key = ?";
$stmt = $conn->prepare($query);
$stmt->execute([$value, $_SESSION['user_id'], $key]);
}
logActivity($_SESSION['user_id'], 'update_settings', 'Updated general settings');
$success_message = 'General settings updated successfully.';
}
} catch (Exception $e) {
$error_message = 'An error occurred while updating settings: ' . $e->getMessage();
}
} elseif ($action === 'update_notifications') {
$email_notifications = isset($_POST['email_notifications']) ? '1' : '0';
$sms_notifications = isset($_POST['sms_notifications']) ? '1' : '0';
try {
$settings = [
'email_notifications' => $email_notifications,
'sms_notifications' => $sms_notifications
];
foreach ($settings as $key => $value) {
$query = "UPDATE settings SET setting_value = ?, updated_by = ?, updated_at = NOW()
WHERE setting_key = ?";
$stmt = $conn->prepare($query);
$stmt->execute([$value, $_SESSION['user_id'], $key]);
}
logActivity($_SESSION['user_id'], 'update_settings', 'Updated notification settings');
$success_message = 'Notification settings updated successfully.';
} catch (Exception $e) {
$error_message = 'An error occurred while updating notification settings.';
}
} elseif ($action === 'update_backup') {
$backup_frequency = $_POST['backup_frequency'] ?? 'weekly';
try {
$query = "UPDATE settings SET setting_value = ?, updated_by = ?, updated_at = NOW()
WHERE setting_key = 'backup_frequency'";
$stmt = $conn->prepare($query);
$stmt->execute([$backup_frequency, $_SESSION['user_id']]);
logActivity($_SESSION['user_id'], 'update_settings', 'Updated backup settings');
$success_message = 'Backup settings updated successfully.';
} catch (Exception $e) {
$error_message = 'An error occurred while updating backup settings.';
}
} elseif ($action === 'create_backup') {
try {
// Create backup filename
$filename = 'backup_' . date('Y-m-d_H-i-s') . '.sql';
$filepath = '../backups/' . $filename;
// Create backups directory if it doesn't exist
if (!is_dir('../backups')) {
mkdir('../backups', 0755, true);
}
// Generate backup SQL
$backup_sql = generateDatabaseBackup($conn);
file_put_contents($filepath, $backup_sql);
// Record backup in database
$query = "INSERT INTO backups (filename, file_size, backup_type, created_by)
VALUES (?, ?, 'manual', ?)";
$stmt = $conn->prepare($query);
$stmt->execute([$filename, filesize($filepath), $_SESSION['user_id']]);
logActivity($_SESSION['user_id'], 'create_backup', "Created manual backup: $filename");
$success_message = 'Database backup created successfully.';
} catch (Exception $e) {
$error_message = 'An error occurred while creating the backup.';
}
}
}
}
// Get current settings
$query = "SELECT setting_key, setting_value FROM settings";
$stmt = $conn->prepare($query);
$stmt->execute();
$current_settings = [];
while ($row = $stmt->fetch()) {
$current_settings[$row['setting_key']] = $row['setting_value'];
}
// Get recent backups
$query = "SELECT * FROM backups ORDER BY created_at DESC LIMIT 10";
$stmt = $conn->prepare($query);
$stmt->execute();
$recent_backups = $stmt->fetchAll();
// Get system statistics
$stats = [];
// Database size
$query = "SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 1) AS db_size
FROM information_schema.tables
WHERE table_schema = DATABASE()";
$stmt = $conn->prepare($query);
$stmt->execute();
$stats['db_size'] = $stmt->fetch()['db_size'] ?? 0;
// Total records
$query = "SELECT
(SELECT COUNT(*) FROM attendance_records) as attendance_count,
(SELECT COUNT(*) FROM programs) as program_count,
(SELECT COUNT(*) FROM users) as user_count,
(SELECT COUNT(*) FROM locations) as location_count";
$stmt = $conn->prepare($query);
$stmt->execute();
$stats = array_merge($stats, $stmt->fetch());
function generateDatabaseBackup($conn) {
$backup = "-- Church Attendance System Database Backup\n";
$backup .= "-- Generated on: " . date('Y-m-d H:i:s') . "\n\n";
// Get all tables
$query = "SHOW TABLES";
$stmt = $conn->prepare($query);
$stmt->execute();
$tables = $stmt->fetchAll(PDO::FETCH_COLUMN);
foreach ($tables as $table) {
$backup .= "\n-- Table: $table\n";
$backup .= "DROP TABLE IF EXISTS `$table`;\n";
// Get CREATE TABLE statement
$query = "SHOW CREATE TABLE `$table`";
$stmt = $conn->prepare($query);
$stmt->execute();
$create = $stmt->fetch();
$backup .= $create['Create Table'] . ";\n\n";
// Get table data
$query = "SELECT * FROM `$table`";
$stmt = $conn->prepare($query);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (!empty($rows)) {
$columns = array_keys($rows[0]);
$backup .= "INSERT INTO `$table` (`" . implode('`, `', $columns) . "`) VALUES\n";
$values = [];
foreach ($rows as $row) {
$escaped = array_map(function($value) use ($conn) {
return $conn->quote($value);
}, array_values($row));
$values[] = "(" . implode(', ', $escaped) . ")";
}
$backup .= implode(",\n", $values) . ";\n\n";
}
}
return $backup;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Settings - Admin Panel</title>
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#3B82F6',
secondary: '#F59E0B',
accent: '#6B7280'
}
}
}
}
</script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
.gradient-bg {
background: linear-gradient(135deg, #3B82F6 0%, #F59E0B 50%, #6B7280 100%);
}
</style>
</head>
<body class="bg-gray-50">
<!-- Include Sidebar -->
<?php include 'includes/sidebar.php'; ?>
<!-- Main Content -->
<div class="md:ml-64">
<!-- Header -->
<header class="bg-white shadow-sm border-b">
<div class="px-6 py-4">
<h1 class="text-2xl font-bold text-gray-900">System Settings</h1>
</div>
</header>
<!-- Content -->
<main class="p-6">
<!-- Success/Error Messages -->
<?php if ($success_message): ?>
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded mb-6">
<div class="flex items-center">
<i class="fas fa-check-circle mr-2"></i>
<span><?php echo $success_message; ?></span>
</div>
</div>
<?php endif; ?>
<?php if ($error_message): ?>
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-6">
<div class="flex items-center">
<i class="fas fa-exclamation-circle mr-2"></i>
<span><?php echo $error_message; ?></span>
</div>
</div>
<?php endif; ?>
<!-- Settings Tabs -->
<div class="bg-white rounded-lg shadow">
<div class="border-b border-gray-200">
<nav class="-mb-px flex space-x-8 px-6">
<button onclick="showTab('general')" id="tab-general"
class="tab-button py-4 px-1 border-b-2 border-primary text-primary font-medium text-sm">
<i class="fas fa-cog mr-2"></i>General
</button>
<button onclick="showTab('notifications')" id="tab-notifications"
class="tab-button py-4 px-1 border-b-2 border-transparent text-gray-500 hover:text-gray-700 font-medium text-sm">
<i class="fas fa-bell mr-2"></i>Notifications
</button>
<button onclick="showTab('backup')" id="tab-backup"
class="tab-button py-4 px-1 border-b-2 border-transparent text-gray-500 hover:text-gray-700 font-medium text-sm">
<i class="fas fa-database mr-2"></i>Backup & Restore
</button>
<button onclick="showTab('system')" id="tab-system"
class="tab-button py-4 px-1 border-b-2 border-transparent text-gray-500 hover:text-gray-700 font-medium text-sm">
<i class="fas fa-info-circle mr-2"></i>System Info
</button>
</nav>
</div>
<!-- General Settings Tab -->
<div id="content-general" class="tab-content p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-4">General Settings</h3>
<form method="POST" enctype="multipart/form-data" class="space-y-6">
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
<input type="hidden" name="action" value="update_general">
<div>
<label for="site_title" class="block text-sm font-medium text-gray-700 mb-2">
Site Title
</label>
<input type="text" id="site_title" name="site_title"
value="<?php echo htmlspecialchars($current_settings['site_title'] ?? ''); ?>"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary">
</div>
<div>
<label for="footer_title" class="block text-sm font-medium text-gray-700 mb-2">
Footer Title
</label>
<input type="text" id="footer_title" name="footer_title"
value="<?php echo htmlspecialchars($current_settings['footer_title'] ?? ''); ?>"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary">
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label for="theme_primary_color" class="block text-sm font-medium text-gray-700 mb-2">
Primary Color
</label>
<div class="flex items-center space-x-2">
<input type="color" id="theme_primary_color" name="theme_primary_color"
value="<?php echo htmlspecialchars($current_settings['theme_primary_color'] ?? '#3B82F6'); ?>"
class="h-10 w-16 border border-gray-300 rounded-md cursor-pointer">
<input type="text" name="theme_primary_color_text"
value="<?php echo htmlspecialchars($current_settings['theme_primary_color'] ?? '#3B82F6'); ?>"
class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary"
readonly>
</div>
</div>
<div>
<label for="theme_secondary_color" class="block text-sm font-medium text-gray-700 mb-2">
Secondary Color
</label>
<div class="flex items-center space-x-2">
<input type="color" id="theme_secondary_color" name="theme_secondary_color"
value="<?php echo htmlspecialchars($current_settings['theme_secondary_color'] ?? '#F59E0B'); ?>"
class="h-10 w-16 border border-gray-300 rounded-md cursor-pointer">
<input type="text" name="theme_secondary_color_text"
value="<?php echo htmlspecialchars($current_settings['theme_secondary_color'] ?? '#F59E0B'); ?>"
class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary"
readonly>
</div>
</div>
</div>
<div>
<label for="site_logo" class="block text-sm font-medium text-gray-700 mb-2">
Site Logo
</label>
<div class="flex items-center space-x-4">
<div class="flex-shrink-0">
<?php
$current_logo = $current_settings['site_logo'] ?? 'assets/images/logo.png';
if (file_exists('../' . $current_logo)):
?>
<img src="../<?php echo htmlspecialchars($current_logo); ?>"
alt="Current Logo"
class="h-16 w-16 object-contain border border-gray-300 rounded-lg bg-white p-2">
<?php else: ?>
<div class="h-16 w-16 border border-gray-300 rounded-lg bg-gray-100 flex items-center justify-center">
<i class="fas fa-image text-gray-400 text-xl"></i>
</div>
<?php endif; ?>
</div>
<div class="flex-1">
<input type="file" id="site_logo" name="site_logo"
accept="image/jpeg,image/jpg,image/png,image/gif,image/webp"
onchange="previewLogo(this)"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary">
<p class="text-xs text-gray-500 mt-1">
Upload JPEG, PNG, GIF, or WebP. Max size: 5MB. Recommended: 200x200px
</p>
</div>
</div>
</div>
<div>
<label for="timezone" class="block text-sm font-medium text-gray-700 mb-2">
Timezone
</label>
<select id="timezone" name="timezone"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary">
<option value="UTC" <?php echo ($current_settings['timezone'] ?? '') === 'UTC' ? 'selected' : ''; ?>>UTC</option>
<option value="America/New_York" <?php echo ($current_settings['timezone'] ?? '') === 'America/New_York' ? 'selected' : ''; ?>>Eastern Time</option>
<option value="America/Chicago" <?php echo ($current_settings['timezone'] ?? '') === 'America/Chicago' ? 'selected' : ''; ?>>Central Time</option>
<option value="America/Denver" <?php echo ($current_settings['timezone'] ?? '') === 'America/Denver' ? 'selected' : ''; ?>>Mountain Time</option>
<option value="America/Los_Angeles" <?php echo ($current_settings['timezone'] ?? '') === 'America/Los_Angeles' ? 'selected' : ''; ?>>Pacific Time</option>
</select>
</div>
<div class="flex items-center">
<input type="checkbox" id="maintenance_mode" name="maintenance_mode"
<?php echo ($current_settings['maintenance_mode'] ?? '0') === '1' ? 'checked' : ''; ?>
class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded">
<label for="maintenance_mode" class="ml-2 block text-sm text-gray-700">
Enable Maintenance Mode
</label>
</div>
<div class="pt-4">
<button type="submit" class="bg-primary text-white px-6 py-2 rounded-lg hover:bg-blue-700 transition duration-300">
<i class="fas fa-save mr-2"></i>
Save General Settings
</button>
</div>
</form>
</div>
<!-- Notifications Tab -->
<div id="content-notifications" class="tab-content p-6 hidden">
<h3 class="text-lg font-semibold text-gray-900 mb-4">Notification Settings</h3>
<form method="POST" class="space-y-6">
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
<input type="hidden" name="action" value="update_notifications">
<div class="flex items-center">
<input type="checkbox" id="email_notifications" name="email_notifications"
<?php echo ($current_settings['email_notifications'] ?? '1') === '1' ? 'checked' : ''; ?>
class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded">
<label for="email_notifications" class="ml-2 block text-sm text-gray-700">
Enable Email Notifications
</label>
</div>
<div class="flex items-center">
<input type="checkbox" id="sms_notifications" name="sms_notifications"
<?php echo ($current_settings['sms_notifications'] ?? '0') === '1' ? 'checked' : ''; ?>
class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded">
<label for="sms_notifications" class="ml-2 block text-sm text-gray-700">
Enable SMS Notifications
</label>
</div>
<div class="pt-4">
<button type="submit" class="bg-primary text-white px-6 py-2 rounded-lg hover:bg-blue-700 transition duration-300">
<i class="fas fa-save mr-2"></i>
Save Notification Settings
</button>
</div>
</form>
</div>
<!-- Backup & Restore Tab -->
<div id="content-backup" class="tab-content p-6 hidden">
<h3 class="text-lg font-semibold text-gray-900 mb-4">Backup & Restore</h3>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<!-- Backup Settings -->
<div>
<h4 class="font-medium text-gray-900 mb-4">Backup Settings</h4>
<form method="POST" class="space-y-4">
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
<input type="hidden" name="action" value="update_backup">
<div>
<label for="backup_frequency" class="block text-sm font-medium text-gray-700 mb-2">
Automatic Backup Frequency
</label>
<select id="backup_frequency" name="backup_frequency"
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-primary">
<option value="daily" <?php echo ($current_settings['backup_frequency'] ?? '') === 'daily' ? 'selected' : ''; ?>>Daily</option>
<option value="weekly" <?php echo ($current_settings['backup_frequency'] ?? '') === 'weekly' ? 'selected' : ''; ?>>Weekly</option>
<option value="monthly" <?php echo ($current_settings['backup_frequency'] ?? '') === 'monthly' ? 'selected' : ''; ?>>Monthly</option>
<option value="disabled" <?php echo ($current_settings['backup_frequency'] ?? '') === 'disabled' ? 'selected' : ''; ?>>Disabled</option>
</select>
</div>
<button type="submit" class="bg-primary text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition duration-300">
<i class="fas fa-save mr-2"></i>
Save Backup Settings
</button>
</form>
<!-- Manual Backup -->
<div class="mt-6 pt-6 border-t">
<h4 class="font-medium text-gray-900 mb-4">Manual Backup</h4>
<form method="POST">
<input type="hidden" name="csrf_token" value="<?php echo generateCSRFToken(); ?>">
<input type="hidden" name="action" value="create_backup">
<button type="submit" class="bg-green-600 text-white px-4 py-2 rounded-lg hover:bg-green-700 transition duration-300">
<i class="fas fa-download mr-2"></i>
Create Backup Now
</button>
</form>
</div>
</div>
<!-- Recent Backups -->
<div>
<h4 class="font-medium text-gray-900 mb-4">Recent Backups</h4>
<?php if (empty($recent_backups)): ?>
<p class="text-gray-500 text-sm">No backups found.</p>
<?php else: ?>
<div class="space-y-2">
<?php foreach ($recent_backups as $backup): ?>
<div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
<div>
<p class="text-sm font-medium text-gray-900"><?php echo htmlspecialchars($backup['filename']); ?></p>
<p class="text-xs text-gray-500">
<?php echo date('M j, Y g:i A', strtotime($backup['created_at'])); ?> •
<?php echo number_format($backup['file_size'] / 1024, 1); ?> KB
</p>
</div>
<div class="flex space-x-2">
<a href="../backups/<?php echo htmlspecialchars($backup['filename']); ?>"
class="text-primary hover:text-blue-700 text-sm">
<i class="fas fa-download"></i>
</a>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</div>
</div>
<!-- System Info Tab -->
<div id="content-system" class="tab-content p-6 hidden">
<h3 class="text-lg font-semibold text-gray-900 mb-4">System Information</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- System Stats -->
<div class="bg-gray-50 rounded-lg p-4">
<h4 class="font-medium text-gray-900 mb-3">Database Statistics</h4>
<div class="space-y-2">
<div class="flex justify-between">
<span class="text-sm text-gray-600">Database Size:</span>
<span class="text-sm font-medium"><?php echo $stats['db_size']; ?> MB</span>
</div>
<div class="flex justify-between">
<span class="text-sm text-gray-600">Attendance Records:</span>
<span class="text-sm font-medium"><?php echo number_format($stats['attendance_count']); ?></span>
</div>
<div class="flex justify-between">
<span class="text-sm text-gray-600">Programs:</span>
<span class="text-sm font-medium"><?php echo number_format($stats['program_count']); ?></span>
</div>
<div class="flex justify-between">
<span class="text-sm text-gray-600">Users:</span>
<span class="text-sm font-medium"><?php echo number_format($stats['user_count']); ?></span>
</div>
<div class="flex justify-between">
<span class="text-sm text-gray-600">Locations:</span>
<span class="text-sm font-medium"><?php echo number_format($stats['location_count']); ?></span>
</div>
</div>
</div>
<!-- Server Info -->
<div class="bg-gray-50 rounded-lg p-4">
<h4 class="font-medium text-gray-900 mb-3">Server Information</h4>
<div class="space-y-2">
<div class="flex justify-between">
<span class="text-sm text-gray-600">PHP Version:</span>
<span class="text-sm font-medium"><?php echo PHP_VERSION; ?></span>
</div>
<div class="flex justify-between">
<span class="text-sm text-gray-600">MySQL Version:</span>
<span class="text-sm font-medium"><?php echo $conn->getAttribute(PDO::ATTR_SERVER_VERSION); ?></span>
</div>
<div class="flex justify-between">
<span class="text-sm text-gray-600">Server Software:</span>
<span class="text-sm font-medium"><?php echo $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown'; ?></span>
</div>
<div class="flex justify-between">
<span class="text-sm text-gray-600">System Version:</span>
<span class="text-sm font-medium">1.0</span>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
<script>
function showTab(tabName) {
// Hide all tab contents
document.querySelectorAll('.tab-content').forEach(content => {
content.classList.add('hidden');
});
// Remove active class from all tab buttons
document.querySelectorAll('.tab-button').forEach(button => {
button.classList.remove('border-primary', 'text-primary');
button.classList.add('border-transparent', 'text-gray-500');
});
// Show selected tab content
document.getElementById(`content-${tabName}`).classList.remove('hidden');
// Add active class to selected tab button
const activeButton = document.getElementById(`tab-${tabName}`);
activeButton.classList.remove('border-transparent', 'text-gray-500');
activeButton.classList.add('border-primary', 'text-primary');
}
function previewLogo(input) {
if (input.files && input.files[0]) {
const file = input.files[0];
// Validate file type
const allowedTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/webp'];
if (!allowedTypes.includes(file.type)) {
alert('Invalid file type. Please upload a JPEG, PNG, GIF, or WebP image.');
input.value = '';
return;
}
// Validate file size (5MB)
if (file.size > 5 * 1024 * 1024) {
alert('File size too large. Maximum size is 5MB.');
input.value = '';
return;
}
const reader = new FileReader();
reader.onload = function(e) {
// Find the logo preview container
const logoContainer = input.closest('.flex').querySelector('.flex-shrink-0');
// Update the preview image
const existingImg = logoContainer.querySelector('img');
const existingDiv = logoContainer.querySelector('div');
if (existingImg) {
existingImg.src = e.target.result;
} else if (existingDiv) {
// Replace the placeholder div with an image
logoContainer.innerHTML = `
<img src="${e.target.result}"
alt="Logo Preview"
class="h-16 w-16 object-contain border border-gray-300 rounded-lg bg-white p-2">
`;
}
};
reader.readAsDataURL(file);
}
}
// Color picker synchronization
document.addEventListener('DOMContentLoaded', function() {
// Primary color sync
const primaryColorPicker = document.getElementById('theme_primary_color');
const primaryColorText = document.querySelector('input[name="theme_primary_color_text"]');
if (primaryColorPicker && primaryColorText) {
primaryColorPicker.addEventListener('input', function() {
primaryColorText.value = this.value;
});
}
// Secondary color sync
const secondaryColorPicker = document.getElementById('theme_secondary_color');
const secondaryColorText = document.querySelector('input[name="theme_secondary_color_text"]');
if (secondaryColorPicker && secondaryColorText) {
secondaryColorPicker.addEventListener('input', function() {
secondaryColorText.value = this.value;
});
}
});
</script>
</body>
</html>
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists