eletrotupi / tcc/ commit / 60f9bbf

frontend/insights: rework the energy widget to an actual feed from the energy correlation

Pedro Lucas Porcellis porcellis@eletrotupi.com 29 days ago 60f9bbfa5397012b3ca230e93570dde25e425392
Parents: 61618fe
3 file(s) changed
  • frontend/app/(tabs)/insights.tsx +2 -10
  • frontend/components/insights/EnergySleepWidget.tsx +77 -0
  • frontend/components/insights/MoodTrendWidget.tsx +1 -1
frontend/app/(tabs)/insights.tsx
1 1
import { View, Text, ScrollView, StyleSheet } from "react-native";
2 2

3 3
import { ThemedText } from "@/components/misc/themed-text";
4 4
import { ThemedView } from "@/components/misc/themed-view";
5 5
import { ScreenLayout } from "@/components/ui/ScreenLayout";
▸ 3 unchanged lines
9 9
import { useThemeColor } from "@/hooks/use-theme-color";
10 10
import { Spacing, BorderRadius, Colors, Typography } from "@/constants/theme";
11 11
import { WeeklyResume } from "@/components/insights/WeeklyResume";
12 12
import { InsightCard, Highlight } from "@/components/insights/InsightCard";
13 13
import { MoodTrendWidget } from "@/components/insights/MoodTrendWidget";
14 +
import { EnergySleepWidget } from "@/components/insights/EnergySleepWidget";
14 15
import { TriggerPatternWidget } from "@/components/insights/TriggerPatternWidget";
15 16

16 17
export default function Insights() {
17 18
  const { user } = useAuth();
18 19

▸ 12 unchanged lines
31 32
      />
32 33

33 34
      <Section>
34 35
        <SectionHeader title="Indicadores" />
35 36

36 -
        <InsightCard
37 -
          category="Energia"
38 -
          body={
39 -
            <Text style={styles.insightBody}>
40 -
              Aumento de <Highlight>20%</Highlight> correlacionado ao sono.
41 -
            </Text>
42 -
          }
43 -
          metric="+20%"
44 -
          accent="green"
45 -
        />
37 +
        <EnergySleepWidget />
46 38

47 39
        <MoodTrendWidget />
48 40

49 41
        <TriggerPatternWidget />
50 42
      </Section>
▸ 88 unchanged lines
139 131
  insightMetric: {
140 132
    ...Typography.headlineLg,
141 133
    fontSize: 22,
142 134
  },
143 135
});
frontend/components/insights/EnergySleepWidget.tsx
@@ -0,0 +1,77 @@
1 + import React from "react";
2 + import { Text, StyleSheet, ActivityIndicator } from "react-native";
3 + import { Card } from "@/components/ui/Cards";
4 + import { ThemedText } from "@/components/misc/themed-text";
5 + import { useInsight } from "@/hooks/useInsights.queries";
6 + import { Spacing, Typography, Colors } from "@/constants/theme";
7 + import { InsightCard, MetricAccent } from "./InsightCard";
8 +
9 + export const EnergySleepWidget: React.FC = () => {
10 + const { data: insight, isLoading } = useInsight("ENERGY_SLEEP_CORRELATION");
11 +
12 + if (isLoading) {
13 + return (
14 + <Card style={styles.container}>
15 + <ActivityIndicator />
16 + </Card>
17 + );
18 + }
19 +
20 + if (!insight) {
21 + return (
22 + <InsightCard
23 + category="Energia"
24 + body={
25 + <Text style={styles.empty}>
26 + Registre sono e humor para ver correlações.
27 + </Text>
28 + }
29 + accent="neutral"
30 + metric="—"
31 + />
32 + );
33 + }
34 +
35 + const meta = insight.metadata as { correlationScore: number; sampleSize: number };
36 + const { label, accent } = resolveCorrelation(meta.correlationScore, meta.sampleSize);
37 +
38 + return (
39 + <InsightCard
40 + category="Energia"
41 + body={insight.body}
42 + metric={label}
43 + accent={accent}
44 + />
45 + );
46 + };
47 +
48 + function resolveCorrelation(
49 + score: number,
50 + sampleSize: number,
51 + ): { label: string; accent: MetricAccent } {
52 + const pct = Math.round(Math.abs(score) * 100);
53 + const lowData = sampleSize < 5;
54 +
55 + if (score > 0.6)
56 + return { label: lowData ? "Alta*" : `+${pct}%`, accent: "green" };
57 + if (score > 0.3)
58 + return { label: lowData ? "Média*" : `+${pct}%`, accent: "green" };
59 + if (score >= -0.3)
60 + return { label: "~0%", accent: "neutral" };
61 + return { label: `-${pct}%`, accent: "purple" };
62 + }
63 +
64 + const styles = StyleSheet.create({
65 + container: {
66 + flex: 1,
67 + padding: Spacing.cardGap,
68 + },
69 + label: {
70 + ...Typography.labelSm,
71 + opacity: 0.6,
72 + },
73 + empty: {
74 + color: Colors.light.lightSlateGray,
75 + marginTop: 4,
76 + },
77 + });
frontend/components/insights/MoodTrendWidget.tsx
1 1
import React from "react";
2 2
import { Text, StyleSheet, ActivityIndicator } from "react-native";
3 3
import { Card } from "@/components/ui/Cards";
4 4
import { useInsight } from "@/hooks/useInsights.queries";
5 5
import { Colors, Spacing, Typography } from "@/constants/theme";
▸ 18 unchanged lines
24 24
          <Text style={styles.empty}>
25 25
            Registre seu humor com mais frequência para acompanhar suas
26 26
            tendências.
27 27
          </Text>
28 28
        }
29 -
        accent="green"
29 +
        accent="neutral"
30 30
        metric="—"
31 31
      />
32 32
    );
33 33
  }
34 34

▸ 48 unchanged lines
83 83
  empty: {
84 84
    color: Colors.light.lightSlateGray,
85 85
    marginTop: 4,
86 86
  },
87 87
});