add status filters to customer, product, and seller management lists
All checks were successful
Beta CI/CD Pipeline / build-and-test (push) Successful in 14s
Beta CI/CD Pipeline / deploy-beta (push) Successful in 6s

This commit is contained in:
vickytechkey 2026-08-16 15:19:03 +05:30
parent 107a2a1e82
commit 078f9ee484
3 changed files with 83 additions and 17 deletions

View file

@ -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 ? (

View file

@ -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 ? (

View file

@ -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)}