Skip to content

Refactoring #1

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

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
145 changes: 145 additions & 0 deletions components/ContactInfoForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import React, { memo } from "react";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если версия React ниже 17.00.0, то в компонентах мы обязаны импортировать React from "react" так как это JSX формат.


import localStorage from '../../../utils/browser/localStorage';
import { WarningIcon, SuccessIcon } from '../../../Icons';
import { Input, SuggestionsInput, FormRow, Button, Range } from '../../../UiComponents';
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Некоторые импорты имеет смысл переделать на алиасы
../../../utils/browser/localStorage -> utils/browser/localStorage
../../../Icons -> Icons
../../../UiComponents -> UiComponents

import { MAGIC_STRINGS, LOCALES } from "./const";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Но не все. Так файл const относится только к данному компоненту. Его лучше оставить относительным.


export const ContactInfoForm = (props) => {
const {
userInfo,
setValue,
validate,
internalErrors,
removeError,
permissions,
phoneVerification,
username,
openModal,
whatsApp,
whatsAppSetNotifications,
} = props;

const sameUser = username === userInfo.username;
const whatsAppEnabled = sameUser && whatsApp && whatsApp.bot_enabled;
const userWorkHours = sameUser && userInfo.workHours;

const phoneVerificationButton = sameUser && (
<Button
type={MAGIC_STRINGS.text}
tooltip={phoneVerification ? LOCALES.phoneConfirmed : LOCALES.phoneNotConfirmed}
mode={phoneVerification ? MAGIC_STRINGS.success : MAGIC_STRINGS.error}
onClick={
!localStorage.getSwitchUser() && !phoneVerification
? () => openModal(MAGIC_STRINGS.verificationPhoneModal)
: () => null
}
>
{phoneVerification ? <SuccessIcon /> : <WarningIcon />}
</Button>
);

const whatsAppNotifyButton = (
<Button
inline
onClick={(e) => {
e.preventDefault();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

У некоторых компонентов Button нет вызова event.preventDefault()
Это повод проверить необходимость данного вызова и удалить его в остальных местах, если он не нужен.

whatsAppSetNotifications(!whatsApp.notify_enabled);
}}
>
{whatsApp.notify_enabled ? LOCALES.notifyWhatsappDisable : LOCALES.notifyWhatsappEnable}
</Button>
);
const whatsAppBotButton = (
<Button
inline
onClick={() =>
openModal(MAGIC_STRINGS.whatsAppAuthModal, {
link: whatsApp[MAGIC_STRINGS.redirect_url],
})
}
>
{LOCALES.whatsappBotEnable}
</Button>
);

return (
<>
<FormRow>
<Input
id={MAGIC_STRINGS.email}
label={LOCALES.email}
size='lg'
disabled={!permissions.editEmail}
value={userInfo.email}
onChange={(value) => setValue([MAGIC_STRINGS.userInfo, MAGIC_STRINGS.email], value)}
onBlur={(value) => {
validate(MAGIC_STRINGS.email, value);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Функции в onChange, onBlur можно вынести в отдельные хендлеры. Тогда компонент будет чище, логика и отображение будут разделены.

}}
error={internalErrors.email}
/>
<Input
id={MAGIC_STRINGS.phone}
label={LOCALES.phone}
disabled={!permissions.editPhone}
value={userInfo.phone}
onChange={(value) => setValue([MAGIC_STRINGS.userInfo, MAGIC_STRINGS.phone], value)}
onBlur={(value) => {
validate(MAGIC_STRINGS.phone, value);
}}
error={internalErrors.phone}
after={phoneVerificationButton}
/>
{
whatsAppEnabled
&& (whatsApp.bot_started ? whatsAppNotifyButton : whatsAppBotButton)
}
<SuggestionsInput
id={MAGIC_STRINGS.address}
label={LOCALES.address}
placeholder={LOCALES.addressDefault}
name={MAGIC_STRINGS.address}
size='xl'
value={userInfo.address}
list={userInfo.addressList}
keyName={MAGIC_STRINGS.text}
onChange={setValue}
onBlur={(address) => {
validate(MAGIC_STRINGS.addressInProfile, address);
removeError(MAGIC_STRINGS.addressInProfile);
}}
error={internalErrors.addressInProfile}
/>
</FormRow>
{permissions.editNote && (
<FormRow>
<Input
id={MAGIC_STRINGS.description}
label={LOCALES.remark}
rows='3'
size='stretch'
disabled={!permissions.editNote}
value={userInfo.notes}
onChange={(value) => setValue([MAGIC_STRINGS.userInfo, MAGIC_STRINGS.notes], value)}
/>
</FormRow>
)}
{userWorkHours && (
<>
{LOCALES.workHours}
<FormRow>
<Range
step={1}
min={0}
max={23}
values={userInfo.workHours}
onChange={(value) => setValue([MAGIC_STRINGS.userInfo, MAGIC_STRINGS.workHours], value)}
/>
</FormRow>
</>
)}
</>
);
};

