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

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

14
  return {
15
    label: 'Ruim', variant: 'red'
16
  } as const
17
}
18

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

26
type Props = { card: HistoryCard & { raw: SleepRecord } }
27

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

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

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

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