mirror of
https://github.com/christianvidalwolf-prog/CrazeAnalytix.git
synced 2026-08-03 11:45:23 +02:00
Refine Forecast View: compact UI and dynamic UK data integration
This commit is contained in:
@@ -90,7 +90,7 @@ const App: React.FC = () => {
|
||||
console.log('[App] Successfully loaded', data.length, 'rows');
|
||||
|
||||
// Refresh forecast too
|
||||
handleForecastFetch(data);
|
||||
handleForecastFetch(data, filters.customer);
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch/parse CSV", error);
|
||||
alert("Error loading data. Please refresh the page.");
|
||||
@@ -143,11 +143,14 @@ const App: React.FC = () => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const handleForecastFetch = useCallback(async (sales: SalesRecord[]) => {
|
||||
const handleForecastFetch = useCallback(async (sales: SalesRecord[], customerFilters: string[] = []) => {
|
||||
try {
|
||||
console.log('[App] Fetching forecast from /forecast.xlsx...');
|
||||
const response = await fetch('/forecast.xlsx');
|
||||
if (!response.ok) throw new Error("Forecast file not found");
|
||||
const isUK = customerFilters.includes('Amazon UK');
|
||||
const filename = isUK ? '/fc UK 26.xlsx' : '/fc 26.xlsx';
|
||||
|
||||
console.log(`[App] Fetching forecast from ${filename}...`);
|
||||
const response = await fetch(filename);
|
||||
if (!response.ok) throw new Error(`Forecast file ${filename} not found`);
|
||||
|
||||
const buffer = await response.arrayBuffer();
|
||||
const fcRecords = await processForecastExcel(buffer);
|
||||
@@ -166,10 +169,17 @@ const App: React.FC = () => {
|
||||
setForecastData(viewData);
|
||||
console.log('[App] Forecast loaded:', viewData.length, 'records');
|
||||
} catch (error) {
|
||||
console.warn("Forecast fetch failed (expected if local file not set up yet):", error);
|
||||
console.warn("Forecast fetch failed:", error);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Update forecast when customer filter changes
|
||||
useEffect(() => {
|
||||
if (rawData.length > 0) {
|
||||
handleForecastFetch(rawData, filters.customer);
|
||||
}
|
||||
}, [filters.customer, rawData, handleForecastFetch]);
|
||||
|
||||
const initializeData = (data: SalesRecord[]) => {
|
||||
setRawData(data);
|
||||
setFilters({
|
||||
@@ -245,7 +255,7 @@ const App: React.FC = () => {
|
||||
handleTrafficFetch();
|
||||
|
||||
// 1d. Fetch Forecast data
|
||||
handleForecastFetch(cachedData || []);
|
||||
handleForecastFetch(cachedData || [], filters.customer);
|
||||
};
|
||||
initApp();
|
||||
}, [handleDataFetch]);
|
||||
|
||||
+13
-13
@@ -135,33 +135,33 @@ const ForecastView: React.FC<ForecastViewProps> = ({ data, filters, top50Ranking
|
||||
<div className="p-6 space-y-6 max-w-7xl mx-auto animate-fade-in pb-24">
|
||||
|
||||
{/* Summary Cards */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<div className="bg-slate-900 border border-border rounded-2xl p-6 shadow-xl relative overflow-hidden group">
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div className="bg-slate-900 border border-border rounded-2xl p-4 shadow-xl relative overflow-hidden group">
|
||||
<div className="absolute top-0 right-0 w-32 h-32 bg-indigo-500/10 rounded-full -mr-16 -mt-16 blur-3xl group-hover:bg-indigo-500/20 transition-all"></div>
|
||||
<h3 className="text-xs font-black text-slate-500 uppercase tracking-widest mb-4">Total Forecast 2026</h3>
|
||||
<div className="text-4xl font-black text-white">
|
||||
{globalSummary.totalForecast.toLocaleString('de-DE')} <span className="text-sm font-medium text-slate-500">Units</span>
|
||||
<h3 className="text-[10px] font-black text-slate-500 uppercase tracking-widest mb-1">Total Forecast 2026</h3>
|
||||
<div className="text-2xl font-black text-white">
|
||||
{globalSummary.totalForecast.toLocaleString('de-DE')} <span className="text-xs font-medium text-slate-500">Units</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-slate-900 border border-border rounded-2xl p-6 shadow-xl relative overflow-hidden group">
|
||||
<div className="bg-slate-900 border border-border rounded-2xl p-4 shadow-xl relative overflow-hidden group">
|
||||
<div className="absolute top-0 right-0 w-32 h-32 bg-emerald-500/10 rounded-full -mr-16 -mt-16 blur-3xl group-hover:bg-emerald-500/20 transition-all"></div>
|
||||
<h3 className="text-xs font-black text-slate-500 uppercase tracking-widest mb-4">Total Actual Sales 2026</h3>
|
||||
<div className="text-4xl font-black text-emerald-400">
|
||||
{globalSummary.totalActual.toLocaleString('de-DE')} <span className="text-sm font-medium text-slate-500">Units</span>
|
||||
<h3 className="text-[10px] font-black text-slate-500 uppercase tracking-widest mb-1">Total Actual Sales 2026</h3>
|
||||
<div className="text-2xl font-black text-emerald-400">
|
||||
{globalSummary.totalActual.toLocaleString('de-DE')} <span className="text-xs font-medium text-slate-500">Units</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="bg-slate-900 border border-indigo-500/30 rounded-2xl p-6 shadow-xl relative overflow-hidden group">
|
||||
<div className="bg-slate-900 border border-indigo-500/30 rounded-2xl p-4 shadow-xl relative overflow-hidden group">
|
||||
<div className="absolute top-0 right-0 w-32 h-32 bg-indigo-500/20 rounded-full -mr-16 -mt-16 blur-3xl"></div>
|
||||
<h3 className="text-xs font-black text-indigo-400 uppercase tracking-widest mb-4">Global Fulfillment</h3>
|
||||
<h3 className="text-[10px] font-black text-indigo-400 uppercase tracking-widest mb-1">Global Fulfillment</h3>
|
||||
<div className="flex items-baseline gap-2">
|
||||
<div className={`text-4xl font-black ${globalSummary.fulfillment >= 100 ? 'text-emerald-400' : 'text-indigo-400'}`}>
|
||||
<div className={`text-2xl font-black ${globalSummary.fulfillment >= 100 ? 'text-emerald-400' : 'text-indigo-400'}`}>
|
||||
{globalSummary.fulfillment.toFixed(1)}%
|
||||
</div>
|
||||
</div>
|
||||
{/* Fulfillment Progress Bar */}
|
||||
<div className="mt-4 w-full h-2 bg-slate-800 rounded-full overflow-hidden">
|
||||
<div className="mt-2 w-full h-1.5 bg-slate-800 rounded-full overflow-hidden">
|
||||
<div
|
||||
className="h-full bg-gradient-to-r from-indigo-500 to-fuchsia-500 shadow-[0_0_8px_rgba(99,102,241,0.5)] transition-all duration-1000"
|
||||
style={{ width: `${Math.min(100, globalSummary.fulfillment)}%` }}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user