eletrotupi / tcc/ commit / 24fd7a7

frontend: flesh a mood entry log component

Pedro Lucas Porcellis porcellis@eletrotupi.com · 5 months ago 24fd7a77032477adf16f02f8321f475ab2c6ea8c Browse files
Parents bdfa463
Changed 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