front-hub/src/pages/AccountSettings/AccountSettings.tsx

301 lines
10 KiB
TypeScript
Raw Normal View History

2023-07-06 21:52:07 +00:00
import { useEffect } from "react";
import {
Box,
SxProps,
Theme,
Typography,
useMediaQuery,
useTheme,
} from "@mui/material";
import CustomButton from "@components/CustomButton";
import InputTextfield from "@components/InputTextfield";
import PasswordInput from "@components/passwordInput";
import SectionWrapper from "@components/SectionWrapper";
2023-07-06 21:52:07 +00:00
import {
openDocumentsDialog,
sendUserData,
setSettingsField,
useUserStore,
} from "@root/stores/user";
2023-06-02 08:22:14 +00:00
import UnderlinedButtonWithIcon from "@root/components/UnderlinedButtonWithIcon";
import UploadIcon from "@root/components/icons/UploadIcon";
import DocumentsDialog from "./DocumentsDialog/DocumentsDialog";
import EyeIcon from "@root/components/icons/EyeIcon";
2023-06-16 19:04:59 +00:00
import { cardShadow } from "@root/utils/themes/shadow";
2023-06-24 18:17:43 +00:00
import { getMessageFromFetchError } from "@frontend/kitui";
import { enqueueSnackbar } from "notistack";
2023-07-06 21:52:07 +00:00
import { VerificationStatus } from "@root/model/account";
import { verify } from "./helper";
2023-03-19 11:26:09 +00:00
2023-06-24 12:03:12 +00:00
export default function AccountSettings() {
2023-07-06 21:52:07 +00:00
const theme = useTheme();
const upMd = useMediaQuery(theme.breakpoints.up("md"));
const upSm = useMediaQuery(theme.breakpoints.up("sm"));
const fields = useUserStore((state) => state.settingsFields);
const verificationStatus = useUserStore((state) => state.verificationStatus);
const verificationType = useUserStore((state) => state.verificationType);
const comment = useUserStore((state) => state.comment);
2023-07-13 12:11:30 +00:00
const userId = useUserStore((state) => state.userId) ?? "";
2023-06-02 08:22:14 +00:00
2023-07-06 21:52:07 +00:00
useEffect(() => {
2023-07-13 12:11:30 +00:00
verify(userId);
2023-07-06 21:52:07 +00:00
}, []);
2023-05-30 18:34:41 +00:00
2023-07-06 21:52:07 +00:00
const textFieldProps = {
gap: upMd ? "16px" : "10px",
color: "#F2F3F7",
bold: true,
};
2023-06-24 18:17:43 +00:00
2023-07-06 21:52:07 +00:00
const verificationStatusData: Record<
VerificationStatus,
{ text: string; color: string }
> = {
verificated: { text: "Верификация пройдена", color: "#0D9F00" },
waiting: { text: "В ожидании верификации", color: "#F18956" },
notVerificated: { text: "Не верифицирован", color: "#E02C2C" },
};
2023-05-30 18:34:41 +00:00
2023-07-06 21:52:07 +00:00
function handleSendDataClick() {
sendUserData()
.then(() => {
enqueueSnackbar("Информация обновлена");
})
.catch((error) => {
const message = getMessageFromFetchError(error);
if (message) enqueueSnackbar(message);
});
}
2023-05-30 18:34:41 +00:00
2023-07-06 21:52:07 +00:00
function VerificationIndicator({
verificationStatus,
sx,
}: {
2023-05-30 18:34:41 +00:00
verificationStatus: VerificationStatus;
sx?: SxProps<Theme>;
2023-07-06 21:52:07 +00:00
}) {
2023-05-30 18:34:41 +00:00
return (
2023-07-06 21:52:07 +00:00
<Box
sx={{
py: "14px",
px: "8.5px",
borderWidth: "1px",
borderStyle: "solid",
color: verificationStatusData[verificationStatus].color,
borderColor: verificationStatusData[verificationStatus].color,
borderRadius: "8px",
textAlign: "center",
...sx,
}}
>
<Typography lineHeight="100%">
{verificationStatusData[verificationStatus].text}
</Typography>
</Box>
2023-05-30 18:34:41 +00:00
);
2023-07-06 21:52:07 +00:00
}
return (
<SectionWrapper
maxWidth="lg"
sx={{
mt: "25px",
mb: "70px",
}}
>
<DocumentsDialog />
<Typography variant="h4" mt="20px">
Настройки аккаунта
</Typography>
<Box
sx={{
mt: "40px",
mb: "40px",
backgroundColor: "white",
display: "flex",
flexDirection: "column",
borderRadius: "12px",
p: "20px",
gap: "40px",
boxShadow: cardShadow,
}}
>
<Box
sx={{
display: "flex",
gap: "31px",
justifyContent: "space-between",
flexDirection: upMd ? "row" : "column",
}}
>
<Box
sx={{
display: "grid",
gridAutoFlow: upSm ? "column" : "row",
gridTemplateRows: "repeat(4, auto)",
gridAutoColumns: "1fr",
rowGap: "15px",
columnGap: "31px",
flexGrow: 1,
}}
>
<InputTextfield
TextfieldProps={{
placeholder: "Имя",
value: fields.firstname.value || "",
helperText: fields.firstname.touched && fields.firstname.error,
error:
fields.firstname.touched && Boolean(fields.firstname.error),
}}
onChange={(e) => setSettingsField("firstname", e.target.value)}
id="firstname"
label="Имя"
{...textFieldProps}
/>
<InputTextfield
TextfieldProps={{
placeholder: "Фамилия",
value: fields.secondname.value || "",
helperText:
fields.secondname.touched && fields.secondname.error,
error:
fields.secondname.touched && Boolean(fields.secondname.error),
}}
onChange={(e) => setSettingsField("secondname", e.target.value)}
id="secondname"
label="Фамилия"
{...textFieldProps}
/>
<InputTextfield
TextfieldProps={{
placeholder: "Отчество",
value: fields.middlename.value || "",
helperText:
fields.middlename.touched && fields.middlename.error,
error:
fields.middlename.touched && Boolean(fields.middlename.error),
}}
onChange={(e) => setSettingsField("middlename", e.target.value)}
id="middlename"
label="Отчество"
{...textFieldProps}
/>
<InputTextfield
TextfieldProps={{
placeholder: "ООО Фирма",
value: fields.orgname.value || "",
helperText: fields.orgname.touched && fields.orgname.error,
error: fields.orgname.touched && Boolean(fields.orgname.error),
}}
onChange={(e) => setSettingsField("orgname", e.target.value)}
id="orgname"
label="Название компании"
{...textFieldProps}
/>
<InputTextfield
TextfieldProps={{
placeholder: "username@penahaub.com",
value: fields.email.value || "",
helperText: fields.email.touched && fields.email.error,
error: fields.email.touched && Boolean(fields.email.error),
}}
onChange={(e) => setSettingsField("email", e.target.value)}
id="email"
label="E-mail"
{...textFieldProps}
/>
<InputTextfield
TextfieldProps={{
placeholder: "+7 900 000 00 00",
value: fields.phoneNumber.value || "",
helperText:
fields.phoneNumber.touched && fields.phoneNumber.error,
error:
fields.phoneNumber.touched &&
Boolean(fields.phoneNumber.error),
}}
onChange={(e) => setSettingsField("phoneNumber", e.target.value)}
id="phoneNumber"
label="Телефон"
{...textFieldProps}
/>
<PasswordInput
TextfieldProps={{
placeholder: "Не менее 8 символов",
value: fields.password.value || "",
helperText: fields.password.touched && fields.password.error,
error:
fields.password.touched && Boolean(fields.password.error),
autoComplete: "new-password",
}}
onChange={(e) => setSettingsField("password", e.target.value)}
id="password"
label="Пароль"
{...textFieldProps}
/>
</Box>
<Box
sx={{
maxWidth: "246px",
}}
>
<Typography variant="p1">Статус</Typography>
<VerificationIndicator
verificationStatus={verificationStatus}
sx={{ mt: "16px", p: "14px 7.5px" }}
/>
{verificationStatus === VerificationStatus.NOT_VERIFICATED && (
<>
<UnderlinedButtonWithIcon
icon={<UploadIcon />}
sx={{ mt: "55px" }}
ButtonProps={{
onClick: () => openDocumentsDialog("juridical"),
}}
>
Загрузить документы для юр лиц
</UnderlinedButtonWithIcon>
<UnderlinedButtonWithIcon
icon={<UploadIcon />}
sx={{ mt: "15px" }}
ButtonProps={{
onClick: () => openDocumentsDialog("nko"),
}}
>
Загрузить документы для НКО
</UnderlinedButtonWithIcon>
</>
)}
{verificationStatus === VerificationStatus.VERIFICATED && (
<UnderlinedButtonWithIcon
icon={<EyeIcon />}
sx={{ mt: "55px" }}
ButtonProps={{
onClick: () => openDocumentsDialog(verificationType),
}}
>
Посмотреть свою верификацию
</UnderlinedButtonWithIcon>
)}
{comment && <p>{comment}</p>}
</Box>
</Box>
<CustomButton
onClick={handleSendDataClick}
variant="contained"
disabled={fields.hasError}
sx={{
width: "180px",
height: "44px",
alignSelf: "end",
backgroundColor: theme.palette.brightPurple.main,
textColor: "white",
}}
>
Сохранить
</CustomButton>
</Box>
</SectionWrapper>
);
}