blob: 1718111721d0bac896b4b38bf018c8b065b35927 [file] [log] [blame]
Krishya6bf199c2025-06-06 21:14:23 +08001import React, { useState, useEffect } from 'react';
Krishyab5ef96d2025-06-05 13:57:05 +08002import { useGroupStore } from '../../context/useGroupStore';
3import { useUser } from '../../context/UserContext';
Krishyaaffe8102025-06-08 00:44:46 +08004import { useLocation } from 'wouter';
5import './GroupDetail.css';
Krishyadbfadaa2025-06-09 20:33:15 +08006import AuthButton from '../../components/AuthButton';
Krishyab5ef96d2025-06-05 13:57:05 +08007
8const GroupItem = ({ group }) => {
Krishyaaffe8102025-06-08 00:44:46 +08009 const [, setLocation] = useLocation();
10 const { handleJoinGroup, joinStatus, setJoinStatus, fetchGroupList } = useGroupStore();
Krishyab5ef96d2025-06-05 13:57:05 +080011 const { user } = useUser();
Krishya6bf199c2025-06-06 21:14:23 +080012
Krishyab5ef96d2025-06-05 13:57:05 +080013 const userId = user?.userId;
Krishya6bf199c2025-06-06 21:14:23 +080014 const groupId = group.groupId;
15
16 const [isMember, setIsMember] = useState(false);
Krishyaaffe8102025-06-08 00:44:46 +080017 const [loading, setLoading] = useState(false);
18 const [error, setError] = useState('');
Krishya6bf199c2025-06-06 21:14:23 +080019
20 useEffect(() => {
Krishya6bf199c2025-06-06 21:14:23 +080021 setIsMember(joinStatus[groupId] === '加入成功');
22 }, [joinStatus, groupId]);
23
Krishya6bf199c2025-06-06 21:14:23 +080024 useEffect(() => {
25 if (userId && groupId) {
26 checkMembershipStatus();
27 }
28 }, [userId, groupId]);
29
Krishya6bf199c2025-06-06 21:14:23 +080030 const checkMembershipStatus = async () => {
31 try {
Krishyaaffe8102025-06-08 00:44:46 +080032 const res = await fetch(`/echo/groups/${groupId}/members`);
Krishya6bf199c2025-06-06 21:14:23 +080033 const isMember = res.data.members.some(member => member.user_id === userId);
Krishya73cd8822025-06-07 15:48:41 +080034 setIsMember(isMember);
Krishya6bf199c2025-06-06 21:14:23 +080035 } catch (error) {
36 console.error('检查成员状态失败:', error);
37 }
38 };
Krishyab5ef96d2025-06-05 13:57:05 +080039
Krishya6bf199c2025-06-06 21:14:23 +080040 const handleLeaveGroup = async () => {
41 setLoading(true);
42 try {
Krishyaaffe8102025-06-08 00:44:46 +080043 const res = await fetch(`/echo/groups/${groupId}/leave`, {
44 method: 'POST',
45 headers: {
46 'Content-Type': 'application/json',
47 },
48 body: JSON.stringify({
49 user_id: userId,
50 }),
Krishya6bf199c2025-06-06 21:14:23 +080051 });
Krishyaaffe8102025-06-08 00:44:46 +080052
53 if (res.ok && res.data.status === 'success') {
54 fetchGroupList();
Krishya6bf199c2025-06-06 21:14:23 +080055 setIsMember(false);
Krishya6bf199c2025-06-06 21:14:23 +080056 group.memberCount = (group.memberCount || 0) - 1;
57 } else {
58 setError(res.data.message || '退出失败');
59 }
60 } catch (error) {
Krishyaaffe8102025-06-08 00:44:46 +080061 // console.error('退出小组失败:', error);
62 // setError('退出小组失败');
Krishya6bf199c2025-06-06 21:14:23 +080063 } finally {
64 setLoading(false);
65 }
66 };
67
Krishya6bf199c2025-06-06 21:14:23 +080068 const handleJoin = async () => {
69 setLoading(true);
70 try {
71 const res = await handleJoinGroup(groupId, userId);
72 if (res && res.status === 'success') {
73 setJoinStatus(groupId, '加入成功');
74 setIsMember(true);
Krishya6bf199c2025-06-06 21:14:23 +080075 group.memberCount = (group.memberCount || 0) + 1;
76 } else {
77 setError(res?.message || '加入失败');
78 }
79 } catch (error) {
80 console.error('加入小组失败:', error);
81 setError('加入小组失败');
82 } finally {
83 setLoading(false);
84 }
85 };
86
Krishyab5ef96d2025-06-05 13:57:05 +080087 return (
88 <div className="group-item">
89 <div className="group-content">
90 <img
91 style={{ width: '40%', height: '40%' }}
22301009e68c0dd2025-06-05 15:28:07 +080092 src={group.coverImage || 'https://picsum.photos/200/200'}
Krishyab5ef96d2025-06-05 13:57:05 +080093 alt={group.groupName}
94 className="group-cover"
95 />
96 <div className="group-info-right">
Krishya6bf199c2025-06-06 21:14:23 +080097 <h3>{group.groupName}</h3>
Krishyab5ef96d2025-06-05 13:57:05 +080098 <p style={{ color: '#BA929A' }}>{group.memberCount || 0}人加入了小组</p>
99
Krishya6bf199c2025-06-06 21:14:23 +0800100 {userId && (
Krishyadbfadaa2025-06-09 20:33:15 +0800101 <AuthButton
102 roles={["chocolate", "ice-cream"]}
Krishyaaffe8102025-06-08 00:44:46 +0800103 style={{ color: '#2167c9', background: 'none', border: 'none', padding: 0, cursor: 'pointer', fontSize: '16px' }}
104 onClick={(e) => {
105 e.stopPropagation();
106 isMember ? handleLeaveGroup() : handleJoin();
Krishya6bf199c2025-06-06 21:14:23 +0800107 }}
108 disabled={loading}
109 >
110 {loading ? '处理中...' : isMember ? '退出小组' : '+加入小组'}
Krishyadbfadaa2025-06-09 20:33:15 +0800111 </AuthButton>
Krishya6bf199c2025-06-06 21:14:23 +0800112 )}
113 {!userId && <button disabled>请登录</button>}
Krishyab5ef96d2025-06-05 13:57:05 +0800114
Krishya6bf199c2025-06-06 21:14:23 +0800115 {error && <p style={{ color: 'red' }}>{error}</p>}
Krishyab5ef96d2025-06-05 13:57:05 +0800116 </div>
117 </div>
118
119 <div className="group-description">
120 <p>{group.description}</p>
121 </div>
122 <p>分类:{group.category}</p>
123
Krishyaaffe8102025-06-08 00:44:46 +0800124 <button
125 style={{
126 background: 'none',
127 border: 'none',
128 color: '#985F6F',
129 fontSize: '16px',
130 cursor: 'pointer',
131 textDecoration: 'underline',
132 marginBottom: '8px',
133 float: 'right',
134 clear: 'both',
135 }}
136 onClick={() => setLocation(`/group/${groupId}`)}
137 >
138 查看详情
139 </button>
Krishyab5ef96d2025-06-05 13:57:05 +0800140 </div>
141 );
142};
143
Krishya6bf199c2025-06-06 21:14:23 +0800144export default GroupItem;