import { useI18n } from '@/hooks/useI18n'; import type { RankingItem } from '@/store/challengesSlice'; import { Ionicons } from '@expo/vector-icons'; import { Image } from 'expo-image'; import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; type ChallengeRankingItemProps = { item: RankingItem; index: number; showDivider?: boolean; unit?: string; }; const formatNumber = (value: number): string => { if (Number.isInteger(value)) { return value.toString(); } return value.toFixed(2).replace(/0+$/, '').replace(/\.$/, ''); }; export function ChallengeRankingItem({ item, index, showDivider = false, unit }: ChallengeRankingItemProps) { const { t } = useI18n(); const formatMinutes = (value: number): string => { const safeValue = Math.max(0, Math.round(value)); const hours = safeValue / 60; return `${hours.toFixed(1)} ${t('challengeDetail.ranking.hour')}`; }; const formatValueWithUnit = (value: number | undefined, unit?: string): string | undefined => { if (typeof value !== 'number' || Number.isNaN(value)) { return undefined; } if (unit === 'min') { return formatMinutes(value); } const formatted = formatNumber(value); return unit ? `${formatted} ${unit}` : formatted; }; const reportedLabel = formatValueWithUnit(item.todayReportedValue, unit); const targetLabel = formatValueWithUnit(item.todayTargetValue, unit); const progressLabel = reportedLabel && targetLabel ? `${t('challengeDetail.ranking.today')} ${reportedLabel} / ${targetLabel}` : reportedLabel ? `${t('challengeDetail.ranking.today')} ${reportedLabel}` : targetLabel ? `${t('challengeDetail.ranking.todayGoal')} ${targetLabel}` : undefined; return ( {index + 1} {item.avatar ? ( ) : ( )} {item.name} {item.metric} {progressLabel ? ( {progressLabel} ) : null} {item.badge ? {item.badge} : null} ); } const styles = StyleSheet.create({ rankingRow: { flexDirection: 'row', alignItems: 'center', paddingVertical: 12, paddingHorizontal: 18, }, rankingRowDivider: { borderTopWidth: StyleSheet.hairlineWidth, borderTopColor: '#E5E7FF', }, rankingOrderCircle: { width: 32, height: 32, borderRadius: 16, alignItems: 'center', justifyContent: 'center', backgroundColor: '#EEF0FF', marginRight: 12, }, rankingOrder: { fontSize: 15, fontWeight: '700', color: '#4F5BD5', }, rankingAvatar: { width: 44, height: 44, borderRadius: 22, marginRight: 14, backgroundColor: '#EEF0FF', }, rankingAvatarPlaceholder: { width: 44, height: 44, borderRadius: 22, marginRight: 14, alignItems: 'center', justifyContent: 'center', backgroundColor: '#EEF0FF', }, rankingInfo: { flex: 1, }, rankingName: { fontSize: 15, fontWeight: '700', color: '#1c1f3a', }, rankingMetric: { marginTop: 4, fontSize: 12, color: '#6f7ba7', }, rankingProgress: { marginTop: 2, fontSize: 10, color: '#8a94c1', }, rankingBadge: { fontSize: 12, color: '#A67CFF', fontWeight: '700', }, });