All files / src/components/features/shop/ShopDetails/RecentlyViewd index.tsx

14.81% Statements 16/108
100% Branches 0/0
0% Functions 0/1
14.81% Lines 16/108

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 1091x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x                                                                                                                                                                                         1x 1x  
"use client";
import React from "react";
import { ProductCard } from "@/components/features/product";
import { Swiper, SwiperSlide } from "swiper/react";
import { useCallback, useRef } from "react";
import type { Swiper as SwiperClass } from "swiper";
import { Icon } from "@/components/ui/icons";
import { useRandomProducts } from "@/hooks/useProducts";
import { ProductGridSkeleton } from "@/components/ui/Skeleton";
import ErrorMessage from "@/components/ui/ErrorMessage";
import "swiper/css/navigation";
import "swiper/css";
 
const RecentlyViewdItems = () => {
  const sliderRef = useRef<SwiperClass | null>(null);
  const { products, loading, error, refetch } = useRandomProducts(8);

  const handlePrev = useCallback(() => {
    if (!sliderRef.current) return;
    sliderRef.current.slidePrev();
  }, []);

  const handleNext = useCallback(() => {
    if (!sliderRef.current) return;
    sliderRef.current.slideNext();
  }, []);

  return (
    <section className="overflow-hidden pt-17.5">
      <div className="max-w-[1170px] w-full mx-auto px-4 sm:px-8 xl:px-0 pb-15 border-b border-gray-3">
        <div className="swiper categories-carousel common-carousel">
          {/* <!-- section title --> */}
          <div className="mb-10 flex items-center justify-between">
            <div>
              <span className="flex items-center gap-2.5 font-medium text-dark mb-1.5">
                <Icon name="tag" className="text-blue" size={17} />
                Categories
              </span>
              <h2 className="font-semibold text-xl xl:text-heading-5 text-dark">
                Browse by Category
              </h2>
            </div>

            <div className="flex items-center gap-3">
              <button onClick={handlePrev} className="swiper-button-prev">
                <Icon name="chevron-left" className="fill-current" size={24} />
              </button>

              <button onClick={handleNext} className="swiper-button-next">
                <Icon name="chevron-right" className="fill-current" size={24} />
              </button>
            </div>
          </div>

          {/* Carousel container with fixed height to prevent CLS */}
          <div className="min-h-[420px]">
            {/* Error State */}
            {error && (
              <div className="mb-6">
                <ErrorMessage
                  title="Failed to Load Products"
                  message={error.message}
                  onRetry={refetch}
                />
              </div>
            )}

            {/* Loading State */}
            {loading && <ProductGridSkeleton count={4} />}

            {/* Success State */}
            {!loading && !error && (
            <>
              {products.length === 0 ? (
                <div className="text-center py-10">
                  <p className="text-gray-500">No products available</p>
                </div>
              ) : (
                <Swiper
                  slidesPerView={4}
                  spaceBetween={20}
                  onSwiper={(swiper) => {
                    sliderRef.current = swiper;
                  }}
                  className="justify-between"
                  breakpoints={{
                    320: { slidesPerView: 1 },
                    640: { slidesPerView: 2 },
                    1024: { slidesPerView: 3 },
                    1280: { slidesPerView: 4 }}}
                >
                  {products.map((item, key) => (
                    <SwiperSlide key={key}>
                      <ProductCard product={item} variant="featured" />
                    </SwiperSlide>
                  ))}
                </Swiper>
              )}
            </>
          )}
          </div>
        </div>
      </div>
    </section>
  );
};
 
export default RecentlyViewdItems;