import React, { useState, useEffect } from 'react' import { useAuth } from './auth/AuthContext' import BoardMembers from './BoardMembers' import Toast from './Toast' import SubmitButton from './SubmitButton' import DeleteButton from './DeleteButton' import './Buttons.css' import './BoardForm.css' function BoardForm({ boardId, onNavigate, onSaved }) { const { authFetch } = useAuth() const [name, setName] = useState('') const [inviteEnabled, setInviteEnabled] = useState(false) const [inviteURL, setInviteURL] = useState('') const [loading, setLoading] = useState(false) const [loadingBoard, setLoadingBoard] = useState(false) const [isDeleting, setIsDeleting] = useState(false) const [copied, setCopied] = useState(false) const [toastMessage, setToastMessage] = useState(null) const isEdit = !!boardId useEffect(() => { if (boardId) { fetchBoard() } }, [boardId]) const fetchBoard = async () => { setLoadingBoard(true) try { const res = await authFetch(`/api/wishlist/boards/${boardId}`) if (res.ok) { const data = await res.json() setName(data.name) setInviteEnabled(data.invite_enabled) setInviteURL(data.invite_url || '') } else { setToastMessage({ text: 'Ошибка загрузки доски', type: 'error' }) } } catch (err) { setToastMessage({ text: 'Ошибка загрузки', type: 'error' }) } finally { setLoadingBoard(false) } } const handleSave = async () => { if (!name.trim()) { setToastMessage({ text: 'Введите название доски', type: 'error' }) return } setLoading(true) try { const url = boardId ? `/api/wishlist/boards/${boardId}` : '/api/wishlist/boards' const res = await authFetch(url, { method: boardId ? 'PUT' : 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: name.trim(), invite_enabled: inviteEnabled }) }) if (res.ok) { const data = await res.json() if (data.invite_url) { setInviteURL(data.invite_url) } onSaved?.() if (!boardId) { // При создании возвращаемся назад onNavigate('wishlist', { boardId: data.id }) } else { // При редактировании возвращаемся на доску onNavigate('wishlist', { boardId: boardId }) } } else { const err = await res.json() setToastMessage({ text: err.error || 'Ошибка сохранения', type: 'error' }) } } catch (err) { setToastMessage({ text: 'Ошибка сохранения', type: 'error' }) } finally { setLoading(false) } } // Функция для автоматической генерации ссылки при включении доступа const generateInviteLink = async () => { try { const res = await authFetch(`/api/wishlist/boards/${boardId}/regenerate-invite`, { method: 'POST' }) if (res.ok) { const data = await res.json() setInviteURL(data.invite_url) setInviteEnabled(true) } } catch (err) { console.error('Error generating invite link:', err) } } const handleCopyLink = () => { navigator.clipboard.writeText(inviteURL) setCopied(true) setToastMessage({ text: 'Ссылка скопирована', type: 'success' }) setTimeout(() => setCopied(false), 2000) } const handleToggleInvite = async (enabled) => { setInviteEnabled(enabled) if (boardId && enabled && !inviteURL) { // Автоматически генерируем ссылку при включении await generateInviteLink() } else if (boardId) { // Просто обновляем статус try { await authFetch(`/api/wishlist/boards/${boardId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ invite_enabled: enabled }) }) } catch (err) { console.error('Error updating invite status:', err) } } } const handleDelete = async () => { if (!window.confirm('Удалить доску? Все желания на ней будут удалены.')) return setIsDeleting(true) try { const res = await authFetch(`/api/wishlist/boards/${boardId}`, { method: 'DELETE' }) if (res.ok) { onSaved?.() // Передаём флаг, что доска удалена, чтобы Wishlist выбрал первую доступную onNavigate('wishlist', { boardDeleted: true }) } else { setToastMessage({ text: 'Ошибка удаления', type: 'error' }) setIsDeleting(false) } } catch (err) { setToastMessage({ text: 'Ошибка удаления', type: 'error' }) setIsDeleting(false) } } const handleClose = () => { window.history.back() } if (loadingBoard) { return (
Пользователь, открывший ссылку, сможет присоединиться к доске