@anker-in/campaign-ui 0.2.11-beta.2 → 0.2.11-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/dist/cjs/components/credits/context/hooks/useSendEmailValidation.d.ts +1 -0
  2. package/dist/cjs/components/credits/context/hooks/useSendEmailValidation.js +2 -0
  3. package/dist/cjs/components/credits/context/hooks/useSendEmailValidation.js.map +7 -0
  4. package/dist/cjs/components/credits/context/hooks/useSubscriptions.d.ts +9 -0
  5. package/dist/cjs/components/credits/context/hooks/useSubscriptions.js +2 -0
  6. package/dist/cjs/components/credits/context/hooks/useSubscriptions.js.map +7 -0
  7. package/dist/cjs/components/credits/context/utils.d.ts +4 -0
  8. package/dist/cjs/components/credits/context/utils.js +1 -1
  9. package/dist/cjs/components/credits/context/utils.js.map +3 -3
  10. package/dist/cjs/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.js +1 -1
  11. package/dist/cjs/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.js.map +3 -3
  12. package/dist/cjs/components/credits/creditsBenefits/benefitItem.js +2 -0
  13. package/dist/cjs/components/credits/creditsBenefits/benefitItem.js.map +7 -0
  14. package/dist/cjs/components/credits/creditsBenefits/index.js +3 -3
  15. package/dist/cjs/components/credits/creditsBenefits/index.js.map +2 -2
  16. package/dist/cjs/components/credits/creditsCash/RedeemableItem.js +1 -1
  17. package/dist/cjs/components/credits/creditsCash/RedeemableItem.js.map +3 -3
  18. package/dist/cjs/components/credits/creditsFaq/index.js +1 -1
  19. package/dist/cjs/components/credits/creditsFaq/index.js.map +3 -3
  20. package/dist/cjs/components/credits/creditsInfoCard/index.js +1 -1
  21. package/dist/cjs/components/credits/creditsInfoCard/index.js.map +3 -3
  22. package/dist/cjs/components/credits/creditsMemberPrice/CreditsMemberPrice.js +1 -1
  23. package/dist/cjs/components/credits/creditsMemberPrice/CreditsMemberPrice.js.map +3 -3
  24. package/dist/cjs/components/credits/creditsMemberPrice/MemberPriceItem.js +1 -1
  25. package/dist/cjs/components/credits/creditsMemberPrice/MemberPriceItem.js.map +3 -3
  26. package/dist/cjs/components/credits/creditsMemberPrice/Pagination.d.ts +7 -0
  27. package/dist/cjs/components/credits/creditsMemberPrice/Pagination.js +2 -0
  28. package/dist/cjs/components/credits/creditsMemberPrice/Pagination.js.map +7 -0
  29. package/dist/cjs/components/credits/creditsRedeemList/AddressForm/CountrySelect.js +1 -1
  30. package/dist/cjs/components/credits/creditsRedeemList/AddressForm/CountrySelect.js.map +3 -3
  31. package/dist/cjs/components/credits/creditsRedeemList/AddressForm/StateSelect.js +1 -1
  32. package/dist/cjs/components/credits/creditsRedeemList/AddressForm/StateSelect.js.map +3 -3
  33. package/dist/cjs/components/credits/creditsRedeemList/AddressForm/index.js +1 -1
  34. package/dist/cjs/components/credits/creditsRedeemList/AddressForm/index.js.map +3 -3
  35. package/dist/cjs/components/credits/creditsRedeemList/CreditsRedeemList.js +1 -1
  36. package/dist/cjs/components/credits/creditsRedeemList/CreditsRedeemList.js.map +3 -3
  37. package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Address.js +1 -1
  38. package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Address.js.map +3 -3
  39. package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Success.js +1 -1
  40. package/dist/cjs/components/credits/creditsRedeemList/RedeemProductModal/Success.js.map +3 -3
  41. package/dist/cjs/components/credits/creditsRedeemList/RedeemableItem.js +1 -1
  42. package/dist/cjs/components/credits/creditsRedeemList/RedeemableItem.js.map +3 -3
  43. package/dist/cjs/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.js +1 -1
  44. package/dist/cjs/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.js.map +3 -3
  45. package/dist/cjs/components/credits/modal/MyRewardsModal.js +1 -1
  46. package/dist/cjs/components/credits/modal/MyRewardsModal.js.map +3 -3
  47. package/dist/cjs/components/credits/modal/activitiesModal.js +1 -1
  48. package/dist/cjs/components/credits/modal/activitiesModal.js.map +3 -3
  49. package/dist/cjs/components/credits/modal/creditsUploadReceiptModal.js +1 -1
  50. package/dist/cjs/components/credits/modal/creditsUploadReceiptModal.js.map +3 -3
  51. package/dist/cjs/components/credits/modal/modalContainer.js +1 -1
  52. package/dist/cjs/components/credits/modal/modalContainer.js.map +3 -3
  53. package/dist/cjs/components/credits/modal/subscribeModal.js +1 -1
  54. package/dist/cjs/components/credits/modal/subscribeModal.js.map +3 -3
  55. package/dist/cjs/components/credits/modal/tip.js +1 -1
  56. package/dist/cjs/components/credits/modal/tip.js.map +3 -3
  57. package/dist/cjs/components/index.d.ts +2 -2
  58. package/dist/cjs/components/index.js +1 -1
  59. package/dist/cjs/components/index.js.map +2 -2
  60. package/dist/cjs/components/registration/authCodeActivate/index.js +1 -1
  61. package/dist/cjs/components/registration/authCodeActivate/index.js.map +3 -3
  62. package/dist/cjs/components/registration/modalContainer.js +1 -1
  63. package/dist/cjs/components/registration/modalContainer.js.map +3 -3
  64. package/dist/cjs/constants.d.ts +1 -0
  65. package/dist/cjs/constants.js +2 -0
  66. package/dist/cjs/constants.js.map +7 -0
  67. package/dist/cjs/helpers/fetchResponse.d.ts +14 -0
  68. package/dist/cjs/helpers/fetchResponse.js +2 -0
  69. package/dist/cjs/helpers/fetchResponse.js.map +7 -0
  70. package/dist/cjs/helpers/fetcher.d.ts +2 -0
  71. package/dist/cjs/helpers/fetcher.js +2 -0
  72. package/dist/cjs/helpers/fetcher.js.map +7 -0
  73. package/dist/cjs/helpers/index.d.ts +2 -0
  74. package/dist/cjs/helpers/index.js +2 -0
  75. package/dist/cjs/helpers/index.js.map +7 -0
  76. package/dist/cjs/helpers/track.d.ts +19 -0
  77. package/dist/cjs/helpers/track.js +2 -0
  78. package/dist/cjs/helpers/track.js.map +7 -0
  79. package/dist/cjs/helpers/utils.d.ts +3 -0
  80. package/dist/cjs/helpers/utils.js +2 -0
  81. package/dist/cjs/helpers/utils.js.map +7 -0
  82. package/dist/cjs/index.d.ts +3 -2
  83. package/dist/cjs/index.js +1 -1
  84. package/dist/cjs/index.js.map +2 -2
  85. package/dist/esm/components/credits/context/hooks/useSendEmailValidation.d.ts +1 -0
  86. package/dist/esm/components/credits/context/hooks/useSendEmailValidation.js +2 -0
  87. package/dist/esm/components/credits/context/hooks/useSendEmailValidation.js.map +7 -0
  88. package/dist/esm/components/credits/context/hooks/useSubscriptions.d.ts +9 -0
  89. package/dist/esm/components/credits/context/hooks/useSubscriptions.js +2 -0
  90. package/dist/esm/components/credits/context/hooks/useSubscriptions.js.map +7 -0
  91. package/dist/esm/components/credits/context/utils.d.ts +4 -0
  92. package/dist/esm/components/credits/context/utils.js +1 -1
  93. package/dist/esm/components/credits/context/utils.js.map +3 -3
  94. package/dist/esm/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.js +1 -1
  95. package/dist/esm/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.js.map +3 -3
  96. package/dist/esm/components/credits/creditsBenefits/benefitItem.js +2 -0
  97. package/dist/esm/components/credits/creditsBenefits/benefitItem.js.map +7 -0
  98. package/dist/esm/components/credits/creditsBenefits/index.js +3 -3
  99. package/dist/esm/components/credits/creditsBenefits/index.js.map +2 -2
  100. package/dist/esm/components/credits/creditsCash/RedeemableItem.js +1 -1
  101. package/dist/esm/components/credits/creditsCash/RedeemableItem.js.map +3 -3
  102. package/dist/esm/components/credits/creditsFaq/index.js +1 -1
  103. package/dist/esm/components/credits/creditsFaq/index.js.map +3 -3
  104. package/dist/esm/components/credits/creditsInfoCard/index.js +1 -1
  105. package/dist/esm/components/credits/creditsInfoCard/index.js.map +2 -2
  106. package/dist/esm/components/credits/creditsMemberPrice/CreditsMemberPrice.js +1 -1
  107. package/dist/esm/components/credits/creditsMemberPrice/CreditsMemberPrice.js.map +3 -3
  108. package/dist/esm/components/credits/creditsMemberPrice/MemberPriceItem.js +1 -1
  109. package/dist/esm/components/credits/creditsMemberPrice/MemberPriceItem.js.map +3 -3
  110. package/dist/esm/components/credits/creditsMemberPrice/Pagination.d.ts +7 -0
  111. package/dist/esm/components/credits/creditsMemberPrice/Pagination.js +2 -0
  112. package/dist/esm/components/credits/creditsMemberPrice/Pagination.js.map +7 -0
  113. package/dist/esm/components/credits/creditsRedeemList/AddressForm/CountrySelect.js +1 -1
  114. package/dist/esm/components/credits/creditsRedeemList/AddressForm/CountrySelect.js.map +2 -2
  115. package/dist/esm/components/credits/creditsRedeemList/AddressForm/StateSelect.js +1 -1
  116. package/dist/esm/components/credits/creditsRedeemList/AddressForm/StateSelect.js.map +2 -2
  117. package/dist/esm/components/credits/creditsRedeemList/AddressForm/index.js +1 -1
  118. package/dist/esm/components/credits/creditsRedeemList/AddressForm/index.js.map +2 -2
  119. package/dist/esm/components/credits/creditsRedeemList/CreditsRedeemList.js +1 -1
  120. package/dist/esm/components/credits/creditsRedeemList/CreditsRedeemList.js.map +3 -3
  121. package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Address.js +1 -1
  122. package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Address.js.map +3 -3
  123. package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Success.js +1 -1
  124. package/dist/esm/components/credits/creditsRedeemList/RedeemProductModal/Success.js.map +2 -2
  125. package/dist/esm/components/credits/creditsRedeemList/RedeemableItem.js +1 -1
  126. package/dist/esm/components/credits/creditsRedeemList/RedeemableItem.js.map +3 -3
  127. package/dist/esm/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.js +1 -1
  128. package/dist/esm/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.js.map +3 -3
  129. package/dist/esm/components/credits/modal/MyRewardsModal.js +1 -1
  130. package/dist/esm/components/credits/modal/MyRewardsModal.js.map +2 -2
  131. package/dist/esm/components/credits/modal/activitiesModal.js +1 -1
  132. package/dist/esm/components/credits/modal/activitiesModal.js.map +3 -3
  133. package/dist/esm/components/credits/modal/creditsUploadReceiptModal.js +1 -1
  134. package/dist/esm/components/credits/modal/creditsUploadReceiptModal.js.map +3 -3
  135. package/dist/esm/components/credits/modal/modalContainer.js +1 -1
  136. package/dist/esm/components/credits/modal/modalContainer.js.map +3 -3
  137. package/dist/esm/components/credits/modal/subscribeModal.js +1 -1
  138. package/dist/esm/components/credits/modal/subscribeModal.js.map +3 -3
  139. package/dist/esm/components/credits/modal/tip.js +1 -1
  140. package/dist/esm/components/credits/modal/tip.js.map +3 -3
  141. package/dist/esm/components/index.d.ts +2 -2
  142. package/dist/esm/components/index.js +1 -1
  143. package/dist/esm/components/index.js.map +2 -2
  144. package/dist/esm/components/registration/authCodeActivate/index.js +1 -1
  145. package/dist/esm/components/registration/authCodeActivate/index.js.map +3 -3
  146. package/dist/esm/components/registration/modalContainer.js +1 -1
  147. package/dist/esm/components/registration/modalContainer.js.map +3 -3
  148. package/dist/esm/constants.d.ts +1 -0
  149. package/dist/esm/constants.js +2 -0
  150. package/dist/esm/constants.js.map +7 -0
  151. package/dist/esm/helpers/fetchResponse.d.ts +14 -0
  152. package/dist/esm/helpers/fetchResponse.js +2 -0
  153. package/dist/esm/helpers/fetchResponse.js.map +7 -0
  154. package/dist/esm/helpers/fetcher.d.ts +2 -0
  155. package/dist/esm/helpers/fetcher.js +2 -0
  156. package/dist/esm/helpers/fetcher.js.map +7 -0
  157. package/dist/esm/helpers/index.d.ts +2 -0
  158. package/dist/esm/helpers/index.js +2 -0
  159. package/dist/esm/helpers/index.js.map +7 -0
  160. package/dist/esm/helpers/track.d.ts +19 -0
  161. package/dist/esm/helpers/track.js +2 -0
  162. package/dist/esm/helpers/track.js.map +7 -0
  163. package/dist/esm/helpers/utils.d.ts +3 -0
  164. package/dist/esm/helpers/utils.js +2 -0
  165. package/dist/esm/helpers/utils.js.map +7 -0
  166. package/dist/esm/index.d.ts +3 -2
  167. package/dist/esm/index.js +1 -1
  168. package/dist/esm/index.js.map +2 -2
  169. package/package.json +3 -3
  170. package/src/components/credits/context/utils.ts +9 -0
  171. package/src/components/credits/creditsAnkersolixTask/CreditsAnkersolixTask.tsx +21 -18
  172. package/src/components/credits/creditsBenefits/BenefitItem.tsx +3 -2
  173. package/src/components/credits/creditsBenefits/index.tsx +1 -1
  174. package/src/components/credits/creditsCash/RedeemableItem.tsx +9 -4
  175. package/src/components/credits/creditsFaq/index.tsx +2 -1
  176. package/src/components/credits/creditsInfoCard/index.tsx +2 -1
  177. package/src/components/credits/creditsMemberPrice/CreditsMemberPrice.tsx +37 -112
  178. package/src/components/credits/creditsMemberPrice/MemberPriceItem.tsx +32 -9
  179. package/src/components/credits/creditsMemberPrice/Pagination.tsx +113 -0
  180. package/src/components/credits/creditsRedeemList/AddressForm/CountrySelect.tsx +2 -1
  181. package/src/components/credits/creditsRedeemList/AddressForm/StateSelect.tsx +2 -1
  182. package/src/components/credits/creditsRedeemList/AddressForm/index.tsx +2 -1
  183. package/src/components/credits/creditsRedeemList/CreditsRedeemList.tsx +2 -1
  184. package/src/components/credits/creditsRedeemList/RedeemProductModal/Address.tsx +2 -1
  185. package/src/components/credits/creditsRedeemList/RedeemProductModal/Success.tsx +2 -1
  186. package/src/components/credits/creditsRedeemList/RedeemableItem.tsx +2 -1
  187. package/src/components/credits/creditsWaysToGetCredits/CreditsWaysToGetCredits.tsx +14 -3
  188. package/src/components/credits/modal/MyRewardsModal.tsx +2 -1
  189. package/src/components/credits/modal/activitiesModal.tsx +2 -1
  190. package/src/components/credits/modal/creditsUploadReceiptModal.tsx +2 -1
  191. package/src/components/credits/modal/modalContainer.tsx +2 -1
  192. package/src/components/credits/modal/subscribeModal.tsx +2 -1
  193. package/src/components/credits/modal/tip.tsx +2 -1
  194. package/src/components/index.ts +2 -2
  195. package/src/components/registration/authCodeActivate/index.tsx +1 -1
  196. package/src/components/registration/modalContainer.tsx +2 -1
  197. package/src/constants.ts +1 -0
  198. package/src/index.ts +3 -2
  199. package/dist/cjs/components/credits/creditsBenefits/BenefitItem.js +0 -2
  200. package/dist/cjs/components/credits/creditsBenefits/BenefitItem.js.map +0 -7
  201. package/dist/esm/components/credits/creditsBenefits/BenefitItem.js +0 -2
  202. package/dist/esm/components/credits/creditsBenefits/BenefitItem.js.map +0 -7
  203. /package/dist/cjs/components/credits/creditsBenefits/{BenefitItem.d.ts → benefitItem.d.ts} +0 -0
  204. /package/dist/cjs/components/credits/creditsBenefits/{IconInfo.d.ts → iconInfo.d.ts} +0 -0
  205. /package/dist/cjs/components/credits/creditsBenefits/{IconInfo.js → iconInfo.js} +0 -0
  206. /package/dist/cjs/components/credits/creditsBenefits/{IconInfo.js.map → iconInfo.js.map} +0 -0
  207. /package/dist/cjs/templates/{Credits.d.ts → credits.d.ts} +0 -0
  208. /package/dist/cjs/templates/{Credits.js → credits.js} +0 -0
  209. /package/dist/cjs/templates/{Credits.js.map → credits.js.map} +0 -0
  210. /package/dist/esm/components/credits/creditsBenefits/{BenefitItem.d.ts → benefitItem.d.ts} +0 -0
  211. /package/dist/esm/components/credits/creditsBenefits/{IconInfo.d.ts → iconInfo.d.ts} +0 -0
  212. /package/dist/esm/components/credits/creditsBenefits/{IconInfo.js → iconInfo.js} +0 -0
  213. /package/dist/esm/components/credits/creditsBenefits/{IconInfo.js.map → iconInfo.js.map} +0 -0
  214. /package/dist/esm/templates/{Credits.d.ts → credits.d.ts} +0 -0
  215. /package/dist/esm/templates/{Credits.js → credits.js} +0 -0
  216. /package/dist/esm/templates/{Credits.js.map → credits.js.map} +0 -0
