39249-vm/index.php
Flatlogic Bot a64664a505 background
2026-03-21 16:24:04 +00:00

423 lines
19 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
@ini_set('display_errors', '1');
@error_reporting(E_ALL);
@date_default_timezone_set('UTC');
require_once __DIR__ . '/db/config.php';
require_once __DIR__ . '/mail/MailService.php';
// Helper to fetch images
function get_images(string $queries): array {
$apiUrl = 'http://127.0.0.1/api/pexels.php?queries=' . urlencode($queries);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $apiUrl,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 5,
]);
$resp = curl_exec($ch);
curl_close($ch);
return json_decode($resp ?: '[]', true) ?: [];
}
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
$now = date('Y-m-d H:i:s');
// Fetch images for sections
$workImages = get_images('design,code,analytics');
$testimonialImages = get_images('person,professional,business');
$formData = [
'name' => '',
'email' => '',
'message' => '',
];
$errors = [];
$toast = null;
$toastType = 'success';
$mailWarning = null;
function ensure_contact_table(): void {
db()->exec(
"CREATE TABLE IF NOT EXISTS contact_requests (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(120) NOT NULL,
email VARCHAR(160) NOT NULL,
message TEXT NOT NULL,
status VARCHAR(30) NOT NULL DEFAULT 'new',
ip_address VARCHAR(45) DEFAULT NULL,
user_agent VARCHAR(255) DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"
);
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$formData['name'] = trim($_POST['name'] ?? '');
$formData['email'] = trim($_POST['email'] ?? '');
$formData['message'] = trim($_POST['message'] ?? '');
if (mb_strlen($formData['name']) < 2) {
$errors[] = 'Please enter your name.';
}
if (!filter_var($formData['email'], FILTER_VALIDATE_EMAIL)) {
$errors[] = 'Please provide a valid email address.';
}
if (mb_strlen($formData['message']) < 10) {
$errors[] = 'Please add a brief message (at least 10 characters).';
}
if (!$errors) {
try {
ensure_contact_table();
$stmt = db()->prepare(
'INSERT INTO contact_requests (name, email, message, ip_address, user_agent) VALUES (:name, :email, :message, :ip, :agent)'
);
$stmt->execute([
':name' => $formData['name'],
':email' => $formData['email'],
':message' => $formData['message'],
':ip' => $_SERVER['REMOTE_ADDR'] ?? null,
':agent' => $_SERVER['HTTP_USER_AGENT'] ?? null,
]);
$to = getenv('MAIL_TO') ?: null;
$mailRes = MailService::sendContactMessage(
$formData['name'],
$formData['email'],
$formData['message'],
$to,
'New portfolio inquiry'
);
if (empty($mailRes['success'])) {
$mailWarning = 'Saved your message, but email delivery failed. Please confirm SMTP settings.';
}
$toast = 'Thanks for reaching out! I will reply within 12 business days.';
$toastType = $mailWarning ? 'warning' : 'success';
$formData = ['name' => '', 'email' => '', 'message' => ''];
} catch (Throwable $e) {
$errors[] = 'Something went wrong while saving your message. Please try again.';
}
}
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Personal Portfolio</title>
<?php if ($projectDescription): ?>
<meta name="description" content="<?= htmlspecialchars($projectDescription) ?>" />
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
<?php endif; ?>
<?php if ($projectImageUrl): ?>
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
<?php endif; ?>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<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&display=swap" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?= time(); ?>">
<style>
.card-img-top { height: 200px; object-fit: cover; }
.testi-img { width: 50px; height: 50px; border-radius: 50%; object-fit: cover; }
</style>
</head>
<body>
<div class="site-background" aria-hidden="true">
<span class="bg-grid"></span>
<span class="bg-orb bg-orb-one" data-depth="18"></span>
<span class="bg-orb bg-orb-two" data-depth="28"></span>
<span class="bg-orb bg-orb-three" data-depth="38"></span>
<span class="bg-cursor-glow"></span>
</div>
<nav class="navbar navbar-expand-lg navbar-light bg-white border-bottom fixed-top">
<div class="container">
<a class="navbar-brand fw-semibold" href="#top">Alex Carter</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#siteNav" aria-controls="siteNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="siteNav">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item"><a class="nav-link" href="#work">Work</a></li>
<li class="nav-item"><a class="nav-link" href="#about">About</a></li>
<li class="nav-item"><a class="nav-link" href="#testimonials">Testimonials</a></li>
<li class="nav-item"><a class="nav-link" href="#contact">Contact</a></li>
</ul>
</div>
</div>
</nav>
<main id="top" class="pt-5">
<section class="section hero-section">
<div class="container">
<div class="row align-items-center g-4">
<div class="col-lg-6">
<p class="eyebrow text-uppercase text-muted mb-3">Product &amp; Brand Designer</p>
<h1 class="display-5 fw-semibold mb-3">Designing calm, precise digital experiences that ship.</h1>
<p class="lead text-muted mb-4">I help modern teams turn complex ideas into elegant product experiences. Focused on UX strategy, UI systems, and launch-ready web design.</p>
<div class="d-flex flex-wrap gap-3">
<a class="btn btn-primary btn-lg" href="#contact">Book a project</a>
<a class="btn btn-outline-dark btn-lg" href="#work">See portfolio</a>
</div>
<div class="hero-meta d-flex flex-wrap gap-4 mt-4">
<div>
<p class="text-muted small mb-1">Availability</p>
<p class="fw-semibold mb-0">New projects from April</p>
</div>
<div>
<p class="text-muted small mb-1">Location</p>
<p class="fw-semibold mb-0">New York · Remote</p>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="hero-card p-4 p-lg-5">
<h2 class="h5 fw-semibold mb-3">Recent highlights</h2>
<ul class="list-unstyled mb-4">
<li class="d-flex justify-content-between border-bottom py-3">
<span class="fw-medium">Fintech onboarding revamp</span>
<span class="text-muted small">+42% activation</span>
</li>
<li class="d-flex justify-content-between border-bottom py-3">
<span class="fw-medium">Healthcare mobile redesign</span>
<span class="text-muted small">4.8★ rating</span>
</li>
<li class="d-flex justify-content-between py-3">
<span class="fw-medium">SaaS dashboard system</span>
<span class="text-muted small">12 screens</span>
</li>
</ul>
<div class="d-flex flex-wrap gap-2">
<span class="badge badge-soft">UX Strategy</span>
<span class="badge badge-soft">Design Systems</span>
<span class="badge badge-soft">Web &amp; Mobile</span>
<span class="badge badge-soft">Prototyping</span>
</div>
</div>
</div>
</div>
</div>
</section>
<section id="work" class="section section-muted">
<div class="container">
<div class="d-flex justify-content-between align-items-end mb-4">
<div>
<h2 class="h3 fw-semibold mb-2">Selected work</h2>
<p class="text-muted mb-0">A handful of case studies covering product strategy, UX, and UI design.</p>
</div>
<span class="text-muted small">2023 — 2026</span>
</div>
<div class="row g-4">
<?php
$projects = [
['title' => 'Signal Labs', 'type' => 'Fintech onboarding', 'summary' => 'Simplified KYC flow, redesigned primary journey, and mapped conversion milestones.'],
['title' => 'Northline Health', 'type' => 'Patient app', 'summary' => 'Built a modular design system and streamlined appointment booking.'],
['title' => 'Sprout Commerce', 'type' => 'SaaS analytics', 'summary' => 'Designed a cross-functional dashboard with usage insights for teams.'],
];
foreach ($projects as $i => $project):
$img = $workImages[$i] ?? ['src' => 'https://picsum.photos/600/400'];
?>
<div class="col-md-4">
<article class="card shadow-sm h-100 border-0">
<img src="<?= htmlspecialchars($img['src']) ?>" class="card-img-top" alt="<?= htmlspecialchars($project['title']) ?>">
<div class="card-body d-flex flex-column">
<p class="text-muted small text-uppercase mb-2"><?= htmlspecialchars($project['type']) ?></p>
<h3 class="h5 fw-semibold"><?= htmlspecialchars($project['title']) ?></h3>
<p class="text-muted mt-3"><?= htmlspecialchars($project['summary']) ?></p>
<div class="mt-auto">
<span class="text-primary small fw-semibold">View case study →</span>
</div>
</div>
</article>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<section id="about" class="section">
<div class="container">
<div class="row g-4 align-items-center">
<div class="col-lg-5">
<h2 class="h3 fw-semibold mb-3">About</h2>
<p class="text-muted mb-4">Im a multidisciplinary designer with 9+ years building digital products for startups and enterprise teams. I specialize in UX direction, visual systems, and stakeholder alignment that turns ideas into shipped work.</p>
<div class="d-flex flex-wrap gap-2">
<span class="badge badge-soft">Figma</span>
<span class="badge badge-soft">Webflow</span>
<span class="badge badge-soft">Framer</span>
<span class="badge badge-soft">Design Systems</span>
</div>
</div>
<div class="col-lg-7">
<div class="about-panel p-4 p-lg-5">
<div class="row g-4">
<div class="col-md-6">
<h3 class="h6 text-uppercase text-muted">Services</h3>
<ul class="list-unstyled text-muted mb-0">
<li class="py-1">Product discovery workshops</li>
<li class="py-1">UX &amp; UI design</li>
<li class="py-1">Design system build</li>
<li class="py-1">Launch planning</li>
</ul>
</div>
<div class="col-md-6">
<h3 class="h6 text-uppercase text-muted">Focus areas</h3>
<ul class="list-unstyled text-muted mb-0">
<li class="py-1">Fintech &amp; SaaS platforms</li>
<li class="py-1">Mobile-first experiences</li>
<li class="py-1">B2B onboarding</li>
<li class="py-1">UX copy + tone</li>
</ul>
</div>
</div>
<div class="border-top mt-4 pt-4 d-flex justify-content-between">
<div>
<p class="text-muted small mb-1">Clients</p>
<p class="fw-semibold mb-0">Stripe, Calm, Notion</p>
</div>
<div>
<p class="text-muted small mb-1">Engagements</p>
<p class="fw-semibold mb-0">Strategy · Design · Launch</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<section id="testimonials" class="section section-muted">
<div class="container">
<div class="d-flex justify-content-between align-items-end mb-4">
<div>
<h2 class="h3 fw-semibold mb-2">Testimonials</h2>
<p class="text-muted mb-0">Short notes from founders and product leads.</p>
</div>
<span class="text-muted small">Updated March <?= date('Y'); ?></span>
</div>
<div class="row g-4">
<?php
$testi = [
['quote' => '“Alex quickly aligned our team and shipped a full design system. The project paid for itself within weeks.”', 'name' => 'Jordan Lee · Product Lead'],
['quote' => '“Clear, structured, and incredibly fast. We felt in control while launching a brand new onboarding.”', 'name' => 'Priya Patel · Founder']
];
foreach ($testi as $i => $item):
$img = $testimonialImages[$i] ?? ['src' => 'https://picsum.photos/100'];
?>
<div class="col-md-6">
<div class="card border-0 shadow-sm h-100">
<div class="card-body d-flex gap-3">
<img src="<?= htmlspecialchars($img['src']) ?>" class="testi-img" alt="Testimonial photo">
<div>
<p class="text-muted mb-2"><?= htmlspecialchars($item['quote']) ?></p>
<p class="fw-semibold mb-0"><?= htmlspecialchars($item['name']) ?></p>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<section id="contact" class="section">
<div class="container">
<div class="row g-4 align-items-start">
<div class="col-lg-5">
<h2 class="h3 fw-semibold mb-3">Lets work together</h2>
<p class="text-muted mb-4">Send a short note about your project or role. Ill reply with availability, timing, and next steps.</p>
<div class="contact-box p-4">
<h3 class="h6 text-uppercase text-muted">Typical engagements</h3>
<ul class="list-unstyled text-muted mb-0">
<li class="py-1">UX audit + roadmap (2 weeks)</li>
<li class="py-1">New product experience (68 weeks)</li>
<li class="py-1">Design system sprint (3 weeks)</li>
</ul>
</div>
</div>
<div class="col-lg-7">
<div class="card border-0 shadow-sm">
<div class="card-body p-4 p-lg-5">
<h3 class="h5 fw-semibold mb-3">Contact form</h3>
<?php if ($errors): ?>
<div class="alert alert-danger" role="alert">
<?= htmlspecialchars(implode(' ', $errors)) ?>
</div>
<?php endif; ?>
<?php if ($mailWarning): ?>
<div class="alert alert-warning" role="alert">
<?= htmlspecialchars($mailWarning) ?>
</div>
<?php endif; ?>
<form method="post" action="#contact" class="row g-3">
<div class="col-md-6">
<label class="form-label">Name</label>
<input class="form-control" type="text" name="name" value="<?= htmlspecialchars($formData['name']) ?>" required>
</div>
<div class="col-md-6">
<label class="form-label">Email</label>
<input class="form-control" type="email" name="email" value="<?= htmlspecialchars($formData['email']) ?>" required>
</div>
<div class="col-12">
<label class="form-label">Message</label>
<textarea class="form-control" name="message" rows="4" required><?= htmlspecialchars($formData['message']) ?></textarea>
</div>
<div class="col-12 d-flex flex-wrap gap-3 align-items-center">
<button class="btn btn-primary btn-lg" type="submit">Send inquiry</button>
<span class="text-muted small">I respond within 48 hours.</span>
</div>
</form>
<?php if (!getenv('MAIL_TO')): ?>
<p class="text-muted small mt-3 mb-0">This is for testing purposes only — Flatlogic does not guarantee usage of the mail server. Please set up your own SMTP in <code>.env</code> (MAIL_/SMTP_ vars) with out AI Agent.</p>
<?php endif; ?>
</div>
</div>
<p class="text-muted small mt-3">Admin view: <a class="link-dark" href="inbox.php">View contact requests</a></p>
</div>
</div>
</div>
</section>
</main>
<footer class="border-top py-4">
<div class="container d-flex flex-wrap justify-content-between align-items-center gap-3">
<p class="text-muted small mb-0">© <?= date('Y'); ?> Alex Carter. All rights reserved.</p>
<div class="d-flex gap-3">
<a class="text-muted small" href="#work">Portfolio</a>
<a class="text-muted small" href="#contact">Contact</a>
<span class="text-muted small">Updated <?= htmlspecialchars($now) ?> UTC</span>
</div>
</div>
</footer>
<div class="toast-container position-fixed bottom-0 end-0 p-3">
<?php if ($toast): ?>
<div class="toast align-items-center text-bg-<?= $toastType ?> border-0 show" role="alert" aria-live="assertive" aria-atomic="true" data-autohide="true">
<div class="d-flex">
<div class="toast-body">
<?= htmlspecialchars($toast) ?>
</div>
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
</div>
<?php endif; ?>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" defer></script>
<script src="assets/js/main.js?v=<?= time(); ?>" defer></script>
</body>
</html>