Skip to content

Commit

Permalink
fix(wallet/frontend): update account settings page (#1698)
Browse files Browse the repository at this point in the history
* remove edit profile form

* update page title

* fix eye positioning on password fields when field has error

* remove unused imports

* move change password at bottom and spacing fix

* remove updateProfile function

* remove line

* remove more unused vars

* remove unused profileSchema
  • Loading branch information
adrianboros authored Oct 9, 2024
1 parent 4d6a554 commit e55a13e
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 147 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export const ChangePasswordForm = () => {
/>
<span
onClick={toggleCurrentPasswordVisibility}
className="absolute right-2.5 top-1/2 cursor-pointer"
className="absolute right-2.5 top-9 cursor-pointer"
>
{isCurrentPasswordVisible ? <SlashEye /> : <Eye />}
</span>
Expand All @@ -109,7 +109,7 @@ export const ChangePasswordForm = () => {
/>
<span
onClick={toggleNewPasswordVisibility}
className="absolute right-2.5 top-1/2 cursor-pointer"
className="absolute right-2.5 top-9 cursor-pointer"
>
{isNewPasswordVisible ? <SlashEye /> : <Eye />}
</span>
Expand All @@ -126,7 +126,7 @@ export const ChangePasswordForm = () => {
/>
<span
onClick={toggleConfirmNewPasswordVisibility}
className="absolute right-2.5 top-1/2 cursor-pointer"
className="absolute right-2.5 top-9 cursor-pointer"
>
{isConfirmNewPasswordVisible ? <SlashEye /> : <Eye />}
</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,5 @@
import { Button } from '@/ui/Button'
import { Form } from '@/ui/forms/Form'
import { useZodForm } from '@/lib/hooks/useZodForm'
import { Input } from '@/ui/forms/Input'
import { useEffect, useState } from 'react'
import { profileSchema, userService } from '@/lib/api/user'
import { useDialog } from '@/lib/hooks/useDialog'
import { ErrorDialog } from '../dialogs/ErrorDialog'
import { getObjectKeys } from '@/utils/helpers'
import { ChangePasswordForm } from './ChangePasswordForm'
import { usePasswordContext } from '@/lib/context/password'
import { UserResponse } from '@wallet/shared'
Expand All @@ -17,132 +10,38 @@ type PersonalSettingsFormProps = {

// TODO: Can these details be updated by the user when switching to GateHub?
export const PersonalSettingsForm = ({ user }: PersonalSettingsFormProps) => {
const [isReadOnly, setIsReadOnly] = useState(true)
const { isChangePassword, setIsChangePassword } = usePasswordContext()
const [openDialog, closeDialog] = useDialog()
const profileForm = useZodForm({
schema: profileSchema,
defaultValues: user
})

useEffect(() => {
profileForm.setFocus('firstName')
}, [isReadOnly, profileForm])

return (
<>
<div className="mb-5">
<h3 className="text-2xl text-green dark:text-teal-neon">Profile</h3>
<h3 className="text-2xl text-green dark:text-teal-neon">Details</h3>
</div>
<Form
form={profileForm}
onSubmit={async (data) => {
const response = await userService.updateProfile(data)

if (!response) {
openDialog(
<ErrorDialog
onClose={closeDialog}
content="Update profile failed. Please try again."
/>
)
return
}

if (response.success) {
setIsReadOnly(!isReadOnly)
} else {
const { errors, message } = response

if (errors) {
getObjectKeys(errors).map((field) =>
profileForm.setError(field, {
message: errors[field]
})
)
}
if (message) {
profileForm.setError('root', { message })
}
}
}}
readOnly={isReadOnly}
>
<div className="mb-4">
<Input
required
label="First name"
placeholder="First name"
error={profileForm.formState.errors.firstName?.message}
{...profileForm.register('firstName')}
disabled
value={user.firstName}
/>
</div>
<div className="mb-4">
<Input
required
label="Last name"
placeholder="Last name"
error={profileForm.formState.errors.lastName?.message}
{...profileForm.register('lastName')}
disabled
value={user.lastName}
/>

{!isReadOnly && (
<div className="mt-2 flex justify-between">
<Button
intent="outline"
aria-label="stop editing"
onClick={() => setIsReadOnly(!isReadOnly)}
>
Close editing
</Button>
<Button
type="submit"
aria-label="save personal settings"
loading={profileForm.formState.isSubmitting}
>
Save profile
</Button>
</div>
)}
</Form>
{isReadOnly && (
<div className="mt-4 flex justify-between">
<Button
intent="primary"
aria-label="edit personal details"
onClick={() => {
setIsReadOnly(!isReadOnly)
setIsChangePassword(false)
}}
>
Edit
</Button>
{!isChangePassword ? (
<Button
intent="primary"
aria-label="change password"
onClick={() => setIsChangePassword(!isChangePassword)}
>
Change Password
</Button>
) : (
<Button
intent="outline"
aria-label="Cancel change password"
onClick={() => setIsChangePassword(!isChangePassword)}
>
Cancel Change Password
</Button>
)}
</div>
)}
{isChangePassword && <ChangePasswordForm />}
<div className="mb-4 mt-6">
</div>
<div className="mb-4">
<Input
label="Address"
placeholder="Address"
disabled
value={user.address}
/>
</div>
<div>
<div className="mb-4">
<Input
type="email"
label="Email"
Expand All @@ -151,6 +50,26 @@ export const PersonalSettingsForm = ({ user }: PersonalSettingsFormProps) => {
value={user.email}
/>
</div>
<div className="mt-4 flex justify-between">
{!isChangePassword ? (
<Button
intent="primary"
aria-label="change password"
onClick={() => setIsChangePassword(!isChangePassword)}
>
Change Password
</Button>
) : (
<Button
intent="outline"
aria-label="Cancel change password"
onClick={() => setIsChangePassword(!isChangePassword)}
>
Cancel Change Password
</Button>
)}
</div>
{isChangePassword && <ChangePasswordForm />}
</>
)
}
26 changes: 0 additions & 26 deletions packages/wallet/frontend/src/lib/api/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ import {
IframeResponse
} from '@wallet/shared'

export const profileSchema = z.object({
firstName: z.string().min(1, { message: 'First name is required' }),
lastName: z.string().min(1, { message: 'Last name is required' })
})

export const resetPasswordSchema = z
.object({
password: z
Expand Down Expand Up @@ -117,10 +112,6 @@ type VerifyEmailResponse = SuccessResponse | VerifyEmailError
type MeResult = SuccessResponse<UserResponse>
type MeResponse = MeResult | ErrorResponse

type ProfileArgs = z.infer<typeof profileSchema>
type ProfileError = ErrorResponse<ProfileArgs | undefined>
type ProfileResponse = SuccessResponse | ProfileError

type ChangePasswordArgs = z.infer<typeof changePasswordSchema>
type ChangePasswordError = ErrorResponse<ChangePasswordArgs | undefined>
type ChangePasswordResponse = SuccessResponse | ChangePasswordError
Expand All @@ -137,7 +128,6 @@ interface UserService {
checkToken: (token: string, cookies?: string) => Promise<CheckTokenResponse>
verifyEmail: (args: VerifyEmailArgs) => Promise<VerifyEmailResponse>
me: (cookies?: string) => Promise<MeResponse>
updateProfile: (args: ProfileArgs) => Promise<ProfileResponse>
changePassword: (args: ChangePasswordArgs) => Promise<ChangePasswordResponse>
resendVerifyEmail: (
args: ResendVerificationEmailArgs
Expand Down Expand Up @@ -288,22 +278,6 @@ const createUserService = (): UserService => ({
}
},

async updateProfile(args) {
try {
const response = await httpClient
.post('updateProfile', {
json: args
})
.json<SuccessResponse>()
return response
} catch (error) {
return getError<ProfileArgs>(
error,
'Something went wrong while updating your profile. Please try again.'
)
}
},

async changePassword(args) {
try {
const response = await httpClient
Expand Down
2 changes: 1 addition & 1 deletion packages/wallet/frontend/src/pages/auth/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ const LoginPage: NextPageWithLayout = () => {
/>
<span
onClick={togglePasswordVisibility}
className="absolute right-2.5 top-1/2 cursor-pointer"
className="absolute right-2.5 top-9 cursor-pointer"
>
{isPasswordVisible ? <SlashEye /> : <Eye />}
</span>
Expand Down
4 changes: 2 additions & 2 deletions packages/wallet/frontend/src/pages/auth/reset/[token].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ const ResetPasswordPage: NextPageWithLayout<ResetPasswordPageProps> = ({
/>
<span
onClick={togglePasswordVisibility}
className="absolute right-2.5 top-1/2 cursor-pointer"
className="absolute right-2.5 top-9 cursor-pointer"
>
{isPasswordVisible ? <SlashEye /> : <Eye />}
</span>
Expand All @@ -112,7 +112,7 @@ const ResetPasswordPage: NextPageWithLayout<ResetPasswordPageProps> = ({
/>
<span
onClick={toggleConfirmPasswordVisibility}
className="absolute right-2.5 top-1/2 cursor-pointer"
className="absolute right-2.5 top-9 cursor-pointer"
>
{isConfirmPasswordVisible ? <SlashEye /> : <Eye />}
</span>
Expand Down
4 changes: 2 additions & 2 deletions packages/wallet/frontend/src/pages/auth/signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ const SignUpPage: NextPageWithLayout = () => {
/>
<span
onClick={togglePasswordVisibility}
className="absolute right-2.5 top-1/2 cursor-pointer"
className="absolute right-2.5 top-9 cursor-pointer"
>
{isPasswordVisible ? <SlashEye /> : <Eye />}
</span>
Expand All @@ -116,7 +116,7 @@ const SignUpPage: NextPageWithLayout = () => {
/>
<span
onClick={toggleRepeatPasswordVisibility}
className="absolute right-2.5 top-1/2 cursor-pointer"
className="absolute right-2.5 top-9 cursor-pointer"
>
{isRepeatPasswordVisible ? <SlashEye /> : <Eye />}
</span>
Expand Down
2 changes: 1 addition & 1 deletion packages/wallet/frontend/src/pages/settings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const AccountSettingsPage: NextPageWithLayout<AccountSettingsProps> = ({
: '/bird-envelope-light.webp'
return (
<>
<PageHeader title="Personal Settings" message="Edit your details" />
<PageHeader title="Account Settings" />
<SettingsTabs />
<div className="flex w-full flex-col md:max-w-lg">
<PersonalSettingsForm user={user} />
Expand Down

0 comments on commit e55a13e

Please sign in to comment.