@akinon/pz-virtual-try-on 1.119.0-rc.3 → 2.0.0-beta.13

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.
@@ -1,308 +0,0 @@
1
- import React from 'react';
2
- import { Product, Pagination, Facet, SortOption } from '@akinon/next/types';
3
-
4
- // ==================== BARCODE SCANNER TYPES ====================
5
-
6
- export type BarcodeFormat =
7
- | 'QR_CODE'
8
- | 'DATA_MATRIX'
9
- | 'AZTEC'
10
- | 'PDF_417'
11
- | 'EAN_8'
12
- | 'EAN_13'
13
- | 'UPC_A'
14
- | 'UPC_E'
15
- | 'CODE_39'
16
- | 'CODE_93'
17
- | 'CODE_128'
18
- | 'CODABAR'
19
- | 'ITF'
20
- | 'RSS_14'
21
- | 'RSS_EXPANDED';
22
-
23
- export interface BarcodeScanResult {
24
- text: string;
25
- format: BarcodeFormat;
26
- timestamp: number;
27
- }
28
-
29
- export interface BarcodeSearchResponse {
30
- pagination: Pagination;
31
- facets: Facet[];
32
- sorters: SortOption[];
33
- search_text: string | null;
34
- products: Product[];
35
- }
36
-
37
- export interface BarcodeSearchRequest {
38
- barcode: string;
39
- page?: number;
40
- limit?: number;
41
- }
42
-
43
- export interface BarcodeScannerState {
44
- isScanning: boolean;
45
- hasPermission: boolean | null;
46
- error: string | null;
47
- lastScanResult: BarcodeScanResult | null;
48
- }
49
-
50
- export interface ScannedProductState {
51
- products: Product[];
52
- isLoading: boolean;
53
- error: string | null;
54
- searchedBarcode: string | null;
55
- }
56
-
57
- // ==================== BARCODE COMPONENT PROPS ====================
58
-
59
- export interface BarcodeScannerButtonProps {
60
- onClick: () => void;
61
- className?: string;
62
- disabled?: boolean;
63
- settings?: BarcodeScannerSettings;
64
- style?: React.CSSProperties;
65
- }
66
-
67
- export interface BarcodeScannerModalProps {
68
- isOpen: boolean;
69
- onClose: () => void;
70
- onProductFound?: (products: Product[]) => void;
71
- onContinueToVTO?: (products: Product[]) => void;
72
- className?: string;
73
- settings?: BarcodeScannerSettings;
74
- }
75
-
76
- export interface BarcodeScannerProps {
77
- onScan: (result: BarcodeScanResult) => void;
78
- onError?: (error: Error) => void;
79
- onPermissionDenied?: () => void;
80
- isActive: boolean;
81
- className?: string;
82
- settings?: BarcodeScannerSettings;
83
- }
84
-
85
- export interface ScannedProductCardProps {
86
- product: Product;
87
- isSelected?: boolean;
88
- onSelect?: (product: Product) => void;
89
- onRemove?: (product: Product) => void;
90
- className?: string;
91
- settings?: BarcodeScannerSettings;
92
- }
93
-
94
- // ==================== BARCODE SETTINGS ====================
95
-
96
- export interface BarcodeScannerSettings {
97
- customStyles?: BarcodeScannerCustomStyles;
98
- customRenderers?: BarcodeScannerCustomRenderers;
99
- theme?: BarcodeScannerTheme;
100
- cssVariables?: Record<string, string>;
101
- // Supported barcode formats - defaults to all
102
- supportedFormats?: BarcodeFormat[];
103
- // Maximum number of products that can be scanned
104
- maxProducts?: number;
105
- // Whether to show the continue to VTO button
106
- showContinueToVTO?: boolean;
107
- // Sound on successful scan
108
- playScanSound?: boolean;
109
- // Vibrate on successful scan (mobile)
110
- vibrateOnScan?: boolean;
111
- }
112
-
113
- export interface BarcodeScannerTheme {
114
- colors?: {
115
- primary?: string;
116
- secondary?: string;
117
- background?: string;
118
- text?: string;
119
- border?: string;
120
- success?: string;
121
- error?: string;
122
- scannerOverlay?: string;
123
- scannerFrame?: string;
124
- scannerCorner?: string;
125
- };
126
- spacing?: {
127
- xs?: string;
128
- sm?: string;
129
- md?: string;
130
- lg?: string;
131
- xl?: string;
132
- };
133
- borderRadius?: {
134
- sm?: string;
135
- md?: string;
136
- lg?: string;
137
- full?: string;
138
- };
139
- fonts?: {
140
- primary?: string;
141
- secondary?: string;
142
- };
143
- }
144
-
145
- export interface BarcodeScannerCustomStyles {
146
- // Button styles
147
- floatingButton?: string;
148
- floatingButtonIcon?: string;
149
-
150
- // Modal styles
151
- modalOverlay?: string;
152
- modalContainer?: string;
153
- modalHeader?: string;
154
- modalTitle?: string;
155
- modalCloseButton?: string;
156
- modalCloseIcon?: string;
157
- modalContent?: string;
158
-
159
- // Scanner styles
160
- scannerContainer?: string;
161
- scannerVideo?: string;
162
- scannerOverlay?: string;
163
- scannerFrame?: string;
164
- scannerCornerTopLeft?: string;
165
- scannerCornerTopRight?: string;
166
- scannerCornerBottomLeft?: string;
167
- scannerCornerBottomRight?: string;
168
- scannerHelpText?: string;
169
- scannerLine?: string;
170
-
171
- // Product display styles
172
- productListContainer?: string;
173
- productList?: string;
174
- productCard?: string;
175
- productCardSelected?: string;
176
- productImage?: string;
177
- productImageWrapper?: string;
178
- productInfo?: string;
179
- productName?: string;
180
- productPrice?: string;
181
- productCheckmark?: string;
182
- productRemoveButton?: string;
183
-
184
- // Actions styles
185
- actionsContainer?: string;
186
- continueButton?: string;
187
- continueButtonDisabled?: string;
188
- scanMoreText?: string;
189
-
190
- // Error and loading styles
191
- errorContainer?: string;
192
- errorMessage?: string;
193
- errorIcon?: string;
194
- errorRetryButton?: string;
195
- loadingContainer?: string;
196
- loadingSpinner?: string;
197
- loadingText?: string;
198
-
199
- // Permission denied styles
200
- permissionDeniedContainer?: string;
201
- permissionDeniedIcon?: string;
202
- permissionDeniedTitle?: string;
203
- permissionDeniedMessage?: string;
204
- permissionDeniedButton?: string;
205
-
206
- // Empty state styles
207
- emptyStateContainer?: string;
208
- emptyStateIcon?: string;
209
- emptyStateTitle?: string;
210
- emptyStateMessage?: string;
211
- }
212
-
213
- export interface BarcodeScannerCustomRenderers {
214
- // Button renderers
215
- renderFloatingButton?: (props: {
216
- onClick: () => void;
217
- className?: string;
218
- }) => React.ReactNode;
219
- renderFloatingButtonIcon?: () => React.ReactNode;
220
-
221
- // Modal renderers
222
- renderModal?: (props: BarcodeScannerModalProps) => React.ReactNode;
223
- renderModalHeader?: (props: {
224
- title: string;
225
- onClose: () => void;
226
- }) => React.ReactNode;
227
- renderModalCloseButton?: (props: {
228
- onClick: () => void;
229
- }) => React.ReactNode;
230
- renderModalCloseIcon?: () => React.ReactNode;
231
-
232
- // Scanner renderers
233
- renderScanner?: (props: BarcodeScannerProps) => React.ReactNode;
234
- renderScannerOverlay?: (props: {
235
- isScanning: boolean;
236
- }) => React.ReactNode;
237
- renderScannerFrame?: () => React.ReactNode;
238
- renderScannerCorners?: () => React.ReactNode;
239
- renderScannerHelpText?: (props: { text: string }) => React.ReactNode;
240
- renderScannerLine?: () => React.ReactNode;
241
-
242
- // Product renderers
243
- renderProductList?: (props: {
244
- products: Product[];
245
- onRemove: (product: Product) => void;
246
- }) => React.ReactNode;
247
- renderProductCard?: (props: ScannedProductCardProps) => React.ReactNode;
248
- renderProductImage?: (props: {
249
- imageUrl: string;
250
- alt: string;
251
- className?: string;
252
- }) => React.ReactNode;
253
- renderProductInfo?: (props: {
254
- product: Product;
255
- }) => React.ReactNode;
256
- renderProductCheckmark?: () => React.ReactNode;
257
- renderProductRemoveButton?: (props: {
258
- onClick: () => void;
259
- }) => React.ReactNode;
260
-
261
- // Actions renderers
262
- renderActionsContainer?: (props: {
263
- children: React.ReactNode;
264
- }) => React.ReactNode;
265
- renderContinueButton?: (props: {
266
- onClick: () => void;
267
- disabled: boolean;
268
- text: string;
269
- }) => React.ReactNode;
270
- renderScanMoreText?: (props: { text: string }) => React.ReactNode;
271
-
272
- // Error renderers
273
- renderError?: (props: {
274
- error: string;
275
- onRetry?: () => void;
276
- }) => React.ReactNode;
277
- renderErrorIcon?: () => React.ReactNode;
278
- renderErrorMessage?: (props: { message: string }) => React.ReactNode;
279
- renderErrorRetryButton?: (props: {
280
- onClick: () => void;
281
- text: string;
282
- }) => React.ReactNode;
283
-
284
- // Loading renderers
285
- renderLoading?: (props: { text?: string }) => React.ReactNode;
286
- renderLoadingSpinner?: () => React.ReactNode;
287
- renderLoadingText?: (props: { text: string }) => React.ReactNode;
288
-
289
- // Permission denied renderers
290
- renderPermissionDenied?: (props: {
291
- onRequestPermission?: () => void;
292
- }) => React.ReactNode;
293
- renderPermissionDeniedIcon?: () => React.ReactNode;
294
- renderPermissionDeniedTitle?: (props: { title: string }) => React.ReactNode;
295
- renderPermissionDeniedMessage?: (props: {
296
- message: string;
297
- }) => React.ReactNode;
298
- renderPermissionDeniedButton?: (props: {
299
- onClick: () => void;
300
- text: string;
301
- }) => React.ReactNode;
302
-
303
- // Empty state renderers
304
- renderEmptyState?: () => React.ReactNode;
305
- renderEmptyStateIcon?: () => React.ReactNode;
306
- renderEmptyStateTitle?: (props: { title: string }) => React.ReactNode;
307
- renderEmptyStateMessage?: (props: { message: string }) => React.ReactNode;
308
- }
@@ -1,63 +0,0 @@
1
- 'use client';
2
-
3
- import React from 'react';
4
- import { twMerge } from 'tailwind-merge';
5
- import { useLocalization } from '@akinon/next/hooks';
6
- import type { BarcodeScannerButtonProps } from '../types/barcode';
7
-
8
- export function BarcodeScannerButton({
9
- onClick,
10
- className,
11
- disabled = false,
12
- settings,
13
- style
14
- }: BarcodeScannerButtonProps) {
15
- const { t } = useLocalization();
16
-
17
- // Custom button renderer
18
- if (settings?.customRenderers?.renderFloatingButton) {
19
- return settings.customRenderers.renderFloatingButton({
20
- onClick,
21
- className
22
- });
23
- }
24
-
25
- return (
26
- <button
27
- onClick={onClick}
28
- disabled={disabled}
29
- aria-label={t('product.barcode_scanner.button_label')}
30
- style={style}
31
- className={twMerge(
32
- // Base styles - fixed position bottom right, mobile only
33
- 'fixed bottom-20 right-4 z-50 md:hidden',
34
- // Button appearance
35
- 'px-4 py-3 rounded-full',
36
- 'bg-black text-white',
37
- 'flex items-center justify-center',
38
- 'shadow-lg hover:shadow-xl',
39
- 'transition-all duration-200',
40
- 'hover:scale-105 active:scale-95',
41
- 'text-sm font-medium whitespace-nowrap',
42
- // Disabled state
43
- disabled && 'opacity-50 cursor-not-allowed hover:scale-100',
44
- // Custom styles
45
- settings?.customStyles?.floatingButton,
46
- className
47
- )}
48
- >
49
- {settings?.customRenderers?.renderFloatingButtonIcon ? (
50
- settings.customRenderers.renderFloatingButtonIcon()
51
- ) : (
52
- <span
53
- className={twMerge(
54
- 'text-sm font-medium',
55
- settings?.customStyles?.floatingButtonIcon
56
- )}
57
- >
58
- {t('product.barcode_scanner.button_text')}
59
- </span>
60
- )}
61
- </button>
62
- );
63
- }