eletrotupi / tcc/ frontend/components/ui/MoodTrendWidget.tsx2f22c81cbb1594f660a5ff704a81f495413baf9b
2.7 KB | 118 lines Raw
1
import React from "react";
2
import { View, StyleSheet, ActivityIndicator } from "react-native";
3
import { Text } from "@/components/ui/Text";
4
import { Ionicons } from "@expo/vector-icons";
5
import { Card } from "@/components/ui/Cards";
6
import { useInsight } from "@/hooks/useInsights.queries";
7
import { useThemeColor } from "@/hooks/use-theme-color";
8
import { Typography } from "@/constants/theme";
9

10
export const MoodTrendWidget: React.FC = () => {
11
  const { data: insight, isLoading } = useInsight("MOOD_TREND");
12

13
  const successColor = useThemeColor({}, "success");
14
  const errorColor = useThemeColor({}, "danger");
15
  const textSecondary = useThemeColor({}, "textSecondary");
16

17
  if (isLoading) {
18
    return (
19
      <Card style={styles.container}>
20
        <ActivityIndicator />
21
      </Card>
22
    );
23
  }
24

25
  if (!insight) {
26
    return (
27
      <Card style={styles.container}>
28
        <Text style={styles.label}>Humor</Text>
29
        <Text style={styles.empty}>
30
          Registre mais humores para ver tendências.
31
        </Text>
32
      </Card>
33
    );
34
  }
35

36
  const meta = insight.metadata as {
37
    delta: number;
38
    dominantMood: string;
39
    avgEnergy: number;
40
  };
41

42
  const isPositive = meta.delta > 0;
43
  const isNeutral = meta.delta === 0;
44
  const deltaColor = isNeutral
45
    ? textSecondary
46
    : isPositive
47
      ? successColor
48
      : errorColor;
49
  const iconName = isNeutral
50
    ? "remove-outline"
51
    : isPositive
52
      ? "trending-up-outline"
53
      : "trending-down-outline";
54

55
  return (
56
    <Card style={styles.container}>
57
      <View style={styles.header}>
58
        <Ionicons name="partly-sunny-outline" size={14} color={textSecondary} />
59
        <Text style={styles.label}>Humor</Text>
60
      </View>
61

62
      <View style={styles.valueRow}>
63
        <Text style={styles.value}>
64
          {MOOD_LABEL[meta.dominantMood] ?? meta.dominantMood}
65
        </Text>
66
        <Ionicons name={iconName} size={18} color={deltaColor} />
67
      </View>
68

69
      {!isNeutral && (
70
        <Text style={[styles.delta, { color: deltaColor }]}>
71
          {isPositive ? "+" : ""}
72
          {meta.delta}% vs período anterior
73
        </Text>
74
      )}
75
    </Card>
76
  );
77
};
78

79
const MOOD_LABEL: Record<string, string> = {
80
  GREAT: "Ótimo",
81
  GOOD: "Bom",
82
  NEUTRAL: "Neutro",
83
  SAD: "Triste",
84
  ANGRY: "Irritado",
85
};
86

87
const styles = StyleSheet.create({
88
  container: {
89
    flex: 1,
90
  },
91
  header: {
92
    flexDirection: "row",
93
    alignItems: "center",
94
    gap: 4,
95
    marginBottom: 10,
96
  },
97
  label: {
98
    ...Typography.labelXs,
99
    opacity: 0.6,
100
  },
101
  valueRow: {
102
    flexDirection: "row",
103
    alignItems: "center",
104
    justifyContent: "space-between",
105
  },
106
  value: {
107
    ...Typography.bodyLg,
108
  },
109
  delta: {
110
    ...Typography.labelSm,
111
    marginTop: 2,
112
  },
113
  empty: {
114
    ...Typography.labelXs,
115
    opacity: 0.5,
116
    marginTop: 4,
117
  },
118
});