eletrotupi / tcc/ frontend/app/(tabs)/new/entry.tsx6b006f28cdcc256212589357ed92e3c06f935c2a
6.1 KB | 204 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
    const result = await createMoodEntry.mutateAsync(data);
67
    const moodId = result.mood.id;
68

69
    reset();
70

71
    router.replace(`/new/post-mood?moodId=${moodId}`);
72
  };
73

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

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

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

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

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

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

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

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

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

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

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

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