39760-vm/index.php
2026-04-21 09:42:14 +00:00

223 lines
11 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/app.php';
ensure_schema();
$formData = [
'name' => '',
'email' => '',
'company' => '',
'project_type' => 'Admin dashboard',
'timeline' => '2-4 weeks',
'budget' => '5k-15k',
'details' => '',
];
$errors = [];
$createdId = isset($_GET['ref']) ? (int) $_GET['ref'] : 0;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$validation = validate_request_input($_POST);
$formData = array_merge($formData, $validation['data']);
$errors = $validation['errors'];
if (!$errors) {
$requestId = create_request($formData);
set_flash('success', 'Request submitted. You can now review it in the admin dashboard.');
header('Location: /?submitted=1&ref=' . $requestId . '#request-form');
exit;
}
}
render_head(project_name() . ' | Intake & admin dashboard', 'Submit a new project request and review it in a clean admin dashboard.');
render_navbar('home');
render_flash_toast();
?>
<main>
<section class="hero-shell border-bottom">
<div class="container py-5 py-lg-6">
<div class="row g-4 align-items-center">
<div class="col-lg-7">
<div class="eyebrow mb-3">Fast LAMP MVP · intake to dashboard</div>
<h1 class="display-5 fw-semibold mb-3">A focused admin app starter for capturing and reviewing project requests.</h1>
<p class="lead text-secondary mb-4">This first slice gives you a public intake form, a secure admin sign-in, a dashboard list, and a detail screen so the workflow already feels like a usable product.</p>
<div class="d-flex flex-wrap gap-2 mb-4">
<a class="btn btn-dark px-4" href="#request-form">Create a request</a>
<a class="btn btn-outline-secondary px-4" href="/login.php">Open admin login</a>
</div>
<div class="hero-metrics row g-3">
<div class="col-sm-4">
<div class="metric-card">
<div class="metric-value">1 form</div>
<div class="metric-label">public intake path</div>
</div>
</div>
<div class="col-sm-4">
<div class="metric-card">
<div class="metric-value">1 dashboard</div>
<div class="metric-label">review queue</div>
</div>
</div>
<div class="col-sm-4">
<div class="metric-card">
<div class="metric-value">1 detail view</div>
<div class="metric-label">status updates</div>
</div>
</div>
</div>
</div>
<div class="col-lg-5">
<div class="panel-card p-4">
<div class="d-flex justify-content-between align-items-start gap-3 mb-4">
<div>
<div class="section-kicker">Admin access</div>
<h2 class="h4 mb-1">Demo sign-in</h2>
<p class="text-secondary mb-0">Use the admin login to review submissions right away.</p>
</div>
<span class="badge text-bg-light border">Ready</span>
</div>
<div class="stack-list">
<div class="stack-row">
<span>Email</span>
<code id="demo-email"><?= e(admin_email()) ?></code>
</div>
<div class="stack-row">
<span>Password</span>
<code id="demo-password"><?= e(admin_password()) ?></code>
</div>
</div>
<div class="d-grid gap-2 mt-4">
<button type="button" class="btn btn-outline-secondary" data-copy-text="<?= e(admin_email()) ?> / <?= e(admin_password()) ?>">Copy demo credentials</button>
<a class="btn btn-dark" href="/login.php">Go to login</a>
</div>
<?php if (using_default_admin_credentials()): ?>
<div class="notice-box mt-3">For this MVP, fallback credentials are enabled. Replace <code>ADMIN_EMAIL</code> and <code>ADMIN_PASSWORD</code> in the environment when you are ready.</div>
<?php endif; ?>
</div>
</div>
</div>
</div>
</section>
<section class="py-5 border-bottom bg-white">
<div class="container">
<div class="row g-3 align-items-stretch">
<div class="col-lg-4">
<div class="feature-card h-100">
<div class="section-kicker">Step 1</div>
<h2 class="h5">Capture the brief</h2>
<p class="text-secondary mb-0">Collect the essentials: contact, project type, budget, timeline, and a concise brief.</p>
</div>
</div>
<div class="col-lg-4">
<div class="feature-card h-100">
<div class="section-kicker">Step 2</div>
<h2 class="h5">Review in dashboard</h2>
<p class="text-secondary mb-0">Admins get a clean queue view with filters, counts, and a direct path to request details.</p>
</div>
</div>
<div class="col-lg-4">
<div class="feature-card h-100">
<div class="section-kicker">Step 3</div>
<h2 class="h5">Update status</h2>
<p class="text-secondary mb-0">Each request has a detail page where you can move it from new to reviewed, qualified, or closed.</p>
</div>
</div>
</div>
</div>
</section>
<section class="py-5 py-lg-6" id="request-form">
<div class="container">
<div class="row g-4 align-items-start">
<div class="col-lg-5">
<div class="sticky-lg-top sticky-offset">
<div class="section-kicker">New request</div>
<h2 class="h1 mb-3">Submit the first project brief.</h2>
<p class="text-secondary">This is the public workflow entry point. After submission, the request is stored in MariaDB and immediately available in the admin dashboard.</p>
<?php if ($createdId > 0): ?>
<div class="success-panel mt-4">
<div class="section-kicker">Confirmation</div>
<h3 class="h5 mb-1">Request <?= e(request_reference($createdId)) ?> is in the queue.</h3>
<p class="text-secondary mb-3">Use the admin dashboard to review the intake details and update its status.</p>
<a class="btn btn-dark btn-sm" href="/login.php">Review in admin</a>
</div>
<?php endif; ?>
</div>
</div>
<div class="col-lg-7">
<div class="panel-card p-4 p-lg-5">
<div class="d-flex justify-content-between align-items-start gap-3 mb-4">
<div>
<div class="section-kicker">Intake form</div>
<h3 class="h4 mb-1">Project request</h3>
<p class="text-secondary mb-0">Required fields are marked clearly and validated on the server.</p>
</div>
<span class="badge rounded-pill text-bg-light border">Live</span>
</div>
<?php if ($errors): ?>
<div class="alert alert-danger" role="alert">Please correct the highlighted fields and submit again.</div>
<?php endif; ?>
<form method="post" novalidate>
<div class="row g-3">
<div class="col-md-6">
<label class="form-label" for="name">Contact name</label>
<input class="form-control <?= isset($errors['name']) ? 'is-invalid' : '' ?>" id="name" name="name" value="<?= e($formData['name']) ?>" required>
<?php if (isset($errors['name'])): ?><div class="invalid-feedback"><?= e($errors['name']) ?></div><?php endif; ?>
</div>
<div class="col-md-6">
<label class="form-label" for="email">Work email</label>
<input class="form-control <?= isset($errors['email']) ? 'is-invalid' : '' ?>" id="email" name="email" type="email" value="<?= e($formData['email']) ?>" required>
<?php if (isset($errors['email'])): ?><div class="invalid-feedback"><?= e($errors['email']) ?></div><?php endif; ?>
</div>
<div class="col-md-6">
<label class="form-label" for="company">Company</label>
<input class="form-control" id="company" name="company" value="<?= e($formData['company']) ?>">
</div>
<div class="col-md-6">
<label class="form-label" for="project_type">Project type</label>
<select class="form-select <?= isset($errors['project_type']) ? 'is-invalid' : '' ?>" id="project_type" name="project_type" required>
<?php foreach (request_type_options() as $value => $label): ?>
<option value="<?= e($value) ?>" <?= $formData['project_type'] === $value ? 'selected' : '' ?>><?= e($label) ?></option>
<?php endforeach; ?>
</select>
<?php if (isset($errors['project_type'])): ?><div class="invalid-feedback"><?= e($errors['project_type']) ?></div><?php endif; ?>
</div>
<div class="col-md-6">
<label class="form-label" for="timeline">Timeline</label>
<select class="form-select <?= isset($errors['timeline']) ? 'is-invalid' : '' ?>" id="timeline" name="timeline" required>
<?php foreach (timeline_options() as $value => $label): ?>
<option value="<?= e($value) ?>" <?= $formData['timeline'] === $value ? 'selected' : '' ?>><?= e($label) ?></option>
<?php endforeach; ?>
</select>
<?php if (isset($errors['timeline'])): ?><div class="invalid-feedback"><?= e($errors['timeline']) ?></div><?php endif; ?>
</div>
<div class="col-md-6">
<label class="form-label" for="budget">Budget</label>
<select class="form-select <?= isset($errors['budget']) ? 'is-invalid' : '' ?>" id="budget" name="budget" required>
<?php foreach (budget_options() as $value => $label): ?>
<option value="<?= e($value) ?>" <?= $formData['budget'] === $value ? 'selected' : '' ?>><?= e($label) ?></option>
<?php endforeach; ?>
</select>
<?php if (isset($errors['budget'])): ?><div class="invalid-feedback"><?= e($errors['budget']) ?></div><?php endif; ?>
</div>
<div class="col-12">
<label class="form-label" for="details">Project brief</label>
<textarea class="form-control <?= isset($errors['details']) ? 'is-invalid' : '' ?>" id="details" name="details" rows="6" required><?= e($formData['details']) ?></textarea>
<?php if (isset($errors['details'])): ?><div class="invalid-feedback"><?= e($errors['details']) ?></div><?php endif; ?>
</div>
</div>
<div class="d-flex flex-column flex-sm-row justify-content-between align-items-sm-center gap-3 mt-4">
<div class="small text-secondary">Stored with PDO prepared statements and available to admins immediately.</div>
<button class="btn btn-dark px-4" type="submit">Submit request</button>
</div>
</form>
</div>
</div>
</div>
</div>
</section>
</main>
<?php render_footer('home'); ?>