Maintenance Love :)
This commit is contained in:
parent
18ee395568
commit
4fc41f2eeb
@ -198,3 +198,60 @@ export const fetchGridSearchExport = async (jobId: string, format: 'md' | 'json'
|
||||
if (!res.ok) throw new Error(`Failed to load report: ${res.statusText}`);
|
||||
return await res.text();
|
||||
};
|
||||
|
||||
// --- Places GridSearch API Methods (New C++ backend) ---
|
||||
|
||||
export const fetchPlacesGridSearches = async (): Promise<GridSearchSummary[]> => {
|
||||
const headers = await getAuthHeaders();
|
||||
const res = await fetch(`${serverUrl}/api/places/gridsearch`, { headers });
|
||||
if (!res.ok) throw new Error(`Failed to fetch places grid searches: ${res.statusText}`);
|
||||
const json = await res.json();
|
||||
return json.data || [];
|
||||
};
|
||||
|
||||
export const fetchPlacesGridSearchById = async (id: string): Promise<any> => {
|
||||
const cacheKey = `places-gridsearch-id-${id}`;
|
||||
return fetchWithDeduplication(cacheKey, async () => {
|
||||
const headers = await getAuthHeaders();
|
||||
const res = await fetch(`${serverUrl}/api/places/gridsearch/${id}`, { headers });
|
||||
if (!res.ok) throw new Error(`Failed to fetch places grid search result: ${res.statusText}`);
|
||||
const json = await res.json();
|
||||
return json.data;
|
||||
}, 60000 * 5);
|
||||
};
|
||||
|
||||
export const fetchPlacesGridSearchRunState = async (id: string): Promise<RestoredRunState> => {
|
||||
const headers = await getAuthHeaders();
|
||||
const res = await fetch(`${serverUrl}/api/places/gridsearch/${id}/state`, { headers });
|
||||
if (!res.ok) throw new Error(`Failed to fetch run state: ${res.statusText}`);
|
||||
const json = await res.json();
|
||||
return json.data;
|
||||
};
|
||||
|
||||
export const submitPlacesGridSearchJob = async (payload: GridSearchJobPayload): Promise<{ message: string; jobId: string }> => {
|
||||
const headers = await getAuthHeaders();
|
||||
const res = await fetch(`${serverUrl}/api/places/gridsearch`, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: JSON.stringify(payload)
|
||||
});
|
||||
if (!res.ok) throw new Error(`Failed to submit places grid search job: ${res.statusText}`);
|
||||
return await res.json();
|
||||
};
|
||||
|
||||
export const deletePlacesGridSearch = async (id: string): Promise<boolean> => {
|
||||
// We will just call the old locations route for deletion to keep it simple,
|
||||
// since both manipulate the exact same Postgres table (grid_search_runs).
|
||||
return deleteGridSearch(id);
|
||||
};
|
||||
|
||||
export const getPlacesGridSearchStreamUrl = (jobId: string, token?: string): string => {
|
||||
// If not implemented in places, fallback to locations or just use the same URL format
|
||||
const url = `${serverUrl}/api/places/gridsearch/${jobId}/stream`;
|
||||
return token ? `${url}?token=${token}` : url;
|
||||
};
|
||||
|
||||
export const fetchPlacesGridSearchExport = async (jobId: string, format: 'md' | 'json' = 'md'): Promise<string> => {
|
||||
// If not implemented in places, fallback to locations export since they share the database
|
||||
return fetchGridSearchExport(jobId, format);
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Loader2, AlertCircle, Download } from 'lucide-react';
|
||||
import MarkdownRenderer from '@/components/MarkdownRenderer';
|
||||
import { fetchGridSearchExport } from '../client-gridsearch';
|
||||
import { fetchPlacesGridSearchExport } from '../client-gridsearch';
|
||||
|
||||
export function CompetitorsReportView({ jobId }: { jobId: string }) {
|
||||
const [markdown, setMarkdown] = useState<string | null>(null);
|
||||
@ -17,7 +17,7 @@ export function CompetitorsReportView({ jobId }: { jobId: string }) {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const text = await fetchGridSearchExport(jobId, 'md');
|
||||
const text = await fetchPlacesGridSearchExport(jobId, 'md');
|
||||
|
||||
if (active) {
|
||||
setMarkdown(text);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { Loader2, Search, MapPin, CheckCircle, ChevronRight, ChevronLeft } from 'lucide-react';
|
||||
import { previewGridSearch, submitGridSearchJob, addActiveGridSearchJob } from '../client-gridsearch';
|
||||
import { previewGridSearch, submitPlacesGridSearchJob, addActiveGridSearchJob } from '../client-gridsearch';
|
||||
import { searchGadmRegions } from '../client-searches';
|
||||
import { CompetitorsGridView } from '../CompetitorsGridView';
|
||||
|
||||
@ -96,7 +96,7 @@ export function GridSearchWizard({ onJobSubmitted }: { onJobSubmitted: (jobId: s
|
||||
setSubmitting(true);
|
||||
setError('');
|
||||
try {
|
||||
const res = await submitGridSearchJob({
|
||||
const res = await submitPlacesGridSearchJob({
|
||||
region: selectedRegionName,
|
||||
types: [searchQuery],
|
||||
level,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Loader2, AlertCircle, Plus, Lock, MapPin } from 'lucide-react';
|
||||
import { fetchGridSearchById } from '../client-gridsearch';
|
||||
import { fetchPlacesGridSearchById } from '../client-gridsearch';
|
||||
import { GridSearchResults } from './GridSearchResults';
|
||||
import { useSearchParams, useNavigate } from 'react-router-dom';
|
||||
import { useRestoredSearch } from './RestoredSearchContext';
|
||||
@ -28,7 +28,7 @@ export function JobViewer({ jobId }: { jobId: string }) {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
const data = await fetchGridSearchById(jobId);
|
||||
const data = await fetchPlacesGridSearchById(jobId);
|
||||
console.log(`job results`, data);
|
||||
|
||||
if (!active) return;
|
||||
@ -92,6 +92,12 @@ export function JobViewer({ jobId }: { jobId: string }) {
|
||||
|
||||
const allResults = jobData?.result?.searchResult?.results || competitors;
|
||||
const foundTypes = Array.from(new Set(allResults.flatMap((r: any) => r.types || []).filter(Boolean))).sort() as string[];
|
||||
console.log(`foundTypes`, foundTypes);
|
||||
console.log(`allResults`, allResults);
|
||||
console.log(`jobData`, jobData);
|
||||
console.log('guidedAreas', guidedAreas);
|
||||
console.log('searchSettings', searchSettings);
|
||||
console.log('searchQuery', searchQuery);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col p-6 flex-1 w-full box-border overflow-hidden min-h-0">
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { getActiveGridSearchJobs, removeActiveGridSearchJob, getGridSearchStreamUrl, fetchGridSearches, deleteGridSearch, GridSearchSummary } from '../client-gridsearch';
|
||||
import { getActiveGridSearchJobs, removeActiveGridSearchJob, getPlacesGridSearchStreamUrl, fetchPlacesGridSearches, deletePlacesGridSearch, GridSearchSummary } from '../client-gridsearch';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { Loader2, XCircle, CheckCircle, Search, ChevronRight, Trash2 } from 'lucide-react';
|
||||
|
||||
@ -19,7 +19,7 @@ const ActiveJobItem = ({ jobId, onSelectJob }: { jobId: string, onSelectJob?: (j
|
||||
|
||||
if (!isSubscribed) return;
|
||||
|
||||
const url = getGridSearchStreamUrl(jobId, token);
|
||||
const url = getPlacesGridSearchStreamUrl(jobId, token);
|
||||
es = new EventSource(url);
|
||||
|
||||
es.addEventListener('progress', (e) => {
|
||||
@ -117,7 +117,7 @@ export const OngoingSearches = ({ onSelectJob, selectedJobId, onSearchDeleted }:
|
||||
|
||||
const loadPast = async () => {
|
||||
try {
|
||||
const history = await fetchGridSearches();
|
||||
const history = await fetchPlacesGridSearches();
|
||||
setPastSearches(history);
|
||||
} catch (err) {
|
||||
console.error('Failed to load past searches', err);
|
||||
@ -190,7 +190,7 @@ export const OngoingSearches = ({ onSelectJob, selectedJobId, onSearchDeleted }:
|
||||
e.stopPropagation();
|
||||
if (confirm('Are you sure you want to delete this search?')) {
|
||||
try {
|
||||
await deleteGridSearch(search.id);
|
||||
await deletePlacesGridSearch(search.id);
|
||||
setPastSearches(prev => prev.filter(s => s.id !== search.id));
|
||||
if (onSearchDeleted) onSearchDeleted(search.id);
|
||||
} catch (err) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
|
||||
import { fetchGridSearchRunState, RestoredRunState } from '../client-gridsearch';
|
||||
import { fetchPlacesGridSearchRunState, RestoredRunState } from '../client-gridsearch';
|
||||
|
||||
interface RestoredSearchContextValue {
|
||||
/** The loaded run state, null until fetched */
|
||||
@ -42,7 +42,7 @@ export function RestoredSearchProvider({
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
try {
|
||||
const data = await fetchGridSearchRunState(id);
|
||||
const data = await fetchPlacesGridSearchRunState(id);
|
||||
setState(data);
|
||||
} catch (err: any) {
|
||||
setError(err.message || 'Failed to load run state');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user