frontend: split time utilities from mood entry log and fetch it

Pedro Lucas Porcellis porcellis@eletrotupi.com 1 month ago 5c34c8e5782048b72506e8cb8b1c65eb7af38e16
Parents: f4ff3fb
3 file(s) changed
  • frontend/app/(tabs)/new/index.tsx +20 -70
  • frontend/components/ui/MoodEntryLog.tsx +5 -24
  • frontend/lib/utils/time.ts +25 -0
frontend/app/(tabs)/new/index.tsx
@@ -2,7 +2,8 @@ import { useEffect, useState } from 'react';
2 2 import {
3 3 StyleSheet,
4 4 View,
5 - Text
5 + Text,
6 + ActivityIndicator
6 7 } from 'react-native';
7 8
8 9 import { ThemedText } from '@/components/misc/themed-text';
@@ -16,75 +17,25 @@ import { Button } from '@/components/ui/Button';
16 17 import { Section, SectionHeader } from '@/components/ui/Sections';
17 18 import { MoodSelector } from '@/components/ui/EmojiSelectors';
18 19 import { Typography, Spacing, Shadows, Colors } from '@/constants/theme';
19 - import { useThemeColor } from '@/hooks/use-theme-color';
20 20 import { router } from 'expo-router';
21 21 import {
22 22 MoodDefinition, MOODS
23 23 } from '@/constants/moods'
24 24
25 - const MoodEntryLog = ({ mood: MoodDefinition, moment: Date }) => {
26 - const styles = StyleSheet.create({
27 - card: {
28 - flexDirection: "row",
29 - alignItems: "center",
30 - gap: 14,
31 - overflow: "hidden",
32 - padding: Spacing.cardGap
33 - },
34 - moodIcon: {
35 - width: 48,
36 - height: 48,
37 - alignItems: "center",
38 - justifyContent: "center",
39 - flexShrink: 0,
40 - },
41 - moodIconEmoji: {
42 - fontSize: 26,
43 - },
44 - // Text
45 - moodBlock: {
46 - flex: 1,
47 - minWidth: 0,
48 - },
49 - title: {
50 - fontSize: 15,
51 - fontWeight: "700",
52 - color: Colors.light.text,
53 - letterSpacing: -0.2,
54 - marginBottom: 3,
55 - },
56 - subtitle: {
57 - fontSize: 12.5,
58 - fontWeight: "500",
59 - color: Colors.light.textSecondary,
60 - letterSpacing: 0.1,
61 - },
62 - });
63 -
64 - return (
65 - <Card style={styles.card}>
66 - <View style={styles.moodIcon}>
67 - <Text style={styles.moodIconEmoji}>😀</Text>
68 - </View>
25 + import {
26 + useThemeColor,
27 + useMoodEntries
28 + } from '@/hooks';
69 29
70 - <View style={styles.moodBlock}>
71 - <Text style={styles.title} numberOfLines={1}>
72 - Neutro
73 - </Text>
74 - <ThemedText style={styles.subtitle} numberOfLines={1}>
75 - Ontem às 10h
76 - </ThemedText>
77 - </View>
78 -
79 - <Badge label="Manhã" />
80 - </Card>
81 - );
82 - }
30 + import MoodEntryLog from '@/components/ui/MoodEntryLog';
83 31
84 32 export default function New() {
85 33 const { user } = useAuth();
86 34 const [mood, setMood] = useState<string>('good');
87 - const [isLoading, setIsLoading] = useState<boolean>(false);
35 + const { data, isLoading } = useMoodEntries({ limit: 5 });
36 + const recentEntries = data?.entries ?? [];
37 +
38 + console.log("entries: ", data, recentEntries)
88 39
89 40 const initQuickRegister = () => {
90 41 // TODO: Set down on camelCase vs kebab case
@@ -124,7 +75,6 @@
124 75 <Button
125 76 title="Salvar Humor"
126 77 onPress={initQuickRegister}
127 - loading={isLoading}
128 78 style={styles.quickRegisterButton}
129 79 />
130 80 </Col>
@@ -145,15 +95,15 @@
145 95 <Section>
146 96 <SectionHeader title="Registros recentes" />
147 97
148 - <MoodEntryLog
149 - mood="sad"
150 - moment={new Date()}
151 - />
152 -
153 - <MoodEntryLog
154 - mood="good"
155 - moment={new Date()}
156 - />
98 + {isLoading ? (
99 + <ActivityIndicator />
100 + ) : (
101 + <Col gap={8}>
102 + {recentEntries.map((entry) => (
103 + <MoodEntryLog key={entry.id} entry={entry} />
104 + ))}
105 + </Col>
106 + )}
157 107 </Section>
158 108 </ScreenLayout>
159 109 )
frontend/components/ui/MoodEntryLog.tsx
@@ -1,35 +1,14 @@
1 1 import { format, isToday, isYesterday } from 'date-fns';
2 2 import { ptBR } from 'date-fns/locale';
3 3 import { StyleSheet, Text, View } from 'react-native';
4 + import { router } from 'expo-router';
4 5
5 6 import { Card } from '@/components/ui/Cards';
6 7 import { Badge } from '@/components/ui/Badge';
7 8 import { getMood } from '@/constants/moods';
8 9 import { Colors, Spacing } from '@/constants/theme';
9 10 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 - }
11 + import { getTimeBadge, formatMoment } from '@/lib/utils/time';
33 12
34 13 interface MoodEntryLogProps {
35 14 entry: MoodEntry;
@@ -40,8 +19,10 @@ const moment = new Date(entry.moment);
40 19 const moodDef = getMood(entry.selectedMood.toLowerCase());
41 20 const badge = getTimeBadge(moment);
42 21
22 + const handlePress = () => router.push(`/entry/${entry.id}`);
23 +
43 24 return (
44 - <Card style={styles.card}>
25 + <Card style={styles.card} onPress={handlePress}>
45 26 <View style={styles.moodIcon}>
46 27 <Text style={styles.moodIconEmoji}>{moodDef?.icon ?? '😐'}</Text>
47 28 </View>
frontend/lib/utils/time.ts
@@ -0,0 +1,25 @@
1 + import { format, isToday, isYesterday } from 'date-fns';
2 + import { ptBR } from 'date-fns/locale';
3 +
4 + type TimeBadgeVariant = 'morning' | 'afternoon' | 'night' | 'latenight';
5 +
6 + export const TIME_BADGES: Record<TimeBadgeVariant, { label: string; backgroundColor: string; color: string }> = {
7 + morning: { label: 'Manhã', backgroundColor: '#dcfce7', color: '#16a34a' },
8 + afternoon: { label: 'Tarde', backgroundColor: '#f1f5f9', color: '#475569' },
9 + night: { label: 'Noite', backgroundColor: '#dbeafe', color: '#1d4ed8' },
10 + latenight: { label: 'Madrugada', backgroundColor: '#f3e8ff', color: '#7e22ce' },
11 + };
12 +
13 + export const getTimeBadge = (date: Date) => {
14 + const h = date.getHours();
15 + if (h >= 6 && h < 12) return TIME_BADGES.morning;
16 + if (h >= 12 && h < 18) return TIME_BADGES.afternoon;
17 + if (h >= 18 && h < 24) return TIME_BADGES.night;
18 + return TIME_BADGES.latenight;
19 + }
20 +
21 + export const formatMoment = (date: Date): string => {
22 + if (isToday(date)) return `Hoje às ${format(date, "HH'h'mm")}`;
23 + if (isYesterday(date)) return `Ontem às ${format(date, "HH'h'mm")}`;
24 + return format(date, "d 'de' MMM 'às' HH'h'mm", { locale: ptBR });
25 + }