|  |  | 
 |  |  |     Stack, | 
 |  |  |     Grid, | 
 |  |  |     Box, | 
 |  |  |     Stepper, | 
 |  |  |     Step, | 
 |  |  |     StepLabel, | 
 |  |  |     StepContent, | 
 |  |  |     Button, | 
 |  |  |     TextField, | 
 |  |  |     InputAdornment, | 
 |  |  |     IconButton, | 
 |  |  | } from '@mui/material'; | 
 |  |  | import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form"; | 
 |  |  | import { matchPath, useLocation } from 'react-router'; | 
 |  |  | import DialogCloseButton from "../components/DialogCloseButton"; | 
 |  |  | import StatusSelectInput from "../components/StatusSelectInput"; | 
 |  |  | import MemoInput from "../components/MemoInput"; | 
 |  |  | import Visibility from '@mui/icons-material/Visibility'; | 
 |  |  | import VisibilityOff from '@mui/icons-material/VisibilityOff'; | 
 |  |  |  | 
 |  |  | const TenantCreate = (props) => { | 
 |  |  |     const { open, setOpen } = props; | 
 |  |  |  | 
 |  |  |     const translate = useTranslate(); | 
 |  |  |     const notify = useNotify(); | 
 |  |  |     const { | 
 |  |  |         control, | 
 |  |  |         handleSubmit, | 
 |  |  |         watch, | 
 |  |  |         setValue, | 
 |  |  |         getValues, | 
 |  |  |         reset, | 
 |  |  |         formState: { | 
 |  |  |             errors, | 
 |  |  |             isDirty, | 
 |  |  |         }, | 
 |  |  |         trigger | 
 |  |  |     } = useForm(); | 
 |  |  |  | 
 |  |  |     const passwordVal = watch('password'); | 
 |  |  |  | 
 |  |  |     const [activeStep, setActiveStep] = useState(0); | 
 |  |  |     const [showPassword, setShowPassword] = useState(false); | 
 |  |  |  | 
 |  |  |     const validateCurrentStep = async () => { | 
 |  |  |         let fieldsToValidate = []; | 
 |  |  |         if (activeStep === 0) { | 
 |  |  |             fieldsToValidate = ['name', 'flag']; | 
 |  |  |         } else if (activeStep === 1) { | 
 |  |  |             fieldsToValidate = ['username', 'email', 'password', 'confirmPassword']; | 
 |  |  |         } else if (activeStep === 2) { | 
 |  |  |             fieldsToValidate = ['memo']; | 
 |  |  |         } | 
 |  |  |         return await trigger(fieldsToValidate); | 
 |  |  |     }; | 
 |  |  |  | 
 |  |  |     const handleNext = async () => { | 
 |  |  |         const isValid = await validateCurrentStep(); | 
 |  |  |         if (!isValid) { | 
 |  |  |             return; | 
 |  |  |         } | 
 |  |  |         setActiveStep(prev => prev + 1); | 
 |  |  |     }; | 
 |  |  |  | 
 |  |  |     const handleBack = () => { | 
 |  |  |         setActiveStep(prev => prev - 1); | 
 |  |  |     }; | 
 |  |  |  | 
 |  |  |     const handleClose = (event, reason) => { | 
 |  |  |         if (reason !== "backdropClick") { | 
 |  |  |             setActiveStep(0); | 
 |  |  |             setOpen(false); | 
 |  |  |             reset(); | 
 |  |  |         } | 
 |  |  |     }; | 
 |  |  |  | 
 |  |  |     const handleSuccess = async (data) => { | 
 |  |  |         setOpen(false); | 
 |  |  |         notify('common.response.success'); | 
 |  |  |     }; | 
 |  |  |     const onSubmit = (data) => { | 
 |  |  |         console.log(data); | 
 |  |  |         return; | 
 |  |  |  | 
 |  |  |     const handleError = async (error) => { | 
 |  |  |         notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } }); | 
 |  |  |     }; | 
 |  |  |         // setOpen(false); | 
 |  |  |         reset(); | 
 |  |  |         // notify('common.response.success'); | 
 |  |  |  | 
 |  |  |         // notify(error.message || 'common.response.fail', { type: 'error', messageArgs: { _: error.message } }); | 
 |  |  |     } | 
 |  |  |  | 
 |  |  |     return ( | 
 |  |  |         <> | 
 |  |  |             <CreateBase | 
 |  |  |                 record={{}} | 
 |  |  |                 transform={(data) => { | 
 |  |  |                     return data; | 
 |  |  |                 }} | 
 |  |  |                 mutationOptions={{ onSuccess: handleSuccess, onError: handleError }} | 
 |  |  |             <Dialog | 
 |  |  |                 open={open} | 
 |  |  |                 onClose={handleClose} | 
 |  |  |                 aria-labelledby="form-dialog-title" | 
 |  |  |                 fullWidth | 
 |  |  |                 disableRestoreFocus | 
 |  |  |                 maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 
 |  |  |             > | 
 |  |  |                 <Dialog | 
 |  |  |                     open={open} | 
 |  |  |                     onClose={handleClose} | 
 |  |  |                     aria-labelledby="form-dialog-title" | 
 |  |  |                     fullWidth | 
 |  |  |                     disableRestoreFocus | 
 |  |  |                     maxWidth="md"   // 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 
 |  |  |                 > | 
 |  |  |                     <Form> | 
 |  |  |                         <DialogTitle id="form-dialog-title" sx={{ | 
 |  |  |                             position: 'sticky', | 
 |  |  |                             top: 0, | 
 |  |  |                             backgroundColor: 'background.paper', | 
 |  |  |                             zIndex: 1000 | 
 |  |  |                         }} | 
 |  |  |                         > | 
 |  |  |                             {translate('create.title')} | 
 |  |  |                             <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}> | 
 |  |  |                                 <DialogCloseButton onClose={handleClose} /> | 
 |  |  |                             </Box> | 
 |  |  |                         </DialogTitle> | 
 |  |  |                         <DialogContent> | 
 |  |  |                             <Grid container rowSpacing={2} columnSpacing={2}> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <TextInput | 
 |  |  |                                         label="table.field.tenant.name" | 
 |  |  |                                         source="name" | 
 |  |  |                                         parse={v => v} | 
 |  |  |                                         autoFocus | 
 |  |  |                                         validate={required()} | 
 |  |  |                                     /> | 
 |  |  |                                 </Grid> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <TextInput | 
 |  |  |                                         label="table.field.tenant.flag" | 
 |  |  |                                         source="flag" | 
 |  |  |                                         parse={v => v} | 
 |  |  |                                         autoFocus | 
 |  |  |                                         validate={required()} | 
 |  |  |                                     /> | 
 |  |  |                                 </Grid> | 
 |  |  |                                 <Grid item xs={6} display="flex" gap={1}> | 
 |  |  |                                     <StatusSelectInput /> | 
 |  |  |                                 </Grid> | 
 |  |  |                                 <Grid item xs={12} display="flex" gap={1}> | 
 |  |  |                                     <Stack direction="column" spacing={1} width={'100%'}> | 
 |  |  |                                         <MemoInput /> | 
 |  |  |                                     </Stack> | 
 |  |  |                                 </Grid> | 
 |  |  |                             </Grid> | 
 |  |  |                         </DialogContent> | 
 |  |  |                         <DialogActions sx={{ position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> | 
 |  |  |                             <Toolbar sx={{ width: '100%', justifyContent: 'space-between' }}  > | 
 |  |  |                                 <SaveButton /> | 
 |  |  |                             </Toolbar> | 
 |  |  |                         </DialogActions> | 
 |  |  |                     </Form> | 
 |  |  |                 </Dialog> | 
 |  |  |             </CreateBase> | 
 |  |  |                 <DialogTitle id="form-dialog-title" sx={{ | 
 |  |  |                     position: 'sticky', | 
 |  |  |                     top: 0, | 
 |  |  |                     backgroundColor: 'background.paper', | 
 |  |  |                     zIndex: 1000 | 
 |  |  |                 }}> | 
 |  |  |                     {translate('create.title')} | 
 |  |  |                     <Box sx={{ position: 'absolute', top: 8, right: 8, zIndex: 1001 }}> | 
 |  |  |                         <DialogCloseButton onClose={handleClose} /> | 
 |  |  |                     </Box> | 
 |  |  |                 </DialogTitle> | 
 |  |  |                 <DialogContent sx={{ mt: 2 }}> | 
 |  |  |                     {open && ( | 
 |  |  |                         <form noValidate onSubmit={handleSubmit(onSubmit)} > | 
 |  |  |                             <Stepper activeStep={activeStep} orientation="vertical"> | 
 |  |  |                                 <Step> | 
 |  |  |                                     <StepLabel>{translate('page.tenant.create.title.basic')}</StepLabel> | 
 |  |  |                                     <StepContent> | 
 |  |  |                                         <Stack spacing={3} mt={2} direction='column' width={'50%'}> | 
 |  |  |                                             <Controller | 
 |  |  |                                                 name="name" | 
 |  |  |                                                 control={control} | 
 |  |  |                                                 defaultValue="" | 
 |  |  |                                                 rules={{ required: true }} | 
 |  |  |                                                 parse={v => v} | 
 |  |  |                                                 render={({ field, fieldState: { error } }) => ( | 
 |  |  |                                                     <TextField | 
 |  |  |                                                         {...field} | 
 |  |  |                                                         label={translate('table.field.tenant.name')} | 
 |  |  |                                                         variant="outlined" | 
 |  |  |                                                         autoComplete="off" | 
 |  |  |                                                         error={!!error} | 
 |  |  |                                                         helperText={error ? translate('ra.validation.required') : ""} | 
 |  |  |                                                     /> | 
 |  |  |                                                 )} | 
 |  |  |                                             /> | 
 |  |  |                                             <Controller | 
 |  |  |                                                 name="flag" | 
 |  |  |                                                 control={control} | 
 |  |  |                                                 defaultValue="" | 
 |  |  |                                                 rules={{ | 
 |  |  |                                                     required: { | 
 |  |  |                                                         value: true, | 
 |  |  |                                                         message: translate('ra.validation.required') | 
 |  |  |                                                     }, | 
 |  |  |                                                     pattern: { | 
 |  |  |                                                         value: /^[A-Za-z]{3,20}$/, | 
 |  |  |                                                         message: translate('page.tenant.create.tip.onlyEn'), | 
 |  |  |                                                     } | 
 |  |  |                                                 }} | 
 |  |  |                                                 parse={v => v} | 
 |  |  |                                                 render={({ field, fieldState: { error } }) => ( | 
 |  |  |                                                     <TextField | 
 |  |  |                                                         {...field} | 
 |  |  |                                                         label={translate('table.field.tenant.flag')} | 
 |  |  |                                                         variant="outlined" | 
 |  |  |                                                         autoComplete="off" | 
 |  |  |                                                         error={!!error} | 
 |  |  |                                                         helperText={error ? error.message : ""} | 
 |  |  |                                                     /> | 
 |  |  |                                                 )} | 
 |  |  |                                             /> | 
 |  |  |                                         </Stack> | 
 |  |  |                                         <Box sx={{ mt: 3 }}> | 
 |  |  |                                             <Button onClick={handleNext} variant="contained"> | 
 |  |  |                                                 {translate('page.tenant.create.btn.next')} | 
 |  |  |                                             </Button> | 
 |  |  |                                             <Button disabled={activeStep === 0} onClick={handleBack}> | 
 |  |  |                                                 {translate('page.tenant.create.btn.back')} | 
 |  |  |                                             </Button> | 
 |  |  |                                         </Box> | 
 |  |  |                                     </StepContent> | 
 |  |  |                                 </Step> | 
 |  |  |  | 
 |  |  |                                 <Step> | 
 |  |  |                                     <StepLabel>{translate('page.tenant.create.title.root')}</StepLabel> | 
 |  |  |                                     <StepContent> | 
 |  |  |                                         <Stack spacing={3} mt={2} direction='column' width={'50%'}> | 
 |  |  |                                             <Controller | 
 |  |  |                                                 name="username" | 
 |  |  |                                                 control={control} | 
 |  |  |                                                 defaultValue="" | 
 |  |  |                                                 rules={{ | 
 |  |  |                                                     required: { | 
 |  |  |                                                         value: true, | 
 |  |  |                                                         message: translate('ra.validation.required') | 
 |  |  |                                                     }, | 
 |  |  |                                                     pattern: { | 
 |  |  |                                                         value: /^[A-Za-z0-9]{3,20}$/, | 
 |  |  |                                                         message: translate('page.settings.resetPwd.tip.usernameLimit'), | 
 |  |  |                                                     }, | 
 |  |  |                                                 }} | 
 |  |  |                                                 parse={v => v} | 
 |  |  |                                                 render={({ field, fieldState: { error } }) => ( | 
 |  |  |                                                     <TextField | 
 |  |  |                                                         {...field} | 
 |  |  |                                                         label={translate('table.field.user.username')} | 
 |  |  |                                                         variant="outlined" | 
 |  |  |                                                         autoComplete="off" | 
 |  |  |                                                         error={!!error} | 
 |  |  |                                                         helperText={error ? error.message : ""} | 
 |  |  |                                                     /> | 
 |  |  |                                                 )} | 
 |  |  |                                             /> | 
 |  |  |                                             <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="password" | 
 |  |  |                                                 control={control} | 
 |  |  |                                                 defaultValue="" | 
 |  |  |                                                 rules={{ | 
 |  |  |                                                     required: { | 
 |  |  |                                                         value: true, | 
 |  |  |                                                         message: translate('ra.validation.required'), | 
 |  |  |                                                     }, | 
 |  |  |                                                     pattern: { | 
 |  |  |                                                         value: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{6,13}$/, | 
 |  |  |                                                         message: translate('page.settings.resetPwd.tip.pwdInputLimit'), | 
 |  |  |                                                     }, | 
 |  |  |                                                 }} | 
 |  |  |                                                 render={({ field, fieldState: { error } }) => ( | 
 |  |  |                                                     <TextField | 
 |  |  |                                                         {...field} | 
 |  |  |                                                         label={translate('page.settings.resetPwd.newPwd')} | 
 |  |  |                                                         type={showPassword ? 'text' : 'password'} | 
 |  |  |                                                         variant="outlined" | 
 |  |  |                                                         autoComplete="off" | 
 |  |  |                                                         error={!!error} | 
 |  |  |                                                         helperText={error ? error.message : ""} | 
 |  |  |                                                         InputProps={{ | 
 |  |  |                                                             endAdornment: ( | 
 |  |  |                                                                 <InputAdornment position="end"> | 
 |  |  |                                                                     <IconButton | 
 |  |  |                                                                         aria-label="toggle password visibility" | 
 |  |  |                                                                         onClick={() => setShowPassword((show) => !show)} | 
 |  |  |                                                                         onMouseDown={(event) => { event.preventDefault() }} | 
 |  |  |                                                                         edge="end" | 
 |  |  |                                                                     > | 
 |  |  |                                                                         {showPassword ? <VisibilityOff /> : <Visibility />} | 
 |  |  |                                                                     </IconButton> | 
 |  |  |                                                                 </InputAdornment> | 
 |  |  |                                                             ), | 
 |  |  |                                                         }} | 
 |  |  |                                                     /> | 
 |  |  |                                                 )} | 
 |  |  |                                             /> | 
 |  |  |                                             <Controller | 
 |  |  |                                                 name="confirmPassword" | 
 |  |  |                                                 control={control} | 
 |  |  |                                                 defaultValue="" | 
 |  |  |                                                 rules={{ | 
 |  |  |                                                     required: translate('ra.validation.required'), | 
 |  |  |                                                     validate: value => | 
 |  |  |                                                         value === passwordVal || translate('page.settings.resetPwd.tip.pwdNotMatch'), | 
 |  |  |                                                 }} | 
 |  |  |                                                 render={({ field, fieldState: { error } }) => ( | 
 |  |  |                                                     <TextField | 
 |  |  |                                                         {...field} | 
 |  |  |                                                         label={translate('page.settings.resetPwd.confirmNewPwd')} | 
 |  |  |                                                         type={showPassword ? 'text' : 'password'} | 
 |  |  |                                                         variant="outlined" | 
 |  |  |                                                         autoComplete="off" | 
 |  |  |                                                         error={!!error} | 
 |  |  |                                                         helperText={error?.message || ""} | 
 |  |  |                                                         InputProps={{ | 
 |  |  |                                                             endAdornment: ( | 
 |  |  |                                                                 <InputAdornment position="end"> | 
 |  |  |                                                                     <IconButton | 
 |  |  |                                                                         aria-label="toggle password visibility" | 
 |  |  |                                                                         onClick={() => setShowPassword((show) => !show)} | 
 |  |  |                                                                         onMouseDown={(event) => { event.preventDefault() }} | 
 |  |  |                                                                         edge="end" | 
 |  |  |                                                                     > | 
 |  |  |                                                                         {showPassword ? <VisibilityOff /> : <Visibility />} | 
 |  |  |                                                                     </IconButton> | 
 |  |  |                                                                 </InputAdornment> | 
 |  |  |                                                             ), | 
 |  |  |                                                         }} | 
 |  |  |                                                     /> | 
 |  |  |                                                 )} | 
 |  |  |                                             /> | 
 |  |  |                                         </Stack> | 
 |  |  |                                         <Box sx={{ mt: 3 }}> | 
 |  |  |                                             <Button onClick={handleNext} variant="contained"> | 
 |  |  |                                                 {translate('page.tenant.create.btn.next')} | 
 |  |  |                                             </Button> | 
 |  |  |                                             <Button onClick={handleBack}> | 
 |  |  |                                                 {translate('page.tenant.create.btn.back')} | 
 |  |  |                                             </Button> | 
 |  |  |                                         </Box> | 
 |  |  |                                     </StepContent> | 
 |  |  |                                 </Step> | 
 |  |  |  | 
 |  |  |                                 <Step> | 
 |  |  |                                     <StepLabel>{translate('page.tenant.create.title.confirm')}</StepLabel> | 
 |  |  |                                     <StepContent> | 
 |  |  |                                         <Stack spacing={3} mt={2} direction='column' width={'50%'}> | 
 |  |  |                                             <Controller | 
 |  |  |                                                 name="memo" | 
 |  |  |                                                 control={control} | 
 |  |  |                                                 defaultValue="" | 
 |  |  |                                                 rules={{ required: false }} | 
 |  |  |                                                 parse={v => v} | 
 |  |  |                                                 render={({ field, fieldState: { error } }) => ( | 
 |  |  |                                                     <TextField | 
 |  |  |                                                         {...field} | 
 |  |  |                                                         label={translate('common.field.memo')} | 
 |  |  |                                                         variant="outlined" | 
 |  |  |                                                         autoComplete="off" | 
 |  |  |                                                         fullWidth | 
 |  |  |                                                         multiline | 
 |  |  |                                                         minRows={2} | 
 |  |  |                                                         error={!!error} | 
 |  |  |                                                         helperText={error ? translate('ra.validation.required') : ""} | 
 |  |  |                                                     /> | 
 |  |  |                                                 )} | 
 |  |  |                                             /> | 
 |  |  |                                         </Stack> | 
 |  |  |                                         <Box sx={{ mt: 3 }}> | 
 |  |  |                                             <Button type="submit" variant="contained"> | 
 |  |  |                                                 {translate('ra.action.save')} | 
 |  |  |                                             </Button> | 
 |  |  |                                             <Button onClick={handleBack}> | 
 |  |  |                                                 {translate('page.tenant.create.btn.back')} | 
 |  |  |                                             </Button> | 
 |  |  |                                         </Box> | 
 |  |  |                                     </StepContent> | 
 |  |  |                                 </Step> | 
 |  |  |                             </Stepper> | 
 |  |  |                         </form> | 
 |  |  |                     )} | 
 |  |  |                 </DialogContent> | 
 |  |  |                 <DialogActions sx={{ height: 10, position: 'sticky', bottom: 0, backgroundColor: 'background.paper', zIndex: 1000 }}> | 
 |  |  |                 </DialogActions> | 
 |  |  |             </Dialog> | 
 |  |  |         </> | 
 |  |  |     ) | 
 |  |  | } |