Код: Выделить всё
export default function Article() {
console.log("component is rendered");
const { user } = useAuth();
const navigate = useNavigate();
const {id} = useParams();
// article data coming from previous route
const location = useLocation()
const { article } = location.state || {};
// cart
const { addToCart , articleLoadingState , setArticleLoadingState } = useCart();
const [sales, setSales] = useState(0);
const [Article,setArticle] = useState(article);
console.log(article)
useEffect(() => {
const fetchArticleData = async () => {
console.log("fetch article data");
if (!article) {
try {
const docRef = doc(db, "Articles", id);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
console.log(docSnap.data());
setArticle(docSnap.data());
}
} catch (err) {}
} else {
setArticle(article);
}
};
fetchArticleData(); // Call the async function
}, [article,id]);
Код: Выделить всё
console.log(article)Код: Выделить всё
Article.jsx:49 Uncaught TypeError: Cannot read properties of undefined (reading 'colors')
at Article (Article.jsx:49:76)
Код: Выделить всё
const [selectedColor, setSelectedColor] = useState(Object.keys(Article.colors)[0],);
Код: Выделить всё
function App() {
return (
{/* Protected Routes */}
);
}
export default App;
Код: Выделить всё
import React, { useState, useEffect } from "react";
import { MdAddShoppingCart } from "react-icons/md";
import { Button , Spinner } from "@nextui-org/react";
import { fireIcon } from "../../assets/images";
import { useNavigate , useLocation , useParams} from "react-router-dom";
import { useCart } from "../../context/CartContext";
import { useAuth } from "../../context/AuthManager";
import { doc, getDoc } from "firebase/firestore";
export default function Article() {
console.log("component is rendered");
const { user } = useAuth();
const navigate = useNavigate();
const {id} = useParams();
// article data coming from previous route
const location = useLocation()
const { article } = location.state || {};
// cart
const { addToCart , articleLoadingState , setArticleLoadingState } = useCart();
const [sales, setSales] = useState(0);
const [Article,setArticle] = useState(article);
console.log(article)
useEffect(() => {
const fetchArticleData = async () => {
console.log("fetch article data");
if (!article) {
try {
console.log("fetch article data");
const docRef = doc(db, "Articles", id);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
console.log(docSnap.data());
setArticle(docSnap.data());
}
} catch (err) {}
} else {
setArticle(article);
}
};
fetchArticleData(); // Call the async function
}, [article,id]);
// article data
const [selectedColor, setSelectedColor] = useState(Object.keys(Article.colors)[0],);// currently selected color
const [selectedImage, setSelectedImage] = useState(0); // Track the active image index
const [imageCounter, setImageCounter] = useState(1); // Track the current image number (1-indexed)
const [isTransitioning, setIsTransitioning] = useState(true); // To control the sliding effect
const [selectedSize, setSelectedSize] = useState(Article.sizes[0]); // Default to the first size
const [amount, setAmount] = useState(1);
// destructing the article data
const { colors, images } = Article;
const articleData = {
articleNo: Article.id,
originalPrice: Article.price,
discount: Article.discount,
available: Article.available,
images,
category: Article.collection,
vendor: Article.vendor,
sizes: Article.sizes,
colors,
};
// fn for adding component to cart
const handleAddToCart = async () => {
setArticleLoadingState(true);
const cartItem = {
id: Article.id,
originalPrice: Article.price,
discount: Article.discount,
available: Article.available,
images: images[selectedColor],
category: Article.collection,
vendor: Article.vendor,
size: selectedSize,
color: selectedColor,
quantity: amount,
};
try {
await addToCart(cartItem); // Add item to the cart
} catch (error) {
} finally {
setArticleLoadingState(false);
}
};
const discountedPrice =
articleData.originalPrice * (1 - articleData.discount / 100);
const handleColorChange = (color) => {
setSelectedColor(color);
setSelectedImage(0); // Reset selected image when changing color
setImageCounter(1); // Reset counter when changing color
setIsTransitioning(false); // Temporarily stop the sliding effect
};
const handleImageSelect = (index) => {
setSelectedImage(index); // Update the active image
setImageCounter(index + 1); // Update the counter (1-indexed)
};
// Set up the automatic image change every 5 seconds
useEffect(() => {
const interval = setInterval(() => {
setSelectedImage((prevIndex) => {
let nextIndex = prevIndex + 1;
// If the next index exceeds the number of images, reset to 0
if (nextIndex >= articleData.images[selectedColor].length) {
nextIndex = 0;
setIsTransitioning(false); // Stop the sliding effect temporarily
setTimeout(() => {
setIsTransitioning(true); // Re-enable the sliding effect after a brief pause
}, 0); // Wait for a short period before re-enabling the transition
}
setImageCounter(nextIndex + 1); // Update counter (1-indexed)
return nextIndex;
});
}, 5000); // Change every 5 seconds
return () => clearInterval(interval); // Clean up the interval when the component unmounts
}, [selectedColor, articleData.images]);
useEffect(() => {
// Set initial sales value to a random number between 10 and 15
const initialSales = Math.floor(Math.random() * (15 - 10 + 1)) + 10;
setSales(initialSales);
// Set up interval to increment sales by 1, 2, or 3 every 2 minutes
const interval = setInterval(
() => {
const increment = Math.floor(Math.random() * 3) + 1; // Random value between 1 and 3
setSales((prevSales) => prevSales + increment);
},
5 * 60 * 1000,
); // 2 minutes in milliseconds
return () => clearInterval(interval); // Clean up the interval on component unmount
}, []);
return (
{/* Main Image with Sliding Effect */}
{articleData.images[selectedColor].map(
(image, index) => (
[img]{image}
className="w-full"
/>
),
)}
{articleData.images[selectedColor].map(
(image, index) => (
handleImageSelect(index)} // Update the active image on click
>
[img]{image}
className="w-11/12"
/>
),
)}
FOOTPULSE
{articleData.articleNo}
{articleData.discount > 0 && (
-{articleData.discount}%
)}
[img]{fireIcon} alt=[/img]
{sales} sold in last 12 hours
Rs.{discountedPrice.toFixed(2)}
{articleData.discount > 0 && (
Rs.{articleData.originalPrice}
)}
Available :{" "}
{articleData.available
? "In Stock"
: "Out of Stock"}
Vendor :{" "}
{articleData.vendor}
Type :{" "}
{articleData.category}
Sizes:
{articleData.sizes.map((size, index) => (
setSelectedSize(size)} // Update the selected size
>
{size}
))}
Colors:
{Object.keys(articleData.colors).map((color, index) => (
handleColorChange(color)}
>
))}
setAmount((prev) => Math.max(prev - 1, 1))
}
>
-
{amount}
setAmount((prev) => prev + 1)}
>
+
{articleLoadingState ? (
) : (
Add to Cart
)}
{
handleAddToCart()
if (user) {
addToCart();
navigate("/checkout")
} else {
navigate("/login")
}
}}
>
Buy Now
);
}
http://localhost:5173/products/casual/AP34524
скажите мне, если вам нужно что-нибудь еще
Подробнее здесь: https://stackoverflow.com/questions/793 ... g-executed