ordering-ui-react-native 0.12.87 → 0.12.88
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/package.json
CHANGED
|
@@ -117,9 +117,11 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
117
117
|
const [{ auth }] = useSession();
|
|
118
118
|
const { product, loading, error } = productObject;
|
|
119
119
|
|
|
120
|
-
const
|
|
121
|
-
const
|
|
122
|
-
|
|
120
|
+
const [selOpt, setSelectedOpt] = useState(null);
|
|
121
|
+
const [optionsLayout, setOptionsLayout] = useState<any>(null)
|
|
122
|
+
|
|
123
|
+
const extraOptions = [].concat(...product?.extras?.map((option: any) => option.options)).filter((i: any) => i.respect_to === null)
|
|
124
|
+
|
|
123
125
|
const scrollViewRef = useRef<any>()
|
|
124
126
|
const isError = (id: number) => {
|
|
125
127
|
let bgColor = theme.colors.white;
|
|
@@ -133,24 +135,22 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
133
135
|
};
|
|
134
136
|
|
|
135
137
|
const handleSaveProduct = () => {
|
|
136
|
-
console.log('----- click handle ------')
|
|
137
138
|
const isErrors = Object.values(errors).length > 0;
|
|
138
139
|
if (!isErrors) {
|
|
139
|
-
console.log('----- save handle ------')
|
|
140
140
|
handleSave && handleSave();
|
|
141
141
|
return;
|
|
142
142
|
}
|
|
143
143
|
};
|
|
144
144
|
|
|
145
145
|
const hasRespected = (options: Array<any>, respect_id: number) => {
|
|
146
|
-
if (respect_id
|
|
146
|
+
if (respect_id === null) return;
|
|
147
147
|
const option: any = options.filter(({ id }: any) => id === selOpt);
|
|
148
|
-
if (option
|
|
149
|
-
if (option?.suboptions?.length
|
|
150
|
-
const sel = option[0]?.suboptions?.filter(
|
|
148
|
+
if (option === undefined) return false;
|
|
149
|
+
if (option?.suboptions?.length === null) return false;
|
|
150
|
+
const sel = option && option[0]?.suboptions?.filter(
|
|
151
151
|
({ id }: any) => id === respect_id,
|
|
152
152
|
);
|
|
153
|
-
return sel[0]?.id !== undefined;
|
|
153
|
+
return sel && sel[0]?.id !== undefined;
|
|
154
154
|
};
|
|
155
155
|
|
|
156
156
|
const handleRedirectLogin = () => {
|
|
@@ -158,73 +158,88 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
158
158
|
navigation.navigate('Login');
|
|
159
159
|
};
|
|
160
160
|
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
161
|
+
const handleClickOption = (value: any) => {
|
|
162
|
+
setSelectedOpt(value)
|
|
163
|
+
|
|
164
|
+
const optionsArray = value
|
|
165
|
+
? Object.values(optionsLayout)
|
|
166
|
+
.filter((opt: any) => opt.position || opt.position === 0)
|
|
167
|
+
.map((i: any) => i.height)
|
|
168
|
+
.slice(0, optionsLayout[value]?.position)
|
|
169
|
+
: []
|
|
170
|
+
|
|
171
|
+
scrollViewRef.current.scrollTo({
|
|
172
|
+
y: optionsArray.length > 0
|
|
173
|
+
? optionsLayout?.header?.height + optionsArray?.reduce((acc, cur) => acc + cur)
|
|
174
|
+
: optionsLayout?.header?.height,
|
|
175
|
+
animated: true
|
|
176
|
+
})
|
|
177
|
+
}
|
|
165
178
|
|
|
166
|
-
const
|
|
179
|
+
const saveErrors = orderState.loading || maxProductQuantity === null || Object.keys(errors).length > 0;
|
|
180
|
+
|
|
181
|
+
const ExtraOptions = ({ options }: any) => (
|
|
167
182
|
<ExtraOptionWrap
|
|
168
183
|
horizontal
|
|
169
184
|
showsHorizontalScrollIndicator={false}
|
|
170
|
-
|
|
171
|
-
|
|
185
|
+
contentContainerStyle={{ paddingHorizontal: 30, paddingTop: 10 }}
|
|
186
|
+
>
|
|
172
187
|
<>
|
|
173
188
|
<TouchableOpacity
|
|
174
189
|
key={`eopt_all_0`}
|
|
175
|
-
onPress={() =>
|
|
190
|
+
onPress={() => handleClickOption(null)}
|
|
176
191
|
style={[
|
|
177
192
|
styles.extraItem,
|
|
178
193
|
{
|
|
179
194
|
borderBottomColor:
|
|
180
|
-
selOpt
|
|
195
|
+
selOpt === null ? theme.colors.textNormal : theme.colors.border,
|
|
181
196
|
},
|
|
182
197
|
]}>
|
|
183
198
|
<OText
|
|
184
|
-
color={selOpt
|
|
185
|
-
size={selOpt
|
|
186
|
-
weight={selOpt
|
|
199
|
+
color={selOpt === null ? theme.colors.textNormal : theme.colors.textSecondary}
|
|
200
|
+
size={selOpt === null ? 14 : 12}
|
|
201
|
+
weight={selOpt === null ? '600' : 'normal'}>
|
|
187
202
|
{t('ALL', 'All')}
|
|
188
203
|
</OText>
|
|
189
204
|
</TouchableOpacity>
|
|
190
205
|
{product?.ingredients.length > 0 && (
|
|
191
206
|
<TouchableOpacity
|
|
192
207
|
key={`eopt_all_00`}
|
|
193
|
-
onPress={() =>
|
|
208
|
+
onPress={() => handleClickOption('ingredients')}
|
|
194
209
|
style={[
|
|
195
210
|
styles.extraItem,
|
|
196
211
|
{
|
|
197
212
|
borderBottomColor:
|
|
198
|
-
selOpt
|
|
213
|
+
selOpt === 'ingredients' ? theme.colors.textNormal : theme.colors.border,
|
|
199
214
|
},
|
|
200
215
|
]}>
|
|
201
216
|
<OText
|
|
202
|
-
color={selOpt
|
|
203
|
-
size={selOpt
|
|
204
|
-
weight={selOpt
|
|
217
|
+
color={selOpt === 'ingredients' ? theme.colors.textNormal : theme.colors.textSecondary}
|
|
218
|
+
size={selOpt === 'ingredients' ? 14 : 12}
|
|
219
|
+
weight={selOpt === 'ingredients' ? '600' : 'normal'}>
|
|
205
220
|
{t('INGREDIENTS', 'Ingredients')}
|
|
206
221
|
</OText>
|
|
207
222
|
</TouchableOpacity>
|
|
208
223
|
)}
|
|
209
224
|
{options.map(({ id, name, respect_to }: any) => (
|
|
210
225
|
<React.Fragment key={`cont_key_${id}`}>
|
|
211
|
-
{respect_to
|
|
226
|
+
{respect_to === null && (
|
|
212
227
|
<TouchableOpacity
|
|
213
228
|
key={`eopt_key_${id}`}
|
|
214
|
-
onPress={() =>
|
|
229
|
+
onPress={() => handleClickOption(`opt_${id}`)}
|
|
215
230
|
style={[
|
|
216
231
|
styles.extraItem,
|
|
217
232
|
{
|
|
218
233
|
borderBottomColor:
|
|
219
|
-
selOpt
|
|
234
|
+
selOpt === `opt_${id}` ? theme.colors.textNormal : theme.colors.border,
|
|
220
235
|
},
|
|
221
236
|
]}>
|
|
222
237
|
<OText
|
|
223
238
|
color={
|
|
224
|
-
selOpt
|
|
239
|
+
selOpt === `opt_${id}` ? theme.colors.textNormal : theme.colors.textSecondary
|
|
225
240
|
}
|
|
226
|
-
size={selOpt
|
|
227
|
-
weight={selOpt
|
|
241
|
+
size={selOpt === `opt_${id}` ? 14 : 12}
|
|
242
|
+
weight={selOpt === `opt_${id}` ? '600' : 'normal'}>
|
|
228
243
|
{name}
|
|
229
244
|
</OText>
|
|
230
245
|
</TouchableOpacity>
|
|
@@ -235,27 +250,32 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
235
250
|
</ExtraOptionWrap>
|
|
236
251
|
);
|
|
237
252
|
|
|
238
|
-
const
|
|
253
|
+
const handleScroll = ({ nativeEvent }: any) => {
|
|
254
|
+
const scrollOffset = nativeEvent.contentOffset.y
|
|
255
|
+
const optionsArray = Object.values(optionsLayout)
|
|
256
|
+
.filter((opt: any) => opt.position || opt.position === 0)
|
|
257
|
+
.map((i: any) => ({ height: i.height, key: i.key }))
|
|
258
|
+
|
|
259
|
+
for (let i = 0; i < optionsArray.length; i++) {
|
|
260
|
+
const opt = optionsArray[i];
|
|
261
|
+
if (scrollOffset <= optionsLayout?.header?.height) {
|
|
262
|
+
setSelectedOpt(null)
|
|
263
|
+
break
|
|
264
|
+
} else if (scrollOffset > optionsLayout?.header?.height && scrollOffset < (optionsLayout?.header?.height + opt.height)) {
|
|
265
|
+
setSelectedOpt(opt.key)
|
|
266
|
+
break
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
}
|
|
239
271
|
|
|
240
272
|
useEffect(() => {
|
|
241
273
|
const keyboardDidShowListener = Keyboard.addListener(
|
|
242
274
|
'keyboardDidShow',
|
|
243
|
-
() => {
|
|
244
|
-
scrollViewRef?.current && scrollViewRef?.current?.scrollToEnd()
|
|
245
|
-
setIsKeyboardShow(true);
|
|
246
|
-
}
|
|
247
|
-
);
|
|
248
|
-
const keyboardDidHideListener = Keyboard.addListener(
|
|
249
|
-
'keyboardDidHide',
|
|
250
|
-
() => {
|
|
251
|
-
setIsKeyboardShow(false);
|
|
252
|
-
}
|
|
275
|
+
() => { scrollViewRef?.current && scrollViewRef?.current?.scrollToEnd()}
|
|
253
276
|
);
|
|
254
277
|
|
|
255
|
-
return () => {
|
|
256
|
-
keyboardDidHideListener.remove();
|
|
257
|
-
keyboardDidShowListener.remove();
|
|
258
|
-
};
|
|
278
|
+
return () => { keyboardDidShowListener.remove()};
|
|
259
279
|
}, []);
|
|
260
280
|
|
|
261
281
|
return (
|
|
@@ -263,9 +283,17 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
263
283
|
enabled
|
|
264
284
|
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
|
|
265
285
|
>
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
286
|
+
{!error && (
|
|
287
|
+
<ScrollView
|
|
288
|
+
ref={scrollViewRef}
|
|
289
|
+
stickyHeaderIndices={[1]}
|
|
290
|
+
scrollEventThrottle={16}
|
|
291
|
+
contentContainerStyle={{ paddingBottom: 60 }}
|
|
292
|
+
// onScroll={(e: any) => handleScroll(e)}
|
|
293
|
+
>
|
|
294
|
+
<View
|
|
295
|
+
onLayout={(event: any) => setOptionsLayout({ ...optionsLayout, header: event.nativeEvent.layout })}
|
|
296
|
+
>
|
|
269
297
|
<WrapHeader>
|
|
270
298
|
{loading && !product ? (
|
|
271
299
|
<View style={styles.productHeaderSkeleton}>
|
|
@@ -316,19 +344,19 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
316
344
|
{product?.name || productCart.name}
|
|
317
345
|
</OText>
|
|
318
346
|
{((product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (product?.estimated_person)) && (
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
347
|
+
<OText size={14} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={'#909BA9'} mBottom={7}>
|
|
348
|
+
{
|
|
349
|
+
((product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (productCart?.sku && productCart?.sku !== '-1' && productCart?.sku !== '1'))
|
|
350
|
+
&& <>{t('SKU', 'Sku')}{' '}{product?.sku || productCart?.sku}</>
|
|
351
|
+
}
|
|
352
|
+
{product?.sku && product?.sku !== '-1' && product?.sku !== '1' && product?.estimated_person && (
|
|
353
|
+
<> · </>
|
|
354
|
+
)}
|
|
355
|
+
{product?.estimated_person
|
|
356
|
+
&& <>{product?.estimated_person}{' '}{t('ESTIMATED_PERSONS', 'persons')}</>
|
|
357
|
+
}
|
|
358
|
+
</OText>
|
|
359
|
+
)}
|
|
332
360
|
<OText size={16} lineHeight={24} color={theme.colors.textNormal}>
|
|
333
361
|
{productCart.price ? parsePrice(productCart.price) : ''}
|
|
334
362
|
</OText>
|
|
@@ -340,269 +368,203 @@ export const ProductOptionsUI = (props: any) => {
|
|
|
340
368
|
{product?.description || productCart?.description}
|
|
341
369
|
</OText>
|
|
342
370
|
</ProductDescription>
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
{[...Array(2)].map((item, i) => (
|
|
346
|
-
<Placeholder
|
|
347
|
-
key={i}
|
|
348
|
-
style={{ marginBottom: 20 }}
|
|
349
|
-
Animation={Fade}>
|
|
350
|
-
<PlaceholderLine
|
|
351
|
-
height={40}
|
|
352
|
-
style={{ flex: 1, marginTop: 10 }}
|
|
353
|
-
/>
|
|
354
|
-
{[...Array(3)].map((item, i) => (
|
|
355
|
-
<View
|
|
356
|
-
key={'place_key_' + i}
|
|
357
|
-
style={{
|
|
358
|
-
flexDirection: 'row',
|
|
359
|
-
justifyContent: 'space-between',
|
|
360
|
-
}}>
|
|
361
|
-
<PlaceholderLine
|
|
362
|
-
height={30}
|
|
363
|
-
width={10}
|
|
364
|
-
style={{ marginBottom: 20 }}
|
|
365
|
-
/>
|
|
366
|
-
<PlaceholderLine
|
|
367
|
-
height={30}
|
|
368
|
-
width={50}
|
|
369
|
-
style={{ marginBottom: 20 }}
|
|
370
|
-
/>
|
|
371
|
-
<PlaceholderLine
|
|
372
|
-
height={30}
|
|
373
|
-
width={30}
|
|
374
|
-
style={{ marginBottom: 20 }}
|
|
375
|
-
/>
|
|
376
|
-
</View>
|
|
377
|
-
))}
|
|
378
|
-
</Placeholder>
|
|
379
|
-
))}
|
|
380
|
-
</>
|
|
381
|
-
) : (
|
|
382
|
-
<ProductEditions>
|
|
383
|
-
{product?.extras.map((extra: any) =>
|
|
384
|
-
<ExtraOptions key={extra.id} options={extra.options} />
|
|
385
|
-
)}
|
|
371
|
+
</WrapContent>
|
|
372
|
+
</View>
|
|
386
373
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
}
|
|
450
|
-
balance={balance}
|
|
451
|
-
option={option}
|
|
452
|
-
suboption={suboption}
|
|
453
|
-
state={currentState}
|
|
454
|
-
disabled={
|
|
455
|
-
isSoldOut ||
|
|
456
|
-
maxProductQuantity <= 0
|
|
457
|
-
}
|
|
458
|
-
/>
|
|
459
|
-
);
|
|
460
|
-
},
|
|
461
|
-
)}
|
|
462
|
-
</WrapperSubOption>
|
|
463
|
-
</ProductOption>
|
|
464
|
-
</View>
|
|
465
|
-
)}
|
|
466
|
-
</React.Fragment>
|
|
467
|
-
);
|
|
468
|
-
}),
|
|
469
|
-
)}
|
|
470
|
-
</>
|
|
471
|
-
) : (
|
|
472
|
-
<>
|
|
473
|
-
{selOpt == -1 ? (
|
|
474
|
-
<View style={styles.optionContainer}>
|
|
475
|
-
<SectionTitle>
|
|
476
|
-
<OText size={16}>
|
|
477
|
-
{t('INGREDIENTS', 'Ingredients')}
|
|
478
|
-
</OText>
|
|
479
|
-
</SectionTitle>
|
|
480
|
-
<WrapperIngredients
|
|
481
|
-
style={{
|
|
482
|
-
backgroundColor:
|
|
483
|
-
isSoldOut || maxProductQuantity <= 0
|
|
484
|
-
? 'hsl(0, 0%, 72%)'
|
|
485
|
-
: theme.colors.white,
|
|
486
|
-
}}>
|
|
487
|
-
{product?.ingredients.map((ingredient: any) => (
|
|
488
|
-
<ProductIngredient
|
|
489
|
-
key={ingredient.id}
|
|
490
|
-
ingredient={ingredient}
|
|
491
|
-
state={
|
|
492
|
-
productCart.ingredients[`id:${ingredient.id}`]
|
|
493
|
-
}
|
|
494
|
-
onChange={handleChangeIngredientState}
|
|
495
|
-
/>
|
|
496
|
-
))}
|
|
497
|
-
</WrapperIngredients>
|
|
498
|
-
</View>
|
|
499
|
-
) : (
|
|
500
|
-
<>
|
|
501
|
-
{product?.extras.map((extra: any) =>
|
|
502
|
-
extra.options.map((option: any) => {
|
|
503
|
-
if (
|
|
504
|
-
option.id == selOpt ||
|
|
505
|
-
(hasRespected(
|
|
506
|
-
extra.options,
|
|
507
|
-
option.respect_to,
|
|
508
|
-
) &&
|
|
509
|
-
showOption(option))
|
|
510
|
-
) {
|
|
511
|
-
const currentState =
|
|
512
|
-
productCart.options[`id:${option.id}`] || {};
|
|
513
|
-
return (
|
|
514
|
-
<React.Fragment key={option.id}>
|
|
515
|
-
{showOption(option) && (
|
|
516
|
-
<View style={styles.optionContainer}>
|
|
517
|
-
<ProductOption
|
|
518
|
-
option={option}
|
|
519
|
-
currentState={currentState}
|
|
520
|
-
error={errors[`id:${option.id}`]}>
|
|
521
|
-
<WrapperSubOption
|
|
522
|
-
style={{
|
|
523
|
-
backgroundColor: isError(
|
|
524
|
-
option.id,
|
|
525
|
-
),
|
|
526
|
-
}}>
|
|
527
|
-
{option.suboptions.map(
|
|
528
|
-
(suboption: any) => {
|
|
529
|
-
const currentState =
|
|
530
|
-
productCart.options[
|
|
531
|
-
`id:${option.id}`
|
|
532
|
-
]?.suboptions[
|
|
533
|
-
`id:${suboption.id}`
|
|
534
|
-
] || {};
|
|
535
|
-
const balance =
|
|
536
|
-
productCart.options[
|
|
537
|
-
`id:${option.id}`
|
|
538
|
-
]?.balance || 0;
|
|
539
|
-
return (
|
|
540
|
-
<ProductOptionSubOption
|
|
541
|
-
key={suboption.id}
|
|
542
|
-
onChange={
|
|
543
|
-
handleChangeSuboptionState
|
|
544
|
-
}
|
|
545
|
-
balance={balance}
|
|
546
|
-
option={option}
|
|
547
|
-
suboption={suboption}
|
|
548
|
-
state={currentState}
|
|
549
|
-
disabled={
|
|
550
|
-
isSoldOut ||
|
|
551
|
-
maxProductQuantity <= 0
|
|
552
|
-
}
|
|
553
|
-
/>
|
|
554
|
-
);
|
|
555
|
-
},
|
|
556
|
-
)}
|
|
557
|
-
</WrapperSubOption>
|
|
558
|
-
</ProductOption>
|
|
559
|
-
</View>
|
|
560
|
-
)}
|
|
561
|
-
</React.Fragment>
|
|
562
|
-
);
|
|
563
|
-
}
|
|
564
|
-
}),
|
|
565
|
-
)}
|
|
566
|
-
</>
|
|
374
|
+
<WrapContent>
|
|
375
|
+
{loading && !product && (
|
|
376
|
+
<>
|
|
377
|
+
{[...Array(2)].map((item, i) => (
|
|
378
|
+
<Placeholder
|
|
379
|
+
key={i}
|
|
380
|
+
style={{ marginBottom: 20 }}
|
|
381
|
+
Animation={Fade}>
|
|
382
|
+
<PlaceholderLine
|
|
383
|
+
height={40}
|
|
384
|
+
style={{ flex: 1, marginTop: 10 }}
|
|
385
|
+
/>
|
|
386
|
+
{[...Array(3)].map((item, i) => (
|
|
387
|
+
<View
|
|
388
|
+
key={'place_key_' + i}
|
|
389
|
+
style={{
|
|
390
|
+
flexDirection: 'row',
|
|
391
|
+
justifyContent: 'space-between',
|
|
392
|
+
}}>
|
|
393
|
+
<PlaceholderLine
|
|
394
|
+
height={30}
|
|
395
|
+
width={10}
|
|
396
|
+
style={{ marginBottom: 20 }}
|
|
397
|
+
/>
|
|
398
|
+
<PlaceholderLine
|
|
399
|
+
height={30}
|
|
400
|
+
width={50}
|
|
401
|
+
style={{ marginBottom: 20 }}
|
|
402
|
+
/>
|
|
403
|
+
<PlaceholderLine
|
|
404
|
+
height={30}
|
|
405
|
+
width={30}
|
|
406
|
+
style={{ marginBottom: 20 }}
|
|
407
|
+
/>
|
|
408
|
+
</View>
|
|
409
|
+
))}
|
|
410
|
+
</Placeholder>
|
|
411
|
+
))}
|
|
412
|
+
</>
|
|
413
|
+
)}
|
|
414
|
+
|
|
415
|
+
{!loading && product && extraOptions?.length > 0 && <ExtraOptions options={extraOptions} />}
|
|
416
|
+
</WrapContent>
|
|
417
|
+
|
|
418
|
+
<WrapContent>
|
|
419
|
+
{!loading && product && (
|
|
420
|
+
<ProductEditions>
|
|
421
|
+
<View
|
|
422
|
+
onLayout={(event: any) => setOptionsLayout({ ...optionsLayout, wrapper: event.nativeEvent.layout })}
|
|
423
|
+
>
|
|
424
|
+
{product?.ingredients.length > 0 && (
|
|
425
|
+
<View
|
|
426
|
+
style={styles.optionContainer}
|
|
427
|
+
onLayout={(event: any) => setOptionsLayout(
|
|
428
|
+
{
|
|
429
|
+
...optionsLayout,
|
|
430
|
+
ingredients: {
|
|
431
|
+
...event.nativeEvent.layout,
|
|
432
|
+
position: 0,
|
|
433
|
+
key: 'ingredients'
|
|
434
|
+
}
|
|
435
|
+
}
|
|
567
436
|
)}
|
|
568
|
-
|
|
437
|
+
>
|
|
438
|
+
<SectionTitle>
|
|
439
|
+
<OText size={16}>
|
|
440
|
+
{t('INGREDIENTS', 'Ingredients')}
|
|
441
|
+
</OText>
|
|
442
|
+
</SectionTitle>
|
|
443
|
+
<WrapperIngredients
|
|
444
|
+
style={{
|
|
445
|
+
backgroundColor:
|
|
446
|
+
isSoldOut || maxProductQuantity <= 0
|
|
447
|
+
? 'hsl(0, 0%, 72%)'
|
|
448
|
+
: theme.colors.white,
|
|
449
|
+
}}>
|
|
450
|
+
{product?.ingredients.map((ingredient: any) => (
|
|
451
|
+
<ProductIngredient
|
|
452
|
+
key={ingredient.id}
|
|
453
|
+
ingredient={ingredient}
|
|
454
|
+
state={
|
|
455
|
+
productCart.ingredients[`id:${ingredient.id}`]
|
|
456
|
+
}
|
|
457
|
+
onChange={handleChangeIngredientState}
|
|
458
|
+
/>
|
|
459
|
+
))}
|
|
460
|
+
</WrapperIngredients>
|
|
461
|
+
</View>
|
|
569
462
|
)}
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
463
|
+
{product?.extras.map((extra: any) => extra.options.map((option: any) => {
|
|
464
|
+
const currentState = productCart.options[`id:${option.id}`] || {};
|
|
465
|
+
return (
|
|
466
|
+
<React.Fragment key={`popt_${option.id}`}>
|
|
467
|
+
{showOption(option) && (
|
|
468
|
+
<View
|
|
469
|
+
style={styles.optionContainer}
|
|
470
|
+
onLayout={
|
|
471
|
+
(event: any) => setOptionsLayout(
|
|
472
|
+
{
|
|
473
|
+
...optionsLayout,
|
|
474
|
+
[`opt_${option.id}`]: {
|
|
475
|
+
...event.nativeEvent.layout,
|
|
476
|
+
position: extraOptions.map((i: any) => i.id).indexOf(option.id) + (product?.ingredients.length > 0 ? 1 : 0),
|
|
477
|
+
key: `opt_${option.id}`
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
)
|
|
481
|
+
}
|
|
482
|
+
>
|
|
483
|
+
<ProductOption
|
|
484
|
+
option={option}
|
|
485
|
+
currentState={currentState}
|
|
486
|
+
error={errors[`id:${option.id}`]}
|
|
487
|
+
>
|
|
488
|
+
<WrapperSubOption
|
|
489
|
+
style={{
|
|
490
|
+
backgroundColor: isError(option.id),
|
|
491
|
+
}}>
|
|
492
|
+
{option.suboptions.map(
|
|
493
|
+
(suboption: any) => {
|
|
494
|
+
const currentState =
|
|
495
|
+
productCart.options[
|
|
496
|
+
`id:${option.id}`
|
|
497
|
+
]?.suboptions[
|
|
498
|
+
`id:${suboption.id}`
|
|
499
|
+
] || {};
|
|
500
|
+
const balance =
|
|
501
|
+
productCart.options[
|
|
502
|
+
`id:${option.id}`
|
|
503
|
+
]?.balance || 0;
|
|
504
|
+
return (
|
|
505
|
+
<ProductOptionSubOption
|
|
506
|
+
key={suboption.id}
|
|
507
|
+
onChange={
|
|
508
|
+
handleChangeSuboptionState
|
|
509
|
+
}
|
|
510
|
+
balance={balance}
|
|
511
|
+
option={option}
|
|
512
|
+
suboption={suboption}
|
|
513
|
+
state={currentState}
|
|
514
|
+
disabled={
|
|
515
|
+
isSoldOut ||
|
|
516
|
+
maxProductQuantity <= 0
|
|
517
|
+
}
|
|
518
|
+
/>
|
|
519
|
+
);
|
|
520
|
+
},
|
|
521
|
+
)}
|
|
522
|
+
</WrapperSubOption>
|
|
523
|
+
</ProductOption>
|
|
524
|
+
</View>
|
|
525
|
+
)}
|
|
526
|
+
</React.Fragment>
|
|
527
|
+
);
|
|
528
|
+
}))}
|
|
529
|
+
</View>
|
|
530
|
+
|
|
531
|
+
<ProductComment>
|
|
532
|
+
<SectionTitle>
|
|
533
|
+
<OText size={16} weight={'600'} lineHeight={24}>
|
|
534
|
+
{t('SPECIAL_COMMENT', 'Special comment')}
|
|
535
|
+
</OText>
|
|
536
|
+
</SectionTitle>
|
|
537
|
+
<OInput
|
|
538
|
+
multiline={true}
|
|
539
|
+
numberOfLines={10}
|
|
540
|
+
placeholder={t('SPECIAL_COMMENT', 'Special comment')}
|
|
541
|
+
value={productCart.comment}
|
|
542
|
+
onChange={(val: string) =>
|
|
543
|
+
handleChangeCommentState({ target: { value: val } })
|
|
544
|
+
}
|
|
545
|
+
isDisabled={
|
|
546
|
+
!(productCart && !isSoldOut && maxProductQuantity)
|
|
547
|
+
}
|
|
548
|
+
style={{
|
|
549
|
+
height: 100,
|
|
550
|
+
justifyContent: "flex-end",
|
|
551
|
+
alignItems: 'flex-start',
|
|
552
|
+
borderWidth: 1,
|
|
553
|
+
borderRadius: 8,
|
|
554
|
+
borderColor: theme.colors.border,
|
|
555
|
+
}}
|
|
556
|
+
/>
|
|
557
|
+
</ProductComment>
|
|
558
|
+
</ProductEditions>
|
|
559
|
+
)}
|
|
560
|
+
</WrapContent>
|
|
561
|
+
</ScrollView>
|
|
562
|
+
)}
|
|
563
|
+
|
|
564
|
+
{error && error.length > 0 && (
|
|
565
|
+
<NotFoundSource content={error[0]?.message || error[0]} />
|
|
566
|
+
)}
|
|
567
|
+
|
|
606
568
|
{!loading && !error && product && (
|
|
607
569
|
<ProductActions>
|
|
608
570
|
<OText size={16} lineHeight={24} weight={'600'}>
|
|
@@ -3,6 +3,7 @@ import styled, { css } from 'styled-components/native'
|
|
|
3
3
|
export const WrapHeader = styled.View`
|
|
4
4
|
position: relative;
|
|
5
5
|
z-index: 1;
|
|
6
|
+
margin-bottom: 20px;
|
|
6
7
|
`
|
|
7
8
|
|
|
8
9
|
export const TopHeader = styled.View`
|
|
@@ -26,11 +27,8 @@ export const ProductHeader = styled.ImageBackground`
|
|
|
26
27
|
`
|
|
27
28
|
|
|
28
29
|
export const WrapContent = styled.View`
|
|
29
|
-
padding:
|
|
30
|
-
|
|
31
|
-
bottom: 20px;
|
|
32
|
-
background-color: white;
|
|
33
|
-
z-index: 100;
|
|
30
|
+
padding: 0 40px;
|
|
31
|
+
background-color: #FFF;
|
|
34
32
|
`
|
|
35
33
|
|
|
36
34
|
export const ProductTitle = styled.View`
|
|
@@ -39,7 +37,7 @@ export const ProductTitle = styled.View`
|
|
|
39
37
|
`
|
|
40
38
|
|
|
41
39
|
export const ProductDescription = styled.View`
|
|
42
|
-
margin-bottom:
|
|
40
|
+
margin-bottom: 10px;
|
|
43
41
|
`
|
|
44
42
|
|
|
45
43
|
export const ProductEditions = styled.View`
|