version7
This commit is contained in:
parent
81d9c6f6ac
commit
3a45bf3328
@ -2,19 +2,24 @@ import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
|
||||
import Header from './Header';
|
||||
import LoginPage from './LoginPage';
|
||||
import ProductList from './ProductList';
|
||||
import ProductDetail from './ProductDetail';
|
||||
import { CartProvider } from './CartContext';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<Router>
|
||||
<Header />
|
||||
<main>
|
||||
<Routes>
|
||||
<Route path="/" element={<ProductList />} />
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
</Routes>
|
||||
</main>
|
||||
<CartProvider>
|
||||
<Header />
|
||||
<main>
|
||||
<Routes>
|
||||
<Route path="/" element={<ProductList />} />
|
||||
<Route path="/product/:id" element={<ProductDetail />} />
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
</Routes>
|
||||
</main>
|
||||
</CartProvider>
|
||||
</Router>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
export default App;
|
||||
34
frontend/src/CartContext.tsx
Normal file
34
frontend/src/CartContext.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import React, { createContext, useContext, useState } from 'react';
|
||||
|
||||
interface CartItem {
|
||||
id: number;
|
||||
name: string;
|
||||
price: number;
|
||||
}
|
||||
|
||||
interface CartContextType {
|
||||
cart: CartItem[];
|
||||
addToCart: (product: CartItem) => void;
|
||||
}
|
||||
|
||||
const CartContext = createContext<CartContextType | undefined>(undefined);
|
||||
|
||||
export const CartProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
const [cart, setCart] = useState<CartItem[]>([]);
|
||||
|
||||
const addToCart = (product: CartItem) => {
|
||||
setCart((prev) => [...prev, product]);
|
||||
};
|
||||
|
||||
return (
|
||||
<CartContext.Provider value={{ cart, addToCart }}>
|
||||
{children}
|
||||
</CartContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useCart = () => {
|
||||
const context = useContext(CartContext);
|
||||
if (!context) throw new Error('useCart must be used within CartProvider');
|
||||
return context;
|
||||
};
|
||||
42
frontend/src/ProductDetail.tsx
Normal file
42
frontend/src/ProductDetail.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { useParams, Link } from 'react-router-dom';
|
||||
import axios from 'axios';
|
||||
import { useCart } from './CartContext';
|
||||
|
||||
interface Product {
|
||||
id: number;
|
||||
name: string;
|
||||
description: string;
|
||||
price: number;
|
||||
}
|
||||
|
||||
const ProductDetail: React.FC = () => {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const [product, setProduct] = useState<Product | null>(null);
|
||||
const { addToCart } = useCart();
|
||||
|
||||
useEffect(() => {
|
||||
axios.get(`http://127.0.0.1:8000/api/products/${id}/`)
|
||||
.then(res => setProduct(res.data))
|
||||
.catch(err => console.error(err));
|
||||
}, [id]);
|
||||
|
||||
if (!product) return <div>Loading...</div>;
|
||||
|
||||
return (
|
||||
<div className="container mx-auto p-4">
|
||||
<Link to="/" className="text-blue-500 mb-4 inline-block">← Back to Products</Link>
|
||||
<h1 className="text-3xl font-bold">{product.name}</h1>
|
||||
<p className="text-gray-700 mt-2">{product.description}</p>
|
||||
<p className="text-xl font-semibold mt-4">${product.price}</p>
|
||||
<button
|
||||
className="bg-green-600 text-white px-4 py-2 mt-4 rounded"
|
||||
onClick={() => addToCart({ id: product.id, name: product.name, price: product.price })}
|
||||
>
|
||||
Add to Cart
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProductDetail;
|
||||
Loading…
x
Reference in New Issue
Block a user