feat: add save sessionStorage to scroll and category on shop

This commit is contained in:
2026-06-24 21:33:39 +03:00
parent e4cefc6c41
commit 2f99653c2c
2 changed files with 35 additions and 8 deletions
+7 -2
View File
@@ -2,7 +2,7 @@ import { useState } from "react";
import Arrow from "../components/Arrow"; import Arrow from "../components/Arrow";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
export default function CardItem({ item, onAddToCart }) { export default function CardItem({ item, onAddToCart, onNavigate }) {
const navigate = useNavigate(); const navigate = useNavigate();
const isPiece = item.unit_type === "piece"; const isPiece = item.unit_type === "piece";
const step = isPiece ? 1 : 0.1; const step = isPiece ? 1 : 0.1;
@@ -20,11 +20,16 @@ export default function CardItem({ item, onAddToCart }) {
); );
}; };
const handleGoToItem = () => {
if (onNavigate) onNavigate();
navigate(`/items/${item.id}`);
};
return ( return (
<div className="flex flex-col text-white w-full"> <div className="flex flex-col text-white w-full">
<div <div
className="w-full rounded-md overflow-hidden bg-slate-800/60 flex h-[400px] md:h-[600px] flex-col items-center justify-center border border-slate-700/50 select-none cursor-pointer" className="w-full rounded-md overflow-hidden bg-slate-800/60 flex h-[400px] md:h-[600px] flex-col items-center justify-center border border-slate-700/50 select-none cursor-pointer"
onClick={() => navigate(`/items/${item.id}`)} onClick={handleGoToItem}
> >
<img <img
src={item.avatar_url} src={item.avatar_url}
+28 -6
View File
@@ -7,9 +7,10 @@ import CardItem from "../components/CardItem";
export default function Shop() { export default function Shop() {
const [items, setItems] = useState([]); const [items, setItems] = useState([]);
const [categories, setCategories] = useState([]); const [categories, setCategories] = useState([]);
const [activeCategory, setActiveCategory] = useState("все"); const [activeCategory, setActiveCategory] = useState(
() => sessionStorage.getItem("shopCategory") || "все",
);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
useEffect(() => { useEffect(() => {
Promise.all([api.getAllItems(), api.getAllCategories()]) Promise.all([api.getAllItems(), api.getAllCategories()])
.then(([itemsRes, categoriesRes]) => { .then(([itemsRes, categoriesRes]) => {
@@ -24,16 +25,32 @@ export default function Shop() {
}); });
}, []); }, []);
// восстановление скролла после загрузки товаров
useEffect(() => {
if (!loading && items.length > 0) {
const saved = sessionStorage.getItem("shopScroll");
if (saved) {
window.scrollTo(0, parseInt(saved));
sessionStorage.removeItem("shopScroll");
}
}
}, [loading, items]);
const filteredItems = useMemo(() => { const filteredItems = useMemo(() => {
return activeCategory === "все" return activeCategory === "все"
? items || [] ? items || []
: (items || []).filter((item) => { : (items || []).filter((item) => {
if (!item || !item.category) return false; if (!item || !item.category) return false;
return item.category.toLowerCase() === activeCategory.toLowerCase(); return item.category.toLowerCase() === activeCategory.toLowerCase();
}); });
}, [items, activeCategory]); }, [items, activeCategory]);
// сохранить позицию и категорию перед уходом на товар
const handleNavigateToItem = () => {
sessionStorage.setItem("shopScroll", window.scrollY);
sessionStorage.setItem("shopCategory", activeCategory);
};
const handleAddToCart = async (product, selectedWeight) => { const handleAddToCart = async (product, selectedWeight) => {
try { try {
await api.addToCart({ await api.addToCart({
@@ -48,11 +65,11 @@ export default function Shop() {
}; };
if (loading) { if (loading) {
return( return (
<PageLayout> <PageLayout>
<p className="text-white grow">Загрузка...</p> <p className="text-white grow">Загрузка...</p>
</PageLayout> </PageLayout>
) );
} }
return ( return (
@@ -68,7 +85,12 @@ export default function Shop() {
/> />
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6 mb-4"> <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-6 mb-4">
{filteredItems.map((item) => ( {filteredItems.map((item) => (
<CardItem key={item.id} item={item} onAddToCart={handleAddToCart} /> <CardItem
key={item.id}
item={item}
onAddToCart={handleAddToCart}
onNavigate={handleNavigateToItem}
/>
))} ))}
</div> </div>
</main> </main>