mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-30 02:23:47 +00:00
fix: improve campaign stats, shared chart components, and i18n coverage
- Extract shared chart constants to constants/charts.ts - Add TREND_STYLES to stats/constants.ts for reuse - Fix useChartColors with MutationObserver for theme changes - Fix DailyChart date parsing to prevent timezone shift - Add truncate to StatCard value for overflow safety - Fix CampaignCard copy feedback inside try block - Add NaN validation and staleTime to AdminCampaignStats - Replace hardcoded strings with i18n keys in Referral page - Add missing i18n keys across all 4 locales (en, ru, zh, fa) - Add sales stats route to AdminPanel and App router
This commit is contained in:
@@ -56,12 +56,15 @@ export function CampaignCard({ campaign }: CampaignCardProps) {
|
||||
try {
|
||||
await copyToClipboard(url);
|
||||
haptic.notification('success');
|
||||
setCopiedLink(key);
|
||||
clearTimeout(copyTimerRef.current);
|
||||
copyTimerRef.current = setTimeout(
|
||||
() => setCopiedLink(null),
|
||||
PARTNER_STATS.COPY_FEEDBACK_MS,
|
||||
);
|
||||
} catch {
|
||||
haptic.notification('error');
|
||||
}
|
||||
setCopiedLink(key);
|
||||
clearTimeout(copyTimerRef.current);
|
||||
copyTimerRef.current = setTimeout(() => setCopiedLink(null), PARTNER_STATS.COPY_FEEDBACK_MS);
|
||||
},
|
||||
[haptic],
|
||||
);
|
||||
|
||||
@@ -42,7 +42,7 @@ export function DailyChart({ data, chartId, title, earningsLabel, countLabel }:
|
||||
data.map((item) => ({
|
||||
...item,
|
||||
earnings_display: item.earnings_kopeks / PARTNER_STATS.KOPEKS_DIVISOR,
|
||||
label: new Date(item.date).toLocaleDateString(i18n.language, {
|
||||
label: new Date(item.date + 'T00:00:00').toLocaleDateString(i18n.language, {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
}),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import type { PeriodComparison as PeriodComparisonType } from './types';
|
||||
import { TREND_STYLES } from './constants';
|
||||
import { PARTNER_STATS } from '../../constants/partner';
|
||||
import { useCurrency } from '../../hooks/useCurrency';
|
||||
|
||||
@@ -12,16 +13,6 @@ interface PeriodComparisonProps {
|
||||
comparisonLabel?: string;
|
||||
}
|
||||
|
||||
const TREND_ARROW_UP = '\u2191';
|
||||
const TREND_ARROW_DOWN = '\u2193';
|
||||
const TREND_ARROW_STABLE = '\u2192';
|
||||
|
||||
const TREND_STYLES = {
|
||||
up: { arrow: TREND_ARROW_UP, className: 'text-success-400' },
|
||||
down: { arrow: TREND_ARROW_DOWN, className: 'text-error-400' },
|
||||
stable: { arrow: TREND_ARROW_STABLE, className: 'text-dark-400' },
|
||||
} as const;
|
||||
|
||||
interface TrendBadgeProps {
|
||||
trend: 'up' | 'down' | 'stable';
|
||||
percent: number;
|
||||
|
||||
@@ -21,7 +21,9 @@ export function StatCard({
|
||||
{icon}
|
||||
<span>{label}</span>
|
||||
</div>
|
||||
<div className={`mt-1 text-base font-semibold sm:text-lg ${valueClassName}`}>{value}</div>
|
||||
<div className={`mt-1 truncate text-base font-semibold sm:text-lg ${valueClassName}`}>
|
||||
{value}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
5
src/components/stats/constants.ts
Normal file
5
src/components/stats/constants.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export const TREND_STYLES = {
|
||||
up: { arrow: '\u2191', className: 'text-success-400' },
|
||||
down: { arrow: '\u2193', className: 'text-error-400' },
|
||||
stable: { arrow: '\u2192', className: 'text-dark-400' },
|
||||
} as const;
|
||||
Reference in New Issue
Block a user