) => {
+ let formData;
+
+ if (e.target.form) {
+ formData = new FormData(e.target.form);
+ }
+
+ const isValid = validatePasswords('confirm-password', formData);
+
+ setIsConfirmPasswordValid(isValid);
+ };
+
+ return (
+ <>
+ {(state.status === 'error' || state.status === 'success') && (
+
+ {messageText}
+
+ )}
+
+
+ >
+ );
+};
diff --git a/core/app/[locale]/(default)/account/[tab]/_components/settings-content.tsx b/core/app/[locale]/(default)/account/[tab]/_components/settings-content.tsx
new file mode 100644
index 000000000..5ba292ecd
--- /dev/null
+++ b/core/app/[locale]/(default)/account/[tab]/_components/settings-content.tsx
@@ -0,0 +1,30 @@
+import { NextIntlClientProvider } from 'next-intl';
+import { getLocale, getMessages } from 'next-intl/server';
+
+import { TabType } from '../layout';
+
+import { ChangePasswordForm } from './change-password-form';
+import { TabHeading } from './tab-heading';
+
+interface Props {
+ title: TabType;
+ action?: string | string[];
+}
+
+export const SettingsContent = async ({ title, action }: Props) => {
+ const locale = await getLocale();
+ const messages = await getMessages({ locale });
+
+ if (action === 'change-password') {
+ return (
+
+
+
+
+
+
+ );
+ }
+
+ return ;
+};
diff --git a/core/app/[locale]/(default)/account/[tab]/_components/tab-heading.tsx b/core/app/[locale]/(default)/account/[tab]/_components/tab-heading.tsx
new file mode 100644
index 000000000..31ed22152
--- /dev/null
+++ b/core/app/[locale]/(default)/account/[tab]/_components/tab-heading.tsx
@@ -0,0 +1,17 @@
+import { getTranslations } from 'next-intl/server';
+
+import { TabType } from '../layout';
+
+export const TabHeading = async ({
+ heading,
+ locale,
+}: {
+ heading: TabType | 'change-password';
+ locale: string;
+}) => {
+ const t = await getTranslations({ locale, namespace: 'Account.Home' });
+ const tab = heading === 'recently-viewed' ? 'recentlyViewed' : heading;
+ const title = tab === 'change-password' ? 'changePassword' : tab;
+
+ return {t(title)}
;
+};
diff --git a/core/app/[locale]/(default)/account/[tab]/page.tsx b/core/app/[locale]/(default)/account/[tab]/page.tsx
index b474d2883..b22dd54dd 100644
--- a/core/app/[locale]/(default)/account/[tab]/page.tsx
+++ b/core/app/[locale]/(default)/account/[tab]/page.tsx
@@ -6,6 +6,8 @@ import { getCustomerAddresses } from '~/client/queries/get-customer-addresses';
import { LocaleType } from '~/i18n';
import { AddressesContent } from './_components/addresses-content';
+import { SettingsContent } from './_components/settings-content';
+import { TabHeading } from './_components/tab-heading';
import { TabType } from './layout';
interface Props {
@@ -28,19 +30,13 @@ export async function generateMetadata({ params: { tab, locale } }: Props): Prom
};
}
-const tabHeading = async (heading: string, locale: string) => {
- const t = await getTranslations({ locale, namespace: 'Account.Home' });
-
- return {t(heading)}
;
-};
-
export default async function AccountTabPage({ params: { tab, locale }, searchParams }: Props) {
switch (tab) {
case 'orders':
- return tabHeading(tab, locale);
+ return ;
case 'messages':
- return tabHeading(tab, locale);
+ return ;
case 'addresses': {
const { before, after } = searchParams;
@@ -60,18 +56,18 @@ export default async function AccountTabPage({ params: { tab, locale }, searchPa
}
case 'wishlists':
- return tabHeading(tab, locale);
+ return ;
case 'recently-viewed':
- return tabHeading('recentlyViewed', locale);
+ return ;
- case 'settings':
- return tabHeading(tab, locale);
+ case 'settings': {
+ return ;
+ }
default:
return notFound();
}
}
-export { tabHeading };
export const runtime = 'edge';
diff --git a/core/client/mutations/submit-change-password.ts b/core/client/mutations/submit-change-password.ts
index d94356434..300cc3209 100644
--- a/core/client/mutations/submit-change-password.ts
+++ b/core/client/mutations/submit-change-password.ts
@@ -1,22 +1,24 @@
import { z } from 'zod';
import { client } from '..';
-import { graphql } from '../graphql';
-
-export const ChangePasswordSchema = z
- .object({
- customerId: z.string(),
- customerToken: z.string(),
- newPassword: z.string(),
- confirmPassword: z.string(),
- })
- .required();
-
-interface SubmitChangePassword {
- newPassword: z.infer['newPassword'];
- token: string;
- customerEntityId: number;
-}
+import { graphql, VariablesOf } from '../graphql';
+
+const ChangePasswordFieldsSchema = z.object({
+ customerId: z.string(),
+ customerToken: z.string(),
+ currentPassword: z.string().min(1),
+ newPassword: z.string().min(1),
+ confirmPassword: z.string().min(1),
+});
+
+export const CustomerChangePasswordSchema = ChangePasswordFieldsSchema.omit({
+ customerId: true,
+ customerToken: true,
+});
+
+export const ChangePasswordSchema = ChangePasswordFieldsSchema.omit({
+ currentPassword: true,
+}).required();
const SUBMIT_CHANGE_PASSWORD_MUTATION = graphql(`
mutation ChangePassword($input: ResetPasswordInput!) {
@@ -34,11 +36,13 @@ const SUBMIT_CHANGE_PASSWORD_MUTATION = graphql(`
}
`);
+type ChangePasswordInput = VariablesOf['input'];
+
export const submitChangePassword = async ({
newPassword,
token,
customerEntityId,
-}: SubmitChangePassword) => {
+}: ChangePasswordInput) => {
const variables = {
input: {
token,
diff --git a/core/client/mutations/submit-customer-change-password.ts b/core/client/mutations/submit-customer-change-password.ts
index ddbdd1b20..8a20100e2 100644
--- a/core/client/mutations/submit-customer-change-password.ts
+++ b/core/client/mutations/submit-customer-change-password.ts
@@ -1,21 +1,7 @@
-import { z } from 'zod';
-
import { getSessionCustomerId } from '~/auth';
import { client } from '..';
-import { graphql } from '../graphql';
-
-export const CustomerChangePasswordSchema = z
- .object({
- currentPassword: z.string(),
- newPassword: z.string(),
- confirmPassword: z.string(),
- })
- .required();
-
-const Input = CustomerChangePasswordSchema.omit({ confirmPassword: true });
-
-type SubmitCustomerChangePassword = z.infer;
+import { graphql, VariablesOf } from '../graphql';
const SUBMIT_CUSTOMER_CHANGE_PASSWORD_MUTATION = graphql(`
mutation CustomerChangePassword($input: ChangePasswordInput!) {
@@ -41,10 +27,12 @@ const SUBMIT_CUSTOMER_CHANGE_PASSWORD_MUTATION = graphql(`
}
`);
+type Variables = VariablesOf;
+
export const submitCustomerChangePassword = async ({
currentPassword,
newPassword,
-}: SubmitCustomerChangePassword) => {
+}: Variables['input']) => {
const customerId = await getSessionCustomerId();
const variables = {
input: {
diff --git a/core/messages/en.json b/core/messages/en.json
index a87374053..3d63b516c 100644
--- a/core/messages/en.json
+++ b/core/messages/en.json
@@ -183,7 +183,8 @@
"addresses": "Addresses",
"wishlists": "Wish lists",
"recentlyViewed": "Recently viewed",
- "settings": "Account settings"
+ "settings": "Account settings",
+ "changePassword": "Change password"
},
"Addresses": {
"defaultAddress": "Default",
@@ -218,9 +219,13 @@
}
},
"ChangePassword": {
+ "currentPasswordLabel": "Current password",
"newPasswordLabel": "New password",
"confirmPasswordLabel": "Confirm password",
+ "cancel": "Cancel",
"confirmPasswordValidationMessage": "Entered passwords are mismatched. Please try again.",
+ "newPasswordValidationMessage": "New password must be different from the current password or/and match confirm password.",
+ "notEmptyMessage": "Field should not be empty",
"successMessage": "Password has been updated successfully!"
},
"SubmitChangePassword": {