|  |  |  | 
|---|
|  |  |  | import React, { useState, useRef, useEffect, useMemo } from "react"; | 
|---|
|  |  |  | import { useNavigate } from 'react-router-dom'; | 
|---|
|  |  |  | import { | 
|---|
|  |  |  | Edit, | 
|---|
|  |  |  | SimpleForm, | 
|---|
|  |  |  | FormDataConsumer, | 
|---|
|  |  |  | useTranslate, | 
|---|
|  |  |  | TextInput, | 
|---|
|  |  |  | NumberInput, | 
|---|
|  |  |  | BooleanInput, | 
|---|
|  |  |  | SaveButton, | 
|---|
|  |  |  | SelectInput, | 
|---|
|  |  |  | Toolbar, | 
|---|
|  |  |  | Labeled, | 
|---|
|  |  |  | NumberField, | 
|---|
|  |  |  | required, | 
|---|
|  |  |  | useRecordContext, | 
|---|
|  |  |  | useTheme, | 
|---|
|  |  |  | useAuthProvider, | 
|---|
|  |  |  | useNotify, | 
|---|
|  |  |  | } from 'react-admin'; | 
|---|
|  |  |  | import { useWatch, useFormContext } from "react-hook-form"; | 
|---|
|  |  |  | import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form"; | 
|---|
|  |  |  | import { | 
|---|
|  |  |  | Stack, | 
|---|
|  |  |  | Grid, | 
|---|
|  |  |  | Box, | 
|---|
|  |  |  | Typography, | 
|---|
|  |  |  | Card, | 
|---|
|  |  |  | CardContent, | 
|---|
|  |  |  | TextField, | 
|---|
|  |  |  | Button, | 
|---|
|  |  |  | FormControl, | 
|---|
|  |  |  | InputLabel, | 
|---|
|  |  |  | Select, | 
|---|
|  |  |  | MenuItem, | 
|---|
|  |  |  | FormHelperText, | 
|---|
|  |  |  | CircularProgress, | 
|---|
|  |  |  | LinearProgress, | 
|---|
|  |  |  | } from '@mui/material'; | 
|---|
|  |  |  | import { updateUserInfo } from '@/api/auth'; | 
|---|
|  |  |  | import avatar from '/avatar.jpg' | 
|---|
|  |  |  |  | 
|---|
|  |  |  | const BaseSettings = (props) => { | 
|---|
|  |  |  | const { children, value, ...other } = props; | 
|---|
|  |  |  | const translate = useTranslate(); | 
|---|
|  |  |  | const notify = useNotify(); | 
|---|
|  |  |  | const { children, userInfo } = props; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | const { | 
|---|
|  |  |  | control, | 
|---|
|  |  |  | handleSubmit, | 
|---|
|  |  |  | watch, | 
|---|
|  |  |  | setValue, | 
|---|
|  |  |  | getValues, | 
|---|
|  |  |  | reset, | 
|---|
|  |  |  | formState: { | 
|---|
|  |  |  | errors, | 
|---|
|  |  |  | isDirty, | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | setError, | 
|---|
|  |  |  | clearErrors, | 
|---|
|  |  |  | } = useForm(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | const [loading, setLoading] = useState(false); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | useEffect(() => { | 
|---|
|  |  |  | if (userInfo) { | 
|---|
|  |  |  | setValue("username", userInfo.username || "", { shouldDirty: false }); | 
|---|
|  |  |  | setValue("nickname", userInfo.nickname || "", { shouldDirty: false }); | 
|---|
|  |  |  | setValue("sex", userInfo.sex ?? "", { shouldDirty: false }); | 
|---|
|  |  |  | setValue("code", userInfo.code || "", { shouldDirty: false }); | 
|---|
|  |  |  | setValue("phone", userInfo.phone || "", { shouldDirty: false }); | 
|---|
|  |  |  | setValue("email", userInfo.email || "", { shouldDirty: false }); | 
|---|
|  |  |  | setValue("realName", userInfo.realName || "", { shouldDirty: false }); | 
|---|
|  |  |  | setValue("idCard", userInfo.idCard || "", { shouldDirty: false }); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }, [userInfo, setValue]) | 
|---|
|  |  |  |  | 
|---|
|  |  |  | const onSubmit = (data) => { | 
|---|
|  |  |  | setLoading(true); | 
|---|
|  |  |  | updateUserInfo({ id: userInfo.id, ...data }).then(res => { | 
|---|
|  |  |  | setLoading(false); | 
|---|
|  |  |  | const { code, msg, data } = res; | 
|---|
|  |  |  | if (code === 200) { | 
|---|
|  |  |  | notify(msg, { type: 'success', messageArgs: { _: msg } }); | 
|---|
|  |  |  | const userToPersist = { | 
|---|
|  |  |  | avatar: avatar, | 
|---|
|  |  |  | fullName: data.nickname, | 
|---|
|  |  |  | id: data.id, | 
|---|
|  |  |  | username: data.username | 
|---|
|  |  |  | } | 
|---|
|  |  |  | localStorage.setItem("user", JSON.stringify(userToPersist)); | 
|---|
|  |  |  | } else if (code === 10005 || code === 10006) { | 
|---|
|  |  |  | setError('email', { | 
|---|
|  |  |  | message: msg | 
|---|
|  |  |  | }) | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | notify(msg, { type: 'error', messageArgs: { _: msg } }); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | }).catch((error) => { | 
|---|
|  |  |  | setLoading(false); | 
|---|
|  |  |  | notify(error.message, { type: 'error', messageArgs: { _: error.message } }); | 
|---|
|  |  |  | console.error(error); | 
|---|
|  |  |  | }) | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return ( | 
|---|
|  |  |  | <Box | 
|---|
|  |  |  | hidden={value !== 0} | 
|---|
|  |  |  | sx={{ p: 3 }} | 
|---|
|  |  |  | {...other} | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <Grid container spacing={6}> | 
|---|
|  |  |  | <Grid item xs={12}> | 
|---|
|  |  |  | {/* https://github.com/themeselection/materio-mui-nextjs-admin-template-free/blob/main/javascript-version/src/views/account-settings/account/AccountDetails.jsx */} | 
|---|
|  |  |  | <Card> | 
|---|
|  |  |  | <CardContent className='mbe-5'> | 
|---|
|  |  |  | <Typography> | 
|---|
|  |  |  | Base Settings | 
|---|
|  |  |  | </Typography> | 
|---|
|  |  |  | </CardContent> | 
|---|
|  |  |  | </Card> | 
|---|
|  |  |  | <Box sx={{ | 
|---|
|  |  |  | position: 'relative', | 
|---|
|  |  |  | p: 3, | 
|---|
|  |  |  | flex: 1, | 
|---|
|  |  |  | overflow: 'auto', | 
|---|
|  |  |  | }}> | 
|---|
|  |  |  | {!userInfo && ( | 
|---|
|  |  |  | <LinearProgress | 
|---|
|  |  |  | sx={{ | 
|---|
|  |  |  | height: "2px", | 
|---|
|  |  |  | position: 'absolute', | 
|---|
|  |  |  | top: 0, | 
|---|
|  |  |  | left: 0, | 
|---|
|  |  |  | right: 0, | 
|---|
|  |  |  | }} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | )} | 
|---|
|  |  |  | <form onSubmit={handleSubmit(onSubmit)} noValidate> | 
|---|
|  |  |  | <Stack | 
|---|
|  |  |  | direction='column' | 
|---|
|  |  |  | spacing={3} | 
|---|
|  |  |  | sx={{ | 
|---|
|  |  |  | width: '30%', | 
|---|
|  |  |  | pt: 1 | 
|---|
|  |  |  | }} | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <Controller | 
|---|
|  |  |  | name="username" | 
|---|
|  |  |  | control={control} | 
|---|
|  |  |  | defaultValue="" | 
|---|
|  |  |  | rules={{ required: true }} | 
|---|
|  |  |  | render={({ field, fieldState: { error } }) => ( | 
|---|
|  |  |  | <TextField | 
|---|
|  |  |  | {...field} | 
|---|
|  |  |  | label={translate('table.field.user.username')} | 
|---|
|  |  |  | variant="outlined" | 
|---|
|  |  |  | autoComplete="off" | 
|---|
|  |  |  | helperText={error ? translate('ra.validation.required') : ""} | 
|---|
|  |  |  | disabled | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | )} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <Controller | 
|---|
|  |  |  | name="nickname" | 
|---|
|  |  |  | control={control} | 
|---|
|  |  |  | defaultValue="" | 
|---|
|  |  |  | rules={{ required: true }} | 
|---|
|  |  |  | render={({ field, fieldState: { error } }) => ( | 
|---|
|  |  |  | <TextField | 
|---|
|  |  |  | {...field} | 
|---|
|  |  |  | label={translate('table.field.user.nickname')} | 
|---|
|  |  |  | variant="outlined" | 
|---|
|  |  |  | autoComplete="off" | 
|---|
|  |  |  | error={!!error} | 
|---|
|  |  |  | helperText={error ? translate('ra.validation.required') : ""} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | )} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <Controller | 
|---|
|  |  |  | name="sex" | 
|---|
|  |  |  | control={control} | 
|---|
|  |  |  | defaultValue="" | 
|---|
|  |  |  | rules={{ required: true }} | 
|---|
|  |  |  | render={({ field, fieldState: { error } }) => ( | 
|---|
|  |  |  | <FormControl fullWidth variant="outlined" error={!!error}> | 
|---|
|  |  |  | <InputLabel>{translate('table.field.user.sex')}</InputLabel> | 
|---|
|  |  |  | <Select | 
|---|
|  |  |  | {...field} | 
|---|
|  |  |  | label={translate('table.field.user.sex')} | 
|---|
|  |  |  | > | 
|---|
|  |  |  | <MenuItem value={0}> | 
|---|
|  |  |  | <em>{translate('table.field.user.sexes.unknown')}</em> | 
|---|
|  |  |  | </MenuItem> | 
|---|
|  |  |  | <MenuItem value={1}>{translate('table.field.user.sexes.male')}</MenuItem> | 
|---|
|  |  |  | <MenuItem value={2}>{translate('table.field.user.sexes.female')}</MenuItem> | 
|---|
|  |  |  | </Select> | 
|---|
|  |  |  | {error && <FormHelperText>{translate('ra.validation.required')}</FormHelperText>} | 
|---|
|  |  |  | </FormControl> | 
|---|
|  |  |  | )} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <Controller | 
|---|
|  |  |  | name="code" | 
|---|
|  |  |  | control={control} | 
|---|
|  |  |  | defaultValue="" | 
|---|
|  |  |  | rules={{ required: false }} | 
|---|
|  |  |  | render={({ field, fieldState: { error } }) => ( | 
|---|
|  |  |  | <TextField | 
|---|
|  |  |  | {...field} | 
|---|
|  |  |  | label={translate('table.field.user.code')} | 
|---|
|  |  |  | variant="outlined" | 
|---|
|  |  |  | autoComplete="off" | 
|---|
|  |  |  | error={!!error} | 
|---|
|  |  |  | helperText={error ? translate('ra.validation.required') : ""} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | )} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <Controller | 
|---|
|  |  |  | name="phone" | 
|---|
|  |  |  | control={control} | 
|---|
|  |  |  | defaultValue="" | 
|---|
|  |  |  | rules={{ required: false }} | 
|---|
|  |  |  | render={({ field, fieldState: { error } }) => ( | 
|---|
|  |  |  | <TextField | 
|---|
|  |  |  | {...field} | 
|---|
|  |  |  | label={translate('table.field.user.phone')} | 
|---|
|  |  |  | variant="outlined" | 
|---|
|  |  |  | autoComplete="off" | 
|---|
|  |  |  | error={!!error} | 
|---|
|  |  |  | helperText={error ? translate('ra.validation.required') : ""} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | )} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <Controller | 
|---|
|  |  |  | name="email" | 
|---|
|  |  |  | control={control} | 
|---|
|  |  |  | defaultValue="" | 
|---|
|  |  |  | rules={{ | 
|---|
|  |  |  | required: false, | 
|---|
|  |  |  | pattern: { | 
|---|
|  |  |  | value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, | 
|---|
|  |  |  | message: translate("ra.validation.email"), | 
|---|
|  |  |  | }, | 
|---|
|  |  |  | }} | 
|---|
|  |  |  | render={({ field, fieldState: { error } }) => ( | 
|---|
|  |  |  | <TextField | 
|---|
|  |  |  | {...field} | 
|---|
|  |  |  | label={translate('table.field.user.email')} | 
|---|
|  |  |  | variant="outlined" | 
|---|
|  |  |  | autoComplete="off" | 
|---|
|  |  |  | error={!!error} | 
|---|
|  |  |  | helperText={error ? error.message : ""} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | )} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <Controller | 
|---|
|  |  |  | name="realName" | 
|---|
|  |  |  | control={control} | 
|---|
|  |  |  | defaultValue="" | 
|---|
|  |  |  | rules={{ required: false }} | 
|---|
|  |  |  | render={({ field, fieldState: { error } }) => ( | 
|---|
|  |  |  | <TextField | 
|---|
|  |  |  | {...field} | 
|---|
|  |  |  | label={translate('table.field.user.realName')} | 
|---|
|  |  |  | variant="outlined" | 
|---|
|  |  |  | autoComplete="off" | 
|---|
|  |  |  | error={!!error} | 
|---|
|  |  |  | helperText={error ? translate('ra.validation.required') : ""} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | )} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <Controller | 
|---|
|  |  |  | name="idCard" | 
|---|
|  |  |  | control={control} | 
|---|
|  |  |  | defaultValue="" | 
|---|
|  |  |  | rules={{ required: false }} | 
|---|
|  |  |  | render={({ field, fieldState: { error } }) => ( | 
|---|
|  |  |  | <TextField | 
|---|
|  |  |  | {...field} | 
|---|
|  |  |  | label={translate('table.field.user.idCard')} | 
|---|
|  |  |  | variant="outlined" | 
|---|
|  |  |  | autoComplete="off" | 
|---|
|  |  |  | error={!!error} | 
|---|
|  |  |  | helperText={error ? translate('ra.validation.required') : ""} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | )} | 
|---|
|  |  |  | /> | 
|---|
|  |  |  | <Button | 
|---|
|  |  |  | type="submit" | 
|---|
|  |  |  | variant="contained" | 
|---|
|  |  |  | disabled={loading || !isDirty} | 
|---|
|  |  |  | sx={{ | 
|---|
|  |  |  | alignSelf: 'flex-start', | 
|---|
|  |  |  | width: '120px' | 
|---|
|  |  |  | }} | 
|---|
|  |  |  | > | 
|---|
|  |  |  | {loading && <CircularProgress size={25} thickness={2} />} | 
|---|
|  |  |  | {translate('ra.action.save')} | 
|---|
|  |  |  | </Button> | 
|---|
|  |  |  | </Stack> | 
|---|
|  |  |  | </form> | 
|---|
|  |  |  |  | 
|---|
|  |  |  | </Grid> | 
|---|
|  |  |  | </Grid> | 
|---|
|  |  |  | </Box> | 
|---|
|  |  |  |  | 
|---|
|  |  |  | ) | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|