imetting_frontend/src/pages/Dashboard.jsx

193 lines
5.9 KiB
React
Raw Normal View History

2025-08-05 01:44:28 +00:00
import React, { useState, useEffect } from 'react';
import { LogOut, User, Calendar, Users, TrendingUp, Clock, MessageSquare, Plus } from 'lucide-react';
import axios from 'axios';
import { Link } from 'react-router-dom';
import { buildApiUrl, API_ENDPOINTS } from '../config/api';
import MeetingTimeline from '../components/MeetingTimeline';
import './Dashboard.css';
const Dashboard = ({ user, onLogout }) => {
const [userInfo, setUserInfo] = useState(null);
const [meetings, setMeetings] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
useEffect(() => {
fetchUserData();
}, [user.user_id]);
const fetchUserData = async () => {
try {
setLoading(true);
console.log('Fetching user data for user_id:', user.user_id);
const userResponse = await axios.get(buildApiUrl(API_ENDPOINTS.USERS.DETAIL(user.user_id)));
console.log('User response:', userResponse.data);
setUserInfo(userResponse.data);
const meetingsResponse = await axios.get(buildApiUrl(`${API_ENDPOINTS.MEETINGS.LIST}?user_id=${user.user_id}`));
console.log('Meetings response:', meetingsResponse.data);
setMeetings(meetingsResponse.data);
} catch (err) {
console.error('Error fetching data:', err);
setError('获取数据失败,请刷新重试');
} finally {
setLoading(false);
}
};
const handleDeleteMeeting = async (meetingId) => {
try {
await axios.delete(buildApiUrl(API_ENDPOINTS.MEETINGS.DELETE(meetingId)));
// Refresh meetings list
const meetingsResponse = await axios.get(buildApiUrl(`${API_ENDPOINTS.MEETINGS.LIST}?user_id=${user.user_id}`));
setMeetings(meetingsResponse.data);
} catch (err) {
console.error('Error deleting meeting:', err);
// You might want to show an error message to the user here
}
};
const groupMeetingsByDate = (meetings) => {
return meetings.reduce((acc, meeting) => {
const date = new Date(meeting.meeting_time || meeting.created_at).toISOString().split('T')[0];
if (!acc[date]) {
acc[date] = [];
}
acc[date].push(meeting);
return acc;
}, {});
};
const formatDate = (dateString) => {
const date = new Date(dateString);
return date.toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
};
if (loading) {
return (
<div className="dashboard">
<div className="loading-container">
<div className="loading-spinner"></div>
<p>加载中...</p>
</div>
</div>
);
}
if (error) {
return (
<div className="dashboard">
<div className="error-container">
<p>{error}</p>
<button onClick={fetchUserData} className="retry-btn">重试</button>
</div>
</div>
);
}
const groupedMeetings = groupMeetingsByDate(meetings);
return (
<div className="dashboard">
{/* Header */}
<header className="dashboard-header">
<div className="header-content">
<div className="logo">
<MessageSquare className="logo-icon" />
<span className="logo-text">iMeeting</span>
</div>
<div className="user-actions">
<span className="welcome-text">欢迎{userInfo?.caption}</span>
<button className="logout-btn" onClick={onLogout}>
<LogOut size={18} />
退出
</button>
</div>
</div>
</header>
<div className="dashboard-content">
{/* User Info Section */}
<section className="user-info-section">
<div className="user-card">
<div className="user-avatar">
<User size={32} />
</div>
<div className="user-details">
<h2>{userInfo?.caption}</h2>
<p className="user-email">{userInfo?.email}</p>
<p className="join-date">加入时间{formatDate(userInfo?.created_at)}</p>
</div>
</div>
{/* Stats Cards */}
<div className="stats-grid">
<div className="stat-card">
<div className="stat-icon">
<Calendar className="icon" />
</div>
<div className="stat-info">
<h3>{userInfo?.meetings_created}</h3>
<p>发起的会议</p>
</div>
</div>
<div className="stat-card">
<div className="stat-icon">
<Users className="icon" />
</div>
<div className="stat-info">
<h3>{userInfo?.meetings_attended}</h3>
<p>参加的会议</p>
</div>
</div>
<div className="stat-card">
<div className="stat-icon">
<TrendingUp className="icon" />
</div>
<div className="stat-info">
<h3>{meetings.length}</h3>
<p>相关会议总数</p>
</div>
</div>
</div>
</section>
{/* Meetings Timeline Section */}
<section className="meetings-section">
<div className="section-header">
<div className="section-title">
<h2>
<Clock size={24} />
会议时间轴
</h2>
<p>按时间顺序展示您参与的所有会议</p>
</div>
<Link to="/meetings/create">
<span className="create-meeting-btn">
<Plus size={20} />
新建会议纪要
</span>
</Link>
</div>
<MeetingTimeline
meetingsByDate={groupedMeetings}
currentUser={user}
onDeleteMeeting={handleDeleteMeeting}
/>
</section>
</div>
</div>
);
};
export default Dashboard;