admin_dashboard.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. <?php
  2. error_reporting(E_ALL);
  3. ini_set("display_errors", 1);
  4. date_default_timezone_set("Australia/Hobart");
  5. $cfg = require __DIR__ . '/config.php';
  6. // HTTP Basic Auth — must be configured in .env
  7. $_au = $cfg['admin_user'] ?? '';
  8. $_ap = $cfg['admin_pass'] ?? '';
  9. if ($_au === '' || $_ap === '' ||
  10. !isset($_SERVER['PHP_AUTH_USER']) ||
  11. $_SERVER['PHP_AUTH_USER'] !== $_au ||
  12. ($_SERVER['PHP_AUTH_PW'] ?? '') !== $_ap) {
  13. header('WWW-Authenticate: Basic realm="Modulos Contracts Admin"');
  14. header('HTTP/1.0 401 Unauthorized');
  15. echo 'Authentication required.';
  16. exit;
  17. }
  18. unset($_au, $_ap);
  19. $dsn = 'mysql:host=' . $cfg['db_host'] . ';dbname=' . $cfg['db_name'] . ';charset=utf8mb4';
  20. $options = [
  21. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  22. PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
  23. ];
  24. try {
  25. $pdo = new PDO($dsn, $cfg['db_username'], $cfg['db_password'], $options);
  26. } catch (PDOException $e) {
  27. exit('Database connection failed: ' . $e->getMessage());
  28. }
  29. $app_id_raw = $_GET['id'] ?? '';
  30. $token = $_GET['token'] ?? '';
  31. $app_id = preg_match('/^\d+$/', $app_id_raw) ? $app_id_raw : '0';
  32. // Fetch applications
  33. $stmt = $pdo->query("SELECT id, reference, client_email FROM applications ORDER BY id DESC");
  34. $applications = $stmt->fetchAll();
  35. ?>
  36. <!doctype html>
  37. <html lang="en">
  38. <head>
  39. <meta charset="utf-8">
  40. <meta name="viewport" content="width=device-width, initial-scale=1">
  41. <title>Admin Dashboard – Application Stages</title>
  42. <link rel="shortcut icon" href="../internal/images/blueprint.ico" type="image/x-icon">
  43. <meta name="robots" content="noindex">
  44. <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-LN+7fdVzj6u52u30Kp6M/trliBMCMKTyK833zpbD+pXdCLuTusPj697FH4R/5mcr" crossorigin="anonymous">
  45. <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/js/bootstrap.bundle.min.js" integrity="sha384-ndDqU0Gzau9qJ1lfW4pNLlhNTkCfHzAVBReH9diLvGRem5+R9g2FzA8ZGN954O5Q" crossorigin="anonymous"></script>
  46. <link href="../internal/css/blueprint.css" rel="stylesheet">
  47. <link href="../internal/css/print.css" rel="stylesheet" media="print">
  48. <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
  49. </head>
  50. <body class="bg-light">
  51. <nav class="navbar bg-brown-dark brown-light border-bottom border-body d-print-none">
  52. <div class="container-fluid">
  53. <span class="navbar-brand brown-light">
  54. <img src="../internal/images/blueprint-logo-light.png" alt="Logo" width="30" height="24" class="d-inline-block align-text-top">
  55. Modulos Design
  56. </span>
  57. <div class="ms-auto d-flex gap-2">
  58. <a href="../internal/dashboard.php" class="btn btn-sm btn-outline-light"><i class="bi bi-grid-fill"></i> Dashboard</a>
  59. </div>
  60. </div>
  61. </nav>
  62. <div class="container my-5">
  63. <h2 class="mb-4">Applications</h2>
  64. <table class="table table-bordered">
  65. <thead class="table-light">
  66. <tr>
  67. <th>ID</th>
  68. <th>Reference</th>
  69. <th>Client Email</th>
  70. <th>Actions</th>
  71. </tr>
  72. </thead>
  73. <tbody>
  74. <?php foreach ($applications as $app): ?>
  75. <tr>
  76. <td><?= $app['id'] ?></td>
  77. <td><?= htmlspecialchars($app['reference'] ?? '', ENT_QUOTES, 'UTF-8') ?></td>
  78. <td><?= htmlspecialchars($app['client_email'] ?? '', ENT_QUOTES, 'UTF-8') ?></td>
  79. <td>
  80. <a href="edit_application.php?id=<?= $app['id'] ?>" class="btn btn-sm btn-primary">Edit Timeline</a>
  81. <a href="progress.php?id=<?= $app['id'] ?>" class="btn btn-sm btn-outline-secondary">View as Client</a>
  82. </td>
  83. </tr>
  84. <?php endforeach; ?>
  85. </tbody>
  86. </table>
  87. </div>
  88. </body>
  89. </html>