From fc0d45e909b45d1155b9a4b0666bde3ed03e4559 Mon Sep 17 00:00:00 2001 From: AmirReza Jamali Date: Sat, 4 Jul 2026 12:51:28 +0330 Subject: [PATCH] Migrate TED dashboard chart to summary API --- cypress/e2e/dashboard/dashboard.cy.ts | 23 ++++++++++++------- .../dashboard/use-dashboard-data.ts | 5 +++- .../_components/dashboard/use-statistics.ts | 20 +++++++++++----- src/hooks/queries/useDashboardQueries.ts | 1 + src/lib/api/services/dashboard-service.ts | 1 + src/lib/api/types/Dashboard.ts | 4 +++- 6 files changed, 38 insertions(+), 16 deletions(-) diff --git a/cypress/e2e/dashboard/dashboard.cy.ts b/cypress/e2e/dashboard/dashboard.cy.ts index 8a63567..4c477c8 100644 --- a/cypress/e2e/dashboard/dashboard.cy.ts +++ b/cypress/e2e/dashboard/dashboard.cy.ts @@ -27,7 +27,9 @@ const stubDashboardRequests = () => { const now = Math.floor(Date.now() / 1000); cy.intercept("GET", "**/api/proxy/dashboard/summary**", (req) => { - expect(req.query.closing_window).to.be.undefined; + const days = Number(req.query.days); + expect(req.query.closing_window).to.eq("168"); + req.alias = days === 30 ? "summary30Days" : "summary14Days"; req.reply({ statusCode: 200, body: apiResponse({ @@ -39,10 +41,15 @@ const stubDashboardRequests = () => { closing_soon: 12, total_estimated_value: 2500000, value_currency: "EUR", + days, + scraped_ted: [ + { date: "2026-06-08", count: days === 30 ? 12 : 5 }, + { date: "2026-06-09", count: days === 30 ? 18 : 8 }, + ], generated_at: now, }), }); - }).as("dashboardSummary"); + }); cy.intercept("GET", "**/api/proxy/dashboard/trend**", (req) => { expect(req.query).to.include({ days: "14", metric: "created" }); @@ -139,10 +146,6 @@ const stubDashboardRequests = () => { days, generated_at: now, daily: { - scraped_ted: [ - { date: "2026-06-08", count: days === 30 ? 12 : 5 }, - { date: "2026-06-09", count: days === 30 ? 18 : 8 }, - ], scraped_documents: [ { date: "2026-06-08", count: days === 30 ? 40 : 20 }, { date: "2026-06-09", count: days === 30 ? 60 : 30 }, @@ -155,6 +158,7 @@ const stubDashboardRequests = () => { totals: { scraped_documents: days === 30 ? 9876 : 4321, translated_tenders: days === 30 ? 654 : 321, + scraped_ted_notices: days === 30 ? 2468 : 1234, }, }), }); @@ -171,7 +175,7 @@ describe("tender dashboard", () => { visitDashboard(); cy.wait([ - "@dashboardSummary", + "@summary14Days", "@dashboardTrend", "@dashboardCountries", "@dashboardNoticeTypes", @@ -213,10 +217,13 @@ describe("tender dashboard", () => { it("reloads scraping and translation statistics for a selected range", () => { visitDashboard(); - cy.wait("@statistics14Days"); + cy.wait(["@summary14Days", "@statistics14Days"]); cy.contains("button", "14d").should("have.class", "bg-primary"); cy.contains("button", "30d").click(); + cy.wait("@summary30Days") + .its("request.query.days") + .should("eq", "30"); cy.wait("@statistics30Days") .its("request.query.days") .should("eq", "30"); diff --git a/src/app/(home)/_components/dashboard/use-dashboard-data.ts b/src/app/(home)/_components/dashboard/use-dashboard-data.ts index 1e93eea..d0d596e 100644 --- a/src/app/(home)/_components/dashboard/use-dashboard-data.ts +++ b/src/app/(home)/_components/dashboard/use-dashboard-data.ts @@ -15,7 +15,10 @@ import { toLabeledPoints } from "./to-labeled-points"; export type DashboardMetrics = ReturnType; export function useDashboardData() { - const summaryQuery = useDashboardSummaryQuery(); + const summaryQuery = useDashboardSummaryQuery({ + closing_window: 168, + days: 14, + }); const trendQuery = useDashboardTrendQuery({ days: 14, metric: "created" }); const countriesQuery = useDashboardCountriesQuery({ limit: 6 }); const noticeTypesQuery = useDashboardNoticeTypesQuery(); diff --git a/src/app/(home)/_components/dashboard/use-statistics.ts b/src/app/(home)/_components/dashboard/use-statistics.ts index a861b82..88536d8 100644 --- a/src/app/(home)/_components/dashboard/use-statistics.ts +++ b/src/app/(home)/_components/dashboard/use-statistics.ts @@ -1,6 +1,9 @@ "use client"; -import { useDashboardStatisticsQuery } from "@/hooks/queries"; +import { + useDashboardStatisticsQuery, + useDashboardSummaryQuery, +} from "@/hooks/queries"; import { useMemo, useState } from "react"; import { toLabeledPoints } from "./to-labeled-points"; @@ -11,14 +14,16 @@ export type StatisticsDays = (typeof STATISTICS_DAY_OPTIONS)[number]; export function useStatistics() { const [days, setDays] = useState(14); + const summaryQuery = useDashboardSummaryQuery({ closing_window: 168, days }); const query = useDashboardStatisticsQuery({ days }); + const summary = summaryQuery.data?.data; const stats = query.data?.data; const daily = stats?.daily; const scrapedTed = useMemo( - () => toLabeledPoints(daily?.scraped_ted ?? []), - [daily], + () => toLabeledPoints(summary?.scraped_ted ?? []), + [summary], ); const scrapedDocuments = useMemo( () => toLabeledPoints(daily?.scraped_documents ?? []), @@ -32,9 +37,12 @@ export function useStatistics() { return { days, setDays, - isLoading: query.isPending, - isError: query.isError, - refetch: query.refetch, + isLoading: query.isPending || summaryQuery.isPending, + isError: query.isError || summaryQuery.isError, + refetch: () => { + summaryQuery.refetch(); + query.refetch(); + }, scrapedTed, scrapedDocuments, translatedNotices, diff --git a/src/hooks/queries/useDashboardQueries.ts b/src/hooks/queries/useDashboardQueries.ts index a3319f8..8e00e2c 100644 --- a/src/hooks/queries/useDashboardQueries.ts +++ b/src/hooks/queries/useDashboardQueries.ts @@ -4,6 +4,7 @@ import { useMemo } from "react"; export const useDashboardSummaryQuery = (params?: { closing_window?: number; + days?: number; }) => { const queryKey = useMemo( () => [API_ENDPOINTS.DASHBOARD.SUMMARY, params], diff --git a/src/lib/api/services/dashboard-service.ts b/src/lib/api/services/dashboard-service.ts index 01597c7..d0e24d8 100644 --- a/src/lib/api/services/dashboard-service.ts +++ b/src/lib/api/services/dashboard-service.ts @@ -13,6 +13,7 @@ import { export const dashboardService = { summary: async (params?: { closing_window?: number; + days?: number; }): Promise> => { try { return (await api.get(API_ENDPOINTS.DASHBOARD.SUMMARY, { params })).data; diff --git a/src/lib/api/types/Dashboard.ts b/src/lib/api/types/Dashboard.ts index 7e3e3a7..00c0598 100644 --- a/src/lib/api/types/Dashboard.ts +++ b/src/lib/api/types/Dashboard.ts @@ -7,6 +7,8 @@ export type TDashboardSummary = { closing_soon: number; total_estimated_value: number; value_currency: string; + days: number; + scraped_ted: TDashboardTrendPoint[]; generated_at: number; }; @@ -22,7 +24,6 @@ export type TDashboardTrend = { }; export type TDashboardStatisticsDaily = { - scraped_ted: TDashboardTrendPoint[]; scraped_documents: TDashboardTrendPoint[]; translated_notices: TDashboardTrendPoint[]; }; @@ -30,6 +31,7 @@ export type TDashboardStatisticsDaily = { export type TDashboardStatisticsTotals = { scraped_documents: number; translated_tenders: number; + scraped_ted_notices: number; }; export type TDashboardStatistics = {