From c9fee651948d931769bc2697ae0a3c439324eef7 Mon Sep 17 00:00:00 2001
From: luxiaotao1123 <t1341870251@gmail.com>
Date: 星期日, 09 二月 2025 15:22:23 +0800
Subject: [PATCH] #

---
 rsf-admin/src/page/dashboard/WordEffect.jsx |   71 +++++++++++++++++++++++
 rsf-admin/package.json                      |    1 
 rsf-admin/src/i18n/zh.js                    |    1 
 rsf-admin/package-lock.json                 |   81 +++++++++++++++++++++++++++
 rsf-admin/src/i18n/en.js                    |    1 
 rsf-admin/src/page/dashboard/index.jsx      |   24 +++++++
 6 files changed, 177 insertions(+), 2 deletions(-)

diff --git a/rsf-admin/package-lock.json b/rsf-admin/package-lock.json
index 9735ebc..d6e39ea 100644
--- a/rsf-admin/package-lock.json
+++ b/rsf-admin/package-lock.json
@@ -15,6 +15,7 @@
         "axios": "^1.7.4",
         "date-fns": "^3.6.0",
         "lodash": "^4.17.21",
+        "motion": "^12.4.1",
         "papaparse": "^5.4.1",
         "pixi.js": "^7.4.0",
         "react": "^18.3.0",
@@ -3787,6 +3788,39 @@
         "node": ">=0.4.x"
       }
     },
+    "node_modules/framer-motion": {
+      "version": "12.4.1",
+      "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.4.1.tgz",
+      "integrity": "sha512-5Ijbea3topSZjadQ0hgc/TcWj2ldMZmNREM7RvAhvsThYOA1HHOA8TT1yKvMu1YXP3jWaFwoZ6Vo9Nw+DUZrzA==",
+      "license": "MIT",
+      "dependencies": {
+        "motion-dom": "^12.0.0",
+        "motion-utils": "^12.0.0",
+        "tslib": "^2.4.0"
+      },
+      "peerDependencies": {
+        "@emotion/is-prop-valid": "*",
+        "react": "^18.0.0 || ^19.0.0",
+        "react-dom": "^18.0.0 || ^19.0.0"
+      },
+      "peerDependenciesMeta": {
+        "@emotion/is-prop-valid": {
+          "optional": true
+        },
+        "react": {
+          "optional": true
+        },
+        "react-dom": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/framer-motion/node_modules/tslib": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+      "license": "0BSD"
+    },
     "node_modules/fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -4827,6 +4861,53 @@
         "node": "*"
       }
     },
