diff --git a/VERSION b/VERSION index 1e16a1f..a42fb8a 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.15.5 +6.15.6 diff --git a/play-life-web/package.json b/play-life-web/package.json index 42e3de5..c6bdbc0 100644 --- a/play-life-web/package.json +++ b/play-life-web/package.json @@ -1,6 +1,6 @@ { "name": "play-life-web", - "version": "6.15.5", + "version": "6.15.6", "type": "module", "scripts": { "dev": "vite", diff --git a/play-life-web/src/components/TodayEntriesList.jsx b/play-life-web/src/components/TodayEntriesList.jsx index dc4149d..a48cccb 100644 --- a/play-life-web/src/components/TodayEntriesList.jsx +++ b/play-life-web/src/components/TodayEntriesList.jsx @@ -1,6 +1,7 @@ -import React, { useState } from 'react' +import React, { useState, useEffect, useRef } from 'react' import LoadingError from './LoadingError' import { useAuth } from './auth/AuthContext' +import TaskDetail from './TaskDetail' // Функция для форматирования скорa (аналогично formatScore из TaskDetail) const formatScore = (num) => { @@ -134,7 +135,56 @@ const formatEntryText = (text, nodes) => { function TodayEntriesList({ data, loading, error, onRetry, onDelete }) { const { authFetch } = useAuth() const [deletingIds, setDeletingIds] = useState(new Set()) - const [clearingAutoCompleteIds, setClearingAutoCompleteIds] = useState(new Set()) + const [selectedTaskId, setSelectedTaskId] = useState(null) + const selectedTaskIdRef = useRef(null) + const historyPushedRef = useRef(false) + + // Обновляем ref при изменении selectedTaskId + useEffect(() => { + selectedTaskIdRef.current = selectedTaskId + }, [selectedTaskId]) + + // Управление историей браузера при открытии/закрытии TaskDetail + useEffect(() => { + if (selectedTaskId && !historyPushedRef.current) { + window.history.pushState({ modalOpen: true, type: 'task-detail-statistics' }, '', window.location.href) + historyPushedRef.current = true + } else if (!selectedTaskId) { + historyPushedRef.current = false + } + + if (!selectedTaskId) return + + const handlePopState = () => { + if (selectedTaskIdRef.current) { + setSelectedTaskId(null) + historyPushedRef.current = false + } + } + + window.addEventListener('popstate', handlePopState) + return () => { + window.removeEventListener('popstate', handlePopState) + } + }, [selectedTaskId]) + + const handleOpenTaskDetail = (taskId) => { + setSelectedTaskId(taskId) + } + + const handleCloseTaskDetail = () => { + if (historyPushedRef.current) { + window.history.back() + } else { + setSelectedTaskId(null) + } + } + + const handleTaskSaved = () => { + if (onDelete) { + onDelete() + } + } const handleDelete = async (entryId) => { if (deletingIds.has(entryId)) return @@ -175,45 +225,6 @@ function TodayEntriesList({ data, loading, error, onRetry, onDelete }) { } } - const handleClearAutoComplete = async (taskId) => { - if (clearingAutoCompleteIds.has(taskId)) return - - if (!window.confirm('Снять автовыполнение в конце дня? Задача не будет выполнена автоматически.')) { - return - } - - setClearingAutoCompleteIds(prev => new Set(prev).add(taskId)) - - try { - const response = await authFetch(`/api/tasks/${taskId}/draft`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ auto_complete: false }), - }) - - if (!response.ok) { - const errorText = await response.text() - console.error('Clear auto_complete error:', response.status, errorText) - throw new Error(`Ошибка: ${response.status}`) - } - - if (onDelete) { - onDelete() - } - } catch (err) { - console.error('Clear auto_complete failed:', err) - alert(err.message || 'Не удалось снять автовыполнение') - } finally { - setClearingAutoCompleteIds(prev => { - const next = new Set(prev) - next.delete(taskId) - return next - }) - } - } - if (loading) { return (
@@ -235,6 +246,7 @@ function TodayEntriesList({ data, loading, error, onRetry, onDelete }) { } return ( + <>
{data.map((entry) => { @@ -248,9 +260,8 @@ function TodayEntriesList({ data, loading, error, onRetry, onDelete }) { > {isDraft ? ( ) : (
+ {selectedTaskId && ( + + )} + ) }