JinGangSwiper.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. "use client";
  2. import { useState } from "react";
  3. import { Swiper, SwiperSlide } from "swiper/react";
  4. import type { Swiper as SwiperType } from "swiper/types";
  5. import { Navigation } from "swiper/modules";
  6. import Image from "next/image";
  7. import type { HomeSectionImage } from "@/types/home/type";
  8. interface jinGangProps {
  9. jinGang: HomeSectionImage[];
  10. }
  11. // const MOCK_DATA = [
  12. // [
  13. // {
  14. // name: "Hd Lace Wig",
  15. // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095740_8181b0e039800e07.png",
  16. // },
  17. // {
  18. // name: "Ready To Go",
  19. // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095740_8181b0e039800e07.png",
  20. // },
  21. // {
  22. // name: "Colored Wig",
  23. // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095740_8181b0e039800e07.png",
  24. // },
  25. // {
  26. // name: "U&V Part Wig",
  27. // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095740_8181b0e039800e07.png",
  28. // },
  29. // {
  30. // name: "New Arrival",
  31. // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095740_8181b0e039800e07.png",
  32. // },
  33. // {
  34. // name: "360 Wig",
  35. // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095740_8181b0e039800e07.png",
  36. // },
  37. // ],
  38. // [
  39. // {
  40. // name: "13x4 Lace Wig",
  41. // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095800_8181b0e039800e07.png",
  42. // },
  43. // {
  44. // name: "Body Wave Wig",
  45. // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095800_8181b0e039800e07.png",
  46. // },
  47. // {
  48. // name: "Deep Wave Wig",
  49. // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095800_8181b0e039800e07.png",
  50. // },
  51. // {
  52. // name: "Straight Wig",
  53. // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095800_8181b0e039800e07.png",
  54. // },
  55. // {
  56. // name: "Curly Wig",
  57. // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095800_8181b0e039800e07.png",
  58. // },
  59. // {
  60. // name: "Bob Wig",
  61. // img: "https://cdn.asteriahair.com/uploads/202602/11/20260211095800_8181b0e039800e07.png",
  62. // },
  63. // ],
  64. // ];
  65. export default function JinGangSwiper({ jinGang }: jinGangProps) {
  66. const [activeIndex, setActiveIndex] = useState(0);
  67. const [swiperRef, setSwiperRef] = useState<SwiperType | null>(null);
  68. if (!jinGang || jinGang.length === 0) return null;
  69. // 4. 真实数据按每6个拆分一组,替换原来的模拟拆分逻辑
  70. const chunkSize = 6;
  71. const productBlocks: HomeSectionImage[][] = [];
  72. for (let i = 0; i < jinGang.length; i += chunkSize) {
  73. productBlocks.push(jinGang.slice(i, i + chunkSize));
  74. }
  75. const handleSlideChange = (swiper: any) => {
  76. setActiveIndex(swiper.activeIndex);
  77. };
  78. const handleIndicatorClick = (index: any) => {
  79. if (swiperRef) {
  80. swiperRef.slideTo(index);
  81. setActiveIndex(index);
  82. }
  83. };
  84. return (
  85. <div className="max-w-screen-md mx-auto p-4">
  86. <Swiper
  87. modules={[Navigation]}
  88. spaceBetween={10}
  89. slidesPerView={1}
  90. onSwiper={(swiper) => setSwiperRef(swiper)}
  91. onSlideChange={handleSlideChange}
  92. className="mb-6"
  93. >
  94. {productBlocks.map((block, blockIndex) => (
  95. <SwiperSlide key={blockIndex}>
  96. <div className="grid grid-cols-3 gap-2">
  97. {block.map((item, idx) => (
  98. <div
  99. key={`block1-${idx}`}
  100. className="relative w-full aspect-[3/4]"
  101. >
  102. <Image
  103. src={item.image}
  104. alt={item.title}
  105. fill
  106. className="object-cover rounded-md"
  107. />
  108. {/* <div className="absolute bottom-2 left-2 text-white text-sm font-medium bg-black/50 px-2 py-1 rounded">
  109. {item.name}
  110. </div> */}
  111. </div>
  112. ))}
  113. </div>
  114. </SwiperSlide>
  115. ))}
  116. </Swiper>
  117. {/* 底部指示器按钮:2个,激活态黑色,未激活灰色 */}
  118. <div className="flex justify-center gap-2">
  119. <button
  120. onClick={() => handleIndicatorClick(0)}
  121. className={`w-6 h-[5px] rounded-full opacity-100 ${
  122. activeIndex === 0 ? "bg-[#333]" : "bg-[#E5E5E5]"
  123. }`}
  124. aria-label="切换到第一块"
  125. />
  126. <button
  127. onClick={() => handleIndicatorClick(1)}
  128. className={`w-6 h-[5px] rounded-full opacity-100 ${
  129. activeIndex === 1 ? "bg-[#333]" : "bg-[#E5E5E5]"
  130. }`}
  131. aria-label="切换到第二块"
  132. />
  133. </div>
  134. </div>
  135. );
  136. }