PNG IHDR x sBIT|d pHYs + tEXtSoftware www.inkscape.org< ,tEXtComment
<?php
// 1. Enable Error Reporting (keep for dev; remove in production)
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
session_start();
// 2. Check Login
if (!isset($_SESSION['admin_logged_in'])) {
header("Location: login.php");
exit;
}
// 3. Connect Database
$configPath = __DIR__ . '/../config/database.php';
if (!file_exists($configPath)) {
die("Error: Config file missing.");
}
require_once $configPath;
try {
$database = new Database();
$db = $database->getConnection();
} catch (Exception $e) {
die("Database Error: " . $e->getMessage());
}
$message = '';
$error = '';
// 4. Handle Form Submission
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// --- A. Handle Password Update ---
if (isset($_POST['update_password'])) {
$new_pass = $_POST['new_password'] ?? '';
$confirm_pass = $_POST['confirm_password'] ?? '';
if (!empty($new_pass) && $new_pass === $confirm_pass) {
try {
$hashed = password_hash($new_pass, PASSWORD_DEFAULT);
$admin_id = $_SESSION['admin_id'] ?? null;
if ($admin_id) {
$stmt = $db->prepare("UPDATE users SET password = :pwd WHERE id = :id");
$stmt->execute([':pwd' => $hashed, ':id' => $admin_id]);
} else {
// fallback to default admin email if session id missing
$stmt = $db->prepare("UPDATE users SET password = :pwd WHERE email = 'admin@swift.com'");
$stmt->execute([':pwd' => $hashed]);
}
$message = "Password updated successfully!";
} catch (Exception $e) {
$error = "Error updating password: " . $e->getMessage();
}
} else {
$error = "Passwords do not match or are empty.";
}
}
// --- B. Handle General Settings Update ---
else {
// Allowed keys to save
$keys = [
'site_name', 'contact_email', 'contact_phone', 'address',
'bank_details', 'crypto_wallet', 'eth_wallet', 'btc_wallet', 'credit_card_link'
];
try {
$db->beginTransaction();
foreach ($keys as $key) {
if (isset($_POST[$key])) {
// Normalize value (trim)
$val = trim($_POST[$key]);
// Check if setting exists
$check = $db->prepare("SELECT id FROM settings WHERE setting_key = :k LIMIT 1");
$check->execute([':k' => $key]);
if ($check->rowCount() > 0) {
$stmt = $db->prepare("UPDATE settings SET setting_value = :v WHERE setting_key = :k");
$stmt->execute([':v' => $val, ':k' => $key]);
} else {
$stmt = $db->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (:k, :v)");
$stmt->execute([':k' => $key, ':v' => $val]);
}
}
}
$db->commit();
$message = "Settings updated successfully!";
} catch (Exception $e) {
if ($db->inTransaction()) $db->rollBack();
$error = "Error updating settings: " . $e->getMessage();
}
}
}
// 5. Fetch Current Settings
$settings = [];
try {
$query = "SELECT setting_key, setting_value FROM settings";
$stmt = $db->prepare($query);
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$settings[$row['setting_key']] = $row['setting_value'];
}
} catch (Exception $e) {
// Keep silent to avoid exposing DB errors in UI; $settings may be empty.
}
function getVal($key, $data) {
return htmlspecialchars($data[$key] ?? '', ENT_QUOTES, 'UTF-8');
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<title>System Settings | titanwaveexpressservice Admin</title>
<!-- TailwindCSS (CDN) -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Lucide Icons -->
<script src="https://unpkg.com/lucide@latest"></script>
<!-- Alpine.js -->
<script src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
<style>
[x-cloak] { display: none !important; }
/* Inline Tailwind helper classes for browsers without @apply support */
.input { width:100%; padding:0.75rem; border:1px solid #e5e7eb; border-radius:0.5rem; outline:none; }
.input:focus { box-shadow: 0 0 0 4px rgba(59,130,246,0.15); }
.textarea { width:100%; padding:0.75rem; border:1px solid #e5e7eb; border-radius:0.5rem; outline:none; font-family:ui-monospace, SFMono-Regular, Menlo, Monaco, "Roboto Mono", "Courier New", monospace; background:#f9fafb; }
.form-label { display:block; font-size:0.6875rem; font-weight:700; color:#6b7280; text-transform:uppercase; margin-bottom:0.25rem; }
.btn-primary { background:#2563eb; color:white; padding:0.75rem 1.5rem; border-radius:0.5rem; font-weight:700; display:inline-flex; align-items:center; gap:0.5rem; }
.btn-primary:hover { background:#1e40af; }
.btn-dark { background:#111827; color:white; padding:0.6rem 1rem; border-radius:0.5rem; font-weight:700; display:inline-flex; align-items:center; gap:0.5rem; }
.btn-dark:hover { background:#000; }
</style>
</head>
<body class="bg-gray-100 min-h-screen" x-data="{ sidebarOpen: false }">
<!-- Mobile overlay -->
<div x-show="sidebarOpen" @click="sidebarOpen = false" x-transition.opacity class="fixed inset-0 z-20 bg-black/50 md:hidden" x-cloak></div>
<!-- Sidebar -->
<aside :class="sidebarOpen ? 'translate-x-0' : '-translate-x-full'" class="fixed inset-y-0 left-0 z-30 w-64 bg-gray-900 text-white transition-transform duration-300 ease-in-out md:relative md:translate-x-0 flex flex-col">
<div class="p-5 border-b border-gray-800 flex items-center justify-between">
<span class="text-lg font-bold">titanwaveexpressservice <span class="text-blue-500">Admin</span></span>
<button @click="sidebarOpen = false" class="md:hidden">
<i data-lucide="x" class="w-6 h-6 text-gray-300"></i>
</button>
</div>
<nav class="flex-1 p-3 overflow-y-auto space-y-1">
<a href="index.php" class="flex items-center gap-3 p-3 rounded-lg text-gray-400 hover:bg-gray-800 hover:text-white">
<i data-lucide="layout-dashboard" class="w-5 h-5"></i> Dashboard
</a>
<a href="shipments.php" class="flex items-center gap-3 p-3 rounded-lg text-gray-400 hover:bg-gray-800 hover:text-white">
<i data-lucide="package" class="w-5 h-5"></i> Shipments
</a>
<a href="settings.php" class="flex items-center gap-3 p-3 rounded-lg bg-blue-600 text-white shadow-md">
<i data-lucide="settings" class="w-5 h-5"></i> Settings
</a>
</nav>
<div class="p-4 border-t border-gray-800">
<a href="logout.php" class="flex items-center gap-2 text-gray-400 hover:text-white text-sm">
<i data-lucide="log-out" class="w-4 h-4"></i> Logout
</a>
</div>
</aside>
<!-- Main content area -->
<main class="md:ml-64">
<!-- Mobile header -->
<header class="md:hidden bg-white border-b p-4 flex items-center gap-3">
<button @click="sidebarOpen = true">
<i data-lucide="menu" class="w-6 h-6 text-gray-700"></i>
</button>
<span class="font-bold text-gray-900 text-lg">Settings</span>
</header>
<div class="p-4 md:p-8 space-y-8">
<!-- Desktop heading -->
<div class="hidden md:block">
<h1 class="text-2xl font-bold text-gray-900">System Settings</h1>
<p class="text-sm text-gray-500 mt-1">Manage global configuration and security</p>
</div>
<!-- Alerts -->
<?php if($message): ?>
<div class="bg-green-50 border border-green-200 text-green-700 p-4 rounded-lg flex items-center gap-2">
<i data-lucide="check-circle" class="w-5 h-5"></i> <?php echo $message; ?>
</div>
<?php endif; ?>
<?php if($error): ?>
<div class="bg-red-50 border border-red-200 text-red-700 p-4 rounded-lg flex items-center gap-2">
<i data-lucide="alert-triangle" class="w-5 h-5"></i> <?php echo $error; ?>
</div>
<?php endif; ?>
<div class="max-w-4xl space-y-8 mx-auto">
<!-- MAIN SETTINGS FORM -->
<form method="POST" class="space-y-8">
<!-- 1. General Information -->
<section class="bg-white p-6 rounded-xl shadow-sm border border-gray-200">
<h2 class="text-lg font-bold text-gray-900 mb-6 border-b pb-2 flex items-center gap-2">
<i data-lucide="globe" class="w-5 h-5 text-blue-600"></i> General Information
</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label class="form-label">Site Name</label>
<input type="text" name="site_name" value="<?php echo getVal('site_name', $settings); ?>" class="input">
</div>
<div>
<label class="form-label">Office Address</label>
<input type="text" name="address" value="<?php echo getVal('address', $settings); ?>" class="input">
</div>
<div>
<label class="form-label">Support Email</label>
<input type="email" name="contact_email" value="<?php echo getVal('contact_email', $settings); ?>" class="input">
</div>
<div>
<label class="form-label">Support Phone</label>
<input type="text" name="contact_phone" value="<?php echo getVal('contact_phone', $settings); ?>" class="input">
</div>
</div>
</section>
<!-- 2. Payment Gateways -->
<!--<section class="bg-white p-6 rounded-xl shadow-sm border border-gray-200">-->
<!-- <h2 class="text-lg font-bold text-gray-900 mb-6 border-b pb-2 flex items-center gap-2">-->
<!-- <i data-lucide="credit-card" class="w-5 h-5 text-green-600"></i> Payment Configuration-->
<!-- </h2>-->
<!-- <div class="space-y-6">-->
<!-- Bank -->
<!-- <div>-->
<!-- <label class="form-label">Bank Transfer Details</label>-->
<!-- <textarea name="bank_details" rows="4" class="textarea" placeholder="Bank Name: ... Account No: ..."><?php echo getVal('bank_details', $settings); ?></textarea>-->
<!-- </div>-->
<!-- Crypto: USDT -->
<!-- <div>-->
<!-- <label class="form-label">USDT Wallet Address (TRC20)</label>-->
<!-- <div class="relative">-->
<!-- <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">-->
<!-- <span class="text-green-500 font-bold text-xs">T</span>-->
<!-- </div>-->
<!-- <input type="text" name="crypto_wallet" value="<?php echo getVal('crypto_wallet', $settings); ?>" class="input" style="padding-left:2.25rem;">-->
<!-- </div>-->
<!-- </div>-->
<!-- Crypto: BTC -->
<!-- <div>-->
<!-- <label class="form-label">Bitcoin Wallet Address (BTC)</label>-->
<!-- <div class="relative">-->
<!-- <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">-->
<!-- <span class="text-orange-500 font-bold text-xs">B</span>-->
<!-- </div>-->
<!-- <input type="text" name="btc_wallet" value="<?php echo getVal('btc_wallet', $settings); ?>" class="input" style="padding-left:2.25rem;">-->
<!-- </div>-->
<!-- </div>-->
<!-- Crypto: ETH -->
<!-- <div>-->
<!-- <label class="form-label">Ethereum Wallet Address (ETH)</label>-->
<!-- <div class="relative">-->
<!-- <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">-->
<!-- <span class="text-purple-500 font-bold text-xs">Ξ</span>-->
<!-- </div>-->
<!-- <input type="text" name="eth_wallet" value="<?php echo getVal('eth_wallet', $settings); ?>" class="input" style="padding-left:2.25rem;">-->
<!-- </div>-->
<!-- </div>-->
<!-- Credit Card Link -->
<!-- <div>-->
<!-- <label class="form-label">Credit Card Payment Link (Stripe/PayPal)</label>-->
<!-- <div class="relative">-->
<!-- <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">-->
<!-- <i data-lucide="link" class="w-4 h-4 text-gray-400"></i>-->
<!-- </div>-->
<!-- <input type="text" name="credit_card_link" value="<?php echo getVal('credit_card_link', $settings); ?>" class="input" style="padding-left:2.5rem;" placeholder="https://buy.stripe.com/...">-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<!--</section>-->
<!-- Save Button -->
<div class="flex justify-end">
<button type="submit" class="btn-primary">
<i data-lucide="save" class="w-5 h-5"></i> Save Settings
</button>
</div>
</form>
<!-- 3. Security Settings (Password update) -->
<form method="POST" class="bg-white p-6 rounded-xl shadow-sm border border-red-100">
<h2 class="text-lg font-bold text-gray-900 mb-6 border-b pb-2 flex items-center gap-2">
<i data-lucide="shield-alert" class="w-5 h-5 text-red-600"></i> Security Settings
</h2>
<input type="hidden" name="update_password" value="1">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label class="form-label">New Password</label>
<input type="password" name="new_password" required class="input">
</div>
<div>
<label class="form-label">Confirm Password</label>
<input type="password" name="confirm_password" required class="input">
</div>
</div>
<div class="flex justify-end mt-6">
<button type="submit" class="btn-dark">
<i data-lucide="key" class="w-4 h-4"></i> Update Password
</button>
</div>
</form>
</div>
</div>
</main>
<script>
// Render icons
if (typeof lucide !== 'undefined' && lucide.createIcons) {
lucide.createIcons();
}
</script>
</body>
</html>
b IDATxytVսϓ22 A@IR:hCiZ[v*E:WũZA ^dQeQ @ !jZ'>gsV仿$|?g)&x-E