frontend: flesh a mood entry log component
Pedro Lucas Porcellis porcellis@eletrotupi.com · 5 months ago
24fd7a77032477adf16f02f8321f475ab2c6ea8c Browse filesParents
bdfa463Changed files
1
Additions
+105
Deletions
0
/dev/null → frontend/components/ui/MoodEntryLog.tsx
1 +
import { format, isToday, isYesterday } from 'date-fns';
2 +
import { ptBR } from 'date-fns/locale';
3 +
import { StyleSheet, Text, View } from 'react-native';
4 +
5 +
import { Card } from '@/components/ui/Cards';
6 +
import { Badge } from '@/components/ui/Badge';
7 +
import { getMood } from '@/constants/moods';
8 +
import { Colors, Spacing } from '@/constants/theme';
9 +
import { MoodEntry } from '@/lib/api';
10 +
11 +
type TimeBadgeVariant = 'morning' | 'afternoon' | 'night' | 'latenight';
12 +
13 +
const TIME_BADGES: Record<TimeBadgeVariant, { label: string; variant: string; }> = {
14 +
morning: { label: 'Manhã', variant: 'green' },
15 +
afternoon: { label: 'Tarde', variant: 'orange' },
16 +
night: { label: 'Noite', variant: 'blue' },
17 +
latenight: { label: 'Madrugada', variant: 'purple' },
18 +
};
19 +
20 +
function getTimeBadge(date: Date) {
21 +
const h = date.getHours();
22 +
if (h >= 6 && h < 12) return TIME_BADGES.morning;
23 +
if (h >= 12 && h < 18) return TIME_BADGES.afternoon;
24 +
if (h >= 18 && h < 24) return TIME_BADGES.night;
25 +
return TIME_BADGES.latenight;
26 +
}
27 +
28 +
function formatMoment(date: Date): string {
29 +
if (isToday(date)) return `Hoje às ${format(date, "HH'h'mm")}`;
30 +
if (isYesterday(date)) return `Ontem às ${format(date, "HH'h'mm")}`;
31 +
return format(date, "d 'de' MMM 'às' HH'h'mm", { locale: ptBR });
32 +
}
33 +
34 +
interface MoodEntryLogProps {
35 +
entry: MoodEntry;
36 +
}
37 +
38 +
const MoodEntryLog = ({ entry }: MoodEntryLogProps) => {
39 +
const moment = new Date(entry.moment);
40 +
const moodDef = getMood(entry.selectedMood.toLowerCase());
41 +
const badge = getTimeBadge(moment);
42 +
43 +
return (
44 +
<Card style={styles.card}>
45 +
<View style={styles.moodIcon}>
46 +
<Text style={styles.moodIconEmoji}>{moodDef?.icon ?? '😐'}</Text>
47 +
</View>
48 +
49 +
<View style={styles.moodBlock}>
50 +
<Text style={styles.title} numberOfLines={1}>
51 +
{moodDef?.label ?? entry.selectedMood}
52 +
</Text>
53 +
54 +
<Text style={styles.subtitle} numberOfLines={1}>
55 +
{formatMoment(moment)}
56 +
</Text>
57 +
</View>
58 +
59 +
<Badge
60 +
label={badge.label}
61 +
variant={badge.variant}
62 +
/>
63 +
</Card>
64 +
);
65 +
}
66 +
67 +
const styles = StyleSheet.create({
68 +
card: {
69 +
flexDirection: "row",
70 +
alignItems: "center",
71 +
gap: 14,
72 +
overflow: "hidden",
73 +
padding: Spacing.cardGap
74 +
},
75 +
moodIcon: {
76 +
width: 48,
77 +
height: 48,
78 +
alignItems: "center",
79 +
justifyContent: "center",
80 +
flexShrink: 0,
81 +
},
82 +
moodIconEmoji: {
83 +
fontSize: 26,
84 +
},
85 +
// Text
86 +
moodBlock: {
87 +
flex: 1,
88 +
minWidth: 0,
89 +
},
90 +
title: {
91 +
fontSize: 15,
92 +
fontWeight: "700",
93 +
color: Colors.light.text,
94 +
letterSpacing: -0.2,
95 +
marginBottom: 3,
96 +
},
97 +
subtitle: {
98 +
fontSize: 12.5,
99 +
fontWeight: "500",
100 +
color: Colors.light.textSecondary,
101 +
letterSpacing: 0.1,
102 +
},
103 +
});
104 +
105 +
export default MoodEntryLog