File size: 2,207 Bytes
0bedb61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import React, { useEffect } from 'react';
import { StyleSheet, Text, View } from 'react-native';
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withTiming,
  withDelay,
  interpolate,
  Easing,
} from 'react-native-reanimated';
import { BlurView } from 'expo-blur';
import { COLORS } from '../constants/colors';

const AnimatedBlurView = Animated.createAnimatedComponent(BlurView);

interface StatCardProps {
  label: string;
  value: string | number;
  icon?: string;
  delay?: number;
  color?: string;
  compact?: boolean;
}

export const StatCard: React.FC<StatCardProps> = ({

  label,

  value,

  icon,

  delay = 0,

  color = COLORS.primary,

  compact = false,

}) => {
  const progress = useSharedValue(0);

  useEffect(() => {
    progress.value = withDelay(
      delay,
      withTiming(1, { duration: 500, easing: Easing.out(Easing.cubic) })
    );
  }, []);

  const animStyle = useAnimatedStyle(() => ({
    opacity: progress.value,
    transform: [
      { translateY: interpolate(progress.value, [0, 1], [15, 0]) },
    ],
  }));

  return (
    <AnimatedBlurView tint="dark" intensity={40} style={[styles.container, compact && styles.compact, animStyle]}>

      {icon && <Text style={styles.icon}>{icon}</Text>}

      <Text style={[styles.value, { color }]}>{value}</Text>

      <Text style={styles.label}>{label}</Text>

    </AnimatedBlurView>
  );
};

const styles = StyleSheet.create({
  container: {
    backgroundColor: 'transparent',
    borderRadius: 16,
    borderWidth: 1,
    borderColor: 'rgba(255,255,255,0.08)',
    padding: 14,
    alignItems: 'center',
    justifyContent: 'center',
    minWidth: 90,
    flex: 1,
    margin: 4,
    overflow: 'hidden',
  },
  compact: {
    padding: 10,
  },
  icon: {
    fontSize: 20,
    marginBottom: 4,
  },
  value: {
    fontFamily: 'Outfit_900Black',
    fontSize: 22,
    marginBottom: 2,
    fontVariant: ['tabular-nums'],
    letterSpacing: 1,
  },
  label: {
    fontFamily: 'Outfit_700Bold',
    fontSize: 9,
    color: COLORS.textDim,
    textTransform: 'uppercase',
    letterSpacing: 1.5,
    textAlign: 'center',
  },
});