Frontend/src/user/views/PersonalInfomrationEditor.tsx
2022-07-18 11:38:44 +03:00

132 lines
4.2 KiB
TypeScript

import React from "react";
import Modal from "components/containers/modal/Modal";
import Button from "components/controls/Button";
import InputField from "components/controls/InputField";
import { useUserStore } from "../data/userSlice";
import { ReactComponent as SVGCircleProgressIcon } from "assets/svg/circle-progress.svg";
import classNames from "classnames";
import { useTranslation } from "react-i18next";
import { Formik } from "formik";
import * as Yup from "yup";
import { useUserViewModel } from "user/controller/userViewModel";
import { User } from "user/domain/userEntity";
type Props = {
isShown: boolean;
onClose: VoidFunction;
};
type FormValues = Pick<User, "username" | "firstname" | "lastname">;
type FormValuesValidation = {
[Prop in keyof FormValues]: any;
};
export default function PersonalInfomrationEditor({
isShown,
onClose: extOnClose,
}: Props) {
const { t } = useTranslation();
const store = useUserStore();
const { user, updatePersonalInfo } = useUserViewModel(store);
const onClose = React.useCallback(() => {
extOnClose();
}, [extOnClose]);
return (
<Modal isOpen={isShown} onClose={onClose} className="max-w-lg">
<Modal.CloseButton onClose={onClose} />
<Modal.Header>{t("account.info")}</Modal.Header>
<Formik
initialValues={{
username: user?.username || "",
firstname: user?.firstname || "",
lastname: user?.lastname || "",
}}
validationSchema={Yup.object().shape<FormValuesValidation>({
username: Yup.string()
.min(2, "min 2 characters")
.max(50, "50 characters max")
.notRequired(),
firstname: Yup.string()
.min(2, "min 2 characters")
.max(50, "50 characters max")
.required("required field"),
lastname: Yup.string()
.min(2, "min 2 characters")
.max(50, "50 characters max")
.required("required field"),
})}
onSubmit={(values, actions) => {
updatePersonalInfo(values)?.then(() => {
onClose();
});
}}
>
{(formik) => (
<form onSubmit={formik.handleSubmit}>
<InputField
name="username"
placeholder="Nickname"
value={formik.values.username}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
autoComplete="off"
error={formik.errors.username}
touched={formik.touched.username}
/>
<InputField
name="firstname"
placeholder="Firstname"
value={formik.values.firstname}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.errors.firstname}
touched={formik.touched.firstname}
/>
<InputField
name="lastname"
placeholder="Lastname"
value={formik.values.lastname}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
error={formik.errors.lastname}
touched={formik.touched.lastname}
/>
<Modal.Footer className="flex justify-between">
<Button type="text" variant="red" onClick={onClose}>
{t("cancel")}
</Button>
<Button
disabled={
!formik.isValid || formik.isSubmitting || !formik.touched
}
htmlType="submit"
type="fill"
variant="blue"
glowing={true}
className="relative"
>
<span
className={classNames({ "opacity-0": formik.isSubmitting })}
>
{t("save")}
</span>
<SVGCircleProgressIcon
className={classNames(
"absolute top-1/2 left-1/2 trasnform -translate-x-1/2 -translate-y-1/2 w-8 h-8 stroke-current",
{ "opacity-0": !formik.isSubmitting }
)}
/>
</Button>
</Modal.Footer>
</form>
)}
</Formik>
</Modal>
);
}