- Move Create Task modal from JobQueue to TasksDashboard - Add pagination to TasksDashboard (25 tasks per page) - Add delete action for failed/completed/pending tasks - Remove JobQueue page and route - Rename nav item from "Task Queue" to "Tasks" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
136 lines
9.2 KiB
TypeScript
Executable File
136 lines
9.2 KiB
TypeScript
Executable File
// CannaIQ v1.8.0 - Emerald Theme
|
|
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
|
|
import { Home } from './pages/Home';
|
|
import { Login } from './pages/Login';
|
|
import { Dashboard } from './pages/Dashboard';
|
|
import { Products } from './pages/Products';
|
|
import { ProductDetail } from './pages/ProductDetail';
|
|
import { Stores } from './pages/Stores';
|
|
import { Dispensaries } from './pages/Dispensaries';
|
|
import { DispensaryDetail } from './pages/DispensaryDetail';
|
|
import { DispensarySchedule } from './pages/DispensarySchedule';
|
|
import { StoreDetail } from './pages/StoreDetail';
|
|
import { StoreBrands } from './pages/StoreBrands';
|
|
import { StoreSpecials } from './pages/StoreSpecials';
|
|
import { Categories } from './pages/Categories';
|
|
import { Campaigns } from './pages/Campaigns';
|
|
import { Analytics } from './pages/Analytics';
|
|
import { ClickAnalytics } from './pages/ClickAnalytics';
|
|
import { Specials } from './pages/Specials';
|
|
import { PriceCompare } from './pages/PriceCompare';
|
|
import { Settings } from './pages/Settings';
|
|
import { Proxies } from './pages/Proxies';
|
|
import { Logs } from './pages/Logs';
|
|
import { ScraperMonitor } from './pages/ScraperMonitor';
|
|
import { ScraperSchedule } from './pages/ScraperSchedule';
|
|
import { ScraperTools } from './pages/ScraperTools';
|
|
import { ChangeApproval } from './pages/ChangeApproval';
|
|
import { ApiPermissions } from './pages/ApiPermissions';
|
|
import { AISettings } from './pages/AISettings';
|
|
import { CrawlSchedulePage } from './pages/CrawlSchedulePage';
|
|
import { StoresListPage } from './pages/StoresListPage';
|
|
import { StoreDetailPage } from './pages/StoreDetailPage';
|
|
import { WholesaleAnalytics } from './pages/WholesaleAnalytics';
|
|
import { Users } from './pages/Users';
|
|
import { OrchestratorDashboard } from './pages/OrchestratorDashboard';
|
|
import { OrchestratorProducts } from './pages/OrchestratorProducts';
|
|
import { OrchestratorBrands } from './pages/OrchestratorBrands';
|
|
import { OrchestratorStores } from './pages/OrchestratorStores';
|
|
import { ChainsDashboard } from './pages/ChainsDashboard';
|
|
import { IntelligenceBrands } from './pages/IntelligenceBrands';
|
|
import { IntelligencePricing } from './pages/IntelligencePricing';
|
|
import { IntelligenceStores } from './pages/IntelligenceStores';
|
|
import { SyncInfoPanel } from './pages/SyncInfoPanel';
|
|
import NationalDashboard from './pages/NationalDashboard';
|
|
import StateHeatmap from './pages/StateHeatmap';
|
|
import CrossStateCompare from './pages/CrossStateCompare';
|
|
import StateDetail from './pages/StateDetail';
|
|
import { Discovery } from './pages/Discovery';
|
|
import { WorkersDashboard } from './pages/WorkersDashboard';
|
|
import TasksDashboard from './pages/TasksDashboard';
|
|
import { ScraperOverviewDashboard } from './pages/ScraperOverviewDashboard';
|
|
import { SeoOrchestrator } from './pages/admin/seo/SeoOrchestrator';
|
|
import { StatePage } from './pages/public/StatePage';
|
|
import { SeoPage } from './pages/public/SeoPage';
|
|
import { PrivateRoute } from './components/PrivateRoute';
|
|
|
|
export default function App() {
|
|
return (
|
|
<BrowserRouter>
|
|
<Routes>
|
|
<Route path="/" element={<Home />} />
|
|
<Route path="/login" element={<Login />} />
|
|
<Route path="/dashboard" element={<PrivateRoute><Dashboard /></PrivateRoute>} />
|
|
<Route path="/products" element={<PrivateRoute><Products /></PrivateRoute>} />
|
|
<Route path="/products/:id" element={<PrivateRoute><ProductDetail /></PrivateRoute>} />
|
|
<Route path="/stores" element={<PrivateRoute><Stores /></PrivateRoute>} />
|
|
<Route path="/dispensaries" element={<PrivateRoute><Dispensaries /></PrivateRoute>} />
|
|
<Route path="/dispensaries/:state/:city/:slug" element={<PrivateRoute><DispensaryDetail /></PrivateRoute>} />
|
|
<Route path="/dispensaries/:state/:city/:slug/schedule" element={<PrivateRoute><DispensarySchedule /></PrivateRoute>} />
|
|
<Route path="/stores/:state/:storeName/:slug/brands" element={<PrivateRoute><StoreBrands /></PrivateRoute>} />
|
|
<Route path="/stores/:state/:storeName/:slug/specials" element={<PrivateRoute><StoreSpecials /></PrivateRoute>} />
|
|
<Route path="/stores/:state/:storeName/:slug" element={<PrivateRoute><StoreDetail /></PrivateRoute>} />
|
|
<Route path="/categories" element={<PrivateRoute><Categories /></PrivateRoute>} />
|
|
<Route path="/campaigns" element={<PrivateRoute><Campaigns /></PrivateRoute>} />
|
|
<Route path="/analytics" element={<PrivateRoute><Analytics /></PrivateRoute>} />
|
|
<Route path="/analytics/clicks" element={<PrivateRoute><ClickAnalytics /></PrivateRoute>} />
|
|
<Route path="/analytics/specials" element={<PrivateRoute><Specials /></PrivateRoute>} />
|
|
<Route path="/analytics/compare" element={<PrivateRoute><PriceCompare /></PrivateRoute>} />
|
|
<Route path="/settings" element={<PrivateRoute><Settings /></PrivateRoute>} />
|
|
<Route path="/changes" element={<PrivateRoute><ChangeApproval /></PrivateRoute>} />
|
|
<Route path="/proxies" element={<PrivateRoute><Proxies /></PrivateRoute>} />
|
|
<Route path="/logs" element={<PrivateRoute><Logs /></PrivateRoute>} />
|
|
<Route path="/scraper-tools" element={<PrivateRoute><ScraperTools /></PrivateRoute>} />
|
|
<Route path="/scraper-monitor" element={<PrivateRoute><ScraperMonitor /></PrivateRoute>} />
|
|
<Route path="/scraper-schedule" element={<PrivateRoute><ScraperSchedule /></PrivateRoute>} />
|
|
{/* Provider-agnostic routes */}
|
|
<Route path="/schedule" element={<PrivateRoute><CrawlSchedulePage /></PrivateRoute>} />
|
|
<Route path="/stores/list" element={<PrivateRoute><StoresListPage /></PrivateRoute>} />
|
|
<Route path="/stores/list/:id" element={<PrivateRoute><StoreDetailPage /></PrivateRoute>} />
|
|
<Route path="/monitor" element={<PrivateRoute><WorkersDashboard /></PrivateRoute>} />
|
|
{/* Legacy AZ routes - redirect to new paths */}
|
|
<Route path="/az-schedule" element={<Navigate to="/schedule" replace />} />
|
|
<Route path="/az" element={<Navigate to="/stores/list" replace />} />
|
|
<Route path="/az/stores/:id" element={<PrivateRoute><StoreDetailPage /></PrivateRoute>} />
|
|
<Route path="/api-permissions" element={<PrivateRoute><ApiPermissions /></PrivateRoute>} />
|
|
<Route path="/ai-settings" element={<PrivateRoute><AISettings /></PrivateRoute>} />
|
|
<Route path="/wholesale-analytics" element={<PrivateRoute><WholesaleAnalytics /></PrivateRoute>} />
|
|
<Route path="/users" element={<PrivateRoute><Users /></PrivateRoute>} />
|
|
{/* National / Multi-State routes */}
|
|
<Route path="/national" element={<PrivateRoute><NationalDashboard /></PrivateRoute>} />
|
|
<Route path="/national/heatmap" element={<PrivateRoute><StateHeatmap /></PrivateRoute>} />
|
|
<Route path="/national/compare" element={<PrivateRoute><CrossStateCompare /></PrivateRoute>} />
|
|
<Route path="/national/state/:stateCode" element={<PrivateRoute><StateDetail /></PrivateRoute>} />
|
|
{/* Admin routes */}
|
|
<Route path="/admin" element={<Navigate to="/admin/orchestrator" replace />} />
|
|
<Route path="/admin/orchestrator" element={<PrivateRoute><OrchestratorDashboard /></PrivateRoute>} />
|
|
<Route path="/admin/orchestrator/products" element={<PrivateRoute><OrchestratorProducts /></PrivateRoute>} />
|
|
<Route path="/admin/orchestrator/brands" element={<PrivateRoute><OrchestratorBrands /></PrivateRoute>} />
|
|
<Route path="/admin/orchestrator/stores" element={<PrivateRoute><OrchestratorStores /></PrivateRoute>} />
|
|
<Route path="/admin/orchestrator/chains" element={<PrivateRoute><ChainsDashboard /></PrivateRoute>} />
|
|
{/* Intelligence routes */}
|
|
<Route path="/admin/intelligence" element={<Navigate to="/admin/intelligence/brands" replace />} />
|
|
<Route path="/admin/intelligence/brands" element={<PrivateRoute><IntelligenceBrands /></PrivateRoute>} />
|
|
<Route path="/admin/intelligence/pricing" element={<PrivateRoute><IntelligencePricing /></PrivateRoute>} />
|
|
<Route path="/admin/intelligence/stores" element={<PrivateRoute><IntelligenceStores /></PrivateRoute>} />
|
|
<Route path="/admin/intelligence/sync" element={<PrivateRoute><SyncInfoPanel /></PrivateRoute>} />
|
|
{/* SEO Orchestrator */}
|
|
<Route path="/admin/seo" element={<PrivateRoute><SeoOrchestrator /></PrivateRoute>} />
|
|
{/* Public SEO pages (no auth) - all use SeoPage renderer for generated content */}
|
|
<Route path="/states/:slug" element={<SeoPage />} />
|
|
<Route path="/alternatives/:slug" element={<SeoPage />} />
|
|
<Route path="/brands/:slug" element={<SeoPage />} />
|
|
{/* Discovery routes */}
|
|
<Route path="/discovery" element={<PrivateRoute><Discovery /></PrivateRoute>} />
|
|
{/* Workers Dashboard */}
|
|
<Route path="/workers" element={<PrivateRoute><WorkersDashboard /></PrivateRoute>} />
|
|
{/* Task Queue Dashboard */}
|
|
<Route path="/tasks" element={<PrivateRoute><TasksDashboard /></PrivateRoute>} />
|
|
{/* Scraper Overview Dashboard (new primary) */}
|
|
<Route path="/scraper/overview" element={<PrivateRoute><ScraperOverviewDashboard /></PrivateRoute>} />
|
|
<Route path="*" element={<Navigate to="/dashboard" replace />} />
|
|
</Routes>
|
|
</BrowserRouter>
|
|
);
|
|
}
|