From 54d6fc96a8ef1e9903a7362c97a00e504c174ab3 Mon Sep 17 00:00:00 2001
From: vincentlu <t1341870251@gmail.com>
Date: 星期五, 07 二月 2025 13:13:42 +0800
Subject: [PATCH] #

---
 rsf-admin/src/config/authProvider.js |    5 
 rsf-admin/src/i18n/zh.js             |    3 
 rsf-admin/src/i18n/en.js             |    3 
 rsf-admin/src/page/login/index1.jsx  |  261 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 rsf-admin/src/App.jsx                |    2 
 5 files changed, 270 insertions(+), 4 deletions(-)

diff --git a/rsf-admin/src/App.jsx b/rsf-admin/src/App.jsx
index 00924d9..6d3a10a 100644
--- a/rsf-admin/src/App.jsx
+++ b/rsf-admin/src/App.jsx
@@ -16,7 +16,7 @@
 import DataProvider from "./config/dataProvider";
 import Dashboard from "./page/dashboard/Dashboard";
 import Settings from "./page/settings/Settings";
-import Login from "./page/login";
+import Login from "./page/login/index1";
 import * as Common from './utils/common'
 import { themes } from './themes/themes';
 import { SPA_NAME, SPA_VERSION, DEFAULT_THEME_NAME, DEFAULT_THEME_MODE, DATA_PROVIDER_SPRING } from "./config/setting";
