admin_dashboard.php 4.3 KB

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