122 lines
4.2 KiB
React
122 lines
4.2 KiB
React
|
|
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}
|
||
|
|
>
|
||
|
|
<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">
|
||
|
|
<span className={`item-members ${board.is_owner ? 'filled' : 'outline'}`}>{board.member_count + 1}</span>
|
||
|
|
</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
|