eletrotupi / tcc/ frontend/app/(tabs)/new/entry.tsx980ac648beb8b6f2a98a5bada1af401b1b399d77
5.6 KB | 207 lines Raw
1
import { useState, useEffect } from 'react';
2
import {
3
  Link, router, useLocalSearchParams
4
} from 'expo-router';
5

6
import {
7
  View,
8
  Text,
9
  StyleSheet,
10
  ScrollView
11
} from 'react-native';
12

13
import { SafeAreaView } from 'react-native-safe-area-context';
14
import { ThemedText } from '@/components/misc/themed-text';
15
import { ThemedView } from '@/components/misc/themed-view';
16
import { ScreenLayout } from '@/components/ui/ScreenLayout';
17
import { useAuth } from '@/context/AuthContext';
18
import { Grid, Col, Row, Between, Center } from '@/components/ui/LayoutHelpers';
19
import { Card } from '@/components/ui/Cards';
20
import { Button } from '@/components/ui/Button';
21
import { Input, TextArea } from '@/components/ui/Input';
22
import { Section, SectionHeader } from '@/components/ui/Sections';
23
import { Spacing, Typography, Colors } from '@/constants/theme';
24
import { ScaleSlider } from '@/components/ui/ScaleSlider';
25
import { MoodComponentCard } from '@/components/ui/MoodComponentCard';
26
import { Ionicons } from '@expo/vector-icons';
27
import { useThemeColor, useCreateMoodEntry } from '@/hooks';
28
import {
29
  useMoodEntryStore,
30
} from '@/stores';
31

32
import {
33
  MOODS,
34
  getMood
35
} from '@/constants/moods';
36

37
import {
38
  intensityToValue
39
} from '@/constants/mood-components';
40

41
import {
42
  apiClient
43
} from '@/lib/api';
44

45
export default function NewMoodEntry() {
46
  const { user } = useAuth();
47
  const tintColor = useThemeColor({}, 'tint');
48

49
  const { initialMood } = useLocalSearchParams();
50
  const [annotation, setAnnotation] = useState();
51
  const [stress, setStress] = useState(0);
52
  const [anxiety, setAnxiety] = useState(0);
53
  const [energy, setEnergy] = useState(0);
54

55
  const {
56
    selectedMood,
57
    setSelectedMood,
58
    components,
59
    reset
60
  } = useMoodEntryStore();
61

62
  const createMoodEntry = useCreateMoodEntry();
63

64
  useEffect(() => {
65
    setSelectedMood(getMood(initialMood));
66
  }, [initialMood]);
67

68
  useEffect(() => {
69
    return () => reset();
70
  }, []);
71

72
  const saveMoodEntry = async () => {
73
    const data = {
74
      selectedMood: selectedMood?.id.toUpperCase(),
75
      stressLevel: stress,
76
      energyLevel: energy,
77
      anxietyLevel: anxiety,
78
      moment: new Date(),
79
      annotation: annotation,
80
      moodComponents: components.map((c) => ({
81
        component: c.id.toUpperCase(),
82
        intensity: intensityToValue(c.intensity)
83
      }))
84
    };
85

86
    await createMoodEntry.mutateAsync(data)
87

88
    reset();
89
    router.replace("/")
90
  }
91

92
  const editComponents = () => {
93
    router.push("/entry/mood-components")
94
  }
95

96
  return (
97
    <View>
98
      <ScrollView
99
        scrollEventThrottle={16}>
100
        <View style={styles.container}>
101
          <Center>
102
            <ThemedText style={styles.statusPrefix}>
103
              Como você está se sentindo agora?
104
            </ThemedText>
105

106
            <ThemedText style={styles.statusText}>
107
              {selectedMood?.label || "Neutro"}
108
            </ThemedText>
109
          </Center>
110

111
          <Card style={styles.resumeCard}>
112
            <Col gap={24}>
113
              <ScaleSlider
114
                variant="rich"
115
                label="Energia"
116
                value={energy}
117
                onValueChange={setEnergy}
118
                icon={<Ionicons name="flower-outline" size={20} color={tintColor} />}
119
                minLabel="Baixa"
120
                maxLabel="Alta"
121
              />
122

123
              <ScaleSlider
124
                variant="rich"
125
                label="Ansiedade"
126
                value={anxiety}
127
                onValueChange={setAnxiety}
128
                icon={<Ionicons name="sad-outline" size={20} color="#FB923C" />}
129
                minLabel="Calmo"
130
                maxLabel="Ansioso"
131
              />
132

133
              <ScaleSlider
134
                variant="rich"
135
                label="Estresse"
136
                value={stress}
137
                onValueChange={setStress}
138
                icon={<Ionicons name="flame" size={20} color="#f87171" />}
139
                minLabel="Relaxado"
140
                maxLabel="Estressado"
141
              />
142
            </Col>
143
          </Card>
144

145
          <Card style={styles.annotationsCard}>
146
            <TextArea
147
              label="Notas sobre o dia"
148
              type="text"
149
              variant="darkGhost"
150
              onChangeText={(val) => setAnnotation(val)}
151
              value={annotation}
152
              minRows={4}
153
              maxRows={6}
154
              placeholder="Escreva uma nota rápida sobre o seu dia até o momento..."
155
            />
156
          </Card>
157

158
          <Section>
159
            <SectionHeader title="Componentes do Humor" info="Editar" />
160
            {components.length > 0 ? (
161
              <Grid gap={2} style={{ marginTop: 8 }}>
162
                {components.map((comp) => (
163
                  <MoodComponentCard
164
                    key={comp.id}
165
                    id={comp.id}
166
                    intensity={comp.intensity}
167
                  />
168
                ))}
169
              </Grid>
170
            ) : null}
171

172
            <Button title="Adicionar Componentes"
173
              onPress={editComponents}
174
              textStyle={{ fontWeight: 500 }}
175
              variant="dashed"
176
            />
177
          </Section>
178

179
          <Button title="Salvar Registro"
180
            onPress={saveMoodEntry}
181
            disabled={!components.length}
182
          />
183
        </View>
184
      </ScrollView>
185
    </View>
186
  );
187
}
188

189
const styles = StyleSheet.create({
190
  container: {
191
    gap: 24,
192
    paddingHorizontal: Spacing.containerPadding,
193
    paddingVertical: Spacing.sectionGap,
194
  },
195
  statusText: {
196
    ...Typography.headlineXg,
197
  },
198
  statusPrefix: {
199
    ...Typography.bodyMd
200
  },
201
  annotationsCard: {
202
    padding: Spacing.cardGap
203
  },
204
  resumeCard: {
205
    padding: Spacing.cardGap,
206
  }
207
});