eletrotupi / tcc/ frontend/app/sleep/new.tsx96e7fe0f1dcc90b9ddef3032a78b7040d2068378
4.0 KB | 148 lines Raw
1
import {
2
  View,
3
  Text,
4
  StyleSheet,
5
  KeyboardAvoidingView,
6
  ScrollView
7
} from 'react-native';
8
import { useEffect, useState } from 'react';
9
import { router } from 'expo-router';
10

11
import { Card } from '@/components/ui/Cards';
12
import { Input, TextArea } from '@/components/ui/Input';
13
import { Button } from '@/components/ui/Button';
14
import { Spacing, Typography, Colors, BorderRadius } from '@/constants/theme';
15
import { Ionicons } from '@expo/vector-icons';
16
import DatePickerField from '@/components/ui/DatePickerField';
17
import { ScaleSlider } from '@/components/ui/ScaleSlider';
18
import { useCreateSleepRecord } from '@/hooks';
19

20
export default function NewSleepRecord() {
21
  const [date, setDate] = useState(new Date())
22
  const [annotations, setAnnotations] = useState();
23
  const [average, setAverage] = useState(7.5);
24
  const createSleepRecord = useCreateSleepRecord();
25

26
  const formatValue = (value: number): string => {
27
    return String(value).replaceAll('.', ',');
28
  };
29

30
  const save = async () => {
31
    const data = {
32
      date,
33
      annotations,
34
      average
35
    };
36

37
    console.log("Sleep record:", data)
38
    await createSleepRecord.mutateAsync(data)
39
    router.replace("/")
40
  };
41

42
  return (
43
    <KeyboardAvoidingView
44
      behavior='height'
45
      style={styles.keyboardView}>
46
      <ScrollView scrollEventThrottle={16}>
47
        <View style={styles.container}>
48
          <View style={styles.header}>
49
            <View style={styles.innerHeaderWrapper}>
50
              <View style={[styles.headerIcon, { backgroundColor: '#EFF6FF' }]}>
51
                <Ionicons name="moon-outline" size={20} color="#2563EB" />
52
              </View>
53

54
              <View style={styles.headerTitleSubtitle}>
55
                <Text style={styles.headerTitle}>Bom descanso</Text>
56
                <Text style={styles.headerSubtitle}>Registre sua noite de sono</Text>
57
              </View>
58
            </View>
59

60
            <Text style={styles.description}>
61
              Acompanhar seu sono ajuda a entender como seu corpo se recupera
62
              e melhora sua performance diária.
63
            </Text>
64
          </View>
65

66
          <Card style={styles.mainCard}>
67
            <DatePickerField
68
              label="Data do Registro"
69
              initialDate={date}
70
              maximumDate={new Date()}
71
              onChange={setDate}
72
            />
73

74
            <View style={{ marginVertical: 15 }}>
75
              <ScaleSlider
76
                label="Duração"
77
                value={average}
78
                onValueChange={setAverage}
79
                onValueFormat={formatValue}
80
                step={0.5}
81
                min={0.0}
82
                max={15.0}
83
                minLabel="0h"
84
                maxLabel="15h" />
85
            </View>
86

87
            <TextArea
88
              label="Notas sobre a qualidade"
89
              type="text"
90
              variant="darkGhost"
91
              onChangeText={(val) => setAnnotations(val)}
92
              value={annotations}
93
              minRows={5}
94
              maxRows={10}
95
              placeholder="Como você se sentiu ao acordar? Teve sonhos marcantes?"
96
              style={styles.notes}
97
            />
98
          </Card>
99

100
          <Button title="Salvar Registro" onPress={save} />
101
        </View>
102
      </ScrollView>
103
    </KeyboardAvoidingView>
104
  );
105
}
106

107
const styles = StyleSheet.create({
108
  container: {
109
    gap: 24,
110
    paddingHorizontal: Spacing.containerPadding,
111
    paddingVertical: Spacing.sectionGap,
112
  },
113
  mainCard: {
114
    padding: Spacing.cardGap
115
  },
116
  // Header
117
  header: {
118
  },
119
  headerIcon: {
120
    paddingVertical: 15,
121
    paddingHorizontal: 14,
122
    width: 48,
123
    borderRadius: BorderRadius.md,
124
  },
125
  innerHeaderWrapper: {
126
    flex: 1,
127
    flexDirection: 'row',
128
    alignItems: 'center'
129
  },
130
  headerTitleSubtitle: {
131
    marginLeft: 10
132
  },
133
  headerTitle: {
134
    ...Typography.headlineMd
135
  },
136
  headerSubtitle: {
137
    ...Typography.bodyMd,
138
    color: Colors.light.textSecondary
139
  },
140
  description: {
141
    ...Typography.bodyMd,
142
    color: Colors.light.textSecondary,
143
    marginTop: 20
144
  },
145
  keyboardView: {
146
    flex: 1,
147
  },
148
})