ordering-ui-react-native 0.16.49 → 0.16.52

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.
Files changed (25) hide show
  1. package/package.json +1 -1
  2. package/src/components/ReviewProducts/index.tsx +11 -0
  3. package/src/components/SingleProductReview/index.tsx +1 -1
  4. package/themes/original/index.tsx +6 -0
  5. package/themes/original/src/components/BusinessController/index.tsx +12 -4
  6. package/themes/original/src/components/BusinessProductsList/index.tsx +1 -0
  7. package/themes/original/src/components/BusinessProductsListing/index.tsx +4 -4
  8. package/themes/original/src/components/BusinessesListing/Layout/Appointment/index.tsx +36 -24
  9. package/themes/original/src/components/BusinessesListing/Layout/Appointment/styles.tsx +3 -2
  10. package/themes/original/src/components/BusinessesListing/Layout/Original/index.tsx +27 -24
  11. package/themes/original/src/components/BusinessesListing/index.tsx +99 -25
  12. package/themes/original/src/components/ProductForm/index.tsx +481 -481
  13. package/themes/original/src/components/ProductForm/styles.tsx +5 -1
  14. package/themes/original/src/components/Reviews/ReviewDriver/index.tsx +301 -0
  15. package/themes/original/src/components/Reviews/ReviewDriver/styles.tsx +39 -0
  16. package/themes/original/src/components/Reviews/ReviewOrder/index.tsx +326 -0
  17. package/themes/original/src/components/Reviews/ReviewOrder/styles.tsx +53 -0
  18. package/themes/original/src/components/Reviews/ReviewProducts/index.tsx +101 -0
  19. package/themes/original/src/components/Reviews/ReviewProducts/styles.tsx +17 -0
  20. package/themes/original/src/components/Reviews/index.tsx +9 -0
  21. package/themes/original/src/components/ServiceForm/index.tsx +15 -5
  22. package/themes/original/src/components/SignupForm/index.tsx +26 -24
  23. package/themes/original/src/components/SingleProductCard/index.tsx +3 -2
  24. package/themes/original/src/components/shared/OBottomPopup.tsx +26 -7
  25. package/themes/original/src/types/index.tsx +26 -20
