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} + </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