2026-01-07 15:41:36 +01:00

173 lines
3.6 KiB
TypeScript

import "server-only";
import { formatCurrency, formatPercentage } from "@/app/utils/formatCurrency";
interface IHealthData {
total?: number;
successful?: number;
acceptance_rate?: number;
amount?: number;
atv?: number;
}
interface IStatItem {
label: string;
value: string | number;
change: string;
}
export const transformHealthDataToStats = (
healthData: IHealthData | null
): IStatItem[] => {
if (!healthData) {
return [
{ label: "TOTAL", value: 0, change: "0%" },
{ label: "SUCCESSFUL", value: 0, change: "0%" },
{ label: "ACCEPTANCE RATE", value: "0%", change: "0%" },
{ label: "AMOUNT", value: "€0.00", change: "0%" },
{ label: "ATV", value: "€0.00", change: "0%" },
];
}
return [
{
label: "TOTAL",
value: healthData.total ?? 0,
change: "0%",
},
{
label: "SUCCESSFUL",
value: healthData.successful ?? 0,
change: "0%",
},
{
label: "ACCEPTANCE RATE",
value: formatPercentage(healthData.acceptance_rate),
change: "0%",
},
{
label: "AMOUNT",
value: formatCurrency(healthData.amount),
change: "0%",
},
{
label: "ATV",
value: formatCurrency(healthData.atv),
change: "0%",
},
];
};
/**
* Map transaction state to color
*/
const getStateColor = (state: string): string => {
const normalizedState = state.toLowerCase();
switch (normalizedState) {
case "success":
case "completed":
case "successful":
return "#4caf50"; // green
case "pending":
case "waiting":
return "#ff9800"; // orange
case "failed":
case "error":
return "#f44336"; // red
case "cancelled":
case "canceled":
return "#9e9e9e"; // gray
default:
return "#9e9e9e"; // gray
}
};
/**
* Calculate percentage for each state
*/
const calculatePercentages = (
items: Array<{ state: string; count: number }>
): Array<{
state: string;
count: number;
percentage: string;
}> => {
const total = items.reduce((sum, item) => sum + item.count, 0);
if (total === 0) {
return items.map(item => ({
...item,
percentage: "0%",
}));
}
return items.map(item => ({
...item,
percentage: `${Math.round((item.count / total) * 100)}%`,
}));
};
/**
* Transform API overview data to include colors
*/
const enrichOverviewData = (
data: Array<{
state: string;
count: number;
percentage: string;
color?: string;
}>
): Array<{
state: string;
count: number;
percentage: string;
color: string;
}> => {
return data.map(item => ({
...item,
color: item.color || getStateColor(item.state),
}));
};
/**
* Transform flat API overview response to enriched array format with percentages and colors
*/
export const transformOverviewResponse = (
data:
| {
cancelled_count?: number;
failed_count?: number;
successful_count?: number;
waiting_count?: number;
}
| null
| undefined
): Array<{
state: string;
count: number;
percentage: string;
color: string;
}> => {
if (!data) {
return [];
}
const states = [
{ key: "successful_count", label: "Successful" },
{ key: "waiting_count", label: "Waiting" },
{ key: "failed_count", label: "Failed" },
{ key: "cancelled_count", label: "Cancelled" },
];
const transformed = states
.map(({ key, label }) => ({
state: label,
count: data[key as keyof typeof data] || 0,
}))
.filter(item => item.count > 0); // Only include states with counts > 0
const withPercentages = calculatePercentages(transformed);
return enrichOverviewData(withPercentages);
};