| import React, { useState, useEffect } from 'react'; |
| import { useGroupStore } from '../../context/useGroupStore'; |
| import { useUser } from '../../context/UserContext'; |
| import { useLocation } from 'wouter'; |
| import './GroupDetail.css'; |
| import AuthButton from '../../components/AuthButton'; |
| |
| const GroupItem = ({ group }) => { |
| const [, setLocation] = useLocation(); |
| const { handleJoinGroup, joinStatus, setJoinStatus, fetchGroupList } = useGroupStore(); |
| const { user } = useUser(); |
| |
| const userId = user?.userId; |
| const groupId = group.groupId; |
| |
| const [isMember, setIsMember] = useState(false); |
| const [loading, setLoading] = useState(false); |
| const [error, setError] = useState(''); |
| |
| useEffect(() => { |
| setIsMember(joinStatus[groupId] === '加入成功'); |
| }, [joinStatus, groupId]); |
| |
| useEffect(() => { |
| if (userId && groupId) { |
| checkMembershipStatus(); |
| } |
| }, [userId, groupId]); |
| |
| const checkMembershipStatus = async () => { |
| try { |
| const res = await fetch(`/echo/groups/${groupId}/members`); |
| const isMember = res.data.members.some(member => member.user_id === userId); |
| setIsMember(isMember); |
| } catch (error) { |
| console.error('检查成员状态失败:', error); |
| } |
| }; |
| |
| const handleLeaveGroup = async () => { |
| setLoading(true); |
| try { |
| const res = await fetch(`/echo/groups/${groupId}/leave`, { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: JSON.stringify({ |
| user_id: userId, |
| }), |
| }); |
| |
| if (res.ok && res.data.status === 'success') { |
| fetchGroupList(); |
| setIsMember(false); |
| group.memberCount = (group.memberCount || 0) - 1; |
| } else { |
| setError(res.data.message || '退出失败'); |
| } |
| } catch (error) { |
| // console.error('退出小组失败:', error); |
| // setError('退出小组失败'); |
| } finally { |
| setLoading(false); |
| } |
| }; |
| |
| const handleJoin = async () => { |
| setLoading(true); |
| try { |
| const res = await handleJoinGroup(groupId, userId); |
| if (res && res.status === 'success') { |
| setJoinStatus(groupId, '加入成功'); |
| setIsMember(true); |
| group.memberCount = (group.memberCount || 0) + 1; |
| } else { |
| setError(res?.message || '加入失败'); |
| } |
| } catch (error) { |
| console.error('加入小组失败:', error); |
| setError('加入小组失败'); |
| } finally { |
| setLoading(false); |
| } |
| }; |
| |
| return ( |
| <div className="group-item"> |
| <div className="group-content"> |
| <img |
| style={{ width: '40%', height: '40%' }} |
| src={group.coverImage || 'https://picsum.photos/200/200'} |
| alt={group.groupName} |
| className="group-cover" |
| /> |
| <div className="group-info-right"> |
| <h3>{group.groupName}</h3> |
| <p style={{ color: '#BA929A' }}>{group.memberCount || 0}人加入了小组</p> |
| |
| {userId && ( |
| <AuthButton |
| roles={["chocolate", "ice-cream"]} |
| style={{ color: '#2167c9', background: 'none', border: 'none', padding: 0, cursor: 'pointer', fontSize: '16px' }} |
| onClick={(e) => { |
| e.stopPropagation(); |
| isMember ? handleLeaveGroup() : handleJoin(); |
| }} |
| disabled={loading} |
| > |
| {loading ? '处理中...' : isMember ? '退出小组' : '+加入小组'} |
| </AuthButton> |
| )} |
| {!userId && <button disabled>请登录</button>} |
| |
| {error && <p style={{ color: 'red' }}>{error}</p>} |
| </div> |
| </div> |
| |
| <div className="group-description"> |
| <p>{group.description}</p> |
| </div> |
| <p>分类:{group.category}</p> |
| |
| <button |
| style={{ |
| background: 'none', |
| border: 'none', |
| color: '#985F6F', |
| fontSize: '16px', |
| cursor: 'pointer', |
| textDecoration: 'underline', |
| marginBottom: '8px', |
| float: 'right', |
| clear: 'both', |
| }} |
| onClick={() => setLocation(`/group/${groupId}`)} |
| > |
| 查看详情 |
| </button> |
| </div> |
| ); |
| }; |
| |
| export default GroupItem; |