98 lines
2.8 KiB
TypeScript
98 lines
2.8 KiB
TypeScript
// app/products/page.tsx
|
|
'use client';
|
|
|
|
import { useState } from 'react';
|
|
|
|
export default function ProductsPage() {
|
|
const [category, setCategory] = useState('');
|
|
const [sort, setSort] = useState('price');
|
|
const [limit, setLimit] = useState('10');
|
|
const [products, setProducts] = useState<any[]>([]);
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const fetchProducts = async () => {
|
|
setLoading(true);
|
|
try {
|
|
// Construct URL with query parameters
|
|
const url = new URL('https://api.example.com/products');
|
|
if (category) url.searchParams.append('category', category);
|
|
if (sort) url.searchParams.append('sort', sort);
|
|
if (limit) url.searchParams.append('limit', limit);
|
|
|
|
const response = await fetch(url.toString());
|
|
const data = await response.json();
|
|
setProducts(data.products);
|
|
} catch (error) {
|
|
console.error('Error fetching products:', error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="p-4">
|
|
<h1 className="text-2xl font-bold mb-4">Product Search</h1>
|
|
|
|
<div className="flex gap-4 mb-6">
|
|
<div>
|
|
<label className="block mb-1">Category</label>
|
|
<input
|
|
type="text"
|
|
value={category}
|
|
onChange={(e) => setCategory(e.target.value)}
|
|
className="border p-2 rounded"
|
|
placeholder="electronics, clothing, etc."
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block mb-1">Sort By</label>
|
|
<select
|
|
value={sort}
|
|
onChange={(e) => setSort(e.target.value)}
|
|
className="border p-2 rounded"
|
|
>
|
|
<option value="price">Price</option>
|
|
<option value="name">Name</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block mb-1">Items Per Page</label>
|
|
<input
|
|
type="number"
|
|
value={limit}
|
|
onChange={(e) => setLimit(e.target.value)}
|
|
className="border p-2 rounded"
|
|
min="1"
|
|
max="100"
|
|
/>
|
|
</div>
|
|
|
|
<button
|
|
onClick={fetchProducts}
|
|
disabled={loading}
|
|
className="bg-blue-500 text-white px-4 py-2 rounded self-end"
|
|
>
|
|
{loading ? 'Loading...' : 'Search'}
|
|
</button>
|
|
</div>
|
|
|
|
{products.length > 0 && (
|
|
<div>
|
|
<h2 className="text-xl font-semibold mb-2">Results</h2>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
{products.map((product) => (
|
|
<div key={product.id} className="border p-4 rounded">
|
|
<h3 className="font-medium">{product.name}</h3>
|
|
<p>Category: {product.category}</p>
|
|
<p>Price: ${product.price}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|