Skip to content

Commit

Permalink
feat(core): add change password for logged-in customer
Browse files Browse the repository at this point in the history
  • Loading branch information
bc-alexsaiannyi committed Mar 26, 2024
1 parent cfab55b commit 62266a4
Show file tree
Hide file tree
Showing 9 changed files with 465 additions and 25 deletions.
5 changes: 5 additions & 0 deletions .changeset/happy-eggs-buy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bigcommerce/catalyst-core": minor
---

add change password for logged-in customer
23 changes: 21 additions & 2 deletions apps/core/app/[locale]/(default)/account/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { BookUser, Eye, Gift, Mail, Package, Settings } from 'lucide-react';
import { redirect } from 'next/navigation';
import { getTranslations } from 'next-intl/server';
import { NextIntlClientProvider } from 'next-intl';
import { getMessages, getTranslations } from 'next-intl/server';
import { ReactNode } from 'react';

import { auth } from '~/auth';
import { Link } from '~/components/link';
import { LocaleType } from '~/i18n';

import { ChangePasswordForm } from '../login/_components/change-password-form';

interface AccountItem {
children: ReactNode;
description?: string;
Expand All @@ -33,16 +36,32 @@ interface Props {
params: {
locale: LocaleType;
};
searchParams: {
action?: 'reset_password';
};
}

export default async function AccountPage({ params: { locale } }: Props) {
export default async function AccountPage({ params: { locale }, searchParams: { action } }: Props) {
const session = await auth();
const t = await getTranslations({ locale, namespace: 'Account.Home' });
const messages = await getMessages({ locale });
const Account = messages.Account ?? {};

if (!session) {
redirect('/login');
}

if (action === 'reset_password') {
return (
<div className="mx-auto my-6 max-w-4xl">
<h2 className="mb-8 text-4xl font-black lg:text-5xl">{t('changePassword')}</h2>
<NextIntlClientProvider locale={locale} messages={{ Account }}>
<ChangePasswordForm isLoggedIn={true} />
</NextIntlClientProvider>
</div>
);
}

return (
<div className="mx-auto max-w-screen-xl">
<h1 className="my-6 my-8 text-4xl font-black lg:my-8 lg:text-5xl">{t('heading')}</h1>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'use server';

import { ZodError } from 'zod';

import {
ChangePasswordSchema,
submitChangePassword,
} from '~/client/mutations/submit-change-password';

export interface State {
status: 'idle' | 'error' | 'success';
message?: string;
}

export const submitChangePasswordForm = async (_previousState: unknown, formData: FormData) => {
try {
const parsedData = ChangePasswordSchema.parse({
customerId: formData.get('customer-id'),
customerToken: formData.get('customer-token'),
newPassword: formData.get('new-password'),
confirmPassword: formData.get('confirm-password'),
});

const response = await submitChangePassword({
newPassword: parsedData.newPassword,
token: parsedData.customerToken,
customerEntityId: Number(parsedData.customerId),
});

if (response.customer.resetPassword.errors.length === 0) {
return { status: 'success', message: '' };
}

return {
status: 'error',
message: response.customer.resetPassword.errors.map((error) => error.message).join('\n'),
};
} catch (error: unknown) {
if (error instanceof ZodError) {
return {
status: 'error',
message: error.issues
.map(({ path, message }) => `${path.toString()}: ${message}.`)
.join('\n'),
};
}

if (error instanceof Error) {
return {
status: 'error',
message: error.message,
};
}

return { status: 'error', message: 'Unknown error' };
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
'use server';

import { ZodError } from 'zod';

import {
CustomerChangePasswordSchema,
submitCustomerChangePassword,
} from '~/client/mutations/submit-customer-change-password';

export interface State {
status: 'idle' | 'error' | 'success';
message?: string;
}

export const submitCustomerChangePasswordForm = async (
_previousState: unknown,
formData: FormData,
) => {
try {
const parsedData = CustomerChangePasswordSchema.parse({
newPassword: formData.get('new-password'),
currentPassword: formData.get('current-password'),
confirmPassword: formData.get('confirm-password'),
});

const response = await submitCustomerChangePassword({
newPassword: parsedData.newPassword,
currentPassword: parsedData.currentPassword,
});

if (response.errors.length === 0) {
return { status: 'success', message: '' };
}

return {
status: 'error',
message: response.errors.map((error) => error.message).join('\n'),
};
} catch (error: unknown) {
if (error instanceof ZodError) {
return {
status: 'error',
message: error.issues
.map(({ path, message }) => `${path.toString()}: ${message}.`)
.join('\n'),
};
}

if (error instanceof Error) {
return {
status: 'error',
message: error.message,
};
}

return { status: 'error', message: 'Unknown error' };
}
};
Loading

0 comments on commit 62266a4

Please sign in to comment.