forked from VinokurovVE/tests
Settings & FormFields
This commit is contained in:
@ -1,11 +1,11 @@
|
||||
import { SubmitHandler, useForm } from 'react-hook-form'
|
||||
import { CreateField } from '../interfaces/create'
|
||||
import { Box, Button, CircularProgress, Stack, TextField, Typography } from '@mui/material';
|
||||
import { useEffect } from 'react';
|
||||
import { AxiosResponse } from 'axios';
|
||||
|
||||
interface Props {
|
||||
title?: string;
|
||||
submitHandler?: any;
|
||||
submitHandler?: (data: any) => Promise<AxiosResponse<any, any>>;
|
||||
fields: CreateField[];
|
||||
submitButtonText?: string;
|
||||
mutateHandler?: any;
|
||||
@ -29,15 +29,21 @@ function FormFields({
|
||||
return result
|
||||
}
|
||||
|
||||
const { register, handleSubmit, watch, formState: { errors, isSubmitting, dirtyFields } } = useForm({
|
||||
defaultValues: getDefaultValues(fields)
|
||||
const { register, handleSubmit, reset, watch, formState: { errors, isSubmitting, dirtyFields, isValid } } = useForm({
|
||||
mode: 'onChange',
|
||||
defaultValues: defaultValues ? getDefaultValues(fields) : {}
|
||||
})
|
||||
|
||||
const onSubmit: SubmitHandler<any> = async (data) => {
|
||||
try {
|
||||
await submitHandler?.(data).then(() => {
|
||||
mutateHandler?.()
|
||||
fields.forEach((field: CreateField) => {
|
||||
if (field.include === false) {
|
||||
delete data[field.key]
|
||||
}
|
||||
})
|
||||
try {
|
||||
const submitResponse = await submitHandler?.(data)
|
||||
mutateHandler?.(JSON.stringify(submitResponse?.data))
|
||||
reset(submitResponse?.data)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
@ -60,16 +66,17 @@ function FormFields({
|
||||
label={field.headerName || field.key.charAt(0).toUpperCase() + field.key.slice(1)}
|
||||
required={field.required || false}
|
||||
{...register(field.key, {
|
||||
required: `${field.key} обязателен`,
|
||||
required: field.required ? `${field.headerName} обязателен` : false,
|
||||
validate: (val: string | boolean) => {
|
||||
if (field.watch) {
|
||||
if (watch(field.watch) != val) {
|
||||
return field.watchMessage || ''
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
})}
|
||||
error={!!errors[field.key]}
|
||||
helperText={errors[field.key]?.message}
|
||||
/>
|
||||
)
|
||||
})}
|
||||
@ -79,7 +86,7 @@ function FormFields({
|
||||
justifyContent: "space-between",
|
||||
gap: "8px"
|
||||
}}>
|
||||
<Button disabled={isSubmitting} type="submit" variant="contained" color="primary">
|
||||
<Button disabled={isSubmitting || Object.keys(dirtyFields).length === 0 || !isValid} type="submit" variant="contained" color="primary">
|
||||
{isSubmitting ? <CircularProgress size={16} /> : submitButtonText}
|
||||
</Button>
|
||||
</Box>
|
||||
|
@ -26,6 +26,10 @@ export interface CreateField {
|
||||
defaultValue?: any;
|
||||
inputType?: InputType;
|
||||
validate?: Validate<string, boolean>;
|
||||
/** Watch for field */
|
||||
watch?: string;
|
||||
/** Message on watch */
|
||||
watchMessage?: string;
|
||||
/** Should field be included in the request */
|
||||
include?: boolean;
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
import { Box, Stack, Typography } from "@mui/material"
|
||||
import { Box, Stack } from "@mui/material"
|
||||
import UserService from "../services/UserService"
|
||||
import { useAuthStore } from "../store/auth"
|
||||
import { setUserData, useAuthStore } from "../store/auth"
|
||||
import { useEffect, useState } from "react"
|
||||
import { CreateField } from "../interfaces/create"
|
||||
import { IUser } from "../interfaces/user"
|
||||
import FormFields from "../components/FormFields"
|
||||
import AuthService from "../services/AuthService"
|
||||
|
||||
export default function Settings() {
|
||||
const { token } = useAuthStore()
|
||||
@ -25,8 +26,8 @@ export default function Settings() {
|
||||
}, [token])
|
||||
|
||||
const profileFields: CreateField[] = [
|
||||
{ key: 'email', headerName: 'E-mail', type: 'string', required: true },
|
||||
{ key: 'login', headerName: 'Логин', type: 'string', required: true },
|
||||
//{ key: 'email', headerName: 'E-mail', type: 'string', required: true },
|
||||
//{ key: 'login', headerName: 'Логин', type: 'string', required: true },
|
||||
{ key: 'phone', headerName: 'Телефон', type: 'string', required: false },
|
||||
{ key: 'name', headerName: 'Имя', type: 'string', required: true },
|
||||
{ key: 'surname', headerName: 'Фамилия', type: 'string', required: true },
|
||||
@ -34,11 +35,12 @@ export default function Settings() {
|
||||
|
||||
const passwordFields: CreateField[] = [
|
||||
{ key: 'password', headerName: 'Новый пароль', type: 'string', required: true, inputType: 'password' },
|
||||
{ key: 'password_confirm', headerName: 'Подтверждение пароля', type: 'string', required: true, inputType: 'password', watch: 'password', watchMessage: 'Пароли не совпадают' },
|
||||
{ key: 'password_confirm', headerName: 'Подтверждение пароля', type: 'string', required: true, inputType: 'password', watch: 'password', watchMessage: 'Пароли не совпадают', include: false },
|
||||
]
|
||||
|
||||
return (
|
||||
<Box sx={{
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "flex-start",
|
||||
@ -51,21 +53,22 @@ export default function Settings() {
|
||||
<FormFields
|
||||
fields={profileFields}
|
||||
defaultValues={currentUser}
|
||||
//submitHandler={RoleService.createRole}
|
||||
mutateHandler={(data: any) => {
|
||||
setUserData(data)
|
||||
}}
|
||||
submitHandler={(data) => UserService.updateUser({ id: currentUser.id, ...data })}
|
||||
title="Пользователь"
|
||||
/>
|
||||
</Stack>
|
||||
|
||||
<Stack width='100%'>
|
||||
<FormFields
|
||||
fields={passwordFields}
|
||||
defaultValues={currentUser}
|
||||
watchValues={['password, password_confirm']}
|
||||
//submitHandler={RoleService.createRole}
|
||||
submitHandler={(data) => AuthService.updatePassword({ id: currentUser.id, ...data })}
|
||||
title="Смена пароля"
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
}
|
||||
</Box>
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||
import { TextField, Button, Container, Typography, Box, Stack, Link } from '@mui/material';
|
||||
import { TextField, Button, Container, Typography, Box, Stack, Link, CircularProgress } from '@mui/material';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import { ApiResponse, LoginFormData } from '../../interfaces/auth';
|
||||
import { login, setUserData } from '../../store/auth';
|
||||
@ -8,7 +8,7 @@ import AuthService from '../../services/AuthService';
|
||||
import UserService from '../../services/UserService';
|
||||
|
||||
const SignIn = () => {
|
||||
const { register, handleSubmit, formState: { errors } } = useForm<LoginFormData>({
|
||||
const { register, handleSubmit, formState: { errors, isSubmitting } } = useForm<LoginFormData>({
|
||||
defaultValues: {
|
||||
username: '',
|
||||
password: '',
|
||||
@ -82,7 +82,7 @@ const SignIn = () => {
|
||||
|
||||
<Box sx={{ display: 'flex', gap: '16px' }}>
|
||||
<Button fullWidth type="submit" variant="contained" color="primary">
|
||||
Вход
|
||||
{isSubmitting ? <CircularProgress size={16} /> : 'Вход'}
|
||||
</Button>
|
||||
|
||||
<Button fullWidth href="/auth/signup" type="button" variant="text" color="primary">
|
||||
|
@ -1,13 +1,12 @@
|
||||
import { AxiosRequestConfig } from "axios";
|
||||
import { BASE_URL } from "../constants";
|
||||
import axiosInstance from "../http/axiosInstance";
|
||||
import { IUser } from "../interfaces/user";
|
||||
|
||||
const config: AxiosRequestConfig = {
|
||||
baseURL: BASE_URL.auth,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
// headers: {
|
||||
// 'Content-Type': 'application/x-www-form-urlencoded'
|
||||
// }
|
||||
}
|
||||
|
||||
export default class AuthService {
|
||||
@ -27,7 +26,7 @@ export default class AuthService {
|
||||
return await axiosInstance.put(`/auth/user/reset_password?email=${email}`, null, config)
|
||||
}
|
||||
|
||||
static async updatePassword(data: IUser) {
|
||||
static async updatePassword(data: { id: number, password: string }) {
|
||||
return await axiosInstance.put(`/auth/user/password_change`, data, config)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user