eletrotupi / tcc/ frontend/components/history/SleepRecordCard.tsxd14a658d66db83b03a1d32445a711a46e2814b78
2.8 KB | 116 lines Raw
1
import { View, Text, StyleSheet } from 'react-native'
2
import { MaterialIcons } from '@expo/vector-icons'
3
import { Card } from '@/components/ui/Cards'
4
import { Badge } from '@/components/ui/Badge'
5
import type { SleepRecord } from '@/lib/api'
6
import { Spacing } from '@/constants/theme';
7

8
function sleepBadge(hours: number) {
9
  if (hours >= 7) return { label: 'Excelente', variant: 'green'  } as const
10
  if (hours >= 5) return { label: 'Regular', variant: 'yellow' } as const
11

12
  return {
13
    label: 'Ruim', variant: 'red'
14
  } as const
15
}
16

17
// TODO: Move this into the time utilities
18
function formatDuration(average: number) {
19
  const h = Math.floor(average)
20
  const m = Math.round((average - h) * 60)
21
  return `${h}h ${m.toString().padStart(2, '0')}min`
22
}
23

24
type Props = { card: HistoryCard & { raw: SleepRecord } }
25

26
export function SleepRecordCard({ card }: Props) {
27
  const badge    = sleepBadge(card.raw.average)
28
  const duration = formatDuration(card.raw.average)
29

30
  const time     = new Date(card.timestamp)
31
    .toLocaleTimeString('pt-BR', { hour: '2-digit', minute: '2-digit' })
32

33
  return (
34
    <Card style={styles.card}>
35
      <View style={styles.row}>
36
        <View style={[styles.iconWrap, { backgroundColor: '#ede9fe' }]}>
37
          <MaterialIcons name="bedtime" size={22} color="#7c3aed" />
38
        </View>
39
        <View style={styles.body}>
40
          <View style={styles.titleRow}>
41
            <Text style={styles.title}>Sono</Text>
42
            <Text style={styles.time}>{time}</Text>
43
          </View>
44
          <View style={styles.durationRow}>
45
            <Text style={styles.duration}>{duration}</Text>
46
          </View>
47
          {card.raw.annotations ? (
48
            <Text style={styles.summary} numberOfLines={2}>
49
              {card.raw.annotations.trim()}
50
            </Text>
51
          ) : null}
52
          <Badge label={badge.label} variant={badge.variant} style={styles.badge} />
53
        </View>
54
      </View>
55
    </Card>
56
  )
57
}
58

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