6.4.2: Закрытие диалогов кнопкой назад (товары)
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m19s

This commit is contained in:
poignatov
2026-03-08 19:25:35 +03:00
parent 01631ff13b
commit c8fead4034
5 changed files with 77 additions and 8 deletions

View File

@@ -1 +1 @@
6.4.1 6.4.2

View File

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

View File

@@ -13,7 +13,6 @@
} }
.shopping-item-form .repetition-label { .shopping-item-form .repetition-label {
color: #64748b; font-size: 1rem;
font-size: 0.875rem;
white-space: nowrap; white-space: nowrap;
} }

View File

@@ -235,7 +235,7 @@ function ShoppingItemForm({ onNavigate, itemId, boardId, onSaved }) {
<div className="form-group"> <div className="form-group">
<label htmlFor="item-repetition">Повторения</label> <label htmlFor="item-repetition">Повторения</label>
<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}> <div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
<span className="repetition-label">Через</span> <span className="repetition-label">Хватает на</span>
<input <input
id="item-repetition" id="item-repetition"
type="number" type="number"

View File

@@ -124,6 +124,12 @@ function ShoppingList({ onNavigate, refreshTrigger = 0, isActive = false, initia
const initialFetchDoneRef = useRef(false) const initialFetchDoneRef = useRef(false)
const prevIsActiveRef = useRef(isActive) const prevIsActiveRef = useRef(isActive)
// Refs для закрытия диалогов кнопкой "Назад"
const historyPushedForDetailRef = useRef(false)
const historyPushedForPostponeRef = useRef(false)
const selectedItemForDetailRef = useRef(selectedItemForDetail)
const selectedItemForPostponeRef = useRef(selectedItemForPostpone)
const setSelectedBoardId = (boardId) => { const setSelectedBoardId = (boardId) => {
setSelectedBoardIdState(boardId) setSelectedBoardIdState(boardId)
try { try {
@@ -250,6 +256,56 @@ function ShoppingList({ onNavigate, refreshTrigger = 0, isActive = false, initia
} }
}, [initialBoardId]) }, [initialBoardId])
// Синхронизация refs для диалогов
useEffect(() => {
selectedItemForDetailRef.current = selectedItemForDetail
selectedItemForPostponeRef.current = selectedItemForPostpone
}, [selectedItemForDetail, selectedItemForPostpone])
// Закрытие диалогов кнопкой "Назад" (browser history API)
useEffect(() => {
if (selectedItemForPostpone && !historyPushedForPostponeRef.current) {
window.history.pushState({ modalOpen: true, type: 'shopping-postpone' }, '', window.location.href)
historyPushedForPostponeRef.current = true
} else if (!selectedItemForPostpone) {
historyPushedForPostponeRef.current = false
}
if (selectedItemForDetail && !historyPushedForDetailRef.current) {
window.history.pushState({ modalOpen: true, type: 'shopping-detail' }, '', window.location.href)
historyPushedForDetailRef.current = true
} else if (!selectedItemForDetail) {
historyPushedForDetailRef.current = false
}
if (!selectedItemForDetail && !selectedItemForPostpone) return
const handlePopState = () => {
const currentDetail = selectedItemForDetailRef.current
const currentPostpone = selectedItemForPostponeRef.current
if (currentPostpone) {
setSelectedItemForPostpone(null)
setPostponeDate('')
historyPushedForPostponeRef.current = false
if (currentDetail) {
window.history.pushState({ modalOpen: true, type: 'shopping-detail' }, '', window.location.href)
}
return
}
if (currentDetail) {
setSelectedItemForDetail(null)
historyPushedForDetailRef.current = false
}
}
window.addEventListener('popstate', handlePopState)
return () => {
window.removeEventListener('popstate', handlePopState)
}
}, [selectedItemForDetail, selectedItemForPostpone])
// Фильтрация и группировка на клиенте // Фильтрация и группировка на клиенте
const groupedItems = useMemo(() => { const groupedItems = useMemo(() => {
const now = new Date() const now = new Date()
@@ -319,10 +375,24 @@ function ShoppingList({ onNavigate, refreshTrigger = 0, isActive = false, initia
if (selectedBoardId) fetchItems(selectedBoardId) if (selectedBoardId) fetchItems(selectedBoardId)
} }
const handleCloseDetail = () => {
if (historyPushedForDetailRef.current) {
window.history.back()
} else {
historyPushedForDetailRef.current = false
setSelectedItemForDetail(null)
}
}
// Модалка переноса // Модалка переноса
const handlePostponeClose = () => { const handlePostponeClose = () => {
setSelectedItemForPostpone(null) if (historyPushedForPostponeRef.current) {
setPostponeDate('') window.history.back()
} else {
historyPushedForPostponeRef.current = false
setSelectedItemForPostpone(null)
setPostponeDate('')
}
} }
const handleDateSelect = (date) => { const handleDateSelect = (date) => {
@@ -607,7 +677,7 @@ function ShoppingList({ onNavigate, refreshTrigger = 0, isActive = false, initia
{selectedItemForDetail && ( {selectedItemForDetail && (
<ShoppingItemDetail <ShoppingItemDetail
itemId={selectedItemForDetail} itemId={selectedItemForDetail}
onClose={() => setSelectedItemForDetail(null)} onClose={handleCloseDetail}
onRefresh={handleRefresh} onRefresh={handleRefresh}
onItemCompleted={() => setToast({ message: 'Товар выполнен', type: 'success' })} onItemCompleted={() => setToast({ message: 'Товар выполнен', type: 'success' })}
onNavigate={onNavigate} onNavigate={onNavigate}