| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- "use client";
- import { useState, useRef } from "react";
- import { Swiper, SwiperSlide } from "swiper/react";
- import type { Swiper as SwiperType } from "swiper/types";
- // import { Navigation } from "swiper/modules";
- import Image from "next/image";
- import Link from "next/link";
- import type { HomeSectionImage,HomeSection } from "@/types/home/type";
- interface jinGangSectionProps{
- jinGangSection:HomeSection |undefined;
- }
- // interface jinGangSection{
- // id: number;
- // type: string;
- // name: string;
- // sort_order: number;
- // images:HomeSectionImage[];
- // }
- // const MOCK_DATA = [
- // [
- // {
- // name: "Hd Lace Wig",
- // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095740_8181b0e039800e07.png",
- // },
- // {
- // name: "Ready To Go",
- // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095740_8181b0e039800e07.png",
- // },
- // {
- // name: "Colored Wig",
- // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095740_8181b0e039800e07.png",
- // },
- // {
- // name: "U&V Part Wig",
- // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095740_8181b0e039800e07.png",
- // },
- // {
- // name: "New Arrival",
- // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095740_8181b0e039800e07.png",
- // },
- // {
- // name: "360 Wig",
- // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095740_8181b0e039800e07.png",
- // },
- // ],
- // [
- // {
- // name: "13x4 Lace Wig",
- // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095800_8181b0e039800e07.png",
- // },
- // {
- // name: "Body Wave Wig",
- // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095800_8181b0e039800e07.png",
- // },
- // {
- // name: "Deep Wave Wig",
- // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095800_8181b0e039800e07.png",
- // },
- // {
- // name: "Straight Wig",
- // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095800_8181b0e039800e07.png",
- // },
- // {
- // name: "Curly Wig",
- // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095800_8181b0e039800e07.png",
- // },
- // {
- // name: "Bob Wig",
- // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095800_8181b0e039800e07.png",
- // },
- // ],
- // ];
- const SLIDES_PER_VIEW = 6.5;
- const SLIDES_PER_GROUP = 6;
- const SPACE_BETWEEN = 24;
- export default function JinGangSwiper({jinGangSection} :jinGangSectionProps ) {
- const jinGang: HomeSectionImage[] = jinGangSection?.images ?? [];
- const swiperRef = useRef<SwiperType | null>(null);
- const [activePage, setActivePage] = useState(0);
- const [isBeginning, setIsBeginning] = useState(true);
- const [isEnd, setIsEnd] = useState(jinGang.length <= SLIDES_PER_VIEW);
- const pageCount = Math.ceil(jinGang.length / SLIDES_PER_VIEW);
- const syncSwiperState = (swiper: SwiperType) => {
- const pageIndex = Math.min(swiper.snapIndex, Math.max(pageCount - 1, 0));
- setActivePage(pageIndex);
- setIsBeginning(swiper.isBeginning);
- setIsEnd(swiper.isEnd);
- };
- const handlePrev = () => {
- swiperRef.current?.slidePrev();
- };
- const handleNext = () => {
- swiperRef.current?.slideNext();
- };
- const handlePaginationClick = (pageIndex: number) => {
- const swiper = swiperRef.current;
- if (!swiper) return;
- swiper.slideTo(pageIndex * SLIDES_PER_GROUP);
- };
- return (
- <div className="relative w-full mt-6">
- {/* Swiper */}
- <div className="pl-12">
- <Swiper
- slidesPerView={SLIDES_PER_VIEW}
- slidesPerGroup={SLIDES_PER_GROUP}
- spaceBetween={SPACE_BETWEEN}
- speed={300}
- watchOverflow
- onSwiper={(swiper) => {
- swiperRef.current = swiper;
- syncSwiperState(swiper);
- }}
- onSlideChange={syncSwiperState}
- onReachBeginning={syncSwiperState}
- onReachEnd={syncSwiperState}
- onFromEdge={syncSwiperState}
- className="w-full"
- >
- {jinGang.map((item, index) => (
- <SwiperSlide key={`${item.title}-${index}`}>
- {item.link ? (
- <Link
- href={item.link}
- className="relative aspect-[3/4] w-full overflow-hidden rounded-md w-full"
- aria-label={item.title}
- >
- <Image
- src={item.image}
- alt={item.title}
- fill
- className="object-cover rounded-md"
- />
- </Link>
- ) : (
- <div className="relative aspect-[3/4] w-full overflow-hidden rounded-md w-full">
- <Image
- src={item.image}
- alt={item.title}
- fill
- className="object-cover rounded-md"
- />
- </div>
- )}
- </SwiperSlide>
- ))}
- </Swiper>
- </div>
- {!isBeginning && (
- <button
- type="button"
- aria-label="Previous"
- onClick={handlePrev}
- className="
- absolute
- left-18
- top-1/2
- z-10
- flex
- h-10
- w-10
- -translate-y-1/2
- items-center
- justify-center
- "
- >
- <svg
- xmlns="http://www.w3.org/2000/svg"
- width="40"
- height="40"
- viewBox="0 0 40 40"
- fill="none"
- className="rotate-180"
- >
- <circle cx="20" cy="20" r="20" fill="#000000" fillOpacity="0.5" />
- <path
- d="M17 26L23 20L17 14"
- stroke="rgba(255, 255, 255, 1)"
- strokeWidth="1.5"
- strokeLinejoin="round"
- strokeLinecap="square"
- />
- </svg>
- </button>
- )}
- {/* Next - 最后一页不显示 */}
- {!isEnd && (
- <button
- type="button"
- aria-label="Next"
- onClick={handleNext}
- className="
- absolute
- right-6
- top-1/2
- z-10
- flex
- h-10
- w-10
- -translate-y-1/2
- items-center
- justify-center
- "
- >
- <svg
- xmlns="http://www.w3.org/2000/svg"
- width="40"
- height="40"
- viewBox="0 0 40 40"
- fill="none"
- >
- <circle cx="20" cy="20" r="20" fill="#000000" fillOpacity="0.5" />
- <path
- d="M17 26L23 20L17 14"
- stroke="rgba(255, 255, 255, 1)"
- strokeWidth="1.5"
- strokeLinejoin="round"
- strokeLinecap="square"
- />
- </svg>
- </button>
- )}
- {/* Pagination */}
- {pageCount > 1 && (
- <div
- className="
- mt-4
- flex
- items-center
- justify-center
- gap-2
- "
- >
- {Array.from({
- length: pageCount,
- }).map((_, index) => (
- <button
- key={index}
- type="button"
- aria-label={`Go to page ${index + 1}`}
- onClick={() => handlePaginationClick(index)}
- className={`
- h-2
- w-10
- rounded-full
- transition-all
- duration-300
- ${activePage === index ? "bg-black" : "bg-[#DBDBDB]!"}
- `}
- />
- ))}
- </div>
- )}
- </div>
- );
- }
|