6.4.2: Закрытие диалогов кнопкой назад (товары)
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m19s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m19s
This commit is contained in:
@@ -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",
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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,11 +375,25 @@ 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 = () => {
|
||||||
|
if (historyPushedForPostponeRef.current) {
|
||||||
|
window.history.back()
|
||||||
|
} else {
|
||||||
|
historyPushedForPostponeRef.current = false
|
||||||
setSelectedItemForPostpone(null)
|
setSelectedItemForPostpone(null)
|
||||||
setPostponeDate('')
|
setPostponeDate('')
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleDateSelect = (date) => {
|
const handleDateSelect = (date) => {
|
||||||
if (date) {
|
if (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}
|
||||||
|
|||||||
Reference in New Issue
Block a user