eletrotupi / tcc/ frontend/components/history/SleepRecordCard.tsxc121404b00d29de6d91827ce3a3fc0ede1a0c5ab
2.8 KB | 111 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 type { HistoryCard } from '@/lib/history/types'
8
import { Spacing } from '@/constants/theme';
9
import { router } from 'expo-router'
10

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

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

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

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

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

33
  return (
34
    <Card style={styles.card} onPress={() => router.push(`/sleep/${card.raw.id}`)}>
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
          </View>
43
          <View style={styles.durationRow}>
44
            <Text style={styles.duration}>{duration}</Text>
45
          </View>
46
          {card.raw.annotations ? (
47
            <Text style={styles.summary} numberOfLines={2}>
48
              {card.raw.annotations.trim()}
49
            </Text>
50
          ) : null}
51
          <Badge label={badge.label} variant={badge.variant} style={styles.badge} />
52
        </View>
53
      </View>
54
    </Card>
55
  )
56
}
57

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