diff --git a/rsf-admin/src/config/authProvider.js b/rsf-admin/src/config/authProvider.js
index 7436b8e..1c440e7 100644
--- a/rsf-admin/src/config/authProvider.js
+++ b/rsf-admin/src/config/authProvider.js
@@ -6,12 +6,11 @@
 
 const AuthProvider = {
   // login
-  login: async ({ username, password }) => {
-
+  login: async ({ username, password, tenantId }) => {
     const { accessToken, user } = await login({
       username: username,
       password: password,
-      tenantId: 1,
+      tenantId: tenantId,
     });
 
     if (user && accessToken) {
diff --git a/rsf-admin/src/i18n/en.js b/rsf-admin/src/i18n/en.js
index d8ea362..7dae7d3 100644
--- a/rsf-admin/src/i18n/en.js
+++ b/rsf-admin/src/i18n/en.js
@@ -221,6 +221,9 @@
     page: {
         login: {
             tenant: 'Tenant',
+            button: {
+                login: 'LOG IN',
+            },
         },
     }
 };
diff --git a/rsf-admin/src/i18n/zh.js b/rsf-admin/src/i18n/zh.js
index 522cd05..bf5b646 100644
--- a/rsf-admin/src/i18n/zh.js
+++ b/rsf-admin/src/i18n/zh.js
@@ -221,6 +221,9 @@
     page: {
         login: {
             tenant: '绉熸埛',
+            button: {
+                login: 'LOG IN',
+            },
         },
     }
 };
diff --git a/rsf-admin/src/page/login/index1.jsx b/rsf-admin/src/page/login/index1.jsx
new file mode 100644
index 0000000..bd9ff5e
--- /dev/null
+++ b/rsf-admin/src/page/login/index1.jsx
@@ -0,0 +1,261 @@
+import React, { useState, useRef, useEffect, useMemo } from "react";
+import { useLocation } from 'react-router-dom';
+import {
+    Box,
+    AppBar,
+    Card,
+    Toolbar,
+    CircularProgress,
+    Typography,
+    Tabs,
+    Tab,
+    Button
+} from '@mui/material';
+import {
+    Form,
+    required,
+    TextInput,
+    useTranslate,
+    useLogin,
+    useNotify,
+    SelectInput,
+} from 'react-admin';
+import { useForm, Controller } from 'react-hook-form';
+import { LOGIN_BACKGROUND } from '@/config/setting';
+import { tenants } from '@/api/auth';
+
+const Login = () => {
+    const translate = useTranslate();
+
+    const [tab, setTab] = useState(0)
+
+    const [tenantList, setTenantList] = useState([]);
+
+    useEffect(() => {
+        tenants().then(data => {
+            setTenantList(data);
+        })
+    }, []);
+
+    return (
+        <Box
+            sx={{
+                display: 'flex',
+                flexDirection: 'column',
+                minHeight: '100vh',
+                alignItems: 'center',
+                justifyContent: 'flex-start',
+                // justifyContent: 'center',
+                background: `url(/login_bg.jpg)`, // https://unsplash.com/
+                backgroundRepeat: 'no-repeat',
+                backgroundSize: 'cover',
+            }
+            }
+        >
+            <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>
+
+            <Card sx={{
+                width: 400,
+                marginTop: '6em',
+                zIndex: 1
+            }}>
+                <div>
+                    <AppBar position="static" sx={{ backgroundColor: '#3D4BA7' }}>
+                        <Toolbar>
+                            <Typography variant="h6" color="inherit">Welcome</Typography>
+                        </Toolbar>
+                    </AppBar>
+                </div>
+
+                <Tabs
+                    value={tab}
+                    onChange={(event, value) => {
+                        setTab(value);
+                    }}
+                    indicatorColor="primary"
+                    textColor="primary"
+                    variant="fullWidth"
+                >
+                    <Tab label="Login" sx={{ fontSize: '.8em' }} />
+                    <Tab label="Register" sx={{ fontSize: '.8em' }} />
+                </Tabs>
+
+                <LoginForm
+                    tab={tab}
+                    tenantList={tenantList}
+                />
+
+                <RegisterForm
+                    tab={tab}
+                    tenantList={tenantList}
+                />
+
+                <Box mt={1} mb={1} sx={{ textAlign: 'center' }}>
+                    <Typography variant="caption" align="center">rsf - sever</Typography>
+                </Box>
+            </Card>
+        </Box >
+    );
+};
+
+const LoginForm = (props) => {
+    const translate = useTranslate();
+    const notify = useNotify();
+    const login = useLogin();
+    const location = useLocation();
+
+    const { tab, tenantList } = props;
+
+    const [loading, setLoading] = useState(false);
+    const [tenantId, setTenantId] = useState(null);
+    const [username, setUsername] = useState('');
+    const [password, setPassword] = useState('');
+    const [btnDisable, setBtnDisable] = useState(true);
+
+    useEffect(() => {
+        if (tenantList.length > 0) {
+            setTenantId(tenantList[0].id);
+        }
+        setBtnDisable(!(tenantId && username && password))
+    }, [tenantList, username, password]);
+
+    const handleSubmit = (auth) => {
+        console.log(auth);
+
+        setLoading(true);
+        // js native confirm && root
+        login(
+            auth,
+            location.state ? (location.state).nextPathname : '/'
+        ).catch((error) => {    
+            setLoading(false);
+            notify(
+                typeof error === 'string'
+                    ? error
+                    : typeof error === 'undefined' || !error.message
+                        ? 'ra.auth.sign_in_error'
+                        : error.message,
+                {
+                    type: 'error',
+                    messageArgs: {
+                        _:
+                            typeof error === 'string'
+                                ? error
+                                : error && error.message
+                                    ? error.message
+                                    : undefined,
+                    },
+                }
+            );
+
+            setUsername(auth.username)
+        });
+    };
+
+    return (
+        <>
+            <Form
+                onSubmit={handleSubmit}
+                noValidate
+            >
+                <Box
+                    hidden={tab !== 0}
+                    p={2}
+                    display="flex"
+                    justifyContent="center"
+                    flexDirection='column'
+                >
+                    <Box width="60%">
+                        <SelectInput
+                            label="page.login.tenant"
+                            source="tenantId"
+                            variant="standard"
+                            choices={tenantList.map(item => ({
+                                id: item.id,
+                                name: item.name
+                            }))}
+                            validate={required()}
+                            defaultValue={tenantId}
+                            onChange={e => setTenantId(e.target.value)}
+                            sx={{ marginTop: 0, marginBottom: 0 }}
+                        />
+                    </Box>
+
+                    <TextInput
+                        label={translate('ra.auth.username')}
+                        source="username"
+                        variant="standard"
+                        disabled={loading}
+                        validate={required()}
+                        value={username}
+                        onChange={e => setUsername(e.target.value)}
+                        autoFocus
+                        sx={{ marginTop: 0, marginBottom: 0 }}
+                    />
+                    <TextInput
+                        label={translate('ra.auth.password')}
+                        source="password"
+                        variant="standard"
+                        type="password"
+                        disabled={loading}
+                        validate={required()}
+                        value={password}
+                        onChange={e => setPassword(e.target.value)}
+                        sx={{ marginTop: 0, marginBottom: 0 }}
+                    />
+                    <Button
+                        variant="contained"
+                        type="submit"
+                        disabled={loading || btnDisable}
+                        fullWidth
+                        sx={{
+                            backgroundColor: "#3D4BA7"
+                        }}
+                    >
+                        {loading && (
+                            <CircularProgress size={25} thickness={2} />
+                        )}
+                        {translate('page.login.button.login')}
+                    </Button>
+
+                    <Box mt={1} mb={1} sx={{ textAlign: 'center' }}>or</Box>
+                </Box >
+            </Form>
+        </>
+    )
+}
+
+const RegisterForm = (props) => {
+
+    return (
+        <>
+            <Box
+                hidden={props.tab !== 1}
+            >
+                Register
+            </Box >
+        </>
+    )
+}
+
+export default Login;

--
Gitblit v1.9.1