refactor: extract shared withdrawal utils and fix status badge fallbacks

- extract formatDate, statusBadgeConfig, getRiskColor to shared utils
- use explicit unknown fallback for unrecognized status values
- add missing 'unknown' i18n keys for withdrawal status
This commit is contained in:
Fringg
2026-02-17 12:42:42 +03:00
parent 9b2742ff3a
commit 74c4c87ec0
6 changed files with 103 additions and 128 deletions

View File

@@ -1,79 +1,15 @@
import { useParams, useNavigate } from 'react-router';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';
import i18n from '../i18n';
import { withdrawalApi } from '../api/withdrawals';
import { AdminBackButton } from '../components/admin';
import { useCurrency } from '../hooks/useCurrency';
// Locale mapping for formatting
const localeMap: Record<string, string> = { ru: 'ru-RU', en: 'en-US', zh: 'zh-CN', fa: 'fa-IR' };
const formatDate = (date: string | null): string => {
if (!date) return '-';
const locale = localeMap[i18n.language] || 'ru-RU';
return new Date(date).toLocaleDateString(locale, {
day: '2-digit',
month: '2-digit',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
});
};
// Status badge config
const statusBadgeConfig: Record<string, { labelKey: string; color: string; bgColor: string }> = {
pending: {
labelKey: 'admin.withdrawals.status.pending',
color: 'text-yellow-400',
bgColor: 'bg-yellow-500/20',
},
approved: {
labelKey: 'admin.withdrawals.status.approved',
color: 'text-accent-400',
bgColor: 'bg-accent-500/20',
},
rejected: {
labelKey: 'admin.withdrawals.status.rejected',
color: 'text-error-400',
bgColor: 'bg-error-500/20',
},
completed: {
labelKey: 'admin.withdrawals.status.completed',
color: 'text-success-400',
bgColor: 'bg-success-500/20',
},
cancelled: {
labelKey: 'admin.withdrawals.status.cancelled',
color: 'text-dark-400',
bgColor: 'bg-dark-500/20',
},
};
// Risk score color helper
function getRiskColor(score: number): { text: string; bg: string; bar: string } {
if (score < 30)
return { text: 'text-success-400', bg: 'bg-success-500/20', bar: 'bg-success-500' };
if (score < 50) return { text: 'text-yellow-400', bg: 'bg-yellow-500/20', bar: 'bg-yellow-500' };
if (score < 70) return { text: 'text-orange-400', bg: 'bg-orange-500/20', bar: 'bg-orange-500' };
return { text: 'text-error-400', bg: 'bg-error-500/20', bar: 'bg-error-500' };
}
// Risk level badge color
function getRiskLevelColor(level: string): { text: string; bg: string } {
switch (level) {
case 'low':
return { text: 'text-success-400', bg: 'bg-success-500/20' };
case 'medium':
return { text: 'text-yellow-400', bg: 'bg-yellow-500/20' };
case 'high':
return { text: 'text-orange-400', bg: 'bg-orange-500/20' };
case 'critical':
return { text: 'text-error-400', bg: 'bg-error-500/20' };
default:
return { text: 'text-dark-400', bg: 'bg-dark-500/20' };
}
}
import {
formatDate,
getWithdrawalStatusBadge,
getRiskColor,
getRiskLevelColor,
} from '../utils/withdrawalUtils';
// Type for parsed risk analysis
interface RiskAnalysis {
@@ -152,7 +88,7 @@ export default function AdminWithdrawalDetail() {
);
}
const badge = statusBadgeConfig[detail.status] || statusBadgeConfig.cancelled;
const badge = getWithdrawalStatusBadge(detail.status);
const riskColor = getRiskColor(detail.risk_score);
// Parse risk analysis