Commit 6e269424 authored by tom's avatar tom

my profile page re-design

parent 4eb5a26f
import { Button, chakra, FormControl, Heading, Input, InputGroup, InputRightElement, Text } from '@chakra-ui/react';
import type { UseQueryResult } from '@tanstack/react-query';
import React from 'react';
import type { SubmitHandler } from 'react-hook-form';
import { FormProvider, useForm } from 'react-hook-form';
import type { UserInfo } from 'types/api/account';
import { EMAIL_REGEXP } from 'lib/validations/email';
import IconSvg from 'ui/shared/IconSvg';
import InputPlaceholder from 'ui/shared/InputPlaceholder';
interface FormFields {
email: string;
}
interface Props {
profileQuery: UseQueryResult<UserInfo, unknown>;
}
const MyProfileEmail = ({ profileQuery }: Props) => {
const formApi = useForm<FormFields>({
mode: 'onBlur',
defaultValues: {
email: profileQuery.data?.email || '',
},
});
const onFormSubmit: SubmitHandler<FormFields> = React.useCallback((formData) => {
// eslint-disable-next-line no-console
console.log(formData);
}, [ ]);
const isDisabled = formApi.formState.isSubmitting;
return (
<section>
<Heading as="h2" size="sm" mb={ 3 }>Notifications</Heading>
<FormProvider { ...formApi }>
<chakra.form
noValidate
onSubmit={ formApi.handleSubmit(onFormSubmit) }
>
<FormControl variant="floating" isDisabled={ isDisabled } isRequired size="md">
<InputGroup>
<Input
{ ...formApi.register('email', { required: true, pattern: EMAIL_REGEXP }) }
required
isInvalid={ Boolean(formApi.formState.errors.email) }
isDisabled={ isDisabled }
autoComplete="off"
/>
<InputPlaceholder text="Email" error={ formApi.formState.errors.email }/>
{ !formApi.formState.isDirty && (
<InputRightElement h="100%">
<IconSvg name="certified" boxSize={ 5 } color="green.500"/>
</InputRightElement>
) }
</InputGroup>
<Text variant="secondary" mt={ 1 } fontSize="sm">Email for watch list notifications and private tags</Text>
</FormControl>
<Button
mt={ 6 }
size="sm"
variant="outline"
type="submit"
isDisabled={ formApi.formState.isSubmitting || !formApi.formState.isDirty }
isLoading={ formApi.formState.isSubmitting }
loadingText="Save changes"
>
Save changes
</Button>
</chakra.form>
</FormProvider>
</section>
);
};
export default React.memo(MyProfileEmail);
import { Button, Heading } from '@chakra-ui/react';
import type { UseQueryResult } from '@tanstack/react-query';
import React from 'react';
import type { UserInfo } from 'types/api/account';
interface Props {
profileQuery: UseQueryResult<UserInfo, unknown>;
}
const MyProfileWallet = ({ profileQuery }: Props) => {
return (
<section>
<Heading as="h2" size="sm" mb={ 3 }>My linked wallet</Heading>
{ !profileQuery.data?.address_hash && <Button size="sm">Link wallet</Button> }
</section>
);
};
export default React.memo(MyProfileWallet);
...@@ -11,6 +11,7 @@ import useGradualIncrement from 'lib/hooks/useGradualIncrement'; ...@@ -11,6 +11,7 @@ import useGradualIncrement from 'lib/hooks/useGradualIncrement';
import useToast from 'lib/hooks/useToast'; import useToast from 'lib/hooks/useToast';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
// TODO @tom2drum delete this page
{ /* will be deleted when we fix login in preview CI stands */ } { /* will be deleted when we fix login in preview CI stands */ }
const Login = () => { const Login = () => {
const toast = useToast(); const toast = useToast();
......
import { VStack, FormControl, FormLabel, Input } from '@chakra-ui/react'; import { Flex } from '@chakra-ui/react';
import React from 'react'; import React from 'react';
import useFetchProfileInfo from 'lib/hooks/useFetchProfileInfo'; import useFetchProfileInfo from 'lib/hooks/useFetchProfileInfo';
import useRedirectForInvalidAuthToken from 'lib/hooks/useRedirectForInvalidAuthToken'; import useRedirectForInvalidAuthToken from 'lib/hooks/useRedirectForInvalidAuthToken';
import MyProfileEmail from 'ui/myProfile/MyProfileEmail';
import MyProfileWallet from 'ui/myProfile/MyProfileWallet';
import ContentLoader from 'ui/shared/ContentLoader'; import ContentLoader from 'ui/shared/ContentLoader';
import DataFetchAlert from 'ui/shared/DataFetchAlert'; import DataFetchAlert from 'ui/shared/DataFetchAlert';
import PageTitle from 'ui/shared/Page/PageTitle'; import PageTitle from 'ui/shared/Page/PageTitle';
import UserAvatar from 'ui/shared/UserAvatar';
const MyProfile = () => { const MyProfile = () => {
const { data, isPending, isError } = useFetchProfileInfo(); const profileQuery = useFetchProfileInfo();
useRedirectForInvalidAuthToken(); useRedirectForInvalidAuthToken();
const content = (() => { const content = (() => {
if (isPending) { if (profileQuery.isPending) {
return <ContentLoader/>; return <ContentLoader/>;
} }
if (isError) { if (profileQuery.isError) {
return <DataFetchAlert/>; return <DataFetchAlert/>;
} }
return ( return (
<VStack maxW="412px" mt={ 8 } gap={ 5 } alignItems="stretch"> <Flex maxW="480px" mt={ 8 } flexDir="column" rowGap={ 12 }>
<UserAvatar size={ 64 }/> <MyProfileEmail profileQuery={ profileQuery }/>
<FormControl variant="floating" id="name" isRequired size="lg"> <MyProfileWallet profileQuery={ profileQuery }/>
<Input </Flex>
required
readOnly
value={ data.name || '' }
/>
<FormLabel>Name</FormLabel>
</FormControl>
<FormControl variant="floating" id="nickname" isRequired size="lg">
<Input
required
readOnly
value={ data.nickname || '' }
/>
<FormLabel>Nickname</FormLabel>
</FormControl>
<FormControl variant="floating" id="email" isRequired size="lg">
<Input
required
readOnly
value={ data.email || '' }
/>
<FormLabel>Email</FormLabel>
</FormControl>
</VStack>
); );
})(); })();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment