SwiperGroup.tsx 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. "use client";
  2. import Box from "@/components/Box";
  3. import { FC, PropsWithChildren, ReactNode, useRef } from "react";
  4. import { Swiper, SwiperClass, SwiperSlide } from "swiper/react";
  5. import { Category, GameListRep } from "@/api/home";
  6. import { CardProps } from "@/components/Card/Card";
  7. import GroupCard, { GroupProps } from "@/components/Card/GroupCard";
  8. import clsx from "clsx";
  9. import { useTranslations } from "next-intl";
  10. import styles from "./style.module.scss";
  11. type TodoHandler = (item: Category) => void;
  12. interface SwiperGroupProps extends GroupProps, CardProps {
  13. group: Category;
  14. page?: number;
  15. // style
  16. bg?: boolean;
  17. visibleTitle?: boolean;
  18. // todos
  19. visibleTodos?: boolean;
  20. todoHandler?: TodoHandler;
  21. // icon
  22. offsetX?: number;
  23. offsetY?: number;
  24. // SwiperSlide
  25. slideRender?: (data: GameListRep[]) => ReactNode;
  26. }
  27. const HomeSwiper: FC<PropsWithChildren<SwiperGroupProps>> = (props) => {
  28. const {
  29. group,
  30. page = 3,
  31. todoHandler,
  32. bg = true,
  33. visibleTitle = true,
  34. visibleTodos = true,
  35. slideRender,
  36. ...other
  37. } = props;
  38. const t = useTranslations("HomePage");
  39. const swiperRef = useRef<SwiperClass | null>(null);
  40. const bodyClass = clsx(
  41. styles.gameContainer,
  42. // "mb-[0.11rem]",
  43. "pt-[0.08rem]"
  44. // "pb-[0.11rem]",
  45. );
  46. if (!group.game_list) return;
  47. const lineNum = page * group.line_num;
  48. const gameList = group.game_list.slice(0, group.line_config_amount);
  49. const swiperData = Array(gameList.length ? Math.ceil(gameList.length / lineNum) : 0)
  50. .fill(0)
  51. .map((_, index) => {
  52. const showData = gameList
  53. .slice(index * lineNum, index * lineNum + lineNum)
  54. .map((subItem) => ({ ...subItem, category_name: group.category_name }));
  55. return {
  56. key: index,
  57. data: showData,
  58. };
  59. });
  60. console.log(swiperData);
  61. const prev = () => {
  62. swiperRef.current!.slidePrev();
  63. };
  64. const next = () => {
  65. swiperRef.current!.slideNext();
  66. };
  67. const iconClass = clsx(styles.mainLeftIcon, "pro-iconfont", `pro-${group.icon}`);
  68. return (
  69. <div>
  70. {visibleTitle && (
  71. <Box none>
  72. <div className={styles.mainTitle}>
  73. {!group.image && (
  74. <div className={styles.mainLeft}>
  75. <div className={iconClass}></div>
  76. <div className={styles.marginLeftTitle}>{group.category_name}</div>
  77. {/* <div className={styles.marginLeftTag}> {t("gameTag")}</div> */}
  78. </div>
  79. )}
  80. {group.image && (
  81. <div className={clsx(styles.mainLeft, "flex items-center")}>
  82. <img className="h-[.3rem] w-[.3rem]" src={group.image} alt="" />
  83. <div className={styles.marginLeftTitle}>{group.category_name}</div>
  84. {/* <div className={styles.marginLeftTag}> {t("gameTag")}</div> */}
  85. </div>
  86. )}
  87. {/* <img
  88. src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAATcAAAA5CAYAAABTX2z2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAF6GlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNi4wLWMwMDIgNzkuMTY0NDg4LCAyMDIwLzA3LzEwLTIyOjA2OjUzICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIyLjAgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0ZT0iMjAyMy0wMy0wOVQxNTozNDowMSswODowMCIgeG1wOk1vZGlmeURhdGU9IjIwMjMtMDMtMDlUMTU6MzQ6MjcrMDg6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMjMtMDMtMDlUMTU6MzQ6MjcrMDg6MDAiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6YmIzNWRiOGYtMjE1Yi04NDRiLTg0NDAtNjFiYjI1YWU0ZjIyIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjQ0MzZBMDQ2QkU0QzExRUQ4MURCRDI3MkM0QzA2QzVGIiB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6NDQzNkEwNDZCRTRDMTFFRDgxREJEMjcyQzRDMDZDNUYiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0ic1JHQiBJRUM2MTk2Ni0yLjEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0NDM2QTA0M0JFNEMxMUVEODFEQkQyNzJDNEMwNkM1RiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0NDM2QTA0NEJFNEMxMUVEODFEQkQyNzJDNEMwNkM1RiIvPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDpiYjM1ZGI4Zi0yMTViLTg0NGItODQ0MC02MWJiMjVhZTRmMjIiIHN0RXZ0OndoZW49IjIwMjMtMDMtMDlUMTU6MzQ6MjcrMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMi4wIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5BhExDAAADo0lEQVR4nO3du4tcVQDH8c9KiCJpfBBhxkLUyge2Qv4Ewc42ghZifMT4RGPnAzXRRGMaMWBrI4iVCCqKCBpERXw/kDhgLMQ1nSGuxZlBI7t377z2ztz7+8AwU5wz91Rfzn3s7Eqv1/sdZ7CKP3By+DqBH/AtvsSf5mwwGMz7EBHREdtwwfDzxRXj1vAdjuM9vKNELyJiIa30er21Cef+iNfxGj5QAji17N4iYhbOmWLu5diH95Vd3X7snMWiIiKmNU3c/usKPI6f8TKunPSL+v3+jJYUEV02q7iNnIdb8RWO4dJJviSBi4hpzTpuI9twixK5/Th3TseJiFjXvOI2skM5Xf0E148zMbu3iJjGvOM2cpVyR/UJZVdXSwIXEZPaqriNjvUI3jXhtbiIiLq2Mm4ju5SHgXfVGZzdW0RMoom4wSV4G7sbOn5EtFxTcYPteAUPbzYwu7eIGFeTcYMVPIkDw88bSuAiYhxNx23kfhyxSeAiIupalLjBHTiqInDZvUVEXYsUN7hdAhcRM7BocaME7kUJXERMYRHjBnskcBExhUWNGyVwlTcZEriI2Mgix41ykyGBi4ixLXrcKIF7QQIXEWNYhrjBnXheAhcRNS1L3OAuCVxE1LRMcaME7rAELiI2sWxxg7txSAIXERWWMW6wVwIXERWWNW6UwD0ngYuIdSxz3OAeJXAbSuAiumnZ40YJ3KGqAQlcRPe0IW5kBxcR/9OWuME+CVxEDLUpbiRwETHUtrhRAvds1YAELqL92hg3uBcHqwYkcBHt1ta4wX0SuIjOanPcKIE7UDUggYtop7bHjfJvA5+pGpDARbRPF+IGD0jgIjqlK3GjBO7pqgEJXER7dClu8CCeqhqQwEW0Q9fiBg9J4CJar4txowTuoPxcUkRrrfR6vbWmF9GgY7gNZ6oGDQaDrVlNRMxM1+MGr2I3/tpsYCIXsTwSt+JN3IRTdQYnchGLL3H71xe4ET/VnZDIRSyurt5QWM81+Bg31J3Q7/dz4yFiQSVuZ7sIbyh/zbC97qRELmLx5LR0Y5/h5uH7WHK6GtG87Nw2dh2OK78qsmOcidnJRTQvO7d6fsNjeEmNR0Ymkd1exGxl51bPThzBN9iD85tdTkRsJnEbz2U4ihM4jKubXExEbCxxm8yF2Ks8G/cpHsW1TS4oIs6Wa26z9Svewof4CJ/jdJ2JueYWMVuJ23ydxvf4evg+wC84idXh6xT+HgwGq00tMqKN/gHg555imkrLwAAAAABJRU5ErkJggg=="
  89. alt=""
  90. /> */}
  91. <div className={styles.mainRight}>
  92. {visibleTodos && (
  93. <div onClick={() => todoHandler && todoHandler(group)}>
  94. {/* Todos */}
  95. <div className="text-[#d76bff]">Todo</div>
  96. <div className={styles.marginRightCount}>
  97. <span>{group.to_tal}</span>
  98. </div>
  99. </div>
  100. )}
  101. {/* <div onClick={prev}>
  102. <span className="iconfont icon-xiangzuo1"></span>
  103. </div>
  104. <div onClick={next}>
  105. <span className="iconfont icon-xiangyou1"></span>
  106. </div> */}
  107. </div>
  108. </div>
  109. </Box>
  110. )}
  111. <Box none className={bodyClass}>
  112. <Box>
  113. <Swiper
  114. spaceBetween={10}
  115. slidesPerView={1}
  116. onSwiper={(swiper) => {
  117. swiperRef.current = swiper;
  118. }}
  119. loop
  120. >
  121. {swiperData?.map((data, index) => {
  122. return (
  123. <SwiperSlide key={data.key}>
  124. {slideRender ? (
  125. slideRender(data.data)
  126. ) : (
  127. <GroupCard
  128. data={data.data}
  129. {...other}
  130. groupType={1}
  131. ></GroupCard>
  132. )}
  133. </SwiperSlide>
  134. );
  135. })}
  136. </Swiper>
  137. </Box>
  138. </Box>
  139. </div>
  140. );
  141. };
  142. export default HomeSwiper;