39519-vm/requests.php
Flatlogic Bot edfa4d1aab first
2026-04-08 10:44:00 +00:00

184 lines
10 KiB
PHP

<?php
declare(strict_types=1);
session_start();
require_once __DIR__ . '/db/config.php';
require_once __DIR__ . '/app_helpers.php';
$projectName = site_project_name('Noah Mercer');
$projectDescription = site_project_description('Contact request inbox for portfolio submissions.');
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
$cssVersion = file_exists(__DIR__ . '/assets/css/custom.css') ? (string) filemtime(__DIR__ . '/assets/css/custom.css') : (string) time();
$jsVersion = file_exists(__DIR__ . '/assets/js/main.js') ? (string) filemtime(__DIR__ . '/assets/js/main.js') : (string) time();
$requests = [];
$selectedRequest = null;
$totalCount = 0;
$newCount = 0;
$todayCount = 0;
$errorMessage = null;
$selectedId = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT) ?: null;
try {
$pdo = db();
ensure_contact_requests_table($pdo);
$requests = $pdo->query('SELECT id, name, email, company, project_type, budget, message, status, created_at FROM contact_requests ORDER BY created_at DESC, id DESC LIMIT 100')->fetchAll();
$totals = $pdo->query("SELECT COUNT(*) AS total_count, SUM(status = 'new') AS new_count, SUM(DATE(created_at) = CURDATE()) AS today_count FROM contact_requests")->fetch();
$totalCount = (int) ($totals['total_count'] ?? 0);
$newCount = (int) ($totals['new_count'] ?? 0);
$todayCount = (int) ($totals['today_count'] ?? 0);
if ($selectedId !== null) {
$stmt = $pdo->prepare('SELECT * FROM contact_requests WHERE id = :id LIMIT 1');
$stmt->bindValue(':id', $selectedId, PDO::PARAM_INT);
$stmt->execute();
$selectedRequest = $stmt->fetch() ?: null;
}
if ($selectedRequest === null && $requests !== []) {
$stmt = $pdo->prepare('SELECT * FROM contact_requests WHERE id = :id LIMIT 1');
$stmt->bindValue(':id', (int) $requests[0]['id'], PDO::PARAM_INT);
$stmt->execute();
$selectedRequest = $stmt->fetch() ?: null;
}
} catch (Throwable $e) {
error_log('Failed to load requests inbox: ' . $e->getMessage());
$errorMessage = 'The inquiry inbox is not available right now.';
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><?= h($projectName) ?> — Inquiry Inbox</title>
<meta name="description" content="<?= h($projectDescription) ?>">
<meta name="robots" content="noindex, nofollow">
<?php if ($projectDescription): ?>
<meta property="og:description" content="<?= h($projectDescription) ?>">
<meta property="twitter:description" content="<?= h($projectDescription) ?>">
<?php endif; ?>
<?php if ($projectImageUrl): ?>
<meta property="og:image" content="<?= h($projectImageUrl) ?>">
<meta property="twitter:image" content="<?= h($projectImageUrl) ?>">
<?php endif; ?>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="stylesheet" href="/assets/css/custom.css?v=<?= h($cssVersion) ?>">
</head>
<body class="inbox-page">
<header class="site-header sticky-top border-bottom bg-white">
<nav class="navbar navbar-expand-lg bg-white">
<div class="container">
<a class="navbar-brand brand-mark" href="/"><?= h($projectName) ?></a>
<div class="d-flex gap-2 ms-auto">
<a class="btn btn-outline-secondary btn-sm" href="/">Back to site</a>
<a class="btn btn-dark btn-sm" href="/healthz.php">Health</a>
</div>
</div>
</nav>
</header>
<main class="section-space">
<div class="container">
<div class="section-heading mb-4">
<span class="section-kicker">Admin inbox</span>
<h1 class="h2 mb-2">Contact requests</h1>
<p class="mb-0">A minimal review view for messages submitted from the portfolio contact form.</p>
</div>
<?php if ($errorMessage): ?>
<div class="alert alert-danger" role="alert"><?= h($errorMessage) ?></div>
<?php else: ?>
<div class="row g-3 mb-4">
<div class="col-md-4">
<div class="stat-card card border-0 shadow-sm h-100"><div class="card-body p-4"><div class="detail-label">Total requests</div><div class="stat-value"><?= h((string) $totalCount) ?></div></div></div>
</div>
<div class="col-md-4">
<div class="stat-card card border-0 shadow-sm h-100"><div class="card-body p-4"><div class="detail-label">New</div><div class="stat-value"><?= h((string) $newCount) ?></div></div></div>
</div>
<div class="col-md-4">
<div class="stat-card card border-0 shadow-sm h-100"><div class="card-body p-4"><div class="detail-label">Today</div><div class="stat-value"><?= h((string) $todayCount) ?></div></div></div>
</div>
</div>
<?php if ($requests === []): ?>
<div class="card border-0 shadow-sm empty-state-card">
<div class="card-body p-5 text-center">
<h2 class="h4 mb-2">No inquiries yet</h2>
<p class="text-secondary mb-4">Submit the contact form from the homepage to populate this inbox.</p>
<a class="btn btn-dark" href="/#contact">Open contact form</a>
</div>
</div>
<?php else: ?>
<div class="row g-4">
<div class="col-lg-5 col-xl-4">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-bottom-0 pt-4 px-4">
<h2 class="h5 mb-1">Inbox list</h2>
<p class="text-secondary small mb-0">Select a request to inspect the full message.</p>
</div>
<div class="card-body p-3 p-lg-4 inbox-list">
<div class="list-group list-group-flush">
<?php foreach ($requests as $request): ?>
<?php $active = $selectedRequest && (int) $selectedRequest['id'] === (int) $request['id']; ?>
<a class="list-group-item list-group-item-action border rounded-3 mb-2 <?= $active ? 'active border-dark' : '' ?>" href="/requests.php?id=<?= h((string) $request['id']) ?>">
<div class="d-flex justify-content-between align-items-start gap-3 mb-2">
<div>
<div class="fw-semibold"><?= h($request['name']) ?></div>
<div class="small <?= $active ? 'text-white-50' : 'text-secondary' ?>"><?= h($request['email']) ?></div>
</div>
<span class="badge text-bg-light border text-dark"><?= h($request['project_type'] ?: 'General') ?></span>
</div>
<p class="small mb-2 <?= $active ? 'text-white-50' : 'text-secondary' ?>"><?= h(text_excerpt((string) $request['message'], 100)) ?></p>
<div class="small <?= $active ? 'text-white-50' : 'text-secondary' ?>"><?= h(date('M j, Y · H:i', strtotime((string) $request['created_at']))) ?></div>
</a>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
<div class="col-lg-7 col-xl-8">
<?php if ($selectedRequest): ?>
<article class="card border-0 shadow-sm">
<div class="card-body p-4 p-lg-5">
<div class="d-flex flex-column flex-md-row justify-content-between align-items-md-start gap-3 mb-4">
<div>
<span class="section-kicker">Selected inquiry</span>
<h2 class="h3 mb-1"><?= h($selectedRequest['name']) ?></h2>
<p class="text-secondary mb-0"><?= h($selectedRequest['email']) ?></p>
</div>
<span class="badge rounded-pill text-bg-dark px-3 py-2"><?= h($selectedRequest['status']) ?></span>
</div>
<div class="row g-3 mb-4">
<div class="col-md-4"><div class="detail-block h-100"><div class="detail-label">Company</div><div class="detail-value"><?= h($selectedRequest['company'] ?: '—') ?></div></div></div>
<div class="col-md-4"><div class="detail-block h-100"><div class="detail-label">Project type</div><div class="detail-value"><?= h($selectedRequest['project_type'] ?: 'General') ?></div></div></div>
<div class="col-md-4"><div class="detail-block h-100"><div class="detail-label">Budget</div><div class="detail-value"><?= h($selectedRequest['budget'] ?: '—') ?></div></div></div>
</div>
<div class="detail-block mb-4">
<div class="detail-label">Message</div>
<div class="detail-value message-body"><?= nl2br(h($selectedRequest['message'])) ?></div>
</div>
<div class="row g-3">
<div class="col-md-6"><div class="detail-block h-100"><div class="detail-label">Submitted</div><div class="detail-value"><?= h(date('F j, Y \a\t H:i', strtotime((string) $selectedRequest['created_at']))) ?></div></div></div>
<div class="col-md-6"><div class="detail-block h-100"><div class="detail-label">Source</div><div class="detail-value"><?= h($selectedRequest['source_url'] ?: base_url() . '/#contact') ?></div></div></div>
</div>
</div>
</article>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
<?php endif; ?>
</div>
</main>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous" defer></script>
<script src="/assets/js/main.js?v=<?= h($jsVersion) ?>" defer></script>
</body>
</html>