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

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

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

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

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

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

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

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

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