@akinon/projectzero 1.48.0-rc.5 → 1.48.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 (48) hide show
  1. package/CHANGELOG.md +1 -59
  2. package/README.md +2 -3
  3. package/app-template/.gitignore +0 -2
  4. package/app-template/.lintstagedrc.js +4 -5
  5. package/app-template/CHANGELOG.md +48 -1406
  6. package/app-template/docs/basic-setup.md +1 -1
  7. package/app-template/docs/plugins.md +7 -7
  8. package/app-template/package.json +20 -22
  9. package/app-template/public/locales/en/account.json +4 -4
  10. package/app-template/public/locales/tr/account.json +1 -1
  11. package/app-template/src/app/[commerce]/[locale]/[currency]/account/address/page.tsx +1 -1
  12. package/app-template/src/app/[commerce]/[locale]/[currency]/account/coupons/page.tsx +4 -4
  13. package/app-template/src/app/[commerce]/[locale]/[currency]/account/profile/page.tsx +0 -1
  14. package/app-template/src/app/[commerce]/[locale]/[currency]/category/[pk]/page.tsx +2 -5
  15. package/app-template/src/app/[commerce]/[locale]/[currency]/orders/completed/[token]/page.tsx +8 -12
  16. package/app-template/src/components/checkbox.tsx +2 -2
  17. package/app-template/src/components/input.tsx +7 -19
  18. package/app-template/src/components/pagination.tsx +18 -13
  19. package/app-template/src/components/price.tsx +4 -9
  20. package/app-template/src/redux/reducers/category.ts +1 -7
  21. package/app-template/src/settings.js +1 -6
  22. package/app-template/src/views/account/address-card.tsx +2 -2
  23. package/app-template/src/views/account/address-form.tsx +7 -22
  24. package/app-template/src/views/account/contact-form.tsx +6 -23
  25. package/app-template/src/views/account/favorite-item.tsx +2 -2
  26. package/app-template/src/views/account/favourite-products/favourite-products-list.tsx +1 -5
  27. package/app-template/src/views/breadcrumb.tsx +1 -4
  28. package/app-template/src/views/category/category-active-filters.tsx +6 -16
  29. package/app-template/src/views/category/category-info.tsx +17 -31
  30. package/app-template/src/views/category/filters/index.tsx +108 -16
  31. package/app-template/src/views/category/layout.tsx +3 -5
  32. package/app-template/src/views/checkout/steps/payment/options/credit-card/index.tsx +4 -33
  33. package/app-template/src/views/checkout/steps/payment/options/redirection.tsx +37 -43
  34. package/app-template/src/views/checkout/steps/payment/payment-option-buttons.tsx +3 -19
  35. package/app-template/src/views/checkout/steps/shipping/address-box.tsx +2 -2
  36. package/app-template/src/views/checkout/steps/shipping/addresses.tsx +1 -1
  37. package/app-template/src/views/checkout/steps/shipping/shipping-options.tsx +37 -230
  38. package/app-template/src/views/find-in-store/index.tsx +3 -2
  39. package/app-template/src/views/header/mobile-menu.tsx +8 -25
  40. package/app-template/src/views/product/product-info.tsx +2 -0
  41. package/app-template/tsconfig.json +4 -14
  42. package/app-template/yarn.lock +1953 -1824
  43. package/commands/create.ts +5 -29
  44. package/dist/commands/create.js +2 -25
  45. package/package.json +2 -2
  46. package/app-template/package-lock.json +0 -29303
  47. package/app-template/src/app/[commerce]/[locale]/[currency]/[...prettyurl]/page.tsx +0 -8
  48. package/app-template/src/views/category/filters/filter-item.tsx +0 -163
@@ -3,9 +3,9 @@ import {
3
3
  Button,
4
4
  FileInput,
5
5
  Input,
6
- Link,
7
6
  LoaderSpinner,
8
- Select
7
+ Select,
8
+ Link
9
9
  } from '@theme/components';
10
10
  import { useSession } from 'next-auth/react';
11
11
  import { useEffect, useState } from 'react';
@@ -45,8 +45,7 @@ const contactFormSchema = (t) =>
45
45
  .when('subject', {
46
46
  is: (value) => value === '2',
47
47
  then: yup.string().required(t('account.contact.form.error.required'))
48
- }),
49
- file: yup.mixed()
48
+ })
50
49
  });
