Files
website-ai-generator/web/index.php

133 lines
5.2 KiB
PHP

<?php
declare(strict_types=1);
$path = (string) parse_url($_SERVER['REQUEST_URI'] ?? '/', PHP_URL_PATH);
$segments = array_values(array_filter(explode('/', ltrim($path, '/'))));
$firstSegment = $segments[0] ?? '';
if (count($segments) === 1 && str_starts_with($firstSegment, 'seed-')) {
$file = __DIR__ . '/../pages/' . $firstSegment . '.html';
if (file_exists($file)) {
header('Content-Type: text/html; charset=UTF-8');
echo file_get_contents($file);
exit;
}
http_response_code(404);
echo 'Page not found';
exit;
}
if ($firstSegment === 'generate') {
include_once __DIR__ . '/generator.php';
exit;
}
if ($firstSegment === 'list') {
header('Content-Type: text/html; charset=UTF-8');
$pageFiles = glob(__DIR__ . '/../pages/seed-*.html') ?: [];
usort($pageFiles, static fn (string $a, string $b): int => filemtime($b) <=> filemtime($a));
echo '<!doctype html><html lang="en"><head><meta charset="UTF-8">';
echo '<meta name="viewport" content="width=device-width, initial-scale=1.0">';
echo '<title>Generated Seed Pages</title>';
echo '<script src="https://cdn.tailwindcss.com"></script></head>';
echo '<body class="min-h-screen bg-zinc-950 text-zinc-100 p-6 md:p-10">';
echo '<div class="max-w-7xl mx-auto">';
echo '<div class="flex flex-wrap items-center justify-between gap-4 mb-8">';
echo '<h1 class="text-3xl md:text-4xl font-bold">Generated Seeds</h1>';
echo '<a href="/" class="px-4 py-2 rounded-md bg-emerald-600 hover:bg-emerald-500 transition text-white font-medium">Generate New</a>';
echo '</div>';
if ($pageFiles === []) {
echo '<p class="text-zinc-300">No generated seed pages found yet.</p>';
} else {
echo '<div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-6">';
foreach ($pageFiles as $pageFile) {
$seed = basename($pageFile, '.html');
$previewWebPath = '/previews/' . $seed . '.jpg';
$previewFsPath = __DIR__ . '/previews/' . $seed . '.jpg';
$hasPreview = file_exists($previewFsPath);
$title = $seed;
$rawHtml = file_get_contents($pageFile);
if ($rawHtml !== false && preg_match('/<title>(.*?)<\/title>/is', $rawHtml, $matches) === 1) {
$title = trim(strip_tags($matches[1]));
}
$updated = date('Y-m-d H:i:s', filemtime($pageFile));
echo '<a href="/' . htmlspecialchars($seed, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '" class="block rounded-xl overflow-hidden border border-zinc-800 bg-zinc-900/70 hover:border-emerald-500 transition">';
echo '<div class="aspect-[16/10] bg-zinc-800">';
if ($hasPreview) {
echo '<img loading="lazy" src="' . htmlspecialchars($previewWebPath, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '" alt="Preview for ' . htmlspecialchars($seed, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '" class="w-full h-full object-cover">';
} else {
echo '<div class="w-full h-full grid place-items-center text-zinc-400 text-sm">Preview not available yet</div>';
}
echo '</div>';
echo '<div class="p-4">';
echo '<h2 class="text-lg font-semibold mb-1 line-clamp-2">' . htmlspecialchars($title, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '</h2>';
echo '<p class="text-xs text-zinc-400 mb-1">' . htmlspecialchars($seed, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '</p>';
echo '<p class="text-xs text-zinc-500">Updated: ' . htmlspecialchars($updated, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8') . '</p>';
echo '</div></a>';
}
echo '</div>';
}
echo '</div></body></html>';
exit;
}
?>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Generation Error</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.10/dist/htmx.min.js"></script>
</head>
<body class="min-h-screen bg-zinc-950 text-zinc-100 p-8" hx-get="/generate" hx-trigger="load">
<h1 class="text-2xl font-bold mb-4">Page being generated, please wait</h1>
<p class="text-zinc-300 mb-3">
Generating content... this should complete in about 30 seconds.
</p>
<div class="w-full max-w-xl h-3 bg-zinc-800 rounded overflow-hidden mb-2" aria-label="Generation progress">
<div id="progress-bar" class="h-full bg-emerald-500 w-0 transition-[width] duration-100"></div>
</div>
<p id="progress-text" class="text-zinc-400 text-sm mb-3">0%</p>
<script>
(() => {
const durationMs = 30000;
const start = performance.now();
const bar = document.getElementById('progress-bar');
const text = document.getElementById('progress-text');
function tick(now) {
const elapsed = now - start;
const progress = Math.min(elapsed / durationMs, 1);
const percent = Math.round(progress * 100);
bar.style.width = percent + '%';
text.textContent = percent + '%';
if (progress < 1) {
requestAnimationFrame(tick);
}
}
requestAnimationFrame(tick);
})();
</script>
</body>
</html>