Fix and UI imporvements 2
This commit is contained in:
@@ -200,22 +200,22 @@ const EnterpriseDashboardPage: React.FC<EnterpriseDashboardPageProps> = ({ tenan
|
||||
|
||||
return (
|
||||
<ErrorBoundary FallbackComponent={ErrorFallback}>
|
||||
<div className="px-4 sm:px-6 lg:px-8 py-6 min-h-screen" style={{ backgroundColor: 'var(--bg-secondary)' }}>
|
||||
<div className="px-4 sm:px-6 lg:px-8 py-6 min-h-screen bg-[var(--bg-secondary)]">
|
||||
{/* Breadcrumb / Return to Network Banner */}
|
||||
{enterpriseState.selectedOutletId && !enterpriseState.isNetworkView && (
|
||||
<div className="mb-6 rounded-lg p-4" style={{
|
||||
backgroundColor: 'var(--color-info-light, #dbeafe)',
|
||||
borderColor: 'var(--color-info, #3b82f6)',
|
||||
borderWidth: '1px',
|
||||
borderStyle: 'solid'
|
||||
}}>
|
||||
<div
|
||||
className="mb-6 rounded-lg p-4 border border-[var(--border-primary)]"
|
||||
style={{
|
||||
backgroundColor: 'var(--color-info-50)',
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<Network className="w-5 h-5" style={{ color: 'var(--color-info)' }} />
|
||||
<Network className="w-5 h-5 text-[var(--color-info)]" />
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<span className="font-medium" style={{ color: 'var(--color-info)' }}>Network Overview</span>
|
||||
<ChevronRight className="w-4 h-4" style={{ color: 'var(--color-info-light, #93c5fd)' }} />
|
||||
<span className="text-gray-700 font-semibold">{enterpriseState.selectedOutletName}</span>
|
||||
<span className="font-medium text-[var(--color-info)]">Network Overview</span>
|
||||
<ChevronRight className="w-4 h-4 text-[var(--color-info-300)]" />
|
||||
<span className="text-[var(--text-primary)] font-semibold">{enterpriseState.selectedOutletName}</span>
|
||||
</div>
|
||||
</div>
|
||||
<Button
|
||||
@@ -230,18 +230,18 @@ const EnterpriseDashboardPage: React.FC<EnterpriseDashboardPageProps> = ({ tenan
|
||||
</div>
|
||||
{enterpriseState.networkMetrics && (
|
||||
<div className="mt-3 pt-3 border-t grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 text-sm"
|
||||
style={{ borderColor: 'var(--color-info-light, #93c5fd)' }}>
|
||||
style={{ borderColor: 'var(--border-primary)' }}>
|
||||
<div>
|
||||
<span style={{ color: 'var(--color-info)' }}>Network Average Sales:</span>
|
||||
<span className="ml-2 font-semibold">€{enterpriseState.networkMetrics.averageSales.toLocaleString()}</span>
|
||||
<span className="text-[var(--color-info)]">Network Average Sales:</span>
|
||||
<span className="ml-2 font-semibold text-[var(--text-primary)]">€{enterpriseState.networkMetrics.averageSales.toLocaleString()}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span style={{ color: 'var(--color-info)' }}>Total Outlets:</span>
|
||||
<span className="ml-2 font-semibold">{enterpriseState.networkMetrics.childCount}</span>
|
||||
<span className="text-[var(--color-info)]">Total Outlets:</span>
|
||||
<span className="ml-2 font-semibold text-[var(--text-primary)]">{enterpriseState.networkMetrics.childCount}</span>
|
||||
</div>
|
||||
<div>
|
||||
<span style={{ color: 'var(--color-info)' }}>Network Total:</span>
|
||||
<span className="ml-2 font-semibold">€{enterpriseState.networkMetrics.totalSales.toLocaleString()}</span>
|
||||
<span className="text-[var(--color-info)]">Network Total:</span>
|
||||
<span className="ml-2 font-semibold text-[var(--text-primary)]">€{enterpriseState.networkMetrics.totalSales.toLocaleString()}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -262,10 +262,10 @@ const EnterpriseDashboardPage: React.FC<EnterpriseDashboardPageProps> = ({ tenan
|
||||
<Network className="w-8 h-8 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-4xl font-bold" style={{ color: 'var(--text-primary)' }}>
|
||||
<h1 className="text-4xl font-bold text-[var(--text-primary)]">
|
||||
{t('enterprise.network_dashboard')}
|
||||
</h1>
|
||||
<p className="mt-1" style={{ color: 'var(--text-secondary)' }}>
|
||||
<p className="mt-1 text-[var(--text-secondary)]">
|
||||
{t('enterprise.network_summary_description')}
|
||||
</p>
|
||||
</div>
|
||||
@@ -288,16 +288,16 @@ const EnterpriseDashboardPage: React.FC<EnterpriseDashboardPageProps> = ({ tenan
|
||||
<Card className="h-full">
|
||||
<CardHeader className="flex flex-row items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<Truck className="w-5 h-5 text-blue-600" />
|
||||
<Truck className="w-5 h-5 text-[var(--color-info)]" />
|
||||
<CardTitle>{t('enterprise.distribution_map')}</CardTitle>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Calendar className="w-4 h-4 text-gray-500" />
|
||||
<Calendar className="w-4 h-4 text-[var(--text-secondary)]" />
|
||||
<input
|
||||
type="date"
|
||||
value={selectedDate}
|
||||
onChange={(e) => setSelectedDate(e.target.value)}
|
||||
className="border rounded px-2 py-1 text-sm"
|
||||
className="border border-[var(--border-primary)] rounded-md px-2 py-1 text-sm bg-[var(--input-bg)] text-[var(--text-primary)]"
|
||||
/>
|
||||
</div>
|
||||
</CardHeader>
|
||||
@@ -308,7 +308,7 @@ const EnterpriseDashboardPage: React.FC<EnterpriseDashboardPageProps> = ({ tenan
|
||||
shipments={distributionOverview.status_counts}
|
||||
/>
|
||||
) : (
|
||||
<div className="h-96 flex items-center justify-center text-gray-500">
|
||||
<div className="h-96 flex items-center justify-center text-[var(--text-secondary)]">
|
||||
{t('enterprise.no_distribution_data')}
|
||||
</div>
|
||||
)}
|
||||
@@ -321,14 +321,14 @@ const EnterpriseDashboardPage: React.FC<EnterpriseDashboardPageProps> = ({ tenan
|
||||
<Card className="h-full">
|
||||
<CardHeader className="flex flex-row items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<BarChart3 className="w-5 h-5 text-green-600" />
|
||||
<BarChart3 className="w-5 h-5 text-[var(--color-success)]" />
|
||||
<CardTitle>{t('enterprise.outlet_performance')}</CardTitle>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<select
|
||||
value={selectedMetric}
|
||||
onChange={(e) => setSelectedMetric(e.target.value)}
|
||||
className="border rounded px-2 py-1 text-sm"
|
||||
className="border border-[var(--border-primary)] rounded-md px-2 py-1 text-sm bg-[var(--input-bg)] text-[var(--text-primary)]"
|
||||
>
|
||||
<option value="sales">{t('enterprise.metrics.sales')}</option>
|
||||
<option value="inventory_value">{t('enterprise.metrics.inventory_value')}</option>
|
||||
@@ -337,7 +337,7 @@ const EnterpriseDashboardPage: React.FC<EnterpriseDashboardPageProps> = ({ tenan
|
||||
<select
|
||||
value={selectedPeriod}
|
||||
onChange={(e) => setSelectedPeriod(Number(e.target.value))}
|
||||
className="border rounded px-2 py-1 text-sm"
|
||||
className="border border-[var(--border-primary)] rounded-md px-2 py-1 text-sm bg-[var(--input-bg)] text-[var(--text-primary)]"
|
||||
>
|
||||
<option value={7}>{t('enterprise.last_7_days')}</option>
|
||||
<option value={30}>{t('enterprise.last_30_days')}</option>
|
||||
@@ -354,7 +354,7 @@ const EnterpriseDashboardPage: React.FC<EnterpriseDashboardPageProps> = ({ tenan
|
||||
onOutletClick={handleOutletClick}
|
||||
/>
|
||||
) : (
|
||||
<div className="h-96 flex items-center justify-center text-gray-500">
|
||||
<div className="h-96 flex items-center justify-center text-[var(--text-secondary)]">
|
||||
{t('enterprise.no_performance_data')}
|
||||
</div>
|
||||
)}
|
||||
@@ -367,121 +367,105 @@ const EnterpriseDashboardPage: React.FC<EnterpriseDashboardPageProps> = ({ tenan
|
||||
<div className="mb-8">
|
||||
<Card>
|
||||
<CardHeader className="flex flex-row items-center gap-2">
|
||||
<TrendingUp className="w-5 h-5 text-purple-600" />
|
||||
<TrendingUp className="w-5 h-5 text-[var(--color-primary)]" />
|
||||
<CardTitle>{t('enterprise.network_forecast')}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
{forecastSummary && forecastSummary.aggregated_forecasts ? (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
{/* Total Demand Card */}
|
||||
<div
|
||||
className="p-6 rounded-xl border-2 transition-all duration-300 hover:shadow-lg"
|
||||
style={{
|
||||
backgroundColor: 'var(--color-info-50)',
|
||||
borderColor: 'var(--color-info-200)',
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div
|
||||
className="w-10 h-10 rounded-lg flex items-center justify-center shadow-md"
|
||||
style={{ backgroundColor: 'var(--color-info-100)' }}
|
||||
>
|
||||
<Package className="w-5 h-5" style={{ color: 'var(--color-info-600)' }} />
|
||||
<Card className="hover:shadow-lg transition-shadow duration-300">
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div
|
||||
className="w-10 h-10 rounded-lg flex items-center justify-center shadow-md"
|
||||
style={{ backgroundColor: 'var(--color-info-100)' }}
|
||||
>
|
||||
<Package className="w-5 h-5" style={{ color: 'var(--color-info-600)' }} />
|
||||
</div>
|
||||
<h3 className="font-semibold text-sm" style={{ color: 'var(--color-info-800)' }}>
|
||||
{t('enterprise.total_demand')}
|
||||
</h3>
|
||||
</div>
|
||||
<h3 className="font-semibold text-sm" style={{ color: 'var(--color-info-800)' }}>
|
||||
{t('enterprise.total_demand')}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-3xl font-bold" style={{ color: 'var(--color-info-900)' }}>
|
||||
{Object.values(forecastSummary.aggregated_forecasts).reduce((total: number, day: any) =>
|
||||
total + Object.values(day).reduce((dayTotal: number, product: any) =>
|
||||
dayTotal + (product.predicted_demand || 0), 0), 0
|
||||
).toLocaleString()}
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-3xl font-bold" style={{ color: 'var(--color-info-900)' }}>
|
||||
{Object.values(forecastSummary.aggregated_forecasts).reduce((total: number, day: any) =>
|
||||
total + Object.values(day).reduce((dayTotal: number, product: any) =>
|
||||
dayTotal + (product.predicted_demand || 0), 0), 0
|
||||
).toLocaleString()}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Days Forecast Card */}
|
||||
<div
|
||||
className="p-6 rounded-xl border-2 transition-all duration-300 hover:shadow-lg"
|
||||
style={{
|
||||
backgroundColor: 'var(--color-success-50)',
|
||||
borderColor: 'var(--color-success-200)',
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div
|
||||
className="w-10 h-10 rounded-lg flex items-center justify-center shadow-md"
|
||||
style={{ backgroundColor: 'var(--color-success-100)' }}
|
||||
>
|
||||
<Calendar className="w-5 h-5" style={{ color: 'var(--color-success-600)' }} />
|
||||
<Card className="hover:shadow-lg transition-shadow duration-300">
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div
|
||||
className="w-10 h-10 rounded-lg flex items-center justify-center shadow-md"
|
||||
style={{ backgroundColor: 'var(--color-success-100)' }}
|
||||
>
|
||||
<Calendar className="w-5 h-5" style={{ color: 'var(--color-success-600)' }} />
|
||||
</div>
|
||||
<h3 className="font-semibold text-sm" style={{ color: 'var(--color-success-800)' }}>
|
||||
{t('enterprise.days_forecast')}
|
||||
</h3>
|
||||
</div>
|
||||
<h3 className="font-semibold text-sm" style={{ color: 'var(--color-success-800)' }}>
|
||||
{t('enterprise.days_forecast')}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-3xl font-bold" style={{ color: 'var(--color-success-900)' }}>
|
||||
{forecastSummary.days_forecast || 7}
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-3xl font-bold" style={{ color: 'var(--color-success-900)' }}>
|
||||
{forecastSummary.days_forecast || 7}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Average Daily Demand Card */}
|
||||
<div
|
||||
className="p-6 rounded-xl border-2 transition-all duration-300 hover:shadow-lg"
|
||||
style={{
|
||||
backgroundColor: 'var(--color-secondary-50)',
|
||||
borderColor: 'var(--color-secondary-200)',
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div
|
||||
className="w-10 h-10 rounded-lg flex items-center justify-center shadow-md"
|
||||
style={{ backgroundColor: 'var(--color-secondary-100)' }}
|
||||
>
|
||||
<Activity className="w-5 h-5" style={{ color: 'var(--color-secondary-600)' }} />
|
||||
<Card className="hover:shadow-lg transition-shadow duration-300">
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div
|
||||
className="w-10 h-10 rounded-lg flex items-center justify-center shadow-md"
|
||||
style={{ backgroundColor: 'var(--color-secondary-100)' }}
|
||||
>
|
||||
<Activity className="w-5 h-5" style={{ color: 'var(--color-secondary-600)' }} />
|
||||
</div>
|
||||
<h3 className="font-semibold text-sm" style={{ color: 'var(--color-secondary-800)' }}>
|
||||
{t('enterprise.avg_daily_demand')}
|
||||
</h3>
|
||||
</div>
|
||||
<h3 className="font-semibold text-sm" style={{ color: 'var(--color-secondary-800)' }}>
|
||||
{t('enterprise.avg_daily_demand')}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-3xl font-bold" style={{ color: 'var(--color-secondary-900)' }}>
|
||||
{forecastSummary.aggregated_forecasts
|
||||
? Math.round(Object.values(forecastSummary.aggregated_forecasts).reduce((total: number, day: any) =>
|
||||
total + Object.values(day).reduce((dayTotal: number, product: any) =>
|
||||
dayTotal + (product.predicted_demand || 0), 0), 0) /
|
||||
Object.keys(forecastSummary.aggregated_forecasts).length
|
||||
).toLocaleString()
|
||||
: 0}
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-3xl font-bold" style={{ color: 'var(--color-secondary-900)' }}>
|
||||
{forecastSummary.aggregated_forecasts
|
||||
? Math.round(Object.values(forecastSummary.aggregated_forecasts).reduce((total: number, day: any) =>
|
||||
total + Object.values(day).reduce((dayTotal: number, product: any) =>
|
||||
dayTotal + (product.predicted_demand || 0), 0), 0) /
|
||||
Object.keys(forecastSummary.aggregated_forecasts).length
|
||||
).toLocaleString()
|
||||
: 0}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Last Updated Card */}
|
||||
<div
|
||||
className="p-6 rounded-xl border-2 transition-all duration-300 hover:shadow-lg"
|
||||
style={{
|
||||
backgroundColor: 'var(--color-warning-50)',
|
||||
borderColor: 'var(--color-warning-200)',
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div
|
||||
className="w-10 h-10 rounded-lg flex items-center justify-center shadow-md"
|
||||
style={{ backgroundColor: 'var(--color-warning-100)' }}
|
||||
>
|
||||
<Clock className="w-5 h-5" style={{ color: 'var(--color-warning-600)' }} />
|
||||
<Card className="hover:shadow-lg transition-shadow duration-300">
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-center gap-3 mb-3">
|
||||
<div
|
||||
className="w-10 h-10 rounded-lg flex items-center justify-center shadow-md"
|
||||
style={{ backgroundColor: 'var(--color-warning-100)' }}
|
||||
>
|
||||
<Clock className="w-5 h-5" style={{ color: 'var(--color-warning-600)' }} />
|
||||
</div>
|
||||
<h3 className="font-semibold text-sm" style={{ color: 'var(--color-warning-800)' }}>
|
||||
{t('enterprise.last_updated')}
|
||||
</h3>
|
||||
</div>
|
||||
<h3 className="font-semibold text-sm" style={{ color: 'var(--color-warning-800)' }}>
|
||||
{t('enterprise.last_updated')}
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-lg font-semibold" style={{ color: 'var(--color-warning-900)' }}>
|
||||
{forecastSummary.last_updated ?
|
||||
new Date(forecastSummary.last_updated).toLocaleTimeString() :
|
||||
'N/A'}
|
||||
</p>
|
||||
</div>
|
||||
<p className="text-lg font-semibold" style={{ color: 'var(--color-warning-900)' }}>
|
||||
{forecastSummary.last_updated ?
|
||||
new Date(forecastSummary.last_updated).toLocaleTimeString() :
|
||||
'N/A'}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center justify-center h-48 text-gray-500">
|
||||
<div className="flex items-center justify-center h-48 text-[var(--text-secondary)]">
|
||||
{t('enterprise.no_forecast_data')}
|
||||
</div>
|
||||
)}
|
||||
@@ -494,10 +478,10 @@ const EnterpriseDashboardPage: React.FC<EnterpriseDashboardPageProps> = ({ tenan
|
||||
<Card>
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<Building2 className="w-6 h-6 text-blue-600" />
|
||||
<h3 className="text-lg font-semibold">Agregar Punto de Venta</h3>
|
||||
<Building2 className="w-6 h-6 text-[var(--color-primary)]" />
|
||||
<h3 className="text-lg font-semibold text-[var(--text-primary)]">Agregar Punto de Venta</h3>
|
||||
</div>
|
||||
<p className="text-gray-600 mb-4">Añadir un nuevo outlet a la red enterprise</p>
|
||||
<p className="text-[var(--text-secondary)] mb-4">Añadir un nuevo outlet a la red enterprise</p>
|
||||
<Button
|
||||
onClick={() => navigate(`/app/tenants/${tenantId}/settings/organization`)}
|
||||
className="w-full"
|
||||
@@ -510,10 +494,10 @@ const EnterpriseDashboardPage: React.FC<EnterpriseDashboardPageProps> = ({ tenan
|
||||
<Card>
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<PackageCheck className="w-6 h-6 text-green-600" />
|
||||
<h3 className="text-lg font-semibold">Transferencias Internas</h3>
|
||||
<PackageCheck className="w-6 h-6 text-[var(--color-success)]" />
|
||||
<h3 className="text-lg font-semibold text-[var(--text-primary)]">Transferencias Internas</h3>
|
||||
</div>
|
||||
<p className="text-gray-600 mb-4">Gestionar pedidos entre obrador central y outlets</p>
|
||||
<p className="text-[var(--text-secondary)] mb-4">Gestionar pedidos entre obrador central y outlets</p>
|
||||
<Button
|
||||
onClick={() => navigate(`/app/tenants/${tenantId}/procurement/internal-transfers`)}
|
||||
variant="outline"
|
||||
@@ -527,10 +511,10 @@ const EnterpriseDashboardPage: React.FC<EnterpriseDashboardPageProps> = ({ tenan
|
||||
<Card>
|
||||
<CardContent className="p-6">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<MapPin className="w-6 h-6 text-red-600" />
|
||||
<h3 className="text-lg font-semibold">Rutas de Distribución</h3>
|
||||
<MapPin className="w-6 h-6 text-[var(--color-info)]" />
|
||||
<h3 className="text-lg font-semibold text-[var(--text-primary)]">Rutas de Distribución</h3>
|
||||
</div>
|
||||
<p className="text-gray-600 mb-4">Optimizar rutas de entrega entre ubicaciones</p>
|
||||
<p className="text-[var(--text-secondary)] mb-4">Optimizar rutas de entrega entre ubicaciones</p>
|
||||
<Button
|
||||
onClick={() => navigate(`/app/tenants/${tenantId}/distribution/routes`)}
|
||||
variant="outline"
|
||||
|
||||
Reference in New Issue
Block a user