hey-pharmacist-ecommerce 1.1.42 → 1.1.44

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 (105) hide show
  1. package/README.md +70 -8
  2. package/dist/index.d.mts +2550 -3081
  3. package/dist/index.d.ts +2550 -3081
  4. package/dist/index.js +506 -399
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +506 -397
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +2 -2
  9. package/src/components/AccountOverviewTab.tsx +5 -5
  10. package/src/components/AccountReviewsTab.tsx +4 -4
  11. package/src/components/CartItem.tsx +15 -15
  12. package/src/components/Header.tsx +1 -1
  13. package/src/components/Notification.tsx +3 -3
  14. package/src/components/OrderCard.tsx +1 -1
  15. package/src/components/ProductCard.tsx +11 -11
  16. package/src/components/QuickViewModal.tsx +16 -16
  17. package/src/components/RatingDistribution.tsx +2 -2
  18. package/src/components/ReviewCard.tsx +2 -2
  19. package/src/components/ReviewForm.tsx +3 -3
  20. package/src/components/ReviewPromptBanner.tsx +4 -4
  21. package/src/components/ReviewsList.tsx +9 -11
  22. package/src/components/StarRating.tsx +3 -3
  23. package/src/hooks/useProducts.ts +0 -1
  24. package/src/hooks/useSmartSearch.ts +68 -0
  25. package/src/lib/Apis/api.ts +1 -1
  26. package/src/lib/Apis/apis/analytics-api.ts +809 -0
  27. package/src/lib/Apis/apis/notifications-api.ts +8 -6
  28. package/src/lib/Apis/apis/products-api.ts +390 -15
  29. package/src/lib/Apis/apis/stores-api.ts +26 -149
  30. package/src/lib/Apis/apis/web-hooks-api.ts +8 -17
  31. package/src/lib/Apis/models/analytics-period-dto.ts +45 -0
  32. package/src/lib/Apis/models/appointment-overview-dto.ts +71 -0
  33. package/src/lib/Apis/models/category-sales-dto.ts +51 -0
  34. package/src/lib/Apis/models/create-store-dto.ts +12 -0
  35. package/src/lib/Apis/models/customer-overview-dto.ts +96 -0
  36. package/src/lib/Apis/models/{country-stats-response-dto.ts → customer-segment-dto.ts} +12 -13
  37. package/src/lib/Apis/models/dashboard-overview-dto.ts +70 -0
  38. package/src/lib/Apis/models/discount-overview-dto.ts +71 -0
  39. package/src/lib/Apis/models/group-with-no-users-dto.ts +0 -6
  40. package/src/lib/Apis/models/group-with-users-dto.ts +0 -6
  41. package/src/lib/Apis/models/index.ts +29 -38
  42. package/src/lib/Apis/models/{single-recipient-dto.ts → inline-response200.ts} +11 -10
  43. package/src/lib/Apis/models/{create-contact-dto.ts → inline-response2001.ts} +11 -11
  44. package/src/lib/Apis/models/inventory-alert-dto.ts +67 -0
  45. package/src/lib/Apis/models/notification-dto.ts +107 -0
  46. package/src/lib/Apis/models/notifications-paginated-response-dto.ts +58 -0
  47. package/src/lib/Apis/models/order-overview-dto.ts +89 -0
  48. package/src/lib/Apis/models/{single-link-stats-dto.ts → order-status-count-dto.ts} +10 -10
  49. package/src/lib/Apis/models/order.ts +0 -6
  50. package/src/lib/Apis/models/payout-history-item-dto.ts +45 -0
  51. package/src/lib/Apis/models/{single-country-stats-dto.ts → popular-time-slot-dto.ts} +10 -10
  52. package/src/lib/Apis/models/populated-order.ts +0 -6
  53. package/src/lib/Apis/models/preference-update-item.ts +1 -0
  54. package/src/lib/Apis/models/product-overview-dto.ts +90 -0
  55. package/src/lib/Apis/models/product.ts +6 -0
  56. package/src/lib/Apis/models/{create-contact-list-dto.ts → products-aidraft-body.ts} +4 -4
  57. package/src/lib/Apis/models/{schedule-campaign-draft-dto.ts → products-processimage-body.ts} +5 -5
  58. package/src/lib/Apis/models/{contact-full-response-dto.ts → rating-distribution-dto.ts} +9 -10
  59. package/src/lib/Apis/models/recent-review-dto.ts +63 -0
  60. package/src/lib/Apis/models/review-overview-dto.ts +65 -0
  61. package/src/lib/Apis/models/store-balance-dto.ts +39 -0
  62. package/src/lib/Apis/models/store-entity.ts +12 -0
  63. package/src/lib/Apis/models/{link-stats-response-dto.ts → store-finance-overview-dto.ts} +10 -15
  64. package/src/lib/Apis/models/store.ts +12 -0
  65. package/src/lib/Apis/models/{add-contact-to-list-dto.ts → time-series-point-dto.ts} +9 -9
  66. package/src/lib/Apis/models/{create-email-template-dto.ts → top-customer-dto.ts} +20 -14
  67. package/src/lib/Apis/models/{marketing-list-contact-dto.ts → top-discount-dto.ts} +12 -12
  68. package/src/lib/Apis/models/{single-browser-stats-dto.ts → top-product-dto.ts} +18 -12
  69. package/src/lib/Apis/models/{marketing-campaign-content-dto.ts → unread-count-dto.ts} +6 -6
  70. package/src/lib/Apis/models/update-store-dto.ts +12 -0
  71. package/src/lib/Apis/models/update-user-dto.ts +0 -6
  72. package/src/lib/Apis/models/user-group.ts +0 -6
  73. package/src/lib/Apis/models/user-with-no-id.ts +0 -6
  74. package/src/lib/Apis/sharedConfig.ts +1 -1
  75. package/src/screens/CartScreen.tsx +10 -10
  76. package/src/screens/CheckoutScreen.tsx +12 -12
  77. package/src/screens/OrderReviewsScreen.tsx +6 -6
  78. package/src/screens/ProductDetailScreen.tsx +40 -40
  79. package/src/screens/SearchResultsScreen.tsx +17 -21
  80. package/src/screens/ShopScreen.tsx +20 -82
  81. package/src/lib/Apis/apis/marketing-api.ts +0 -3099
  82. package/src/lib/Apis/models/api-key-info-dto.ts +0 -49
  83. package/src/lib/Apis/models/browser-stats-response-dto.ts +0 -40
  84. package/src/lib/Apis/models/campaign-content-response-dto.ts +0 -40
  85. package/src/lib/Apis/models/campaign-draft-dto.ts +0 -175
  86. package/src/lib/Apis/models/campaign-draft-response-dto.ts +0 -40
  87. package/src/lib/Apis/models/campaign-draft-schedule-dto.ts +0 -49
  88. package/src/lib/Apis/models/campaign-draft-schedule-response-dto.ts +0 -40
  89. package/src/lib/Apis/models/campaign-draft-sending-dto.ts +0 -43
  90. package/src/lib/Apis/models/campaign-draft-sending-response-dto.ts +0 -40
  91. package/src/lib/Apis/models/contact-aggregated-stats-response-dto.ts +0 -40
  92. package/src/lib/Apis/models/contact-full-dto.ts +0 -93
  93. package/src/lib/Apis/models/contact-list-stats-response-dto.ts +0 -40
  94. package/src/lib/Apis/models/contact-lists-response-dto.ts +0 -40
  95. package/src/lib/Apis/models/create-marketing-campaign-dto.ts +0 -81
  96. package/src/lib/Apis/models/email-template-response-dto.ts +0 -117
  97. package/src/lib/Apis/models/general-stats-response-dto.ts +0 -40
  98. package/src/lib/Apis/models/send-test-email-dto.ts +0 -28
  99. package/src/lib/Apis/models/single-contact-aggregated-stats-dto.ts +0 -129
  100. package/src/lib/Apis/models/single-contact-list-stats-dto.ts +0 -117
  101. package/src/lib/Apis/models/single-general-stats.ts +0 -153
  102. package/src/lib/Apis/models/store-api-keys-response-dto.ts +0 -34
  103. package/src/lib/Apis/models/update-api-keys-dto.ts +0 -39
  104. package/src/lib/Apis/models/update-campaign-draft-content-dto.ts +0 -27
  105. package/src/lib/Apis/models/update-marketing-camp-draft-dto.ts +0 -81
