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

11
import { Card } from "@/components/ui/Cards";
12
import { 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 behavior="height" style={styles.keyboardView}>
44
      <ScrollView scrollEventThrottle={16}>
45
        <View style={styles.container}>
46
          <View style={styles.header}>
47
            <View style={styles.innerHeaderWrapper}>
48
              <View style={[styles.headerIcon, { backgroundColor: "#EFF6FF" }]}>
49
                <Ionicons name="moon-outline" size={20} color="#2563EB" />
50
              </View>
51

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

60
            <Text style={styles.description}>
61
              Acompanhar seu sono ajuda a entender como seu corpo se recupera e
62
              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
              />
86
            </View>
87

88
            <TextArea
89
              label="Notas sobre a qualidade"
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
            />
97
          </Card>
98

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

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