feat: polished appointment booking UI for LinkedIn CTA #6
No reviewers
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
ldraney/gcal-scheduler!6
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "5-feat-polished-appointment-booking-ui-for"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Replaces the bare placeholder
static/index.htmlwith a production-grade appointment booking page for Pal-E Agency's LinkedIn CTA. Professional consulting aesthetic with warm color palette, distinctive typography, mobile-first responsive design, and complete booking flow with error/success handling.Changes
static/index.html-- Complete rewrite from 16-line placeholder to full booking UI:GET /api/availability, splits large availability windows into 30-minute slots, groups by calendar day with "Today"/"Tomorrow" labelsPOST /api/book, shows spinner during request, handles 409 conflicts and API errors gracefullyprefers-reduced-motionsupport, semantic HTMLTest Plan
/and verify slots load for next 7 daysReview Checklist
static/index.htmlmodified)Related
plan-pal-e-posts-- Phase 1 (gcal-scheduler Booking UI)Self-Review Findings
Three issues identified and fixed in commit
c2af53c:1. ARIA semantic mismatch (accessibility)
Before:
role="listbox"on slots grid withrole="option"on<button>elements. Buttons inside a listbox is semantically invalid per WAI-ARIA spec -- listbox options must not be interactive elements.Fix: Changed to
role="group"on the grid andaria-pressed="true/false"on buttons (toggle button pattern).2. Non-JSON error response crash (resilience)
Before: Error handling called
res.json().then(...)directly. If the server returns a non-JSON error (e.g., 502 from a reverse proxy, or HTML error page),res.json()throws, and the user-facing error message is lost.Fix: Added
.catch(function() { return {}; })before.then()so non-JSON responses gracefully fall through to the default error message. Applied to both/api/availabilityand/api/bookfetch calls.3. Submit button reset after success (cosmetic, not fixed)
The
.finally()block resets the submit button text and disabled state even after a successful booking. This is harmless since the form is hidden byshowSuccess(), so no user-visible impact. Left as-is to avoid adding state tracking complexity for zero UX benefit.