Improve UI
This commit is contained in:
@@ -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')}
|
||||
|
||||
@@ -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') :
|
||||
|
||||
@@ -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>
|
||||
))}
|
||||
|
||||
@@ -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,
|
||||
})}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user