6.11.3: Настройки доски внутри селекта
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m6s

This commit is contained in:
poignatov
2026-03-11 09:18:56 +03:00
parent ac1f6c3a47
commit 20778d6d39
4 changed files with 106 additions and 83 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "play-life-web",
"version": "6.11.2",
"version": "6.11.3",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -15,7 +15,6 @@
.board-header {
display: flex;
gap: 12px;
align-items: center;
}
@@ -70,48 +69,30 @@
white-space: nowrap;
}
.chevron {
color: #9ca3af;
flex-shrink: 0;
transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.chevron.rotated {
transform: rotate(180deg);
}
/* Кнопка действия (настройки/выход) */
.board-action-btn {
/* Иконка настроек/выхода внутри pill */
.pill-action-btn {
display: flex;
align-items: center;
justify-content: center;
width: 52px;
height: 52px;
padding: 0;
background: white;
border: 1px solid #e5e7eb;
border-radius: 50%;
cursor: pointer;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
color: #6b7280;
width: 32px;
height: 32px;
margin-left: 4px;
border-left: 1px solid #e5e7eb;
padding-left: 10px;
color: #9ca3af;
flex-shrink: 0;
cursor: pointer;
transition: color 0.15s ease;
box-sizing: content-box;
}
.board-action-btn:hover {
background: #f9fafb;
color: #374151;
border-color: #6366f1;
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
transform: translateY(-1px);
.board-pill:hover:not(:disabled) .pill-action-btn,
.board-pill.open .pill-action-btn {
border-left-color: rgba(99, 102, 241, 0.3);
}
.board-action-btn:active {
transform: translateY(0);
}
.board-action-btn svg {
width: 22px;
height: 22px;
.pill-action-btn:hover {
color: #4f46e5;
}
/* Выпадающий список */
@@ -259,3 +240,26 @@
width: 20px;
height: 20px;
}
/* Кнопка настроек/выхода в дропдауне */
.dropdown-item.board-action-item {
margin-top: 2px;
padding-top: 14px;
border-top: 1px solid #f3f4f6;
border-radius: 0 0 12px 12px;
color: #6b7280;
font-weight: 500;
gap: 12px;
justify-content: flex-start;
}
.dropdown-item.board-action-item:hover {
background: #f3f4f6;
color: #374151;
}
.dropdown-item.board-action-item svg {
flex-shrink: 0;
width: 20px;
height: 20px;
}

View File

@@ -1,17 +1,17 @@
import React, { useState, useEffect, useRef } from 'react'
import './BoardSelector.css'
function BoardSelector({
boards,
selectedBoardId,
onBoardChange,
function BoardSelector({
boards,
selectedBoardId,
onBoardChange,
onBoardEdit,
onAddBoard,
loading
loading
}) {
const [isOpen, setIsOpen] = useState(false)
const dropdownRef = useRef(null)
const selectedBoard = boards.find(b => b.id === selectedBoardId)
// Закрытие при клике снаружи
@@ -30,10 +30,16 @@ function BoardSelector({
setIsOpen(false)
}
const handleBoardAction = (e) => {
e.stopPropagation()
setIsOpen(false)
onBoardEdit()
}
return (
<div className="board-selector" ref={dropdownRef}>
<div className="board-header">
<button
<button
className={`board-pill ${isOpen ? 'open' : ''}`}
onClick={() => setIsOpen(!isOpen)}
disabled={loading}
@@ -41,46 +47,33 @@ function BoardSelector({
<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>
{selectedBoard && (
<span
className="pill-action-btn"
role="button"
tabIndex={0}
title={selectedBoard.is_owner ? 'Настройки доски' : 'Покинуть доску'}
onClick={handleBoardAction}
onKeyDown={(e) => e.key === 'Enter' && handleBoardAction(e)}
>
{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>
)}
</span>
)}
</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 ? (
@@ -103,7 +96,7 @@ function BoardSelector({
))}
</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>
@@ -112,6 +105,32 @@ function BoardSelector({
</svg>
<span>Создать доску</span>
</button>
{selectedBoard && (
<button
className="dropdown-item board-action-item"
onClick={(e) => { setIsOpen(false); onBoardEdit() }}
>
{selectedBoard.is_owner ? (
<>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<circle cx="12" cy="12" r="3"></circle>
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
</svg>
<span>Настройки доски</span>
</>
) : (
<>
<svg width="16" height="16" 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>
<span>Покинуть доску</span>
</>
)}
</button>
)}
</div>
</div>
</div>