@akinon/projectzero 1.99.0-rc.68 → 1.99.0-rc.70
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.
- package/CHANGELOG.md +4 -0
- package/app-template/CHANGELOG.md +56 -0
- package/app-template/package.json +20 -20
- package/app-template/public/locales/en/common.json +6 -0
- package/app-template/public/locales/tr/common.json +6 -0
- package/app-template/src/app/api/form/[...id]/route.ts +1 -7
- package/app-template/src/components/__tests__/link.test.tsx +2 -0
- package/app-template/src/components/generate-form-fields.tsx +43 -4
- package/app-template/src/components/input.tsx +7 -1
- package/app-template/src/components/pagination.tsx +1 -0
- package/app-template/src/views/account/contact-form.tsx +1 -1
- package/app-template/src/views/account/faq/faq-tabs.tsx +8 -2
- package/app-template/src/views/basket/basket-item.tsx +6 -1
- package/app-template/src/views/breadcrumb.tsx +2 -2
- package/app-template/src/views/category/category-info.tsx +1 -0
- package/app-template/src/views/category/filters/index.tsx +1 -1
- package/app-template/src/views/product/product-info.tsx +1 -0
- package/app-template/src/widgets/footer-menu.tsx +6 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,61 @@
|
|
|
1
1
|
# projectzeronext
|
|
2
2
|
|
|
3
|
+
## 1.99.0-rc.70
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 5ad87ff: ZERO-3646: Refactor form submission API to handle form data and improve error responses
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [5ad87ff]
|
|
12
|
+
- @akinon/next@1.99.0-rc.70
|
|
13
|
+
- @akinon/pz-akifast@1.99.0-rc.70
|
|
14
|
+
- @akinon/pz-b2b@1.99.0-rc.70
|
|
15
|
+
- @akinon/pz-basket-gift-pack@1.99.0-rc.70
|
|
16
|
+
- @akinon/pz-bkm@1.99.0-rc.70
|
|
17
|
+
- @akinon/pz-checkout-gift-pack@1.99.0-rc.70
|
|
18
|
+
- @akinon/pz-click-collect@1.99.0-rc.70
|
|
19
|
+
- @akinon/pz-credit-payment@1.99.0-rc.70
|
|
20
|
+
- @akinon/pz-gpay@1.99.0-rc.70
|
|
21
|
+
- @akinon/pz-hepsipay@1.99.0-rc.70
|
|
22
|
+
- @akinon/pz-masterpass@1.99.0-rc.70
|
|
23
|
+
- @akinon/pz-one-click-checkout@1.99.0-rc.70
|
|
24
|
+
- @akinon/pz-otp@1.99.0-rc.70
|
|
25
|
+
- @akinon/pz-pay-on-delivery@1.99.0-rc.70
|
|
26
|
+
- @akinon/pz-saved-card@1.99.0-rc.70
|
|
27
|
+
- @akinon/pz-similar-products@1.99.0-rc.70
|
|
28
|
+
- @akinon/pz-tabby-extension@1.99.0-rc.70
|
|
29
|
+
- @akinon/pz-tamara-extension@1.99.0-rc.70
|
|
30
|
+
|
|
31
|
+
## 1.99.0-rc.69
|
|
32
|
+
|
|
33
|
+
### Minor Changes
|
|
34
|
+
|
|
35
|
+
- 3b255fe: ZERO-3629 :edit warnings in build
|
|
36
|
+
|
|
37
|
+
### Patch Changes
|
|
38
|
+
|
|
39
|
+
- Updated dependencies [3b255fe]
|
|
40
|
+
- @akinon/next@1.99.0-rc.69
|
|
41
|
+
- @akinon/pz-akifast@1.99.0-rc.69
|
|
42
|
+
- @akinon/pz-b2b@1.99.0-rc.69
|
|
43
|
+
- @akinon/pz-basket-gift-pack@1.99.0-rc.69
|
|
44
|
+
- @akinon/pz-bkm@1.99.0-rc.69
|
|
45
|
+
- @akinon/pz-checkout-gift-pack@1.99.0-rc.69
|
|
46
|
+
- @akinon/pz-click-collect@1.99.0-rc.69
|
|
47
|
+
- @akinon/pz-credit-payment@1.99.0-rc.69
|
|
48
|
+
- @akinon/pz-gpay@1.99.0-rc.69
|
|
49
|
+
- @akinon/pz-hepsipay@1.99.0-rc.69
|
|
50
|
+
- @akinon/pz-masterpass@1.99.0-rc.69
|
|
51
|
+
- @akinon/pz-one-click-checkout@1.99.0-rc.69
|
|
52
|
+
- @akinon/pz-otp@1.99.0-rc.69
|
|
53
|
+
- @akinon/pz-pay-on-delivery@1.99.0-rc.69
|
|
54
|
+
- @akinon/pz-saved-card@1.99.0-rc.69
|
|
55
|
+
- @akinon/pz-similar-products@1.99.0-rc.69
|
|
56
|
+
- @akinon/pz-tabby-extension@1.99.0-rc.69
|
|
57
|
+
- @akinon/pz-tamara-extension@1.99.0-rc.69
|
|
58
|
+
|
|
3
59
|
## 1.99.0-rc.68
|
|
4
60
|
|
|
5
61
|
### Minor Changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "projectzeronext",
|
|
3
|
-
"version": "1.99.0-rc.
|
|
3
|
+
"version": "1.99.0-rc.70",
|
|
4
4
|
"private": true,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"scripts": {
|
|
@@ -24,24 +24,24 @@
|
|
|
24
24
|
"test:middleware": "jest middleware-matcher.test.ts --bail"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@akinon/next": "1.99.0-rc.
|
|
28
|
-
"@akinon/pz-akifast": "1.99.0-rc.
|
|
29
|
-
"@akinon/pz-b2b": "1.99.0-rc.
|
|
30
|
-
"@akinon/pz-basket-gift-pack": "1.99.0-rc.
|
|
31
|
-
"@akinon/pz-bkm": "1.99.0-rc.
|
|
32
|
-
"@akinon/pz-checkout-gift-pack": "1.99.0-rc.
|
|
33
|
-
"@akinon/pz-click-collect": "1.99.0-rc.
|
|
34
|
-
"@akinon/pz-credit-payment": "1.99.0-rc.
|
|
35
|
-
"@akinon/pz-gpay": "1.99.0-rc.
|
|
36
|
-
"@akinon/pz-hepsipay": "1.99.0-rc.
|
|
37
|
-
"@akinon/pz-masterpass": "1.99.0-rc.
|
|
38
|
-
"@akinon/pz-one-click-checkout": "1.99.0-rc.
|
|
39
|
-
"@akinon/pz-otp": "1.99.0-rc.
|
|
40
|
-
"@akinon/pz-pay-on-delivery": "1.99.0-rc.
|
|
41
|
-
"@akinon/pz-saved-card": "1.99.0-rc.
|
|
42
|
-
"@akinon/pz-similar-products": "1.99.0-rc.
|
|
43
|
-
"@akinon/pz-tabby-extension": "1.99.0-rc.
|
|
44
|
-
"@akinon/pz-tamara-extension": "1.99.0-rc.
|
|
27
|
+
"@akinon/next": "1.99.0-rc.70",
|
|
28
|
+
"@akinon/pz-akifast": "1.99.0-rc.70",
|
|
29
|
+
"@akinon/pz-b2b": "1.99.0-rc.70",
|
|
30
|
+
"@akinon/pz-basket-gift-pack": "1.99.0-rc.70",
|
|
31
|
+
"@akinon/pz-bkm": "1.99.0-rc.70",
|
|
32
|
+
"@akinon/pz-checkout-gift-pack": "1.99.0-rc.70",
|
|
33
|
+
"@akinon/pz-click-collect": "1.99.0-rc.70",
|
|
34
|
+
"@akinon/pz-credit-payment": "1.99.0-rc.70",
|
|
35
|
+
"@akinon/pz-gpay": "1.99.0-rc.70",
|
|
36
|
+
"@akinon/pz-hepsipay": "1.99.0-rc.70",
|
|
37
|
+
"@akinon/pz-masterpass": "1.99.0-rc.70",
|
|
38
|
+
"@akinon/pz-one-click-checkout": "1.99.0-rc.70",
|
|
39
|
+
"@akinon/pz-otp": "1.99.0-rc.70",
|
|
40
|
+
"@akinon/pz-pay-on-delivery": "1.99.0-rc.70",
|
|
41
|
+
"@akinon/pz-saved-card": "1.99.0-rc.70",
|
|
42
|
+
"@akinon/pz-similar-products": "1.99.0-rc.70",
|
|
43
|
+
"@akinon/pz-tabby-extension": "1.99.0-rc.70",
|
|
44
|
+
"@akinon/pz-tamara-extension": "1.99.0-rc.70",
|
|
45
45
|
"@hookform/resolvers": "2.9.0",
|
|
46
46
|
"@next/third-parties": "14.1.0",
|
|
47
47
|
"@react-google-maps/api": "2.17.1",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"yup": "0.32.11"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"@akinon/eslint-plugin-projectzero": "1.99.0-rc.
|
|
67
|
+
"@akinon/eslint-plugin-projectzero": "1.99.0-rc.70",
|
|
68
68
|
"@semantic-release/changelog": "6.0.2",
|
|
69
69
|
"@semantic-release/exec": "6.0.3",
|
|
70
70
|
"@semantic-release/git": "10.0.1",
|
|
@@ -112,5 +112,11 @@
|
|
|
112
112
|
"processing_error": "Error processing image",
|
|
113
113
|
"crop_processing_error": "Error processing cropped image"
|
|
114
114
|
}
|
|
115
|
+
},
|
|
116
|
+
"forms": {
|
|
117
|
+
"sending": "Sending...",
|
|
118
|
+
"success": "Form submitted successfully!",
|
|
119
|
+
"error": "An error occurred while submitting the form. Please try again.",
|
|
120
|
+
"submit_error": "Form submit error:"
|
|
115
121
|
}
|
|
116
122
|
}
|
|
@@ -112,5 +112,11 @@
|
|
|
112
112
|
"processing_error": "Görsel işleme hatası",
|
|
113
113
|
"crop_processing_error": "Kırpılan görsel işleme hatası"
|
|
114
114
|
}
|
|
115
|
+
},
|
|
116
|
+
"forms": {
|
|
117
|
+
"sending": "Gönderiliyor...",
|
|
118
|
+
"success": "Form başarıyla gönderildi!",
|
|
119
|
+
"error": "Form gönderilirken bir hata oluştu. Lütfen tekrar deneyin.",
|
|
120
|
+
"submit_error": "Form gönderme hatası:"
|
|
115
121
|
}
|
|
116
122
|
}
|
|
@@ -7,6 +7,7 @@ import { useForm } from 'react-hook-form';
|
|
|
7
7
|
import { yupResolver } from '@hookform/resolvers/yup';
|
|
8
8
|
import * as yup from 'yup';
|
|
9
9
|
import DynamicForm from './dynamic-form';
|
|
10
|
+
|
|
10
11
|
import {
|
|
11
12
|
AllFieldClassesType,
|
|
12
13
|
FieldPropertiesType,
|
|
@@ -14,6 +15,7 @@ import {
|
|
|
14
15
|
FormPropertiesType,
|
|
15
16
|
Schema
|
|
16
17
|
} from '@akinon/next/types';
|
|
18
|
+
import { useLocalization } from '@akinon/next/hooks';
|
|
17
19
|
|
|
18
20
|
export function GenerateFormFields({
|
|
19
21
|
schema,
|
|
@@ -28,8 +30,14 @@ export function GenerateFormFields({
|
|
|
28
30
|
formProperties: FormPropertiesType;
|
|
29
31
|
submitButtonText: string;
|
|
30
32
|
}) {
|
|
33
|
+
const { t } = useLocalization();
|
|
31
34
|
const [fields, setFields] = useState([]);
|
|
32
35
|
const [loading, setIsLoading] = useState(true);
|
|
36
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
37
|
+
const [submitStatus, setSubmitStatus] = useState<
|
|
38
|
+
'idle' | 'success' | 'error'
|
|
39
|
+
>('idle');
|
|
40
|
+
const [submitMessage, setSubmitMessage] = useState('');
|
|
33
41
|
|
|
34
42
|
const generateValidationSchema = () => {
|
|
35
43
|
const schemaObject = {};
|
|
@@ -80,6 +88,7 @@ export function GenerateFormFields({
|
|
|
80
88
|
const {
|
|
81
89
|
handleSubmit,
|
|
82
90
|
register,
|
|
91
|
+
reset,
|
|
83
92
|
formState: { errors }
|
|
84
93
|
} = useForm<FormField>({
|
|
85
94
|
resolver: yupResolver(generateValidationSchema())
|
|
@@ -108,6 +117,10 @@ export function GenerateFormFields({
|
|
|
108
117
|
}, [schema, fieldProperties]);
|
|
109
118
|
|
|
110
119
|
const onSubmit = async (data) => {
|
|
120
|
+
setIsSubmitting(true);
|
|
121
|
+
setSubmitStatus('idle');
|
|
122
|
+
setSubmitMessage('');
|
|
123
|
+
|
|
111
124
|
try {
|
|
112
125
|
const formData = new FormData();
|
|
113
126
|
|
|
@@ -115,12 +128,25 @@ export function GenerateFormFields({
|
|
|
115
128
|
formData.append(key, data[key]);
|
|
116
129
|
});
|
|
117
130
|
|
|
118
|
-
fetch(formProperties.actionUrl, {
|
|
131
|
+
const response = await fetch(formProperties.actionUrl, {
|
|
119
132
|
method: 'POST',
|
|
120
133
|
body: formData
|
|
121
134
|
});
|
|
135
|
+
|
|
136
|
+
if (response.ok) {
|
|
137
|
+
setSubmitStatus('success');
|
|
138
|
+
setSubmitMessage(t('common.forms.success'));
|
|
139
|
+
reset();
|
|
140
|
+
} else {
|
|
141
|
+
setSubmitStatus('error');
|
|
142
|
+
setSubmitMessage(t('common.forms.error'));
|
|
143
|
+
}
|
|
122
144
|
} catch (error) {
|
|
123
|
-
console.error('
|
|
145
|
+
console.error(t('common.forms.submit_error'), error);
|
|
146
|
+
setSubmitStatus('error');
|
|
147
|
+
setSubmitMessage(t('common.forms.error'));
|
|
148
|
+
} finally {
|
|
149
|
+
setIsSubmitting(false);
|
|
124
150
|
}
|
|
125
151
|
};
|
|
126
152
|
|
|
@@ -337,9 +363,22 @@ export function GenerateFormFields({
|
|
|
337
363
|
<LoaderSpinner />
|
|
338
364
|
) : (
|
|
339
365
|
<>
|
|
366
|
+
{submitStatus === 'success' && (
|
|
367
|
+
<div className="mb-4 p-3 bg-green-100 border border-green-400 text-green-700 rounded">
|
|
368
|
+
{submitMessage}
|
|
369
|
+
</div>
|
|
370
|
+
)}
|
|
371
|
+
|
|
372
|
+
{submitStatus === 'error' && (
|
|
373
|
+
<div className="mb-4 p-3 bg-red-100 border border-red-400 text-red-700 rounded">
|
|
374
|
+
{submitMessage}
|
|
375
|
+
</div>
|
|
376
|
+
)}
|
|
377
|
+
|
|
340
378
|
{fields.map((field: FormField) => generateField(field))}
|
|
341
|
-
|
|
342
|
-
|
|
379
|
+
|
|
380
|
+
<Button type="submit" className="w-full" disabled={isSubmitting}>
|
|
381
|
+
{isSubmitting ? t('common.forms.sending') : submitButtonText}
|
|
343
382
|
</Button>
|
|
344
383
|
</>
|
|
345
384
|
)}
|
|
@@ -48,7 +48,13 @@ export const Input = forwardRef<
|
|
|
48
48
|
props.className
|
|
49
49
|
);
|
|
50
50
|
|
|
51
|
-
const inputProps:
|
|
51
|
+
const inputProps: {
|
|
52
|
+
id?: string;
|
|
53
|
+
ref?: Ref<HTMLInputElement>;
|
|
54
|
+
className?: string;
|
|
55
|
+
onFocus?: () => void;
|
|
56
|
+
onBlur?: (event: FocusEvent<HTMLInputElement>) => void;
|
|
57
|
+
} = {
|
|
52
58
|
id,
|
|
53
59
|
ref,
|
|
54
60
|
className: inputClass,
|
|
@@ -111,7 +111,7 @@ const ContactForm = () => {
|
|
|
111
111
|
resolver: yupResolver(contactFormSchema(t))
|
|
112
112
|
});
|
|
113
113
|
|
|
114
|
-
const onSubmit: SubmitHandler<ContactFormType> = (data
|
|
114
|
+
const onSubmit: SubmitHandler<ContactFormType> = (data) => {
|
|
115
115
|
const formData = new FormData();
|
|
116
116
|
|
|
117
117
|
Object.keys(data ?? {}).forEach((key) => {
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { Accordion, LoaderSpinner, TabPanel, Tabs } from '@theme/components';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { useGetWidgetQuery } from '@akinon/next/data/client/misc';
|
|
6
|
+
import { useLocalization } from '@akinon/next/hooks';
|
|
6
7
|
|
|
7
8
|
interface Props {
|
|
8
9
|
searchKey?: string;
|
|
@@ -11,6 +12,7 @@ interface Props {
|
|
|
11
12
|
export function FaqTabs(props: Props) {
|
|
12
13
|
const { searchKey } = props;
|
|
13
14
|
const { data, isLoading } = useGetWidgetQuery('faq');
|
|
15
|
+
const { locale } = useLocalization();
|
|
14
16
|
|
|
15
17
|
if (isLoading) {
|
|
16
18
|
return <LoaderSpinner className="mt-4" />;
|
|
@@ -29,8 +31,12 @@ export function FaqTabs(props: Props) {
|
|
|
29
31
|
{data?.attributes?.faq_contents
|
|
30
32
|
?.filter(
|
|
31
33
|
(faq) =>
|
|
32
|
-
faq.value.content
|
|
33
|
-
|
|
34
|
+
faq.value.content
|
|
35
|
+
.toLocaleLowerCase(locale)
|
|
36
|
+
.includes(searchKey) ||
|
|
37
|
+
faq.value.title
|
|
38
|
+
.toLocaleLowerCase(locale)
|
|
39
|
+
.includes(searchKey)
|
|
34
40
|
)
|
|
35
41
|
.map((faq, index) => {
|
|
36
42
|
if (faq.value.category == item.value.category_id) {
|
|
@@ -40,7 +40,12 @@ export const BasketItem = (props: Props) => {
|
|
|
40
40
|
quantity: number,
|
|
41
41
|
attributes: object = {}
|
|
42
42
|
) => {
|
|
43
|
-
const requestParams:
|
|
43
|
+
const requestParams: {
|
|
44
|
+
product: number;
|
|
45
|
+
quantity: number;
|
|
46
|
+
attributes: object;
|
|
47
|
+
namespace?: string;
|
|
48
|
+
} = {
|
|
44
49
|
product: productPk,
|
|
45
50
|
quantity,
|
|
46
51
|
attributes
|
|
@@ -12,7 +12,7 @@ export interface BreadcrumbProps {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export default function Breadcrumb(props: BreadcrumbProps) {
|
|
15
|
-
const { t } = useLocalization();
|
|
15
|
+
const { t, locale } = useLocalization();
|
|
16
16
|
const { breadcrumbList = [] } = props;
|
|
17
17
|
|
|
18
18
|
const list = [
|
|
@@ -28,7 +28,7 @@ export default function Breadcrumb(props: BreadcrumbProps) {
|
|
|
28
28
|
{list.map((item, index) => (
|
|
29
29
|
<Fragment key={index}>
|
|
30
30
|
<Link href={item.url}>
|
|
31
|
-
{capitalize(item.text.toLocaleLowerCase())}
|
|
31
|
+
{capitalize(item.text.toLocaleLowerCase(locale))}
|
|
32
32
|
</Link>
|
|
33
33
|
{index !== list.length - 1 && <Icon name="chevron-end" size={8} />}
|
|
34
34
|
</Fragment>
|
|
@@ -57,6 +57,7 @@ export default function ListPage(props: ListPageProps) {
|
|
|
57
57
|
newUrl.searchParams.delete('page');
|
|
58
58
|
router.push(newUrl.pathname + newUrl.search, undefined);
|
|
59
59
|
}
|
|
60
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
60
61
|
}, [searchParams, data.products, page]);
|
|
61
62
|
|
|
62
63
|
const { t } = useLocalization();
|
|
@@ -6,7 +6,7 @@ import { useLocalization } from '@akinon/next/hooks';
|
|
|
6
6
|
import { useAppDispatch, useAppSelector } from '@akinon/next/redux/hooks';
|
|
7
7
|
import { resetSelectedFacets } from '@theme/redux/reducers/category';
|
|
8
8
|
import CategoryActiveFilters from '@theme/views/category/category-active-filters';
|
|
9
|
-
import { useMemo,
|
|
9
|
+
import { useMemo, useTransition } from 'react';
|
|
10
10
|
import { FilterItem } from './filter-item';
|
|
11
11
|
|
|
12
12
|
interface Props {
|
|
@@ -2,6 +2,7 @@ import 'server-only';
|
|
|
2
2
|
|
|
3
3
|
import { Link, Accordion } from '@theme/components';
|
|
4
4
|
import { getWidgetData } from '@akinon/next/data/server';
|
|
5
|
+
import { ServerVariables } from '@akinon/next/utils/server-variables';
|
|
5
6
|
|
|
6
7
|
type SideItem = {
|
|
7
8
|
value: string;
|
|
@@ -47,6 +48,7 @@ type FooterMenuType = {
|
|
|
47
48
|
|
|
48
49
|
export default async function FooterMenu() {
|
|
49
50
|
const data = await getWidgetData<FooterMenuType>({ slug: 'footer-menu' });
|
|
51
|
+
const { locale } = ServerVariables;
|
|
50
52
|
|
|
51
53
|
return (
|
|
52
54
|
<div className="flex-1">
|
|
@@ -72,7 +74,7 @@ export default async function FooterMenu() {
|
|
|
72
74
|
: '_self'
|
|
73
75
|
}
|
|
74
76
|
data-testid={`footer-categories-${item?.value?.name
|
|
75
|
-
?.toLocaleLowerCase()
|
|
77
|
+
?.toLocaleLowerCase(locale)
|
|
76
78
|
.split(' ')
|
|
77
79
|
.join('')}`}
|
|
78
80
|
>
|
|
@@ -96,7 +98,9 @@ export default async function FooterMenu() {
|
|
|
96
98
|
? '_blank'
|
|
97
99
|
: '_self'
|
|
98
100
|
}
|
|
99
|
-
data-testid={`footer-categories-${item?.value?.name?.toLocaleLowerCase(
|
|
101
|
+
data-testid={`footer-categories-${item?.value?.name?.toLocaleLowerCase(
|
|
102
|
+
locale
|
|
103
|
+
)}`}
|
|
100
104
|
>
|
|
101
105
|
{item?.value?.name}
|
|
102
106
|
</Link>
|