eletrotupi / tcc/ frontend/components/history/MoodHistoryCard.tsxd9717b316a8c7ad13ff9c659e8507cc1f9528e12
3.4 KB | 112 lines Raw
1
// components/history/cards/MoodHistoryCard.tsx
2
import { View, StyleSheet } from 'react-native';
3
import { Text } from '@/components/ui/Text';
4
import { MaterialIcons } from '@expo/vector-icons';
5
import { Card } from '@/components/ui/Cards';
6
import { Badge } from '@/components/ui/Badge';
7
import type { HistoryCard } from '@/lib/history/types';
8
import type { MoodEntry } from '@/lib/api';
9
import { Spacing } from '@/constants/theme';
10
import { getMood } from '@/constants/moods';
11
import { format } from 'date-fns';
12
import { router } from 'expo-router';
13

14
function inferBadge(anxiety: number, stress: number, energy: number) {
15
  if (anxiety >= 7) return { label: 'Ansiedade alta', variant: 'red'    } as const
16
  if (stress  >= 7) return { label: 'Estresse alto',  variant: 'orange' } as const
17
  if (energy  <= 3) return { label: 'Energia baixa',  variant: 'yellow' } as const
18
  if (energy  >= 7) return { label: 'Energia alta', variant: 'green' } as const
19

20
  return undefined
21
}
22

23
// TODO: Perhaps we could move these into the constants instead and use it everywhere?
24
const MOOD_META: Record<string, { color: string; bg: string }> = {
25
  GREAT:   { color: '#16a34a', bg: '#dcfce7' },
26
  GOOD:    { color: '#2563eb', bg: '#dbeafe' },
27
  NEUTRAL: { color: '#d97706', bg: '#fef3c7' },
28
  SAD:     { color: '#7c3aed', bg: '#ede9fe' },
29
  ANGRY:   { color: '#dc2626', bg: '#fee2e2' },
30
}
31

32
type Props = { card: HistoryCard & { raw: MoodEntry } }
33

34
export function MoodHistoryCard({ card }: Props) {
35
  const meta = MOOD_META[card.raw.selectedMood] ?? MOOD_META.NEUTRAL
36
  const badge = inferBadge(card.raw.anxietyLevel, card.raw.stressLevel, card.raw.energyLevel)
37
  const time = format(card.timestamp, 'HH:mm')
38
  const moodDef = getMood(card.raw.selectedMood.toLowerCase());
39

40
  return (
41
    <Card style={styles.card} onPress={() => router.push(`/entry/${card.raw.id}`)}>
42
      <View style={styles.row}>
43
        <View style={[styles.iconWrap, { backgroundColor: meta.bg }]}>
44
          <Text style={styles.moodIconEmoji}>{moodDef?.icon ?? '😐'}</Text>
45

46
          {false && (<MaterialIcons name={meta.icon} size={22} color={meta.color} />)}
47
        </View>
48
        <View style={styles.body}>
49
          <View style={styles.titleRow}>
50
            <Text style={styles.title}>{moodDef.label}</Text>
51
            <Text style={styles.time}>{time}</Text>
52
          </View>
53
          {card.raw.annotation ? (
54
            <Text style={styles.summary} numberOfLines={2}>
55
              {card.raw.annotation?.trim()}
56
            </Text>
57
          ) : null}
58
          {(badge ? (<Badge label={badge.label} variant={badge.variant} style={styles.badge}/>) : null)}
59
        </View>
60
      </View>
61
    </Card>
62
  )
63
}
64

65
const styles = StyleSheet.create({
66
  card: {
67
    padding: Spacing.cardGap
68
  },
69
  row: {
70
    flexDirection: 'row',
71
    alignItems: 'flex-start',
72
    gap: 12
73
  },
74
  iconWrap: {
75
    width: 40,
76
    height: 40,
77
    borderRadius: 20,
78
    alignItems: 'center',
79
    justifyContent: 'center',
80
    marginTop: 1
81
  },
82
  body: { flex: 1 },
83
  titleRow: {
84
    flexDirection: 'row',
85
    justifyContent: 'space-between',
86
    alignItems: 'center',
87
    marginBottom: 2
88
  },
89
  title: {
90
    fontSize: 15,
91
    fontWeight: '600'
92
  },
93
  moodIconEmoji: {
94
    fontSize: 26,
95
  },
96
  time: {
97
    fontSize: 13,
98
    opacity: 0.45
99
  },
100
  summary: {
101
    fontSize: 13,
102
    opacity: 0.6,
103
    lineHeight: 18,
104
    marginBottom: 6,
105
    fontStyle: 'italic'
106
  },
107
  badge: {
108
    alignSelf: 'flex-start',
109
    marginTop: 4,
110
    maxWidth: '50%'
111
  }
112
})