Fix new services implementation 5
This commit is contained in:
@@ -2,7 +2,8 @@
|
||||
// Complete dashboard hook using your API infrastructure
|
||||
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useAuth, useSales, useExternal, useForecast } from '../api';
|
||||
import { useAuth, useSales, useExternal, useForecast, useInventoryProducts } from '../api';
|
||||
import type { ProductInfo } from '../api/types';
|
||||
|
||||
import { useTenantId } from './useTenantId';
|
||||
|
||||
@@ -14,6 +15,7 @@ interface DashboardData {
|
||||
} | null;
|
||||
todayForecasts: Array<{
|
||||
product: string;
|
||||
inventory_product_id: string;
|
||||
predicted: number;
|
||||
confidence: 'high' | 'medium' | 'low';
|
||||
change: number;
|
||||
@@ -24,18 +26,22 @@ interface DashboardData {
|
||||
accuracy: number;
|
||||
stockouts: number;
|
||||
} | null;
|
||||
products: string[];
|
||||
products: ProductInfo[];
|
||||
}
|
||||
|
||||
export const useDashboard = () => {
|
||||
const { user } = useAuth();
|
||||
const {
|
||||
getProductsList,
|
||||
getSalesAnalytics,
|
||||
getDashboardStats,
|
||||
isLoading: salesLoading,
|
||||
error: salesError
|
||||
} = useSales();
|
||||
const {
|
||||
getProductsList,
|
||||
isLoading: inventoryLoading,
|
||||
error: inventoryError
|
||||
} = useInventoryProducts();
|
||||
const {
|
||||
getCurrentWeather,
|
||||
isLoading: externalLoading,
|
||||
@@ -83,19 +89,31 @@ export const useDashboard = () => {
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
// 1. Get available products
|
||||
let products: string[] = [];
|
||||
// 1. Get available products from inventory service
|
||||
let products: ProductInfo[] = [];
|
||||
try {
|
||||
products = await getProductsList(tenantId);
|
||||
|
||||
// Fallback to default products if none found
|
||||
if (products.length === 0) {
|
||||
products = ['Croissants', 'Pan de molde', 'Baguettes', 'Café', 'Napolitanas'];
|
||||
console.warn('No products found from API, using default products');
|
||||
products = [
|
||||
{ inventory_product_id: 'fallback-croissants', name: 'Croissants' },
|
||||
{ inventory_product_id: 'fallback-pan', name: 'Pan de molde' },
|
||||
{ inventory_product_id: 'fallback-baguettes', name: 'Baguettes' },
|
||||
{ inventory_product_id: 'fallback-cafe', name: 'Café' },
|
||||
{ inventory_product_id: 'fallback-napolitanas', name: 'Napolitanas' }
|
||||
];
|
||||
console.warn('No products found from inventory API, using default products');
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to fetch products:', error);
|
||||
products = ['Croissants', 'Pan de molde', 'Baguettes', 'Café', 'Napolitanas'];
|
||||
console.warn('Failed to fetch products from inventory:', error);
|
||||
products = [
|
||||
{ inventory_product_id: 'fallback-croissants', name: 'Croissants' },
|
||||
{ inventory_product_id: 'fallback-pan', name: 'Pan de molde' },
|
||||
{ inventory_product_id: 'fallback-baguettes', name: 'Baguettes' },
|
||||
{ inventory_product_id: 'fallback-cafe', name: 'Café' },
|
||||
{ inventory_product_id: 'fallback-napolitanas', name: 'Napolitanas' }
|
||||
];
|
||||
}
|
||||
// 2. Get weather data (Madrid coordinates)
|
||||
let weather = null;
|
||||
@@ -112,11 +130,10 @@ export const useDashboard = () => {
|
||||
}
|
||||
|
||||
// 3. Generate forecasts for each product
|
||||
const forecastPromises = products.map(async (product) => {
|
||||
const forecastPromises = products.map(async (productInfo) => {
|
||||
try {
|
||||
const forecastRequest = {
|
||||
inventory_product_id: product, // Use product as inventory_product_id
|
||||
product_name: product, // Keep for backward compatibility
|
||||
inventory_product_id: productInfo.inventory_product_id, // ✅ Now using actual inventory product ID
|
||||
forecast_date: new Date().toISOString().split('T')[0], // Today's date as YYYY-MM-DD
|
||||
forecast_days: 1,
|
||||
location: 'madrid_centro', // Default location for Madrid bakery
|
||||
@@ -125,6 +142,7 @@ export const useDashboard = () => {
|
||||
// confidence_level is handled by backend internally (default 0.8)
|
||||
};
|
||||
|
||||
console.log(`🔮 Requesting forecast for ${productInfo.name} (${productInfo.inventory_product_id})`);
|
||||
const forecastResults = await createSingleForecast(tenantId, forecastRequest);
|
||||
|
||||
if (forecastResults && forecastResults.length > 0) {
|
||||
@@ -138,20 +156,24 @@ export const useDashboard = () => {
|
||||
// Calculate change (placeholder - you might want historical comparison)
|
||||
const change = Math.round(Math.random() * 20 - 10);
|
||||
|
||||
console.log(`✅ Forecast successful for ${productInfo.name}: ${forecast.predicted_demand}`);
|
||||
|
||||
return {
|
||||
product,
|
||||
product: productInfo.name,
|
||||
inventory_product_id: productInfo.inventory_product_id,
|
||||
predicted: Math.round(forecast.predicted_demand || 0),
|
||||
confidence,
|
||||
change
|
||||
};
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`Forecast failed for ${product}:`, error);
|
||||
console.warn(`❌ Forecast failed for ${productInfo.name} (${productInfo.inventory_product_id}):`, error);
|
||||
}
|
||||
|
||||
// Fallback for failed forecasts
|
||||
return {
|
||||
product,
|
||||
product: productInfo.name,
|
||||
inventory_product_id: productInfo.inventory_product_id,
|
||||
predicted: Math.round(Math.random() * 50 + 20),
|
||||
confidence: 'medium' as const,
|
||||
change: Math.round(Math.random() * 20 - 10)
|
||||
@@ -213,11 +235,11 @@ export const useDashboard = () => {
|
||||
precipitation: 0
|
||||
},
|
||||
todayForecasts: [
|
||||
{ product: 'Croissants', predicted: 48, confidence: 'high', change: 8 },
|
||||
{ product: 'Pan de molde', predicted: 35, confidence: 'high', change: 3 },
|
||||
{ product: 'Baguettes', predicted: 25, confidence: 'medium', change: -3 },
|
||||
{ product: 'Café', predicted: 72, confidence: 'high', change: 5 },
|
||||
{ product: 'Napolitanas', predicted: 26, confidence: 'medium', change: 3 }
|
||||
{ product: 'Croissants', inventory_product_id: 'fallback-croissants', predicted: 48, confidence: 'high', change: 8 },
|
||||
{ product: 'Pan de molde', inventory_product_id: 'fallback-pan', predicted: 35, confidence: 'high', change: 3 },
|
||||
{ product: 'Baguettes', inventory_product_id: 'fallback-baguettes', predicted: 25, confidence: 'medium', change: -3 },
|
||||
{ product: 'Café', inventory_product_id: 'fallback-cafe', predicted: 72, confidence: 'high', change: 5 },
|
||||
{ product: 'Napolitanas', inventory_product_id: 'fallback-napolitanas', predicted: 26, confidence: 'medium', change: 3 }
|
||||
],
|
||||
metrics: {
|
||||
totalSales: 1247,
|
||||
@@ -225,7 +247,13 @@ export const useDashboard = () => {
|
||||
accuracy: 87.2,
|
||||
stockouts: 2
|
||||
},
|
||||
products: ['Croissants', 'Pan de molde', 'Baguettes', 'Café', 'Napolitanas']
|
||||
products: [
|
||||
{ inventory_product_id: 'fallback-croissants', name: 'Croissants' },
|
||||
{ inventory_product_id: 'fallback-pan', name: 'Pan de molde' },
|
||||
{ inventory_product_id: 'fallback-baguettes', name: 'Baguettes' },
|
||||
{ inventory_product_id: 'fallback-cafe', name: 'Café' },
|
||||
{ inventory_product_id: 'fallback-napolitanas', name: 'Napolitanas' }
|
||||
]
|
||||
});
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
@@ -241,8 +269,8 @@ export const useDashboard = () => {
|
||||
|
||||
return {
|
||||
...dashboardData,
|
||||
isLoading: isLoading || salesLoading || externalLoading || forecastLoading,
|
||||
error: error || salesError || externalError || forecastError,
|
||||
isLoading: isLoading || salesLoading || inventoryLoading || externalLoading || forecastLoading,
|
||||
error: error || salesError || inventoryError || externalError || forecastError,
|
||||
reload: () => tenantId ? loadDashboardData(tenantId) : Promise.resolve(),
|
||||
clearError: () => setError(null)
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user