version 10

This commit is contained in:
Flatlogic Bot 2026-03-13 01:58:29 +00:00
parent 968b83badc
commit e87d7c53d1
5 changed files with 207 additions and 5 deletions

View File

@ -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() {
<Route path="/admin/*" element={<AdminRoute />}>
<Route element={<AdminLayout />}>
<Route path="products" element={<ProductManagement />} />
<Route path="categories" element={<div>Category Management (To be implemented)</div>} />
<Route path="sellers" element={<div>Seller Management (To be implemented)</div>} />
<Route path="products/create" element={<ProductForm />} />
<Route path="products/edit/:id" element={<ProductForm />} />
<Route path="categories" element={<CategoryManagement />} />
<Route path="sellers" element={<SellerManagement />} />
</Route>
</Route>
</Routes>
@ -43,4 +48,4 @@ function App() {
)
}
export default App;
export default App;

View File

@ -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<Category[]>([]);
const [loading, setLoading] = useState<boolean>(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 <div className="text-center p-4">Loading...</div>;
return (
<div className="p-4">
<h2 className="text-xl font-bold mb-4">Category Management</h2>
<table className="min-w-full bg-white border border-gray-200">
<thead>
<tr>
<th className="py-2 px-4 border-b">ID</th>
<th className="py-2 px-4 border-b">Name</th>
<th className="py-2 px-4 border-b">Slug</th>
<th className="py-2 px-4 border-b">Actions</th>
</tr>
</thead>
<tbody>
{categories.map(category => (
<tr key={category.id}>
<td className="py-2 px-4 border-b">{category.id}</td>
<td className="py-2 px-4 border-b">{category.name}</td>
<td className="py-2 px-4 border-b">{category.slug}</td>
<td className="py-2 px-4 border-b">
<button
onClick={() => deleteCategory(category.id)}
className="bg-red-500 text-white px-2 py-1 rounded"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default CategoryManagement;

View File

@ -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 (
<div className="p-4">
<h2 className="text-xl font-bold mb-4">{id ? 'Edit' : 'Create'} Product</h2>
<form onSubmit={handleSubmit} className="space-y-4">
<input className="block w-full p-2 border" placeholder="Name" value={formData.name} onChange={e => setFormData({...formData, name: e.target.value})} />
<input className="block w-full p-2 border" placeholder="Price" value={formData.price} onChange={e => setFormData({...formData, price: e.target.value})} />
<textarea className="block w-full p-2 border" placeholder="Description" value={formData.description} onChange={e => setFormData({...formData, description: e.target.value})} />
<select className="block w-full p-2 border" value={formData.category} onChange={e => setFormData({...formData, category: e.target.value})}>
<option value="">Select Category</option>
{categories.map(c => <option key={c.id} value={c.id}>{c.name}</option>)}
</select>
<button type="submit" className="bg-blue-500 text-white p-2 rounded">Save</button>
</form>
</div>
);
};
export default ProductForm;

View File

@ -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 (
<div className="p-4">
<h2 className="text-xl font-bold mb-4">Product Management</h2>
<div className="flex justify-between items-center mb-4">
<h2 className="text-xl font-bold">Product Management</h2>
<Link to="/admin/products/create" className="bg-green-500 text-white px-4 py-2 rounded">Create Product</Link>
</div>
<table className="min-w-full bg-white border border-gray-200">
<thead>
<tr>
@ -58,6 +62,7 @@ const ProductManagement: React.FC = () => {
<td className="py-2 px-4 border-b">{product.name}</td>
<td className="py-2 px-4 border-b">{product.price}</td>
<td className="py-2 px-4 border-b">
<Link to={`/admin/products/edit/${product.id}`} className="bg-blue-500 text-white px-2 py-1 rounded mr-2">Edit</Link>
<button
onClick={() => 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;

View File

@ -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<Seller[]>([]);
const [loading, setLoading] = useState<boolean>(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 <div className="text-center p-4">Loading...</div>;
return (
<div className="p-4">
<h2 className="text-xl font-bold mb-4">Seller Management</h2>
<table className="min-w-full bg-white border border-gray-200">
<thead>
<tr>
<th className="py-2 px-4 border-b">ID</th>
<th className="py-2 px-4 border-b">Store Name</th>
<th className="py-2 px-4 border-b">Verified</th>
<th className="py-2 px-4 border-b">Actions</th>
</tr>
</thead>
<tbody>
{sellers.map(seller => (
<tr key={seller.id}>
<td className="py-2 px-4 border-b">{seller.id}</td>
<td className="py-2 px-4 border-b">{seller.store_name}</td>
<td className="py-2 px-4 border-b">{seller.is_verified ? 'Yes' : 'No'}</td>
<td className="py-2 px-4 border-b">
<button
onClick={() => deleteSeller(seller.id)}
className="bg-red-500 text-white px-2 py-1 rounded"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default SellerManagement;