@@ -361,7 +361,7 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
361
361
  <div className="max-w-[1400px] mx-auto px-8 md:px-12">
362
362
  <button
363
363
  onClick={() => router.push(buildPath('/shop'))}
364
- className="flex items-center gap-2 font-['Poppins',sans-serif] text-[13px] text-hmuted hover:text-hprimary transition-colors"
364
+ className="flex items-center gap-2 text-[13px] text-hmuted hover:text-hprimary transition-colors"
365
365
  >
366
366
  <ChevronLeft className="size-4" />
367
367
  Back to Shop
@@ -405,22 +405,22 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
405
405
 
406
406
  <div className="absolute top-6 left-6 flex flex-col gap-3">
407
407
  {discount > 0 && (
408
- <div className="bg-[#E67E50] text-white rounded-full px-4 py-2">
409
- <span className="font-['Poppins',sans-serif] font-bold text-[12px] uppercase tracking-wide">
408
+ <div className="bg-hsecondary text-white rounded-full px-4 py-2">
409
+ <span className="font-bold text-[12px] uppercase tracking-wide">
410
410
  Save {discount}%
411
411
  </span>
412
412
  </div>
413
413
  )}
414
414
  {/* {product.bestseller && (
415
415
  <div className="bg-hsecondary text-white rounded-full px-4 py-2">
416
- <span className="font-['Poppins',sans-serif] font-semibold text-[11px] uppercase tracking-wide">
416
+ <span className="font-semibold text-[11px] uppercase tracking-wide">
417
417
  Bestseller
418
418
  </span>
419
419
  </div>
420
420
  )}
421
421
  {product.newArrival && (
422
422
  <div className="bg-hprimary text-white rounded-full px-4 py-2">
423
- <span className="font-['Poppins',sans-serif] font-semibold text-[11px] uppercase tracking-wide">
423
+ <span className="font-semibold text-[11px] uppercase tracking-wide">
424
424
  New Arrival
425
425
  </span>
426
426
  </div>
@@ -461,10 +461,10 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
461
461
  <aside className="space-y-6 lg:sticky lg:top-24">
462
462
  {/* Category Path */}
