Improve UI

This commit is contained in:
Urtzi Alfaro
2025-12-30 14:40:20 +01:00
parent e494ea8635
commit c07df124fb
71 changed files with 647 additions and 265 deletions

View File

@@ -11,6 +11,7 @@ import { useTranslation } from 'react-i18next';
import { useDistributionOverview } from '../../api/hooks/useEnterpriseDashboard';
import { useSSEEvents } from '../../hooks/useSSE';
import StatusCard from '../ui/StatusCard/StatusCard';
import { useTenantCurrency } from '../../hooks/useTenantCurrency';
interface DistributionTabProps {
tenantId: string;
@@ -20,6 +21,7 @@ interface DistributionTabProps {
const DistributionTab: React.FC<DistributionTabProps> = ({ tenantId, selectedDate, onDateChange }) => {
const { t } = useTranslation('dashboard');
const { currencySymbol } = useTenantCurrency();
// Get distribution data
const {
@@ -317,7 +319,7 @@ const DistributionTab: React.FC<DistributionTabProps> = ({ tenantId, selectedDat
</CardHeader>
<CardContent>
<div className="text-3xl font-bold text-[var(--color-info)]">
{optimizationMetrics.fuelSaved.toFixed(2)}
{currencySymbol}{optimizationMetrics.fuelSaved.toFixed(2)}
</div>
<p className="text-xs text-[var(--text-secondary)] mt-1">
{t('enterprise.estimated_fuel_savings')}

View File

@@ -11,6 +11,7 @@ import { useTranslation } from 'react-i18next';
import { useChildrenPerformance } from '../../api/hooks/useEnterpriseDashboard';
import PerformanceChart from '../charts/PerformanceChart';
import StatusCard from '../ui/StatusCard/StatusCard';
import { useTenantCurrency } from '../../hooks/useTenantCurrency';
interface NetworkPerformanceTabProps {
tenantId: string;
@@ -19,6 +20,7 @@ interface NetworkPerformanceTabProps {
const NetworkPerformanceTab: React.FC<NetworkPerformanceTabProps> = ({ tenantId, onOutletClick }) => {
const { t } = useTranslation('dashboard');
const { currencySymbol } = useTenantCurrency();
const [selectedMetric, setSelectedMetric] = useState('sales');
const [selectedPeriod, setSelectedPeriod] = useState(30);
const [viewMode, setViewMode] = useState<'chart' | 'cards'>('chart');
@@ -216,8 +218,8 @@ const NetworkPerformanceTab: React.FC<NetworkPerformanceTabProps> = ({ tenantId,
</CardHeader>
<CardContent>
<div className="text-3xl font-bold text-[var(--color-success)]">
{selectedMetric === 'sales' ? `${networkMetrics.avgSales.toLocaleString()}` :
selectedMetric === 'inventory_value' ? `${networkMetrics.avgInventory.toLocaleString()}` :
{selectedMetric === 'sales' ? `${currencySymbol}${networkMetrics.avgSales.toLocaleString()}` :
selectedMetric === 'inventory_value' ? `${currencySymbol}${networkMetrics.avgInventory.toLocaleString()}` :
networkMetrics.avgOrders.toLocaleString()}
</div>
<p className="text-xs text-[var(--text-secondary)] mt-1">
@@ -266,8 +268,8 @@ const NetworkPerformanceTab: React.FC<NetworkPerformanceTabProps> = ({ tenantId,
}}
title={networkMetrics.topPerformer.outlet_name}
subtitle={t('enterprise.best_in_network')}
primaryValue={selectedMetric === 'sales' ? `${networkMetrics.topPerformer.metric_value.toLocaleString()}` :
selectedMetric === 'inventory_value' ? `${networkMetrics.topPerformer.metric_value.toLocaleString()}` :
primaryValue={selectedMetric === 'sales' ? `${currencySymbol}${networkMetrics.topPerformer.metric_value.toLocaleString()}` :
selectedMetric === 'inventory_value' ? `${currencySymbol}${networkMetrics.topPerformer.metric_value.toLocaleString()}` :
networkMetrics.topPerformer.metric_value.toLocaleString()}
primaryValueLabel={selectedMetric === 'sales' ? t('enterprise.sales') :
selectedMetric === 'inventory_value' ? t('enterprise.inventory_value') :
@@ -305,8 +307,8 @@ const NetworkPerformanceTab: React.FC<NetworkPerformanceTabProps> = ({ tenantId,
}}
title={networkMetrics.bottomPerformer.outlet_name}
subtitle={t('enterprise.improvement_opportunity')}
primaryValue={selectedMetric === 'sales' ? `${networkMetrics.bottomPerformer.metric_value.toLocaleString()}` :
selectedMetric === 'inventory_value' ? `${networkMetrics.bottomPerformer.metric_value.toLocaleString()}` :
primaryValue={selectedMetric === 'sales' ? `${currencySymbol}${networkMetrics.bottomPerformer.metric_value.toLocaleString()}` :
selectedMetric === 'inventory_value' ? `${currencySymbol}${networkMetrics.bottomPerformer.metric_value.toLocaleString()}` :
networkMetrics.bottomPerformer.metric_value.toLocaleString()}
primaryValueLabel={selectedMetric === 'sales' ? t('enterprise.sales') :
selectedMetric === 'inventory_value' ? t('enterprise.inventory_value') :
@@ -429,8 +431,8 @@ const NetworkPerformanceTab: React.FC<NetworkPerformanceTabProps> = ({ tenantId,
}}
title={outlet.outlet_name}
subtitle={`#${index + 1} ${t('enterprise.of')} ${childrenPerformance.rankings.length}`}
primaryValue={selectedMetric === 'sales' ? `${outlet.metric_value.toLocaleString()}` :
selectedMetric === 'inventory_value' ? `${outlet.metric_value.toLocaleString()}` :
primaryValue={selectedMetric === 'sales' ? `${currencySymbol}${outlet.metric_value.toLocaleString()}` :
selectedMetric === 'inventory_value' ? `${currencySymbol}${outlet.metric_value.toLocaleString()}` :
outlet.metric_value.toLocaleString()}
primaryValueLabel={selectedMetric === 'sales' ? t('enterprise.sales') :
selectedMetric === 'inventory_value' ? t('enterprise.inventory_value') :

View File

@@ -16,6 +16,7 @@ import {
} from 'chart.js';
import { Card, CardContent } from '../ui/Card';
import { useTranslation } from 'react-i18next';
import { useTenantCurrency } from '../../hooks/useTenantCurrency';
// Register Chart.js components
ChartJS.register(
@@ -42,6 +43,7 @@ interface PerformanceChartProps {
export const PerformanceChart: React.FC<PerformanceChartProps> = ({ data, metric, period }) => {
const { t } = useTranslation('dashboard');
const { currencySymbol } = useTenantCurrency();
// Prepare chart data
const chartData = {
@@ -76,7 +78,7 @@ export const PerformanceChart: React.FC<PerformanceChartProps> = ({ data, metric
}
if (context.parsed.y !== null) {
if (metric === 'sales') {
label += `${context.parsed.y.toFixed(2)}`;
label += `${currencySymbol}${context.parsed.y.toFixed(2)}`;
} else {
label += context.parsed.y;
}
@@ -142,7 +144,7 @@ export const PerformanceChart: React.FC<PerformanceChartProps> = ({ data, metric
<td className="px-3 py-2">{item.rank}</td>
<td className="px-3 py-2 font-medium">{item.anonymized_name}</td>
<td className="px-3 py-2 text-right">
{metric === 'sales' ? `${item.metric_value.toFixed(2)}` : item.metric_value}
{metric === 'sales' ? `${currencySymbol}${item.metric_value.toFixed(2)}` : item.metric_value}
</td>
</tr>
))}

View File

@@ -19,6 +19,7 @@ import {
ShoppingCart,
X,
} from 'lucide-react';
import { useTenantCurrency } from '../../../hooks/useTenantCurrency';
interface PendingPurchasesBlockProps {
pendingPOs: any[];
@@ -36,6 +37,7 @@ export function PendingPurchasesBlock({
loading,
}: PendingPurchasesBlockProps) {
const { t } = useTranslation(['dashboard', 'common']);
const { currencySymbol } = useTenantCurrency();
const [expandedReasoningId, setExpandedReasoningId] = useState<string | null>(null);
const [processingId, setProcessingId] = useState<string | null>(null);
@@ -288,7 +290,7 @@ export function PendingPurchasesBlock({
</p>
<p className="text-lg font-bold text-[var(--text-primary)]">
{(po.total_amount || po.total || 0).toLocaleString(undefined, {
{currencySymbol}{(po.total_amount || po.total || 0).toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
})}

View File

@@ -22,6 +22,7 @@ import {
TrendingUp,
} from 'lucide-react';
import type { ControlPanelData, OrchestrationSummary } from '../../../api/hooks/useControlPanelData';
import { useTenantCurrency } from '../../../hooks/useTenantCurrency';
interface SystemStatusBlockProps {
data: ControlPanelData | undefined;
@@ -30,6 +31,7 @@ interface SystemStatusBlockProps {
export function SystemStatusBlock({ data, loading }: SystemStatusBlockProps) {
const { t } = useTranslation(['dashboard', 'common']);
const { currencySymbol } = useTenantCurrency();
const [isExpanded, setIsExpanded] = useState(false);
if (loading) {
@@ -234,7 +236,7 @@ export function SystemStatusBlock({ data, loading }: SystemStatusBlockProps) {
{t('dashboard:new_dashboard.system_status.estimated_savings')}
</div>
<div className="text-xl font-bold text-[var(--color-success-600)]">
{orchestrationSummary.estimatedSavingsEur.toLocaleString()}
{currencySymbol}{orchestrationSummary.estimatedSavingsEur.toLocaleString()}
</div>
</div>
)}
@@ -266,7 +268,7 @@ export function SystemStatusBlock({ data, loading }: SystemStatusBlockProps) {
</p>
{issue.business_impact?.financial_impact_eur && (
<p className="text-xs text-[var(--text-secondary)]">
{t('dashboard:new_dashboard.system_status.saved')}: {issue.business_impact.financial_impact_eur.toLocaleString()}
{t('dashboard:new_dashboard.system_status.saved')}: {currencySymbol}{issue.business_impact.financial_impact_eur.toLocaleString()}
</p>
)}
</div>