diff --git a/src/food-market.web/src/pages/SupplyEditPage.tsx b/src/food-market.web/src/pages/SupplyEditPage.tsx index 191fc16..caba533 100644 --- a/src/food-market.web/src/pages/SupplyEditPage.tsx +++ b/src/food-market.web/src/pages/SupplyEditPage.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, type FormEvent, type ReactNode } from 'react' +import { useState, useEffect, useRef, type FormEvent, type ReactNode } from 'react' import { useNavigate, useParams, Link } from 'react-router-dom' import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query' import { ArrowLeft, Plus, Trash2, Save, CheckCircle } from 'lucide-react' @@ -65,6 +65,16 @@ export function SupplyEditPage() { const [form, setForm] = useState
(emptyForm) const [pickerOpen, setPickerOpen] = useState(false) const [error, setError] = useState(null) + // Скролл-контейнер тела документа: после каждого добавления строки + // автоскроллим к низу, чтобы новая строка и input оказались в зоне видимости. + const scrollBodyRef = useRef(null) + const scrollToBottom = () => { + const el = scrollBodyRef.current + if (!el) return + requestAnimationFrame(() => { + el.scrollTo({ top: el.scrollHeight, behavior: 'smooth' }) + }) + } const existing = useQuery({ queryKey: ['/api/purchases/supplies', id], @@ -211,6 +221,7 @@ export function SupplyEditPage() { ...form, lines: form.lines.map((l, ix) => ix === idx ? { ...l, quantity: l.quantity + 1 } : l), }) + scrollToBottom() return true } const defaultRetail = p.prices?.[0]?.amount ?? null @@ -228,6 +239,7 @@ export function SupplyEditPage() { retailPriceOverride: null, }], }) + scrollToBottom() return false } const updateLine = (i: number, patch: Partial) => @@ -273,7 +285,7 @@ export function SupplyEditPage() { {/* Scrollable body */} -
+
{error && (
{error}
@@ -448,23 +460,25 @@ export function SupplyEditPage() { )} - - {!isPosted && ( - // Sticky-bottom вне Section (overflow-hidden родителя ломает sticky): - // пользователь может подряд сканировать партию штрихкодов — после - // каждого скана строка добавляется в таблицу выше, а input остаётся - // прибит к низу скроллируемого тела документа и принимает следующий ввод. -
- -
- )}
+ {/* Quick-add bar — flex-sibling формы, всегда у нижнего края viewport. + * Не sticky внутри scroll-body, чтобы overflow родителей и высота + * содержимого не влияли на видимость. После каждого добавления + * строки тело документа автоскроллится к низу. */} + {!isPosted && ( +
+
+ +
+
+ )} + setPickerOpen(false)} onPick={addLineFromProduct} /> )