import { useCallback, useEffect, useState } from "react"; import { Text, View } from "react-native"; import PieChart from "react-native-pie-chart"; import { getRiskLevel } from "@/utils/getRiskLevel"; interface RiskScoreIndicatorProps { value: number; maxValue?: number; size?: number; subtitle?: string; } /** * RiskScoreIndicator component displays a visual representation of risk level * using PieChart from react-native-pie-chart */ export const RiskScoreIndicator = ({ value, maxValue = 100, size = 100, subtitle, }: RiskScoreIndicatorProps) => { const { color } = getRiskLevel(value); const [animatedValue, setAnimatedValue] = useState(0.1); const finalValue = value > 0 ? value : 0.1; const animationSetup = useCallback(() => { const startTime = Date.now(); const duration = 1000; const animate = () => { const elapsed = Date.now() - startTime; const progress = Math.min(elapsed / duration, 1); const easeOut = (t: number) => 1 - Math.pow(1 - t, 2); const currentValue = 0.1 + easeOut(progress) * (finalValue - 0.1); setAnimatedValue(currentValue); if (progress < 1) { requestAnimationFrame(animate); } }; const animationFrame = requestAnimationFrame(animate); return () => cancelAnimationFrame(animationFrame); }, [finalValue]); useEffect(() => { animationSetup(); }, [animationSetup]); return ( 0 ? maxValue - animatedValue : 0.1, color: "white", }, { value: maxValue / 4, color: "transparent" }, ]} cover={{ radius: 0.8, color: "white" }} /> {Math.round(value)} {subtitle && {subtitle}} ); };