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

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

17
  return undefined
18
}
19

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

29
type Props = { card: HistoryCard & { raw: MoodEntry } }
30

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

37
  return (
38
    <Card style={styles.card}>
39
      <View style={styles.row}>
40
        <View style={[styles.iconWrap, { backgroundColor: meta.bg }]}>
41
          <Text style={styles.moodIconEmoji}>{moodDef?.icon ?? '😐'}</Text>
42

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

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