@@ -0,0 +1,2 @@
1
+ import{clsx as r}from"clsx";import{twMerge as t}from"tailwind-merge";function p(...o){return t(r(o))}function a(){}export{p as cn,a as noop};
2
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/helpers/utils.ts"],
4
+ "sourcesContent": ["import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\nexport function noop(): any {}\n"],
5
+ "mappings": "AAAA,OAAS,QAAAA,MAA6B,OACtC,OAAS,WAAAC,MAAe,iBAEjB,SAASC,KAAMC,EAAsB,CAC1C,OAAOF,EAAQD,EAAKG,CAAM,CAAC,CAC7B,CAEO,SAASC,GAAY,CAAC",
6
+ "names": ["clsx", "twMerge", "cn", "inputs", "noop"]
7
+ }
@@ -1,2 +1,3 @@
1
- export * from './components';
2
- export * from './templates';
1
+ export * from './components/index.js';
2
+ export * from './templates/index.js';
3
+ export * from './constants.js';
package/dist/esm/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export*from"./components";export*from"./templates";
1
+ export*from"./components/index.js";export*from"./templates/index.js";export*from"./constants.js";
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts"],
4
- "sourcesContent": ["export * from './components'\nexport * from './templates'\n"],
5
- "mappings": "AAAA,WAAc,eACd,WAAc",
4
+ "sourcesContent": ["export * from './components/index.js'\nexport * from './templates/index.js'\nexport * from './constants.js'\n"],
5
+ "mappings": "AAAA,WAAc,wBACd,WAAc,uBACd,WAAc",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anker-in/campaign-ui",
3
- "version": "0.2.11-beta.2",
3
+ "version": "0.2.11-beta.3",
4
4
  "description": "Campaign UI components and utilities for Anker projects",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",
