132 lines
4.2 KiB
JavaScript
132 lines
4.2 KiB
JavaScript
import { X, UserPlus, UserMinus } from 'lucide-react'
|
|
import { useNavigate } from 'react-router-dom'
|
|
import { useState } from 'react'
|
|
import { followUser, unfollowUser } from '../utils/api'
|
|
import { hapticFeedback } from '../utils/telegram'
|
|
import './FollowListModal.css'
|
|
|
|
export default function FollowListModal({ users, title, onClose, currentUser }) {
|
|
const navigate = useNavigate()
|
|
const [userStates, setUserStates] = useState(
|
|
users.reduce((acc, user) => {
|
|
acc[user._id] = {
|
|
isFollowing: currentUser?.following?.some(f => f._id === user._id || f === user._id) || false
|
|
}
|
|
return acc
|
|
}, {})
|
|
)
|
|
|
|
const handleOverlayClick = (e) => {
|
|
if (e.target === e.currentTarget) {
|
|
onClose()
|
|
}
|
|
}
|
|
|
|
const handleUserClick = (userId) => {
|
|
hapticFeedback('light')
|
|
onClose()
|
|
navigate(`/user/${userId}`)
|
|
}
|
|
|
|
const handleFollowToggle = async (userId, e) => {
|
|
e.stopPropagation()
|
|
|
|
try {
|
|
hapticFeedback('light')
|
|
const isCurrentlyFollowing = userStates[userId]?.isFollowing || false
|
|
|
|
if (isCurrentlyFollowing) {
|
|
await unfollowUser(userId)
|
|
setUserStates(prev => ({
|
|
...prev,
|
|
[userId]: { isFollowing: false }
|
|
}))
|
|
} else {
|
|
await followUser(userId)
|
|
setUserStates(prev => ({
|
|
...prev,
|
|
[userId]: { isFollowing: true }
|
|
}))
|
|
}
|
|
|
|
hapticFeedback('success')
|
|
} catch (error) {
|
|
console.error('Ошибка подписки:', error)
|
|
hapticFeedback('error')
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="follow-list-modal-overlay" onClick={handleOverlayClick}>
|
|
<div className="follow-list-modal" onClick={(e) => e.stopPropagation()}>
|
|
{/* Хедер */}
|
|
<div className="follow-list-header">
|
|
<button className="close-btn" onClick={onClose}>
|
|
<X size={24} />
|
|
</button>
|
|
<h2>{title}</h2>
|
|
<div style={{ width: 40 }} />
|
|
</div>
|
|
|
|
{/* Список пользователей */}
|
|
<div className="follow-list-content">
|
|
{users.length === 0 ? (
|
|
<div className="empty-state">
|
|
<p>Пока никого нет</p>
|
|
</div>
|
|
) : (
|
|
<div className="users-list">
|
|
{users.map((user) => {
|
|
const isOwnProfile = user._id === currentUser?.id
|
|
const isFollowing = userStates[user._id]?.isFollowing || false
|
|
|
|
return (
|
|
<div
|
|
key={user._id}
|
|
className="user-item"
|
|
onClick={() => handleUserClick(user._id)}
|
|
>
|
|
<img
|
|
src={user.photoUrl || '/default-avatar.png'}
|
|
alt={user.username || user.firstName || 'User'}
|
|
className="user-avatar"
|
|
onError={(e) => { e.target.src = '/default-avatar.png' }}
|
|
/>
|
|
<div className="user-info">
|
|
<div className="user-name">
|
|
{user.firstName || ''} {user.lastName || ''}
|
|
{!user.firstName && !user.lastName && 'Пользователь'}
|
|
</div>
|
|
<div className="user-username">@{user.username || user.firstName || 'user'}</div>
|
|
</div>
|
|
|
|
{!isOwnProfile && (
|
|
<button
|
|
className={`follow-btn ${isFollowing ? 'following' : ''}`}
|
|
onClick={(e) => handleFollowToggle(user._id, e)}
|
|
>
|
|
{isFollowing ? (
|
|
<>
|
|
<UserMinus size={16} />
|
|
<span>Отписаться</span>
|
|
</>
|
|
) : (
|
|
<>
|
|
<UserPlus size={16} />
|
|
<span>Подписаться</span>
|
|
</>
|
|
)}
|
|
</button>
|
|
)}
|
|
</div>
|
|
)
|
|
})}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|