eletrotupi / tcc/ frontend/components/insights/InsightCard.tsx6a5c371ce1221ee4c61aa0cb3c665e3793580dc3
2.3 KB | 104 lines Raw
1
import React from "react";
2
import { View, Text, StyleSheet } from "react-native";
3

4
import { Card } from "@/components/ui/Cards";
5
import { Colors, Spacing, Typography } from "@/constants/theme";
6

7
export type MetricAccent = "green" | "purple" | "neutral";
8

9
const metricColor: Record<MetricAccent, string> = {
10
  green: Colors.light.tint,
11
  purple: Colors.light.accentDarkPurple,
12
  neutral: Colors.light.text,
13
};
14

15
interface InsightCardProps {
16
  category: string;
17
  body: React.ReactNode;
18
  metric: string;
19
  accent?: MetricAccent;
20
  footnote?: string;
21
}
22

23
export const InsightCard: React.FC<InsightCardProps> = ({
24
  category,
25
  body,
26
  metric,
27
  accent = "neutral",
28
  footnote,
29
}) => (
30
  <Card style={styles.cardContainer}>
31
    <View style={styles.inner}>
32
      <View style={styles.left}>
33
        <Text style={styles.category}>{category}</Text>
34
        {typeof body === "string" ? (
35
          <Text style={styles.body}>{body}</Text>
36
        ) : (
37
          body
38
        )}
39
      </View>
40
      <Text style={[styles.metric, { color: metricColor[accent] }]}>
41
        {metric}
42
      </Text>
43
    </View>
44
    {footnote && (
45
      <>
46
        <View style={styles.divider} />
47
        <Text style={styles.footnote}>{footnote}</Text>
48
      </>
49
    )}
50
  </Card>
51
);
52

53
interface HighlightProps {
54
  children: React.ReactNode;
55
  color?: string;
56
}
57

58
export const Highlight: React.FC<HighlightProps> = ({
59
  children,
60
  color = Colors.light.tint,
61
}) => <Text style={{ color, fontWeight: "700" }}>{children}</Text>;
62

63
const styles = StyleSheet.create({
64
  cardContainer: {
65
    padding: Spacing.cardGap,
66
  },
67
  inner: {
68
    flexDirection: "row",
69
    alignItems: "center",
70
    justifyContent: "space-between",
71
    gap: 12,
72
  },
73
  left: {
74
    flex: 1,
75
    gap: 6,
76
  },
77
  category: {
78
    fontSize: 11,
79
    fontWeight: "600",
80
    letterSpacing: 0.8,
81
    textTransform: "uppercase",
82
    color: Colors.light.textSecondary,
83
  },
84
  body: {
85
    ...Typography.bodyMd,
86
    color: Colors.light.text,
87
  },
88
  metric: {
89
    ...Typography.headlineLg,
90
    fontSize: 22,
91
  },
92
  divider: {
93
    height: StyleSheet.hairlineWidth,
94
    backgroundColor: Colors.light.divider,
95
    marginTop: Spacing.cardGap,
96
    marginBottom: 8,
97
  },
98
  footnote: {
99
    fontSize: 11,
100
    lineHeight: 15,
101
    color: Colors.light.textSecondary,
102
    fontStyle: "italic",
103
  },
104
});