@clicka1/booking 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,171 @@
1
+ # @clicka1/booking
2
+
3
+ White-label booking widget for salon sites powered by the Clicka engine API.
4
+
5
+ ## What This Package Does
6
+
7
+ - makes booking easy to attach inside a React or Next.js site
8
+ - keeps the booking UX inside the client-owned website
9
+ - talks to Clicka only through the public engine API
10
+
11
+ This package does **not** create the salon tenant in Clicka.
12
+
13
+ That is a separate operator flow:
14
+
15
+ 1. create the salon in Clicka from `/pa`
16
+ 2. choose and save the slug
17
+ 3. return the operator/admin magic link
18
+ 4. use that slug in the client site integration
19
+
20
+ Example:
21
+
22
+ - salon created in Clicka: `diworks`
23
+ - client site integration uses: `salonSlug="diworks"`
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ npm install @clicka1/booking
29
+ ```
30
+
31
+ Peer deps: `react ^18 || ^19`, `react-dom ^18 || ^19`, `lucide-react`.
32
+
33
+ ## Recommended DX
34
+
35
+ ### Fastest Manual Setup
36
+
37
+ ```tsx
38
+ 'use client';
39
+
40
+ import { BookingProvider, BookingButton } from '@clicka1/booking';
41
+ import '@clicka1/booking/styles.css';
42
+
43
+ export function AppShell({ children }: { children: React.ReactNode }) {
44
+ return (
45
+ <BookingProvider
46
+ salonSlug={process.env.NEXT_PUBLIC_SALON_SLUG}
47
+ engineUrl={process.env.NEXT_PUBLIC_ENGINE_URL}
48
+ successUrl={`${process.env.NEXT_PUBLIC_SITE_URL}/booking/success`}
49
+ cancelUrl={`${process.env.NEXT_PUBLIC_SITE_URL}/booking/cancel`}
50
+ >
51
+ {children}
52
+ </BookingProvider>
53
+ );
54
+ }
55
+
56
+ export function HeroCta() {
57
+ return <BookingButton service="free-call">Book a Free Call</BookingButton>;
58
+ }
59
+ ```
60
+
61
+ ### One-Command Onboarding
62
+
63
+ ```bash
64
+ npx @clicka1/clicka init
65
+ ```
66
+
67
+ The `clicka init` flow is meant to:
68
+
69
+ - add `@clicka1/booking`
70
+ - add the CSS import
71
+ - mount a provider near the app root
72
+ - add the required env placeholders
73
+ - make CTA wiring straightforward
74
+
75
+ ## Environment Variables
76
+
77
+ Supported engine env names:
78
+
79
+ - `NEXT_PUBLIC_ENGINE_URL`
80
+ - `NEXT_PUBLIC_CLICKA_ENGINE`
81
+ - `NEXT_PUBLIC_CLICKA_API_URL`
82
+
83
+ Recommended client-site envs:
84
+
85
+ ```bash
86
+ NEXT_PUBLIC_ENGINE_URL=https://www.clicka.bg
87
+ NEXT_PUBLIC_SALON_SLUG=diworks
88
+ NEXT_PUBLIC_SITE_URL=https://diworks.example
89
+ ```
90
+
91
+ ## Usage
92
+
93
+ ```tsx
94
+ 'use client';
95
+
96
+ import { BookingProvider, BookingButton } from '@clicka1/booking';
97
+ import '@clicka1/booking/styles.css';
98
+
99
+ export function Root({ children }: { children: React.ReactNode }) {
100
+ return (
101
+ <BookingProvider salonSlug="my-salon" engineUrl="https://www.clicka.bg">
102
+ {children}
103
+ <BookingButton>Book now</BookingButton>
104
+ </BookingProvider>
105
+ );
106
+ }
107
+ ```
108
+
109
+ If you already have your own button markup, keep it and add the attribute:
110
+
111
+ ```tsx
112
+ <button data-clicka-book>Book now</button>
113
+ <button data-clicka-book="free-call">Book a Free Call</button>
114
+ ```
115
+
116
+ ## API surface
117
+
118
+ ### `BookingProvider`
119
+
120
+ | Prop | Type | Notes |
121
+ | --- | --- | --- |
122
+ | `salonSlug?` | `string` | Salon tenant slug. Falls back to env, meta tag, or `window` globals. |
123
+ | `engineUrl?` | `string` | Clicka engine origin. Falls back to env, meta tag, or `window` globals. |
124
+ | `locale?` | `string` | BCP-47 locale. Defaults from `<html lang>`, then browser locale. |
125
+ | `successUrl?` | `string` | Stripe success redirect on the client-owned site. |
126
+ | `cancelUrl?` | `string` | Stripe cancel redirect on the client-owned site. |
127
+ | `accentGradient?` | `string` | Accent styling override. |
128
+ | `formatPrice?` | `(n: number) => string` | Custom formatter. |
129
+ | `onEvent?` | `(name, payload?) => void` | Booking analytics hook. |
130
+ | `basePath?` | `string` | Prefix for legal links. |
131
+ | `autoTriggers?` | `boolean` | Enables `[data-clicka-book]` click delegation. Default: `true`. |
132
+ | `honorUrlParams?` | `boolean` | Auto-opens for `?service=` or `?book=1`. Default: `true`. |
133
+
134
+ ### `BookingButton`
135
+
136
+ | Prop | Type | Notes |
137
+ | --- | --- | --- |
138
+ | `service?` | `string` | Pre-selects this service on open. |
139
+ | `...buttonProps` | `React.ButtonHTMLAttributes<HTMLButtonElement>` | Keeps consumer classes, styles, and handlers. |
140
+
141
+ ### Advanced
142
+
143
+ The raw `BookingWidget` export still exists for custom control over state and
144
+ rendering.
145
+
146
+ ## Engine API requirements
147
+
148
+ The SDK calls **only** these versioned public endpoints — `engineUrl + path`:
149
+
150
+ - `GET /api/public/v1/salons/:slug/staff`
151
+ - `GET /api/public/v1/salons/:slug/slots?date=YYYY-MM-DD&staffMemberId=…`
152
+ - `POST /api/public/v1/salons/:slug/bookings`
153
+ - `POST /api/public/v1/salons/:slug/booking-checkout`
154
+
155
+ All endpoints respond with permissive CORS (`Access-Control-Allow-Origin: *`).
156
+
157
+ ## Styling
158
+
159
+ The widget ships a pre-compiled Tailwind CSS bundle (`dist/booking.css`). Import
160
+ it once at the top of your app or inside the component tree:
161
+
162
+ ```ts
163
+ import '@clicka1/booking/styles.css';
164
+ ```
165
+
166
+ No Tailwind config is required in the consumer project. The bundle is scoped to
167
+ utilities the widget actually uses.
168
+
169
+ ## License
170
+
171
+ Public package for Clicka-powered client-site integrations.