update,
This commit is contained in:
@@ -7,15 +7,18 @@ import Grid from '@mui/material/Grid';
|
||||
import Stack from '@mui/material/Stack';
|
||||
import Switch from '@mui/material/Switch';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import { useState } from 'react';
|
||||
import { Controller, useForm } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { isValidPhoneNumber } from 'react-phone-number-input/input';
|
||||
import { createUser, deleteUser, saveUser } from 'src/actions/user';
|
||||
import { Field, Form, schemaHelper } from 'src/components/hook-form';
|
||||
import { Label } from 'src/components/label';
|
||||
import { toast } from 'src/components/snackbar';
|
||||
import { useRouter } from 'src/routes/hooks';
|
||||
import { paths } from 'src/routes/paths';
|
||||
import type { IUserItem } from 'src/types/user';
|
||||
import { fileToBase64 } from 'src/utils/file-to-base64';
|
||||
import { fData } from 'src/utils/format-number';
|
||||
import { z as zod } from 'zod';
|
||||
|
||||
@@ -24,26 +27,27 @@ import { z as zod } from 'zod';
|
||||
export type NewUserSchemaType = zod.infer<typeof NewUserSchema>;
|
||||
|
||||
export const NewUserSchema = zod.object({
|
||||
avatarUrl: schemaHelper.file({ message: 'Avatar is required!' }),
|
||||
name: zod.string().min(1, { message: 'Name is required!' }),
|
||||
city: zod.string().min(1, { message: 'City is required!' }),
|
||||
role: zod.string().min(1, { message: 'Role is required!' }),
|
||||
email: zod
|
||||
.string()
|
||||
.min(1, { message: 'Email is required!' })
|
||||
.email({ message: 'Email must be a valid email address!' }),
|
||||
phoneNumber: schemaHelper.phoneNumber({ isValid: isValidPhoneNumber }),
|
||||
state: zod.string().min(1, { message: 'State is required!' }),
|
||||
status: zod.string(),
|
||||
address: zod.string().min(1, { message: 'Address is required!' }),
|
||||
country: schemaHelper.nullableInput(zod.string().min(1, { message: 'Country is required!' }), {
|
||||
// message for null value
|
||||
message: 'Country is required!',
|
||||
}),
|
||||
address: zod.string().min(1, { message: 'Address is required!' }),
|
||||
company: zod.string().min(1, { message: 'Company is required!' }),
|
||||
state: zod.string().min(1, { message: 'State is required!' }),
|
||||
city: zod.string().min(1, { message: 'City is required!' }),
|
||||
role: zod.string().min(1, { message: 'Role is required!' }),
|
||||
zipCode: zod.string().min(1, { message: 'Zip code is required!' }),
|
||||
// Not required
|
||||
status: zod.string(),
|
||||
company: zod.string().min(1, { message: 'Company is required!' }),
|
||||
avatarUrl: schemaHelper.file({ message: 'Avatar is required!' }),
|
||||
phoneNumber: schemaHelper.phoneNumber({ isValid: isValidPhoneNumber }),
|
||||
isVerified: zod.boolean(),
|
||||
username: zod.string(),
|
||||
password: zod.string(),
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
@@ -61,16 +65,19 @@ export function UserNewEditForm({ currentUser }: Props) {
|
||||
status: '',
|
||||
avatarUrl: null,
|
||||
isVerified: true,
|
||||
name: '',
|
||||
email: '',
|
||||
phoneNumber: '',
|
||||
country: '',
|
||||
state: '',
|
||||
city: '',
|
||||
address: '',
|
||||
zipCode: '',
|
||||
company: '',
|
||||
role: '',
|
||||
name: '新用戶名字',
|
||||
email: 'user@123.com',
|
||||
phoneNumber: '+85291234567',
|
||||
country: 'Hong Kong',
|
||||
state: 'HK',
|
||||
city: 'hong kong',
|
||||
address: 'Kwun Tong, Sau Mau Ping',
|
||||
zipCode: '00000',
|
||||
company: 'test company',
|
||||
role: 'user',
|
||||
//
|
||||
username: '',
|
||||
password: '',
|
||||
};
|
||||
|
||||
const methods = useForm<NewUserSchemaType>({
|
||||
@@ -85,18 +92,50 @@ export function UserNewEditForm({ currentUser }: Props) {
|
||||
watch,
|
||||
control,
|
||||
handleSubmit,
|
||||
formState: { isSubmitting },
|
||||
formState: { errors, isSubmitting },
|
||||
} = methods;
|
||||
|
||||
const values = watch();
|
||||
|
||||
const onSubmit = handleSubmit(async (data) => {
|
||||
const [disableDeleteUserButton, setDisableDeleteUserButton] = useState<boolean>(false);
|
||||
const handleDeleteUserClick = async () => {
|
||||
setDisableDeleteUserButton(true);
|
||||
try {
|
||||
if (currentUser) {
|
||||
await deleteUser(currentUser.id);
|
||||
toast.success(t('user deleted'));
|
||||
router.push(paths.dashboard.user.list);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
setDisableDeleteUserButton(false);
|
||||
};
|
||||
|
||||
const onSubmit = handleSubmit(async (data: any) => {
|
||||
try {
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
reset();
|
||||
toast.success(currentUser ? 'Update success!' : 'Create success!');
|
||||
|
||||
const temp: any = data.avatarUrl;
|
||||
if (temp instanceof File) {
|
||||
data.avatarUrl = await fileToBase64(temp);
|
||||
}
|
||||
|
||||
if (currentUser) {
|
||||
// perform save
|
||||
await saveUser(currentUser.id, data);
|
||||
} else {
|
||||
// perform create
|
||||
await createUser(data);
|
||||
}
|
||||
|
||||
toast.success(currentUser ? t('Update success!') : t('Create success!'));
|
||||
|
||||
router.push(paths.dashboard.user.list);
|
||||
console.info('DATA', data);
|
||||
|
||||
// console.info('DATA', data);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
@@ -135,8 +174,8 @@ export function UserNewEditForm({ currentUser }: Props) {
|
||||
color: 'text.disabled',
|
||||
}}
|
||||
>
|
||||
Allowed *.jpeg, *.jpg, *.png, *.gif
|
||||
<br /> max size of {fData(3145728)}
|
||||
{t('Allowed')} *.jpeg, *.jpg, *.png, *.gif
|
||||
<br /> {t('max size of')} {fData(3145728)}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
@@ -163,10 +202,10 @@ export function UserNewEditForm({ currentUser }: Props) {
|
||||
label={
|
||||
<>
|
||||
<Typography variant="subtitle2" sx={{ mb: 0.5 }}>
|
||||
Banned
|
||||
{t('Banned')}
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ color: 'text.secondary' }}>
|
||||
Apply disable account
|
||||
{t('Apply disable account')}
|
||||
</Typography>
|
||||
</>
|
||||
}
|
||||
@@ -185,10 +224,10 @@ export function UserNewEditForm({ currentUser }: Props) {
|
||||
label={
|
||||
<>
|
||||
<Typography variant="subtitle2" sx={{ mb: 0.5 }}>
|
||||
Email verified
|
||||
{t('Email verified')}
|
||||
</Typography>
|
||||
<Typography variant="body2" sx={{ color: 'text.secondary' }}>
|
||||
Disabling this will automatically send the user a verification email
|
||||
{t('Disabling this will automatically send the user a verification email')}
|
||||
</Typography>
|
||||
</>
|
||||
}
|
||||
@@ -197,8 +236,14 @@ export function UserNewEditForm({ currentUser }: Props) {
|
||||
|
||||
{currentUser && (
|
||||
<Stack sx={{ mt: 3, alignItems: 'center', justifyContent: 'center' }}>
|
||||
<Button variant="soft" color="error">
|
||||
Delete user
|
||||
<Button
|
||||
disabled={disableDeleteUserButton}
|
||||
loading={disableDeleteUserButton}
|
||||
variant="soft"
|
||||
color="error"
|
||||
onClick={handleDeleteUserClick}
|
||||
>
|
||||
{t('Delete user')}
|
||||
</Button>
|
||||
</Stack>
|
||||
)}
|
||||
@@ -215,32 +260,33 @@ export function UserNewEditForm({ currentUser }: Props) {
|
||||
gridTemplateColumns: { xs: 'repeat(1, 1fr)', sm: 'repeat(2, 1fr)' },
|
||||
}}
|
||||
>
|
||||
<Field.Text name="name" label="Full name" />
|
||||
<Field.Text name="email" label="Email address" />
|
||||
<Field.Phone
|
||||
name="phoneNumber"
|
||||
label="Phone number"
|
||||
country={!currentUser ? 'DE' : undefined}
|
||||
/>
|
||||
<Field.Text name="name" label={t('Full name')} />
|
||||
<Field.Text name="email" label={t('Email address')} />
|
||||
<Field.Phone name="phoneNumber" label={t('Phone number')} country="HK" />
|
||||
|
||||
<Field.CountrySelect
|
||||
fullWidth
|
||||
name="country"
|
||||
label="Country"
|
||||
placeholder="Choose a country"
|
||||
label={t('Country')}
|
||||
placeholder={t('Choose a country')}
|
||||
/>
|
||||
|
||||
<Field.Text name="state" label="State/region" />
|
||||
<Field.Text name="city" label="City" />
|
||||
<Field.Text name="state" label={t('State/region')} />
|
||||
<Field.Text name="city" label={t('City')} />
|
||||
<Field.Text name="address" label={t('Address')} />
|
||||
<Field.Text name="zipCode" label="Zip/code" />
|
||||
<Field.Text name="company" label="Company" />
|
||||
<Field.Text name="role" label="Role" />
|
||||
<Field.Text name="zipCode" label={t('Zip/code')} />
|
||||
<Field.Text name="company" label={t('Company')} />
|
||||
<Field.Text name="role" label={t('Role')} />
|
||||
</Box>
|
||||
|
||||
<Stack sx={{ mt: 3, alignItems: 'flex-end' }}>
|
||||
<Button type="submit" variant="contained" loading={isSubmitting}>
|
||||
{!currentUser ? 'Create user' : 'Save changes'}
|
||||
<Button
|
||||
disabled={isSubmitting}
|
||||
loading={isSubmitting}
|
||||
type="submit"
|
||||
variant="contained"
|
||||
>
|
||||
{!currentUser ? t('Create user') : t('Save changes')}
|
||||
</Button>
|
||||
</Stack>
|
||||
</Card>
|
||||
|
Reference in New Issue
Block a user