accountSwiper.tsx 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. "use client";
  2. // import { Swiper, SwiperSlide } from 'swiper/react';
  3. import { OpenAddToCartModalButton } from "@/components/common/AddToCartModal/OpenAddToCartModalButton";
  4. import Image from 'next/image';
  5. interface ProductItem {
  6. id: number;
  7. sku: string;
  8. name: string;
  9. slug: string | null;
  10. type: string;
  11. price: number;
  12. min_price: number;
  13. special_price: number | null;
  14. image_url: string | null;
  15. is_new: boolean;
  16. is_featured: boolean;
  17. short_description: string;
  18. rating: number;
  19. review_count: number;
  20. }
  21. // import 'swiper/css';
  22. // 模拟商品数据(和图片内容匹配)
  23. const productList:ProductItem[] = [
  24. {
  25. "id": 3792,
  26. "sku": "BW--Closure",
  27. "name": "100% Brazilian Virgin Hair Body Wave HD Transparent Lace Closure ",
  28. "slug": null,
  29. "type": "flexible_variant",
  30. "price": 94.71,
  31. "min_price": 94.71,
  32. "special_price": null,
  33. "image_url": "https:www.asteriahair.com/media/catalog/product/b/o/body_13__1_1.jpg",
  34. "is_new": true,
  35. "is_featured": false,
  36. "short_description": "Asteria Hair 100% Brazilian Virgin Hair Body Wave Lace Closure, Free Part 4x4 Closure Can be Parted anywhere you like, transparent lace color and HD invisible lace to choose from, both color body wave hair lace closure fits all skin tone perfectly.",
  37. "rating": 5,
  38. "review_count": 10
  39. },
  40. {
  41. "id": 3843,
  42. "sku": "#613--STW--3+C--10A613",
  43. "name": "100% Human Hair 613 Blonde Brazilian Straight Hair 3 Bundles With Closure In Stock",
  44. "slug": null,
  45. "type": "flexible_variant",
  46. "price": 168.18,
  47. "min_price": 168.18,
  48. "special_price": null,
  49. "image_url": "https:www.asteriahair.com/media/catalog/product/6/1/613_3_.jpg",
  50. "is_new": true,
  51. "is_featured": false,
  52. "short_description": "Asteria Hair 613 Blonde Color Straight Human Hair Weave 3 Bundles With 4x4 Lace Closure Transparent Lace Color",
  53. "rating": 0,
  54. "review_count": 0
  55. },
  56. {
  57. "id": 3850,
  58. "sku": "#613--BW--4--10A613",
  59. "name": "100% Human Hair Body Wave 4 Bundles 613 Blonde Hair",
  60. "slug": null,
  61. "type": "flexible_variant",
  62. "price": 156.73,
  63. "min_price": 156.73,
  64. "special_price": null,
  65. "image_url": "https:www.asteriahair.com/media/catalog/product/b/l/blonde_hair.jpg",
  66. "is_new": true,
  67. "is_featured": false,
  68. "short_description": "100% Brazilian Virgin Human Hair Weaves Body Wave 4 Bundles 613 Blonde Hair For Sale",
  69. "rating": 0,
  70. "review_count": 0
  71. },
  72. {
  73. "id": 3790,
  74. "sku": "BW--3",
  75. "name": "100% Human Hair Natural Black Brazilian Body Wave Hair 8-30 Inch",
  76. "slug": null,
  77. "type": "flexible_variant",
  78. "price": 183.29,
  79. "min_price": 183.29,
  80. "special_price": null,
  81. "image_url": "https:www.asteriahair.com/media/catalog/product/b/o/body_wave_human_hair_bundles.png",
  82. "is_new": true,
  83. "is_featured": false,
  84. "short_description": "Unprocessed Brazilian Body Wave 3 Bundles Virgin Hair Body Wave Natural Black Hot Sale Asteria Hair Product",
  85. "rating": 0,
  86. "review_count": 0
  87. },
  88. {
  89. "id": 3868,
  90. "sku": "P--LD--3",
  91. "name": "100% Unprocessed Virgin Peruvian Human Hair Weave Loose Deep 3 PCS In Stock",
  92. "slug": null,
  93. "type": "flexible_variant",
  94. "price": 193.24,
  95. "min_price": 193.24,
  96. "special_price": null,
  97. "image_url": "https:www.asteriahair.com/media/catalog/product/3/_/3__1_9.jpg",
  98. "is_new": true,
  99. "is_featured": false,
  100. "short_description": "Asteria Hair 100% Unprocessed Peruvian Virgin Human Hair Weave 3 Bundles Deal Loose Deep Wave Weaves 3 PCs Hair Bundles",
  101. "rating": 5,
  102. "review_count": 17
  103. },
  104. {
  105. "id": 3835,
  106. "sku": "P--BW--4",
  107. "name": "100% Virgin Hair Natural Black Peruvian Body Wave Hair 8-30 Inch For Selling",
  108. "slug": null,
  109. "type": "flexible_variant",
  110. "price": 222.27,
  111. "min_price": 222.27,
  112. "special_price": null,
  113. "image_url": "https:www.asteriahair.com/media/catalog/product/x/y/xys_3917_2.jpg",
  114. "is_new": true,
  115. "is_featured": false,
  116. "short_description": "Unprocessed Peruvian Body Wave 4 Bundles Virgin Hair Body Wave Natural Black Top Selling Asteria Hair Bundles",
  117. "rating": 5,
  118. "review_count": 10
  119. },
  120. {
  121. "id": 3786,
  122. "sku": "test11111",
  123. "name": "12312312",
  124. "slug": null,
  125. "type": "flexible_variant",
  126. "price": 111,
  127. "min_price": 111,
  128. "special_price": null,
  129. "image_url": null,
  130. "is_new": true,
  131. "is_featured": true,
  132. "short_description": "<p>3324124124</p>",
  133. "rating": 0,
  134. "review_count": 0
  135. },
  136. {
  137. "id": 3807,
  138. "sku": "DW--Frontal",
  139. "name": "13*4 Ear to Ear Transparent HD Lace Frontal Human Brazilian Hair Deep Wave Hair",
  140. "slug": null,
  141. "type": "flexible_variant",
  142. "price": 121.75,
  143. "min_price": 121.75,
  144. "special_price": null,
  145. "image_url": "https:www.asteriahair.com/media/catalog/product/0/2/02_4_3.jpg",
  146. "is_new": true,
  147. "is_featured": false,
  148. "short_description": "Asteria 13*4 Lace Frontal Human Hair Brazilian Hair Sale Deep Wave Hair Cheap Brazilian Hair Ear To Ear Lace Frontal Human Hair",
  149. "rating": 5,
  150. "review_count": 3
  151. },
  152. {
  153. "id": 3860,
  154. "sku": "#T1 B613--BW--3+F--10A",
  155. "name": "1B 613 Ombre Human Virgin Hair Body Wave Hair 3 Bundles with 13*4 Lace Frontal",
  156. "slug": null,
  157. "type": "flexible_variant",
  158. "price": 199.24,
  159. "min_price": 199.24,
  160. "special_price": null,
  161. "image_url": "https:www.asteriahair.com/media/catalog/product/1/b/1b-613-blonde-bundles-with-frontal.jpg",
  162. "is_new": true,
  163. "is_featured": false,
  164. "short_description": "Asteria Hair #1B\/613 Ombre Blonde Hair Color 100% Human Body Wave Hair 3 Bundles with Ear to Ear Lace Frontal Deal",
  165. "rating": 0,
  166. "review_count": 0
  167. },
  168. {
  169. "id": 3800,
  170. "sku": "STW--3+F",
  171. "name": "1pc Ear To Ear Lace Frontal with 3 Bundles Straight Virgin Brazilian Hair Weft",
  172. "slug": null,
  173. "type": "flexible_variant",
  174. "price": 281.86,
  175. "min_price": 281.86,
  176. "special_price": null,
  177. "image_url": "https:www.asteriahair.com/media/catalo/product/3/_/3_11_1.jpg",
  178. "is_new": true,
  179. "is_featured": false,
  180. "short_description": "High Quality Asteria Products 1pc Ear To Ear Lace Frontal Closure Totally Hand Made Pre-Plucked Hairline With Baby Hair 3 Bundles Human Straight Virgin Brazilian Hair Weft Natural Black Tangle Free No Splits",
  181. "rating": 0,
  182. "review_count": 0
  183. },
  184. ]
  185. // 五星星星渲染
  186. const renderStars = (count: number) => {
  187. return Array.from({ length: count }).map((_, idx) => (
  188. <svg
  189. key={idx}
  190. className="w-4 h-4 text-green-600 inline-block"
  191. viewBox="0 0 24 24"
  192. fill="currentColor"
  193. >
  194. <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
  195. </svg>
  196. ));
  197. };
  198. const AccountSwiper = () => {
  199. return (
  200. <div className="w-full max-w-[700px] mx-auto px-4">
  201. {/* 商品2列网格 */}
  202. <div className="grid grid-cols-2 gap-4">
  203. {productList.map((item) => (
  204. <div key={item.id} className="flex flex-col gap-3">
  205. {/* Next.Image 商品图容器 */}
  206. <div className="relative w-full aspect-[3/4] overflow-hidden rounded-md">
  207. <Image
  208. src={item.image_url?item.image_url:''}
  209. alt={item.name}
  210. fill
  211. sizes="(max-width:768px) 50vw, 33vw"
  212. className="object-cover"
  213. />
  214. </div>
  215. {/* 标题 */}
  216. <p className="text-sm text-gray-800 truncate">{item.name}</p>
  217. {/* 星级 + 评论数 */}
  218. <div className="flex items-center gap-1">
  219. {renderStars(item.rating)}
  220. <span className="text-sm text-gray-600 ml-1 underline">
  221. {item.review_count}
  222. </span>
  223. </div>
  224. {/* 价格 + 购物车图标 */}
  225. <div className="flex items-center justify-between">
  226. <div className="flex items-center gap-1">
  227. <span className="font-semibold">${item.min_price}</span>
  228. <span className="text-xs text-gray-500 line-through">
  229. ${item.price}
  230. </span>
  231. </div>
  232. {/* 购物车图标 */}
  233. <OpenAddToCartModalButton
  234. productId={
  235. item.id
  236. }
  237. icon={
  238. <svg
  239. xmlns="http://www.w3.org/2000/svg"
  240. width="32"
  241. height="32"
  242. viewBox="0 0 32 32"
  243. fill="none"
  244. >
  245. <rect
  246. x="0"
  247. y="0"
  248. width="32"
  249. height="32"
  250. rx="8"
  251. fill="#036141"
  252. ></rect>
  253. <path
  254. stroke="rgba(255, 255, 255, 1)"
  255. stroke-width="1.3333333333333333"
  256. stroke-linejoin="round"
  257. stroke-linecap="round"
  258. d="M6.40039 7.79993L8.03372 7.79993L8.73372 10.5999M8.73372 10.5999L11.0671 19.9333L23.2004 19.9333L25.5337 10.5999L8.73372 10.5999Z"
  259. ></path>
  260. <ellipse
  261. cx="11.066040515899658"
  262. cy="23.199928283691406"
  263. rx="1.4000248908996582"
  264. ry="1.4000015258789062"
  265. stroke="rgba(255, 255, 255, 1)"
  266. stroke-width="1.3333333333333333"
  267. stroke-linejoin="round"
  268. stroke-linecap="round"
  269. ></ellipse>
  270. <ellipse
  271. cx="23.1998291015625"
  272. cy="23.199928283691406"
  273. rx="1.4000244140625"
  274. ry="1.4000015258789062"
  275. stroke="rgba(255, 255, 255, 1)"
  276. stroke-width="1.3333333333333333"
  277. stroke-linejoin="round"
  278. stroke-linecap="round"
  279. ></ellipse>
  280. <path
  281. stroke="rgba(255, 255, 255, 1)"
  282. stroke-width="1.3333333333333333"
  283. stroke-linejoin="round"
  284. stroke-linecap="round"
  285. d="M15.2656 15.2665L18.999 15.2665"
  286. ></path>
  287. <path
  288. stroke="rgba(255, 255, 255, 1)"
  289. stroke-width="1.3333333333333333"
  290. stroke-linejoin="round"
  291. stroke-linecap="round"
  292. d="M17.1348 17.1332L17.1348 13.3999"
  293. ></path>
  294. </svg>
  295. }
  296. />
  297. </div>
  298. </div>
  299. ))}
  300. </div>
  301. {/* Swiper 核心容器 */}
  302. {/* 分页器容器(底部小圆点) */}
  303. {/* <div className="swiper-pagination flex justify-center mt-4"></div> */}
  304. </div>
  305. );
  306. };
  307. // <Swiper
  308. // slidesPerView={2} // 一行显示2个商品(和图片一致)
  309. // spaceBetween={8} // 商品之间的间距
  310. // breakpoints={{
  311. // // 响应式适配(小屏显示1个)
  312. // 390: { slidesPerView: 2 },
  313. // 640: { slidesPerView: 2 },
  314. // }}
  315. // className="product-swiper"
  316. // >
  317. // {/* 循环渲染商品卡片 */}
  318. // {productList.map((product) => (
  319. // <SwiperSlide key={product.id} className="rounded-lg overflow-hidden">
  320. // <div className="flex flex-col h-full">
  321. // {/* 商品图片(带标签) */}
  322. // <div className="relative w-full aspect-[3/4]">
  323. // <Image
  324. // src={product.imgUrl}
  325. // alt={product.title}
  326. // fill
  327. // className="w-full h-auto object-cover rounded-t-lg"
  328. // />
  329. // {/* 促销标签(有内容才显示) */}
  330. // {product.tag && (
  331. // <div className="absolute bottom-2 left-2 bg-black/80 text-white text-xs px-2 py-1 rounded">
  332. // {product.tag}
  333. // </div>
  334. // )}
  335. // </div>
  336. // {/* 商品标题 */}
  337. // <p className="mt-3 text-sm text-gray-800 font-medium line-clamp-2">
  338. // {product.title}
  339. // </p>
  340. // {/* 价格区域 */}
  341. // <div className="flex items-center gap-2 mt-2">
  342. // <span className="text-red-600 font-bold">{product.price}</span>
  343. // <span className="text-xs text-gray-500 line-through">
  344. // {product.originalPrice}
  345. // </span>
  346. // {/* 购物车图标 */}
  347. // <span className="ml-auto text-gray-600">🛒</span>
  348. // </div>
  349. // </div>
  350. // </SwiperSlide>
  351. // ))}
  352. // </Swiper>
  353. export default AccountSwiper;