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

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

View File

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

View File

@@ -124,6 +124,12 @@ function ShoppingList({ onNavigate, refreshTrigger = 0, isActive = false, initia
const initialFetchDoneRef = useRef(false)
const prevIsActiveRef = useRef(isActive)
// Refs для закрытия диалогов кнопкой "Назад"
const historyPushedForDetailRef = useRef(false)
const historyPushedForPostponeRef = useRef(false)
const selectedItemForDetailRef = useRef(selectedItemForDetail)
const selectedItemForPostponeRef = useRef(selectedItemForPostpone)
const setSelectedBoardId = (boardId) => {
setSelectedBoardIdState(boardId)
try {
@@ -250,6 +256,56 @@ function ShoppingList({ onNavigate, refreshTrigger = 0, isActive = false, initia
}
}, [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 now = new Date()
@@ -319,10 +375,24 @@ function ShoppingList({ onNavigate, refreshTrigger = 0, isActive = false, initia
if (selectedBoardId) fetchItems(selectedBoardId)
}
const handleCloseDetail = () => {
if (historyPushedForDetailRef.current) {
window.history.back()
} else {
historyPushedForDetailRef.current = false
setSelectedItemForDetail(null)
}
}
// Модалка переноса
const handlePostponeClose = () => {
setSelectedItemForPostpone(null)
setPostponeDate('')
if (historyPushedForPostponeRef.current) {
window.history.back()
} else {
historyPushedForPostponeRef.current = false
setSelectedItemForPostpone(null)
setPostponeDate('')
}
}
const handleDateSelect = (date) => {
@@ -607,7 +677,7 @@ function ShoppingList({ onNavigate, refreshTrigger = 0, isActive = false, initia
{selectedItemForDetail && (
<ShoppingItemDetail
itemId={selectedItemForDetail}
onClose={() => setSelectedItemForDetail(null)}
onClose={handleCloseDetail}
onRefresh={handleRefresh}
onItemCompleted={() => setToast({ message: 'Товар выполнен', type: 'success' })}
onNavigate={onNavigate}