@akinon/pz-virtual-try-on 2.0.0-beta.16 → 2.0.0-beta.18
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/CHANGELOG.md +29 -0
- package/README.md +403 -7
- package/package.json +4 -3
- package/src/components/barcode-scanner.tsx +422 -0
- package/src/data/barcode-endpoints.ts +34 -0
- package/src/hooks/use-barcode-search.ts +172 -0
- package/src/hooks/use-image-cropper.ts +38 -7
- package/src/hooks/use-virtual-try-on-async.ts +1 -0
- package/src/hooks/use-virtual-try-on.ts +14 -2
- package/src/index.ts +26 -1
- package/src/types/barcode.ts +308 -0
- package/src/types/index.ts +32 -0
- package/src/utils/error-mapping.ts +3 -1
- package/src/utils/index.ts +115 -0
- package/src/views/barcode-scanner-button.tsx +63 -0
- package/src/views/barcode-scanner-modal.tsx +632 -0
- package/src/views/barcode-scanner-plugin.tsx +232 -0
- package/src/views/basket-async-modal.tsx +7 -2
- package/src/views/virtual-try-on-upload-modal.tsx +47 -41
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# @akinon/pz-virtual-try-on
|
|
2
2
|
|
|
3
|
+
## 2.0.0-beta.18
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [929374c5]
|
|
8
|
+
- Updated dependencies [71f8011d]
|
|
9
|
+
- Updated dependencies [9be2c081]
|
|
10
|
+
- Updated dependencies [bd431e36]
|
|
11
|
+
- Updated dependencies [54eac86b]
|
|
12
|
+
- @akinon/next@2.0.0-beta.18
|
|
13
|
+
|
|
14
|
+
## 2.0.0-beta.17
|
|
15
|
+
|
|
16
|
+
### Minor Changes
|
|
17
|
+
|
|
18
|
+
- 36143125: ZERO-3987: Add barcode scanner functionality with modal and button
|
|
19
|
+
- 5fb34b5c: ZERO-3955: Add aspect ratio validation and error handling for image cropping
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [8218dafa]
|
|
24
|
+
- Updated dependencies [2a8ddcf6]
|
|
25
|
+
- Updated dependencies [8a7fd0f4]
|
|
26
|
+
- Updated dependencies [36143125]
|
|
27
|
+
- Updated dependencies [f7e0f646]
|
|
28
|
+
- Updated dependencies [94a86fcc]
|
|
29
|
+
- Updated dependencies [bcaad120]
|
|
30
|
+
- @akinon/next@2.0.0-beta.17
|
|
31
|
+
|
|
3
32
|
## 2.0.0-beta.16
|
|
4
33
|
|
|
5
34
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
- [Customization Strategies](#markdown-header-customization-strategies)
|
|
18
18
|
- [Professional Examples](#markdown-header-professional-examples)
|
|
19
19
|
- [Usage Blueprints](#markdown-header-usage-blueprints)
|
|
20
|
+
- [Upload Modal Content Customization](#markdown-header-upload-modal-content-customization)
|
|
20
21
|
- [Styling Reference](#markdown-header-styling-reference)
|
|
21
22
|
- [Workflow & Caching](#markdown-header-workflow-caching)
|
|
22
23
|
- [Best Practices](#markdown-header-best-practices)
|
|
@@ -92,8 +93,10 @@
|
|
|
92
93
|
- **⚙️ Per-Component Control**: Independent customization for each modal and component
|
|
93
94
|
- **🔒 Type Safety**: Full TypeScript support for all customization options
|
|
94
95
|
- **🌍 Localization Support**: Built-in `useLocalization` hook integration in every component for multi-language UI
|
|
96
|
+
- **🖼️ Upload Modal Images**: Replace rule example images with custom branded assets via `customStyles.uploadModalImages`
|
|
97
|
+
- **📝 Upload Modal Texts**: Customize all modal text content via `customStyles.uploadModalTexts`
|
|
95
98
|
|
|
96
|
-
**Customizable Components (
|
|
99
|
+
**Customizable Components (12/12 - 100%):**
|
|
97
100
|
|
|
98
101
|
- ✅ `VirtualTryOnUploadModal` - 30+ render functions, 80+ style points, CSS variables, cropping UI
|
|
99
102
|
- ✅ `VirtualTryOnResultModal` - 15+ render functions, 50+ style points, mobile-optimized feedback
|
|
@@ -103,9 +106,24 @@
|
|
|
103
106
|
- ✅ `VirtualTryOnProductSelector` - 3 render functions, 30+ style points, max selection UI
|
|
104
107
|
- ✅ `VirtualTryOnAsyncModal` - 5 render functions, 35+ style points, async feedback system
|
|
105
108
|
- ✅ `BasketVirtualTryOn` - 2 render functions, 4 style points, eligibility filtering
|
|
109
|
+
- ✅ `BarcodeScannerPlugin` - Complete VTO flow orchestration with customization pass-through
|
|
110
|
+
- ✅ `BarcodeScannerButton` - 2 render functions, 2 style points, floating button
|
|
111
|
+
- ✅ `BarcodeScannerModal` - 30+ render functions, 50+ style points, scanner UI
|
|
106
112
|
- ✅ `BasketAsyncModal` - 3 render functions, 25+ style points, real-time polling
|
|
107
113
|
- ✅ `VirtualTryOnButton` - 4 render functions, 10+ style points, variant support
|
|
108
114
|
|
|
115
|
+
### 🆕 NEW: Barcode Scanner Integration
|
|
116
|
+
|
|
117
|
+
- **📷 Barcode Scanning**: Scan product barcodes with your mobile camera to find and try on products instantly
|
|
118
|
+
- **🔍 Universal Barcode Support**: Supports all major formats (EAN-13, EAN-8, UPC-A, UPC-E, Code-128, Code-39, QR Code, and more)
|
|
119
|
+
- **📱 Homepage Only**: Floating button visible only on mobile devices and only on homepage
|
|
120
|
+
- **⚡ Real-time Search**: Instantly searches products by barcode number
|
|
121
|
+
- **🛒 Multi-Product Scanning**: Scan multiple products before continuing to VTO
|
|
122
|
+
- **🎨 Fully Customizable**: 50+ style points, 30+ render functions, theme support, CSS variables
|
|
123
|
+
- **📳 Haptic Feedback**: Optional vibration on successful scan
|
|
124
|
+
- **🔒 Permission Handling**: Graceful camera permission requests and error handling
|
|
125
|
+
- **⏱️ Auto-dismiss Errors**: Error messages automatically dismiss after 2 seconds
|
|
126
|
+
|
|
109
127
|
### 🆕 NEW: Multiple Product Try-On (Basket Integration)
|
|
110
128
|
|
|
111
129
|
- **🛒 Basket Integration**: Try on multiple products from basket simultaneously (max 3 products)
|
|
@@ -127,6 +145,240 @@ Select `pz-virtual-try-on` when prompted. In existing monorepos run `yarn instal
|
|
|
127
145
|
|
|
128
146
|
## Quick Start
|
|
129
147
|
|
|
148
|
+
### 🆕 Barcode Scanner Integration (Mobile Homepage)
|
|
149
|
+
|
|
150
|
+
**NEW**: Scan product barcodes to instantly find and try on products!
|
|
151
|
+
|
|
152
|
+
#### Method 1: Using PluginModule (Recommended)
|
|
153
|
+
|
|
154
|
+
The barcode scanner is automatically available via the PluginModule system. Add it to your **homepage only** (not client-root, as it should only appear on the homepage):
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
// In src/app/[commerce]/[locale]/[currency]/home-client.tsx
|
|
158
|
+
'use client';
|
|
159
|
+
|
|
160
|
+
import PluginModule, { Component } from '@akinon/next/components/plugin-module';
|
|
161
|
+
|
|
162
|
+
export function HomeClient() {
|
|
163
|
+
return (
|
|
164
|
+
<>
|
|
165
|
+
{/* Barcode Scanner Plugin - Mobile only floating button */}
|
|
166
|
+
<PluginModule component={Component.BarcodeScannerPlugin} />
|
|
167
|
+
</>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Then use it in your homepage:
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
// In src/app/[commerce]/[locale]/[currency]/page.tsx
|
|
176
|
+
import { HomeClient } from './home-client';
|
|
177
|
+
|
|
178
|
+
async function Page() {
|
|
179
|
+
return (
|
|
180
|
+
<>
|
|
181
|
+
{/* Your homepage widgets */}
|
|
182
|
+
<HomeClient />
|
|
183
|
+
</>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### Method 2: Direct Component Import
|
|
189
|
+
|
|
190
|
+
```tsx
|
|
191
|
+
import { BarcodeScannerPlugin } from '@akinon/pz-virtual-try-on';
|
|
192
|
+
import type {
|
|
193
|
+
BarcodeScannerSettings,
|
|
194
|
+
VirtualTryOnPluginSettings
|
|
195
|
+
} from '@akinon/pz-virtual-try-on';
|
|
196
|
+
|
|
197
|
+
// Full customization example with styles and renderers
|
|
198
|
+
const barcodeScannerSettings: BarcodeScannerSettings = {
|
|
199
|
+
maxProducts: 5,
|
|
200
|
+
vibrateOnScan: true,
|
|
201
|
+
// Theme customization
|
|
202
|
+
theme: {
|
|
203
|
+
colors: {
|
|
204
|
+
primary: '#3b82f6',
|
|
205
|
+
background: '#ffffff',
|
|
206
|
+
text: '#1f2937',
|
|
207
|
+
success: '#10b981',
|
|
208
|
+
error: '#ef4444',
|
|
209
|
+
scannerOverlay: 'rgba(0, 0, 0, 0.6)',
|
|
210
|
+
scannerFrame: '#3b82f6',
|
|
211
|
+
scannerCorner: '#3b82f6'
|
|
212
|
+
},
|
|
213
|
+
borderRadius: {
|
|
214
|
+
sm: '4px',
|
|
215
|
+
md: '8px',
|
|
216
|
+
lg: '16px'
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
// 50+ Custom style points
|
|
220
|
+
customStyles: {
|
|
221
|
+
// Floating button
|
|
222
|
+
floatingButton: 'bg-blue-600 shadow-xl hover:bg-blue-700',
|
|
223
|
+
floatingButtonIcon: 'text-white w-7 h-7',
|
|
224
|
+
// Modal
|
|
225
|
+
modalOverlay: 'bg-black/80',
|
|
226
|
+
modalContainer: 'bg-white rounded-2xl',
|
|
227
|
+
modalHeader: 'border-b border-gray-100',
|
|
228
|
+
modalCloseButton: 'hover:bg-gray-100 rounded-full',
|
|
229
|
+
// Scanner
|
|
230
|
+
scannerContainer: 'rounded-lg overflow-hidden',
|
|
231
|
+
scannerFrame: 'border-2 border-blue-500',
|
|
232
|
+
scannerHelpText: 'text-white text-sm',
|
|
233
|
+
// Products
|
|
234
|
+
productCard: 'rounded-lg shadow-sm',
|
|
235
|
+
productImage: 'object-cover',
|
|
236
|
+
productRemoveButton: 'bg-red-500 hover:bg-red-600',
|
|
237
|
+
// Actions
|
|
238
|
+
continueButton: 'bg-blue-600 hover:bg-blue-700 text-white font-semibold',
|
|
239
|
+
// Error states
|
|
240
|
+
errorContainer: 'bg-red-500/90 rounded-lg',
|
|
241
|
+
errorMessage: 'text-white',
|
|
242
|
+
// Loading
|
|
243
|
+
loadingSpinner: 'text-blue-500',
|
|
244
|
+
// Permission denied
|
|
245
|
+
permissionDeniedButton: 'bg-blue-600 text-white'
|
|
246
|
+
},
|
|
247
|
+
// 30+ Custom render functions
|
|
248
|
+
customRenderers: {
|
|
249
|
+
// Custom floating button
|
|
250
|
+
renderFloatingButton: ({ onClick }) => (
|
|
251
|
+
<button
|
|
252
|
+
onClick={onClick}
|
|
253
|
+
className="fixed bottom-20 right-4 z-50 md:hidden w-16 h-16 rounded-full bg-gradient-to-r from-blue-500 to-purple-500 text-white shadow-xl"
|
|
254
|
+
>
|
|
255
|
+
📷
|
|
256
|
+
</button>
|
|
257
|
+
),
|
|
258
|
+
// Custom modal header
|
|
259
|
+
renderModalHeader: ({ title, onClose }) => (
|
|
260
|
+
<div className="flex justify-between items-center p-4 bg-gradient-to-r from-blue-500 to-purple-500">
|
|
261
|
+
<h2 className="text-white font-bold text-lg">{title}</h2>
|
|
262
|
+
<button onClick={onClose} className="text-white">
|
|
263
|
+
✕
|
|
264
|
+
</button>
|
|
265
|
+
</div>
|
|
266
|
+
),
|
|
267
|
+
// Custom product card
|
|
268
|
+
renderProductCard: ({ product, onRemove }) => (
|
|
269
|
+
<div className="relative p-2 bg-white rounded-lg shadow">
|
|
270
|
+
<img
|
|
271
|
+
src={product.productimage_set?.[0]?.image}
|
|
272
|
+
alt={product.name}
|
|
273
|
+
className="w-16 h-16 object-cover rounded"
|
|
274
|
+
/>
|
|
275
|
+
<button
|
|
276
|
+
onClick={() => onRemove?.(product)}
|
|
277
|
+
className="absolute -top-2 -right-2 w-5 h-5 bg-red-500 text-white rounded-full text-xs"
|
|
278
|
+
>
|
|
279
|
+
×
|
|
280
|
+
</button>
|
|
281
|
+
</div>
|
|
282
|
+
),
|
|
283
|
+
// Custom continue button
|
|
284
|
+
renderContinueButton: ({ onClick, disabled, text }) => (
|
|
285
|
+
<button
|
|
286
|
+
onClick={onClick}
|
|
287
|
+
disabled={disabled}
|
|
288
|
+
className={`w-full py-3 rounded-full font-bold transition ${
|
|
289
|
+
disabled
|
|
290
|
+
? 'bg-gray-300'
|
|
291
|
+
: 'bg-gradient-to-r from-blue-500 to-purple-500 text-white'
|
|
292
|
+
}`}
|
|
293
|
+
>
|
|
294
|
+
{text}
|
|
295
|
+
</button>
|
|
296
|
+
),
|
|
297
|
+
// Custom error display
|
|
298
|
+
renderError: ({ error, onRetry }) => (
|
|
299
|
+
<div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded">
|
|
300
|
+
<span>{error}</span>
|
|
301
|
+
{onRetry && (
|
|
302
|
+
<button onClick={onRetry} className="ml-2 underline">
|
|
303
|
+
Retry
|
|
304
|
+
</button>
|
|
305
|
+
)}
|
|
306
|
+
</div>
|
|
307
|
+
)
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
export function HomePage() {
|
|
312
|
+
return (
|
|
313
|
+
<div>
|
|
314
|
+
{/* Your homepage content */}
|
|
315
|
+
|
|
316
|
+
{/* Barcode Scanner Button (shows on mobile only) */}
|
|
317
|
+
<BarcodeScannerPlugin
|
|
318
|
+
barcodeScannerSettings={barcodeScannerSettings}
|
|
319
|
+
onProductsScanned={(products) => {
|
|
320
|
+
// Handle scanned products
|
|
321
|
+
}}
|
|
322
|
+
onVTOComplete={(result) => {
|
|
323
|
+
// Handle VTO completion
|
|
324
|
+
}}
|
|
325
|
+
/>
|
|
326
|
+
</div>
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
#### Method 3: Configure via settings.js
|
|
332
|
+
|
|
333
|
+
You can also configure the barcode scanner via `settings.js`:
|
|
334
|
+
|
|
335
|
+
```javascript
|
|
336
|
+
// settings.js
|
|
337
|
+
module.exports = {
|
|
338
|
+
// ... other settings
|
|
339
|
+
plugins: {
|
|
340
|
+
'pz-virtual-try-on': {
|
|
341
|
+
barcodeScanner: {
|
|
342
|
+
maxProducts: 5,
|
|
343
|
+
vibrateOnScan: true,
|
|
344
|
+
customStyles: {
|
|
345
|
+
floatingButton: 'bg-black shadow-xl',
|
|
346
|
+
continueButton: 'bg-black hover:bg-gray-800'
|
|
347
|
+
}
|
|
348
|
+
},
|
|
349
|
+
vto: {
|
|
350
|
+
theme: {
|
|
351
|
+
colors: {
|
|
352
|
+
primary: '#000000'
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**How it works:**
|
|
362
|
+
|
|
363
|
+
1. Floating button appears in bottom-right corner (mobile only)
|
|
364
|
+
2. Click opens fullscreen barcode scanner
|
|
365
|
+
3. Point camera at product barcode
|
|
366
|
+
4. Product is searched and displayed automatically
|
|
367
|
+
5. Scan more products or click "Sanal Kabine Devam Et" (Continue to Virtual Cabin)
|
|
368
|
+
6. Upload photo and see VTO results for all scanned products
|
|
369
|
+
|
|
370
|
+
**Supported Barcode Formats:**
|
|
371
|
+
|
|
372
|
+
- EAN-13 / EAN-8 (European Article Number)
|
|
373
|
+
- UPC-A / UPC-E (Universal Product Code)
|
|
374
|
+
- Code-128 / Code-39 / Code-93
|
|
375
|
+
- QR Code
|
|
376
|
+
- Data Matrix
|
|
377
|
+
- PDF-417
|
|
378
|
+
- Codabar
|
|
379
|
+
- ITF (Interleaved 2 of 5)
|
|
380
|
+
- Aztec
|
|
381
|
+
|
|
130
382
|
### 🆕 Basket Integration (Multiple Products)
|
|
131
383
|
|
|
132
384
|
**NEW**: Try on multiple products from basket page!
|
|
@@ -226,10 +478,10 @@ const virtualTryOnSettings: VirtualTryOnPluginSettings = {
|
|
|
226
478
|
{step === 'upload'
|
|
227
479
|
? ' 01'
|
|
228
480
|
: step === 'crop'
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
481
|
+
? ' 02'
|
|
482
|
+
: step === 'processing'
|
|
483
|
+
? ' 03'
|
|
484
|
+
: ' 04'}
|
|
233
485
|
</p>
|
|
234
486
|
<h2 className="text-xl font-semibold text-gray-900">{title}</h2>
|
|
235
487
|
</div>
|
|
@@ -648,7 +900,17 @@ type VirtualTryOnPluginSettings = {
|
|
|
648
900
|
buttonSize?: 'sm' | 'md' | 'lg';
|
|
649
901
|
legal_text?: string;
|
|
650
902
|
instructions?: string;
|
|
651
|
-
customStyles?:
|
|
903
|
+
customStyles?: {
|
|
904
|
+
// CSS class overrides (300+ slots)
|
|
905
|
+
button?: string;
|
|
906
|
+
uploadModal?: string;
|
|
907
|
+
resultModal?: string;
|
|
908
|
+
// ... and many more
|
|
909
|
+
|
|
910
|
+
// Upload Modal Content Customization
|
|
911
|
+
uploadModalImages?: VirtualTryOnModalImages;
|
|
912
|
+
uploadModalTexts?: VirtualTryOnModalTexts;
|
|
913
|
+
};
|
|
652
914
|
customRenderers?: {
|
|
653
915
|
UploadModal?: React.ComponentType<VirtualTryOnUploadModalProps>;
|
|
654
916
|
ResultModal?: React.ComponentType<VirtualTryOnResultModalProps>;
|
|
@@ -672,7 +934,7 @@ type VirtualTryOnPluginSettings = {
|
|
|
672
934
|
};
|
|
673
935
|
```
|
|
674
936
|
|
|
675
|
-
> `customStyles` exposes 300+ slots (see [Styling Reference](#markdown-header-styling-reference)); `CustomRendererProps` provides 60+ render callbacks across all 10 components with full localization support.
|
|
937
|
+
> `customStyles` exposes 300+ slots for CSS classes plus `uploadModalImages` and `uploadModalTexts` for content customization (see [Upload Modal Content Customization](#markdown-header-upload-modal-content-customization) and [Styling Reference](#markdown-header-styling-reference)); `CustomRendererProps` provides 60+ render callbacks across all 10 components with full localization support.
|
|
676
938
|
|
|
677
939
|
### Service Endpoints
|
|
678
940
|
|
|
@@ -1695,6 +1957,140 @@ Customize modal overlays, sizes, and button styles for brand consistency.
|
|
|
1695
1957
|
/>
|
|
1696
1958
|
```
|
|
1697
1959
|
|
|
1960
|
+
## Upload Modal Content Customization
|
|
1961
|
+
|
|
1962
|
+
The upload modal images and texts can be fully customized via `customStyles.uploadModalImages` and `customStyles.uploadModalTexts`. This is useful for:
|
|
1963
|
+
|
|
1964
|
+
- Replacing default rule images with custom branded examples
|
|
1965
|
+
- Translating or customizing all modal text content
|
|
1966
|
+
- Providing localized photo guidelines with custom imagery
|
|
1967
|
+
- A/B testing different upload instructions
|
|
1968
|
+
|
|
1969
|
+
### Available Image Slots
|
|
1970
|
+
|
|
1971
|
+
| Property | Description | Default |
|
|
1972
|
+
|----------|-------------|---------|
|
|
1973
|
+
| `ruleGoodExample` | Good photo example (rule 1 image) | Built-in asset |
|
|
1974
|
+
| `ruleBadExample1` | Bad example: cluttered background | Built-in asset |
|
|
1975
|
+
| `ruleBadExample2` | Bad example: poor lighting | Built-in asset |
|
|
1976
|
+
| `ruleBadExample3` | Bad example: cropped body | Built-in asset |
|
|
1977
|
+
| `ruleBadExample4` | Bad example: multiple people | Built-in asset |
|
|
1978
|
+
| `uploadIcon` | Upload area icon | Built-in SVG |
|
|
1979
|
+
|
|
1980
|
+
### Available Text Slots
|
|
1981
|
+
|
|
1982
|
+
| Property | Description | Fallback Localization Key |
|
|
1983
|
+
|----------|-------------|---------------------------|
|
|
1984
|
+
| `title` | Modal header title | `product.virtual_try_on.title` |
|
|
1985
|
+
| `editPhotoTitle` | Title when editing/cropping photo | `product.virtual_try_on.edit_photo_title` |
|
|
1986
|
+
| `uploadPrompt` | Main upload prompt text | `product.virtual_try_on.upload_prompt` |
|
|
1987
|
+
| `uploadRequirements` | File requirements text | `product.virtual_try_on.upload_requirements` |
|
|
1988
|
+
| `uploadInfo` | Additional upload info | `product.virtual_try_on.upload_info` |
|
|
1989
|
+
| `rule1` | Rule 1 description | `product.virtual_try_on.rule_1` |
|
|
1990
|
+
| `rule2` | Rule 2 description | `product.virtual_try_on.rule_2` |
|
|
1991
|
+
| `rule3` | Rule 3 description | `product.virtual_try_on.rule_3` |
|
|
1992
|
+
| `rule4` | Rule 4 description | `product.virtual_try_on.rule_4` |
|
|
1993
|
+
| `rule5` | Rule 5 description | `product.virtual_try_on.rule_5` |
|
|
1994
|
+
| `rule6` | Rule 6 description | `product.virtual_try_on.rule_6` |
|
|
1995
|
+
| `processingTitle` | Processing overlay title | `product.virtual_try_on.processing` |
|
|
1996
|
+
| `processingMessage` | Processing overlay message | `product.virtual_try_on.processing_message` |
|
|
1997
|
+
| `retryUpload` | Retry upload button text | `product.virtual_try_on.retry` |
|
|
1998
|
+
|
|
1999
|
+
### Example: Custom Images and Texts
|
|
2000
|
+
|
|
2001
|
+
```tsx
|
|
2002
|
+
import PluginModule, { Component } from '@akinon/next/components/plugin-module';
|
|
2003
|
+
|
|
2004
|
+
<PluginModule
|
|
2005
|
+
component={Component.VirtualTryOnPlugin}
|
|
2006
|
+
props={{
|
|
2007
|
+
product: data.product,
|
|
2008
|
+
settings: {
|
|
2009
|
+
customStyles: {
|
|
2010
|
+
// Custom button styling
|
|
2011
|
+
button: 'bg-purple-600 hover:bg-purple-700 text-white font-bold px-6 py-3 rounded-lg',
|
|
2012
|
+
|
|
2013
|
+
// Custom Upload Modal Images
|
|
2014
|
+
uploadModalImages: {
|
|
2015
|
+
ruleGoodExample: 'https://cdn.example.com/vto/good-example.jpg',
|
|
2016
|
+
ruleBadExample1: 'https://cdn.example.com/vto/bad-background.jpg',
|
|
2017
|
+
ruleBadExample2: 'https://cdn.example.com/vto/bad-lighting.jpg',
|
|
2018
|
+
ruleBadExample3: 'https://cdn.example.com/vto/bad-cropped.jpg',
|
|
2019
|
+
ruleBadExample4: 'https://cdn.example.com/vto/bad-multiple.jpg',
|
|
2020
|
+
uploadIcon: 'https://cdn.example.com/vto/upload-icon.svg'
|
|
2021
|
+
},
|
|
2022
|
+
|
|
2023
|
+
// Custom Upload Modal Texts
|
|
2024
|
+
uploadModalTexts: {
|
|
2025
|
+
title: '🎭 Virtual Try-On Studio',
|
|
2026
|
+
editPhotoTitle: '✂️ Adjust Your Photo',
|
|
2027
|
+
uploadPrompt: '📸 Drag & drop your photo here',
|
|
2028
|
+
uploadRequirements: 'JPEG or PNG, max 5MB',
|
|
2029
|
+
uploadInfo: 'Your photo will be processed securely',
|
|
2030
|
+
rule1: '🌟 Use a plain background',
|
|
2031
|
+
rule2: '💡 Ensure good lighting',
|
|
2032
|
+
rule3: '👤 Show your full body',
|
|
2033
|
+
rule4: '🚫 No multiple people',
|
|
2034
|
+
rule5: '📐 Face the camera directly',
|
|
2035
|
+
rule6: '👔 Wear fitted clothing',
|
|
2036
|
+
processingTitle: '✨ Creating your look...',
|
|
2037
|
+
processingMessage: 'Our AI is working its magic!',
|
|
2038
|
+
retryUpload: '🔄 Try another photo'
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
}}
|
|
2043
|
+
/>
|
|
2044
|
+
```
|
|
2045
|
+
|
|
2046
|
+
### TypeScript Interfaces
|
|
2047
|
+
|
|
2048
|
+
```ts
|
|
2049
|
+
interface VirtualTryOnModalImages {
|
|
2050
|
+
ruleGoodExample?: string;
|
|
2051
|
+
ruleBadExample1?: string;
|
|
2052
|
+
ruleBadExample2?: string;
|
|
2053
|
+
ruleBadExample3?: string;
|
|
2054
|
+
ruleBadExample4?: string;
|
|
2055
|
+
uploadIcon?: string;
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
interface VirtualTryOnModalTexts {
|
|
2059
|
+
title?: string;
|
|
2060
|
+
editPhotoTitle?: string;
|
|
2061
|
+
uploadPrompt?: string;
|
|
2062
|
+
uploadRequirements?: string;
|
|
2063
|
+
uploadInfo?: string;
|
|
2064
|
+
rule1?: string;
|
|
2065
|
+
rule2?: string;
|
|
2066
|
+
rule3?: string;
|
|
2067
|
+
rule4?: string;
|
|
2068
|
+
rule5?: string;
|
|
2069
|
+
rule6?: string;
|
|
2070
|
+
processingTitle?: string;
|
|
2071
|
+
processingMessage?: string;
|
|
2072
|
+
retryUpload?: string;
|
|
2073
|
+
}
|
|
2074
|
+
|
|
2075
|
+
// Usage in VirtualTryOnPluginSettings
|
|
2076
|
+
interface VirtualTryOnPluginSettings {
|
|
2077
|
+
customStyles?: {
|
|
2078
|
+
// ... other style slots
|
|
2079
|
+
uploadModalImages?: VirtualTryOnModalImages;
|
|
2080
|
+
uploadModalTexts?: VirtualTryOnModalTexts;
|
|
2081
|
+
};
|
|
2082
|
+
}
|
|
2083
|
+
```
|
|
2084
|
+
|
|
2085
|
+
### Fallback Behavior
|
|
2086
|
+
|
|
2087
|
+
If a custom image or text is not provided, the component automatically falls back to:
|
|
2088
|
+
|
|
2089
|
+
1. **Images**: Built-in default assets from the package
|
|
2090
|
+
2. **Texts**: Localized strings via `useLocalization()` hook with the corresponding translation key
|
|
2091
|
+
|
|
2092
|
+
This allows partial customization - you can override only the images or texts you need while keeping defaults for the rest.
|
|
2093
|
+
|
|
1698
2094
|
## Styling Reference
|
|
1699
2095
|
|
|
1700
2096
|
### Button Targets
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akinon/pz-virtual-try-on",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.18",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"peerDependencies": {
|
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@akinon/next": "2.0.0-beta.
|
|
11
|
+
"@akinon/next": "2.0.0-beta.18",
|
|
12
12
|
"clsx": "^2.0.0",
|
|
13
13
|
"tailwind-merge": "^2.0.0",
|
|
14
|
-
"react-image-crop": "^11.0.5"
|
|
14
|
+
"react-image-crop": "^11.0.5",
|
|
15
|
+
"html5-qrcode": "^2.3.8"
|
|
15
16
|
},
|
|
16
17
|
"devDependencies": {
|
|
17
18
|
"@types/node": "^18.7.8",
|