@@ -88,8 +88,8 @@
88
88
  "swiper": "^11.1.3",
89
89
  "tailwind-merge": "^2.3.0",
90
90
  "tailwindcss": "^3.4.3",
91
- "@anker-in/headless-ui": "1.1.25-alpha.1767516866003",
92
- "@anker-in/lib": "1.1.2-beta.1"
91
+ "@anker-in/lib": "1.1.2-beta.2",
92
+ "@anker-in/headless-ui": "1.1.25-alpha.1767516866003"
93
93
  },
94
94
  "publishConfig": {
95
95
  "access": "public",
@@ -147,3 +147,12 @@ export function formatVariantPrice({
147
147
 
148
148
  return { price, basePrice, discount }
149
149
  }
150
+
151
+ /**
152
+ * 提取 variant id,去掉 gid://shopify/ProductVariant/ 前缀
153
+ */
154
+ export function extractVariantId(id: string | number | undefined): string | null {
155
+ if (!id) return null
156
+ const idStr = typeof id === 'number' ? id.toString() : id
157
+ return idStr.replace('gid://shopify/ProductVariant/', '')
158
+ }
@@ -6,10 +6,11 @@ import { useMemo, useState } from 'react'
6
6
  import { TaskType, type CreditsAnkersolixTaskProps } from './type'
7
7
  import { useActions } from '../creditsWaysToGetCredits/useActions'
8
8
  import { useCreditsContext } from '../context/provider'
9
- import { classNames as cn, useHeadlessContext, ROUNDED_BRANDS } from '@anker-in/lib'
9
+ import { classNames as cn, useHeadlessContext } from '@anker-in/lib'
10
10
  import { useRegistration } from '../../registration'
11
11
  import { CreditsUploadReceiptModal } from '../modal/creditsUploadReceiptModal'
12
12
  import { CreditsSubscribeModal } from '../modal/subscribeModal'
13
+ import { ROUNDED_BRANDS } from '../../../constants'
13
14
 
14
15
  export const CreditsAnkersolixTask = ({ copy, classNames, id }: CreditsAnkersolixTaskProps & { id?: string }) => {
15
16
  const [showMore, setShowMore] = useState(false)
@@ -94,8 +95,8 @@ export const CreditsAnkersolixTask = ({ copy, classNames, id }: CreditsAnkersoli
94
95
  const shouldShowMask = list.length > 3
95
96
 
96
97
  return (
97
- <Container id={id} className="[&>div]:l:!px-0 bg-[#F5F5F7]">
98
- <Heading as="h2" size="4" html={copy.title} className='md:px-[16px]'/>
98
+ <Container id={id} className="bg-[#F5F5F7]">
99
+ <Heading as="h2" size="4" html={copy.title} />
99
100
  <div
100
101
  className={cn(
101
102
  'mt-[24px] p-[32px] md-l:p-[32px] md:p-[16px] relative overflow-hidden',
@@ -114,8 +115,8 @@ export const CreditsAnkersolixTask = ({ copy, classNames, id }: CreditsAnkersoli
114
115
  }}
115
116
  />
116
117
  {/* 副标题和装饰图部分 */}
117
- <div className="flex items-center justify-between h-[560px] md:h-auto md:flex-col md:items-start l:h-auto l:mb-[16px] l:flex-col-reverse l:items-start">
118
- <div className="flex flex-col gap-[8px]">
118
+ <div className="flex items-center justify-between xl-xxl:h-[448px] l-xl:h-[336px] h-[560px] l:h-auto md:flex-col md:items-start l:h-auto l:mb-[16px] l:flex-col-reverse l:items-start">
119
+ <div className="flex flex-col gap-[8px] l:mt-[8px]">
119
120
  <Heading
120
121
  as="h3"
121
122
  size={4}
@@ -130,16 +131,18 @@ export const CreditsAnkersolixTask = ({ copy, classNames, id }: CreditsAnkersoli
130
131
  </div>
131
132
  </div>
132
133
  {copy.mainImage?.url && (
133
- <Picture className="w-full max-w-[50%] md:max-w-full md:mt-[24px] l:max-w-full l:mt-[24px]" source={copy.mainImage.url} />
134
+ <Picture
135
+ className="h-full object-contain l:mx-auto md:h-auto md:w-full md-l:h-[302px]"
136
+ imgClassName="!h-full !object-contain"
137
+ source={copy.mainImage.url}
138
+ />
134
139
  )}
135
140
  </div>
136
141
 
137
142
  {/* 卡片列表 */}
138
- <div className="relative">
143
+ <div className="relative mt-[24px]">
139
144
  <motion.div
140
- className={cn(
141
- 'grid grid-cols-3 gap-[16px] overflow-hidden md:grid-cols-1 md-l:grid-cols-2 min-md:!h-auto'
142
- )}
145
+ className={cn('grid grid-cols-3 gap-[16px] overflow-hidden md:grid-cols-1 md-l:grid-cols-2 min-md:!h-auto')}
143
146
  initial={{ height: shouldShowMask ? 512 : 'auto' }}
144
147
  animate={{ height: showMore || !shouldShowMask ? 'auto' : 512 }}
145
148
  transition={{ duration: 0.3 }}
@@ -156,27 +159,27 @@ export const CreditsAnkersolixTask = ({ copy, classNames, id }: CreditsAnkersoli
156
159
  <div
157
160
  key={item.id}
158
161
  className={cn(
159
- 'flex min-h-[241px] xl-xxl:min-h-[192px] l:min-h-[160px] l-xl:min-h-[170px] flex-col justify-between bg-white p-[32px] md:p-[16px] l:p-[24px]',
160
- rounded ? '' : ''
162
+ 'flex min-h-[241px] xl-xxl:min-h-[192px] l:min-h-[160px] l-xl:min-h-[170px] flex-col justify-between bg-white p-[32px] xl:p-[16px]',
163
+ rounded ? 'rounded-[16px]' : ''
161
164
  )}
162
165
  >
163
166
  <div>
164
- <Heading
165
- as="h4"
167
+ <Text
168
+ as="p"
166
169
  html={item.title}
167
170
  size={2}
168
- className="text-[24px] font-bold text-[#080a0f] tracking-[-0.96px] leading-[1.2] text-pretty md:text-[18px] l:text-[20px]"
171
+ className="text-pretty text-[24px] font-bold xxl:text-[20px]"
169
172
  />
170
- <div className="mt-[8px] flex items-center gap-[4px]">
173
+ <div className="mt-[8px] l:mt-[4px] flex items-center">
171
174
  <Picture
172
- className="size-[24px] [&_path]:size-full"
175
+ className="size-[24px] xxl:size-[18px] [&_path]:size-full"
173
176
  source="https://cdn.shopify.com/s/files/1/0511/6346/3874/files/20250902-153351.png?v=1756798450"
174
177
  />
175
178
  <Text
176
179
  as="p"
177
180
  html={item.credits}
178
181
  size={2}
179
- className="text-[18px] font-bold text-[#080a0f] tracking-[-0.36px] leading-[1.4] md:text-[16px]"
182
+ className="ml-[4px] mt-[6px] text-[18px] xxl:text-[14px]"
180
183
  />
181
184
  </div>
182
185
  </div>
@@ -1,6 +1,7 @@
1
1
  import { Heading, Picture, Text } from '@anker-in/headless-ui'
2
- import { classNames as cn, useHeadlessContext, ROUNDED_BRANDS } from '@anker-in/lib'
2
+ import { classNames as cn, useHeadlessContext } from '@anker-in/lib'
3
3
  import IconInfo from './IconInfo'
4
+ import { ROUNDED_BRANDS } from '../../../constants'
4
5
 
5
6
  export interface BenefitItemCopy {
6
7
  icon: {
@@ -60,7 +61,7 @@ const BenefitItem = ({
60
61
  <div className="flex flex-col">
61
62
  <Picture className={iconSizeClass} alt={item.icon?.alt} source={item.icon?.url} />
62
63
  <div className="flex items-center">
63
- <Heading html={item.text} size="2" className="break-all" />
64
+ <Heading html={item.text} size="2" className="break-all md-l:line-clamp-3" />
64
65
  {item.note && (
65
66
  <div
66
67
  role="button"
@@ -47,7 +47,7 @@ export const CreditsBenefits = ({ copy, id }: { copy: CreditsBenefitsCopy; id?:
47
47
  return (
48
48
  <Container id={id} className="!z-[30] bg-[#F5F5F7]">
49
49
  <Heading as="h2" size="4" html={copy?.title} />
50
- <div className="mt-[24px] grid grid-cols-4 xl:grid-cols-3 gap-[16px] l:hidden items-stretch">
50
+ <div className="mt-[24px] grid grid-cols-4 gap-[16px] l:hidden items-stretch">
51
51
  {copy.benefits.map((item, index) => (
52
52
  <BenefitItem
53
53
  key={index}
@@ -4,9 +4,10 @@ import { useMemo, useState } from 'react'
4
4
  import { CreditsCashCopy, RedeemItem } from './type'
5
5
  import { useCreditsContext } from '../context/provider'
6
6
  import { useRedeemAndBuy } from '../context/hooks/useRedeemAndBuy'
7
- import { formatPrice, numberFormat } from '../context/utils'
8
- import { gaTrack, classNames as cn, ROUNDED_BRANDS, useHeadlessContext } from '@anker-in/lib'
7
+ import { formatPrice, numberFormat, extractVariantId } from '../context/utils'
8
+ import { gaTrack, classNames as cn, useHeadlessContext } from '@anker-in/lib'
9
9
  import { useRegistration } from '../../../components/registration'
10
+ import { ROUNDED_BRANDS } from '../../../constants'
10
11
 
11
12
  function RedeemableItem({
12
13
  copy,
@@ -112,13 +113,17 @@ function RedeemableItem({
112
113
  return (
113
114
  <div
114
115
  className={cn(
115
- 'flex flex-col items-center rounded-[16px] bg-[#EAEAEC] p-[24px] md:rounded-[12px] md:px-[8px] xl:py-[16px] md-xl:px-[16px]',
116
+ 'flex flex-col items-center rounded-[16px] bg-[#EAEAEC] md:rounded-[12px] p-[24px] l:p-[8px] md-xl:p-[16px]',
116
117
  !rounded && 'rounded-none md:rounded-none',
117
118
  className
118
119
  )}
119
120
  >
120
121
  <a
121
- href={`/products/${itemData.product.handle}`}
122
+ href={
123
+ extractVariantId(itemData.productVariant?.id)
124
+ ? `/products/${itemData.product.handle}?variant=${extractVariantId(itemData.productVariant?.id)}`
125
+ : `/products/${itemData.product.handle}`
126
+ }
122
127
  className={cn('relative mx-auto h-[224px] w-fit l:h-[120px] l-xxl:h-[138px]')}
123
128
  >
124
129
  <Picture
@@ -1,8 +1,9 @@
1
1
  import { Container, Heading, Tabs, TabsList, TabsTrigger, Text } from '@anker-in/headless-ui'
2
- import { classNames as cn, useHeadlessContext, ROUNDED_BRANDS } from '@anker-in/lib'
2
+ import { classNames as cn, useHeadlessContext } from '@anker-in/lib'
3
3
  import { useMemo, useState } from 'react'
4
4
 
5
5
  import { FaqItem } from './faqItem/FaqItem'
6
+ import { ROUNDED_BRANDS } from '../../../constants'
6
7
 
7
8
  export type CreditsFaqCopy = {
8
9
  title: string
@@ -5,7 +5,8 @@ import { useCreditsContext } from '../context/provider'
5
5
  import { numberFormat } from '../context/utils'
6
6
  import ActivitiesModal from '../modal/activitiesModal'
7
7
  import MyRewardsModal from '../modal/MyRewardsModal'
8
- import { gaNormalClick, classNames as cn, useHeadlessContext, ROUNDED_BRANDS } from '@anker-in/lib'
8
+ import { gaNormalClick, classNames as cn, useHeadlessContext } from '@anker-in/lib'
9
+ import { ROUNDED_BRANDS } from '../../../constants'
9
10
 
10
11
  type ButtonConfig = {
11
12
  text: string
@@ -1,11 +1,12 @@
1
1
  import { Container, Heading, Tabs, TabsList, TabsTrigger } from '@anker-in/headless-ui'
2
- import { useMemo, useState, useEffect, useCallback } from 'react'
2
+ import { useMemo, useState, useEffect, useCallback, useRef } from 'react'
3
3
  import Decimal from 'decimal.js'
4
4
 
5
5
  import MemberPriceItem from './MemberPriceItem'
6
6
  import RedeemableItem from '../creditsCash/RedeemableItem'
7
7
  import useRedeemableList from '../context/hooks/useRedeemableList'
8
8
  import RulesModal from '../modal/rulesModal'
9
+ import { Pagination } from './Pagination'
9
10
  import { useProductsByHandles } from '@anker-in/lib'
10
11
  import { CreditsMemberPriceCopy, MemberPriceProduct } from './type'
11
12
  import { Product, classNames as cn } from '@anker-in/lib'
@@ -20,6 +21,7 @@ export const CreditsMemberPrice = ({ copy, id }: { copy: CreditsMemberPriceCopy;
20
21
  const [itemsPerPage, setItemsPerPage] = useState(9) // 默认 1024px 以上:3列 × 3行 = 9
21
22
  const { redeemableList } = useRedeemableList()
22
23
  const { pageCommon, memberPriceDiscount } = useCreditsContext()
24
+ const containerRef = useRef<HTMLDivElement>(null)
23
25
 
24
26
  console.log('copy in CreditsMemberPrice', copy)
25
27
 
@@ -35,11 +37,17 @@ export const CreditsMemberPrice = ({ copy, id }: { copy: CreditsMemberPriceCopy;
35
37
  useEffect(() => {
36
38
  const updateItemsPerPage = () => {
37
39
  const width = window.innerWidth
38
- if (width >= 1024) {
39
- // 1024px 以上:3列 × 3行 = 9
40
+ if (width >= 1440) {
41
+ // 1920px 以上:4列 × 3行 = 12
42
+ setItemsPerPage(12)
43
+ } else if (width >= 1024) {
44
+ // 1024px - 1919px:3列 × 3行 = 9个
40
45
  setItemsPerPage(9)
46
+ } else if (width >= 768) {
47
+ // 1024px 以下:3列 × 4行 = 12个
48
+ setItemsPerPage(12)
41
49
  } else {
42
- // 1024px 以下:2列 × 4行 = 8个
50
+ // 768px 以下:2列 × 4行 = 8个
43
51
  setItemsPerPage(8)
44
52
  }
45
53
  }
@@ -208,115 +216,24 @@ export const CreditsMemberPrice = ({ copy, id }: { copy: CreditsMemberPriceCopy;
208
216
  }
209
217
  }, [redeemList, currentPage, itemsPerPage])
210
218
 
211
- // 分页导航组件 - 按照 Figma 设计
212
- const renderPagination = (totalPages: number) => {
213
- if (totalPages <= 1) return null
214
-
215
- // 计算要显示的页码
216
- const getPageNumbers = () => {
217
- const delta = 2 // 当前页前后显示的页码数量
218
- const range = []
219
- const rangeWithDots = []
220
-
221
- for (let i = 1; i <= totalPages; i++) {
222
- if (i === 1 || i === totalPages || (i >= currentPage - delta && i <= currentPage + delta)) {
223
- range.push(i)
224
- }
225
- }
226
-
227
- let prev = 0
228
- for (const i of range) {
229
- if (prev && i - prev > 1) {
230
- rangeWithDots.push('...')
231
- }
232
- rangeWithDots.push(i)
233
- prev = i
219
+ // 处理页面切换,滚动到模块顶部
220
+ const handlePageChange = useCallback(
221
+ (page: number) => {
222
+ setCurrentPage(page)
223
+ // 滚动到模块顶部
224
+ if (containerRef.current) {
225
+ const top = containerRef.current.offsetTop
226
+ window.scrollTo({
227
+ top: top - 80, // 减去 80px 的偏移量,避免被固定头部遮挡
228
+ behavior: 'smooth',
229
+ })
234
230
  }
235
-
236
- return rangeWithDots
237
- }
238
-
239
- const pages = getPageNumbers()
240
-
241
- return (
242
- <div className="mt-[32px] flex items-center justify-center gap-[8px]">
243
- {/* 上一页按钮 */}
244
- <button
245
- onClick={() => setCurrentPage(prev => Math.max(1, prev - 1))}
246
- disabled={currentPage === 1}
247
- className={cn(
248
- 'flex size-[32px] xl:size-[24px] items-center justify-center overflow-hidden bg-white',
249
- currentPage === 1 && 'cursor-not-allowed opacity-50'
250
- )}
251
- >
252
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
253
- <path
254
- d="M10 12L6 8L10 4"
255
- stroke={currentPage === 1 ? '#767880' : '#080A0F'}
256
- strokeWidth="1.5"
257
- strokeLinecap="round"
258
- strokeLinejoin="round"
259
- />
260
- </svg>
261
- </button>
262
-
263
- {/* 页码按钮 */}
264
- {pages.map((page, index) => {
265
- if (page === '...') {
266
- return (
267
- <div
268
- key={`ellipsis-${index}`}
269
- className="flex size-[32px] xl:size-[24px] items-center justify-center overflow-hidden bg-white"
270
- >
271
- <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
272
- <circle cx="4.5" cy="10" r="1.25" fill="#2A2C32" />
273
- <circle cx="10" cy="10" r="1.25" fill="#2A2C32" />
274
- <circle cx="15.5" cy="10" r="1.25" fill="#2A2C32" />
275
- </svg>
276
- </div>
277
- )
278
- }
279
-
280
- const isActive = currentPage === page
281
- return (
282
- <button
283
- key={page}
284
- onClick={() => setCurrentPage(page as number)}
285
- className={cn(
286
- 'flex size-[32px] xl:size-[24px] pt-[4px] items-center justify-center overflow-hidden text-[16px] xl:text-[14px] font-bold leading-[1.4] tracking-[-0.28px]',
287
- isActive ? 'bg-[#080a0f] text-white' : 'bg-white text-[#080a0f]'
288
- )}
289
- >
290
- {page}
291
- </button>
292
- )
293
- })}
294
-
295
- {/* 下一页按钮 */}
296
- <button
297
- onClick={() => setCurrentPage(prev => Math.min(totalPages, prev + 1))}
298
- disabled={currentPage === totalPages}
299
- className={cn(
300
- 'flex size-[32px] xl:size-[24px] items-center justify-center overflow-hidden bg-white',
301
- currentPage === totalPages && 'cursor-not-allowed opacity-50'
302
- )}
303
- >
304
- <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
305
- <path
306
- d="M6 4L10 8L6 12"
307
- stroke={currentPage === totalPages ? '#767880' : '#080A0F'}
308
- strokeWidth="1.5"
309
- strokeLinecap="round"
310
- strokeLinejoin="round"
311
- />
312
- </svg>
313
- </button>
314
- </div>
315
- )
316
- }
231
+ },
232
+ [setCurrentPage]
233
+ )
317
234
 
318
235
  return (
319
- <Container id={id} className={cn('bg-[#F5F5F5]')}>
236
+ <Container id={id} className={cn('bg-[#F5F5F5]')} ref={containerRef}>
320
237
  <Heading as="h2" size="4" html={copy.title} className="mx:px-[16px]" />
321
238
 
322
239
  <Tabs
@@ -344,7 +261,11 @@ export const CreditsMemberPrice = ({ copy, id }: { copy: CreditsMemberPriceCopy;
344
261
  <MemberPriceItem key={index} itemData={item} copy={copy.memberPriceTab} />
345
262
  ))}
346
263
  </div>
347
- {renderPagination(memberPricePagination.totalPages)}
264
+ <Pagination
265
+ currentPage={currentPage}
266
+ totalPages={memberPricePagination.totalPages}
267
+ onPageChange={handlePageChange}
268
+ />
348
269
  </>
349
270
  )}
350
271
 
@@ -365,7 +286,11 @@ export const CreditsMemberPrice = ({ copy, id }: { copy: CreditsMemberPriceCopy;
365
286
  />
366
287
  ))}
367
288
  </div>
368
- {renderPagination(redeemPagination.totalPages)}
289
+ <Pagination
290
+ currentPage={currentPage}
291
+ totalPages={redeemPagination.totalPages}
292
+ onPageChange={handlePageChange}
293
+ />
369
294
  </>
370
295
  )}
371
296
  </div>
@@ -2,9 +2,10 @@ import { Button, Text, Picture } from '@anker-in/headless-ui'
2
2
  import { useMemo } from 'react'
3
3
 
4
4
  import { CreditsMemberPriceCopy, MemberPriceProduct } from './type'
5
- import { formatPrice } from '../context/utils'
6
- import { classNames as cn, ROUNDED_BRANDS, useHeadlessContext, useBuyNow } from '@anker-in/lib'
5
+ import { formatPrice, extractVariantId } from '../context/utils'
6
+ import { classNames as cn, useHeadlessContext, useBuyNow } from '@anker-in/lib'
7
7
  import { useCreditsContext } from '../context/provider'
8
+ import { ROUNDED_BRANDS } from '../../../constants'
8
9
 
9
10
  function MemberPriceItem({
10
11
  itemData,
@@ -16,7 +17,7 @@ function MemberPriceItem({
16
17
  className?: string
17
18
  }) {
18
19
  const { brand, locale } = useHeadlessContext()
19
- const { profile } = useCreditsContext()
20
+ const { profile, openSignUpPopup } = useCreditsContext()
20
21
  const rounded = ROUNDED_BRANDS.includes(brand)
21
22
 
22
23
  // 使用 buyNow hook 来处理结算
@@ -26,13 +27,28 @@ function MemberPriceItem({
26
27
  return itemData.productVariant?.availableForSale
27
28
  }, [itemData.productVariant?.availableForSale])
28
29
 
30
+ const isLogin = useMemo(() => {
31
+ return !!profile
32
+ }, [profile])
33
+
29
34
  // Learn More 按钮点击 - 跳转到产品详情页
30
35
  const handleLearnMore = () => {
31
- window.location.href = `/products/${itemData.product.handle}`
36
+ const variantId = extractVariantId(itemData.productVariant?.id)
37
+ const url = variantId
38
+ ? `/products/${itemData.product.handle}?variant=${variantId}`
39
+ : `/products/${itemData.product.handle}`
40
+ window.location.href = url
32
41
  }
33
42
 
34
- // Shop Now 按钮点击 - 使用 buyNow 进行结算
43
+ // Shop Now 按钮点击 - 检查登录状态后使用 buyNow 进行结算
35
44
  const handleShopNow = () => {
45
+ // 如果未登录,弹出登录弹窗
46
+ if (!isLogin) {
47
+ openSignUpPopup()
48
+ return
49
+ }
50
+
51
+ // 已登录,执行购买
36
52
  buyNow({
37
53
  customAttributes: [
38
54
  {
@@ -52,7 +68,7 @@ function MemberPriceItem({
52
68
  return (
53
69
  <div
54
70
  className={cn(
55
- 'relative flex flex-col items-center bg-[#EAEAEC] p-[16px] md:rounded-[12px]',
71
+ 'relative flex flex-col items-center bg-[#EAEAEC] p-[24px] l:p-[8px] rounded-[16px] md-xl:p-[16px] md:rounded-[12px]',
56
72
  !rounded && 'rounded-none md:rounded-none',
57
73
  className
58
74
  )}
@@ -68,7 +84,14 @@ function MemberPriceItem({
68
84
  )}
69
85
 
70
86
  {/* 产品图片 - 优先使用产品的 metafields 透明图 */}
71
- <a href={`/products/${itemData.product.handle}`} className={cn('relative mx-auto size-[138px]')}>
87
+ <a
88
+ href={
89
+ extractVariantId(itemData.productVariant?.id)
90
+ ? `/products/${itemData.product.handle}?variant=${extractVariantId(itemData.productVariant?.id)}`
91
+ : `/products/${itemData.product.handle}`
92
+ }
93
+ className={cn('relative mx-auto size-[138px]')}
94
+ >
72
95
  <Picture
73
96
  className="mx-auto size-full"
74
97
  imgClassName="object-contain"
@@ -81,7 +104,7 @@ function MemberPriceItem({
81
104
  </a>
82
105
 
83
106
  {/* 产品信息 */}
84
- <div className={cn('mt-[4px] w-full')}>
107
+ <div className={cn('mt-[10px] xl:mt-[8px] w-full')}>
85
108
  {/* 产品标题 - 使用产品的真实标题 */}
86
109
  <Text
87
110
  html={itemData?.product?.title}
@@ -125,7 +148,7 @@ function MemberPriceItem({
125
148
  </div>
126
149
 
127
150
  {/* 按钮组 */}
128
- <div className="flex w-full gap-[8px] md:flex-col">
151
+ <div className="flex w-full gap-[8px] l:flex-col">
129
152
  {/* Learn More 按钮 */}
130
153
  <Button
131
154
  variant="secondary"
@@ -0,0 +1,113 @@
1
+ import { classNames as cn } from '@anker-in/lib'
2
+
3
+ interface PaginationProps {
4
+ currentPage: number
5
+ totalPages: number
6
+ onPageChange: (page: number) => void
7
+ }
8
+
9
+ export function Pagination({ currentPage, totalPages, onPageChange }: PaginationProps) {
10
+ if (totalPages <= 1) return null
11
+
12
+ // 计算要显示的页码
13
+ const getPageNumbers = () => {
14
+ const delta = 2 // 当前页前后显示的页码数量
15
+ const range = []
16
+ const rangeWithDots = []
17
+
18
+ for (let i = 1; i <= totalPages; i++) {
19
+ if (i === 1 || i === totalPages || (i >= currentPage - delta && i <= currentPage + delta)) {
20
+ range.push(i)
21
+ }
22
+ }
23
+
24
+ let prev = 0
25
+ for (const i of range) {
26
+ if (prev && i - prev > 1) {
27
+ rangeWithDots.push('...')
28
+ }
29
+ rangeWithDots.push(i)
30
+ prev = i
31
+ }
32
+
33
+ return rangeWithDots
34
+ }
35
+
36
+ const pages = getPageNumbers()
37
+
38
+ return (
39
+ <div className="mt-[32px] flex items-center justify-center gap-[8px]">
40
+ {/* 上一页按钮 */}
41
+ <button
42
+ onClick={() => onPageChange(Math.max(1, currentPage - 1))}
43
+ disabled={currentPage === 1}
44
+ className={cn(
45
+ 'flex size-[32px] xl:size-[24px] items-center justify-center overflow-hidden bg-white',
46
+ currentPage === 1 && 'cursor-not-allowed opacity-50'
47
+ )}
48
+ >
49
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
50
+ <path
51
+ d="M10 12L6 8L10 4"
52
+ stroke={currentPage === 1 ? '#767880' : '#080A0F'}
53
+ strokeWidth="1.5"
54
+ strokeLinecap="round"
55
+ strokeLinejoin="round"
56
+ />
57
+ </svg>
58
+ </button>
59
+
60
+ {/* 页码按钮 */}
61
+ {pages.map((page, index) => {
62
+ if (page === '...') {
63
+ return (
64
+ <div
65
+ key={`ellipsis-${index}`}
66
+ className="flex size-[32px] xl:size-[24px] items-center justify-center overflow-hidden bg-white"
67
+ >
68
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
69
+ <circle cx="4.5" cy="10" r="1.25" fill="#2A2C32" />
70
+ <circle cx="10" cy="10" r="1.25" fill="#2A2C32" />
71
+ <circle cx="15.5" cy="10" r="1.25" fill="#2A2C32" />
72
+ </svg>
73
+ </div>
74
+ )
75
+ }
76
+
77
+ const isActive = currentPage === page
78
+ return (
79
+ <button
80
+ key={page}
81
+ onClick={() => onPageChange(page as number)}
82
+ className={cn(
83
+ 'flex size-[32px] xl:size-[24px] pt-[4px] items-center justify-center overflow-hidden text-[16px] xl:text-[14px] font-bold leading-[1.4] tracking-[-0.28px]',
84
+ isActive ? 'bg-[#080a0f] text-white' : 'bg-white text-[#080a0f]'
85
+ )}
86
+ >
87
+ {page}
88
+ </button>
89
+ )
90
+ })}
91
+
92
+ {/* 下一页按钮 */}
93
+ <button
94
+ onClick={() => onPageChange(Math.min(totalPages, currentPage + 1))}
95
+ disabled={currentPage === totalPages}
96
+ className={cn(
97
+ 'flex size-[32px] xl:size-[24px] items-center justify-center overflow-hidden bg-white',
98
+ currentPage === totalPages && 'cursor-not-allowed opacity-50'
99
+ )}
100
+ >
101
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none">
102
+ <path
103
+ d="M6 4L10 8L6 12"
104
+ stroke={currentPage === totalPages ? '#767880' : '#080A0F'}
105
+ strokeWidth="1.5"
106
+ strokeLinecap="round"
107
+ strokeLinejoin="round"
108
+ />
109
+ </svg>
110
+ </button>
111
+ </div>
112
+ )
113
+ }