feat: online booking portal (closes groombook/groombook#3) (#27)
Add customer-facing booking flow with three public API endpoints (/api/book/services, /api/book/availability, /api/book/appointments) and a four-step React wizard (service → date/time → contact info → confirm). Availability is computed from real groomer schedules with slot-level conflict detection. Booking auto-creates or matches clients by email and uses a transaction to guard against race conditions. Co-authored-by: Groom Book CTO <cto@groombook.app> Co-authored-by: Paperclip <noreply@paperclip.ing>
This commit was merged in pull request #27.
This commit is contained in:
committed by
GitHub
parent
b767a00b5f
commit
e524099214
@@ -4,6 +4,7 @@ import { ClientsPage } from "./pages/Clients.js";
|
||||
import { ServicesPage } from "./pages/Services.js";
|
||||
import { StaffPage } from "./pages/Staff.js";
|
||||
import { InvoicesPage } from "./pages/Invoices.js";
|
||||
import { BookPage } from "./pages/Book.js";
|
||||
|
||||
const NAV_LINKS = [
|
||||
{ to: "/", label: "Appointments" },
|
||||
@@ -28,6 +29,21 @@ export function App() {
|
||||
}}
|
||||
>
|
||||
<strong style={{ marginRight: "1rem", fontSize: 16 }}>Groom Book</strong>
|
||||
<Link
|
||||
to="/book"
|
||||
style={{
|
||||
padding: "0.35rem 0.75rem",
|
||||
borderRadius: 4,
|
||||
textDecoration: "none",
|
||||
fontSize: 14,
|
||||
fontWeight: 600,
|
||||
color: "#fff",
|
||||
background: "#4f8a6f",
|
||||
marginRight: "0.5rem",
|
||||
}}
|
||||
>
|
||||
Book
|
||||
</Link>
|
||||
{NAV_LINKS.map(({ to, label }) => {
|
||||
const active =
|
||||
to === "/" ? location.pathname === "/" : location.pathname.startsWith(to);
|
||||
@@ -57,6 +73,7 @@ export function App() {
|
||||
<Route path="/services" element={<ServicesPage />} />
|
||||
<Route path="/staff" element={<StaffPage />} />
|
||||
<Route path="/invoices" element={<InvoicesPage />} />
|
||||
<Route path="/book" element={<BookPage />} />
|
||||
</Routes>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user