2025-08-08 19:05:43 +08:00

162 lines
5.6 KiB
TypeScript

import ImgTotalSvg from "@/assets/icons/svg/imgTotalWhite.svg";
import LiveTotalSvg from "@/assets/icons/svg/liveTotal.svg";
import PeopleSvg from "@/assets/icons/svg/people.svg";
import TimeTotalSvg from "@/assets/icons/svg/timeTotalWhite.svg";
import VideoTotalSvg from "@/assets/icons/svg/videoTotalWhite.svg";
import { BlurView } from "expo-blur";
import { Image, StyleProp, StyleSheet, View, ViewStyle } from "react-native";
import { ThemedText } from "../ThemedText";
interface CategoryProps {
title: string;
data: { title: string, number: { s: number, m: number, h: number } | number }[];
bgSvg: string | null;
style?: StyleProp<ViewStyle>;
width: number;
}
const TimeUnit = ({ value, unit }: { value: number; unit: string }) => (
value > 0 && (
<>
<ThemedText style={styles.itemNumber}>{value}</ThemedText>
<ThemedText style={[styles.itemNumber, { fontSize: 10 }]}>{unit}</ThemedText>
</>
)
);
const CategoryComponent = ({ title, data, bgSvg, style, width }: CategoryProps) => {
const renderTimeDisplay = (time: { s: number; m: number; h: number }) => {
const { h, m, s } = time;
const showSeconds = s > 0 || (s === 0 && m === 0 && h === 0);
return (
<ThemedText style={{ flexDirection: 'row', alignItems: 'flex-end', gap: 2 }}>
<TimeUnit value={h} unit="h" />
<TimeUnit value={m} unit="m" />
{showSeconds && (
<>
<ThemedText style={styles.itemNumber}>{s}</ThemedText>
<ThemedText style={[styles.itemNumber, { fontSize: 10 }]}>s</ThemedText>
</>
)}
</ThemedText>
);
};
return (
<View style={[styles.container, style, { width: width * 0.73 }]}>
<View style={styles.backgroundContainer}>
<Image
source={bgSvg !== "" && bgSvg !== null ? { uri: bgSvg } : require('@/assets/images/png/owner/people.png')}
style={{
width: "100%",
height: "100%",
resizeMode: "cover",
}}
/>
<BlurView intensity={10} style={styles.overlay} />
</View>
<View style={styles.content}>
{data.map((item, index) => (
<View style={styles.item} key={index}>
<View style={{ flexDirection: 'row', alignItems: 'center', gap: index == 1 ? 12 : 16, flex: 3 }}>
<View>
{
index == 0 ? <VideoTotalSvg width={20} height={20} /> : index == 1 ? <ImgTotalSvg width={24} height={24} /> : index == 2 ? <TimeTotalSvg width={20} height={20} /> : <LiveTotalSvg width={20} height={20} />
}
</View>
<ThemedText style={styles.itemTitle}>{item.title}</ThemedText>
</View>
<View style={{ alignSelf: 'flex-start', flex: 1 }}>
{item?.title === "Length" ? (
typeof item.number === 'object' ? (
renderTimeDisplay(item.number)
) : (
<ThemedText style={[styles.itemNumber]}>{item.number}</ThemedText>
)
) : (
<ThemedText style={[styles.itemNumber]}>
{typeof item.number === 'number' ? item.number : 0}
</ThemedText>
)}
</View>
</View>
))}
<View style={styles.titleContent}>
<ThemedText style={styles.title}>{title}</ThemedText>
<PeopleSvg />
</View>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
borderRadius: 32,
overflow: 'hidden',
position: 'relative',
aspectRatio: 1,
},
backgroundContainer: {
...StyleSheet.absoluteFillObject,
width: "100%",
height: "100%",
},
overlay: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'rgba(0, 0, 0, 0.4)',
backdropFilter: 'blur(5px)',
},
content: {
padding: 32,
paddingRight: 16,
justifyContent: "space-between",
flex: 1
},
titleContent: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
position: 'relative',
width: '100%',
paddingVertical: 4
},
title: {
color: 'white',
fontSize: 20,
fontWeight: '700',
textShadowColor: 'rgba(0, 0, 0, 0.5)',
textShadowOffset: { width: 1, height: 1 },
textShadowRadius: 2,
position: 'absolute',
textAlign: 'center',
width: '100%',
zIndex: 1,
},
item: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
paddingVertical: 16,
width: '100%',
},
itemTitle: {
color: 'white',
fontSize: 22,
fontWeight: '700',
marginLeft: 16,
flex: 1,
},
itemNumber: {
color: 'white',
fontSize: 28,
lineHeight: 30,
fontWeight: '700',
textAlign: 'left',
flex: 1,
}
});
export default CategoryComponent;