import React, { useState, useEffect, useCallback } from 'react'; import { useSource, useAppState, useAction } from './sdk'; import { Badge, Metric, Glass, Icon } from './components'; import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend, BarChart, Bar, Cell } from 'recharts'; import { TrendingUp, DollarSign, Users, AlertTriangle, CheckCircle, RefreshCw, Settings, Bell, Clock, History, BarChart3, Search, Shield, Zap, AlertCircle } from 'lucide-react'; // Mock data for competitors const MOCK_COMPETITORS = [ { id: 'comp-1', name: 'Competitor A', url: 'https://competitor-a.com/pricing', status: 'connected', lastScrape: '2026-04-10T18:30:00Z', health: 'healthy', plans: [ { name: 'Starter', price: 29, cycle: 'month', features: ['5 users', '10GB storage', 'Email support'] }, { name: 'Professional', price: 79, cycle: 'month', features: ['25 users', '100GB storage', 'Priority support'] }, { name: 'Enterprise', price: 199, cycle: 'month', features: ['Unlimited users', '1TB storage', '24/7 support'] } ] }, { id: 'comp-2', name: 'Competitor B', url: 'https://competitor-b.com/pricing', status: 'connected', lastScrape: '2026-04-10T17:45:00Z', health: 'healthy', plans: [ { name: 'Basic', price: 25, cycle: 'month', features: ['3 users', '5GB storage', 'Community support'] }, { name: 'Pro', price: 69, cycle: 'month', features: ['20 users', '50GB storage', 'Email support'] }, { name: 'Business', price: 149, cycle: 'month', features: ['Unlimited users', '500GB storage', 'Phone support'] } ] }, { id: 'comp-3', name: 'Competitor C', url: 'https://competitor-c.com/pricing', status: 'connected', lastScrape: '2026-04-10T19:00:00Z', health: 'warning', plans: [ { name: 'Starter', price: 35, cycle: 'month', features: ['10 users', '20GB storage', 'Email support'] }, { name: 'Growth', price: 89, cycle: 'month', features: ['50 users', '200GB storage', 'Priority support'] }, { name: 'Scale', price: 249, cycle: 'month', features: ['Unlimited users', '2TB storage', 'Dedicated support'] } ] } ]; const MOCK_CHANGES = [ { id: 1, competitor: 'Competitor A', type: 'price_change', description: 'Professional plan increased from $69 to $79', change: '+14.5%', timestamp: '2026-04-10T18:30:00Z', severity: 'medium' }, { id: 2, competitor: 'Competitor B', type: 'new_plan', description: 'Added new "Team" plan at $99/month', change: 'new', timestamp: '2026-04-09T14:20:00Z', severity: 'high' }, { id: 3, competitor: 'Competitor C', type: 'feature_change', description: 'Starter plan now includes 10 users (was 5)', change: 'feature', timestamp: '2026-04-08T10:15:00Z', severity: 'low' }, { id: 4, competitor: 'Competitor A', type: 'price_change', description: 'Enterprise plan decreased from $249 to $199', change: '-20%', timestamp: '2026-04-07T16:45:00Z', severity: 'high' }, { id: 5, competitor: 'Competitor B', type: 'discount', description: 'Annual billing now offers 20% discount (was 15%)', change: 'discount', timestamp: '2026-04-06T09:30:00Z', severity: 'medium' } ]; const MOCK_PRICE_HISTORY = [ { date: '2026-04-01', compA: 69, compB: 65, compC: 85 }, { date: '2026-04-03', compA: 69, compB: 65, compC: 85 }, { date: '2026-04-05', compA: 79, compB: 65, compC: 85 }, { date: '2026-04-07', compA: 79, compB: 69, compC: 89 }, { date: '2026-04-09', compA: 79, compB: 69, compC: 89 }, { date: '2026-04-10', compA: 79, compB: 69, compC: 89 } ]; const COLORS = { violet: '#8b5cf6', cyan: '#06b6d4', emerald: '#10b981', amber: '#f59e0b', red: '#ef4444', slate: '#64748b' }; export default function App() { const [activeTab, setActiveTab] = useState<'overview' | 'pricing' | 'changes' | 'settings'>('overview'); const [selectedCompetitor, setSelectedCompetitor] = useState(null); const [isScraping, setIsScraping] = useState(false); const [alertConfig, setAlertConfig] = useAppState('alertConfig', { emailEnabled: true, emailThreshold: 5, notifyOnPriceChange: true, notifyOnNewPlan: true, notifyOnFeatureChange: false }); const [showSettings, setShowSettings] = useState(false); const dispatch = useAction(); // Simulate scraping status const [scrapeStatus, setScrapeStatus] = useState({ lastRun: '2026-04-10T19:00:00Z', nextRun: '2026-04-11T01:00:00Z', status: 'healthy', totalScrapes: 142, successRate: 98.5 }); const handleManualScrape = useCallback(async () => { setIsScraping(true); // Simulate scrape operation setTimeout(() => { setIsScraping(false); dispatch('toast', { message: 'Scrape completed successfully', type: 'success' }); setScrapeStatus(prev => ({ ...prev, lastRun: new Date().toISOString(), totalScrapes: prev.totalScrapes + 1 })); }, 2000); }, [dispatch]); const handleSaveSettings = useCallback(() => { dispatch('toast', { message: 'Alert settings saved', type: 'success' }); setShowSettings(false); }, [dispatch]); const formatDate = (isoString: string) => { const date = new Date(isoString); return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }); }; const getSeverityColor = (severity: string) => { switch (severity) { case 'high': return 'negative'; case 'medium': return 'neutral'; case 'low': return 'positive'; default: return 'neutral'; } }; const renderOverview = () => (
{/* Status Banner */}

