diff --git a/web/app/api/scrape/route.ts b/web/app/api/scrape/route.ts index 31d938b..ed7b8a3 100644 --- a/web/app/api/scrape/route.ts +++ b/web/app/api/scrape/route.ts @@ -5,23 +5,25 @@ const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000'; export async function POST(request: NextRequest) { try { const body = await request.json(); - const { url, business_name, business_address, rating_snapshot, total_reviews_snapshot } = body; + const { url, business_name, business_address, rating_snapshot, total_reviews_snapshot, scraper_version } = body; if (!url) { return NextResponse.json({ error: 'URL is required' }, { status: 400 }); } - // Call the containerized scraper API with business metadata + // Call the containerized scraper API with business metadata and version const response = await fetch(`${API_BASE_URL}/scrape`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url, + scraper_version, // Pass version to backend for routing metadata: { business_name, business_address, rating_snapshot, total_reviews_snapshot, + scraper_version, // Also store in metadata for job tracking }, }), }); diff --git a/web/app/new/page.tsx b/web/app/new/page.tsx index 62e0123..5bfaf3f 100644 --- a/web/app/new/page.tsx +++ b/web/app/new/page.tsx @@ -134,12 +134,12 @@ export default function NewScrapePage() { } catch (err) { console.error('Failed to fetch scrapers:', err); setError('Failed to load available scrapers'); - // Fallback to showing Google Reviews as available + // Fallback to showing Google Reviews as available with both versions setScrapers([{ job_type: 'google-reviews', ...SCRAPER_METADATA['google-reviews'], available: true, - versions: ['v1.0.0'], + versions: ['v1.1.0 (Multi-Sort)', 'v1.0.0'], }]); } finally { setLoading(false); diff --git a/web/components/ScraperTest.tsx b/web/components/ScraperTest.tsx index 2cf273a..4cc6a51 100644 --- a/web/components/ScraperTest.tsx +++ b/web/components/ScraperTest.tsx @@ -64,6 +64,13 @@ export default function ScraperTest({ onJobsChange, onSelectReviews }: ScraperTe const [businessImage, setBusinessImage] = useState(null); const [businessCategory, setBusinessCategory] = useState(null); + // Scraper version selection - v1.1.0 is default (multi-sort enabled) + const AVAILABLE_VERSIONS = [ + { value: '1.1.0', label: 'v1.1.0 (Multi-Sort)', description: 'Bypasses ~1000 review limit' }, + { value: '1.0.0', label: 'v1.0.0 (Standard)', description: 'Original scraper' }, + ]; + const [scraperVersion, setScraperVersion] = useState('1.1.0'); + const [userFingerprint, setUserFingerprint] = useState<{ geolocation?: {lat: number, lng: number}, userAgent?: string, @@ -471,6 +478,7 @@ export default function ScraperTest({ onJobsChange, onSelectReviews }: ScraperTe browser_fingerprint: userFingerprint, // Pass full fingerprint // Google Reviews scraper (this component is specific to Google Reviews) job_type: 'google-reviews', + scraper_version: scraperVersion, // Selected scraper version }), }); @@ -1304,6 +1312,30 @@ export default function ScraperTest({ onJobsChange, onSelectReviews }: ScraperTe

{businessAddress}

)} + + {/* Scraper Version Selector */} +
+ + +

+ {scraperVersion === '1.1.0' + ? '✨ Multi-sort enabled: Can collect more than 1000 reviews' + : 'Standard scraping (up to ~1000 reviews)'} +

+
+

The scraping job will run in the background. You can monitor progress below.