463
463
  <div className="mb-4">
464
- <p className="font-['Poppins',sans-serif] text-[12px] text-hprimary uppercase tracking-wide font-medium mb-2">
464
+ <p className="text-[12px] text-hprimary uppercase tracking-wide font-medium mb-2">
465
465
  {product.brand} • {product.categoryIds?.[0]?.name || 'Uncategorized'}
466
466
  </p>
467
- <h1 className="text-3xl font-['Poppins',sans-serif] font-semibold text-hsecondary tracking-[-1.5px] mb-3">
467
+ <h1 className="text-3xl font-semibold text-hsecondary tracking-[-1.5px] mb-3">
468
468
  {selectedVariant?.name || product.name}
469
469
  </h1>
470
470
  {/* Rating */}
@@ -474,28 +474,28 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
474
474
  <Star
475
475
  key={i}
476
476
  className={`size-4 ${i < Math.floor(reviewStats.averageRating)
477
- ? 'text-[#E67E50] fill-[#E67E50]'
477
+ ? 'text-haccent-500 fill-haccent-500'
478
478
  : 'text-gray-300'
479
479
  }`}
480
480
  />
481
481
  ))}
482
482
  </div>
483
- <span className="font-['Poppins',sans-serif] text-[14px] text-hmuted">
483
+ <span className="text-[14px] text-hmuted">
484
484
  {reviewStats.averageRating} ({reviewStats.reviewCount} {reviewStats.reviewCount === 1 ? 'review' : 'reviews'})
485
485
  </span>
486
486
  </div>
