@chronowl/widget 1.0.0
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/LICENSE +21 -0
- package/dist/ChronOwlWidget.d.ts +22 -0
- package/dist/components/atoms/Badge.d.ts +10 -0
- package/dist/components/atoms/Button.d.ts +10 -0
- package/dist/components/atoms/Card.d.ts +9 -0
- package/dist/components/atoms/Divider.d.ts +9 -0
- package/dist/components/atoms/Icon.d.ts +10 -0
- package/dist/components/atoms/Input.d.ts +10 -0
- package/dist/components/atoms/Label.d.ts +9 -0
- package/dist/components/atoms/Spinner.d.ts +9 -0
- package/dist/components/atoms/Typography.d.ts +10 -0
- package/dist/components/atoms/index.d.ts +9 -0
- package/dist/components/hooks/useAvailability.d.ts +11 -0
- package/dist/components/hooks/useBooking.d.ts +12 -0
- package/dist/components/hooks/useForm.d.ts +19 -0
- package/dist/components/hooks/useServices.d.ts +10 -0
- package/dist/components/index.d.ts +5 -0
- package/dist/components/molecules/AvailabilitySlot.d.ts +9 -0
- package/dist/components/molecules/ButtonGroup.d.ts +9 -0
- package/dist/components/molecules/ConfirmationBadge.d.ts +9 -0
- package/dist/components/molecules/DateSelector.d.ts +10 -0
- package/dist/components/molecules/EmptyState.d.ts +9 -0
- package/dist/components/molecules/FormGroup.d.ts +10 -0
- package/dist/components/molecules/InputWithIcon.d.ts +9 -0
- package/dist/components/molecules/LoadingState.d.ts +9 -0
- package/dist/components/molecules/ServiceCard.d.ts +10 -0
- package/dist/components/molecules/TimeSelector.d.ts +9 -0
- package/dist/components/molecules/index.d.ts +10 -0
- package/dist/components/organisms/AvailabilityGrid.d.ts +9 -0
- package/dist/components/organisms/BookingForm.d.ts +10 -0
- package/dist/components/organisms/Calendar.d.ts +10 -0
- package/dist/components/organisms/ConfirmationModal.d.ts +10 -0
- package/dist/components/organisms/ErrorModal.d.ts +9 -0
- package/dist/components/organisms/Footer.d.ts +9 -0
- package/dist/components/organisms/Header.d.ts +10 -0
- package/dist/components/organisms/ServiceList.d.ts +9 -0
- package/dist/components/organisms/Stepper.d.ts +10 -0
- package/dist/components/organisms/TimeSlotSelector.d.ts +10 -0
- package/dist/components/organisms/index.d.ts +10 -0
- package/dist/components/pages/BookingPage.d.ts +17 -0
- package/dist/components/pages/ConfirmationPage.d.ts +16 -0
- package/dist/components/pages/ErrorPage.d.ts +14 -0
- package/dist/components/pages/index.d.ts +3 -0
- package/dist/components/templates/BookingPageTemplate.d.ts +11 -0
- package/dist/components/templates/CenteredLayout.d.ts +9 -0
- package/dist/components/templates/MainLayout.d.ts +11 -0
- package/dist/components/templates/index.d.ts +3 -0
- package/dist/constants/api.d.ts +14 -0
- package/dist/constants/design.d.ts +56 -0
- package/dist/favicon.svg +21 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +2053 -0
- package/dist/style.css +1 -0
- package/dist/tokens/borders.d.ts +14 -0
- package/dist/tokens/colors.d.ts +56 -0
- package/dist/tokens/elevation.d.ts +15 -0
- package/dist/tokens/index.d.ts +12 -0
- package/dist/tokens/motion.d.ts +38 -0
- package/dist/tokens/spacing.d.ts +28 -0
- package/dist/tokens/typography.d.ts +107 -0
- package/dist/types/api.d.ts +43 -0
- package/dist/types/booking.d.ts +50 -0
- package/dist/types/components.d.ts +242 -0
- package/dist/utils/api.d.ts +10 -0
- package/dist/utils/helpers.d.ts +3 -0
- package/dist/utils/validators.d.ts +6 -0
- package/package.json +55 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { ReactNode, ButtonHTMLAttributes, InputHTMLAttributes, HTMLAttributes, SVGAttributes } from 'react';
|
|
2
|
+
|
|
3
|
+
export type Size = 'sm' | 'md' | 'lg';
|
|
4
|
+
export type ButtonVariant = 'filled' | 'tonal' | 'outlined' | 'text';
|
|
5
|
+
export type ButtonColor = 'primary' | 'secondary' | 'error' | 'success' | 'warning';
|
|
6
|
+
export type BadgeVariant = 'confirmed' | 'pending' | 'cancelled' | 'completed' | 'info';
|
|
7
|
+
export type TypographyVariant = 'display-lg' | 'display-md' | 'display-sm' | 'headline-lg' | 'headline-md' | 'headline-sm' | 'title-lg' | 'title-md' | 'title-sm' | 'body-lg' | 'body-md' | 'body-sm' | 'label-lg' | 'label-md' | 'label-sm';
|
|
8
|
+
export type TypographyAs = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'span' | 'small' | 'label' | 'caption';
|
|
9
|
+
export interface Service {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
duration: number;
|
|
14
|
+
price: number;
|
|
15
|
+
currency: string;
|
|
16
|
+
category?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface TimeSlot {
|
|
19
|
+
id: string;
|
|
20
|
+
startTime: string;
|
|
21
|
+
endTime: string;
|
|
22
|
+
available: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface BookingData {
|
|
25
|
+
serviceId: string;
|
|
26
|
+
date: string;
|
|
27
|
+
timeSlotId: string;
|
|
28
|
+
clientName: string;
|
|
29
|
+
clientEmail: string;
|
|
30
|
+
clientPhone: string;
|
|
31
|
+
notes?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface BookingConfirmation {
|
|
34
|
+
id: string;
|
|
35
|
+
service: Service;
|
|
36
|
+
date: string;
|
|
37
|
+
timeSlot: TimeSlot;
|
|
38
|
+
clientName: string;
|
|
39
|
+
clientEmail: string;
|
|
40
|
+
status: BadgeVariant;
|
|
41
|
+
createdAt: string;
|
|
42
|
+
}
|
|
43
|
+
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
44
|
+
variant?: ButtonVariant;
|
|
45
|
+
color?: ButtonColor;
|
|
46
|
+
size?: Size;
|
|
47
|
+
fullWidth?: boolean;
|
|
48
|
+
loading?: boolean;
|
|
49
|
+
icon?: ReactNode;
|
|
50
|
+
iconPosition?: 'start' | 'end';
|
|
51
|
+
}
|
|
52
|
+
export interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
|
|
53
|
+
label?: string;
|
|
54
|
+
error?: string;
|
|
55
|
+
helperText?: string;
|
|
56
|
+
leadingIcon?: ReactNode;
|
|
57
|
+
trailingIcon?: ReactNode;
|
|
58
|
+
fullWidth?: boolean;
|
|
59
|
+
}
|
|
60
|
+
export interface LabelProps extends HTMLAttributes<HTMLLabelElement> {
|
|
61
|
+
htmlFor?: string;
|
|
62
|
+
required?: boolean;
|
|
63
|
+
children: ReactNode;
|
|
64
|
+
}
|
|
65
|
+
export interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
|
|
66
|
+
variant: BadgeVariant;
|
|
67
|
+
size?: Size;
|
|
68
|
+
icon?: ReactNode;
|
|
69
|
+
}
|
|
70
|
+
export interface CardProps extends HTMLAttributes<HTMLDivElement> {
|
|
71
|
+
elevation?: 0 | 1 | 2 | 3 | 4 | 5;
|
|
72
|
+
outlined?: boolean;
|
|
73
|
+
padding?: Size;
|
|
74
|
+
children: ReactNode;
|
|
75
|
+
}
|
|
76
|
+
export interface DividerProps extends HTMLAttributes<HTMLHRElement> {
|
|
77
|
+
orientation?: 'horizontal' | 'vertical';
|
|
78
|
+
inset?: boolean;
|
|
79
|
+
}
|
|
80
|
+
export type IconName = 'calendar' | 'clock' | 'check' | 'close' | 'chevron-left' | 'chevron-right' | 'chevron-down' | 'search' | 'user' | 'mail' | 'phone' | 'notes' | 'alert' | 'info' | 'star' | 'location' | 'edit' | 'trash' | 'arrow-left' | 'arrow-right' | 'spinner' | 'owl';
|
|
81
|
+
export interface IconProps extends SVGAttributes<SVGSVGElement> {
|
|
82
|
+
name: IconName;
|
|
83
|
+
size?: Size;
|
|
84
|
+
color?: string;
|
|
85
|
+
}
|
|
86
|
+
export interface SpinnerProps extends HTMLAttributes<HTMLDivElement> {
|
|
87
|
+
size?: Size;
|
|
88
|
+
color?: string;
|
|
89
|
+
}
|
|
90
|
+
export interface TypographyProps extends HTMLAttributes<HTMLElement> {
|
|
91
|
+
variant?: TypographyVariant;
|
|
92
|
+
as?: TypographyAs;
|
|
93
|
+
color?: string;
|
|
94
|
+
truncate?: boolean;
|
|
95
|
+
align?: 'left' | 'center' | 'right';
|
|
96
|
+
children: ReactNode;
|
|
97
|
+
}
|
|
98
|
+
export interface FormGroupProps {
|
|
99
|
+
label: string;
|
|
100
|
+
htmlFor: string;
|
|
101
|
+
error?: string;
|
|
102
|
+
helperText?: string;
|
|
103
|
+
required?: boolean;
|
|
104
|
+
children: ReactNode;
|
|
105
|
+
}
|
|
106
|
+
export interface TimeSelectorProps {
|
|
107
|
+
slots: TimeSlot[];
|
|
108
|
+
selectedSlotId?: string;
|
|
109
|
+
onSelectSlot: (slot: TimeSlot) => void;
|
|
110
|
+
loading?: boolean;
|
|
111
|
+
}
|
|
112
|
+
export interface DateSelectorProps {
|
|
113
|
+
selectedDate?: Date;
|
|
114
|
+
onSelectDate: (date: Date) => void;
|
|
115
|
+
minDate?: Date;
|
|
116
|
+
maxDate?: Date;
|
|
117
|
+
disabledDates?: string[];
|
|
118
|
+
availableDates?: string[];
|
|
119
|
+
}
|
|
120
|
+
export interface ServiceCardProps {
|
|
121
|
+
service: Service;
|
|
122
|
+
selected?: boolean;
|
|
123
|
+
onSelect: (service: Service) => void;
|
|
124
|
+
}
|
|
125
|
+
export interface AvailabilitySlotProps {
|
|
126
|
+
slot: TimeSlot;
|
|
127
|
+
selected?: boolean;
|
|
128
|
+
onSelect: (slot: TimeSlot) => void;
|
|
129
|
+
}
|
|
130
|
+
export interface ConfirmationBadgeProps {
|
|
131
|
+
status: BadgeVariant;
|
|
132
|
+
label: string;
|
|
133
|
+
}
|
|
134
|
+
export interface EmptyStateProps {
|
|
135
|
+
icon?: IconName;
|
|
136
|
+
title: string;
|
|
137
|
+
description?: string;
|
|
138
|
+
action?: {
|
|
139
|
+
label: string;
|
|
140
|
+
onClick: () => void;
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
export interface LoadingStateProps {
|
|
144
|
+
message?: string;
|
|
145
|
+
size?: Size;
|
|
146
|
+
}
|
|
147
|
+
export interface InputWithIconProps extends InputProps {
|
|
148
|
+
icon: ReactNode;
|
|
149
|
+
iconPosition?: 'start' | 'end';
|
|
150
|
+
}
|
|
151
|
+
export interface ButtonGroupProps {
|
|
152
|
+
children: ReactNode;
|
|
153
|
+
orientation?: 'horizontal' | 'vertical';
|
|
154
|
+
fullWidth?: boolean;
|
|
155
|
+
}
|
|
156
|
+
export interface HeaderProps {
|
|
157
|
+
title?: string;
|
|
158
|
+
subtitle?: string;
|
|
159
|
+
onBack?: () => void;
|
|
160
|
+
actions?: ReactNode;
|
|
161
|
+
}
|
|
162
|
+
export interface StepperProps {
|
|
163
|
+
steps: string[];
|
|
164
|
+
currentStep: number;
|
|
165
|
+
onStepClick?: (step: number) => void;
|
|
166
|
+
}
|
|
167
|
+
export interface ServiceListProps {
|
|
168
|
+
services: Service[];
|
|
169
|
+
selectedServiceId?: string;
|
|
170
|
+
onSelectService: (service: Service) => void;
|
|
171
|
+
loading?: boolean;
|
|
172
|
+
}
|
|
173
|
+
export interface CalendarProps {
|
|
174
|
+
selectedDate?: Date;
|
|
175
|
+
onSelectDate: (date: Date) => void;
|
|
176
|
+
minDate?: Date;
|
|
177
|
+
maxDate?: Date;
|
|
178
|
+
disabledDates?: string[];
|
|
179
|
+
availableDates?: string[];
|
|
180
|
+
}
|
|
181
|
+
export interface AvailabilityGridProps {
|
|
182
|
+
slots: TimeSlot[];
|
|
183
|
+
selectedSlotId?: string;
|
|
184
|
+
onSelectSlot: (slot: TimeSlot) => void;
|
|
185
|
+
loading?: boolean;
|
|
186
|
+
}
|
|
187
|
+
export interface BookingFormProps {
|
|
188
|
+
onSubmit: (data: Omit<BookingData, 'serviceId' | 'date' | 'timeSlotId'>) => void;
|
|
189
|
+
loading?: boolean;
|
|
190
|
+
initialValues?: Partial<BookingData>;
|
|
191
|
+
}
|
|
192
|
+
export interface ConfirmationModalProps {
|
|
193
|
+
open: boolean;
|
|
194
|
+
onClose: () => void;
|
|
195
|
+
confirmation: BookingConfirmation | null;
|
|
196
|
+
onNewBooking?: () => void;
|
|
197
|
+
}
|
|
198
|
+
export interface ErrorModalProps {
|
|
199
|
+
open: boolean;
|
|
200
|
+
onClose: () => void;
|
|
201
|
+
title?: string;
|
|
202
|
+
message: string;
|
|
203
|
+
onRetry?: () => void;
|
|
204
|
+
}
|
|
205
|
+
export interface TimeSlotSelectorProps {
|
|
206
|
+
slots: TimeSlot[];
|
|
207
|
+
selectedSlotId?: string;
|
|
208
|
+
onSelectSlot: (slot: TimeSlot) => void;
|
|
209
|
+
columns?: number;
|
|
210
|
+
}
|
|
211
|
+
export interface FooterProps {
|
|
212
|
+
companyName?: string;
|
|
213
|
+
poweredBy?: boolean;
|
|
214
|
+
}
|
|
215
|
+
export interface MainLayoutProps {
|
|
216
|
+
header?: ReactNode;
|
|
217
|
+
footer?: ReactNode;
|
|
218
|
+
children: ReactNode;
|
|
219
|
+
}
|
|
220
|
+
export interface CenteredLayoutProps {
|
|
221
|
+
children: ReactNode;
|
|
222
|
+
maxWidth?: string;
|
|
223
|
+
}
|
|
224
|
+
export interface BookingPageTemplateProps {
|
|
225
|
+
steps: string[];
|
|
226
|
+
currentStep: number;
|
|
227
|
+
onStepClick?: (step: number) => void;
|
|
228
|
+
onBack?: () => void;
|
|
229
|
+
title?: string;
|
|
230
|
+
children: ReactNode;
|
|
231
|
+
footer?: ReactNode;
|
|
232
|
+
}
|
|
233
|
+
export type BookingStep = 'service' | 'datetime' | 'form' | 'confirmation';
|
|
234
|
+
export interface ChronOwlWidgetProps {
|
|
235
|
+
services: Service[];
|
|
236
|
+
onFetchSlots: (serviceId: string, date: string) => Promise<TimeSlot[]>;
|
|
237
|
+
onSubmitBooking: (data: BookingData) => Promise<BookingConfirmation>;
|
|
238
|
+
theme?: 'light' | 'dark';
|
|
239
|
+
locale?: string;
|
|
240
|
+
companyName?: string;
|
|
241
|
+
className?: string;
|
|
242
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ApiConfig, BookingResponse, CreateBookingParams } from '../types/api';
|
|
2
|
+
import { Service, TimeSlot } from '../types/components';
|
|
3
|
+
|
|
4
|
+
export declare function configureApi(newConfig: Partial<ApiConfig>): void;
|
|
5
|
+
export declare const chronowlApi: {
|
|
6
|
+
getServices(saasId?: string): Promise<Service[]>;
|
|
7
|
+
getAvailability(serviceId: string, date: string, saasId?: string): Promise<TimeSlot[]>;
|
|
8
|
+
createBooking(params: CreateBookingParams): Promise<BookingResponse>;
|
|
9
|
+
cancelBooking(bookingId: string, saasId?: string): Promise<BookingResponse>;
|
|
10
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function validateEmail(email: string): boolean;
|
|
2
|
+
export declare function validatePhone(phone: string): boolean;
|
|
3
|
+
export declare function validateRequired(value: string): boolean;
|
|
4
|
+
export declare function formatDate(date: Date, locale?: string): string;
|
|
5
|
+
export declare function formatDateShort(date: Date, locale?: string): string;
|
|
6
|
+
export declare function dateToString(date: Date): string;
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@chronowl/widget",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "ChronOwl - Sabia gestión del tiempo para tus citas. Widget de reservas/citas reutilizable.",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.mjs",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"dev": "vite",
|
|
14
|
+
"build": "tsc && vite build",
|
|
15
|
+
"preview": "vite preview",
|
|
16
|
+
"lint": "eslint src --ext .ts,.tsx",
|
|
17
|
+
"type-check": "tsc --noEmit"
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
21
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/react": "^18.2.0",
|
|
25
|
+
"@types/react-dom": "^18.2.0",
|
|
26
|
+
"autoprefixer": "^10.4.16",
|
|
27
|
+
"postcss": "^8.4.32",
|
|
28
|
+
"react": "^18.2.0",
|
|
29
|
+
"react-dom": "^18.2.0",
|
|
30
|
+
"tailwindcss": "^3.4.0",
|
|
31
|
+
"typescript": "^5.3.0",
|
|
32
|
+
"@vitejs/plugin-react": "^4.2.0",
|
|
33
|
+
"vite": "^5.0.0",
|
|
34
|
+
"vite-plugin-dts": "^3.7.0"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"chronowl",
|
|
38
|
+
"booking",
|
|
39
|
+
"widget",
|
|
40
|
+
"appointments",
|
|
41
|
+
"scheduling",
|
|
42
|
+
"react",
|
|
43
|
+
"design-system",
|
|
44
|
+
"stitch",
|
|
45
|
+
"material-design-3"
|
|
46
|
+
],
|
|
47
|
+
"license": "MIT",
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "https://github.com/chronowl/widget"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
}
|
|
55
|
+
}
|