feat: add XLSX export functionality for Stalker products and enhance UI for export link

This commit is contained in:
Victor Noguera
2026-05-19 23:12:34 -04:00
parent 90bfee8791
commit 0c2e59771c
3 changed files with 174 additions and 23 deletions

View File

@@ -1153,32 +1153,39 @@ function StalkerProductsExplorer({
const [pageSize, setPageSize] = useState(50);
const [sort, setSort] = useState<SortState>({ field: "monthly_sold", direction: "DESC" });
function buildStalkerProductParams(includePaging: boolean): URLSearchParams {
const params = new URLSearchParams({
sort: buildSortValue(sort),
});
if (includePaging) {
params.set("page", String(page));
params.set("pageSize", String(pageSize));
}
if (search) params.set("q", search);
if (sellerId) params.set("sellerId", sellerId);
if (runId) params.set("runId", runId);
if (verdict) params.set("verdict", verdict);
if (amazonIsSeller) params.set("amazonIsSeller", amazonIsSeller);
if (minPrice) params.set("minPrice", minPrice);
if (maxPrice) params.set("maxPrice", maxPrice);
if (minMonthlySold) params.set("minMonthlySold", minMonthlySold);
if (maxMonthlySold) params.set("maxMonthlySold", maxMonthlySold);
if (minSalesRank) params.set("minSalesRank", minSalesRank);
if (maxSalesRank) params.set("maxSalesRank", maxSalesRank);
if (minSellerCount) params.set("minSellerCount", minSellerCount);
if (maxSellerCount) params.set("maxSellerCount", maxSellerCount);
if (minRatingCount) params.set("minRatingCount", minRatingCount);
if (maxRatingCount) params.set("maxRatingCount", maxRatingCount);
if (minConfidence) params.set("minConfidence", minConfidence);
if (maxConfidence) params.set("maxConfidence", maxConfidence);
return params;
}
useEffect(() => {
let cancelled = false;
async function load() {
setLoading(true);
const params = new URLSearchParams({
page: String(page),
pageSize: String(pageSize),
sort: buildSortValue(sort),
});
if (search) params.set("q", search);
if (sellerId) params.set("sellerId", sellerId);
if (runId) params.set("runId", runId);
if (verdict) params.set("verdict", verdict);
if (amazonIsSeller) params.set("amazonIsSeller", amazonIsSeller);
if (minPrice) params.set("minPrice", minPrice);
if (maxPrice) params.set("maxPrice", maxPrice);
if (minMonthlySold) params.set("minMonthlySold", minMonthlySold);
if (maxMonthlySold) params.set("maxMonthlySold", maxMonthlySold);
if (minSalesRank) params.set("minSalesRank", minSalesRank);
if (maxSalesRank) params.set("maxSalesRank", maxSalesRank);
if (minSellerCount) params.set("minSellerCount", minSellerCount);
if (maxSellerCount) params.set("maxSellerCount", maxSellerCount);
if (minRatingCount) params.set("minRatingCount", minRatingCount);
if (maxRatingCount) params.set("maxRatingCount", maxRatingCount);
if (minConfidence) params.set("minConfidence", minConfidence);
if (maxConfidence) params.set("maxConfidence", maxConfidence);
const params = buildStalkerProductParams(true);
const res = await fetch(`/api/stalker/products?${params.toString()}`);
const payload = (await res.json()) as StalkerProductsResponse;
@@ -1236,6 +1243,8 @@ function StalkerProductsExplorer({
setPage(1);
}
const exportHref = `/api/stalker/products/export.xlsx?${buildStalkerProductParams(false).toString()}`;
return (
<div className="page">
<button className="back" onClick={onBack}>Back</button>
@@ -1298,6 +1307,7 @@ function StalkerProductsExplorer({
<option value="100">100 / page</option>
</select>
<button onClick={resetFilters}>Reset filters</button>
<a className="button-link" href={exportHref}>Export XLSX</a>
</div>
</div>