feat: add save sessionStorage to scroll and category on shop
This commit is contained in:
@@ -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}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user