@akinon/projectzero 1.32.0 → 1.33.0

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 (506) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/app-template/.editorconfig +7 -0
  3. package/app-template/.env.example +9 -0
  4. package/app-template/.eslintignore +1 -0
  5. package/app-template/.eslintrc.js +31 -0
  6. package/app-template/.gitattributes +18 -0
  7. package/app-template/.husky/pre-commit +4 -0
  8. package/app-template/.lintstagedrc.js +12 -0
  9. package/app-template/.prettierrc +13 -0
  10. package/app-template/.releaserc.json +49 -0
  11. package/app-template/.stylelintrc.json +37 -0
  12. package/app-template/.vscode/extensions.json +11 -0
  13. package/app-template/.vscode/launch.json +29 -0
  14. package/app-template/.yarnrc +1 -0
  15. package/app-template/CHANGELOG.md +636 -0
  16. package/app-template/LICENSE +21 -0
  17. package/app-template/Procfile +1 -0
  18. package/app-template/README.md +29 -0
  19. package/app-template/akinon.json +28 -0
  20. package/app-template/bitbucket-pipelines.yml +54 -0
  21. package/app-template/build.sh +7 -0
  22. package/app-template/docs/CHANGELOG.md +85 -0
  23. package/app-template/docs/advanced-usage.md +43 -0
  24. package/app-template/docs/basic-setup.md +59 -0
  25. package/app-template/docs/data-fetching/client/account.md +1064 -0
  26. package/app-template/docs/data-fetching/client/address.md +805 -0
  27. package/app-template/docs/data-fetching/client/basket.md +107 -0
  28. package/app-template/docs/data-fetching/client/checkout.md +904 -0
  29. package/app-template/docs/data-fetching/client/misc.md +135 -0
  30. package/app-template/docs/data-fetching/client/product.md +284 -0
  31. package/app-template/docs/data-fetching/client/user.md +56 -0
  32. package/app-template/docs/data-fetching/client/wishlist.md +111 -0
  33. package/app-template/docs/data-fetching/server/category.md +324 -0
  34. package/app-template/docs/data-fetching/server/flat-page.md +42 -0
  35. package/app-template/docs/data-fetching/server/list.md +353 -0
  36. package/app-template/docs/data-fetching/server/menu.md +363 -0
  37. package/app-template/docs/data-fetching/server/product.md +131 -0
  38. package/app-template/docs/data-fetching/server/seo.md +44 -0
  39. package/app-template/docs/data-fetching/server/special-page.md +79 -0
  40. package/app-template/docs/data-fetching/server/widget.md +218 -0
  41. package/app-template/docs/delete-account.md +25 -0
  42. package/app-template/docs/deployment.md +46 -0
  43. package/app-template/docs/dynamic-route.md +33 -0
  44. package/app-template/docs/icons.md +52 -0
  45. package/app-template/docs/localization.md +204 -0
  46. package/app-template/docs/logging.md +48 -0
  47. package/app-template/docs/plugins.md +76 -0
  48. package/app-template/docs/seo-management.md +125 -0
  49. package/app-template/docs/static-assets.md +36 -0
  50. package/app-template/docs/widgets.md +127 -0
  51. package/app-template/global.d.ts +1 -0
  52. package/app-template/jest.config.ts +34 -0
  53. package/app-template/next-env.d.ts +6 -0
  54. package/app-template/next.config.mjs +34 -0
  55. package/app-template/package.json +97 -0
  56. package/app-template/plugins.d.ts +1 -0
  57. package/app-template/postcss.config.js +6 -0
  58. package/app-template/public/404.png +0 -0
  59. package/app-template/public/500.png +0 -0
  60. package/app-template/public/apple-splash-1125-2436.jpg +0 -0
  61. package/app-template/public/apple-splash-1136-640.jpg +0 -0
  62. package/app-template/public/apple-splash-1170-2532.jpg +0 -0
  63. package/app-template/public/apple-splash-1242-2208.jpg +0 -0
  64. package/app-template/public/apple-splash-1242-2688.jpg +0 -0
  65. package/app-template/public/apple-splash-1284-2778.jpg +0 -0
  66. package/app-template/public/apple-splash-1334-750.jpg +0 -0
  67. package/app-template/public/apple-splash-1536-2048.jpg +0 -0
  68. package/app-template/public/apple-splash-1620-2160.jpg +0 -0
  69. package/app-template/public/apple-splash-1668-2224.jpg +0 -0
  70. package/app-template/public/apple-splash-1668-2388.jpg +0 -0
  71. package/app-template/public/apple-splash-1792-828.jpg +0 -0
  72. package/app-template/public/apple-splash-2048-1536.jpg +0 -0
  73. package/app-template/public/apple-splash-2048-2732.jpg +0 -0
  74. package/app-template/public/apple-splash-2160-1620.jpg +0 -0
  75. package/app-template/public/apple-splash-2208-1242.jpg +0 -0
  76. package/app-template/public/apple-splash-2224-1668.jpg +0 -0
  77. package/app-template/public/apple-splash-2388-1668.jpg +0 -0
  78. package/app-template/public/apple-splash-2436-1125.jpg +0 -0
  79. package/app-template/public/apple-splash-2532-1170.jpg +0 -0
  80. package/app-template/public/apple-splash-2688-1242.jpg +0 -0
  81. package/app-template/public/apple-splash-2732-2048.jpg +0 -0
  82. package/app-template/public/apple-splash-2778-1284.jpg +0 -0
  83. package/app-template/public/apple-splash-640-1136.jpg +0 -0
  84. package/app-template/public/apple-splash-750-1334.jpg +0 -0
  85. package/app-template/public/apple-splash-828-1792.jpg +0 -0
  86. package/app-template/public/apple-touch-icon-152x152.png +0 -0
  87. package/app-template/public/apple-touch-icon-167x167.png +0 -0
  88. package/app-template/public/apple-touch-icon-180x180.png +0 -0
  89. package/app-template/public/apple-touch-icon.png +0 -0
  90. package/app-template/public/apple.svg +47 -0
  91. package/app-template/public/cvv.jpg +0 -0
  92. package/app-template/public/facebook.svg +3 -0
  93. package/app-template/public/google.svg +12 -0
  94. package/app-template/public/icon-192x192.png +0 -0
  95. package/app-template/public/icon-256x256.png +0 -0
  96. package/app-template/public/icon-384x384.png +0 -0
  97. package/app-template/public/icon-512x512.png +0 -0
  98. package/app-template/public/icon-sprite.svg +528 -0
  99. package/app-template/public/locales/en/account.json +490 -0
  100. package/app-template/public/locales/en/auth.json +100 -0
  101. package/app-template/public/locales/en/basket.json +50 -0
  102. package/app-template/public/locales/en/category.json +26 -0
  103. package/app-template/public/locales/en/checkout.json +152 -0
  104. package/app-template/public/locales/en/common.json +65 -0
  105. package/app-template/public/locales/en/forgot_password.json +41 -0
  106. package/app-template/public/locales/en/form.json +5 -0
  107. package/app-template/public/locales/en/product.json +39 -0
  108. package/app-template/public/locales/tr/account.json +490 -0
  109. package/app-template/public/locales/tr/auth.json +100 -0
  110. package/app-template/public/locales/tr/basket.json +50 -0
  111. package/app-template/public/locales/tr/category.json +26 -0
  112. package/app-template/public/locales/tr/checkout.json +152 -0
  113. package/app-template/public/locales/tr/common.json +65 -0
  114. package/app-template/public/locales/tr/forgot_password.json +41 -0
  115. package/app-template/public/locales/tr/form.json +5 -0
  116. package/app-template/public/locales/tr/product.json +39 -0
  117. package/app-template/public/logo.svg +29 -0
  118. package/app-template/public/manifest.json +35 -0
  119. package/app-template/public/mastercard.png +0 -0
  120. package/app-template/public/mastersecure.png +0 -0
  121. package/app-template/public/mfs-client.min.js +3 -0
  122. package/app-template/public/noimage.jpg +0 -0
  123. package/app-template/public/safari-pinned-tab.svg +320 -0
  124. package/app-template/public/ssl-secure.png +0 -0
  125. package/app-template/public/vbv.png +0 -0
  126. package/app-template/public/visa.png +0 -0
  127. package/app-template/public/zepto.min.js +2 -0
  128. package/app-template/sentry.client.config.ts +16 -0
  129. package/app-template/sentry.edge.config.ts +3 -0
  130. package/app-template/sentry.properties +4 -0
  131. package/app-template/sentry.server.config.ts +3 -0
  132. package/app-template/setupTests.ts +4 -0
  133. package/app-template/src/__tests__/index.test.tsx +7 -0
  134. package/app-template/src/__tests__/tsconfig.json +7 -0
  135. package/app-template/src/app/[commerce]/[locale]/[currency]/account/address/page.tsx +74 -0
  136. package/app-template/src/app/[commerce]/[locale]/[currency]/account/change-email/page.tsx +174 -0
  137. package/app-template/src/app/[commerce]/[locale]/[currency]/account/change-password/page.tsx +206 -0
  138. package/app-template/src/app/[commerce]/[locale]/[currency]/account/contact/page.tsx +7 -0
  139. package/app-template/src/app/[commerce]/[locale]/[currency]/account/coupons/page.tsx +210 -0
  140. package/app-template/src/app/[commerce]/[locale]/[currency]/account/email-verification/page.tsx +5 -0
  141. package/app-template/src/app/[commerce]/[locale]/[currency]/account/faq/page.tsx +23 -0
  142. package/app-template/src/app/[commerce]/[locale]/[currency]/account/favourite-products/page.tsx +32 -0
  143. package/app-template/src/app/[commerce]/[locale]/[currency]/account/layout.tsx +28 -0
  144. package/app-template/src/app/[commerce]/[locale]/[currency]/account/my-quotations/page.tsx +7 -0
  145. package/app-template/src/app/[commerce]/[locale]/[currency]/account/orders/[id]/cancellation/page.tsx +255 -0
  146. package/app-template/src/app/[commerce]/[locale]/[currency]/account/orders/[id]/layout.tsx +5 -0
  147. package/app-template/src/app/[commerce]/[locale]/[currency]/account/orders/[id]/page.tsx +309 -0
  148. package/app-template/src/app/[commerce]/[locale]/[currency]/account/orders/page.tsx +137 -0
  149. package/app-template/src/app/[commerce]/[locale]/[currency]/account/page.tsx +226 -0
  150. package/app-template/src/app/[commerce]/[locale]/[currency]/account/profile/page.tsx +399 -0
  151. package/app-template/src/app/[commerce]/[locale]/[currency]/address/stores/page.tsx +271 -0
  152. package/app-template/src/app/[commerce]/[locale]/[currency]/anonymous-tracking/page.tsx +33 -0
  153. package/app-template/src/app/[commerce]/[locale]/[currency]/auth/oauth-login/page.tsx +3 -0
  154. package/app-template/src/app/[commerce]/[locale]/[currency]/auth/page.tsx +76 -0
  155. package/app-template/src/app/[commerce]/[locale]/[currency]/basket/page.tsx +77 -0
  156. package/app-template/src/app/[commerce]/[locale]/[currency]/basket-b2b/page.tsx +7 -0
  157. package/app-template/src/app/[commerce]/[locale]/[currency]/category/[pk]/loading.tsx +53 -0
  158. package/app-template/src/app/[commerce]/[locale]/[currency]/category/[pk]/page.tsx +16 -0
  159. package/app-template/src/app/[commerce]/[locale]/[currency]/client-root.tsx +9 -0
  160. package/app-template/src/app/[commerce]/[locale]/[currency]/contact-us/page.tsx +11 -0
  161. package/app-template/src/app/[commerce]/[locale]/[currency]/error.tsx +20 -0
  162. package/app-template/src/app/[commerce]/[locale]/[currency]/flat-page/[pk]/loading.tsx +5 -0
  163. package/app-template/src/app/[commerce]/[locale]/[currency]/flat-page/[pk]/page.tsx +18 -0
  164. package/app-template/src/app/[commerce]/[locale]/[currency]/forms/[pk]/generate/page.tsx +48 -0
  165. package/app-template/src/app/[commerce]/[locale]/[currency]/group-product/[pk]/loading.tsx +5 -0
  166. package/app-template/src/app/[commerce]/[locale]/[currency]/group-product/[pk]/page.tsx +72 -0
  167. package/app-template/src/app/[commerce]/[locale]/[currency]/landing-page/[pk]/loading.tsx +5 -0
  168. package/app-template/src/app/[commerce]/[locale]/[currency]/landing-page/[pk]/page.tsx +23 -0
  169. package/app-template/src/app/[commerce]/[locale]/[currency]/layout.tsx +78 -0
  170. package/app-template/src/app/[commerce]/[locale]/[currency]/list/loading.tsx +53 -0
  171. package/app-template/src/app/[commerce]/[locale]/[currency]/list/page.tsx +16 -0
  172. package/app-template/src/app/[commerce]/[locale]/[currency]/orders/checkout/page.tsx +140 -0
  173. package/app-template/src/app/[commerce]/[locale]/[currency]/orders/completed/[token]/layout.tsx +5 -0
  174. package/app-template/src/app/[commerce]/[locale]/[currency]/orders/completed/[token]/page.tsx +284 -0
  175. package/app-template/src/app/[commerce]/[locale]/[currency]/page.tsx +50 -0
  176. package/app-template/src/app/[commerce]/[locale]/[currency]/product/[pk]/loading.tsx +67 -0
  177. package/app-template/src/app/[commerce]/[locale]/[currency]/product/[pk]/page.tsx +81 -0
  178. package/app-template/src/app/[commerce]/[locale]/[currency]/special-page/[pk]/loading.tsx +53 -0
  179. package/app-template/src/app/[commerce]/[locale]/[currency]/special-page/[pk]/page.tsx +25 -0
  180. package/app-template/src/app/[commerce]/[locale]/[currency]/template.tsx +75 -0
  181. package/app-template/src/app/[commerce]/[locale]/[currency]/users/email-set-primary/[[...id]]/page.tsx +43 -0
  182. package/app-template/src/app/[commerce]/[locale]/[currency]/users/password/reset/page.tsx +79 -0
  183. package/app-template/src/app/[commerce]/[locale]/[currency]/users/registration/account-confirm-email/[[...id]]/page.tsx +43 -0
  184. package/app-template/src/app/[commerce]/[locale]/[currency]/users/reset/[[...id]]/page.tsx +110 -0
  185. package/app-template/src/app/[commerce]/[locale]/[currency]/xml-sitemap/[node]/route.ts +25 -0
  186. package/app-template/src/app/[commerce]/[locale]/[currency]/xml-sitemap/route.ts +37 -0
  187. package/app-template/src/app/api/cache/route.ts +1 -0
  188. package/app-template/src/app/api/client/[...slug]/route.ts +1 -0
  189. package/app-template/src/app/api/form/[...id]/route.ts +7 -0
  190. package/app-template/src/app/api/logout/route.ts +1 -0
  191. package/app-template/src/app/api/sentry/route.ts +9 -0
  192. package/app-template/src/app/api/web-vitals/route.ts +1 -0
  193. package/app-template/src/app/favicon.ico +0 -0
  194. package/app-template/src/assets/fonts/Jost/Jost-Black.eot +0 -0
  195. package/app-template/src/assets/fonts/Jost/Jost-Black.ttf +0 -0
  196. package/app-template/src/assets/fonts/Jost/Jost-Black.woff +0 -0
  197. package/app-template/src/assets/fonts/Jost/Jost-Black.woff2 +0 -0
  198. package/app-template/src/assets/fonts/Jost/Jost-BlackItalic.eot +0 -0
  199. package/app-template/src/assets/fonts/Jost/Jost-BlackItalic.ttf +0 -0
  200. package/app-template/src/assets/fonts/Jost/Jost-BlackItalic.woff +0 -0
  201. package/app-template/src/assets/fonts/Jost/Jost-BlackItalic.woff2 +0 -0
  202. package/app-template/src/assets/fonts/Jost/Jost-Bold.eot +0 -0
  203. package/app-template/src/assets/fonts/Jost/Jost-Bold.ttf +0 -0
  204. package/app-template/src/assets/fonts/Jost/Jost-Bold.woff +0 -0
  205. package/app-template/src/assets/fonts/Jost/Jost-Bold.woff2 +0 -0
  206. package/app-template/src/assets/fonts/Jost/Jost-BoldItalic.eot +0 -0
  207. package/app-template/src/assets/fonts/Jost/Jost-BoldItalic.ttf +0 -0
  208. package/app-template/src/assets/fonts/Jost/Jost-BoldItalic.woff +0 -0
  209. package/app-template/src/assets/fonts/Jost/Jost-BoldItalic.woff2 +0 -0
  210. package/app-template/src/assets/fonts/Jost/Jost-ExtraBold.eot +0 -0
  211. package/app-template/src/assets/fonts/Jost/Jost-ExtraBold.ttf +0 -0
  212. package/app-template/src/assets/fonts/Jost/Jost-ExtraBold.woff +0 -0
  213. package/app-template/src/assets/fonts/Jost/Jost-ExtraBold.woff2 +0 -0
  214. package/app-template/src/assets/fonts/Jost/Jost-ExtraBoldItalic.eot +0 -0
  215. package/app-template/src/assets/fonts/Jost/Jost-ExtraBoldItalic.ttf +0 -0
  216. package/app-template/src/assets/fonts/Jost/Jost-ExtraBoldItalic.woff +0 -0
  217. package/app-template/src/assets/fonts/Jost/Jost-ExtraBoldItalic.woff2 +0 -0
  218. package/app-template/src/assets/fonts/Jost/Jost-ExtraLight.eot +0 -0
  219. package/app-template/src/assets/fonts/Jost/Jost-ExtraLight.ttf +0 -0
  220. package/app-template/src/assets/fonts/Jost/Jost-ExtraLight.woff +0 -0
  221. package/app-template/src/assets/fonts/Jost/Jost-ExtraLight.woff2 +0 -0
  222. package/app-template/src/assets/fonts/Jost/Jost-ExtraLightItalic.eot +0 -0
  223. package/app-template/src/assets/fonts/Jost/Jost-ExtraLightItalic.ttf +0 -0
  224. package/app-template/src/assets/fonts/Jost/Jost-ExtraLightItalic.woff +0 -0
  225. package/app-template/src/assets/fonts/Jost/Jost-ExtraLightItalic.woff2 +0 -0
  226. package/app-template/src/assets/fonts/Jost/Jost-Italic.eot +0 -0
  227. package/app-template/src/assets/fonts/Jost/Jost-Italic.ttf +0 -0
  228. package/app-template/src/assets/fonts/Jost/Jost-Italic.woff +0 -0
  229. package/app-template/src/assets/fonts/Jost/Jost-Italic.woff2 +0 -0
  230. package/app-template/src/assets/fonts/Jost/Jost-Light.eot +0 -0
  231. package/app-template/src/assets/fonts/Jost/Jost-Light.ttf +0 -0
  232. package/app-template/src/assets/fonts/Jost/Jost-Light.woff +0 -0
  233. package/app-template/src/assets/fonts/Jost/Jost-Light.woff2 +0 -0
  234. package/app-template/src/assets/fonts/Jost/Jost-LightItalic.eot +0 -0
  235. package/app-template/src/assets/fonts/Jost/Jost-LightItalic.ttf +0 -0
  236. package/app-template/src/assets/fonts/Jost/Jost-LightItalic.woff +0 -0
  237. package/app-template/src/assets/fonts/Jost/Jost-LightItalic.woff2 +0 -0
  238. package/app-template/src/assets/fonts/Jost/Jost-Medium.eot +0 -0
  239. package/app-template/src/assets/fonts/Jost/Jost-Medium.ttf +0 -0
  240. package/app-template/src/assets/fonts/Jost/Jost-Medium.woff +0 -0
  241. package/app-template/src/assets/fonts/Jost/Jost-Medium.woff2 +0 -0
  242. package/app-template/src/assets/fonts/Jost/Jost-MediumItalic.eot +0 -0
  243. package/app-template/src/assets/fonts/Jost/Jost-MediumItalic.ttf +0 -0
  244. package/app-template/src/assets/fonts/Jost/Jost-MediumItalic.woff +0 -0
  245. package/app-template/src/assets/fonts/Jost/Jost-MediumItalic.woff2 +0 -0
  246. package/app-template/src/assets/fonts/Jost/Jost-Regular.eot +0 -0
  247. package/app-template/src/assets/fonts/Jost/Jost-Regular.ttf +0 -0
  248. package/app-template/src/assets/fonts/Jost/Jost-Regular.woff +0 -0
  249. package/app-template/src/assets/fonts/Jost/Jost-Regular.woff2 +0 -0
  250. package/app-template/src/assets/fonts/Jost/Jost-SemiBold.eot +0 -0
  251. package/app-template/src/assets/fonts/Jost/Jost-SemiBold.ttf +0 -0
  252. package/app-template/src/assets/fonts/Jost/Jost-SemiBold.woff +0 -0
  253. package/app-template/src/assets/fonts/Jost/Jost-SemiBold.woff2 +0 -0
  254. package/app-template/src/assets/fonts/Jost/Jost-SemiBoldItalic.eot +0 -0
  255. package/app-template/src/assets/fonts/Jost/Jost-SemiBoldItalic.ttf +0 -0
  256. package/app-template/src/assets/fonts/Jost/Jost-SemiBoldItalic.woff +0 -0
  257. package/app-template/src/assets/fonts/Jost/Jost-SemiBoldItalic.woff2 +0 -0
  258. package/app-template/src/assets/fonts/Jost/Jost-Thin.eot +0 -0
  259. package/app-template/src/assets/fonts/Jost/Jost-Thin.ttf +0 -0
  260. package/app-template/src/assets/fonts/Jost/Jost-Thin.woff +0 -0
  261. package/app-template/src/assets/fonts/Jost/Jost-Thin.woff2 +0 -0
  262. package/app-template/src/assets/fonts/Jost/Jost-ThinItalic.eot +0 -0
  263. package/app-template/src/assets/fonts/Jost/Jost-ThinItalic.ttf +0 -0
  264. package/app-template/src/assets/fonts/Jost/Jost-ThinItalic.woff +0 -0
  265. package/app-template/src/assets/fonts/Jost/Jost-ThinItalic.woff2 +0 -0
  266. package/app-template/src/assets/fonts/Jost/index.scss +269 -0
  267. package/app-template/src/assets/fonts/index.scss +1 -0
  268. package/app-template/src/assets/fonts/pz-icon.css +154 -0
  269. package/app-template/src/assets/fonts/pz-icon.eot +0 -0
  270. package/app-template/src/assets/fonts/pz-icon.html +456 -0
  271. package/app-template/src/assets/fonts/pz-icon.scss +300 -0
  272. package/app-template/src/assets/fonts/pz-icon.svg +144 -0
  273. package/app-template/src/assets/fonts/pz-icon.ttf +0 -0
  274. package/app-template/src/assets/fonts/pz-icon.woff +0 -0
  275. package/app-template/src/assets/fonts/pz-icon.woff2 +0 -0
  276. package/app-template/src/assets/globals.scss +65 -0
  277. package/app-template/src/assets/icons/akinon.svg +11 -0
  278. package/app-template/src/assets/icons/arrow-up.svg +11 -0
  279. package/app-template/src/assets/icons/bell.svg +1 -0
  280. package/app-template/src/assets/icons/cart.svg +13 -0
  281. package/app-template/src/assets/icons/check.svg +19 -0
  282. package/app-template/src/assets/icons/chevron-down.svg +8 -0
  283. package/app-template/src/assets/icons/chevron-end.svg +8 -0
  284. package/app-template/src/assets/icons/chevron-start.svg +8 -0
  285. package/app-template/src/assets/icons/chevron-up.svg +8 -0
  286. package/app-template/src/assets/icons/close.svg +12 -0
  287. package/app-template/src/assets/icons/cvc.svg +54 -0
  288. package/app-template/src/assets/icons/default.svg +6 -0
  289. package/app-template/src/assets/icons/directions.svg +14 -0
  290. package/app-template/src/assets/icons/eye-off.svg +10 -0
  291. package/app-template/src/assets/icons/eye-on.svg +17 -0
  292. package/app-template/src/assets/icons/facebook-login.svg +11 -0
  293. package/app-template/src/assets/icons/facebook.svg +9 -0
  294. package/app-template/src/assets/icons/giftbox.svg +22 -0
  295. package/app-template/src/assets/icons/globe.svg +12 -0
  296. package/app-template/src/assets/icons/google-login.svg +19 -0
  297. package/app-template/src/assets/icons/google.svg +9 -0
  298. package/app-template/src/assets/icons/hamburger.svg +5 -0
  299. package/app-template/src/assets/icons/heart-full.svg +20 -0
  300. package/app-template/src/assets/icons/heart-stroke.svg +22 -0
  301. package/app-template/src/assets/icons/info.svg +1 -0
  302. package/app-template/src/assets/icons/instagram.svg +14 -0
  303. package/app-template/src/assets/icons/layout-2.svg +7 -0
  304. package/app-template/src/assets/icons/layout-3.svg +4 -0
  305. package/app-template/src/assets/icons/logo.svg +24 -0
  306. package/app-template/src/assets/icons/mail.svg +1 -0
  307. package/app-template/src/assets/icons/minus.svg +4 -0
  308. package/app-template/src/assets/icons/money.svg +4 -0
  309. package/app-template/src/assets/icons/mp-otp.svg +1 -0
  310. package/app-template/src/assets/icons/pin.svg +16 -0
  311. package/app-template/src/assets/icons/pinterest.svg +12 -0
  312. package/app-template/src/assets/icons/plus.svg +5 -0
  313. package/app-template/src/assets/icons/search.svg +13 -0
  314. package/app-template/src/assets/icons/share.svg +10 -0
  315. package/app-template/src/assets/icons/spinner.svg +6 -0
  316. package/app-template/src/assets/icons/store-pin.svg +14 -0
  317. package/app-template/src/assets/icons/track-order.svg +1 -0
  318. package/app-template/src/assets/icons/twitter.svg +11 -0
  319. package/app-template/src/assets/icons/user.svg +14 -0
  320. package/app-template/src/assets/icons/whatsapp.svg +45 -0
  321. package/app-template/src/components/__tests__/Modal.test.tsx +103 -0
  322. package/app-template/src/components/__tests__/accordion.test.tsx +65 -0
  323. package/app-template/src/components/__tests__/badge.test.tsx +20 -0
  324. package/app-template/src/components/__tests__/button.test.tsx +59 -0
  325. package/app-template/src/components/__tests__/checkbox.test.tsx +57 -0
  326. package/app-template/src/components/__tests__/file-input.test.tsx +42 -0
  327. package/app-template/src/components/__tests__/icon.test.tsx +39 -0
  328. package/app-template/src/components/__tests__/input.test.tsx +69 -0
  329. package/app-template/src/components/__tests__/language-select.test.tsx +81 -0
  330. package/app-template/src/components/__tests__/link.test.tsx +65 -0
  331. package/app-template/src/components/__tests__/price.test.tsx +72 -0
  332. package/app-template/src/components/__tests__/radio.test.tsx +52 -0
  333. package/app-template/src/components/__tests__/select.test.tsx +115 -0
  334. package/app-template/src/components/__tests__/tab.test.tsx +101 -0
  335. package/app-template/src/components/accordion.tsx +64 -0
  336. package/app-template/src/components/badge.tsx +21 -0
  337. package/app-template/src/components/button.tsx +46 -0
  338. package/app-template/src/components/canonical-url.tsx +21 -0
  339. package/app-template/src/components/carousel-core.tsx +42 -0
  340. package/app-template/src/components/checkbox.tsx +28 -0
  341. package/app-template/src/components/currency-select.tsx +81 -0
  342. package/app-template/src/components/custom-loader.tsx +21 -0
  343. package/app-template/src/components/dynamic-form.tsx +17 -0
  344. package/app-template/src/components/file-input.tsx +8 -0
  345. package/app-template/src/components/generate-form-fields.tsx +349 -0
  346. package/app-template/src/components/icon.tsx +18 -0
  347. package/app-template/src/components/index.ts +41 -0
  348. package/app-template/src/components/input.tsx +110 -0
  349. package/app-template/src/components/language-select.tsx +33 -0
  350. package/app-template/src/components/link.tsx +53 -0
  351. package/app-template/src/components/loader-spinner.tsx +23 -0
  352. package/app-template/src/components/modal.tsx +66 -0
  353. package/app-template/src/components/pagination.tsx +267 -0
  354. package/app-template/src/components/password-rules-feedback.tsx +60 -0
  355. package/app-template/src/components/price.tsx +54 -0
  356. package/app-template/src/components/pwa-tags.tsx +233 -0
  357. package/app-template/src/components/radio.tsx +18 -0
  358. package/app-template/src/components/react-portal.tsx +47 -0
  359. package/app-template/src/components/select.tsx +70 -0
  360. package/app-template/src/components/shimmer.tsx +21 -0
  361. package/app-template/src/components/skeleton-article.tsx +15 -0
  362. package/app-template/src/components/skeleton-product.tsx +14 -0
  363. package/app-template/src/components/skeleton-profile.tsx +19 -0
  364. package/app-template/src/components/skeleton-wrapper.tsx +19 -0
  365. package/app-template/src/components/skeleton.tsx +37 -0
  366. package/app-template/src/components/source.tsx +12 -0
  367. package/app-template/src/components/tab-panel.tsx +10 -0
  368. package/app-template/src/components/tab.tsx +58 -0
  369. package/app-template/src/components/tabs.tsx +58 -0
  370. package/app-template/src/components/types/index.ts +89 -0
  371. package/app-template/src/hooks/index.ts +1 -0
  372. package/app-template/src/hooks/use-add-product-to-basket.ts +48 -0
  373. package/app-template/src/hooks/use-contract.tsx +58 -0
  374. package/app-template/src/hooks/use-fav-button.tsx +99 -0
  375. package/app-template/src/instrumentation.ts +1 -0
  376. package/app-template/src/middleware.ts +33 -0
  377. package/app-template/src/pages/_error.js +14 -0
  378. package/app-template/src/pages/api/auth/[...nextauth].ts +3 -0
  379. package/app-template/src/plugins.js +14 -0
  380. package/app-template/src/redux/middlewares/category.ts +42 -0
  381. package/app-template/src/redux/reducers/category.ts +67 -0
  382. package/app-template/src/redux/store.ts +47 -0
  383. package/app-template/src/routes/index.ts +46 -0
  384. package/app-template/src/settings.js +62 -0
  385. package/app-template/src/theme.js +1 -0
  386. package/app-template/src/types/index.ts +72 -0
  387. package/app-template/src/types/next-auth.d.ts +24 -0
  388. package/app-template/src/types/widgets.ts +115 -0
  389. package/app-template/src/utils/convert-facet-search-params.ts +15 -0
  390. package/app-template/src/utils/generate-jsonld.ts +23 -0
  391. package/app-template/src/utils/gtm.ts +247 -0
  392. package/app-template/src/utils/index.ts +60 -0
  393. package/app-template/src/views/account/account-menu.tsx +117 -0
  394. package/app-template/src/views/account/address-card.tsx +157 -0
  395. package/app-template/src/views/account/address-form.tsx +374 -0
  396. package/app-template/src/views/account/back-button.tsx +27 -0
  397. package/app-template/src/views/account/contact-form.tsx +283 -0
  398. package/app-template/src/views/account/content-header.tsx +52 -0
  399. package/app-template/src/views/account/faq/faq-footer.tsx +30 -0
  400. package/app-template/src/views/account/faq/faq-search.tsx +35 -0
  401. package/app-template/src/views/account/faq/faq-tabs.tsx +54 -0
  402. package/app-template/src/views/account/faq/index.ts +3 -0
  403. package/app-template/src/views/account/favorite-item.tsx +191 -0
  404. package/app-template/src/views/account/favourite-products/favourite-products-list.tsx +65 -0
  405. package/app-template/src/views/account/index.ts +4 -0
  406. package/app-template/src/views/account/order.tsx +89 -0
  407. package/app-template/src/views/account/orders/order-cancellation-item.tsx +99 -0
  408. package/app-template/src/views/account/orders/order-detail-header.tsx +39 -0
  409. package/app-template/src/views/anonymous-tracking/index.tsx +109 -0
  410. package/app-template/src/views/anonymous-tracking/order-detail/index.tsx +318 -0
  411. package/app-template/src/views/basket/basket-item.tsx +231 -0
  412. package/app-template/src/views/basket/index.ts +2 -0
  413. package/app-template/src/views/basket/summary.tsx +220 -0
  414. package/app-template/src/views/breadcrumb.tsx +35 -0
  415. package/app-template/src/views/category/category-active-filters.tsx +98 -0
  416. package/app-template/src/views/category/category-banner.tsx +34 -0
  417. package/app-template/src/views/category/category-header.tsx +143 -0
  418. package/app-template/src/views/category/category-info.tsx +123 -0
  419. package/app-template/src/views/category/filters/index.tsx +163 -0
  420. package/app-template/src/views/category/filters/size-filter.tsx +27 -0
  421. package/app-template/src/views/category/layout.tsx +38 -0
  422. package/app-template/src/views/checkout/auth.tsx +54 -0
  423. package/app-template/src/views/checkout/index.tsx +3 -0
  424. package/app-template/src/views/checkout/layout/footer.tsx +48 -0
  425. package/app-template/src/views/checkout/layout/header.tsx +38 -0
  426. package/app-template/src/views/checkout/step-button.tsx +69 -0
  427. package/app-template/src/views/checkout/step-list.tsx +51 -0
  428. package/app-template/src/views/checkout/steps/payment/agreements.tsx +42 -0
  429. package/app-template/src/views/checkout/steps/payment/index.tsx +31 -0
  430. package/app-template/src/views/checkout/steps/payment/options/credit-card/index.tsx +382 -0
  431. package/app-template/src/views/checkout/steps/payment/options/credit-card/installments.tsx +100 -0
  432. package/app-template/src/views/checkout/steps/payment/options/credit-payment.tsx +14 -0
  433. package/app-template/src/views/checkout/steps/payment/options/funds-transfer.tsx +174 -0
  434. package/app-template/src/views/checkout/steps/payment/options/loyalty.tsx +19 -0
  435. package/app-template/src/views/checkout/steps/payment/options/pay-on-delivery.tsx +15 -0
  436. package/app-template/src/views/checkout/steps/payment/options/redirection.tsx +94 -0
  437. package/app-template/src/views/checkout/steps/payment/payment-header.tsx +17 -0
  438. package/app-template/src/views/checkout/steps/payment/payment-option-buttons.tsx +73 -0
  439. package/app-template/src/views/checkout/steps/shipping/address-box.tsx +244 -0
  440. package/app-template/src/views/checkout/steps/shipping/addresses.tsx +189 -0
  441. package/app-template/src/views/checkout/steps/shipping/index.tsx +27 -0
  442. package/app-template/src/views/checkout/steps/shipping/shipping-options.tsx +72 -0
  443. package/app-template/src/views/checkout/summary.tsx +181 -0
  444. package/app-template/src/views/coupon-item/index.tsx +80 -0
  445. package/app-template/src/views/find-in-store/index.tsx +183 -0
  446. package/app-template/src/views/footer.tsx +21 -0
  447. package/app-template/src/views/guest-login/index.tsx +130 -0
  448. package/app-template/src/views/header/action-menu.tsx +117 -0
  449. package/app-template/src/views/header/band.tsx +32 -0
  450. package/app-template/src/views/header/index.tsx +66 -0
  451. package/app-template/src/views/header/mini-basket.tsx +267 -0
  452. package/app-template/src/views/header/mobile-hamburger-button.tsx +35 -0
  453. package/app-template/src/views/header/mobile-menu.tsx +144 -0
  454. package/app-template/src/views/header/navbar.tsx +186 -0
  455. package/app-template/src/views/header/pwa-back-button.tsx +60 -0
  456. package/app-template/src/views/header/search/index.tsx +82 -0
  457. package/app-template/src/views/header/search/results.tsx +123 -0
  458. package/app-template/src/views/header/user-menu.tsx +72 -0
  459. package/app-template/src/views/index.tsx +2 -0
  460. package/app-template/src/views/installment-options/index.tsx +127 -0
  461. package/app-template/src/views/login/index.tsx +233 -0
  462. package/app-template/src/views/otp-login/index.tsx +152 -0
  463. package/app-template/src/views/page-loader-spinner/index.tsx +9 -0
  464. package/app-template/src/views/product/accordion-wrapper.tsx +59 -0
  465. package/app-template/src/views/product/combine-product-card.tsx +82 -0
  466. package/app-template/src/views/product/index.ts +8 -0
  467. package/app-template/src/views/product/layout.tsx +40 -0
  468. package/app-template/src/views/product/misc-buttons.tsx +65 -0
  469. package/app-template/src/views/product/price-wrapper.tsx +41 -0
  470. package/app-template/src/views/product/product-group-info.tsx +63 -0
  471. package/app-template/src/views/product/product-info.tsx +273 -0
  472. package/app-template/src/views/product/slider.tsx +124 -0
  473. package/app-template/src/views/product/variant.tsx +104 -0
  474. package/app-template/src/views/product-item/index.tsx +96 -0
  475. package/app-template/src/views/product-pointer-banner-item.tsx +243 -0
  476. package/app-template/src/views/register/index.tsx +417 -0
  477. package/app-template/src/views/root-modal.tsx +21 -0
  478. package/app-template/src/views/sales-contract-modal/index.tsx +288 -0
  479. package/app-template/src/views/share/index.tsx +71 -0
  480. package/app-template/src/views/widgets/home-hero-slider-content.tsx +54 -0
  481. package/app-template/src/views/widgets/recommendation-content.tsx +86 -0
  482. package/app-template/src/widgets/footer-copyright.tsx +25 -0
  483. package/app-template/src/widgets/footer-info.tsx +78 -0
  484. package/app-template/src/widgets/footer-menu.tsx +258 -0
  485. package/app-template/src/widgets/footer-social.tsx +53 -0
  486. package/app-template/src/widgets/footer-subscription/footer-subscription-form.tsx +110 -0
  487. package/app-template/src/widgets/footer-subscription/index.tsx +30 -0
  488. package/app-template/src/widgets/header-band-text.tsx +21 -0
  489. package/app-template/src/widgets/home-discovery.tsx +191 -0
  490. package/app-template/src/widgets/home-hero-slider.tsx +36 -0
  491. package/app-template/src/widgets/home-product-recommendation.tsx +18 -0
  492. package/app-template/src/widgets/home-single-banner.tsx +87 -0
  493. package/app-template/src/widgets/home-stories-eng.tsx +112 -0
  494. package/app-template/src/widgets/index.ts +25 -0
  495. package/app-template/src/widgets/product-pointer-banners.tsx +35 -0
  496. package/app-template/src/widgets/special-page-banner.tsx +49 -0
  497. package/app-template/src/widgets/special-page-carousel.tsx +68 -0
  498. package/app-template/src/widgets/widget-order.tsx +1 -0
  499. package/app-template/tailwind.config.js +170 -0
  500. package/app-template/tsconfig.json +44 -0
  501. package/app-template/tsconfig.test.json +6 -0
  502. package/app-template/yarn.lock +11278 -0
  503. package/commands/create.ts +49 -118
  504. package/dist/commands/create.js +32 -68
  505. package/package.json +1 -1
  506. package/tsconfig.json +9 -8
