eletrotupi / tcc/ frontend/app/(tabs)/new/entry.tsxd02f513430f49f5c5ff57d78eab853a7284e0cf2
6.0 KB | 202 lines Raw
1
import { useState, useEffect } from "react";
2
import { Link, router, useLocalSearchParams } from "expo-router";
3

4
import { View, Text, StyleSheet, ScrollView } from "react-native";
5

6
import { SafeAreaView } from "react-native-safe-area-context";
7
import { ThemedText } from "@/components/misc/themed-text";
8
import { ThemedView } from "@/components/misc/themed-view";
9
import { ScreenLayout } from "@/components/ui/ScreenLayout";
10
import { useAuth } from "@/context/AuthContext";
11
import { Grid, Col, Row, Between, Center } from "@/components/ui/LayoutHelpers";
12
import { Card } from "@/components/ui/Cards";
13
import { Button } from "@/components/ui/Button";
14
import { Input, TextArea } from "@/components/ui/Input";
15
import { Section, SectionHeader } from "@/components/ui/Sections";
16
import { Spacing, Typography, Colors } from "@/constants/theme";
17
import { ScaleSlider } from "@/components/ui/ScaleSlider";
18
import { MoodComponentCard } from "@/components/ui/MoodComponentCard";
19
import { Ionicons } from "@expo/vector-icons";
20
import { useThemeColor, useCreateMoodEntry } from "@/hooks";
21
import { useMoodEntryStore } from "@/stores";
22

23
import { MOODS, getMood } from "@/constants/moods";
24

25
import { intensityToValue } from "@/constants/mood-components";
26

27
import { apiClient } from "@/lib/api";
28

29
export default function NewMoodEntry() {
30
  const { user } = useAuth();
31
  const tintColor = useThemeColor({}, "tint");
32

33
  const { initialMood } = useLocalSearchParams();
34
  const [annotation, setAnnotation] = useState();
35
  const [stress, setStress] = useState(0);
36
  const [anxiety, setAnxiety] = useState(0);
37
  const [energy, setEnergy] = useState(0);
38

39
  const { selectedMood, setSelectedMood, components, reset } =
40
    useMoodEntryStore();
41

42
  const createMoodEntry = useCreateMoodEntry();
43

44
  useEffect(() => {
45
    setSelectedMood(getMood(initialMood));
46
  }, [initialMood]);
47

48
  useEffect(() => {
49
    return () => reset();
50
  }, []);
51

52
  const saveMoodEntry = async () => {
53
    const data = {
54
      selectedMood: selectedMood?.id.toUpperCase(),
55
      stressLevel: stress,
56
      energyLevel: energy,
57
      anxietyLevel: anxiety,
58
      moment: new Date(),
59
      annotation: annotation,
60
      moodComponents: components.map((c) => ({
61
        component: c.id.toUpperCase(),
62
        intensity: intensityToValue(c.intensity),
63
      })),
64
    };
65

66
    await createMoodEntry.mutateAsync(data);
67

68
    reset();
69
    router.replace("/");
70
  };
71

72
  const editComponents = () => {
73
    router.push("/entry/mood-components");
74
  };
75

76
  return (
77
    <View>
78
      <ScrollView scrollEventThrottle={16}>
79
        <View style={styles.container}>
80
          <Center>
81
            <ThemedText style={styles.statusPrefix}>
82
              Como você está se sentindo agora?
83
            </ThemedText>
84

85
            <ThemedText style={styles.statusText}>
86
              {selectedMood?.label || "Neutro"}
87
            </ThemedText>
88
          </Center>
89

90
          <Card style={styles.resumeCard}>
91
            <ThemedText style={styles.infoText}>
92
              Não existe resposta certa ou errada. Estime, de 0 a 10, como tu
93
              percebe tua energia, estresse e ansiedade neste momento. O
94
              objetivo é registrar uma impressão geral, não uma medida precisa.
95
            </ThemedText>
96

97
            <Col gap={24}>
98
              <ScaleSlider
99
                variant="rich"
100
                label="Energia"
101
                value={energy}
102
                onValueChange={setEnergy}
103
                icon={
104
                  <Ionicons name="flower-outline" size={20} color={tintColor} />
105
                }
106
                minLabel="Baixa"
107
                maxLabel="Alta"
108
              />
109

110
              <ScaleSlider
111
                variant="rich"
112
                label="Ansiedade"
113
                value={anxiety}
114
                onValueChange={setAnxiety}
115
                icon={<Ionicons name="sad-outline" size={20} color="#FB923C" />}
116
                minLabel="Calmo"
117
                maxLabel="Ansioso"
118
              />
119

120
              <ScaleSlider
121
                variant="rich"
122
                label="Estresse"
123
                value={stress}
124
                onValueChange={setStress}
125
                icon={<Ionicons name="flame" size={20} color="#f87171" />}
126
                minLabel="Relaxado"
127
                maxLabel="Estressado"
128
              />
129
            </Col>
130
          </Card>
131

132
          <Card style={styles.annotationsCard}>
133
            <TextArea
134
              label="Notas sobre o dia"
135
              type="text"
136
              variant="darkGhost"
137
              onChangeText={(val) => setAnnotation(val)}
138
              value={annotation}
139
              minRows={4}
140
              maxRows={6}
141
              placeholder="Escreva uma nota rápida sobre o seu dia até o momento..."
142
            />
143
          </Card>
144

145
          <Section>
146
            <SectionHeader title="Também estou..." />
147
            {components.length > 0 ? (
148
              <Grid gap={2} style={{ marginTop: 8 }}>
149
                {components.map((comp) => (
150
                  <MoodComponentCard
151
                    key={comp.id}
152
                    id={comp.id}
153
                    intensity={comp.intensity}
154
                  />
155
                ))}
156
              </Grid>
157
            ) : null}
158

159
            <Button
160
              title="Adicionar estados & emoções"
161
              onPress={editComponents}
162
              textStyle={{ fontWeight: 500 }}
163
              variant="dashed"
164
            />
165
          </Section>
166

167
          <Button
168
            title="Salvar Registro"
169
            onPress={saveMoodEntry}
170
            disabled={!components.length}
171
          />
172
        </View>
173
      </ScrollView>
174
    </View>
175
  );
176
}
177

178
const styles = StyleSheet.create({
179
  container: {
180
    gap: 24,
181
    paddingHorizontal: Spacing.containerPadding,
182
    paddingVertical: Spacing.sectionGap,
183
  },
184
  infoText: {
185
    ...Typography.labelSm,
186
    color: Colors.light.textSecondary,
187
    marginBottom: 20,
188
    fontWeight: "400" as const,
189
  },
190
  statusText: {
191
    ...Typography.headlineXg,
192
  },
193
  statusPrefix: {
194
    ...Typography.bodyMd,
195
  },
196
  annotationsCard: {
197
    padding: Spacing.cardGap,
198
  },
199
  resumeCard: {
200
    padding: Spacing.cardGap,
201
  },
202
});