@@ -373,518 +373,518 @@ export const ProductOptionsUI = (props: any) => {
373
373
  <OIcon src={theme.images.general.arrow_left} width={30} />
374
374
  </TopActions>
375
375
  </TopHeader>
376
- <ScrollView ref={scrollViewRef}>
377
- {!error && (
378
- <View style={{ paddingBottom: 80 }}>
379
- <WrapHeader onLayout={(event: any) => setHeaderRefHeight(event.nativeEvent.layout?.height)}>
380
- {loading && !product ? (
381
- <View style={styles.productHeaderSkeleton}>
382
- <Placeholder Animation={Fade}>
383
- <PlaceholderLine
384
- height={258}
385
- style={{ borderRadius: 0 }}
386
- width={windowWidth}
387
- />
388
- </Placeholder>
389
- </View>
390
- ) : (
391
- <>
392
- <Swiper
393
- loop={false}
394
- ref={swiperRef}
395
- showsButtons={true}
396
- style={styles.mainSwiper}
397
- showsPagination={false}
398
- onIndexChanged={(index) => handleChangeMainIndex(index)}
399
- prevButton={
400
- <View style={styles.swiperButton}>
401
- <IconAntDesign
402
- name="caretleft"
403
- color={theme.colors.white}
404
- size={13}
405
- // style={styles.starIcon}
406
- />
407
- </View>
408
- }
409
- nextButton={
410
- <View style={styles.swiperButton}>
411
- <IconAntDesign
412
- name="caretright"
413
- color={theme.colors.white}
414
- size={13}
415
- // style={styles.starIcon}
376
+ {!error && (
377
+ <ScrollView
378
+ ref={scrollViewRef}
379
+ contentContainerStyle={{ paddingBottom: 80 }}
380
+ stickyHeaderIndices={[2]}>
381
+ <WrapHeader onLayout={(event: any) => setHeaderRefHeight(event.nativeEvent.layout?.height)}>
382
+ {loading && !product ? (
383
+ <View style={styles.productHeaderSkeleton}>
384
+ <Placeholder Animation={Fade}>
385
+ <PlaceholderLine
386
+ height={258}
387
+ style={{ borderRadius: 0 }}
388
+ width={windowWidth}
389
+ />
390
+ </Placeholder>
391
+ </View>
392
+ ) : (
393
+ <>
394
+ <Swiper
395
+ loop={false}
396
+ ref={swiperRef}
397
+ showsButtons={true}
398
+ style={styles.mainSwiper}
399
+ showsPagination={false}
400
+ onIndexChanged={(index) => handleChangeMainIndex(index)}
401
+ prevButton={
402
+ <View style={styles.swiperButton}>
403
+ <IconAntDesign
404
+ name="caretleft"
405
+ color={theme.colors.white}
406
+ size={13}
407
+ // style={styles.starIcon}
408
+ />
409
+ </View>
410
+ }
411
+ nextButton={
412
+ <View style={styles.swiperButton}>
413
+ <IconAntDesign
414
+ name="caretright"
415
+ color={theme.colors.white}
416
+ size={13}
417
+ // style={styles.starIcon}
418
+ />
419
+ </View>
420
+ }
421
+ >
422
+ {gallery && gallery.length > 0 && gallery.map((img, i) => (
423
+ <View
424
+ style={styles.slide1}
425
+ key={i}
426
+ >
427
+ {img.includes('image') ? (
428
+ <FastImage
429
+ style={{ height: '100%', opacity: isSoldOut ? 0.5 : 1 }}
430
+ source={{
431
+ uri: optimizeImage(img, 'h_1024,c_limit'),
432
+ priority: FastImage.priority.normal,
433
+ }}
416
434
  />
417
- </View>
418
- }
419
- >
420
- {gallery && gallery.length > 0 && gallery.map((img, i) => (
435
+ ) : (
436
+ <>
437
+ <YoutubePlayer
438
+ height={300}
439
+ play={playing}
440
+ videoId={img}
441
+ onChangeState={onStateChange}
442
+ />
443
+ <Button title={playing ? "pause" : "play"} onPress={togglePlaying} />
444
+ </>
445
+ )}
446
+ </View>
447
+ ))}
448
+ </Swiper>
449
+ <ScrollView
450
+ horizontal
451
+ contentContainerStyle={{
452
+ paddingHorizontal: 30,
453
+ paddingVertical: 15
454
+ }}
455
+ >
456
+ {gallery.length > 0 && gallery.map((img, index) => (
457
+ <TouchableOpacity
458
+ key={index}
459
+ onPress={() => handleClickThumb(index)}
460
+ >
421
461
  <View
422
- style={styles.slide1}
423
- key={i}
462
+ style={{
463
+ height: 56,
464
+ borderRadius: 8,
465
+ margin: 8,
466
+ opacity: index === thumbsSwiper ? 1 : 0.8
467
+ }}
424
468
  >
425
469
  {img.includes('image') ? (
426
- <FastImage
427
- style={{ height: '100%', opacity: isSoldOut ? 0.5 : 1 }}
428
- source={{
429
- uri: optimizeImage(img, 'h_1024,c_limit'),
430
- priority: FastImage.priority.normal,
470
+ <OIcon
471
+ url={img}
472
+ style={{
473
+ borderColor: theme.colors.lightGray,
474
+ borderRadius: 8,
475
+ minHeight: '100%',
476
+ opacity: isSoldOut ? 0.5 : 1
431
477
  }}
478
+ width={56}
479
+ height={56}
480
+ cover
432
481
  />
433
482
  ) : (
434
- <>
435
- <YoutubePlayer
436
- height={300}
437
- play={playing}
438
- videoId={img}
439
- onChangeState={onStateChange}
440
- />
441
- <Button title={playing ? "pause" : "play"} onPress={togglePlaying} />
442
- </>
483
+ <OIcon
484
+ url={'http://img.youtube.com/vi/' + img + '/0.jpg'}
485
+ style={{
486
+ borderColor: theme.colors.lightGray,
487
+ borderRadius: 8,
488
+ minHeight: '100%',
489
+ opacity: isSoldOut ? 0.5 : 1
490
+ }}
491
+ width={56}
492
+ height={56}
493
+ cover
494
+ />
443
495
  )}
444
496
  </View>
445
- ))}
446
- </Swiper>
447
- <ScrollView
448
- horizontal
449
- contentContainerStyle={{
450
- paddingHorizontal: 30,
451
- paddingVertical: 15
452
- }}
453
- >
454
- {gallery.length > 0 && gallery.map((img, index) => (
455
- <TouchableOpacity
456
- key={index}
457
- onPress={() => handleClickThumb(index)}
458
- >
459
- <View
460
- style={{
461
- height: 56,
462
- borderRadius: 8,
463
- margin: 8,
464
- opacity: index === thumbsSwiper ? 1 : 0.8
465
- }}
466
- >
467
- {img.includes('image') ? (
468
- <OIcon
469
- url={img}
470
- style={{
471
- borderColor: theme.colors.lightGray,
472
- borderRadius: 8,
473
- minHeight: '100%',
474
- opacity: isSoldOut ? 0.5 : 1
475
- }}
476
- width={56}
477
- height={56}
478
- cover
479
- />
480
- ) : (
481
- <OIcon
482
- url={'http://img.youtube.com/vi/' + img + '/0.jpg'}
483
- style={{
484
- borderColor: theme.colors.lightGray,
485
- borderRadius: 8,
486
- minHeight: '100%',
487
- opacity: isSoldOut ? 0.5 : 1
488
- }}
489
- width={56}
490
- height={56}
491
- cover
492
- />
493
- )}
494
- </View>
495
- </TouchableOpacity>
497
+ </TouchableOpacity>
496
498
 
497
- ))}
498
- </ScrollView>
499
+ ))}
500
+ </ScrollView>
501
+ </>
502
+ )}
503
+ </WrapHeader>
504
+ <ProductSummary onLayout={(event: any) => setSummaryRefHeight(event.nativeEvent.layout?.height)}>
505
+ <ProductTitle>
506
+ {loading && !product ? (
507
+ <Placeholder Animation={Fade}>
508
+ <View
509
+ style={{
510
+ flexDirection: 'row',
511
+ justifyContent: 'space-between',
512
+ }}>
513
+ <PlaceholderLine width={40} height={20} />
514
+ <PlaceholderLine width={30} height={20} />
515
+ </View>
516
+ </Placeholder>
517
+ ) : (
518
+ <>
519
+ <View style={{ flexDirection: 'row' }}>
520
+ <OText
521
+ size={20}
522
+ lineHeight={30}
523
+ weight={'600'}
524
+ style={{ flex: 1, marginBottom: 10 }}>
525
+ {product?.name || productCart.name}
526
+ </OText>
527
+ {!!product?.calories && (
528
+ <OText size={16} style={{ color: '#808080' }}>{product?.calories} cal
529
+ </OText>
530
+ )}
531
+ </View>
532
+ {((!!product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (!!product?.estimated_person)) && (
533
+ <OText size={14} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={'#909BA9'} mBottom={7}>
534
+ {
535
+ ((product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (productCart?.sku && productCart?.sku !== '-1' && productCart?.sku !== '1'))
536
+ && <>{t('SKU', 'Sku')}{' '}{product?.sku || productCart?.sku}</>
537
+ }
538
+ {product?.sku && product?.sku !== '-1' && product?.sku !== '1' && product?.estimated_person && (
539
+ <>&nbsp;&#183;&nbsp;</>
540
+ )}
541
+ {product?.estimated_person
542
+ && <>{product?.estimated_person}{' '}{t('ESTIMATED_PERSONS', 'persons')}</>
543
+ }
544
+ </OText>
545
+ )}
546
+ {isHaveWeight ? (
547
+ <OText size={16} lineHeight={24} color={theme.colors.primary}>{parsePrice(pricePerWeightUnit)} / {product?.weight_unit}</OText>
548
+ ) : (
549
+ <View style={{ flexDirection: 'row', marginBottom: 10 }}>
550
+ <OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
551
+ {product?.offer_price !== null && product?.in_offer && (
552
+ <OText style={{
553
+ fontSize: 14,
554
+ color: '#808080',
555
+ textDecorationLine: 'line-through',
556
+ marginLeft: 7,
557
+ marginRight: 7
558
+ }}>{product?.offer_price ? parsePrice(product?.offer_price) : ''}</OText>
559
+ )}
560
+ </View>
561
+ )}
499
562
  </>
500
563
  )}
501
- </WrapHeader>
502
- <WrapContent>
503
- <ProductSummary onLayout={(event: any) => setSummaryRefHeight(event.nativeEvent.layout?.height)}>
504
- <ProductTitle>
505
- {loading && !product ? (
506
- <Placeholder Animation={Fade}>
507
- <View
508
- style={{
509
- flexDirection: 'row',
510
- justifyContent: 'space-between',
511
- }}>
512
- <PlaceholderLine width={40} height={20} />
513
- <PlaceholderLine width={30} height={20} />
514
- </View>
515
- </Placeholder>
564
+ </ProductTitle>
565
+ <ProductDescription>
566
+ <OText color={theme.colors.textSecondary} size={12} lineHeight={18}>
567
+ {product?.description || productCart?.description}
568
+ </OText>
569
+ </ProductDescription>
570
+ <ScrollView
571
+ horizontal
572
+ showsHorizontalScrollIndicator={false}
573
+ contentContainerStyle={{ paddingBottom: 30 }}
574
+ >
575
+ {product?.tags?.map((tag: any) => (
576
+ <View
577
+ key={tag.id}
578
+ style={styles.productTagWrapper}
579
+ >
580
+ {!!tag?.image ? (
581
+ <OIcon
582
+ url={optimizeImage(tag?.image, 'h_40,c_limit')}
583
+ style={styles.productTagImageStyle}
584
+ />
516
585
  ) : (
517
- <>
518
- <View style={{ flexDirection: 'row' }}>
519
- <OText
520
- size={20}
521
- lineHeight={30}
522
- weight={'600'}
523
- style={{ flex: 1, marginBottom: 10 }}>
524
- {product?.name || productCart.name}
525
- </OText>
526
- {!!product?.calories && (
527
- <OText size={16} style={{ color: '#808080' }}>{product?.calories} cal
528
- </OText>
529
- )}
530
- </View>
531
- {((!!product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (!!product?.estimated_person)) && (
532
- <OText size={14} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={'#909BA9'} mBottom={7}>
533
- {
534
- ((product?.sku && product?.sku !== '-1' && product?.sku !== '1') || (productCart?.sku && productCart?.sku !== '-1' && productCart?.sku !== '1'))
535
- && <>{t('SKU', 'Sku')}{' '}{product?.sku || productCart?.sku}</>
536
- }
537
- {product?.sku && product?.sku !== '-1' && product?.sku !== '1' && product?.estimated_person && (
538
- <>&nbsp;&#183;&nbsp;</>
539
- )}
540
- {product?.estimated_person
541
- && <>{product?.estimated_person}{' '}{t('ESTIMATED_PERSONS', 'persons')}</>
542
- }
543
- </OText>
544
- )}
545
- {isHaveWeight ? (
546
- <OText size={16} lineHeight={24} color={theme.colors.primary}>{parsePrice(pricePerWeightUnit)} / {product?.weight_unit}</OText>
547
- ) : (
548
- <View style={{ flexDirection: 'row', marginBottom: 10 }}>
549
- <OText size={16} style={{ flex: I18nManager.isRTL ? 1 : 0 }} color={theme.colors.primary}>{productCart.price ? parsePrice(productCart.price) : ''}</OText>
550
- {product?.offer_price !== null && product?.in_offer && (
551
- <OText style={{
552
- fontSize: 14,
553
- color: '#808080',
554
- textDecorationLine: 'line-through',
555
- marginLeft: 7,
556
- marginRight: 7
557
- }}>{product?.offer_price ? parsePrice(product?.offer_price) : ''}</OText>
558
- )}
559
- </View>
560
- )}
561
- </>
586
+ <OIcon
587
+ src={theme.images?.dummies?.product}
588
+ style={styles.productTagImageStyle}
589
+ />
562
590
  )}
563
- </ProductTitle>
564
- <ProductDescription>
565
- <OText color={theme.colors.textSecondary} size={12} lineHeight={18}>
566
- {product?.description || productCart?.description}
591
+ <OText color={theme.colors.textSecondary} size={12} style={styles.productTagNameStyle}>{tag.name}</OText>
592
+ </View>
593
+ ))}
594
+ </ScrollView>
595
+ </ProductSummary>
596
+ {(!loading && product) && (
597
+ <ExtraOptionWrap
598
+ horizontal
599
+ showsHorizontalScrollIndicator={false}
600
+ style={{ marginBottom: 20 }}
601
+ contentContainerStyle={{ marginHorizontal: 40, paddingHorizontal: 33, backgroundColor: theme.colors.white }}
602
+ >
603
+ <TouchableOpacity
604
+ key={`eopt_all_0`}
605
+ onPress={() => setSelectedOpt(0)}
606
+ style={[
607
+ styles.extraItem,
608
+ {
609
+ borderBottomColor: selOpt == 0 ? theme.colors.textNormal : theme.colors.border,
610
+ },
611
+ ]}>
612
+ <OText
613
+ color={selOpt == 0 ? theme.colors.textNormal : theme.colors.textSecondary}
614
+ size={selOpt == 0 ? 14 : 12}
615
+ weight={selOpt == 0 ? '600' : 'normal'}>
616
+ {t('ALL', 'All')}
617
+ </OText>
618
+ </TouchableOpacity>
619
+ {product?.ingredients.length > 0 && (
620
+ <TouchableOpacity
621
+ key={`eopt_all_00`}
622
+ onPress={() => setSelectedOpt(-1)}
623
+ style={[
624
+ styles.extraItem,
625
+ {
626
+ borderBottomColor:
627
+ selOpt == -1 ? theme.colors.textNormal : theme.colors.border,
628
+ },
629
+ ]}>
630
+ <OText
631
+ color={selOpt == -1 ? theme.colors.textNormal : theme.colors.textSecondary}
632
+ size={selOpt == -1 ? 14 : 12}
633
+ weight={selOpt == -1 ? '600' : 'normal'}>
634
+ {t('INGREDIENTS', 'Ingredients')}
567
635
  </OText>
568
- </ProductDescription>
569
- <ScrollView
570
- horizontal
571
- showsHorizontalScrollIndicator={false}
572
- contentContainerStyle={{ paddingBottom: 30 }}
573
- >
574
- {product?.tags?.map((tag: any) => (
636
+ </TouchableOpacity>
637
+ )}
638
+ {product?.extras.map((extra: any) =>
639
+ <ExtraOptions key={extra.id} options={extra.options} />
640
+ )}
641
+ </ExtraOptionWrap>
642
+ )}
643
+ {loading && !product ? (
644
+ <>
645
+ {[...Array(2)].map((item, i) => (
646
+ <Placeholder
647
+ key={i}
648
+ style={{ marginBottom: 20 }}
649
+ Animation={Fade}>
650
+ <PlaceholderLine
651
+ height={40}
652
+ style={{ flex: 1, marginTop: 10 }}
653
+ />
654
+ {[...Array(3)].map((item, i) => (
575
655
  <View
576
- key={tag.id}
577
- style={styles.productTagWrapper}
578
- >
579
- {!!tag?.image ? (
580
- <OIcon
581
- url={optimizeImage(tag?.image, 'h_40,c_limit')}
582
- style={styles.productTagImageStyle}
583
- />
584
- ) : (
585
- <OIcon
586
- src={theme.images?.dummies?.product}
587
- style={styles.productTagImageStyle}
588
- />
589
- )}
590
- <OText color={theme.colors.textSecondary} size={12} style={styles.productTagNameStyle}>{tag.name}</OText>
656
+ key={'place_key_' + i}
657
+ style={{
658
+ flexDirection: 'row',
659
+ justifyContent: 'space-between',
660
+ }}>
661
+ <PlaceholderLine
662
+ height={30}
663
+ width={10}
664
+ style={{ marginBottom: 20 }}
665
+ />
666
+ <PlaceholderLine
667
+ height={30}
668
+ width={50}
669
+ style={{ marginBottom: 20 }}
670
+ />
671
+ <PlaceholderLine
672
+ height={30}
673
+ width={30}
674
+ style={{ marginBottom: 20 }}
675
+ />
591
676
  </View>
592
677
  ))}
593
- </ScrollView>
594
- </ProductSummary>
595
- {loading && !product ? (
678
+ </Placeholder>
679
+ ))}
680
+ </>
681
+ ) : (
682
+ <ProductEditions>
683
+ {selOpt == 0 ? (
596
684
  <>
597
- {[...Array(2)].map((item, i) => (
598
- <Placeholder
599
- key={i}
600
- style={{ marginBottom: 20 }}
601
- Animation={Fade}>
602
- <PlaceholderLine
603
- height={40}
604
- style={{ flex: 1, marginTop: 10 }}
605
- />
606
- {[...Array(3)].map((item, i) => (
607
- <View
608
- key={'place_key_' + i}
609
- style={{
610
- flexDirection: 'row',
611
- justifyContent: 'space-between',
612
- }}>
613
- <PlaceholderLine
614
- height={30}
615
- width={10}
616
- style={{ marginBottom: 20 }}
617
- />
618
- <PlaceholderLine
619
- height={30}
620
- width={50}
621
- style={{ marginBottom: 20 }}
622
- />
623
- <PlaceholderLine
624
- height={30}
625
- width={30}
626
- style={{ marginBottom: 20 }}
685
+ {product?.ingredients.length > 0 && (
686
+ <View style={styles.optionContainer}>
687
+ <SectionTitle>
688
+ <OText size={16}>
689
+ {t('INGREDIENTS', 'Ingredients')}
690
+ </OText>
691
+ </SectionTitle>
692
+ <WrapperIngredients>
693
+ {product?.ingredients.map((ingredient: any) => (
694
+ <ProductIngredient
695
+ key={ingredient.id}
696
+ ingredient={ingredient}
697
+ state={
698
+ productCart.ingredients[`id:${ingredient.id}`]
699
+ }
700
+ onChange={handleChangeIngredientState}
701
+ isSoldOut={isSoldOut}
627
702
  />
628
- </View>
629
- ))}
630
- </Placeholder>
631
- ))}
703
+ ))}
704
+ </WrapperIngredients>
705
+ </View>
706
+ )}
707
+ {product?.extras.sort((a: any, b: any) => a.rank - b.rank).map((extra: any) =>
708
+ extra.options.sort((a: any, b: any) => a.rank - b.rank).map((option: any) => {
709
+ const currentState =
710
+ productCart.options[`id:${option.id}`] || {};
711
+ return (
712
+ <React.Fragment key={`popt_${option.id}`}>
713
+ {showOption(option) && (
714
+ <View style={styles.optionContainer} onLayout={(event: any) => handleOnLayout(event, option?.id)}>
715
+ <ProductOption
716
+ option={option}
717
+ currentState={currentState}
718
+ error={errors[`id:${option.id}`]}>
719
+ <WrapperSubOption
720
+ style={{
721
+ backgroundColor: isError(option.id),
722
+ borderRadius: 7.6
723
+ }}>
724
+ {option.suboptions.sort((a: any, b: any) => a.rank - b.rank).map(
725
+ (suboption: any) => {
726
+ const currentState =
727
+ productCart.options[
728
+ `id:${option.id}`
729
+ ]?.suboptions[
730
+ `id:${suboption.id}`
731
+ ] || {};
732
+ const balance =
733
+ productCart.options[
734
+ `id:${option.id}`
735
+ ]?.balance || 0;
736
+ return (
737
+ <ProductOptionSubOption
738
+ key={suboption.id}
739
+ isSoldOut={isSoldOut}
740
+ onChange={
741
+ handleChangeSuboptionState
742
+ }
743
+ balance={balance}
744
+ option={option}
745
+ suboption={suboption}
746
+ state={currentState}
747
+ disabled={
748
+ isSoldOut ||
749
+ maxProductQuantity <= 0
750
+ }
751
+ setIsScrollAvailable={setIsScrollAvailable}
752
+ error={errors[`id:${option.id}`]}
753
+ />
754
+ );
755
+ },
756
+ )}
757
+ </WrapperSubOption>
758
+ </ProductOption>
759
+ </View>
760
+ )}
761
+ </React.Fragment>
762
+ );
763
+ }),
764
+ )}
632
765
  </>
633
766
  ) : (
634
- <ProductEditions>
635
- <ExtraOptionWrap
636
- horizontal
637
- showsHorizontalScrollIndicator={false}
638
- style={{ marginBottom: 20 }}
639
- contentContainerStyle={{ paddingHorizontal: 33 }}
640
- >
641
- <TouchableOpacity
642
- key={`eopt_all_0`}
643
- onPress={() => setSelectedOpt(0)}
644
- style={[
645
- styles.extraItem,
646
- {
647
- borderBottomColor: selOpt == 0 ? theme.colors.textNormal : theme.colors.border,
648
- },
649
- ]}>
650
- <OText
651
- color={selOpt == 0 ? theme.colors.textNormal : theme.colors.textSecondary}
652
- size={selOpt == 0 ? 14 : 12}
653
- weight={selOpt == 0 ? '600' : 'normal'}>
654
- {t('ALL', 'All')}
655
- </OText>
656
- </TouchableOpacity>
657
- {product?.ingredients.length > 0 && (
658
- <TouchableOpacity
659
- key={`eopt_all_00`}
660
- onPress={() => setSelectedOpt(-1)}
661
- style={[
662
- styles.extraItem,
663
- {
664
- borderBottomColor:
665
- selOpt == -1 ? theme.colors.textNormal : theme.colors.border,
666
- },
667
- ]}>
668
- <OText
669
- color={selOpt == -1 ? theme.colors.textNormal : theme.colors.textSecondary}
670
- size={selOpt == -1 ? 14 : 12}
671
- weight={selOpt == -1 ? '600' : 'normal'}>
767
+ <>
768
+ {selOpt == -1 ? (
769
+ <View style={styles.optionContainer}>
770
+ <SectionTitle>
771
+ <OText size={16}>
672
772
  {t('INGREDIENTS', 'Ingredients')}
673
773
  </OText>
674
- </TouchableOpacity>
675
- )}
676
- {product?.extras.map((extra: any) =>
677
- <ExtraOptions key={extra.id} options={extra.options} />
678
- )}
679
- </ExtraOptionWrap>
680
-
681
- {selOpt == 0 ? (
774
+ </SectionTitle>
775
+ <WrapperIngredients>
776
+ {product?.ingredients.map((ingredient: any) => (
777
+ <ProductIngredient
778
+ key={ingredient.id}
779
+ ingredient={ingredient}
780
+ state={
781
+ productCart.ingredients[`id:${ingredient.id}`]
782
+ }
783
+ onChange={handleChangeIngredientState}
784
+ isSoldOut={isSoldOut}
785
+ />
786
+ ))}
787
+ </WrapperIngredients>
788
+ </View>
789
+ ) : (
682
790
  <>
683
- {product?.ingredients.length > 0 && (
684
- <View style={styles.optionContainer}>
685
- <SectionTitle>
686
- <OText size={16}>
687
- {t('INGREDIENTS', 'Ingredients')}
688
- </OText>
689
- </SectionTitle>
690
- <WrapperIngredients>
691
- {product?.ingredients.map((ingredient: any) => (
692
- <ProductIngredient
693
- key={ingredient.id}
694
- ingredient={ingredient}
695
- state={
696
- productCart.ingredients[`id:${ingredient.id}`]
697
- }
698
- onChange={handleChangeIngredientState}
699
- isSoldOut={isSoldOut}
700
- />
701
- ))}
702
- </WrapperIngredients>
703
- </View>
704
- )}
705
- {product?.extras.sort((a: any, b: any) => a.rank - b.rank).map((extra: any) =>
791
+ {product?.extras.map((extra: any) =>
706
792
  extra.options.sort((a: any, b: any) => a.rank - b.rank).map((option: any) => {
707
- const currentState =
708
- productCart.options[`id:${option.id}`] || {};
709
- return (
710
- <React.Fragment key={`popt_${option.id}`}>
711
- {showOption(option) && (
712
- <View style={styles.optionContainer} onLayout={(event: any) => handleOnLayout(event, option?.id)}>
713
- <ProductOption
714
- option={option}
715
- currentState={currentState}
716
- error={errors[`id:${option.id}`]}>
717
- <WrapperSubOption
718
- style={{
719
- backgroundColor: isError(option.id),
720
- borderRadius: 7.6
721
- }}>
722
- {option.suboptions.sort((a: any, b: any) => a.rank - b.rank).map(
723
- (suboption: any) => {
724
- const currentState =
725
- productCart.options[
726
- `id:${option.id}`
727
- ]?.suboptions[
728
- `id:${suboption.id}`
729
- ] || {};
730
- const balance =
731
- productCart.options[
732
- `id:${option.id}`
733
- ]?.balance || 0;
734
- return (
735
- <ProductOptionSubOption
736
- key={suboption.id}
737
- isSoldOut={isSoldOut}
738
- onChange={
739
- handleChangeSuboptionState
740
- }
741
- balance={balance}
742
- option={option}
743
- suboption={suboption}
744
- state={currentState}
745
- disabled={
746
- isSoldOut ||
747
- maxProductQuantity <= 0
748
- }
749
- setIsScrollAvailable={setIsScrollAvailable}
750
- error={errors[`id:${option.id}`]}
751
- />
752
- );
753
- },
754
- )}
755
- </WrapperSubOption>
756
- </ProductOption>
757
- </View>
758
- )}
759
- </React.Fragment>
760
- );
793
+ if (
794
+ option.id == selOpt ||
795
+ (hasRespected(
796
+ extra.options,
797
+ option.respect_to,
798
+ ) &&
799
+ showOption(option))
800
+ ) {
801
+ const currentState =
802
+ productCart.options[`id:${option.id}`] || {};
803
+ return (
804
+ <React.Fragment key={option.id}>
805
+ {showOption(option) && (
806
+ <View style={styles.optionContainer}>
807
+ <ProductOption
808
+ option={option}
809
+ currentState={currentState}
810
+ error={errors[`id:${option.id}`]}>
811
+ <WrapperSubOption
812
+ style={{
813
+ backgroundColor: isError(
814
+ option.id,
815
+ ),
816
+ }}>
817
+ {option.suboptions.sort((a: any, b: any) => a.rank - b.rank).map(
818
+ (suboption: any) => {
819
+ const currentState =
820
+ productCart.options[
821
+ `id:${option.id}`
822
+ ]?.suboptions[
823
+ `id:${suboption.id}`
824
+ ] || {};
825
+ const balance =
826
+ productCart.options[
827
+ `id:${option.id}`
828
+ ]?.balance || 0;
829
+ return (
830
+ <ProductOptionSubOption
831
+ key={suboption.id}
832
+ onChange={
833
+ handleChangeSuboptionState
834
+ }
835
+ balance={balance}
836
+ option={option}
837
+ suboption={suboption}
838
+ state={currentState}
839
+ disabled={
840
+ isSoldOut ||
841
+ maxProductQuantity <= 0
842
+ }
843
+ />
844
+ );
845
+ },
846
+ )}
847
+ </WrapperSubOption>
848
+ </ProductOption>
849
+ </View>
850
+ )}
851
+ </React.Fragment>
852
+ );
853
+ }
761
854
  }),
762
855
  )}
763
856
  </>
764
- ) : (
765
- <>
766
- {selOpt == -1 ? (
767
- <View style={styles.optionContainer}>
768
- <SectionTitle>
769
- <OText size={16}>
770
- {t('INGREDIENTS', 'Ingredients')}
771
- </OText>
772
- </SectionTitle>
773
- <WrapperIngredients>
774
- {product?.ingredients.map((ingredient: any) => (
775
- <ProductIngredient
776
- key={ingredient.id}
777
- ingredient={ingredient}
778
- state={
779
- productCart.ingredients[`id:${ingredient.id}`]
780
- }
781
- onChange={handleChangeIngredientState}
782
- isSoldOut={isSoldOut}
783
- />
784
- ))}
785
- </WrapperIngredients>
786
- </View>
787
- ) : (
788
- <>
789
- {product?.extras.map((extra: any) =>
790
- extra.options.sort((a: any, b: any) => a.rank - b.rank).map((option: any) => {
791
- if (
792
- option.id == selOpt ||
793
- (hasRespected(
794
- extra.options,
795
- option.respect_to,
796
- ) &&
797
- showOption(option))
798
- ) {
799
- const currentState =
800
- productCart.options[`id:${option.id}`] || {};
801
- return (
802
- <React.Fragment key={option.id}>
803
- {showOption(option) && (
804
- <View style={styles.optionContainer}>
805
- <ProductOption
806
- option={option}
807
- currentState={currentState}
808
- error={errors[`id:${option.id}`]}>
809
- <WrapperSubOption
810
- style={{
811
- backgroundColor: isError(
812
- option.id,
813
- ),
814
- }}>
815
- {option.suboptions.sort((a: any, b: any) => a.rank - b.rank).map(
816
- (suboption: any) => {
817
- const currentState =
818
- productCart.options[
819
- `id:${option.id}`
820
- ]?.suboptions[
821
- `id:${suboption.id}`
822
- ] || {};
823
- const balance =
824
- productCart.options[
825
- `id:${option.id}`
826
- ]?.balance || 0;
827
- return (
828
- <ProductOptionSubOption
829
- key={suboption.id}
830
- onChange={
831
- handleChangeSuboptionState
832
- }
833
- balance={balance}
834
- option={option}
835
- suboption={suboption}
836
- state={currentState}
837
- disabled={
838
- isSoldOut ||
839
- maxProductQuantity <= 0
840
- }
841
- />
842
- );
843
- },
844
- )}
845
- </WrapperSubOption>
846
- </ProductOption>
847
- </View>
848
- )}
849
- </React.Fragment>
850
- );
851
- }
852
- }),
853
- )}
854
- </>
855
- )}
856
- </>
857
- )}
858
- {!product?.hide_special_instructions && (
859
- <ProductComment>
860
- <SectionTitle>
861
- <OText size={16} weight={'600'} lineHeight={24}>
862
- {t('SPECIAL_COMMENT', 'Special comment')}
863
- </OText>
864
- </SectionTitle>
865
- <OInput
866
- multiline
867
- placeholder={t('SPECIAL_COMMENT', 'Special comment')}
868
- value={productCart.comment}
869
- onChange={(val: string) =>
870
- handleChangeCommentState({ target: { value: val } })
871
- }
872
- isDisabled={
873
- !(productCart && !isSoldOut && maxProductQuantity)
874
- }
875
- style={styles.comment}
876
- />
877
- </ProductComment>
878
857
  )}
879
- </ProductEditions>
858
+ </>
880
859
  )}
881
- </WrapContent>
882
- </View>
883
- )}
884
- {!!error && error.length > 0 && (
885
- <NotFoundSource content={error[0]?.message || error[0]} />
886
- )}
887
- </ScrollView>
860
+ {!product?.hide_special_instructions && (
861
+ <ProductComment>
862
+ <SectionTitle>
863
+ <OText size={16} weight={'600'} lineHeight={24}>
864
+ {t('SPECIAL_COMMENT', 'Special comment')}
865
+ </OText>
866
+ </SectionTitle>
867
+ <OInput
868
+ multiline
869
+ placeholder={t('SPECIAL_COMMENT', 'Special comment')}
870
+ value={productCart.comment}
871
+ onChange={(val: string) =>
872
+ handleChangeCommentState({ target: { value: val } })
873
+ }
874
+ isDisabled={
875
+ !(productCart && !isSoldOut && maxProductQuantity)
876
+ }
877
+ style={styles.comment}
878
+ />
879
+ </ProductComment>
880
+ )}
881
+ </ProductEditions>
882
+ )}
883
+ {!!error && error.length > 0 && (
884
+ <NotFoundSource content={error[0]?.message || error[0]} />
885
+ )}
886
+ </ScrollView>
887
+ )}
888
888
  {!loading && !error && product && (
889
889
  <ProductActions ios={Platform?.OS === 'ios'}>
890
890
  <View>