+    "node_modules/motion": {
+      "version": "12.4.1",
+      "resolved": "https://registry.npmjs.org/motion/-/motion-12.4.1.tgz",
+      "integrity": "sha512-TBnf5NyZVZFOHOc87fyC6qTSU+6LUe09LwxA1Sna35YL7qgOv1EZv96mu6o7uQ2Rl1GvTSQLeyfrQAEG+zlh+w==",
+      "license": "MIT",
+      "dependencies": {
+        "framer-motion": "^12.4.1",
+        "tslib": "^2.4.0"
+      },
+      "peerDependencies": {
+        "@emotion/is-prop-valid": "*",
+        "react": "^18.0.0 || ^19.0.0",
+        "react-dom": "^18.0.0 || ^19.0.0"
+      },
+      "peerDependenciesMeta": {
+        "@emotion/is-prop-valid": {
+          "optional": true
+        },
+        "react": {
+          "optional": true
+        },
+        "react-dom": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/motion-dom": {
+      "version": "12.0.0",
+      "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.0.0.tgz",
+      "integrity": "sha512-CvYd15OeIR6kHgMdonCc1ihsaUG4MYh/wrkz8gZ3hBX/uamyZCXN9S9qJoYF03GqfTt7thTV/dxnHYX4+55vDg==",
+      "license": "MIT",
+      "dependencies": {
+        "motion-utils": "^12.0.0"
+      }
+    },
+    "node_modules/motion-utils": {
+      "version": "12.0.0",
+      "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.0.0.tgz",
+      "integrity": "sha512-MNFiBKbbqnmvOjkPyOKgHUp3Q6oiokLkI1bEwm5QA28cxMZrv0CbbBGDNmhF6DIXsi1pCQBSs0dX8xjeER1tmA==",
+      "license": "MIT"
+    },
+    "node_modules/motion/node_modules/tslib": {
+      "version": "2.8.1",
+      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+      "license": "0BSD"
+    },
     "node_modules/ms": {
       "version": "2.1.2",
       "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz",
diff --git a/rsf-admin/package.json b/rsf-admin/package.json
index 96e85a3..896b101 100644
--- a/rsf-admin/package.json
+++ b/rsf-admin/package.json
@@ -19,6 +19,7 @@
     "axios": "^1.7.4",
     "date-fns": "^3.6.0",
     "lodash": "^4.17.21",
+    "motion": "^12.4.1",
     "papaparse": "^5.4.1",
     "pixi.js": "^7.4.0",
     "react": "^18.3.0",
diff --git a/rsf-admin/src/i18n/en.js b/rsf-admin/src/i18n/en.js
index a31fa3a..445e912 100644
--- a/rsf-admin/src/i18n/en.js
+++ b/rsf-admin/src/i18n/en.js
@@ -220,6 +220,7 @@
         }
     },
     page: {
+        welcome: '    Welcome to the RSF Management System',
         login: {
             title: 'Welcome',
             footer: 'Footer Goes Here',
diff --git a/rsf-admin/src/i18n/zh.js b/rsf-admin/src/i18n/zh.js
index 7f4efd3..c628c00 100644
--- a/rsf-admin/src/i18n/zh.js
+++ b/rsf-admin/src/i18n/zh.js
@@ -220,6 +220,7 @@
         }
     },
     page: {
+        welcome: '    Welcome to the RSF Management System',
         login: {
             title: 'Welcome',
             footer: 'Footer Goes Here',
diff --git a/rsf-admin/src/page/dashboard/WordEffect.jsx b/rsf-admin/src/page/dashboard/WordEffect.jsx
new file mode 100644
index 0000000..3d26c26
--- /dev/null
+++ b/rsf-admin/src/page/dashboard/WordEffect.jsx
@@ -0,0 +1,71 @@
+import { useEffect } from "react"
+import { motion, stagger, useAnimate } from "framer-motion"
+
+export const WordEffect = ({
+    words,
+    filter = true,
+    duration = 0.5,
+    delay = 0.1,
+    color = "black",
+}) => {
+    const [scope, animate] = useAnimate()
+    const wordsArray = words.split(" ")
+    useEffect(() => {
+        animate(
+            "span",
+            {
+                opacity: 1,
+                filter: filter ? "blur(0px)" : "none",
+            },
+            {
+                duration: duration ?? 1,
+                delay: stagger(delay ?? 0.1),
+            },
+        )
+    }, [scope.current])
+
+    const renderWords = () => {
+        return (
+            <motion.div ref={scope}>
+                {wordsArray.map((word, idx) => {
+                    return (
+                        <motion.span
+                            key={word + idx}
+                            style={{
+                                opacity: 0,
+                                filter: filter ? "blur(10px)" : "none",
+                                color: color,
+                                fontWeight: 'bold',
+                                display: 'inline-block',
+                            }}
+                        >
+                            {word}&nbsp;
+                        </motion.span>
+                    )
+                })}
+            </motion.div>
+        )
+    }
+
+    return (
+        <div
+            style={{
+                fontWeight: 'bold',
+            }}
+        >
+            <div style={{ marginTop: '1rem' }}>
+                <div
+                    style={{
+                        color: 'black',
+                        fontSize: '1.5rem',
+                        lineHeight: '2rem',
+                        letterSpacing: '0.05em',
+                    }}
+                >
+                    {renderWords()}
+                </div>
+            </div>
+        </div >
+    )
+}
+
diff --git a/rsf-admin/src/page/dashboard/index.jsx b/rsf-admin/src/page/dashboard/index.jsx
index 3a9b0d1..9c22ac1 100644
--- a/rsf-admin/src/page/dashboard/index.jsx
+++ b/rsf-admin/src/page/dashboard/index.jsx
@@ -1,10 +1,14 @@
 import React, { useState, useRef, useEffect, useMemo } from "react";
 import { useNavigate } from 'react-router-dom';
-import { useAuthProvider } from 'react-admin';
+import { useTheme } from '@mui/material/styles';
+import { useTranslate, useAuthProvider } from 'react-admin';
+import { WordEffect } from './WordEffect'
 
 const Dashboard = () => {
     const authProvider = useAuthProvider();
     const navigate = useNavigate();
+    const theme = useTheme();
+    const translate = useTranslate();
 
     useEffect(() => {
         authProvider.checkAuth().catch(() => {
@@ -14,7 +18,23 @@
 
     return (
         <>
-            <h1>Dashboard</h1>
+            <div
+                style={{
+                    boxSizing: 'border-box',
+                    display: 'flex',
+                    width: '100%',
+                    height: '100%',
+                    flexDirection: 'column',
+                    justifyContent: 'flex-start',
+                    alignItems: 'flex-start',
+                    padding: '2rem 1rem',
+                }}
+            >
+                <WordEffect
+                    words={translate('page.welcome')}
+                    color={theme.palette.mode === 'light' ? '#666' : '#eeeeee'}
+                />
+            </div>
         </>
     )
 }

--
Gitblit v1.9.1