Files
smoothschedule/frontend/src/puckConfig.tsx
poduck 4a66246708 Add booking flow, business hours, and dark mode support
Features:
- Complete multi-step booking flow with service selection, date/time picker,
  auth (login/signup with email verification), payment, and confirmation
- Business hours settings page for defining when business is open
- TimeBlock purpose field (BUSINESS_HOURS, CLOSURE, UNAVAILABLE)
- Service resource assignment with prep/takedown time buffers
- Availability checking respects business hours and service buffers
- Customer registration via email verification code

UI/UX:
- Full dark mode support for all booking components
- Separate first/last name fields in signup form
- Back buttons on each wizard step
- Removed auto-redirect from confirmation page

API:
- Public endpoints for services, availability, business hours
- Customer verification and registration endpoints
- Tenant lookup from X-Business-Subdomain header

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-11 20:20:18 -05:00

121 lines
4.2 KiB
TypeScript

import React from "react";
import type { Config } from "@measured/puck";
import BookingWidget from "./components/booking/BookingWidget";
import { ArrowRight } from "lucide-react";
type Props = {
Hero: {
title: string;
subtitle: string;
align: "left" | "center" | "right";
ctaText?: string;
ctaLink?: string;
};
TextSection: { heading: string; body: string };
Booking: { headline: string; subheading: string };
};
export const config: Config<Props> = {
components: {
Hero: {
fields: {
title: { type: "text" },
subtitle: { type: "text" },
align: {
type: "radio",
options: [
{ label: "Left", value: "left" },
{ label: "Center", value: "center" },
{ label: "Right", value: "right" },
],
},
ctaText: { type: "text", label: "Button Text" },
ctaLink: { type: "text", label: "Button Link" },
},
defaultProps: {
title: "Welcome to our site",
subtitle: "We provide great services",
align: "center",
ctaText: "Book Now",
ctaLink: "/book",
},
render: ({ title, subtitle, align, ctaText, ctaLink }) => (
<section className="relative bg-gradient-to-br from-gray-50 to-white dark:from-gray-900 dark:to-gray-800 py-20 sm:py-28">
<div className="absolute inset-0 bg-grid-pattern opacity-[0.02] dark:opacity-[0.05]"></div>
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className={`relative z-10 ${align === 'center' ? 'text-center' : align === 'right' ? 'text-right' : 'text-left'}`}>
<h1 className="text-5xl sm:text-6xl lg:text-7xl font-bold text-gray-900 dark:text-white mb-6 tracking-tight">
{title}
</h1>
<p className="text-xl sm:text-2xl text-gray-600 dark:text-gray-300 mb-10 max-w-3xl mx-auto leading-relaxed">
{subtitle}
</p>
{ctaText && ctaLink && (
<a
href={ctaLink}
className="inline-flex items-center px-8 py-4 bg-indigo-600 dark:bg-indigo-500 text-white text-lg font-semibold rounded-xl shadow-lg hover:bg-indigo-700 dark:hover:bg-indigo-600 hover:shadow-xl transform hover:-translate-y-0.5 transition-all duration-200"
>
{ctaText}
<ArrowRight className="ml-2 w-5 h-5" />
</a>
)}
</div>
</div>
</section>
),
},
TextSection: {
fields: {
heading: { type: "text" },
body: { type: "textarea" },
},
defaultProps: {
heading: "About Us",
body: "Enter your text here...",
},
render: ({ heading, body }) => (
<section className="py-16 sm:py-20 bg-white dark:bg-gray-900">
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
<h2 className="text-3xl sm:text-4xl font-bold text-gray-900 dark:text-white mb-6">
{heading}
</h2>
<div className="text-lg text-gray-600 dark:text-gray-300 leading-relaxed whitespace-pre-wrap">
{body}
</div>
</div>
</section>
),
},
Booking: {
fields: {
headline: { type: "text" },
subheading: { type: "text" },
},
defaultProps: {
headline: "Schedule Your Appointment",
subheading: "Choose a service and time that works for you",
},
render: ({ headline, subheading }) => (
<section className="py-16 sm:py-20 bg-gray-50 dark:bg-gray-800">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12">
<h2 className="text-3xl sm:text-4xl font-bold text-gray-900 dark:text-white mb-4">
{headline}
</h2>
<p className="text-lg text-gray-600 dark:text-gray-300 max-w-2xl mx-auto">
{subheading}
</p>
</div>
<BookingWidget
headline={headline}
subheading={subheading}
accentColor="#4f46e5"
buttonLabel="Book Now"
/>
</div>
</section>
),
},
},
};