Browse Source

Settings & FormFields

master
cracklesparkle 10 months ago
parent
commit
748aa81a99
  1. 27
      frontend_reactjs/src/components/FormFields.tsx
  2. 4
      frontend_reactjs/src/interfaces/create.ts
  3. 35
      frontend_reactjs/src/pages/Settings.tsx
  4. 6
      frontend_reactjs/src/pages/auth/SignIn.tsx
  5. 9
      frontend_reactjs/src/services/AuthService.ts

27
frontend_reactjs/src/components/FormFields.tsx

@ -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) => {
fields.forEach((field: CreateField) => {
if (field.include === false) {
delete data[field.key]
}
})
try {
await submitHandler?.(data).then(() => {
mutateHandler?.()
})
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>

4
frontend_reactjs/src/interfaces/create.ts

@ -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;
}

35
frontend_reactjs/src/pages/Settings.tsx

@ -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,16 +35,17 @@ 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={{
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
gap: "16px",
}}
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
gap: "16px",
}}
>
{currentUser &&
<Stack spacing={2} width='100%'>
@ -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>
)

6
frontend_reactjs/src/pages/auth/SignIn.tsx

@ -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">

9
frontend_reactjs/src/services/AuthService.ts

@ -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)
}
}
Loading…
Cancel
Save