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 filesParents
61618feChanged 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
});