Files
2025-11-02 10:08:56 +01:00

102 lines
2.5 KiB
TypeScript

import { useMemo } from "react";
import { View } from "react-native";
import { Text } from "react-native-paper";
import { RiskEnum } from "@/constants/riskEnum";
import { SizeEnum } from "@/constants/sizeEnum";
type RiskData = {
bars: number;
color: string;
};
const RISK_CONFIG: Record<string, RiskData> = {
[RiskEnum.HIGH_RISK]: { bars: 3, color: "bg-highRisk" },
[RiskEnum.MODERATE_RISK]: { bars: 2, color: "bg-mediumRisk" },
[RiskEnum.LOW_RISK]: { bars: 1, color: "bg-lowRisk" },
};
const SIZE_CONFIG = {
[SizeEnum.Small]: {
width: "w-1",
heights: ["h-2", "h-3", "h-4"],
},
[SizeEnum.Moderate]: {
width: "w-1.5",
heights: ["h-3", "h-4", "h-5"],
},
[SizeEnum.Regular]: {
width: "w-1.5",
heights: ["h-3", "h-4", "h-5"],
},
[SizeEnum.Large]: {
width: "w-2",
heights: ["h-4", "h-6", "h-8"],
},
};
interface RiskIndicatorProps {
risk: RiskEnum | string;
showLabel?: boolean;
size?: SizeEnum;
}
/**
* RiskIndicator component displays a visual representation of risk level
* using color bars similar to a pie chart
*/
export const RiskIndicator = ({
risk,
showLabel = false,
size = SizeEnum.Moderate,
}: RiskIndicatorProps) => {
const { filledBars, barColor, barSizes } = useMemo(() => {
const riskData = RISK_CONFIG[risk] || {
bars: 0,
color: "bg-mediumGray",
};
const sizeData = SIZE_CONFIG[size] || SIZE_CONFIG[SizeEnum.Moderate];
return {
filledBars: riskData.bars,
barColor: riskData.color,
barSizes: {
width: sizeData.width,
heights: sizeData.heights,
},
};
}, [risk, size]);
return (
<View className="flex-row items-center">
<View className="flex-row items-end gap-0.5 mr-1">
<View
className={`${barSizes.width} ${barSizes.heights[0]} rounded-sm ${
filledBars >= 1 ? barColor : "bg-mediumGray"
}`}
/>
<View
className={`${barSizes.width} ${barSizes.heights[1]} rounded-sm ${
filledBars >= 2 ? barColor : "bg-mediumGray"
}`}
/>
<View
className={`${barSizes.width} ${barSizes.heights[2]} rounded-sm ${
filledBars >= 3 ? barColor : "bg-mediumGray"
}`}
/>
</View>
{showLabel && (
<Text className="text-xs ml-1">
{typeof risk === "string"
? risk.charAt(0).toUpperCase() + risk.slice(1).toLowerCase()
: risk}
</Text>
)}
</View>
);
};