frontend: introduce a mood trending widget + rig with insights queries
Pedro Lucas Porcellis porcellis@eletrotupi.com · 4 months ago
1205479d3c1c2c9130f91b16355f7b8160d94048 Browse filesParents
f1583dfChanged 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 +
});