51
50
 
52
51
  const ContactForm = () => {
@@ -111,18 +110,8 @@ const ContactForm = () => {
111
110
  resolver: yupResolver(contactFormSchema(t))
112
111
  });
113
112
 
114
- const onSubmit: SubmitHandler<ContactFormType> = (data, event) => {
115
- const formData = new FormData();
116
-
117
- Object.keys(data ?? {}).forEach((key) => {
118
- if (key === 'file' && data[key]) {
119
- formData.append(key, data[key][0]);
120
- } else if (data[key]) {
121
- formData.append(key, data[key]);
122
- }
123
- });
124
-
125
- sendContact(formData);
113
+ const onSubmit: SubmitHandler<ContactFormType> = (data) => {
114
+ sendContact(data);
126
115
  };
127
116
 
128
117
  const handleChange = (e) => {
@@ -245,7 +234,6 @@ const ContactForm = () => {
245
234
  className="border-gray-500 border w-full text-xs p-2.5 focus-visible:outline-none focus:border-black hover:border-black"
246
235
  rows={7}
247
236
  name="message"
248
- // @ts-expect-error -- awaiting fix:
249
237
  {...register('message')}
250
238
  />
251
239
  {errors.message && (
@@ -254,12 +242,7 @@ const ContactForm = () => {
254
242
  <label className="text-xs text-gray-800 mb-2 block">
255
243
  {t('account.contact.form.file.title')}
256
244
  </label>
257
- <FileInput
258
- name="file"
259
- title="file"
260
- className="w-full mb-5"
261
- {...register('file')}
262
- />
245
+ <FileInput className="w-full mb-5" title="test" />
263
246
  <Button type="submit" className="w-full font-medium">
264
247
  {t('account.contact.form.submit_button')}
265
248
  </Button>
@@ -93,8 +93,8 @@ export const FavoriteItem = (props: Props) => {
93
93
  className={clsx(
94
94
  'absolute top-4 right-4 cursor-pointer',
95
95
  isRemoveFavoriteLoading
96
- ? 'hover:cursor-wait'
97
- : 'hover:cursor-pointer'
96
+ ? 'pointer-events-none hover:cursor-wait' // TODO: Cursors not working fix!
97
+ : 'hove:cursor-pointer'
98
98
  )}
99
99
  data-testid="favorites-remove"
100
100
  />
@@ -30,11 +30,7 @@ const FavoriteProductsList = () => {
30
30
  }
31
31
 
32
32
  if (isLoading || isFetching) {
33
- return (
34
- <div className="flex items-center justify-center h-80">
35
- <LoaderSpinner />
36
- </div>
37
- );
33
+ return <LoaderSpinner />; // TODO: Fix loader spinner position
38
34
  }
39
35
 
40
36
  return (
@@ -5,7 +5,6 @@ import { Icon, Link } from '@theme/components';
5
5
  import { ROUTES } from '@theme/routes';
6
6
  import { useLocalization } from '@akinon/next/hooks';
7
7
  import { BreadcrumbResultType } from '@akinon/next/types';
8
- import { capitalize } from '@akinon/next/utils';
9
8
 
10
9
  export interface BreadcrumbProps {
11
10
  breadcrumbList?: BreadcrumbResultType[];
@@ -27,9 +26,7 @@ export default function Breadcrumb(props: BreadcrumbProps) {
27
26
  <div className="flex items-center gap-3 text-xs leading-4 text-gray-950">
28
27
  {list.map((item, index) => (
29
28
  <Fragment key={index}>
30
- <Link href={item.url}>
31
- {capitalize(item.text.toLocaleLowerCase())}
32
- </Link>
29
+ <Link href={item.url}>{item.text}</Link>
33
30
  {index !== list.length - 1 && <Icon name="chevron-end" size={8} />}
34
31
  </Fragment>
35
32
  ))}
@@ -22,28 +22,17 @@ const CategoryActiveFilters = () => {
22
22
  const handleRemoveFilter = ({ facet, choice }) => {
23
23
  if (facet.widget_type === WIDGET_TYPE.category) {
24
24
  dispatch(removeCategoryFacet({ facet, choice }));
25
- } else {
26
- dispatch(toggleFacet({ facet, choice }));
25
+ return;
27
26
  }
28
27
 
29
- const urlSearchParams = new URLSearchParams(window.location.search);
30
- urlSearchParams.delete(facet.search_key);
31
- router.replace(pathname + '?' + urlSearchParams.toString());
28
+ dispatch(toggleFacet({ facet, choice }));
32
29
  };
33
30
 
34
31
  const url = useMemo(() => {
35
- const facetSearchParams = convertFacetSearchParams(selectedFacets);
36
- const urlSearchParams = new URLSearchParams(searchParams.toString());
32
+ const facetSearchParams =
33
+ convertFacetSearchParams(selectedFacets).toString();
37
34
 
38
- for (const key of Array.from(urlSearchParams.keys())) {
39
- if (facetSearchParams.has(key)) {
40
- urlSearchParams.delete(key);
41
- }
42
- }
43
-
44
- for (const [key, value] of Array.from(facetSearchParams.entries())) {
45
- urlSearchParams.append(key, value);
46
- }
35
+ const urlSearchParams = new URLSearchParams(facetSearchParams);
47
36
 
48
37
  const searchText = searchParams.get('search_text');
49
38
  const page = searchParams.get('page');
@@ -64,6 +53,7 @@ const CategoryActiveFilters = () => {
64
53
 
65
54
  useEffect(() => {
66
55
  router.push(url);
56
+
67
57
  // eslint-disable-next-line react-hooks/exhaustive-deps
68
58
  }, [url]);
69
59
 
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { useEffect, useMemo } from 'react';
3
+ import { useEffect, useMemo, useState } from 'react';
4
4
  import clsx from 'clsx';
5
5
  import { useSearchParams } from 'next/navigation';
6
6
  import { CategoryHeader } from './category-header';
@@ -8,14 +8,13 @@ import { Filters } from './filters';
8
8
  import { Pagination } from '@theme/components';
9
9
  import { ProductItem } from '@theme/views/product-item';
10
10
  import { GetCategoryResponse } from '@akinon/next/types';
11
- import { useAppDispatch, useAppSelector } from '@akinon/next/redux/hooks';
12
- import { setFacets, setMenuOpen } from '@theme/redux/reducers/category';
11
+ import { useAppDispatch } from '@akinon/next/redux/hooks';
12
+ import { setFacets } from '@theme/redux/reducers/category';
13
13
  import CategoryActiveFilters from '@theme/views/category/category-active-filters';
14
14
  import { useLocalization } from '@akinon/next/hooks';
15
15
  import { Link, LoaderSpinner } from '@akinon/next/components';
16
16
  import { ROUTES } from '@theme/routes';
17
17
  import { useRouter } from '@akinon/next/hooks';
18
- import { RootState } from '@theme/redux/store';
19
18
 
20
19
  interface ListPageProps {
21
20
  data: GetCategoryResponse;
@@ -23,16 +22,13 @@ interface ListPageProps {
23
22
 
24
23
  export default function ListPage(props: ListPageProps) {
25
24
  const { data } = props;
26
- const dispatch = useAppDispatch();
27
- const isMenuOpen = useAppSelector(
28
- (state: RootState) => state.category.isMenuOpen
29
- );
25
+ const [isMenuOpen, setIsMenuOpen] = useState(false); // TODO: Move to redux
30
26
 
31
27
  const searchParams = useSearchParams();
32
28
  const router = useRouter();
33
29
 
34
30
  const layoutSize = useMemo(
35
- () => Number(searchParams.get('layout') ?? 3),
31
+ () => searchParams.get('layout') ?? 3,
36
32
  [searchParams]
37
33
  );
38
34
 
@@ -41,24 +37,16 @@ export default function ListPage(props: ListPageProps) {
41
37
  [searchParams]
42
38
  );
43
39
 
44
- const itemDimensions = useMemo(() => {
45
- switch (layoutSize) {
46
- case 2:
47
- return { width: 510, height: 765 };
48
- case 3:
49
- default:
50
- return { width: 340, height: 510 };
51
- }
52
- }, [layoutSize]);
53
-
54
40
  useEffect(() => {
55
41
  if (page > 1 && data.products?.length === 0) {
56
42
  const newUrl = new URL(window.location.href);
43
+
57
44
  newUrl.searchParams.delete('page');
58
45
  router.push(newUrl.pathname + newUrl.search, undefined);
59
46
  }
60
- }, [searchParams, data.products, page]);
47
+ }, [searchParams, data.products, page]); // eslint-disable-line react-hooks/exhaustive-deps
61
48
 
49
+ const dispatch = useAppDispatch();
62
50
  const { t } = useLocalization();
63
51
 
64
52
  useEffect(() => {
@@ -70,12 +58,9 @@ export default function ListPage(props: ListPageProps) {
70
58
  <>
71
59
  <div className="container px-4 mx-auto lg:px-0 lg:my-4">
72
60
  <div className="grid grid-cols-[19rem_1fr]">
73
- <Filters
74
- isMenuOpen={isMenuOpen}
75
- setIsMenuOpen={(open) => dispatch(setMenuOpen(open))}
76
- />
61
+ <Filters isMenuOpen={isMenuOpen} setIsMenuOpen={setIsMenuOpen} />
77
62
  <div
78
- onClick={() => dispatch(setMenuOpen(false))}
63
+ onClick={() => setIsMenuOpen(false)}
79
64
  className={clsx(
80
65
  'transition-opacity duration-300 ease-linear lg:hidden',
81
66
  isMenuOpen
@@ -86,7 +71,7 @@ export default function ListPage(props: ListPageProps) {
86
71
  <div className="flex flex-col items-center lg:items-stretch col-span-2 lg:col-span-1">
87
72
  <CategoryHeader
88
73
  totalCount={data.pagination?.total_count}
89
- setMenuStatus={() => dispatch(setMenuOpen(true))}
74
+ setMenuStatus={() => setIsMenuOpen(true)}
90
75
  sortOptions={data.sorters}
91
76
  />
92
77
  <div className="hidden lg:block">
@@ -106,17 +91,18 @@ export default function ListPage(props: ListPageProps) {
106
91
 
107
92
  <div
108
93
  className={clsx('grid gap-x-4 gap-y-12 grid-cols-2', {
109
- 'md:grid-cols-3': layoutSize === 3,
110
- 'lg:grid-cols-2': layoutSize === 2,
111
- 'lg:grid-cols-3': layoutSize === 3
94
+ 'md:grid-cols-3': Number(layoutSize) === 3,
95
+ 'lg:grid-cols-2': Number(layoutSize) === 2,
96
+ 'lg:grid-cols-3': Number(layoutSize) === 3
112
97
  })}
113
98
  >
114
99
  {data.products.map((product, index) => (
115
100
  <ProductItem
116
101
  key={product.pk}
117
102
  product={product}
118
- width={itemDimensions.width}
119
- height={itemDimensions.height}
103
+ // TODO: Find a better way to handle layout size
104
+ width={340}
105
+ height={510}
120
106
  index={index}
121
107
  />
122
108
  ))}
@@ -1,13 +1,26 @@
1
1
  'use client';
2
2
 
3
+ import { WIDGET_TYPE } from '@theme/types';
3
4
  import clsx from 'clsx';
4
- import { Button, Icon } from '@theme/components';
5
- import { useLocalization } from '@akinon/next/hooks';
5
+
6
+ import { Accordion, Button, Checkbox, Icon, Radio } from '@theme/components';
7
+ import { SizeFilter } from './size-filter';
8
+
9
+ import { useLocalization, useRouter } from '@akinon/next/hooks';
10
+ import { Facet, FacetChoice } from '@akinon/next/types';
6
11
  import { useAppDispatch, useAppSelector } from '@akinon/next/redux/hooks';
7
- import { resetSelectedFacets } from '@theme/redux/reducers/category';
12
+ import {
13
+ resetSelectedFacets,
14
+ toggleFacet
15
+ } from '@theme/redux/reducers/category';
8
16
  import CategoryActiveFilters from '@theme/views/category/category-active-filters';
9
- import { useMemo, useState, useTransition } from 'react';
10
- import { FilterItem } from './filter-item';
17
+ import { useMemo } from 'react';
18
+ import { commonProductAttributes } from '@theme/settings';
19
+
20
+ const COMPONENT_TYPES = {
21
+ [WIDGET_TYPE.category]: Radio,
22
+ [WIDGET_TYPE.multiselect]: Checkbox
23
+ };
11
24
 
12
25
  interface Props {
13
26
  isMenuOpen: boolean;
@@ -15,16 +28,37 @@ interface Props {
15
28
  }
16
29
 
17
30
  export const Filters = (props: Props) => {
31
+ const router = useRouter();
18
32
  const facets = useAppSelector((state) => state.category.facets);
19
33
  const dispatch = useAppDispatch();
20
34
  const { t } = useLocalization();
21
35
  const { isMenuOpen, setIsMenuOpen } = props;
22
36
 
23
- const [isPending, startTransition] = useTransition();
37
+ const handleSelectFilter = ({
38
+ facet,
39
+ choice
40
+ }: {
41
+ facet: Facet;
42
+ choice: FacetChoice;
43
+ }) => {
44
+ if (facet.key === 'category_ids') {
45
+ router.push(choice.url);
46
+ } else {
47
+ dispatch(
48
+ toggleFacet({
49
+ facet,
50
+ choice
51
+ })
52
+ );
53
+ }
54
+ };
24
55
 
25
56
  const haveFilter = useMemo(() => {
26
- return facets.some((facet) =>
27
- facet.data.choices.some((choice) => choice.is_selected)
57
+ return (
58
+ facets.filter(
59
+ (facet) =>
60
+ facet.data.choices.filter((choice) => choice.is_selected).length > 0
61
+ ).length > 0
28
62
  );
29
63
  }, [facets]);
30
64
 
@@ -32,6 +66,10 @@ export const Filters = (props: Props) => {
32
66
  dispatch(resetSelectedFacets());
33
67
  };
34
68
 
69
+ const sizeKey = commonProductAttributes.find(
70
+ (item) => item.translationKey === 'size'
71
+ ).key;
72
+
35
73
  return (
36
74
  <div
37
75
  className={clsx(
@@ -49,22 +87,76 @@ export const Filters = (props: Props) => {
49
87
  <span className="text-sm">1 {t('category.filters.results')}</span>
50
88
  <span>{t('category.filters.ready_to_wear')}</span>
51
89
  </div>
52
-
53
90
  {facets.map((facet) => {
91
+ let Component = null;
92
+ const choices = [...facet.data.choices];
93
+
94
+ if (facet.key === sizeKey) {
95
+ // If it's a size facet, use the custom size filter component
96
+ Component = SizeFilter;
97
+
98
+ const order = ['xs', 's', 'm', 'l', 'xl'];
99
+ choices.sort((a, b) => {
100
+ return (
101
+ order.indexOf(a.label.toLowerCase()) -
102
+ order.indexOf(b.label.toLowerCase())
103
+ );
104
+ });
105
+ } else {
106
+ Component =
107
+ COMPONENT_TYPES[facet.widget_type] ||
108
+ COMPONENT_TYPES[WIDGET_TYPE.category];
109
+ }
110
+
54
111
  return (
55
- <FilterItem
112
+ <Accordion
56
113
  key={facet.key}
57
- facet={facet}
58
- isPending={isPending}
59
- startTransition={startTransition}
60
- />
114
+ title={facet.name}
115
+ isCollapse={choices.some((choice) => choice.is_selected)}
116
+ dataTestId={`filter-${facet.name}`}
117
+ >
118
+ <div
119
+ className={clsx(
120
+ 'flex gap-4 flex-wrap',
121
+ facet.key === sizeKey ? 'flex-row' : 'flex-col' // TODO: This condition must be refactor to a better way
122
+ )}
123
+ >
124
+ {choices.map((choice, index) => (
125
+ <Component // TODO: This dynamic component can be a hook or higher order component so it props can be standardized
126
+ key={choice.label}
127
+ data={choice}
128
+ name={facet.key}
129
+ onChange={() => {
130
+ if (facet.key !== sizeKey) {
131
+ // TODO: This condition must be refactor to a better way
132
+ handleSelectFilter({ facet, choice });
133
+ }
134
+ }}
135
+ onClick={() => {
136
+ if (facet.key === sizeKey) {
137
+ // TODO: This condition must be refactor to a better way
138
+ handleSelectFilter({ facet, choice });
139
+ }
140
+ }}
141
+ checked={choice.is_selected}
142
+ data-testid={`${choice.label.trim()}`}
143
+ >
144
+ {choice.label} (
145
+ <span
146
+ data-testid={`filter-count-${facet.name.toLowerCase()}-${index}`}
147
+ >
148
+ {choice.quantity}
149
+ </span>
150
+ )
151
+ </Component>
152
+ ))}
153
+ </div>
154
+ </Accordion>
61
155
  );
62
156
  })}
63
-
64
157
  <div className="lg:hidden">
65
158
  <CategoryActiveFilters />
66
159
  </div>
67
-
68
160
  {haveFilter && (
69
161
  <div className="lg:hidden">
70
162
  <Button
@@ -1,17 +1,15 @@
1
1
  import clsx from 'clsx';
2
- import { BreadcrumbResultType, GetCategoryResponse } from '@akinon/next/types';
2
+ import { GetCategoryResponse } from '@akinon/next/types';
3
3
  import Breadcrumb from '@theme/views/breadcrumb';
4
4
  import { CategoryBanner } from '@theme/views/category/category-banner';
5
5
  import ListPage from '@theme/views/category/category-info';
6
6
 
7
7
  export default async function Layout({
8
8
  data,
9
- children,
10
- breadcrumbData
9
+ children
11
10
  }: {
12
11
  data: GetCategoryResponse;
13
12
  children?: React.ReactNode;
14
- breadcrumbData?: BreadcrumbResultType[];
15
13
  }) {
16
14
  return (
17
15
  <>
@@ -30,7 +28,7 @@ export default async function Layout({
30
28
  'lg:absolute lg:inset-x-0 z-10 container lg:my-4 mx-auto'
31
29
  )}
32
30
  >
33
- <Breadcrumb breadcrumbList={breadcrumbData} />
31
+ <Breadcrumb />
34
32
  </div>
35
33
  <CategoryBanner {...data.category?.attributes?.category_banner} />
36
34
  </div>
@@ -23,29 +23,13 @@ import { PaymentOption } from '@akinon/next/types';
23
23
  const creditCardFormSchema = (
24
24
  t,
25
25
  payment_option: PaymentOption,
26
- isMasterpassDirectPurchase?: boolean,
27
- isMasterpassCvcRequired?: boolean
26
+ isMasterpassDirectPurchase?: boolean
28
27
  ) => {
29
28
  if (
30
29
  payment_option?.payment_type === 'masterpass' &&
31
30
  isMasterpassDirectPurchase === false
32
31
  ) {
33
32
  return yup.object().shape({
34
- card_cvv: yup
35
- .string()
36
- .transform((value: string) => value.replace(/_/g, '').replace(/ /g, ''))
37
- .when('*', (_, schema) => {
38
- if (isMasterpassCvcRequired) {
39
- return schema
40
- .length(
41
- 3,
42
- t('checkout.payment.credit_card.form.error.cvv_length')
43
- )
44
- .required(t('checkout.payment.credit_card.form.error.required'));
45
- }
46
-
47
- return schema;
48
- }),
49
33
  agreement: yup
50
34
  .boolean()
51
35
  .oneOf([true], t('checkout.payment.credit_card.form.error.required'))
@@ -103,16 +87,10 @@ const CheckoutCreditCard = () => {
103
87
  control,
104
88
  formState: { errors },
105
89
  setError,
106
- getValues,
107
- clearErrors
90
+ getValues
108
91
  } = useForm<CreditCardForm>({
109
92
  resolver: yupResolver(
110
- creditCardFormSchema(
111
- t,
112
- payment_option,
113
- masterpass?.isDirectPurchase,
114
- masterpass?.cvcRequired
115
- )
93
+ creditCardFormSchema(t, payment_option, masterpass?.isDirectPurchase)
116
94
  )
117
95
  });
118
96
  const [months, setMonths] = useState([]);
@@ -339,14 +317,7 @@ const CheckoutCreditCard = () => {
339
317
  <PluginModule
340
318
  component={Component.MasterpassCardList}
341
319
  props={{
342
- className: 'p-10',
343
- form: {
344
- control,
345
- register,
346
- errors,
347
- setFormValue,
348
- clearErrors
349
- }
320
+ className: 'p-10'
350
321
  }}
351
322
  />
352
323
 
@@ -9,7 +9,6 @@ import { twMerge } from 'tailwind-merge';
9
9
  import * as yup from 'yup';
10
10
  import { useEffect, useState } from 'react';
11
11
  import { getPosError } from '@akinon/next/utils';
12
- import { useMessageListener } from '@akinon/next/hooks';
13
12
 
14
13
  interface FormValues {
15
14
  agreement: boolean;
@@ -26,6 +25,7 @@ const formSchema = () =>
26
25
  export default function RedirectionPayment() {
27
26
  const { payment_option } = useAppSelector((state) => state.checkout.preOrder);
28
27
  const [formError, setFormError] = useState(null);
28
+
29
29
  const {
30
30
  register,
31
31
  handleSubmit,
@@ -34,12 +34,11 @@ export default function RedirectionPayment() {
34
34
  resolver: yupResolver(formSchema())
35
35
  });
36
36
  const [completeRedirectionPayment] = useCompleteRedirectionPaymentMutation();
37
+
37
38
  const onSubmit = async () => {
38
39
  completeRedirectionPayment();
39
40
  };
40
41
 
41
- useMessageListener();
42
-
43
42
  useEffect(() => {
44
43
  const posErrors = getPosError();
45
44
 
@@ -49,49 +48,44 @@ export default function RedirectionPayment() {
49
48
  }, []);
50
49
 
51
50
  return (
52
- <div className="checkout-redirection-payment-wrapper">
53
- <form
54
- onSubmit={handleSubmit(onSubmit)}
55
- className="lg-5 space-y-5 lg:p-10"
56
- >
57
- <h1 className="text-2xl font-bold px-4 md:px-0">
58
- Pay With {payment_option.name}
59
- </h1>
51
+ <form onSubmit={handleSubmit(onSubmit)} className="lg-5 space-y-5 lg:p-10">
52
+ <h1 className="text-2xl font-bold px-4 md:px-0">
53
+ Pay With {payment_option.name}
54
+ </h1>
60
55
 
61
- <p className="px-4 md:px-0">
62
- You can quickly and easily pay and complete your order with{' '}
63
- {payment_option.name}.
64
- </p>
56
+ <p className="px-4 md:px-0">
57
+ You can quickly and easily pay and complete your order with{' '}
58
+ {payment_option.name}.
59
+ </p>
65
60
 
66
- <Checkbox
67
- className="px-4 md:px-0"
68
- {...register('agreement')}
69
- error={errors.agreement}
70
- >
71
- Check here to indicate that you have read and agree to the all terms.
72
- </Checkbox>
61
+ <Checkbox
62
+ className="px-4 md:px-0"
63
+ {...register('agreement')}
64
+ error={errors.agreement}
65
+ >
66
+ Check here to indicate that you have read and agree to the all terms.
67
+ </Checkbox>
73
68
 
74
- {formError?.non_field_errors && (
75
- <div
76
- className="w-full text-xs text-start px-1 mt-3 text-error"
77
- data-testid="checkout-form-error"
78
- >
79
- {formError.non_field_errors}
80
- </div>
81
- )}
82
- {formError?.status && (
83
- <div
84
- className="w-full text-xs text-start px-1 mt-3 text-error"
85
- data-testid="checkout-form-error"
86
- >
87
- {formError.status}
88
- </div>
89
- )}
69
+ {formError?.non_field_errors && (
70
+ <div
71
+ className="w-full text-xs text-start px-1 mt-3 text-error"
72
+ data-testid="checkout-form-error"
73
+ >
74
+ {formError.non_field_errors}
75
+ </div>
76
+ )}
77
+ {formError?.status && (
78
+ <div
79
+ className="w-full text-xs text-start px-1 mt-3 text-error"
80
+ data-testid="checkout-form-error"
81
+ >
82
+ {formError.status}
83
+ </div>
84
+ )}
90
85
 
91
- <Button className={twMerge('w-full md:w-36 px-4 md:px-0')}>
92
- {payment_option.name}
93
- </Button>
94
- </form>
95
- </div>
86
+ <Button className={twMerge('w-full md:w-36 px-4 md:px-0')}>
87
+ {payment_option.name}
88
+ </Button>
89
+ </form>
96
90
  );
97
91
  }