@@ -0,0 +1,243 @@
1
+ 'use client';
2
+
3
+ import { useState, useEffect } from 'react';
4
+ import {
5
+ PointerComponentProduct,
6
+ PointerComponentProductItem
7
+ } from '@theme/types';
8
+ import clsx from 'clsx';
9
+
10
+ import { Button, Link } from '@theme/components';
11
+ import { useMediaQuery } from '@akinon/next/hooks';
12
+ import { Image } from '@akinon/next/components/image';
13
+ import { useInView } from 'react-intersection-observer';
14
+ import { pushViewPromotion, pushSelectPromotion } from '@theme/utils/gtm';
15
+
16
+ interface ProductPointerWidgetProps {
17
+ productItem?: PointerComponentProductItem;
18
+ productPointerItem?: PointerComponentProduct;
19
+ }
20
+
21
+ const ProductPointerWidget = (props: ProductPointerWidgetProps) => {
22
+ const { productItem, productPointerItem } = props;
23
+ const [viewed, setViewed] = useState(false);
24
+ const { ref, inView } = useInView();
25
+ const matches = useMediaQuery('(min-width: 768px)');
26
+ const [buttonStatus, setButtonStatus] = useState(true);
27
+ const [matchesStatus, setMatchesStatus] = useState(false);
28
+
29
+ const handleClick = () => {
30
+ setButtonStatus(!buttonStatus);
31
+ };
32
+
33
+ const generatePromotionPayload = (promotion) => {
34
+ return {
35
+ creative_name: promotion?.value.banner_title_text,
36
+ promotion_id: `promo_${promotion?.value?.url}`,
37
+ promotion_name: promotion?.value?.banner_title_text,
38
+ items: [
39
+ {
40
+ item_id: promotion?.value?.url,
41
+ item_name: promotion?.value?.banner_title_text,
42
+ price:
43
+ parseFloat(promotion?.value.reduced_price?.replace(',', '.')) || 0,
44
+ quantity: 1
45
+ }
46
+ ]
47
+ };
48
+ };
49
+
50
+ const handleSelectPromotion = (promotionType) => {
51
+ const promotion =
52
+ promotionType === 'pointerItem' ? productPointerItem : productItem;
53
+ if (promotion && promotion?.value?.url) {
54
+ pushSelectPromotion(generatePromotionPayload(promotion));
55
+ }
56
+ };
57
+
58
+ useEffect(() => {
59
+ if (inView && !viewed) {
60
+ setViewed(true);
61
+
62
+ const promotions = [productItem, productPointerItem].filter(Boolean);
63
+ promotions.forEach((promotion) => {
64
+ if (promotion?.value?.url) {
65
+ pushViewPromotion(generatePromotionPayload(promotion));
66
+ }
67
+ });
68
+ }
69
+ }, [productItem, productPointerItem, inView, viewed]);
70
+
71
+ useEffect(() => {
72
+ setMatchesStatus(matches);
73
+ }, [matches]);
74
+
75
+ return (
76
+ <div ref={ref} className="relative flex-1 mb-4 xl:mb-0">
77
+ <Link href={productPointerItem?.value?.url || '#'}>
78
+ <Image
79
+ src={productPointerItem?.kwargs?.value?.mobile_image?.url}
80
+ alt={productPointerItem?.value?.alt}
81
+ aspectRatio={1.3}
82
+ sizes="380px"
83
+ fill
84
+ className="block md:hidden"
85
+ />
86
+
87
+ <Image
88
+ src={productPointerItem?.kwargs?.value?.desktop_image?.url}
89
+ alt={productPointerItem?.value?.alt}
90
+ aspectRatio={1.3}
91
+ sizes="675px"
92
+ fill
93
+ className="hidden md:block"
94
+ />
95
+ </Link>
96
+ <div
97
+ className="absolute"
98
+ style={{
99
+ left: matchesStatus
100
+ ? `${productPointerItem?.value?.product_button_desktop_position_left}%`
101
+ : `${productPointerItem?.value?.product_button_mobile_position_left}%`,
102
+ top: matchesStatus
103
+ ? `${productPointerItem?.value?.product_button_desktop_position_top}%`
104
+ : `${productPointerItem?.value?.product_button_mobile_position_top}%`
105
+ }}
106
+ >
107
+ <div
108
+ className={clsx('absolute w-60 h-32 bg-white bottom-10 p-2 z-10', {
109
+ hidden: buttonStatus
110
+ })}
111
+ >
112
+ <div className="w-full h-full flex items-center gap-2 flex-shrink-0">
113
+ <Image
114
+ src={productItem?.kwargs?.value?.card_image?.url}
115
+ alt={productItem?.value?.alt}
116
+ width={110}
117
+ height={110}
118
+ />
119
+ <div className="flex flex-col h-full">
120
+ {productItem?.value?.banner_title_text && (
121
+ <div
122
+ className="text-md line-clamp-2 font-medium"
123
+ style={{
124
+ color: productItem?.value?.banner_title_color
125
+ }}
126
+ >
127
+ {productItem?.value?.banner_title_text}
128
+ </div>
129
+ )}
130
+ {productItem?.value.normal_price && (
131
+ <div className="text-sm line-through">
132
+ ₺ {productItem?.value?.normal_price}
133
+ </div>
134
+ )}
135
+
136
+ {productItem?.value?.reduced_price && (
137
+ <div className="text-sm mb-1.5">
138
+ ₺ {productItem?.value?.reduced_price}
139
+ </div>
140
+ )}
141
+
142
+ {productItem?.value?.banner_button_text && (
143
+ <Link
144
+ href={productItem?.value?.url || '#'}
145
+ onClick={() => handleSelectPromotion('item')}
146
+ >
147
+ <Button
148
+ appearance="filled"
149
+ style={{
150
+ backgroundColor:
151
+ productItem?.value?.banner_button_bg_color,
152
+ borderColor: productItem?.value?.banner_button_bg_color,
153
+ color: productItem?.value?.banner_button_text_color
154
+ }}
155
+ >
156
+ {productItem?.value?.banner_button_text}
157
+ </Button>
158
+ </Link>
159
+ )}
160
+ </div>
161
+ </div>
162
+ </div>
163
+
164
+ {productPointerItem?.value?.slider_banner_product_button ===
165
+ 'shown' && (
166
+ <div
167
+ className="relative flex items-center justify-center w-8 h-8 cursor-pointer z-10"
168
+ onClick={handleClick}
169
+ >
170
+ <div className="absolute animate-ping w-6 h-6 bg-white rounded-full"></div>
171
+ <div className="border-4 border-white w-6 h-6 bg-secondary rounded-full relative"></div>
172
+ </div>
173
+ )}
174
+ </div>
175
+
176
+ <div
177
+ className={clsx('absolute flex justify-center items-center flex-col', {
178
+ 'top-8 right-24':
179
+ productPointerItem?.value?.position_content_over_image ===
180
+ 'top-right',
181
+ 'top-8 left-24':
182
+ productPointerItem?.value?.position_content_over_image ===
183
+ 'top-left',
184
+ 'bottom-12 left-10':
185
+ productPointerItem?.value?.position_content_over_image ===
186
+ 'bottom-left',
187
+ 'bottom-12 right-10':
188
+ productPointerItem?.value?.position_content_over_image ===
189
+ 'bottom-right'
190
+ })}
191
+ >
192
+ {productPointerItem?.value?.banner_title_text && (
193
+ <div
194
+ className="text-base font-normal leading-tight mb-1.5"
195
+ style={{
196
+ color: productPointerItem?.value?.banner_title_color
197
+ }}
198
+ >
199
+ {productPointerItem?.value?.banner_title_text}
200
+ </div>
201
+ )}
202
+
203
+ <div
204
+ className="text-base font-normal leading-tight mb-1.5"
205
+ style={{
206
+ color: productPointerItem?.value?.banner_description_color
207
+ }}
208
+ >
209
+ {productPointerItem?.value?.normal_price && (
210
+ <span className="line-through font-light px-1">
211
+ ₺ {productPointerItem?.value?.normal_price}
212
+ </span>
213
+ )}
214
+ {productPointerItem?.value?.reduced_price && (
215
+ <span className="font-medium text-xl px-1">
216
+ ₺ {productPointerItem?.value?.reduced_price}
217
+ </span>
218
+ )}
219
+ </div>
220
+
221
+ {productPointerItem?.value?.banner_button_text && (
222
+ <div
223
+ className="text-base font-normal leading-tight flex w-full"
224
+ style={{
225
+ color: productPointerItem?.value?.banner_button_text_color,
226
+ backgroundColor: productPointerItem?.value?.banner_button_bg_color
227
+ }}
228
+ >
229
+ <Link
230
+ onClick={() => handleSelectPromotion('pointerItem')}
231
+ href={productPointerItem?.value?.url || '#'}
232
+ className="w-full flex justify-center py-2 text-sm"
233
+ >
234
+ {productPointerItem?.value?.banner_button_text}
235
+ </Link>
236
+ </div>
237
+ )}
238
+ </div>
239
+ </div>
240
+ );
241
+ };
242
+
243
+ export default ProductPointerWidget;
@@ -0,0 +1,417 @@
1
+ 'use client';
2
+
3
+ import { yupResolver } from '@hookform/resolvers/yup';
4
+ import clsx from 'clsx';
5
+ import { signIn, SignInOptions } from 'next-auth/react';
6
+ import { useState } from 'react';
7
+ import { SubmitHandler, useForm } from 'react-hook-form';
8
+ import { useAppDispatch, useAppSelector } from '@akinon/next/redux/hooks';
9
+ import { RegisterFormType } from '@theme/types';
10
+ import { Button, Checkbox, Icon, Input, Modal } from '@theme/components';
11
+ import * as yup from 'yup';
12
+ import { useCaptcha, useLocalization, useRouter } from '@akinon/next/hooks';
13
+ import { AuthError } from '@akinon/next/types';
14
+ import PluginModule, { Component } from '@akinon/next/components/plugin-module';
15
+ import PasswordRulesFeedback from '@theme/components/password-rules-feedback';
16
+ import { showPopup as showOtpPopup } from '@akinon/pz-otp/src/redux/reducer';
17
+
18
+ const registerFormSchema = (t) =>
19
+ yup.object().shape({
20
+ email: yup
21
+ .string()
22
+ .email(t('auth.register.form.error.email_valid'))
23
+ .required(t('auth.register.form.error.required')),
24
+ first_name: yup
25
+ .string()
26
+ .required(t('auth.register.form.error.required'))
27
+ .min(2, t('auth.register.form.error.name_min'))
28
+ .max(50, t('auth.register.form.error.name_max'))
29
+ .matches(
30
+ /^[a-zA-ZğüşöçıİĞÜŞÖÇ\s]+$/,
31
+ t('auth.register.form.error.name_match')
32
+ ),
33
+ last_name: yup
34
+ .string()
35
+ .required(t('auth.register.form.error.required'))
36
+ .min(2, t('auth.register.form.error.surname_min'))
37
+ .max(50, t('auth.register.form.error.surname_max'))
38
+ .matches(
39
+ /^[a-zA-ZğüşöçıİĞÜŞÖÇ\s]+$/,
40
+ t('auth.register.form.error.surname_match')
41
+ ),
42
+ password: yup
43
+ .string()
44
+ .required(t('auth.register.form.error.required'))
45
+ .matches(
46
+ /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^a-zA-Z\d]).{6,}$/,
47
+ t('auth.register.form.error.password_rule')
48
+ )
49
+ .max(50, t('auth.register.form.error.password_max')),
50
+ phone: yup
51
+ .string()
52
+ .transform((value: string) => value.replace(/_/g, '').replace(/ /g, ''))
53
+ .length(11, t('auth.register.form.error.phone_length'))
54
+ .required(t('auth.register.form.error.required')),
55
+ confirm: yup
56
+ .boolean()
57
+ .oneOf([true], t('auth.register.form.error.required')),
58
+ kvkk_confirm: yup
59
+ .boolean()
60
+ .oneOf([true], t('auth.register.form.error.required'))
61
+ });
62
+
63
+ export const Register = () => {
64
+ const { t, locale } = useLocalization();
65
+ const dispatch = useAppDispatch();
66
+ const [openModal, setOpenModal] = useState(false);
67
+ const otpPopupVisible = useAppSelector((state) => state.otp?.isPopupVisible);
68
+
69
+ const [contentModal, setContentModal] = useState({
70
+ title: undefined,
71
+ description: undefined
72
+ });
73
+
74
+ const STATIC_CONTENT = {
75
+ content_1: {
76
+ title: t('auth.register.form.agreements.membership.modal_title'),
77
+ description:
78
+ "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum"
79
+ },
80
+ content_2: {
81
+ title: t('auth.register.form.agreements.kvkk.modal_title'),
82
+ description:
83
+ "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of 'de Finibus Bonorum et Malorum' (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, 'Lorem ipsum dolor sit amet..', comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from 'de Finibus Bonorum et Malorum' by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham."
84
+ },
85
+ content_3: {
86
+ title: t('auth.register.form.agreements.email_communication.modal_title'),
87
+ description:
88
+ "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
89
+ },
90
+ content_4: {
91
+ title: t('auth.register.form.agreements.sms_communication.modal_title'),
92
+ description:
93
+ "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
94
+ }
95
+ };
96
+
97
+ const {
98
+ register,
99
+ handleSubmit,
100
+ control,
101
+ formState: { errors },
102
+ setError,
103
+ getValues,
104
+ watch
105
+ } = useForm<RegisterFormType>({
106
+ resolver: yupResolver(registerFormSchema(t))
107
+ });
108
+
109
+ const router = useRouter();
110
+ const passwordValue = watch('password', '');
111
+
112
+ const {
113
+ CaptchaView,
114
+ validated: captchaValidated,
115
+ isVisible: isCaptchaVisible,
116
+ validate: validateCaptcha
117
+ } = useCaptcha();
118
+
119
+ const [formError, setFormError] = useState(null);
120
+ const [showPassword, setShowPassword] = useState(false);
121
+ const { user_phone_format } = useAppSelector((state) => state.config);
122
+
123
+ const registerHandler: SubmitHandler<RegisterFormType> = async (data) => {
124
+ return await signIn('default', {
125
+ redirect: false,
126
+ callbackUrl: '/',
127
+ captchaValidated,
128
+ ...data
129
+ } as SignInOptions);
130
+ };
131
+
132
+ const onSubmit: SubmitHandler<RegisterFormType> = async (data) => {
133
+ const registerResponse = await registerHandler(data);
134
+
135
+ if (registerResponse.error === 'Captcha') {
136
+ if (await validateCaptcha()) {
137
+ onSubmit(data);
138
+ }
139
+
140
+ return;
141
+ }
142
+
143
+ if (registerResponse.error) {
144
+ const errors: AuthError[] = JSON.parse(registerResponse.error);
145
+
146
+ if (errors.find((error) => error.type === 'captcha')) {
147
+ if (await validateCaptcha()) {
148
+ onSubmit(data);
149
+ }
150
+
151
+ return;
152
+ } else if (errors.find((error) => error.type === 'otp')) {
153
+ if (showOtpPopup) {
154
+ dispatch(showOtpPopup());
155
+ }
156
+
157
+ return;
158
+ }
159
+
160
+ const fieldErrors = errors.find((error) => error.type === 'field_errors')
161
+ ?.data as { name: string; value: string[] }[];
162
+ const nonFieldErrors = errors.find(
163
+ (error) => error.type === 'non_field_errors'
164
+ )?.data as string[];
165
+
166
+ fieldErrors?.forEach((item) => {
167
+ setError(item.name as keyof RegisterFormType, {
168
+ type: 'custom',
169
+ message: item.value.join(', ')
170
+ });
171
+ });
172
+
173
+ if (nonFieldErrors?.length) {
174
+ setFormError(nonFieldErrors.join(', '));
175
+ }
176
+
177
+ return;
178
+ }
179
+
180
+ if (registerResponse.url) {
181
+ router.replace(registerResponse.url);
182
+ return;
183
+ }
184
+
185
+ router.push('/');
186
+ };
187
+
188
+ const modalChange = (e, content) => {
189
+ e.preventDefault(e);
190
+ setContentModal(content);
191
+ setOpenModal(true);
192
+ };
193
+
194
+ return (
195
+ <section className="w-full py-10 px-5 md:py-0 md:block md:px-8 md:mx-auto lg:px-16">
196
+ <Modal
197
+ title={contentModal.title}
198
+ portalId="portal-modal-container"
199
+ open={openModal}
200
+ setOpen={setOpenModal}
201
+ className="w-3/4 md:max-w-xl"
202
+ >
203
+ <div className="p-4 max-h-80 overflow-auto">
204
+ {contentModal.description}
205
+ </div>
206
+ </Modal>
207
+ {otpPopupVisible && (
208
+ <PluginModule
209
+ component={Component.Otp}
210
+ props={{
211
+ data: getValues(),
212
+ submitAction: registerHandler
213
+ }}
214
+ />
215
+ )}
216
+ <h2 className="mb-3 text-lg text-start text-black-800 font-light md:mb-9 md:text-2xl">
217
+ {t('auth.register.title')}
218
+ </h2>
219
+
220
+ <p className="mb-3 text-xs leading-4 text-primary-400">
221
+ {t('auth.register.subtitle')}
222
+ </p>
223
+
224
+ <form onSubmit={handleSubmit(onSubmit)} className="flex flex-col gap-4">
225
+ <input type="hidden" value="register" {...register('formType')} />
226
+ <input type="hidden" value={locale} {...register('locale')} />
227
+
228
+ <div className={clsx({ 'mb-4': errors.email })}>
229
+ <Input
230
+ labelStyle="floating"
231
+ label={t('auth.register.form.email.placeholder')}
232
+ className="h-14"
233
+ {...register('email')}
234
+ error={errors.email}
235
+ data-testid="register-email"
236
+ required
237
+ />
238
+ </div>
239
+
240
+ <div
241
+ className={clsx('lg:flex', {
242
+ 'mb-4': errors.first_name || errors.last_name
243
+ })}
244
+ >
245
+ <div className="w-full lg:pr-2">
246
+ <Input
247
+ labelStyle="floating"
248
+ label={t('auth.register.form.name.placeholder')}
249
+ className="block h-14"
250
+ {...register('first_name')}
251
+ error={errors.first_name}
252
+ data-testid="register-name"
253
+ required
254
+ />
255
+ </div>
256
+
257
+ <div className="w-full mt-4 lg:pl-2 lg:mt-0">
258
+ <Input
259
+ labelStyle="floating"
260
+ label={t('auth.register.form.surname.placeholder')}
261
+ className="block h-14"
262
+ {...register('last_name')}
263
+ error={errors.last_name}
264
+ data-testid="register-surname"
265
+ required
266
+ />
267
+ </div>
268
+ </div>
269
+
270
+ <div className={clsx('relative', { 'mb-4': errors.password })}>
271
+ <div className="relative">
272
+ <Input
273
+ labelStyle="floating"
274
+ label={t('auth.register.form.password.placeholder')}
275
+ className="h-14 pr-16"
276
+ type={showPassword ? 'text' : 'password'}
277
+ {...register('password')}
278
+ data-testid="register-password"
279
+ required
280
+ />
281
+ <Icon
282
+ size={25}
283
+ className="absolute h-full flex items-center top-0 right-4 cursor-pointer"
284
+ name={showPassword ? 'eye-on' : 'eye-off'}
285
+ onClick={() => setShowPassword(!showPassword)}
286
+ />
287
+ </div>
288
+
289
+ {errors.password && (
290
+ <span className="mt-1 text-sm text-error">
291
+ {errors.password.message}
292
+ </span>
293
+ )}
294
+
295
+ <PasswordRulesFeedback
296
+ password={passwordValue}
297
+ isVisible={errors?.password?.message ? true : false}
298
+ />
299
+ </div>
300
+
301
+ <div className={clsx({ 'mb-4': errors.phone })}>
302
+ <Input
303
+ labelStyle="floating"
304
+ label={t('auth.register.form.phone.placeholder')}
305
+ className="h-14"
306
+ format={user_phone_format.replace(/\9/g, '#')}
307
+ allowEmptyFormatting
308
+ mask="_"
309
+ control={control}
310
+ {...register('phone')}
311
+ error={errors.phone}
312
+ data-testid="register-phone"
313
+ required
314
+ />
315
+ </div>
316
+
317
+ <div className="text-sm text-black-400 md:text-xs">
318
+ <p className="mb-4">{t('auth.register.form.agreements.title')}:</p>
319
+
320
+ <Checkbox
321
+ className={clsx(errors.confirm ? 'mb-8' : 'mb-4')}
322
+ {...register('confirm')}
323
+ error={errors.confirm}
324
+ data-testid="register-agreement-1"
325
+ >
326
+ {t('auth.register.form.agreements.membership.label')}
327
+ <br />
328
+ <span className="cursor-pointer">
329
+ <b
330
+ onClick={(e) => {
331
+ modalChange(e, STATIC_CONTENT.content_1);
332
+ }}
333
+ >
334
+ <u>{t('auth.register.form.agreements.click_contract_text')}</u>
335
+ </b>
336
+ </span>
337
+ </Checkbox>
338
+
339
+ <Checkbox
340
+ className={clsx(errors.kvkk_confirm ? 'mb-8' : 'mb-4')}
341
+ {...register('kvkk_confirm')}
342
+ error={errors.kvkk_confirm}
343
+ data-testid="register-agreement-2"
344
+ >
345
+ {t('auth.register.form.agreements.kvkk.label')}
346
+ <br />
347
+ <span className="cursor-pointer">
348
+ <b
349
+ onClick={(e) => {
350
+ modalChange(e, STATIC_CONTENT.content_2);
351
+ }}
352
+ >
353
+ <u>{t('auth.register.form.agreements.read_approve')}</u>
354
+ </b>
355
+ </span>
356
+ </Checkbox>
357
+
358
+ <Checkbox
359
+ className="mb-4"
360
+ {...register('email_allowed')}
361
+ data-testid="register-agreement-3"
362
+ >
363
+ {t('auth.register.form.agreements.email_communication.label')}
364
+ <br />
365
+ <span className="cursor-pointer">
366
+ <b
367
+ onClick={(e) => {
368
+ modalChange(e, STATIC_CONTENT.content_3);
369
+ }}
370
+ >
371
+ <u>{t('auth.register.form.agreements.read_approve')}</u>
372
+ </b>
373
+ </span>
374
+ </Checkbox>
375
+
376
+ <Checkbox
377
+ className="mb-4"
378
+ {...register('sms_allowed')}
379
+ data-testid="register-agreement-4"
380
+ >
381
+ {t('auth.register.form.agreements.sms_communication.label')} <br />
382
+ <span className="cursor-pointer">
383
+ <b
384
+ onClick={(e) => {
385
+ modalChange(e, STATIC_CONTENT.content_4);
386
+ }}
387
+ >
388
+ <u>{t('auth.register.form.agreements.read_approve')}</u>
389
+ </b>
390
+ </span>
391
+ </Checkbox>
392
+ </div>
393
+
394
+ <label className="text-error mb-2 hidden"></label>
395
+
396
+ {formError && <p className="text-error text-xs">{formError}</p>}
397
+
398
+ <div className="flex justify-center">
399
+ <CaptchaView className="mb-5" data-testid="register-captcha" />
400
+ </div>
401
+
402
+ <Button
403
+ className="text-xs font-semibold uppercase w-full h-14"
404
+ type="submit"
405
+ disabled={isCaptchaVisible && !captchaValidated}
406
+ data-testid="register-submit"
407
+ >
408
+ {t('auth.register.form.submit')}
409
+ </Button>
410
+
411
+ <p className="text-xs text-gray-600 italic mt-3">
412
+ {t('auth.register.form.mandatory_fields')}
413
+ </p>
414
+ </form>
415
+ </section>
416
+ );
417
+ };
@@ -0,0 +1,21 @@
1
+ 'use client';
2
+
3
+ import { Modal } from '@theme/components';
4
+ import { useAppSelector } from '@akinon/next/redux/hooks';
5
+
6
+ export default function RootModal() {
7
+ const { open, title, content } = useAppSelector(
8
+ (state) => state.root.rootModal
9
+ );
10
+
11
+ return (
12
+ <Modal
13
+ portalId="root-modal"
14
+ title={title}
15
+ open={open}
16
+ className="w-full sm:w-[28rem] max-h-[90vh] overflow-y-auto"
17
+ >
18
+ <div className="p-6">{content}</div>
19
+ </Modal>
20
+ );
21
+ }