diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 941eb68..1757990 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -7,6 +7,9 @@ import CartPage from './CartPage'; import AdminLayout from './AdminLayout'; import AdminRoute from './AdminRoute'; import ProductManagement from './ProductManagement'; +import ProductForm from './ProductForm'; +import SellerManagement from './SellerManagement'; +import CategoryManagement from './CategoryManagement'; import { CartProvider } from './CartContext'; import { AuthProvider } from './AuthContext'; @@ -32,8 +35,10 @@ function App() { }> }> } /> - Category Management (To be implemented)} /> - Seller Management (To be implemented)} /> + } /> + } /> + } /> + } /> @@ -43,4 +48,4 @@ function App() { ) } -export default App; +export default App; \ No newline at end of file diff --git a/frontend/src/CategoryManagement.tsx b/frontend/src/CategoryManagement.tsx new file mode 100644 index 0000000..bdccb88 --- /dev/null +++ b/frontend/src/CategoryManagement.tsx @@ -0,0 +1,74 @@ +import React, { useEffect, useState } from 'react'; +import axios from 'axios'; + +interface Category { + id: number; + name: string; + slug: string; +} + +const CategoryManagement: React.FC = () => { + const [categories, setCategories] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + fetchCategories(); + }, []); + + const fetchCategories = () => { + axios.get('http://127.0.0.1:8000/categories/') + .then(response => { + setCategories(response.data); + setLoading(false); + }) + .catch(error => { + console.error('Error fetching categories:', error); + setLoading(false); + }); + }; + + const deleteCategory = (id: number) => { + if (window.confirm('Are you sure you want to delete this category?')) { + axios.delete(`http://127.0.0.1:8000/categories/${id}/`) + .then(() => fetchCategories()) + .catch(error => console.error('Error deleting category:', error)); + } + }; + + if (loading) return Loading...; + + return ( + + Category Management + + + + ID + Name + Slug + Actions + + + + {categories.map(category => ( + + {category.id} + {category.name} + {category.slug} + + deleteCategory(category.id)} + className="bg-red-500 text-white px-2 py-1 rounded" + > + Delete + + + + ))} + + + + ); +}; + +export default CategoryManagement; diff --git a/frontend/src/ProductForm.tsx b/frontend/src/ProductForm.tsx new file mode 100644 index 0000000..d62bef0 --- /dev/null +++ b/frontend/src/ProductForm.tsx @@ -0,0 +1,44 @@ +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; +import { useNavigate, useParams } from 'react-router-dom'; + +const ProductForm: React.FC = () => { + const { id } = useParams<{ id: string }>(); + const navigate = useNavigate(); + const [formData, setFormData] = useState({ name: '', price: '', description: '', category: '' }); + const [categories, setCategories] = useState<{ id: number; name: string }[]>([]); + + useEffect(() => { + axios.get('http://127.0.0.1:8000/categories/') + .then(res => setCategories(res.data)); + + if (id) { + axios.get(`http://127.0.0.1:8000/products/${id}/`) + .then(res => setFormData(res.data)); + } + }, [id]); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + const action = id ? axios.put(`http://127.0.0.1:8000/products/${id}/`, formData) : axios.post('http://127.0.0.1:8000/products/', formData); + action.then(() => navigate('/admin/products')); + }; + + return ( + + {id ? 'Edit' : 'Create'} Product + + setFormData({...formData, name: e.target.value})} /> + setFormData({...formData, price: e.target.value})} /> + setFormData({...formData, description: e.target.value})} /> + setFormData({...formData, category: e.target.value})}> + Select Category + {categories.map(c => {c.name})} + + Save + + + ); +}; + +export default ProductForm; diff --git a/frontend/src/ProductManagement.tsx b/frontend/src/ProductManagement.tsx index 54a2983..83a215b 100644 --- a/frontend/src/ProductManagement.tsx +++ b/frontend/src/ProductManagement.tsx @@ -1,5 +1,6 @@ import React, { useEffect, useState } from 'react'; import axios from 'axios'; +import { Link } from 'react-router-dom'; interface Product { id: number; @@ -41,7 +42,10 @@ const ProductManagement: React.FC = () => { return ( - Product Management + + Product Management + Create Product + @@ -58,6 +62,7 @@ const ProductManagement: React.FC = () => { {product.name} {product.price} + Edit deleteProduct(product.id)} className="bg-red-500 text-white px-2 py-1 rounded" @@ -73,4 +78,4 @@ const ProductManagement: React.FC = () => { ); }; -export default ProductManagement; +export default ProductManagement; \ No newline at end of file diff --git a/frontend/src/SellerManagement.tsx b/frontend/src/SellerManagement.tsx new file mode 100644 index 0000000..a631157 --- /dev/null +++ b/frontend/src/SellerManagement.tsx @@ -0,0 +1,74 @@ +import React, { useEffect, useState } from 'react'; +import axios from 'axios'; + +interface Seller { + id: number; + store_name: string; + is_verified: boolean; +} + +const SellerManagement: React.FC = () => { + const [sellers, setSellers] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + fetchSellers(); + }, []); + + const fetchSellers = () => { + axios.get('http://127.0.0.1:8000/sellers/') + .then(response => { + setSellers(response.data); + setLoading(false); + }) + .catch(error => { + console.error('Error fetching sellers:', error); + setLoading(false); + }); + }; + + const deleteSeller = (id: number) => { + if (window.confirm('Are you sure you want to delete this seller?')) { + axios.delete(`http://127.0.0.1:8000/sellers/${id}/`) + .then(() => fetchSellers()) + .catch(error => console.error('Error deleting seller:', error)); + } + }; + + if (loading) return Loading...; + + return ( + + Seller Management + + + + ID + Store Name + Verified + Actions + + + + {sellers.map(seller => ( + + {seller.id} + {seller.store_name} + {seller.is_verified ? 'Yes' : 'No'} + + deleteSeller(seller.id)} + className="bg-red-500 text-white px-2 py-1 rounded" + > + Delete + + + + ))} + + + + ); +}; + +export default SellerManagement;