eletrotupi / tcc/ commit / 1205479

frontend: introduce a mood trending widget + rig with insights queries

Pedro Lucas Porcellis porcellis@eletrotupi.com · 4 months ago 1205479d3c1c2c9130f91b16355f7b8160d94048 Browse files
Parents f1583df
Changed files
1
Additions
+89
Deletions
0
/dev/null → frontend/components/insights/MoodTrendWidget.tsx
1 +
import React from "react";
2 +
import { Text, StyleSheet, ActivityIndicator } from "react-native";
3 +
import { Card } from "@/components/ui/Cards";
4 +
import { useInsight } from "@/hooks/useInsights.queries";
5 +
import { Colors, Spacing, Typography } from "@/constants/theme";
6 +
import { InsightCard } from "./InsightCard";
7 +

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

11 +
  if (isLoading) {
12 +
    return (
13 +
      <Card style={styles.container}>
14 +
        <ActivityIndicator />
15 +
      </Card>
16 +
    );
17 +
  }
18 +

19 +
  if (!insight) {
20 +
    return (
21 +
      <InsightCard
22 +
        category="Humor"
23 +
        body={
24 +
          <Text style={styles.empty}>
25 +
            Registre seu humor com mais frequência para acompanhar suas
26 +
            tendências.
27 +
          </Text>
28 +
        }
29 +
        accent="green"
30 +
        metric="—"
31 +
      />
32 +
    );
33 +
  }
34 +

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

41 +
  const metric = metadata?.delta
42 +
    ? `+${Math.round(metadata.delta * 100)}%`
43 +
    : "N/A";
44 +

45 +
  const accent = metadata?.delta
46 +
    ? metadata.delta < 0
47 +
      ? "green"
48 +
      : "purple"
49 +
    : "green";
50 +

51 +
  return (
52 +
    <InsightCard
53 +
      category="Humor"
54 +
      body={insight.body}
55 +
      metric={metric}
56 +
      accent={accent}
57 +
    />
58 +
  );
59 +
};
60 +

61 +
const styles = StyleSheet.create({
62 +
  container: {
63 +
    flex: 1,
64 +
    padding: Spacing.cardGap,
65 +
  },
66 +
  header: {
67 +
    flexDirection: "row",
68 +
    alignItems: "center",
69 +
    gap: 4,
70 +
    marginBottom: 5,
71 +
  },
72 +
  label: {
73 +
    ...Typography.labelSm,
74 +
    opacity: 0.6,
75 +
  },
76 +
  value: {
77 +
    ...Typography.labelSm,
78 +
    fontWeight: "600" as const,
79 +
  },
80 +
  delta: {
81 +
    ...Typography.labelSm,
82 +
    opacity: 0.6,
83 +
    marginTop: 2,
84 +
  },
85 +
  empty: {
86 +
    color: Colors.light.lightSlateGray,
87 +
    marginTop: 4,
88 +
  },
89 +
});