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

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

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

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

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

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

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

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

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

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

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

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