add status filters to customer, product, and seller management lists
This commit is contained in:
parent
107a2a1e82
commit
078f9ee484
3 changed files with 83 additions and 17 deletions
|
|
@ -6,6 +6,7 @@ import { useAuth } from '../../context/AuthContext';
|
|||
|
||||
const CustomerList = () => {
|
||||
const { token } = useAuth();
|
||||
const [filter, setFilter] = useState('all');
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [customers, setCustomers] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
|
@ -15,10 +16,13 @@ const CustomerList = () => {
|
|||
const fetchCustomers = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
// Include search query parameter if any
|
||||
const url = searchTerm
|
||||
? `${API_BASE_URL}/customers/?search=${encodeURIComponent(searchTerm)}`
|
||||
: `${API_BASE_URL}/customers/`;
|
||||
let url = `${API_BASE_URL}/customers/`;
|
||||
const params = [];
|
||||
if (searchTerm) params.push(`search=${encodeURIComponent(searchTerm)}`);
|
||||
if (filter !== 'all') params.push(`status=${filter}`);
|
||||
if (params.length > 0) {
|
||||
url += `?${params.join('&')}`;
|
||||
}
|
||||
|
||||
const res = await fetch(url, {
|
||||
headers: {
|
||||
|
|
@ -36,21 +40,34 @@ const CustomerList = () => {
|
|||
};
|
||||
|
||||
fetchCustomers();
|
||||
}, [searchTerm, token]);
|
||||
}, [searchTerm, filter, token]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1 className="page-title">Customer Management</h1>
|
||||
|
||||
<div className="glass-card">
|
||||
<div style={{ marginBottom: '20px' }}>
|
||||
<div style={{ display: 'flex', gap: '16px', marginBottom: '20px', flexWrap: 'wrap' }}>
|
||||
<input
|
||||
type="text"
|
||||
className="form-input"
|
||||
style={{ flex: 1, minWidth: '200px' }}
|
||||
placeholder="Search customers by name or email..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
/>
|
||||
<div style={{ display: 'flex', gap: '8px' }}>
|
||||
{['all', 'active', 'banned'].map((status) => (
|
||||
<button
|
||||
key={status}
|
||||
onClick={() => setFilter(status)}
|
||||
className={`btn ${filter === status ? 'btn-primary' : 'btn-secondary'}`}
|
||||
style={{ fontSize: '13px', padding: '8px 16px', textTransform: 'capitalize' }}
|
||||
>
|
||||
{status}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import { useAuth } from '../../context/AuthContext';
|
|||
const ProductList = () => {
|
||||
const { token } = useAuth();
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [productFilter, setProductFilter] = useState('all');
|
||||
const [sellerFilter, setSellerFilter] = useState('all');
|
||||
const [products, setProducts] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
|
|
@ -14,7 +16,15 @@ const ProductList = () => {
|
|||
const fetchProducts = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const res = await fetch(`${API_BASE_URL}/products/`, {
|
||||
let url = `${API_BASE_URL}/products/`;
|
||||
const params = [];
|
||||
if (productFilter !== 'all') params.push(`status=${productFilter}`);
|
||||
if (sellerFilter !== 'all') params.push(`seller_status=${sellerFilter}`);
|
||||
if (params.length > 0) {
|
||||
url += `?${params.join('&')}`;
|
||||
}
|
||||
|
||||
const res = await fetch(url, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
|
|
@ -31,7 +41,7 @@ const ProductList = () => {
|
|||
|
||||
useEffect(() => {
|
||||
fetchProducts();
|
||||
}, [token]);
|
||||
}, [productFilter, sellerFilter, token]);
|
||||
|
||||
const handleStatusChange = async (prodId, action) => {
|
||||
try {
|
||||
|
|
@ -78,14 +88,53 @@ const ProductList = () => {
|
|||
<h1 className="page-title">Product Review & Management</h1>
|
||||
|
||||
<div className="glass-card">
|
||||
<div style={{ marginBottom: '20px' }}>
|
||||
<input
|
||||
type="text"
|
||||
className="form-input"
|
||||
placeholder="Search products by title or seller name..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
/>
|
||||
{/* Search and Filters row */}
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', marginBottom: '20px' }}>
|
||||
<div>
|
||||
<input
|
||||
type="text"
|
||||
className="form-input"
|
||||
placeholder="Search products by title or seller name..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', gap: '20px', flexWrap: 'wrap', alignItems: 'center' }}>
|
||||
{/* Product Status Filter */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
<span style={{ fontSize: '13px', color: 'var(--text-secondary)', fontWeight: '500' }}>Product Status:</span>
|
||||
<div style={{ display: 'flex', gap: '6px' }}>
|
||||
{['all', 'pending', 'approved', 'hold', 'rejected'].map((status) => (
|
||||
<button
|
||||
key={status}
|
||||
onClick={() => setProductFilter(status)}
|
||||
className={`btn ${productFilter === status ? 'btn-primary' : 'btn-secondary'}`}
|
||||
style={{ fontSize: '12px', padding: '6px 12px', textTransform: 'capitalize' }}
|
||||
>
|
||||
{status}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Seller Status Filter */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
<span style={{ fontSize: '13px', color: 'var(--text-secondary)', fontWeight: '500' }}>Seller Status:</span>
|
||||
<div style={{ display: 'flex', gap: '6px' }}>
|
||||
{['all', 'unverified', 'pending_approval', 'approved', 'rejected', 'suspended'].map((status) => (
|
||||
<button
|
||||
key={status}
|
||||
onClick={() => setSellerFilter(status)}
|
||||
className={`btn ${sellerFilter === status ? 'btn-primary' : 'btn-secondary'}`}
|
||||
style={{ fontSize: '12px', padding: '6px 12px', textTransform: 'capitalize' }}
|
||||
>
|
||||
{status.replace('_', ' ')}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ const SellerList = () => {
|
|||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
/>
|
||||
<div style={{ display: 'flex', gap: '8px' }}>
|
||||
{['all', 'pending_approval', 'approved', 'suspended', 'banned'].map((status) => (
|
||||
{['all', 'unverified', 'pending_approval', 'approved', 'rejected', 'suspended'].map((status) => (
|
||||
<button
|
||||
key={status}
|
||||
onClick={() => setFilter(status)}
|
||||
|
|
|
|||
Loading…
Reference in a new issue