Monitoring Active

All {MOCK_COMPETITORS.length} competitors being tracked successfully

{/* Metrics Row */}
{/* Price History Chart */}

Price History Trend

{/* Recent Changes */}

Recent Changes

{MOCK_CHANGES.slice(0, 3).map((change) => (

{change.description}

{change.competitor} {formatDate(change.timestamp)}
{change.change}
))}
); const renderPricing = () => (
{MOCK_COMPETITORS.map((competitor) => (
setSelectedCompetitor(competitor)}>

{competitor.name}

{competitor.plans.map((plan, idx) => (
{plan.name} ${plan.price}

/{plan.cycle}

{plan.features.slice(0, 2).map((feature, fIdx) => ( {feature} ))} {plan.features.length > 2 && ( +{plan.features.length - 2} more )}
))}
Last: {formatDate(competitor.lastScrape)} e.stopPropagation()} > Visit site
))}
{/* Comparison Table */}

Price Comparison

{MOCK_COMPETITORS.map((c) => ( ))} {['Starter', 'Basic', 'Professional', 'Pro', 'Growth', 'Enterprise', 'Business', 'Scale'].map((planName, idx) => { const prices = MOCK_COMPETITORS.map(c => { const plan = c.plans.find(p => p.name.toLowerCase().includes(planName.toLowerCase())); return plan ? plan.price : null; }); if (prices.every(p => p === null)) return null; return ( {prices.map((price, cIdx) => ( ))} ); })}
Plan{c.name}
{planName} {price !== null ? ( ${price} ) : ( )}
); const renderChanges = () => (

Change History

{MOCK_CHANGES.map((change) => (
{change.type === 'price_change' ? : change.type === 'new_plan' ? : }
{change.competitor}

{change.description}

{formatDate(change.timestamp)} {change.change}
))}
); const renderSettings = () => (

Alert Configuration

Email Notifications

Receive email alerts for significant changes

Notification Triggers

{[ { key: 'notifyOnPriceChange', label: 'Price changes', desc: 'Any price increase or decrease' }, { key: 'notifyOnNewPlan', label: 'New plans', desc: 'When competitors add new pricing tiers' }, { key: 'notifyOnFeatureChange', label: 'Feature changes', desc: 'Updates to plan features or limits' } ].map((item) => (

{item.label}

{item.desc}

))}

Sensitivity Threshold

setAlertConfig({ ...alertConfig, emailThreshold: parseInt(e.target.value) })} className="flex-1 h-2 bg-slate-700 rounded-lg appearance-none cursor-pointer" /> {alertConfig.emailThreshold}%

Only alert on price changes greater than {alertConfig.emailThreshold}%

Scraping Schedule

Scrape Interval

How often to check competitor pricing pages

Next Scheduled Run

{formatDate(scrapeStatus.nextRun)}

); return (
{/* Header */}

Competitive Intelligence Monitor

Track competitor pricing changes in real-time

{/* Tabs */}
{[ { id: 'overview', label: 'Overview', icon: BarChart3 }, { id: 'pricing', label: 'Pricing', icon: DollarSign }, { id: 'changes', label: 'Changes', icon: History }, { id: 'settings', label: 'Settings', icon: Settings } ].map((tab) => ( ))}
{/* Content */} {activeTab === 'overview' && renderOverview()} {activeTab === 'pricing' && renderPricing()} {activeTab === 'changes' && renderChanges()} {activeTab === 'settings' && renderSettings()} {/* Competitor Detail Modal */} {selectedCompetitor && (
setSelectedCompetitor(null)} >
e.stopPropagation()} >

{selectedCompetitor.name}

Pricing Plans

{selectedCompetitor.plans.map((plan, idx) => (
{plan.name} ${plan.price}

Billed {plan.cycle}

    {plan.features.map((feature, fIdx) => (
  • {feature}
  • ))}
))}

Monitoring Status

Last scraped: {formatDate(selectedCompetitor.lastScrape)}
)}
); } // Helper component for external link icon function Globe({ className }: { className?: string }) { return ; }