197 lines
11 KiB
PHP
197 lines
11 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/includes/site.php';
|
|
require_once __DIR__ . '/includes/inquiries.php';
|
|
|
|
$pageTitle = 'Start a project';
|
|
$pageDescription = 'Submit a short project brief to discuss a new software build, modernization initiative, or AI workflow.';
|
|
$activeNav = 'contact';
|
|
|
|
$textLength = static function (string $value): int {
|
|
return function_exists('mb_strlen') ? mb_strlen($value) : strlen($value);
|
|
};
|
|
|
|
$form = [
|
|
'full_name' => '',
|
|
'company_name' => '',
|
|
'email' => '',
|
|
'project_type' => project_type_options()[0],
|
|
'budget_range' => budget_options()[0],
|
|
'launch_window' => launch_options()[0],
|
|
'message' => '',
|
|
];
|
|
$errors = [];
|
|
$submissionError = '';
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$form['full_name'] = trim((string) ($_POST['full_name'] ?? ''));
|
|
$form['company_name'] = trim((string) ($_POST['company_name'] ?? ''));
|
|
$form['email'] = trim((string) ($_POST['email'] ?? ''));
|
|
$form['project_type'] = trim((string) ($_POST['project_type'] ?? ''));
|
|
$form['budget_range'] = trim((string) ($_POST['budget_range'] ?? ''));
|
|
$form['launch_window'] = trim((string) ($_POST['launch_window'] ?? ''));
|
|
$form['message'] = trim((string) ($_POST['message'] ?? ''));
|
|
|
|
if ($form['full_name'] === '' || $textLength($form['full_name']) < 2) {
|
|
$errors['full_name'] = 'Please enter your name.';
|
|
}
|
|
if ($form['company_name'] === '' || $textLength($form['company_name']) < 2) {
|
|
$errors['company_name'] = 'Please enter your company name.';
|
|
}
|
|
if (!filter_var($form['email'], FILTER_VALIDATE_EMAIL)) {
|
|
$errors['email'] = 'Please enter a valid work email.';
|
|
}
|
|
if (!in_array($form['project_type'], project_type_options(), true)) {
|
|
$errors['project_type'] = 'Please choose a valid project type.';
|
|
}
|
|
if (!in_array($form['budget_range'], budget_options(), true)) {
|
|
$errors['budget_range'] = 'Please choose a valid budget range.';
|
|
}
|
|
if (!in_array($form['launch_window'], launch_options(), true)) {
|
|
$errors['launch_window'] = 'Please choose a valid launch window.';
|
|
}
|
|
if ($form['message'] === '' || $textLength($form['message']) < 30) {
|
|
$errors['message'] = 'Please share at least a short project summary (30+ characters).';
|
|
}
|
|
|
|
if ($errors === []) {
|
|
try {
|
|
$reference = create_project_inquiry($form);
|
|
header('Location: /brief.php?ref=' . urlencode($reference) . '&created=1');
|
|
exit;
|
|
} catch (Throwable $exception) {
|
|
error_log('Project inquiry save failed: ' . $exception->getMessage());
|
|
$submissionError = 'We could not save your brief right now. Please try again in a moment.';
|
|
}
|
|
}
|
|
}
|
|
|
|
$fieldValue = static function (string $key) use ($form): string {
|
|
return htmlspecialchars($form[$key] ?? '');
|
|
};
|
|
|
|
require __DIR__ . '/partials/header.php';
|
|
?>
|
|
<main>
|
|
<section class="section-shell border-bottom page-hero">
|
|
<div class="container">
|
|
<div class="row g-4 align-items-end">
|
|
<div class="col-lg-8">
|
|
<span class="eyebrow">Contact</span>
|
|
<h1 class="section-title">Tell us what you are building and we will shape the next step.</h1>
|
|
<p class="section-copy mb-0">This first form is intentionally concise. It gives us enough context to propose the right engagement model, timeline, and next conversation.</p>
|
|
</div>
|
|
<div class="col-lg-4">
|
|
<div class="surface-panel compact-panel h-100">
|
|
<div class="panel-label">What happens next</div>
|
|
<div class="content-row">
|
|
<h3>1. Brief review</h3>
|
|
<p>We assess scope, urgency, and likely delivery shape within one business day.</p>
|
|
</div>
|
|
<div class="content-row">
|
|
<h3>2. Working session</h3>
|
|
<p>If there is a fit, we use the first call to refine goals, constraints, and success metrics.</p>
|
|
</div>
|
|
<div class="content-row mb-0">
|
|
<h3>3. Clear recommendation</h3>
|
|
<p>You receive a pragmatic recommendation: discovery sprint, delivery pod, or a smaller advisory step.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section-shell">
|
|
<div class="container">
|
|
<div class="row g-4 align-items-start">
|
|
<div class="col-lg-7">
|
|
<div class="surface-panel form-panel">
|
|
<?php if ($submissionError !== ''): ?>
|
|
<div class="alert alert-danger" role="alert"><?= htmlspecialchars($submissionError) ?></div>
|
|
<?php elseif ($errors !== []): ?>
|
|
<div class="alert alert-warning" role="alert">Please review the highlighted fields and try again.</div>
|
|
<?php endif; ?>
|
|
<form method="post" action="/contact.php" novalidate>
|
|
<div class="row g-3">
|
|
<div class="col-md-6">
|
|
<label class="form-label" for="full_name">Name</label>
|
|
<input class="form-control<?= isset($errors['full_name']) ? ' is-invalid' : '' ?>" id="full_name" name="full_name" type="text" maxlength="120" required value="<?= $fieldValue('full_name') ?>">
|
|
<?php if (isset($errors['full_name'])): ?><div class="invalid-feedback"><?= htmlspecialchars($errors['full_name']) ?></div><?php endif; ?>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<label class="form-label" for="company_name">Company</label>
|
|
<input class="form-control<?= isset($errors['company_name']) ? ' is-invalid' : '' ?>" id="company_name" name="company_name" type="text" maxlength="150" required value="<?= $fieldValue('company_name') ?>">
|
|
<?php if (isset($errors['company_name'])): ?><div class="invalid-feedback"><?= htmlspecialchars($errors['company_name']) ?></div><?php endif; ?>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="email">Work email</label>
|
|
<input class="form-control<?= isset($errors['email']) ? ' is-invalid' : '' ?>" id="email" name="email" type="email" maxlength="190" required value="<?= $fieldValue('email') ?>">
|
|
<?php if (isset($errors['email'])): ?><div class="invalid-feedback"><?= htmlspecialchars($errors['email']) ?></div><?php endif; ?>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<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">
|
|
<?php foreach (project_type_options() as $option): ?>
|
|
<option value="<?= htmlspecialchars($option) ?>"<?= $form['project_type'] === $option ? ' selected' : '' ?>><?= htmlspecialchars($option) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<?php if (isset($errors['project_type'])): ?><div class="invalid-feedback"><?= htmlspecialchars($errors['project_type']) ?></div><?php endif; ?>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label" for="budget_range">Budget</label>
|
|
<select class="form-select<?= isset($errors['budget_range']) ? ' is-invalid' : '' ?>" id="budget_range" name="budget_range">
|
|
<?php foreach (budget_options() as $option): ?>
|
|
<option value="<?= htmlspecialchars($option) ?>"<?= $form['budget_range'] === $option ? ' selected' : '' ?>><?= htmlspecialchars($option) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<?php if (isset($errors['budget_range'])): ?><div class="invalid-feedback"><?= htmlspecialchars($errors['budget_range']) ?></div><?php endif; ?>
|
|
</div>
|
|
<div class="col-md-4">
|
|
<label class="form-label" for="launch_window">Target launch</label>
|
|
<select class="form-select<?= isset($errors['launch_window']) ? ' is-invalid' : '' ?>" id="launch_window" name="launch_window">
|
|
<?php foreach (launch_options() as $option): ?>
|
|
<option value="<?= htmlspecialchars($option) ?>"<?= $form['launch_window'] === $option ? ' selected' : '' ?>><?= htmlspecialchars($option) ?></option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<?php if (isset($errors['launch_window'])): ?><div class="invalid-feedback"><?= htmlspecialchars($errors['launch_window']) ?></div><?php endif; ?>
|
|
</div>
|
|
<div class="col-12">
|
|
<label class="form-label" for="message">Project brief</label>
|
|
<textarea class="form-control<?= isset($errors['message']) ? ' is-invalid' : '' ?>" id="message" name="message" rows="7" maxlength="3000" required placeholder="What are you building, why now, and what is the main constraint or outcome you care about most?"><?= $fieldValue('message') ?></textarea>
|
|
<?php if (isset($errors['message'])): ?><div class="invalid-feedback"><?= htmlspecialchars($errors['message']) ?></div><?php endif; ?>
|
|
</div>
|
|
<div class="col-12 d-flex flex-wrap gap-3 align-items-center pt-2">
|
|
<button class="btn btn-primary btn-lg" type="submit">Submit brief</button>
|
|
<span class="mini-label">Stored securely in your project database for follow-up and future admin tooling.</span>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="col-lg-5">
|
|
<div class="surface-panel compact-panel mb-4">
|
|
<div class="panel-label">Good fit</div>
|
|
<ul class="list-unstyled service-points mb-0">
|
|
<li>New customer-facing products with real launch pressure</li>
|
|
<li>Internal platforms that need cleaner workflows and reporting</li>
|
|
<li>Modernization programs where downtime or regressions are expensive</li>
|
|
<li>AI and automation work linked to measurable operational outcomes</li>
|
|
</ul>
|
|
</div>
|
|
<div class="surface-panel compact-panel">
|
|
<div class="panel-label">Prefer to explore first?</div>
|
|
<p class="mb-3">Review our representative work and editorial thinking before sending a brief.</p>
|
|
<div class="d-flex flex-wrap gap-3">
|
|
<a class="btn btn-outline-dark" href="/work.php">View work</a>
|
|
<a class="btn btn-outline-dark" href="/insights.php">Read insights</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
<?php require __DIR__ . '/partials/footer.php'; ?>
|