eletrotupi / tcc/ commit / 60f9bbf

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

Pedro Lucas Porcellis porcellis@eletrotupi.com · 4 months ago 60f9bbfa5397012b3ca230e93570dde25e425392 Browse files
Parents 61618fe
Changed files
3
Additions
+80
Deletions
-11
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";
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

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>
139 131
  insightMetric: {
140 132
    ...Typography.headlineLg,
141 133
    fontSize: 22,
142 134
  },
143 135
});
/dev/null → frontend/components/insights/EnergySleepWidget.tsx
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";
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

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