今天,我們要來為系統增加一些功能,並且優化整體的用戶體驗。
首先,我們來實現一個即時通知系統,讓用戶可以及時收到重要的消息。我們將使用 Socket.IO 來實現這個功能。
npm install socket.io-client
在 src/services/socketService.ts
中:
import { io } from 'socket.io-client';
const socket = io('http://localhost:3001'); // 替換成你的 Socket.IO server地址
export const connectSocket = () => {
socket.on('connect', () => {
console.log('Connected to Socket.IO server');
});
socket.on('notification', (message) => {
// 這裡可以觸發一個全局的通知顯示
console.log('New notification:', message);
});
};
export const disconnectSocket = () => {
socket.disconnect();
};
在 src/App.tsx
中:
import React, { useEffect } from 'react';
import { connectSocket, disconnectSocket } from './services/socketService';
function App() {
useEffect(() => {
connectSocket();
return () => {
disconnectSocket();
};
}, []);
// ... 其他code
}
接下來,我們來改進全局的錯誤處理,讓用戶在遇到問題時能夠得到更好的反饋。
在 src/hooks/useErrorHandler.ts
中:
import { useCallback } from 'react';
import { toast } from 'react-toastify';
export const useErrorHandler = () => {
const handleError = useCallback((error: any) => {
console.error('An error occurred:', error);
if (error.response) {
// 處理來自服務器的錯誤響應
toast.error(`錯誤:${error.response.data.message || '發生未知錯誤'}`);
} else if (error.request) {
// 處理沒有收到響應的請求錯誤
toast.error('無法連接到服務器,請檢查您的網絡連接');
} else {
// 處理其他錯誤
toast.error(`發生錯誤:${error.message}`);
}
}, []);
return handleError;
};
在需要處理錯誤的組件中:
import React from 'react';
import { useQuery } from '@tanstack/react-query';
import { getMembers } from '../services/memberService';
import { useErrorHandler } from '../hooks/useErrorHandler';
const MemberList: React.FC = () => {
const handleError = useErrorHandler();
const { data, isLoading, error } = useQuery(['members'], getMembers, {
onError: handleError,
});
if (isLoading) return <div>載入中...</div>;
if (error) return <div>發生錯誤,請稍後再試</div>;
// 渲染會員列表
};
為了幫助新用戶快速上手,我們可以添加一個導引功能。我們將使用 react-joyride 來實現這個功能。
npm install react-joyride
在 src/components/UserGuide.tsx
中:
import React, { useState } from 'react';
import Joyride, { Step } from 'react-joyride';
const steps: Step[] = [
{
target: '.dashboard',
content: '這是儀表板,你可以在這裡看到重要的統計數據',
},
{
target: '.member-list',
content: '這裡列出了所有的會員',
},
{
target: '.class-schedule',
content: '這是課程表,你可以在這裡管理所有的課程',
},
// ... 可以繼續增加更多步驟
];
const UserGuide: React.FC = () => {
const [run, setRun] = useState(true);
return (
<Joyride
steps={steps}
run={run}
continuous
showProgress
showSkipButton
styles={{
options: {
primaryColor: '#4f46e5',
},
}}
callback={(data) => {
const { status } = data;
if (status === 'finished' || status === 'skipped') {
setRun(false);
}
}}
/>
);
};
export default UserGuide;
在 src/pages/Dashboard.tsx
中:
import React from 'react';
import UserGuide from '../components/UserGuide';
const Dashboard: React.FC = () => {
return (
<div>
<UserGuide />
{/* 儀表板的其他內容 */}
</div>
);
};
export default Dashboard;
最後,我們來添加一些簡單的 UI 動畫,讓界面看起來更加生動。我們將使用 Framer Motion 來實現這些動畫。
npm install framer-motion
在 src/components/AnimatedCard.tsx
中:
import React from 'react';
import { motion } from 'framer-motion';
interface AnimatedCardProps {
children: React.ReactNode;
}
const AnimatedCard: React.FC<AnimatedCardProps> = ({ children }) => {
return (
<motion.div
initial={{ opacity: 0, y: 50 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
className="bg-white p-6 rounded-lg shadow-lg"
>
{children}
</motion.div>
);
};
export default AnimatedCard;
在需要動畫效果的地方使用 AnimatedCard
:
import React from 'react';
import AnimatedCard from '../components/AnimatedCard';
const Dashboard: React.FC = () => {
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<AnimatedCard>
<h2>會員統計</h2>
{/* 會員統計內容 */}
</AnimatedCard>
<AnimatedCard>
<h2>課程統計</h2>
{/* 課程統計內容 */}
</AnimatedCard>
<AnimatedCard>
<h2>收入統計</h2>
{/* 收入統計內容 */}
</AnimatedCard>
</div>
);
};
export default Dashboard;
今天我們為 Gym Pro 系統增加一些功能: