From 2d1b39fae6abed7cda7bd5722fcea23fefdb6e12 Mon Sep 17 00:00:00 2001
From: vincentlu <t1341870251@gmail.com>
Date: 星期二, 11 二月 2025 10:56:52 +0800
Subject: [PATCH] #

---
 rsf-admin/src/page/login/Login.jsx |  255 ++++++++++++++++++++++++++++-----------------------
 1 files changed, 140 insertions(+), 115 deletions(-)

diff --git a/rsf-admin/src/page/login/Login.jsx b/rsf-admin/src/page/login/Login.jsx
index f212d46..0eedaad 100644
--- a/rsf-admin/src/page/login/Login.jsx
+++ b/rsf-admin/src/page/login/Login.jsx
@@ -1,38 +1,57 @@
-import * as React from 'react';
-import { useState } from 'react';
+import React, { useState, useRef, useEffect, useMemo } from "react";
 import { useLocation } from 'react-router-dom';
 import {
-    Avatar,
     Box,
-    Button,
-    Card,
-    CardActions,
     CircularProgress,
+    Typography,
+    Button,
+    TextField,
+    Stack,
+    Autocomplete,
+    InputAdornment,
+    IconButton,
 } from '@mui/material';
-import LockIcon from '@mui/icons-material/Lock';
 import {
-    Form,
-    required,
-    TextInput,
     useTranslate,
     useLogin,
     useNotify,
 } from 'react-admin';
-import { LOGIN_BACKGROUND } from '@/config/setting';
+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 = () => {
-    const [loading, setLoading] = useState(false);
+const Login = (props) => {
     const translate = useTranslate();
-
     const notify = useNotify();
     const login = useLogin();
     const location = useLocation();
+    const { tenantList } = props;
 
-    const handleSubmit = (auth) => {
+    const { control, handleSubmit, watch, setValue, getValues } = 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);
-        // js native confirm && root
         login(
-            auth,
+            data,
             location.state ? (location.state).nextPathname : '/'
         ).catch((error) => {
             setLoading(false);
@@ -58,107 +77,113 @@
     };
 
     return (
-        <Form onSubmit={handleSubmit} noValidate>
-            {/* https://unsplash.com/ */}
+        <>
             <Box
-                sx={{
-                    display: 'flex',
-                    flexDirection: 'column',
-                    minHeight: '100vh',
-                    alignItems: 'center',
-                    justifyContent: 'flex-start',
-                    // justifyContent: 'center',
-                    background: `url(/login_bg.jpg)`,
-                    backgroundRepeat: 'no-repeat',
-                    backgroundSize: 'cover',
-                }}
+                p={2}
+                display="flex"
+                flexDirection='column'
+                component="form" onSubmit={handleSubmit(onSubmit)} noValidate
             >
-                <video
-                    autoPlay
-                    loop
-                    muted
-                    style={{
-                        position: 'fixed',
-                        top: 0,
-                        left: 0,
-                        width: '100%',
-                        height: '100%',
-                        // objectFit: 'cover',
-                        // objectFit: 'contain',
-                        objectFit: 'fill',
-                        // objectFit: 'scale-down',
-                        zIndex: 0,
-                    }}
-                >
-                    {LOGIN_BACKGROUND === 'media' && (
-                        <source src="/login_bg.mp4" type="video/mp4" />
-                    )}
-                </video>
+                <Stack spacing={2}>
+                    <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}
+                                        />
+                                    )}
+                                />
+                            );
+                        }}
+                    />
 
-                <Card sx={{
-                    minWidth: 300,
-                    marginTop: '6em',
-                    zIndex: 1
-                }}>
-                    <Box
-                        sx={{
-                            margin: '1em',
-                            display: 'flex',
-                            justifyContent: 'center',
-                        }}
-                    >
-                        <Avatar sx={{ bgcolor: 'secondary.main' }}>
-                            <LockIcon />
-                        </Avatar>
-                    </Box>
-                    <Box
-                        sx={{
-                            marginTop: '1em',
-                            display: 'flex',
-                            justifyContent: 'center',
-                            color: theme => theme.palette.grey[500],
-                        }}
-                    >
-                        Hint: root / 123456
-                    </Box>
-                    <Box sx={{ padding: '0 1em 1em 1em' }}>
-                        <Box sx={{ marginTop: '1em' }}>
-                            <TextInput
+                    <Controller
+                        name="username"
+                        control={control}
+                        defaultValue=""
+                        rules={{ required: true }}
+                        render={({ field }) => (
+                            <TextField
+                                {...field}
+                                label={translate("page.login.username")}
+                                variant="standard"
+                                disabled={loading}
                                 autoFocus
-                                source="username"
-                                label={translate('ra.auth.username')}
-                                disabled={loading}
-                                validate={required()}
+                                autoComplete="off"
                             />
-                        </Box>
-                        <Box sx={{ marginTop: '1em' }}>
-                            <TextInput
-                                source="password"
-                                label={translate('ra.auth.password')}
-                                type="password"
-                                disabled={loading}
-                                validate={required()}
-                            />
-                        </Box>
-                    </Box>
-                    <CardActions sx={{ padding: '0 1em 1em 1em' }}>
-                        <Button
-                            variant="contained"
-                            type="submit"
-                            color="primary"
-                            disabled={loading}
-                            fullWidth
-                        >
-                            {loading && (
-                                <CircularProgress size={25} thickness={2} />
-                            )}
-                            {translate('ra.auth.sign_in')}
-                        </Button>
-                    </CardActions>
-                </Card>
-            </Box>
-        </Form>
-    );
-};
+                        )}
+                    />
 
-export default Login;
+                    <Controller
+                        name="password"
+                        control={control}
+                        defaultValue=""
+                        rules={{ required: true }}
+                        render={({ field }) => (
+                            <TextField
+                                {...field}
+                                label={translate("page.login.password")}
+                                type={showPassword ? 'text' : 'password'}
+                                variant="standard"
+                                disabled={loading}
+                                autoComplete="off"
+                                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 || !(tenantId && username && password)}
+                        sx={{
+                            // backgroundColor: "#3D4BA7"
+                        }}
+                    >
+                        {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;
\ No newline at end of file

--
Gitblit v1.9.1