export default memo(ContactInfoForm);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Мемоизация поможет избежать лишних ререндеров.

146 changes: 146 additions & 0 deletions components/LegalInfoForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import React, { memo } from "react";
import moment from "moment";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Библиотека moment.js deprecated. Можно использовать более легковесную библиотеку day.js


import {
Input,
DateInput,
RadioButtons,
FormRow,
} from "../../../UiComponents";
import { MAGIC_STRINGS, LOCALES, REGEXP, DATES_FORMAT } from "./const";

export const LegalInfoForm = (props) => {
const {
userInfo,
setValue,
validate,
internalErrors,
isJuridical,
permissions,
rejectSet,
} = props;

const setIsJuridical = (value) => {
if (permissions.editJuridical) {
setValue([MAGIC_STRINGS.userInfo, MAGIC_STRINGS.isJuridical], value);
} else {
rejectSet(LOCALES.juridicalError);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Смущает название. Ассоциируется с Promise.reject.
  • Необходимо разобраться, за что отвечает данная функция. Есть вероятность, что ее функциональность может быть реализована через банальный useState в данном компоненте.

}
};

return (
<FormRow>
<RadioButtons
id={MAGIC_STRINGS.isJuridical}
value={isJuridical}
list={[
{ title: LOCALES.physical, value: false },
{ title: LOCALES.juridical, value: true },
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно вынести в константы, зависит от код стиля проекта и необходимости переиспользовать такого типа объект.

]}
onChange={(value) => setIsJuridical(value)}
/>
{isJuridical ? (
<Input
id={MAGIC_STRINGS.inn}
label={LOCALES.inn}
maxLength="12"
value={userInfo.inn}
onChange={(value) => {
if (
REGEXP.inn.test(value) ||
value.length < userInfo.inn.length
)
return setValue([MAGIC_STRINGS.userInfo, MAGIC_STRINGS.inn], value);
}}
/>
) : (
<>
<Input
id={MAGIC_STRINGS.series}
label={LOCALES.passportSerial}
placeholder={LOCALES.passportSerialDefault}
maxLength="4"
size="xs"
value={userInfo.series}
onChange={(value) => {
if (
REGEXP.passportSerial.test(value) ||
value.length < userInfo.series.length
)
return setValue([MAGIC_STRINGS.userInfo, MAGIC_STRINGS.series], value);
}}
onBlur={(value) => {
validate(MAGIC_STRINGS.series, value, {
documentType: MAGIC_STRINGS.passport,
});
}}
error={internalErrors.series}
/>
<Input
id={MAGIC_STRINGS.number}
label={LOCALES.passportNumber}
placeholder={LOCALES.passportNumberDefault}
maxLength="6"
size="xs"
value={userInfo.number}
onChange={(value) => {
if (
REGEXP.passportNumber.test(value) ||
value.length < userInfo.number.length
)
return setValue([MAGIC_STRINGS.userInfo, MAGIC_STRINGS.number], value);
}}
onBlur={(value) => {
validate(MAGIC_STRINGS.number, value, {
documentType: MAGIC_STRINGS.passport,
});
}}
error={internalErrors.number}
/>
<DateInput
id={MAGIC_STRINGS.birthday}
label={LOCALES.birthday}
value={userInfo.birthday}
onChange={(value) => {
if (
REGEXP.birthday.test(value) ||
value.length < userInfo.birthday.length
)
return setValue([MAGIC_STRINGS.userInfo, MAGIC_STRINGS.birthday], value);
}}
onBlur={(value) => {
validate(MAGIC_STRINGS.birthday, value);
if (userInfo.issuedAt)
validate(MAGIC_STRINGS.issuedAt, userInfo.issuedAt, {
documentType: MAGIC_STRINGS.passport,
birth: value,
});
if (moment(value, DATES_FORMAT.DDMMYYYY).isValid()) {
setValue(
[MAGIC_STRINGS.userInfo, MAGIC_STRINGS.birthday],
moment(value, DATES_FORMAT.DDMMYYYY).format(DATES_FORMAT.DDMMYYYY)
);
}
}}
error={internalErrors.birthday}
/>
<Input
id={MAGIC_STRINGS.snils}
label={LOCALES.snils}
maxLength="11"
value={userInfo.snils}
onChange={(value) => {
if (
REGEXP.snils.test(value) ||
value.length < userInfo.snils.length
)
return setValue([MAGIC_STRINGS.userInfo, MAGIC_STRINGS.snils], value);
}}
/>
</>
)}
</FormRow>
);
};

export default memo(LegalInfoForm);
Loading