frontend/insights: rework the energy widget to an actual feed from the energy correlation
Parents:
61618fe3 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
});