Files
play-life/play-life-web/src/components/BoardSelector.jsx
poignatov f9928c6470
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m0s
Доски желаний и политика награждения
2026-01-13 22:35:01 +03:00

133 lines
4.7 KiB
JavaScript

import React, { useState, useEffect, useRef } from 'react'
import './BoardSelector.css'
function BoardSelector({
boards,
selectedBoardId,
onBoardChange,
onBoardEdit,
onAddBoard,
loading
}) {
const [isOpen, setIsOpen] = useState(false)
const dropdownRef = useRef(null)
const selectedBoard = boards.find(b => b.id === selectedBoardId)
// Закрытие при клике снаружи
useEffect(() => {
const handleClickOutside = (e) => {
if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
setIsOpen(false)
}
}
document.addEventListener('mousedown', handleClickOutside)
return () => document.removeEventListener('mousedown', handleClickOutside)
}, [])
const handleSelectBoard = (board) => {
onBoardChange(board.id)
setIsOpen(false)
}
return (
<div className="board-selector" ref={dropdownRef}>
<div className="board-header">
<button
className={`board-pill ${isOpen ? 'open' : ''}`}
onClick={() => setIsOpen(!isOpen)}
disabled={loading}
>
{!selectedBoard?.is_owner && selectedBoard && (
<span className="shared-icon">👥</span>
)}
<span className="board-label">
{loading ? 'Загрузка...' : (selectedBoard?.name || 'Выберите доску')}
</span>
<svg
className={`chevron ${isOpen ? 'rotated' : ''}`}
width="14"
height="14"
viewBox="0 0 12 12"
>
<path
d="M2.5 4.5L6 8L9.5 4.5"
fill="none"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
</button>
{selectedBoard && (
<button
className="board-action-btn"
onClick={onBoardEdit}
title={selectedBoard.is_owner ? 'Настройки доски' : 'Покинуть доску'}
>
{selectedBoard.is_owner ? (
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<circle cx="12" cy="12" r="1.5"></circle>
<circle cx="19" cy="12" r="1.5"></circle>
<circle cx="5" cy="12" r="1.5"></circle>
</svg>
) : (
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path>
<polyline points="16 17 21 12 16 7"></polyline>
<line x1="21" y1="12" x2="9" y2="12"></line>
</svg>
)}
</button>
)}
</div>
<div className={`board-dropdown ${isOpen ? 'visible' : ''}`}>
<div className="dropdown-content">
{boards.length === 0 ? (
<div className="dropdown-empty">
Нет досок
</div>
) : (
<div className="dropdown-list">
{boards.map(board => (
<button
key={board.id}
className={`dropdown-item ${board.id === selectedBoardId ? 'selected' : ''}`}
onClick={() => handleSelectBoard(board)}
>
<span className="item-name">{board.name}</span>
<div className="item-meta">
{!board.is_owner && <span className="item-badge shared">👥</span>}
{board.member_count > 0 && (
<span className="item-members">{board.member_count}</span>
)}
{board.id === selectedBoardId && (
<svg className="check-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
)}
</div>
</button>
))}
</div>
)}
<button className="dropdown-item add-board" onClick={onAddBoard}>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
<circle cx="12" cy="12" r="10"></circle>
<line x1="12" y1="8" x2="12" y2="16"></line>
<line x1="8" y1="12" x2="16" y2="12"></line>
</svg>
<span>Создать доску</span>
</button>
</div>
</div>
</div>
)
}
export default BoardSelector