update: implement account page reducer to manage account page state

This commit is contained in:
Aaron William Po
2023-06-02 00:08:50 -04:00
parent 81cb95391a
commit 02d753fb41
5 changed files with 121 additions and 37 deletions

View File

@@ -3,19 +3,25 @@ import validateUsernameRequest from '@/requests/validateUsernameRequest';
import { BaseCreateUserSchema } from '@/services/User/schema/CreateUserValidationSchemas';
import { Switch } from '@headlessui/react';
import { zodResolver } from '@hookform/resolvers/zod';
import { FC, useContext, useState } from 'react';
import { Dispatch, FC, useContext } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import UserContext from '@/contexts/UserContext';
import sendEditUserRequest from '@/requests/User/sendEditUserRequest';
import createErrorToast from '@/util/createErrorToast';
import { toast } from 'react-hot-toast';
import { AccountPageAction, AccountPageState } from '@/reducers/accountPageReducer';
import FormError from '../ui/forms/FormError';
import FormInfo from '../ui/forms/FormInfo';
import FormLabel from '../ui/forms/FormLabel';
import FormTextInput from '../ui/forms/FormTextInput';
const AccountInfo: FC = () => {
interface AccountInfoProps {
pageState: AccountPageState;
dispatch: Dispatch<AccountPageAction>;
}
const AccountInfo: FC<AccountInfoProps> = ({ pageState, dispatch }) => {
const { user, mutate } = useContext(UserContext);
const EditUserSchema = BaseCreateUserSchema.pick({
@@ -47,18 +53,16 @@ const AccountInfo: FC = () => {
),
});
const [editToggled, setEditToggled] = useState(false);
const onSubmit = async (data: z.infer<typeof EditUserSchema>) => {
const loadingToast = toast.loading('Submitting edits...');
try {
await sendEditUserRequest({ user: user!, data });
toast.remove(loadingToast);
toast.success('Edits submitted successfully.');
setEditToggled(false);
dispatch({ type: 'CLOSE_ALL' });
await mutate!();
} catch (error) {
setEditToggled(false);
dispatch({ type: 'CLOSE_ALL' });
toast.remove(loadingToast);
createErrorToast(error);
await mutate!();
@@ -82,9 +86,9 @@ const AccountInfo: FC = () => {
<Switch
className="toggle"
id="edit-toggle"
checked={editToggled}
checked={pageState.accountInfoOpen}
onClick={async () => {
setEditToggled((val) => !val);
dispatch({ type: 'TOGGLE_ACCOUNT_INFO_VISIBILITY' });
await mutate!();
reset({
username: user!.username,
@@ -96,7 +100,7 @@ const AccountInfo: FC = () => {
/>
</div>
</div>
{editToggled && (
{pageState.accountInfoOpen && (
<form
className="form-control space-y-5"
onSubmit={handleSubmit(onSubmit)}
@@ -109,7 +113,7 @@ const AccountInfo: FC = () => {
</FormInfo>
<FormTextInput
type="text"
disabled={!editToggled || formState.isSubmitting}
disabled={!pageState.accountInfoOpen || formState.isSubmitting}
error={!!formState.errors.username}
id="username"
formValidationSchema={register('username')}
@@ -120,7 +124,7 @@ const AccountInfo: FC = () => {
</FormInfo>
<FormTextInput
type="email"
disabled={!editToggled || formState.isSubmitting}
disabled={!pageState.accountInfoOpen || formState.isSubmitting}
error={!!formState.errors.email}
id="email"
formValidationSchema={register('email')}
@@ -134,7 +138,7 @@ const AccountInfo: FC = () => {
</FormInfo>
<FormTextInput
type="text"
disabled={!editToggled || formState.isSubmitting}
disabled={!pageState.accountInfoOpen || formState.isSubmitting}
error={!!formState.errors.firstName}
id="firstName"
formValidationSchema={register('firstName')}
@@ -147,7 +151,7 @@ const AccountInfo: FC = () => {
</FormInfo>
<FormTextInput
type="text"
disabled={!editToggled || formState.isSubmitting}
disabled={!pageState.accountInfoOpen || formState.isSubmitting}
error={!!formState.errors.lastName}
id="lastName"
formValidationSchema={register('lastName')}
@@ -157,7 +161,7 @@ const AccountInfo: FC = () => {
<button
className="btn-primary btn my-5 w-full"
type="submit"
disabled={!editToggled || formState.isSubmitting}
disabled={!pageState.accountInfoOpen || formState.isSubmitting}
>
Save Changes
</button>

View File

@@ -1,10 +1,16 @@
import { AccountPageState, AccountPageAction } from '@/reducers/accountPageReducer';
import { Switch } from '@headlessui/react';
import { useRouter } from 'next/router';
import { FunctionComponent, useRef, useState } from 'react';
const DeleteAccount: FunctionComponent = () => {
const [deleteToggled, setDeleteToggled] = useState(false);
import { Dispatch, FunctionComponent, useRef } from 'react';
interface DeleteAccountProps {
pageState: AccountPageState;
dispatch: Dispatch<AccountPageAction>;
}
const DeleteAccount: FunctionComponent<DeleteAccountProps> = ({
dispatch,
pageState,
}) => {
const deleteRef = useRef<null | HTMLDialogElement>(null);
const router = useRouter();
@@ -20,14 +26,14 @@ const DeleteAccount: FunctionComponent = () => {
<Switch
className="toggle"
id="edit-toggle"
checked={deleteToggled}
checked={pageState.deleteAccountOpen}
onClick={() => {
setDeleteToggled((val) => !val);
dispatch({ type: 'TOGGLE_DELETE_ACCOUNT_VISIBILITY' });
}}
/>
</div>
</div>
{deleteToggled && (
{pageState.deleteAccountOpen && (
<>
<div className="mt-3">
<button

View File

@@ -1,17 +1,24 @@
import { Switch } from '@headlessui/react';
import { FunctionComponent, useState } from 'react';
import { Dispatch, FunctionComponent } from 'react';
import { SubmitHandler, useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { UpdatePasswordSchema } from '@/services/User/schema/CreateUserValidationSchemas';
import sendUpdatePasswordRequest from '@/requests/User/sendUpdatePasswordRequest';
import { AccountPageState, AccountPageAction } from '@/reducers/accountPageReducer';
import toast from 'react-hot-toast';
import createErrorToast from '@/util/createErrorToast';
import FormError from '../ui/forms/FormError';
import FormInfo from '../ui/forms/FormInfo';
import FormLabel from '../ui/forms/FormLabel';
import FormTextInput from '../ui/forms/FormTextInput';
const Security: FunctionComponent = () => {
const [editToggled, setEditToggled] = useState(false);
interface SecurityProps {
pageState: AccountPageState;
dispatch: Dispatch<AccountPageAction>;
}
const Security: FunctionComponent<SecurityProps> = ({ dispatch, pageState }) => {
const { register, handleSubmit, formState, reset } = useForm<
z.infer<typeof UpdatePasswordSchema>
>({
@@ -19,9 +26,16 @@ const Security: FunctionComponent = () => {
});
const onSubmit: SubmitHandler<z.infer<typeof UpdatePasswordSchema>> = async (data) => {
await sendUpdatePasswordRequest(data);
setEditToggled((value) => !value);
reset();
const loadingToast = toast.loading('Changing password.');
try {
await sendUpdatePasswordRequest(data);
toast.remove(loadingToast);
toast.success('Password changed successfully.');
dispatch({ type: 'CLOSE_ALL' });
} catch (error) {
dispatch({ type: 'CLOSE_ALL' });
createErrorToast(error);
}
};
return (
@@ -36,15 +50,15 @@ const Security: FunctionComponent = () => {
<Switch
className="toggle"
id="edit-toggle"
checked={editToggled}
checked={pageState.securityOpen}
onClick={() => {
setEditToggled((val) => !val);
dispatch({ type: 'TOGGLE_SECURITY_VISIBILITY' });
reset();
}}
/>
</div>
</div>
{editToggled && (
{pageState.securityOpen && (
<form className="form-control" noValidate onSubmit={handleSubmit(onSubmit)}>
<FormInfo>
<FormLabel htmlFor="password">New Password</FormLabel>
@@ -52,7 +66,7 @@ const Security: FunctionComponent = () => {
</FormInfo>
<FormTextInput
type="password"
disabled={!editToggled || formState.isSubmitting}
disabled={!pageState.securityOpen || formState.isSubmitting}
error={!!formState.errors.password}
id="password"
formValidationSchema={register('password')}
@@ -63,7 +77,7 @@ const Security: FunctionComponent = () => {
</FormInfo>
<FormTextInput
type="password"
disabled={!editToggled || formState.isSubmitting}
disabled={!pageState.securityOpen || formState.isSubmitting}
error={!!formState.errors.confirmPassword}
id="password"
formValidationSchema={register('confirmPassword')}
@@ -71,7 +85,7 @@ const Security: FunctionComponent = () => {
<button
className="btn-primary btn mt-5"
disabled={!editToggled || formState.isSubmitting}
disabled={!pageState.securityOpen || formState.isSubmitting}
type="submit"
>
Update