- Admin menu page: mobile item cards now put Actions in the top-right
corner next to Status, matching the desktop row layout instead of
stacking at the bottom; same treatment applied to announcements and
users for consistency across all three admin lists
- Center button label text everywhere via .btn { justify-content: center }
instead of one-off overrides
- Add a Disable/Enable Menu toggle to the admin menu toolbar; the public
menu page shows its existing "menu being updated" message while disabled
- Add an Enabled/Disabled status to user accounts, with its own toggle
badge, guardrails against disabling your own account or the last
enabled account, and an immediate session kick for anyone disabled
mid-session
- Fix the announcement banner / hero tagline "·" separators to hide only
when their neighboring text actually wraps onto a different line,
instead of a fixed breakpoint or always-on dot
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 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>
- Public site: replace the always-hidden mobile nav with a hamburger
toggle (index.php, menu.php, main.js, styles.css)
- Admin: render the Menu/Announcements/Users tables as labeled cards
below ~760px instead of squeezing descriptions into unreadable
single-word-per-line columns
- Admin menu: replace the manual "Order" number (which allowed
duplicates and never reflected in real time) with ↑/↓ buttons that
reorder items and categories immediately and renumber sort_order
sequentially on every move, self-healing any stale duplicates
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Implement admin user management interface (, , ) with async CRUD and password updating
- Add Users tab link to admin navigation across and
- Use in to lower specificity for native button resets, allowing modifier classes like to take precedence
Adds a public menu page (menu.php) and an admin CRUD interface
(admin/menu.php + admin/menu.js) backed by new menu_categories and
menu_items tables, replacing the "menu lives on Facebook" placeholder
on the homepage.
The admin JS/PHP came out of an AI-assisted pass that used outdated
JS (var, .then() chains, string-built HTML) and had some rough edges
security-wise, so this also:
- Rewrites the admin JS to modern ES (const/let, async/await,
template literals, dataset API) and splits it out of admin/menu.php
into admin/menu.js for proper separation of concerns
- Adds declare(strict_types=1) and PHP 8 match-based action dispatch
in place of an if-chain
- Validates category_id/item_id/category_id server-side before use,
so a bad ID returns a clean JSON error instead of an uncaught
PDOException or a null item breaking the client
- Rejects non-string POST fields instead of crashing trim() on them
- Replaces the category-save handler's full-page location.reload()
with in-place DOM updates (panel insert/update, resort by
sort_order, keep the item modal's category dropdown in sync), so
every admin action is now AJAX with no reload
- Sets data-name/data-desc via dataset assignment rather than string-
interpolating them into an HTML attribute, closing a stored-XSS
path through the category name/description fields
Removes seed-menu.php, a leftover stub with no working code left in
it after the AI's one-time seeding run.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Update inc/announcements.php to support listing, fetching by ID, toggling, and deleting multiple announcements
- Upgrade admin/index.php to an announcement management view with data table, status indicators, and create/edit sub-views
- Add admin table and action styles to styles.css without using inline style blocks
- Update index.php to render all currently active banner and hours announcements dynamically
- Add SQLite database initialization and management in inc/db.php
- Implement session authentication and CSRF security helpers in inc/auth.php
- Implement announcement querying and saving in inc/announcements.php
- Add management dashboard, login, and logout in admin/
- Protect db/ directory with Apache access controls
Static-turned-PHP site for a pub in Marion, Indiana, with:
- Hero section with tiled brick-texture background
- Live-capable stat card (Facebook followers/reviews via Graph API,
with graceful fallback to config.php constants when no token is set)
- Open Graph / Twitter Card meta tags for social sharing
- robots.txt
config.php is gitignored (holds a Facebook Page Access Token once
generated); config.sample.php is the tracked template — copy it to
config.php and fill in values to run this locally or in deployment.