487
487
  {selectedVariant && (
488
488
  <div className="flex items-center gap-3 mb-6 pb-6 border-b-2 border-gray-100">
489
- <span className="font-['Poppins',sans-serif] font-bold text-[40px] text-[#E67E50]">
489
+ <span className="font-bold text-[40px] text-hsecondary">
490
490
  ${variantPrice.toFixed(2)}
491
491
  </span>
492
492
  {variantComparePrice && variantComparePrice > variantPrice && (
493
493
  <>
494
- <span className="font-['Poppins',sans-serif] text-[24px] text-hmuted line-through">
494
+ <span className="text-[24px] text-hmuted line-through">
495
495
  ${variantComparePrice.toFixed(2)}
496
496
  </span>
497
- <div className="px-3 py-1 rounded-full bg-[#E67E50]/10">
498
- <span className="font-['Poppins',sans-serif] font-semibold text-[13px] text-[#E67E50]">
497
+ <div className="px-3 py-1 rounded-full bg-hsecondary/10">
498
+ <span className="font-semibold text-[13px] text-hsecondary">
499
499
  Save ${formatPrice(variantComparePrice - variantPrice)}
500
500
  </span>
501
501
  </div>
@@ -510,28 +510,28 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
510
510
  {selectedVariant.inventoryStatus === ProductVariantInventoryStatusEnum.OUTOFSTOCK ? (
511
511
  <>
512
512
  <div className="size-3 rounded-full bg-red-500" />
513
- <span className="font-['Poppins',sans-serif] text-[13px] text-red-600 font-medium">
513
+ <span className="text-[13px] text-red-600 font-medium">
514
514
  Out of Stock
515
515
  </span>
516
516
  </>
517
517
  ) : selectedVariant.inventoryStatus === ProductVariantInventoryStatusEnum.LOWSTOCK || selectedVariant.inventoryCount <= 10 ? (
518
518
  <>
519
519
  <div className="size-3 rounded-full bg-hprimary animate-pulse" />
520
- <span className="font-['Poppins',sans-serif] text-[13px] text-hprimary font-medium">
520
+ <span className="text-[13px] text-hprimary font-medium">
521
521
  Only {selectedVariant.inventoryCount} left in stock - Order soon!
522
522
  </span>
523
523
  </>
524
524
  ) : (
525
525
  <>
526
526
  <div className="size-3 rounded-full bg-green-500" />
527
- <span className="font-['Poppins',sans-serif] text-[13px] text-green-600 font-medium">
527
+ <span className="text-[13px] text-green-600 font-medium">
528
528
  In Stock
529
529
  </span>
530
530
  </>
531
531
  )}
532
532
 
533
533
  </div>
534
- <p className="font-['Poppins',sans-serif] text-[12px] text-hmuted">
534
+ <p className="text-[12px] text-hmuted">
535
535
  SKU: {selectedVariant?.sku || product?.sku}
536
536
  </p>
537
537
  </div>
@@ -540,7 +540,7 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
540
540
  {/* Description */}
541
541
  {product.description && (
542
542
  <div
543
- className="font-['Poppins',sans-serif] text-[14px] text-hmuted leading-[1.7] mb-8 max-w-full overflow-hidden break-words"
543
+ className="text-[14px] text-hmuted leading-[1.7] mb-8 max-w-full overflow-hidden break-words"
544
544
  dangerouslySetInnerHTML={{ __html: product.description }}
545
545
  />
546
546
  )}
@@ -548,7 +548,7 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
548
548
  {/* Variant Selector with Images */}
549
549
  {product?.variants && product.variants.length > 0 && (
550
550
  <div className="mb-6">
551
- <h3 className="font-['Poppins',sans-serif] font-semibold text-[14px] text-hsecondary mb-3">
551
+ <h3 className="font-semibold text-[14px] text-hsecondary mb-3">
552
552
  Select Variant
553
553
  </h3>
554
554
  <div className="flex flex-wrap gap-3">
@@ -598,7 +598,7 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
598
598
 
599
599
  {/* Quantity Selector */}
600
600
  <div className="mb-8">
601
- <h3 className="font-['Poppins',sans-serif] font-semibold text-[14px] text-hsecondary mb-3">
601
+ <h3 className="font-semibold text-[14px] text-hsecondary mb-3">
602
602
  Quantity
603
603
  </h3>
604
604
  <div className="flex items-center gap-3">
@@ -608,18 +608,18 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
608
608
  type="button"
609
609
  onClick={() => setQuantity((current) => Math.max(1, current - 1))}
610
610
 
611
- className="font-['Poppins',sans-serif] font-bold text-[18px] text-hsecondary hover:text-hprimary transition-colors"
611
+ className="font-bold text-[18px] text-hsecondary hover:text-hprimary transition-colors"
612
612
  aria-label="Increase quantity"
613
613
  >
614
614
  -
615
615
  </button>
616
- <span className="font-['Poppins',sans-serif] font-semibold text-[16px] text-hsecondary min-w-[30px] text-center">
616
+ <span className="font-semibold text-[16px] text-hsecondary min-w-[30px] text-center">
617
617
  {quantity}
618
618
  </span>
619
619
  <button
620
620
  onClick={() => setQuantity(Math.min(selectedVariant?.inventoryCount || product.inventoryCount || 999, quantity + 1))}
621
621
  disabled={quantity >= (selectedVariant?.inventoryCount || product.inventoryCount || 0)}
622
- className="font-['Poppins',sans-serif] font-bold text-[18px] text-hsecondary hover:text-hprimary transition-colors disabled:opacity-50"
622
+ className="font-bold text-[18px] text-hsecondary hover:text-hprimary transition-colors disabled:opacity-50"
623
623
  >
624
624
  +
625
625
  </button>
@@ -635,7 +635,7 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
635
635
  {/* Action Buttons */}
636
636
  <div className="flex flex-col sm:flex-row gap-3 mb-8">
637
637
  <button
638
- className="flex-1 font-['Poppins',sans-serif] font-medium text-[14px] px-8 py-4 rounded-full transition-all duration-300 flex items-center justify-center gap-3 bg-[#E67E50] text-white hover:bg-[#d66f45] hover:shadow-lg disabled:opacity-50 disabled:cursor-not-allowed"
638
+ className="flex-1 font-medium text-[14px] px-8 py-4 rounded-full transition-all duration-300 flex items-center justify-center gap-3 bg-hsecondary text-white hover:bg-hsecondary/80 hover:shadow-lg disabled:opacity-50 disabled:cursor-not-allowed"
639
639
  onClick={handleAddToCart}
640
640
  disabled={!selectedVariant || selectedVariant.inventoryStatus === ProductVariantInventoryStatusEnum.OUTOFSTOCK || isAddingToCart}
641
641
  >
@@ -675,10 +675,10 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
675
675
  <Truck className="size-5 text-hprimary" />
676
676
  </div>
677
677
  <div>
678
- <p className="font-['Poppins',sans-serif] font-semibold text-[12px] text-hsecondary mb-1">
678
+ <p className="font-semibold text-[12px] text-hsecondary mb-1">
679
679
  Free Shipping
680
680
  </p>
681
- <p className="font-['Poppins',sans-serif] text-[11px] text-hmuted">
681
+ <p className="text-[11px] text-hmuted">
682
682
  On all orders
683
683
  </p>
684
684
  </div>
@@ -688,10 +688,10 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
688
688
  <RotateCcw className="size-5 text-hprimary" />
689
689
  </div>
690
690
  <div>
691
- <p className="font-['Poppins',sans-serif] font-semibold text-[12px] text-hsecondary mb-1">
691
+ <p className="font-semibold text-[12px] text-hsecondary mb-1">
692
692
  Easy Returns
693
693
  </p>
694
- <p className="font-['Poppins',sans-serif] text-[11px] text-hmuted">
694
+ <p className="text-[11px] text-hmuted">
695
695
  30-day return policy
696
696
  </p>
697
697
  </div>
@@ -701,10 +701,10 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
701
701
  <Shield className="size-5 text-hprimary" />
702
702
  </div>
703
703
  <div>
704
- <p className="font-['Poppins',sans-serif] font-semibold text-[12px] text-hsecondary mb-1">
704
+ <p className="font-semibold text-[12px] text-hsecondary mb-1">
705
705
  Secure Checkout
706
706
  </p>
707
- <p className="font-['Poppins',sans-serif] text-[11px] text-hmuted">
707
+ <p className="text-[11px] text-hmuted">
708
708
  Safe & protected
709
709
  </p>
710
710
  </div>
@@ -714,10 +714,10 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
714
714
  <Package className="size-5 text-hprimary" />
715
715
  </div>
716
716
  <div>
717
- <p className="font-['Poppins',sans-serif] font-semibold text-[12px] text-hsecondary mb-1">
717
+ <p className="font-semibold text-[12px] text-hsecondary mb-1">
718
718
  Quality Guaranteed
719
719
  </p>
720
- <p className="font-['Poppins',sans-serif] text-[11px] text-hmuted">
720
+ <p className="text-[11px] text-hmuted">
721
721
  Premium materials
722
722
  </p>
723
723
  </div>
@@ -734,7 +734,7 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
734
734
  <button
735
735
  key={tab}
736
736
  onClick={() => setActiveTab(tab)}
737
- className={`font-['Poppins',sans-serif] font-medium text-[14px] px-6 py-4 transition-all ${activeTab === tab
737
+ className={`font-medium text-[14px] px-6 py-4 transition-all ${activeTab === tab
738
738
  ? 'text-hprimary border-b-2 border-hprimary -mb-0.5'
739
739
  : 'text-hmuted hover:text-hprimary'
740
740
  }`}
@@ -747,29 +747,29 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
747
747
  <div className="bg-white rounded-[24px] p-8 border-2 border-gray-100">
748
748
  {activeTab === 'description' && (
749
749
  <div>
750
- <h3 className="font-['Poppins',sans-serif] font-semibold text-hsecondary mb-4">
750
+ <h3 className="font-semibold text-hsecondary mb-4">
751
751
  Product Description
752
752
  </h3>
753
753
  <div
754
- className="font-['Poppins',sans-serif] text-[14px] text-hmuted leading-[1.8] mb-4 max-w-full overflow-hidden break-words"
754
+ className="text-[14px] text-hmuted leading-[1.8] mb-4 max-w-full overflow-hidden break-words"
755
755
  dangerouslySetInnerHTML={{ __html: product.description }}
756
756
  />
757
757
 
758
758
  <div className="mt-6">
759
- <h4 className="font-['Poppins',sans-serif] font-semibold text-[13px] text-hsecondary mb-3">
759
+ <h4 className="font-semibold text-[13px] text-hsecondary mb-3">
760
760
  Last updated:
761
761
  </h4>
762
- <p className="font-['Poppins',sans-serif] text-[14px] text-hmuted">
762
+ <p className="text-[14px] text-hmuted">
763
763
  {lastUpdatedLabel}
764
764
  </p>
765
765
  </div>
766
766
 
767
767
  {/* shipped from */}
768
768
  <div className="mt-6">
769
- <h4 className="font-['Poppins',sans-serif] font-semibold text-[13px] text-hsecondary mb-3">
769
+ <h4 className="font-semibold text-[13px] text-hsecondary mb-3">
770
770
  Shipped from:
771
771
  </h4>
772
- <p className="font-['Poppins',sans-serif] text-[14px] text-hmuted">
772
+ <p className="text-[14px] text-hmuted">
773
773
  Local pharmacy distribution center
774
774
  </p>
775
775
  </div>
@@ -786,7 +786,7 @@ export function ProductDetailScreen({ productId }: ProductDetailScreenProps) {
786
786
  {/* Related Products */}
787
787
  {relatedProducts.length > 0 && (
788
788
  <div>
789
- <h2 className="font-['Poppins',sans-serif] font-semibold text-hsecondary mb-8 text-2xl">
789
+ <h2 className="font-semibold text-hsecondary mb-8 text-2xl">
790
790
  You May Also Like
791
791
  </h2>
792
792
  <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
@@ -112,34 +112,30 @@ export default function SearchPage() {
112
112
  return;
113
113
  }
114
114
 
115
+ // Require at least 2 characters for search
116
+ if (sanitizedQuery.length < 2) {
117
+ setProducts([]);
118
+ setIsLoading(false);
119
+ setHasSearched(false);
120
+ return;
121
+ }
122
+
115
123
  try {
116
124
  setIsLoading(true);
117
125
  const api = new ProductsApi(AXIOS_CONFIG);
118
126
 
119
- // Search for products using getAllProducts
120
- let response = await api.getAllProducts(
121
- sanitizedQuery, // searchTerm
122
- undefined, // maxPrice
123
- undefined, // minPrice
124
- undefined, // brandFilter
125
- undefined, // availability
126
- 'relevance', // sort
127
- undefined, // subCategoryId
128
- undefined, // categoryId
129
- true, // isActive
130
- 20, // limit
131
- 1 // page
132
- );
133
-
134
- console.log('Search API Response:', {
127
+ // Use AI-powered smart search for typo tolerance and semantic matching
128
+ const response = await api.smartSearch(sanitizedQuery, 20);
129
+
130
+ console.log('Smart Search API Response:', {
135
131
  query: sanitizedQuery,
136
132
  status: response.status,
137
- dataLength: response.data?.data?.length,
138
- totalItems: response.data?.totalItems
133
+ productsCount: response.data?.products?.length,
134
+ scores: response.data?.scores
139
135
  });
140
136
 
141
- if (response.data?.data) {
142
- const transformedProducts = response.data.data.map((item: Product) => ({
137
+ if (response.data?.products) {
138
+ const transformedProducts = response.data.products.map((item: Product) => ({
143
139
  ...item,
144
140
  id: item._id || '',
145
141
  }));
@@ -155,7 +151,7 @@ export default function SearchPage() {
155
151
  }
156
152
  setHasSearched(true);
157
153
  } catch (error) {
158
- console.error('Error fetching search results:', error);
154
+ console.error('Error fetching smart search results:', error);
159
155
  if (error instanceof Error) {
160
156
  console.error('Error details:', error.message);
161
157
  }
@@ -151,68 +151,6 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
151
151
  [categories]
152
152
  );
153
153
 
154
- const productInsights = useMemo(() => {
155
- if (!products.length) {
156
- return { newArrivals: 0, inStockCount: 0 };
157
- }
158
-
159
- const monthAgo = Date.now() - 30 * 24 * 60 * 60 * 1000;
160
- let newArrivals = 0;
161
- let inStockCount = 0;
162
-
163
- products.forEach((product) => {
164
- if (product.summary?.totalInventory > 0) inStockCount += 1;
165
- if (new Date(product.createdAt).getTime() >= monthAgo) newArrivals += 1;
166
- });
167
-
168
- return { newArrivals, inStockCount };
169
- }, [products]);
170
- const insightCards = useMemo(
171
- () => [
172
- {
173
- id: 'new',
174
- label: 'New arrivals',
175
- value: productInsights.newArrivals
176
- ? productInsights.newArrivals.toLocaleString()
177
- : isLoading
178
- ? '...'
179
- : '0',
180
- helper: filters.newArrivals ? 'Filter active: showing last 30 days' : 'Click to show last 30 days',
181
- icon: Sparkles,
182
- },
183
- {
184
- id: 'stock',
185
- label: 'Available now',
186
- value: productInsights.inStockCount
187
- ? productInsights.inStockCount.toLocaleString()
188
- : isLoading
189
- ? '...'
190
- : '0',
191
- helper: 'Ready to ship today',
192
- icon: ShieldCheck,
193
- },
194
- {
195
- id: 'catalogue',
196
- label: 'Total products',
197
- value:
198
- pagination.total || products.length
199
- ? (pagination.total || products.length).toLocaleString()
200
- : isLoading
201
- ? '...'
202
- : '0',
203
- helper: 'Across all categories',
204
- icon: TrendingUp,
205
- },
206
- ],
207
- [
208
- isLoading,
209
- pagination.total,
210
- productInsights.inStockCount,
211
- productInsights.newArrivals,
212
- products.length,
213
- filters.newArrivals,
214
- ]
215
- );
216
154
 
217
155
  const filteredProducts = useMemo(() => {
218
156
  if (isLoading) return products;
@@ -664,12 +602,12 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
664
602
 
665
603
  <div className={`lg:w-72 ${showFilters ? 'block rounded-full' : 'hidden lg:block'}`}>
666
604
  <div className="bg-white rounded-[24px] p-6 border-2 border-gray-100 sticky top-24">
667
- <h3 className="font-['Poppins',sans-serif] font-semibold text-hsecondary">
605
+ <h3 className="font-semibold text-hsecondary">
668
606
  Filters
669
607
  </h3>
670
608
  {/* Search */}
671
609
  <div className="mb-6">
672
- <label className="font-['Poppins',sans-serif] text-[12px] text-hmuted mb-2 block font-medium">
610
+ <label className="text-[12px] text-hmuted mb-2 block font-medium">
673
611
  Search Products
674
612
  </label>
675
613
  <div className="relative">
@@ -679,7 +617,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
679
617
  placeholder="Search..."
680
618
  value={searchQuery}
681
619
  onChange={handleInputChange}
682
- className="w-full pl-10 pr-4 py-2.5 rounded-xl border-2 border-gray-200 focus:border-hprimary focus:outline-hidden font-['Poppins',sans-serif] text-[13px] text-hsecondary"
620
+ className="w-full pl-10 pr-4 py-2.5 rounded-xl border-2 border-gray-200 focus:border-hprimary focus:outline-hidden text-[13px] text-hsecondary"
683
621
  />
684
622
  </div>
685
623
  </div>
@@ -690,7 +628,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
690
628
  onClick={() => toggleFilterSection('category')}
691
629
  className="w-full flex items-center justify-between mb-3"
692
630
  >
693
- <label className="font-['Poppins',sans-serif] text-[12px] text-hmuted font-medium cursor-pointer">
631
+ <label className="text-[12px] text-hmuted font-medium cursor-pointer">
694
632
  Category
695
633
  </label>
696
634
  {expandedFilterSections.category ? (
@@ -713,7 +651,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
713
651
  if (!isExpanded) toggleCategoryExpand(categoryId);
714
652
  handleCategoryChange(categoryId);
715
653
  }}
716
- className={`w-full text-left px-4 py-3 rounded-xl font-['Poppins',sans-serif] text-[13px] transition-all flex items-center gap-3 ${isCategoryActive
654
+ className={`w-full text-left px-4 py-3 rounded-xl text-[13px] transition-all flex items-center gap-3 ${isCategoryActive
717
655
  ? 'bg-hprimary text-white shadow-lg'
718
656
  : 'text-hsecondary hover:bg-gray-50 border-2 border-gray-100'
719
657
  }`}
@@ -733,7 +671,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
733
671
  onClick={() => toggleFilterSection('brand')}
734
672
  className="w-full flex items-center justify-between mb-3"
735
673
  >
736
- <label className="font-['Poppins',sans-serif] text-[12px] text-hmuted font-medium cursor-pointer">
674
+ <label className="text-[12px] text-hmuted font-medium cursor-pointer">
737
675
  Brand
738
676
  </label>
739
677
  <ChevronDown className={`size-4 text-hmuted transition-transform ${expandedFilterSections.brand ? 'rotate-180' : ''}`} />
@@ -748,7 +686,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
748
686
  <button
749
687
  key={brand}
750
688
  onClick={() => handleBrandChange(brand)}
751
- className={`w-full text-left px-4 py-3 rounded-xl font-['Poppins',sans-serif] text-[13px] transition-all ${isSelected
689
+ className={`w-full text-left px-4 py-3 rounded-xl text-[13px] transition-all ${isSelected
752
690
  ? 'bg-hprimary text-white shadow-lg'
753
691
  : 'text-hsecondary hover:bg-gray-50 border-2 border-gray-100'
754
692
  }`}
@@ -769,7 +707,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
769
707
  onClick={() => toggleFilterSection('availability')}
770
708
  className="w-full flex items-center justify-between mb-3"
771
709
  >
772
- <label className="font-['Poppins',sans-serif] text-[12px] text-hmuted font-medium cursor-pointer">
710
+ <label className="text-[12px] text-hmuted font-medium cursor-pointer">
773
711
  Availability
774
712
  </label>
775
713
  <ChevronDown className={`size-4 text-hmuted transition-transform ${expandedFilterSections.availability ? 'rotate-180' : ''}`} />
@@ -778,7 +716,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
778
716
  <div className="space-y-2">
779
717
  <button
780
718
  onClick={handleToggleStock}
781
- className={`w-full flex items-center justify-between px-4 py-3 rounded-xl font-['Poppins',sans-serif] text-[13px] transition-all border-2 ${inStockOnly
719
+ className={`w-full flex items-center justify-between px-4 py-3 rounded-xl text-[13px] transition-all border-2 ${inStockOnly
782
720
  ? 'bg-hprimary text-white shadow-lg'
783
721
  : 'text-hsecondary hover:bg-gray-50 border-2 border-gray-100'
784
722
  }`}
@@ -794,7 +732,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
794
732
  onClick={() => toggleFilterSection('price')}
795
733
  className="w-full flex items-center justify-between mb-3"
796
734
  >
797
- <label className="font-['Poppins',sans-serif] text-[12px] text-hmuted font-medium cursor-pointer">
735
+ <label className="text-[12px] text-hmuted font-medium cursor-pointer">
798
736
  Price Range
799
737
  </label>
800
738
  <ChevronDown className={`size-4 text-hmuted transition-transform ${expandedFilterSections.price ? 'rotate-180' : ''}`} />
@@ -809,7 +747,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
809
747
  type="button"
810
748
  key={range.value}
811
749
  onClick={() => handlePriceRangeSelect(range.value)}
812
- className={`w-full flex items-center justify-between px-4 py-3 rounded-xl font-['Poppins',sans-serif] text-[13px] transition-all border-2 ${isActive
750
+ className={`w-full flex items-center justify-between px-4 py-3 rounded-xl text-[13px] transition-all border-2 ${isActive
813
751
  ? 'bg-hprimary text-white shadow-lg'
814
752
  : 'text-hsecondary hover:bg-gray-50 border-2 border-gray-100'
815
753
  }`}
@@ -828,7 +766,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
828
766
  onChange={(event) =>
829
767
  setCustomPrice((current) => ({ ...current, min: event.target.value }))
830
768
  }
831
- className="w-1/2 px-4 py-2.5 rounded-xl border-2 border-gray-200 focus:border-hprimary focus:outline-hidden font-['Poppins',sans-serif] text-[13px] text-hsecondary"
769
+ className="w-1/2 px-4 py-2.5 rounded-xl border-2 border-gray-200 focus:border-hprimary focus:outline-hidden text-[13px] text-hsecondary"
832
770
  />
833
771
  <Input
834
772
  type="number"
@@ -838,7 +776,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
838
776
  onChange={(event) =>
839
777
  setCustomPrice((current) => ({ ...current, max: event.target.value }))
840
778
  }
841
- className="w-1/2 px-4 py-2.5 rounded-xl border-2 border-gray-200 focus:border-hprimary focus:outline-hidden font-['Poppins',sans-serif] text-[13px] text-hsecondary"
779
+ className="w-1/2 px-4 py-2.5 rounded-xl border-2 border-gray-200 focus:border-hprimary focus:outline-hidden text-[13px] text-hsecondary"
842
780
  />
843
781
  </div>
844
782
  <button
@@ -926,9 +864,9 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
926
864
  </section>
927
865
 
928
866
  {/* Shop by Category Section */}
929
- <section className="py-8 bg-white">
867
+ <section className="py-8 bg-white/50">
930
868
  <div className="container mx-auto px-4">
931
- <h2 className="text-2xl md:text-3xl font-['Poppins',sans-serif] font-semibold text-hsecondary mb-6">
869
+ <h2 className="text-2xl md:text-3xl font-semibold text-hsecondary mb-6">
932
870
  Shop by Category
933
871
  </h2>
934
872
  <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4">
@@ -948,11 +886,11 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
948
886
  <Package className={`size-6 ${!categoryFilter ? 'text-white' : 'text-hprimary'
949
887
  }`} />
950
888
  </div>
951
- <h3 className={`font-['Poppins',sans-serif] font-semibold text-[14px] mb-1.5 ${!categoryFilter ? 'text-white' : 'text-hsecondary'
889
+ <h3 className={`font-semibold text-[14px] mb-1.5 ${!categoryFilter ? 'text-white' : 'text-hsecondary'
952
890
  }`}>
953
891
  All Products
954
892
  </h3>
955
- <p className={`font-['Poppins',sans-serif] text-[11px] ${!categoryFilter ? 'text-white/80' : 'text-hmuted'
893
+ <p className={`text-[11px] ${!categoryFilter ? 'text-white/80' : 'text-hmuted'
956
894
  }`}>
957
895
  Browse Everything
958
896
  </p>
@@ -983,11 +921,11 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
983
921
  <Icon className={`size-6 ${isSelected ? 'text-white' : 'text-hprimary'
984
922
  }`} />
985
923
  </div>
986
- <h3 className={`font-['Poppins',sans-serif] font-semibold text-[14px] mb-1.5 ${isSelected ? 'text-white' : 'text-hsecondary'
924
+ <h3 className={`font-semibold text-[14px] mb-1.5 ${isSelected ? 'text-white' : 'text-hsecondary'
987
925
  }`}>
988
926
  {category.name}
989
927
  </h3>
990
- <p className={`font-['Poppins',sans-serif] text-[11px] ${isSelected ? 'text-white/80' : 'text-hmuted'
928
+ <p className={`text-[11px] ${isSelected ? 'text-white/80' : 'text-hmuted'
991
929
  }`}>
992
930
  {category.description}
993
931
  </p>
@@ -1177,7 +1115,7 @@ export function ShopScreen({ initialFilters = {}, categoryName }: ShopScreenProp
1177
1115
  event.stopPropagation();
1178
1116
  router.push(buildPath(`/products/${product._id}`));
1179
1117
  }}
1180
- className="w-full font-['Poppins',sans-serif] font-medium text-sm px-3 py-2 rounded-xl bg-hsecondary text-white hover:opacity-80 hover:shadow-lg transition-all duration-300 flex items-center justify-center gap-1.5 disabled:opacity-50 disabled:cursor-not-allowed"
1118
+ className="w-full font-medium text-sm px-3 py-2 rounded-xl bg-hsecondary text-white hover:opacity-80 hover:shadow-lg transition-all duration-300 flex items-center justify-center gap-1.5 disabled:opacity-50 disabled:cursor-not-allowed"
1181
1119
  >
1182
1120
  View product
1183
1121
  </button>