diff --git a/frontend/src/pages/MarketView.tsx b/frontend/src/pages/MarketView.tsx index ca37187..a2485d9 100644 --- a/frontend/src/pages/MarketView.tsx +++ b/frontend/src/pages/MarketView.tsx @@ -1,4 +1,4 @@ -import React, { useState, useMemo, useCallback } from 'react' +import React, { useState, useMemo, useCallback, useEffect } from 'react' import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' import api from '../api' @@ -922,18 +922,42 @@ const RateMatrixTab: React.FC = () => { const [showDirect, setShowDirect] = useState(false) const queryClient = useQueryClient() + // The scrape endpoint returns immediately (runs in background), so we watch + // scraper status until a new batch finishes, then refetch the matrix. + const [scrapeWatch, setScrapeWatch] = useState<{ prevBatch: string | null, startedAt: number } | null>(null) + const dateScrapeM = useMutation({ mutationFn: async (d: string) => { + const st = (await api.get('/competitors/status')).data as ScraperStatus setScrapingDate(d) + setScrapeWatch({ prevBatch: st?.last_scrape?.batch_id ?? null, startedAt: Date.now() }) return (await api.post('/competitors/scrape', { from_date: d, to_date: d })).data }, - onSuccess: () => { + onError: () => { + setScrapingDate(null) + setScrapeWatch(null) + }, + }) + + const { data: watchStatus } = useQuery({ + queryKey: ['scraper-status'], + queryFn: async () => (await api.get('/competitors/status')).data, + enabled: scrapeWatch !== null, + refetchInterval: scrapeWatch !== null ? 5000 : false, + }) + + useEffect(() => { + if (!scrapeWatch) return + const ls = watchStatus?.last_scrape + const finished = ls && ls.batch_id !== scrapeWatch.prevBatch && ls.status !== 'running' + const timedOut = Date.now() - scrapeWatch.startedAt > 10 * 60 * 1000 + if (finished || timedOut) { queryClient.invalidateQueries({ queryKey: ['competitor-matrix'] }) queryClient.invalidateQueries({ queryKey: ['scraper-status'] }) setScrapingDate(null) - }, - onError: () => setScrapingDate(null), - }) + setScrapeWatch(null) + } + }, [watchStatus, scrapeWatch, queryClient]) const onCellEnter = useCallback((row: number, col: number) => { setHoveredCell({ row, col }) @@ -1229,7 +1253,7 @@ const RateMatrixTab: React.FC = () => { priceIndexBadge = ( - {idx} + {idx}% ) }