好友的相关前端

Change-Id: Iebe50bff7e96fcf6c13b57c159182f54d0a38b93
diff --git a/src/pages/Friend.css b/src/pages/Friend.css
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/pages/Friend.css
diff --git a/src/pages/Friend.jsx b/src/pages/Friend.jsx
new file mode 100644
index 0000000..fbb384d
--- /dev/null
+++ b/src/pages/Friend.jsx
@@ -0,0 +1,128 @@
+import React, { useState, useEffect } from 'react';
+import { useNavigate } from 'react-router-dom';
+import { getActivityPreviews, getFullActivities } from '../api/activity';
+import FriendManager from '../components/FriendManager';
+import ChatBox from '../components/ChatBox';
+import Navbar from '../components/Navbar';
+import { TeamOutlined, MessageOutlined } from '@ant-design/icons';
+import { Layout, Row, Col, Typography, Empty, Spin } from 'antd';
+import './Friend.css';
+
+const { Title, Text } = Typography;
+const { Content } = Layout;
+
+const Friend = () => {
+    const navigate = useNavigate();
+
+    // 使用 localStorage 获取当前登录用户
+    const [currentUser, setCurrentUser] = useState(null);
+    const [loading, setLoading] = useState(true);
+
+    useEffect(() => {
+        // 从 localStorage 获取用户信息
+        const userData = localStorage.getItem('user');
+        if (userData) {
+            try {
+                const user = JSON.parse(userData);
+                setCurrentUser(user);
+            } catch (e) {
+                console.error('Failed to parse user data');
+                navigate('/login');
+            } finally {
+                setLoading(false);
+            }
+        } else {
+            // 未登录则重定向到登录页
+            navigate('/login');
+        }
+    }, [navigate]);
+
+    const [selectedRelation, setSelectedRelation] = useState(null);
+    const [activityPreviews, setActivityPreviews] = useState([]);
+    const [fullActivities, setFullActivities] = useState([]);
+    const [selectedActivityId, setSelectedActivityId] = useState(null);
+
+    useEffect(() => {
+        if (currentUser) {
+            getActivityPreviews().then(res => setActivityPreviews(res.data));
+            getFullActivities().then(res => setFullActivities(res.data));
+        }
+    }, [currentUser]);
+
+    if (loading) {
+        return (
+            <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}>
+                <Spin size="large" />
+            </div>
+        );
+    }
+
+    return (
+        <Layout style={{ minHeight: '100vh', background: '#f0f2f5', padding: '24px' }}>
+            <Content>
+                <Navbar />
+                <Row justify="space-between" align="middle" style={{ marginBottom: 24 }} />
+
+                <Row gutter={24} style={{ height: 'calc(100vh - 140px)' }}>
+                    {/* 好友管理 - 左侧 */}
+                    <Col xs={24} sm={24} md={10} lg={8} xl={6} style={{ background: '#fff', borderRadius: 8, padding: 24, boxShadow: '0 2px 8px rgba(0,0,0,0.1)', overflowY: 'auto' }}>
+                        <Title level={4} style={{ color: '#722ed1', marginBottom: 24 }}>
+                            <TeamOutlined style={{ marginRight: 8 }} />
+                            好友管理
+                        </Title>
+                        <FriendManager
+                            currentUser={currentUser} // 传递真实登录用户
+                            onSelectRelation={setSelectedRelation}
+                        />
+                    </Col>
+
+                    {/* 聊天窗口 - 右侧 */}
+                    <Col
+                        xs={24}
+                        sm={24}
+                        md={14}
+                        lg={16}
+                        xl={18}
+                        style={{
+                            background: '#fff',
+                            borderRadius: 8,
+                            padding: 24,
+                            boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
+                            display: 'flex',
+                            flexDirection: 'column',
+                        }}
+                    >
+                        <Title level={4} style={{ color: '#eb2f96', marginBottom: 24 }}>
+                            <MessageOutlined style={{ marginRight: 8 }} />
+                            聊天窗口
+                        </Title>
+
+                        <div style={{ flex: 1, minHeight: 0 }}>
+                            {selectedRelation ? (
+                                <div style={{ height: 'calc(100vh - 220px)' }}>
+                                    <ChatBox
+                                        senderId={currentUser.userid} // 使用真实用户ID
+                                        receiverId={selectedRelation.friendId}
+                                    />
+                                </div>
+                            ) : (
+                                <Empty
+                                    image={Empty.PRESENTED_IMAGE_SIMPLE}
+                                    description={<Text type="secondary">请选择一位好友开始聊天</Text>}
+                                    style={{
+                                        height: '100%',
+                                        display: 'flex',
+                                        justifyContent: 'center',
+                                        alignItems: 'center',
+                                    }}
+                                />
+                            )}
+                        </div>
+                    </Col>
+                </Row>
+            </Content>
+        </Layout>
+    );
+};
+
+export default Friend;
\ No newline at end of file