feat(frontend): rewire dashboard to use AZ data endpoint
Main dashboard now uses /api/az/dashboard for dispensary, product, and brand counts instead of the legacy /api/dashboard/stats endpoint. This ensures the dashboard displays consistent data with the /az pages. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -6,8 +6,7 @@ import {
|
||||
Package,
|
||||
Target,
|
||||
Image as ImageIcon,
|
||||
MousePointer,
|
||||
Shield,
|
||||
Tag,
|
||||
TrendingUp,
|
||||
TrendingDown,
|
||||
RefreshCw,
|
||||
@@ -62,12 +61,42 @@ export function Dashboard() {
|
||||
|
||||
const loadData = async () => {
|
||||
try {
|
||||
const [statsData, activityData] = await Promise.all([
|
||||
api.getDashboardStats(),
|
||||
api.getDashboardActivity()
|
||||
]);
|
||||
setStats(statsData);
|
||||
// Fetch AZ dashboard data (primary data source)
|
||||
const azDashboard = await api.getDutchieAZDashboard();
|
||||
|
||||
// Map AZ dashboard data to the expected stats format
|
||||
setStats({
|
||||
products: {
|
||||
total: azDashboard.productCount,
|
||||
in_stock: azDashboard.productCount, // All AZ products are in stock by default
|
||||
with_images: 0 // Not tracked in AZ pipeline
|
||||
},
|
||||
stores: {
|
||||
total: azDashboard.dispensaryCount,
|
||||
active: azDashboard.dispensaryCount // All are active in AZ
|
||||
},
|
||||
brands: {
|
||||
total: azDashboard.brandCount
|
||||
},
|
||||
campaigns: {
|
||||
active: 0,
|
||||
total: 0
|
||||
},
|
||||
clicks: {
|
||||
clicks_24h: azDashboard.snapshotCount24h // Use snapshots as activity metric
|
||||
},
|
||||
failedJobs: azDashboard.failedJobCount,
|
||||
lastCrawlTime: azDashboard.lastCrawlTime
|
||||
});
|
||||
|
||||
// Try to fetch activity data (may fail if not authenticated)
|
||||
try {
|
||||
const activityData = await api.getDashboardActivity();
|
||||
setActivity(activityData);
|
||||
} catch {
|
||||
// Activity data requires auth, just skip it
|
||||
setActivity(null);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load dashboard:', error);
|
||||
} finally {
|
||||
@@ -196,9 +225,9 @@ export function Dashboard() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p className="text-sm font-medium text-gray-600">Active Stores</p>
|
||||
<p className="text-3xl font-semibold text-gray-900">{stats?.stores?.active || 0}</p>
|
||||
<p className="text-xs text-gray-500">{stats?.stores?.total || 0} total stores</p>
|
||||
<p className="text-sm font-medium text-gray-600">Total Dispensaries</p>
|
||||
<p className="text-3xl font-semibold text-gray-900">{stats?.stores?.total || 0}</p>
|
||||
<p className="text-xs text-gray-500">{stats?.stores?.active || 0} active (crawlable)</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -242,33 +271,33 @@ export function Dashboard() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Clicks */}
|
||||
{/* Snapshots (24h) */}
|
||||
<div className="bg-white rounded-xl border border-gray-200 p-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="p-2 bg-cyan-50 rounded-lg">
|
||||
<MousePointer className="w-5 h-5 text-cyan-600" />
|
||||
<Activity className="w-5 h-5 text-cyan-600" />
|
||||
</div>
|
||||
<Clock className="w-4 h-4 text-gray-400" />
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p className="text-sm font-medium text-gray-600">Clicks (24h)</p>
|
||||
<p className="text-sm font-medium text-gray-600">Snapshots (24h)</p>
|
||||
<p className="text-3xl font-semibold text-gray-900">{stats?.clicks?.clicks_24h?.toLocaleString() || 0}</p>
|
||||
<p className="text-xs text-gray-500">Last 24 hours</p>
|
||||
<p className="text-xs text-gray-500">Product snapshots created</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Proxies */}
|
||||
{/* Brands */}
|
||||
<div className="bg-white rounded-xl border border-gray-200 p-6">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="p-2 bg-indigo-50 rounded-lg">
|
||||
<Shield className="w-5 h-5 text-indigo-600" />
|
||||
<Tag className="w-5 h-5 text-indigo-600" />
|
||||
</div>
|
||||
<Activity className="w-4 h-4 text-gray-400" />
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<p className="text-sm font-medium text-gray-600">Active Proxies</p>
|
||||
<p className="text-3xl font-semibold text-gray-900">{stats?.proxies?.active || 0}</p>
|
||||
<p className="text-xs text-gray-500">{stats?.proxies?.total || 0} total proxies</p>
|
||||
<p className="text-sm font-medium text-gray-600">Brands</p>
|
||||
<p className="text-3xl font-semibold text-gray-900">{stats?.brands?.total || stats?.products?.unique_brands || 0}</p>
|
||||
<p className="text-xs text-gray-500">Unique brands tracked</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user