@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 +171 -0
- package/dist/SalonBookingModal-ZIIKN2O2.js +941 -0
- package/dist/SalonBookingModal-ZIIKN2O2.js.map +1 -0
- package/dist/booking.css +2 -0
- package/dist/chunk-HA7DFBYI.js +548 -0
- package/dist/chunk-HA7DFBYI.js.map +1 -0
- package/dist/index.d.ts +192 -0
- package/dist/index.js +970 -0
- package/dist/index.js.map +1 -0
- package/package.json +37 -0
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.
|