diff --git a/VERSION b/VERSION index d613169..0438a6c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.4.12 +6.4.13 diff --git a/play-life-web/package.json b/play-life-web/package.json index 0ec45fd..c4abe5c 100644 --- a/play-life-web/package.json +++ b/play-life-web/package.json @@ -1,6 +1,6 @@ { "name": "play-life-web", - "version": "6.4.12", + "version": "6.4.13", "type": "module", "scripts": { "dev": "vite", diff --git a/play-life-web/src/App.jsx b/play-life-web/src/App.jsx index e91b05b..f6d0409 100644 --- a/play-life-web/src/App.jsx +++ b/play-life-web/src/App.jsx @@ -773,9 +773,10 @@ function AppContent() { // Проверяем, есть ли открытые модальные окна в DOM const taskDetailModal = document.querySelector('.task-detail-modal-overlay') const wishlistDetailModal = document.querySelector('.wishlist-detail-modal-overlay') + const conditionFormOverlay = document.querySelector('.condition-form-overlay') // Если есть открытые модальные окна, не обрабатываем здесь - компоненты сами закроют их - if (taskDetailModal || wishlistDetailModal) { + if (taskDetailModal || wishlistDetailModal || conditionFormOverlay) { return } @@ -922,7 +923,7 @@ function AppContent() { if (isNewTabDeep) { // Проверяем, была ли последняя запись в истории от модального окна const currentState = window.history.state || {} - const isFromModal = currentState.modalOpen === true + const isFromModal = currentState.modalOpen === true || currentState.conditionForm === true const isNavigatingToForm = tab === 'task-form' || tab === 'wishlist-form' || tab === 'shopping-item-form' if (isFromModal && isNavigatingToForm) { diff --git a/play-life-web/src/components/TaskForm.jsx b/play-life-web/src/components/TaskForm.jsx index 44da907..585c7e3 100644 --- a/play-life-web/src/components/TaskForm.jsx +++ b/play-life-web/src/components/TaskForm.jsx @@ -768,11 +768,11 @@ function TaskForm({ onNavigate, taskId, wishlistId, isTest: isTestFromProps = fa // Если был returnTo, возвращаемся на форму желания с ID новой задачи if (returnTo === 'wishlist-form') { - console.log('[TaskForm] Navigating back to wishlist-form with newTaskId:', newTaskId) - onNavigate?.(returnTo, { - wishlistId: returnWishlistId, - newTaskId: newTaskId, - }) + console.log('[TaskForm] Saving newTaskId to sessionStorage and going back:', newTaskId) + // Сохраняем newTaskId в sessionStorage, чтобы WishlistForm мог его прочитать + sessionStorage.setItem('wishlistFormNewTaskId', String(newTaskId)) + // Используем history.back() чтобы не создавать лишнюю запись в стеке + window.history.back() } else { console.log('[TaskForm] No returnTo, going back in history') // Возврат назад по стеку истории (на список задач, желаний и т.д.) diff --git a/play-life-web/src/components/WishlistForm.jsx b/play-life-web/src/components/WishlistForm.jsx index 303711e..85d9f99 100644 --- a/play-life-web/src/components/WishlistForm.jsx +++ b/play-life-web/src/components/WishlistForm.jsx @@ -9,8 +9,20 @@ const TASKS_API_URL = '/api/tasks' const PROJECTS_API_URL = '/projects' const WISHLIST_FORM_STATE_KEY = 'wishlistFormPendingState' -function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, boardId }) { +function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId: newTaskIdProp, boardId }) { const { authFetch, user } = useAuth() + + // newTaskId может прийти из props (через onNavigate) или из sessionStorage (через history.back) + const [newTaskId] = useState(() => { + if (newTaskIdProp) return newTaskIdProp + const stored = sessionStorage.getItem('wishlistFormNewTaskId') + if (stored) { + sessionStorage.removeItem('wishlistFormNewTaskId') + return parseInt(stored, 10) + } + return undefined + }) + const [name, setName] = useState('') const [price, setPrice] = useState('') const [link, setLink] = useState('') @@ -33,10 +45,14 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b const [toastMessage, setToastMessage] = useState(null) const [loadingWishlist, setLoadingWishlist] = useState(false) const [fetchingMetadata, setFetchingMetadata] = useState(false) - const [restoredFromSession, setRestoredFromSession] = useState(false) // Флаг восстановления из sessionStorage + const [restoredFromSession, setRestoredFromSession] = useState(() => { + // Инициализируем флаг сразу, чтобы loadWishlist не запустился до восстановления + return !!(newTaskId && sessionStorage.getItem(WISHLIST_FORM_STATE_KEY)) + }) const [loadedWishlistData, setLoadedWishlistData] = useState(null) // Данные желания для последующего маппинга условий const [imageUrlInput, setImageUrlInput] = useState('') // Ссылка на картинку для загрузки по URL const [loadingImageFromUrl, setLoadingImageFromUrl] = useState(false) + const [newTaskConsumed, setNewTaskConsumed] = useState(false) // Флаг что newTaskId уже добавлен как цель const fileInputRef = useRef(null) // Загрузка задач, проектов и саджестов групп @@ -139,6 +155,24 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b } }, [editConditionIndex, unlockConditions]) + // Обработка кнопки "назад" для диалога ConditionForm + const showConditionFormRef = useRef(false) + const conditionClosedByPopStateRef = useRef(false) + showConditionFormRef.current = showConditionForm + + useEffect(() => { + const handlePopState = () => { + if (showConditionFormRef.current) { + // Закрываем диалог — popstate уже убрал запись из стека + conditionClosedByPopStateRef.current = true + setShowConditionForm(false) + setEditingConditionIndex(null) + } + } + window.addEventListener('popstate', handlePopState) + return () => window.removeEventListener('popstate', handlePopState) + }, []) + // Восстановление состояния при возврате с создания задачи useEffect(() => { const savedState = sessionStorage.getItem(WISHLIST_FORM_STATE_KEY) @@ -161,6 +195,9 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b const restoredConditions = state.unlockConditions || [] console.log('[WishlistForm] Restored conditions:', restoredConditions) + // Устанавливаем флаг синхронно, чтобы loadWishlist не перезаписал восстановленное состояние + setRestoredFromSession(true) + // Перезагружаем задачи, чтобы новая задача была в списке const reloadTasks = async () => { console.log('[WishlistForm] Reloading tasks...') @@ -171,7 +208,7 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b const tasksData = await tasksResponse.json() console.log('[WishlistForm] Tasks loaded:', tasksData.length) setTasks(Array.isArray(tasksData) ? tasksData : []) - + // Автоматически добавляем цель с новой задачей console.log('[WishlistForm] pendingConditionType:', state.pendingConditionType) if (state.pendingConditionType === 'task_completion') { @@ -184,11 +221,11 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b display_order: restoredConditions.length, } console.log('[WishlistForm] New condition to add:', newCondition) - + // Если редактировали существующее условие, заменяем его if (state.editingConditionIndex !== null && state.editingConditionIndex !== undefined) { console.log('[WishlistForm] Replacing existing condition at index:', state.editingConditionIndex) - const updatedConditions = restoredConditions.map((cond, idx) => + const updatedConditions = restoredConditions.map((cond, idx) => idx === state.editingConditionIndex ? { ...newCondition, display_order: idx } : cond ) setUnlockConditions(updatedConditions) @@ -199,12 +236,10 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b console.log('[WishlistForm] Adding new condition, final conditions:', finalConditions) setUnlockConditions(finalConditions) } + setNewTaskConsumed(true) } else { setUnlockConditions(restoredConditions) } - - // Устанавливаем флаг, что состояние восстановлено - setRestoredFromSession(true) } } catch (err) { console.error('[WishlistForm] Error reloading tasks:', err) @@ -543,9 +578,25 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b } } + const openConditionForm = () => { + setShowConditionForm(true) + conditionClosedByPopStateRef.current = false + window.history.pushState({ conditionForm: true }, '', window.location.href) + } + + const closeConditionForm = () => { + setShowConditionForm(false) + setEditingConditionIndex(null) + // Если закрытие через popstate — запись уже убрана, не делаем back + if (!conditionClosedByPopStateRef.current) { + window.history.back() + } + conditionClosedByPopStateRef.current = false + } + const handleAddCondition = () => { setEditingConditionIndex(null) - setShowConditionForm(true) + openConditionForm() } const handleEditCondition = (index) => { @@ -556,26 +607,24 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b return } setEditingConditionIndex(index) - setShowConditionForm(true) + openConditionForm() } const handleConditionSubmit = (condition) => { if (editingConditionIndex !== null) { // Редактирование существующего условия - setUnlockConditions(prev => prev.map((cond, idx) => + setUnlockConditions(prev => prev.map((cond, idx) => idx === editingConditionIndex ? { ...condition, display_order: idx } : cond )) } else { // Добавление нового условия setUnlockConditions([...unlockConditions, { ...condition, display_order: unlockConditions.length }]) } - setShowConditionForm(false) - setEditingConditionIndex(null) + closeConditionForm() } const handleConditionCancel = () => { - setShowConditionForm(false) - setEditingConditionIndex(null) + closeConditionForm() } const handleRemoveCondition = (index) => { @@ -590,6 +639,9 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b // Обработчик для создания задачи из ConditionForm const handleCreateTaskFromCondition = () => { + // Закрываем диалог цели перед переходом + setShowConditionForm(false) + // Сохранить текущее состояние формы const stateToSave = { name, @@ -602,7 +654,7 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b } console.log('[WishlistForm] Saving state and navigating to task-form:', stateToSave) sessionStorage.setItem(WISHLIST_FORM_STATE_KEY, JSON.stringify(stateToSave)) - + // Навигация на форму создания задачи const navParams = { returnTo: 'wishlist-form', @@ -987,7 +1039,7 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b onCancel={handleConditionCancel} editingCondition={editingConditionIndex !== null ? unlockConditions[editingConditionIndex] : null} onCreateTask={handleCreateTaskFromCondition} - preselectedTaskId={newTaskId} + preselectedTaskId={newTaskConsumed ? undefined : newTaskId} authFetch={authFetch} /> )}