eletrotupi / tcc/ frontend/app/(tabs)/new/entry.tsx766a1ea0406afc664eb2ebc05cd2393aad8794a4
5.5 KB | 203 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 } from '@/hooks/use-theme-color';
28
import {
29
  useMoodEntryStore,
30
} from '@/stores/moodEntry';
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
  useEffect(() => {
63
    setSelectedMood(getMood(initialMood));
64
  }, [initialMood]);
65

66
  useEffect(() => {
67
    return () => reset();
68
  }, []);
69

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

84
    const result = await apiClient.createMoodEntry(data)
85

86
    router.push("/")
87
  }
88

89
  const editComponents = () => {
90
    router.push("/entry/mood-components")
91
  }
92

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

103
            <ThemedText style={styles.statusText}>
104
              {selectedMood?.label || "Neutro"}
105
            </ThemedText>
106
          </Center>
107

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

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

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

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

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

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

176
          <Button title="Salvar Registro"
177
            onPress={saveMoodEntry}
178
          />
179
        </View>
180
      </ScrollView>
181
    </View>
182
  );
183
}
184

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