Public booking page + iframe embed (#17)

Adds the customer-facing /book/<slug> page: service/slot picker, booking
form, and confirmation screen, built on #16's existing booking JSON API.
Includes iframe auto-fit height reporting (mirroring
deploy/booking/booking_layout.js's eaBookingHeight message), brand-color
theming via a ?color= query param, a honeypot field with a fake-success
response indistinguishable from a real booking, and a clear "just taken"
message on slot-conflict. Caddy per-IP rate limiting is documented in
deploy/booking/RATE_LIMIT.md for manual application (no Caddyfile is
tracked in this repo).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 15:15:29 +02:00
parent 2f6e0c1459
commit b895663c3a
7 changed files with 556 additions and 5 deletions
+2
View File
@@ -20,9 +20,11 @@ from waitress import serve
import db
from sheets import Sheets
from booking_api import bp as booking_bp
from public_booking import bp as public_booking_bp
app = Flask(__name__, static_folder="static", static_url_path="")
app.register_blueprint(booking_bp)
app.register_blueprint(public_booking_bp)
CRM_TOKEN = os.environ.get("CRM_API_TOKEN", "")
# Separate read-only token for the public iCal feed (calendar apps can't send