- Add a Hours admin panel (admin/hours.php, admin/hours.js) for editing the weekly open/close schedule and an optional per-day kitchen closing time, with a live preview of how it'll read on the public site - Store hours in a new pub_hours table (inc/db.php), seeded with the site's existing Thu-Sat/9pm-kitchen schedule; inc/hours.php formats and groups it for display (day ranges, kitchen-close note, footer summary) - Wire the public Visit card and both site footers (index.php, menu.php) to read hours from that data instead of hardcoded copy - Rebuild the Announcements and Users admin tables onto the same CSS Grid list pattern already used for the Menu (admin-table-actions -> row-actions), and make the Announcements status toggle an in-place AJAX action like the menu item's (admin/index.js) - Add the Hours tab to admin nav across all four admin pages Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
129 lines
4.4 KiB
PHP
129 lines
4.4 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
|
||
/**
|
||
* Database connection & schema management for SQLite
|
||
*/
|
||
|
||
function get_db(): PDO {
|
||
static $pdo = null;
|
||
if ($pdo !== null) {
|
||
return $pdo;
|
||
}
|
||
|
||
$dbDir = __DIR__ . '/../db';
|
||
if (!is_dir($dbDir)) {
|
||
mkdir($dbDir, 0755, true);
|
||
}
|
||
|
||
$dbPath = $dbDir . '/fitz.sqlite';
|
||
$isNew = !file_exists($dbPath);
|
||
|
||
$pdo = new PDO('sqlite:' . $dbPath, null, null, [
|
||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||
PDO::ATTR_TIMEOUT => 5
|
||
]);
|
||
|
||
// Enable WAL mode for concurrency and performance
|
||
$pdo->exec('PRAGMA journal_mode = WAL;');
|
||
$pdo->exec('PRAGMA foreign_keys = ON;');
|
||
|
||
// Initialize tables if needed
|
||
init_db_schema($pdo);
|
||
|
||
return $pdo;
|
||
}
|
||
|
||
function init_db_schema(PDO $pdo): void {
|
||
$pdo->exec("
|
||
CREATE TABLE IF NOT EXISTS users (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
username TEXT UNIQUE NOT NULL,
|
||
password_hash TEXT NOT NULL,
|
||
role TEXT NOT NULL DEFAULT 'admin',
|
||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
CREATE TABLE IF NOT EXISTS announcements (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
is_active INTEGER NOT NULL DEFAULT 1,
|
||
type TEXT NOT NULL DEFAULT 'holiday',
|
||
headline TEXT NOT NULL,
|
||
message TEXT NOT NULL,
|
||
start_date TEXT NULL,
|
||
end_date TEXT NULL,
|
||
show_banner INTEGER NOT NULL DEFAULT 1,
|
||
show_in_hours INTEGER NOT NULL DEFAULT 1,
|
||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
CREATE TABLE IF NOT EXISTS menu_categories (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
name TEXT NOT NULL,
|
||
description TEXT NULL,
|
||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
CREATE TABLE IF NOT EXISTS menu_items (
|
||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
category_id INTEGER NOT NULL REFERENCES menu_categories(id) ON DELETE CASCADE,
|
||
name TEXT NOT NULL,
|
||
description TEXT NULL,
|
||
price TEXT NOT NULL,
|
||
badge TEXT NULL,
|
||
is_available INTEGER NOT NULL DEFAULT 1,
|
||
sort_order INTEGER NOT NULL DEFAULT 0,
|
||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
|
||
CREATE TABLE IF NOT EXISTS pub_hours (
|
||
day_of_week INTEGER PRIMARY KEY,
|
||
is_open INTEGER NOT NULL DEFAULT 0,
|
||
open_time TEXT NULL,
|
||
close_time TEXT NULL,
|
||
kitchen_close_time TEXT NULL,
|
||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||
);
|
||
");
|
||
|
||
// Seed default admin user if table is empty (username: admin / password: password)
|
||
$stmt = $pdo->query("SELECT COUNT(*) as count FROM users");
|
||
$userCount = $stmt->fetchColumn();
|
||
if ($userCount == 0) {
|
||
$defaultPassHash = password_hash('password', PASSWORD_DEFAULT);
|
||
$insert = $pdo->prepare("INSERT INTO users (username, password_hash, role) VALUES (?, ?, 'admin')");
|
||
$insert->execute(['admin', $defaultPassHash]);
|
||
}
|
||
|
||
// Seed default weekly hours if the table is empty: closed Sun–Wed,
|
||
// 4–10pm Thu–Sat with the kitchen closing at 9 — matches the hours the
|
||
// site originally shipped with as hardcoded copy.
|
||
$stmt = $pdo->query("SELECT COUNT(*) as count FROM pub_hours");
|
||
$hoursCount = $stmt->fetchColumn();
|
||
if ($hoursCount == 0) {
|
||
$insert = $pdo->prepare("
|
||
INSERT INTO pub_hours (day_of_week, is_open, open_time, close_time, kitchen_close_time)
|
||
VALUES (?, ?, ?, ?, ?)
|
||
");
|
||
// 0=Sunday ... 6=Saturday
|
||
$defaults = [
|
||
0 => null, // Sunday — closed
|
||
1 => null, // Monday — closed
|
||
2 => null, // Tuesday — closed
|
||
3 => null, // Wednesday — closed
|
||
4 => ['16:00', '22:00', '21:00'], // Thursday
|
||
5 => ['16:00', '22:00', '21:00'], // Friday
|
||
6 => ['16:00', '22:00', '21:00'], // Saturday
|
||
];
|
||
foreach ($defaults as $day => $times) {
|
||
if ($times === null) {
|
||
$insert->execute([$day, 0, null, null, null]);
|
||
} else {
|
||
$insert->execute([$day, 1, $times[0], $times[1], $times[2]]);
|
||
}
|
||
}
|
||
}
|
||
}
|