Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ameerul / FEQ-2343 Fix the issues on My profile page #126

Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const BlockUnblockUserModal = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isSuccess, onClickBlocked, unblockIsSuccess, unblockError, error, setErrorMessage]);

const textSize = isMobile ? 'md' : 'sm';
const getModalTitle = () => (isBlocked ? `Unblock ${advertiserName}?` : `Block ${advertiserName}?`);

const getModalContent = () =>
Expand Down Expand Up @@ -82,7 +83,7 @@ const BlockUnblockUserModal = ({
</Text>
</Modal.Header>
<Modal.Body>
<Text as='p' className='px-[1.6rem] lg:px-[2.4rem]' size={isMobile ? 'md' : 'sm'}>
<Text as='p' className='px-[1.6rem] lg:px-[2.4rem]' size={textSize}>
{getModalContent()}
</Text>
</Modal.Body>
Expand All @@ -92,12 +93,12 @@ const BlockUnblockUserModal = ({
color='black'
onClick={onRequestClose}
size='lg'
textSize='sm'
textSize={textSize}
variant='outlined'
>
<Localize i18n_default_text='Cancel' />
</Button>
<Button onClick={onClickBlockUnblock} size='lg' textSize='sm'>
<Button onClick={onClickBlockUnblock} size='lg' textSize={textSize}>
{isBlocked ? <Localize i18n_default_text='Unblock' /> : <Localize i18n_default_text='Block' />}
</Button>
</Modal.Footer>
Expand Down
1 change: 1 addition & 0 deletions src/components/PaymentMethodCard/PaymentMethodCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const PaymentMethodCard = ({
isEditable={isEditable}
isSelectable={!isEditable && toAdd}
isSelected={isSelected}
medium={medium}
onDeletePaymentMethod={onDeletePaymentMethod}
onEditPaymentMethod={onEditPaymentMethod}
onSelectPaymentMethod={() => onSelectPaymentMethodCard?.(Number(paymentMethod.id))}
Expand Down
5 changes: 3 additions & 2 deletions src/components/PaymentMethodForm/PaymentMethodForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const PaymentMethodForm = ({
}: TPaymentMethodFormProps) => {
const {
control,
formState: { isDirty, isSubmitting, isValid },
formState: { dirtyFields, isDirty, isSubmitting, isValid },
handleSubmit,
reset,
} = useForm({ mode: 'all' });
Expand Down Expand Up @@ -63,8 +63,9 @@ const PaymentMethodForm = ({
}));
return listItems || [];
}, [availablePaymentMethods]);

const handleGoBack = () => {
if (isDirty) {
if (Object.keys(dirtyFields).length) {
ameerul-deriv marked this conversation as resolved.
Show resolved Hide resolved
setIsError(true);
} else {
onResetFormState();
Expand Down
13 changes: 13 additions & 0 deletions src/components/Search/Search.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
width: 100%;
background-color: #fff;

input[type='search']::-webkit-search-cancel-button {
display: none;
}

rect {
fill: #999;
}

.deriv-input {
padding: 6px 8px;
font-size: 1.4rem;
Expand Down Expand Up @@ -30,5 +38,10 @@
&__label {
left: 3rem;
}

&__right-content {
display: flex;
align-items: center;
}
}
}
30 changes: 23 additions & 7 deletions src/components/Search/Search.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useCallback } from 'react';
import { useCallback, useState } from 'react';
import clsx from 'clsx';
import { LabelPairedSearchMdRegularIcon } from '@deriv/quill-icons';
import { LabelPairedSearchMdRegularIcon, LegacyCloseCircle1pxIcon } from '@deriv/quill-icons';
import { Input } from '@deriv-com/ui';
import './Search.scss';

Expand All @@ -14,6 +14,8 @@ type TSearchProps = {

//TODO: replace the component with deriv shared component
const Search = ({ delayTimer = 500, hideBorder = false, name, onSearch, placeholder }: TSearchProps) => {
const [searchValue, setSearchValue] = useState('');

const debounce = (func: (value: string) => void, delay: number) => {
let timer: ReturnType<typeof setTimeout>;
return (value: string) => {
Expand All @@ -22,20 +24,34 @@ const Search = ({ delayTimer = 500, hideBorder = false, name, onSearch, placehol
};
};

// eslint-disable-next-line react-hooks/exhaustive-deps
const debouncedOnSearch = useCallback(debounce(onSearch, delayTimer), [onSearch]);

const handleInputChange = (event: React.FormEvent<HTMLFormElement>) => {
const value = (event.target as HTMLInputElement).value;
setSearchValue(value);
debouncedOnSearch(value);
};

const clearSearch = () => {
setSearchValue('');
debouncedOnSearch('');
};

return (
<form
className='search'
onChange={event => debouncedOnSearch((event.target as HTMLInputElement).value)}
role='search'
>
<form className='search' onChange={event => handleInputChange(event)} role='search'>
<Input
ameerul-deriv marked this conversation as resolved.
Show resolved Hide resolved
className={clsx({ 'border-none': hideBorder })}
label={placeholder}
leftPlaceholder={<LabelPairedSearchMdRegularIcon />}
name={name}
rightPlaceholder={
searchValue && (
<LegacyCloseCircle1pxIcon className='cursor-pointer' iconSize='xs' onClick={clearSearch} />
)
}
type='search'
value={searchValue}
/>
ameerul-deriv marked this conversation as resolved.
Show resolved Hide resolved
</form>
);
Expand Down
3 changes: 2 additions & 1 deletion src/pages/my-profile/screens/MyProfile/MyProfile.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
flex-direction: column;
padding-top: 2.4rem;
overflow-y: auto;
height: calc(100vh - 19rem);
max-height: calc(100vh - 19rem);

@include mobile {
padding: 0;
max-height: calc(100vh - 11rem);
}

&__tabs {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,21 @@

& .deriv-textarea {
&__footer {
justify-content: space-between;

& .deriv-text {
font-size: 1.2rem;
margin-top: -0.5rem;
margin-left: 1rem;

@include mobile {
margin-top: -0.2rem;
line-height: 1.4rem;
}

&:only-child {
margin-left: auto;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,133 +1,110 @@
import { Dispatch, SetStateAction, useEffect, useMemo, useState } from 'react';
import { useEffect } from 'react';
import clsx from 'clsx';
import { debounce } from 'lodash';
import { Control, FieldValues, useForm } from 'react-hook-form';
import { FullPageMobileWrapper } from '@/components';
import { api } from '@/hooks';
import { useQueryString } from '@/hooks/custom-hooks';
import { LabelPairedCheckMdFillIcon } from '@deriv/quill-icons';
import { Localize, useTranslations } from '@deriv-com/translations';
import { Button, Loader, Text, TextArea, useDevice } from '@deriv-com/ui';
import { Localize } from '@deriv-com/translations';
import { Button, Loader, Text, useDevice } from '@deriv-com/ui';
import { MyProfileAdDetailsTextArea } from './MyProfileAdDetailsTextArea';
import './MyProfileAdDetails.scss';

type TMYProfileAdDetailsTextAreaProps = {
advertDescription: string;
contactInfo: string;
setAdvertDescription: Dispatch<SetStateAction<string>>;
setContactInfo: Dispatch<SetStateAction<string>>;
};

const MyProfileAdDetailsTextArea = ({
advertDescription,
contactInfo,
setAdvertDescription,
setContactInfo,
}: TMYProfileAdDetailsTextAreaProps) => {
const { localize } = useTranslations();
const { isMobile } = useDevice();
const textSize = isMobile ? 'md' : 'sm';
return (
<>
<TextArea
data-testid='dt_profile_ad_details_contact'
label={localize('Contact details')}
maxLength={300}
onChange={e => setContactInfo(e.target.value)}
shouldShowCounter
textSize={textSize}
value={contactInfo}
/>
<TextArea
data-testid='dt_profile_ad_details_description'
hint={localize('This information will be visible to everyone.')}
label={localize('Instructions')}
maxLength={300}
onChange={e => setAdvertDescription(e.target.value)}
shouldShowCounter
textSize={textSize}
value={advertDescription}
/>
</>
);
};

const MyProfileAdDetails = () => {
const { data: advertiserInfo, isLoading } = api.advertiser.useGetInfo();
const { isPending, mutate: updateAdvertiser } = api.advertiser.useUpdate();
const [contactInfo, setContactInfo] = useState('');
const [advertDescription, setAdvertDescription] = useState('');
const { isSuccess, mutate: updateAdvertiser, reset } = api.advertiser.useUpdate();
const { isMobile } = useDevice();
const { setQueryString } = useQueryString();

const hasUpdated = useMemo(() => {
return (
contactInfo !== advertiserInfo?.contact_info ||
advertDescription !== advertiserInfo?.default_advert_description
);
}, [advertiserInfo?.contact_info, advertiserInfo?.default_advert_description, contactInfo, advertDescription]);
const {
control,
formState: { isDirty, isValid },
getValues,
handleSubmit,
reset: resetForm,
watch,
} = useForm({
defaultValues: {
ad_details_contact: advertiserInfo?.contact_info,
ad_details_description: advertiserInfo?.default_advert_description,
},
mode: 'onChange',
});

const debouncedReset = debounce(() => {
reset();
resetForm(watch(), { keepDefaultValues: false, keepDirty: false, keepValues: false });
}, 2000);

const isButtonDisabled = !isDirty || !isValid || isSuccess;
const saveButtonClass = clsx({ 'my-profile-ad-details__button--submitting': isSuccess });
const buttonIcon = isSuccess ? <LabelPairedCheckMdFillIcon fill='#fff' /> : null;

useEffect(() => {
setContactInfo(advertiserInfo?.contact_info || '');
setAdvertDescription(advertiserInfo?.default_advert_description || '');
}, [advertiserInfo]);
if (isSuccess) debouncedReset();
}, [debouncedReset, isSuccess]);

const submitAdDetails = () => {
updateAdvertiser({
contact_info: contactInfo,
default_advert_description: advertDescription,
contact_info: getValues('ad_details_contact'),
default_advert_description: getValues('ad_details_description'),
});
};

if (isLoading && !advertiserInfo) return <Loader className='mt-16' />;

if (isMobile) {
return (
<FullPageMobileWrapper
className='my-profile-ad-details__mobile-wrapper'
onBack={() =>
setQueryString({
tab: 'default',
})
}
renderFooter={() => (
<Button disabled={!hasUpdated} isFullWidth onClick={submitAdDetails} size='lg'>
<Localize i18n_default_text='Save' />
</Button>
)}
renderHeader={() => (
<Text size='lg' weight='bold'>
<Localize i18n_default_text='Ad Details ' />
</Text>
)}
>
<div className='my-profile-ad-details'>
<MyProfileAdDetailsTextArea
advertDescription={advertDescription}
contactInfo={contactInfo}
setAdvertDescription={setAdvertDescription}
setContactInfo={setContactInfo}
/>
</div>
</FullPageMobileWrapper>
<form onSubmit={handleSubmit(submitAdDetails)}>
<FullPageMobileWrapper
className='my-profile-ad-details__mobile-wrapper'
onBack={() =>
setQueryString({
tab: 'default',
})
}
renderFooter={() => (
<Button
className={saveButtonClass}
disabled={!isDirty || !isValid || isSuccess}
icon={buttonIcon}
isFullWidth
size='lg'
>
<Localize i18n_default_text='Save' />
</Button>
)}
renderHeader={() => (
<Text size='lg' weight='bold'>
<Localize i18n_default_text='Ad Details ' />
</Text>
)}
>
<div className='my-profile-ad-details'>
<MyProfileAdDetailsTextArea control={control as unknown as Control<FieldValues>} />
</div>
</FullPageMobileWrapper>
</form>
);
}

return (
<div className='my-profile-ad-details'>
<MyProfileAdDetailsTextArea
advertDescription={advertDescription}
contactInfo={contactInfo}
setAdvertDescription={setAdvertDescription}
setContactInfo={setContactInfo}
/>
<div className='my-profile-ad-details__border' />
<Button
className={isPending ? 'my-profile-ad-details__button--submitting' : ''}
disabled={!hasUpdated || isPending}
icon={isPending ? <LabelPairedCheckMdFillIcon fill='#fff' /> : null}
onClick={submitAdDetails}
size='lg'
textSize='sm'
>
<Localize i18n_default_text='Save' />
</Button>
</div>
<form onSubmit={handleSubmit(submitAdDetails)}>
<div className='my-profile-ad-details'>
<MyProfileAdDetailsTextArea control={control as unknown as Control<FieldValues>} />
<div className='my-profile-ad-details__border' />
<Button
className={saveButtonClass}
disabled={isButtonDisabled}
icon={buttonIcon}
size='lg'
textSize='sm'
>
<Localize i18n_default_text='Save' />
</Button>
</div>
</form>
);
};

Expand Down
Loading
Loading