skyouc
2025-02-18 36e6c98d9e34fd8e90ae803e7de2eef0a4d0741b
rsf-admin/src/page/login/Login.jsx
New file
@@ -0,0 +1,190 @@
import React, { useState, useRef, useEffect, useMemo } from "react";
import { useLocation } from 'react-router-dom';
import {
    Box,
    CircularProgress,
    Typography,
    Button,
    TextField,
    Stack,
    Autocomplete,
    InputAdornment,
    IconButton,
} from '@mui/material';
import {
    useTranslate,
    useLogin,
    useNotify,
} from 'react-admin';
import { useForm, Controller, useWatch, FormProvider, useFormContext } from "react-hook-form";
import ProviderChoices from "./ProviderChoices";
import Visibility from '@mui/icons-material/Visibility';
import VisibilityOff from '@mui/icons-material/VisibilityOff';
const Login = (props) => {
    const translate = useTranslate();
    const notify = useNotify();
    const login = useLogin();
    const location = useLocation();
    const { systemInfo: { mode }, tenantList } = props;
    const { control, handleSubmit, watch, setValue, getValues, setError, clearErrors } = useForm();
    const [loading, setLoading] = useState(false);
    const [showPassword, setShowPassword] = useState(false);
    const username = watch('username');
    const password = watch('password');
    const tenantId = watch('tenantId');
    useEffect(() => {
        if (tenantList.length > 0 && !tenantId) {
            const rememberTenantId = localStorage.getItem('remember_tenantId');
            if (rememberTenantId && tenantList.some(t => t.id === Number(rememberTenantId))) {
                setValue('tenantId', Number(rememberTenantId));
            } else {
                setValue('tenantId', tenantList[0].id);
            }
        }
    }, [tenantList, setValue]);
    const onSubmit = (data) => {
        setLoading(true);
        login(
            data,
            location.state ? (location.state).nextPathname : '/'
        ).catch((res) => {
            setLoading(false);
            const { code, msg, data } = res;
            if (code === 10003) {
                setError('username', {
                    message: msg
                })
            } else if (code === 10004) {
                setError('username', {
                    message: msg
                })
            } else if (code === 10001) {
                setError('password', {
                    message: msg
                })
            } else {
                notify(msg, { type: 'error', messageArgs: { _: msg } });
            }
        });
    };
    return (
        <>
            <Box
                p={2}
                display="flex"
                flexDirection='column'
                component="form" onSubmit={handleSubmit(onSubmit)} noValidate
            >
                <Stack spacing={2}>
                    {mode === 'OFFLINE' && (
                        <Controller
                            name="tenantId"
                            control={control}
                            rules={{ required: true }}
                            defaultValue={tenantList.length > 0 ? tenantList[0].id : ''}
                            render={({ field: { onChange, value, ref } }) => {
                                const selectedTenant = tenantList.find(tenant => tenant.id === value) || null;
                                return (
                                    <Autocomplete
                                        options={tenantList}
                                        getOptionLabel={(option) => option.name}
                                        value={selectedTenant}
                                        onChange={(_, newValue) => {
                                            const newTenantId = newValue ? newValue.id : '';
                                            onChange(newTenantId);
                                            localStorage.setItem('remember_tenantId', newTenantId);
                                        }}
                                        renderInput={(params) => (
                                            <TextField
                                                {...params}
                                                label={translate("page.login.tenant")}
                                                variant="standard"
                                                inputRef={ref}
                                            />
                                        )}
                                    />
                                );
                            }}
                        />
                    )}
                    <Controller
                        name="username"
                        control={control}
                        defaultValue=""
                        rules={{ required: true }}
                        render={({ field, fieldState: { error } }) => (
                            <TextField
                                {...field}
                                label={translate("page.login.username")}
                                variant="standard"
                                disabled={loading}
                                autoFocus
                                autoComplete="off"
                                error={!!error}
                                helperText={error?.message || ""}
                            />
                        )}
                    />
                    <Controller
                        name="password"
                        control={control}
                        defaultValue=""
                        rules={{ required: true }}
                        render={({ field, fieldState: { error } }) => (
                            <TextField
                                {...field}
                                label={translate("page.login.password")}
                                type={showPassword ? 'text' : 'password'}
                                variant="standard"
                                disabled={loading}
                                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>
                                    ),
                                }}
                            />
                        )}
                    />
                    <Box />
                    <Button
                        type="submit"
                        variant="contained"
                        disabled={loading || !((mode === 'OFFLINE' ? tenantId : true) && username && password)}
                    >
                        {loading && <CircularProgress size={25} thickness={2} />}
                        {translate('page.login.button.login')}
                    </Button>
                </Stack>
                <Box mt={1} mb={1} sx={{ textAlign: 'center' }}>or</Box>
                <ProviderChoices type="LOG IN" />
            </Box >
        </>
    )
}
export default Login;