eletrotupi / tcc/ frontend/app/triggers/new.tsxd139cd140eae38d7f5b7000fa39a09c78d163f07
6.5 KB | 224 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, useLocalSearchParams } 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 { Section, SectionHeader } from "@/components/ui/Sections";
15
import { Spacing, Typography, Colors, BorderRadius } from "@/constants/theme";
16
import { Ionicons, MaterialIcons } from "@expo/vector-icons";
17
import { useCreateTrigger, useMoodEntries, useLinkMoodToTrigger } from "@/hooks";
18
import { CategoryChips, CategoryOption } from "@/components/ui/CategoryChips";
19
import { TriggerCategory } from "@/constants/triggers";
20
import { TRIGGER_CATEGORY_DEFINITIONS } from "@/constants/trigger-categories";
21
import { TimePicker } from "@/components/ui/TimePicker";
22
import { getMood } from "@/constants/moods";
23
import { LinkRow } from "@/components/ui/LinkRow";
24

25
const TRIGGER_CATEGORIES: CategoryOption<TriggerCategory>[] =
26
  TRIGGER_CATEGORY_DEFINITIONS.map((d) => ({
27
    label: d.label,
28
    value: d.id,
29
    icon: <MaterialIcons size={16} color={d.color} name={d.icon} />,
30
  }));
31

32
export default function NewTrigger() {
33
  const [moment, setMoment] = useState(new Date());
34
  const [comment, setComment] = useState("");
35
  const { category: initialCategory, moodId: linkedMoodId } = useLocalSearchParams<{ category?: string; moodId?: string }>();
36
  const [category, setCategory] = useState(initialCategory ?? "WORK");
37
  const createTrigger = useCreateTrigger();
38
  const linkMoodToTrigger = useLinkMoodToTrigger();
39
  const [linkMood, setLinkMood] = useState(false);
40
  const { data: moodEntries, isLoading: isLoadingMood } = useMoodEntries({
41
    limit: 1,
42
  });
43

44
  const latestMood = moodEntries?.entries[0] ?? null;
45
  const moodDef = latestMood
46
    ? getMood(latestMood.selectedMood.toLowerCase())
47
    : null;
48

49
  const save = async () => {
50
    const data = {
51
      moment,
52
      comment,
53
      category,
54
      ...(linkMood && latestMood ? { moodId: latestMood.id } : null),
55
    };
56

57
    const result = await createTrigger.mutateAsync(data);
58

59
    if (linkedMoodId) {
60
      await linkMoodToTrigger.mutateAsync({
61
        triggerId: String(result.trigger.id),
62
        moodId: linkedMoodId,
63
        perceivedImpact: 3,
64
      });
65
      router.back();
66
    } else {
67
      router.replace("/(tabs)/actions");
68
    }
69
  };
70

71
  return (
72
    <KeyboardAvoidingView behavior="height" style={styles.keyboardView}>
73
      <ScrollView scrollEventThrottle={16}>
74
        <View style={styles.container}>
75
          <View style={styles.header}>
76
            <View style={styles.innerHeaderWrapper}>
77
              <View style={[styles.headerIcon, { backgroundColor: "#FFF7ED" }]}>
78
                <Ionicons name="flash-outline" size={20} color="#EA580C" />
79
              </View>
80

81
              <View style={styles.headerTitleSubtitle}>
82
                <Text style={styles.headerTitle}>Aconteceu algo?</Text>
83
                <Text style={styles.headerSubtitle}>
84
                  Registre acontecimentos fora do padrão
85
                </Text>
86
              </View>
87
            </View>
88

89
            <Text style={styles.description}>
90
              Identificar gatilhos ajuda a entender melhor seus padrões
91
              emocionais
92
            </Text>
93
          </View>
94

95
          <Section>
96
            <SectionHeader title="Horário do Evento" />
97
            <TimePicker value={moment} onChange={setMoment} />
98
          </Section>
99

100
          <Section>
101
            <SectionHeader title="Selecionar uma categoria" />
102
            <CategoryChips
103
              options={TRIGGER_CATEGORIES}
104
              active={category}
105
              onChange={setCategory}
106
            />
107
          </Section>
108

109
          <Section>
110
            <SectionHeader title="Adicione detalhes" />
111

112
            <Card style={styles.mainCard}>
113
              <TextArea
114
                label="Comentários sobre"
115
                variant="darkGhost"
116
                onChangeText={(val) => setComment(val)}
117
                value={comment}
118
                minRows={5}
119
                maxRows={10}
120
                placeholder="Descreva o que gerou esse sentimento"
121
              />
122
            </Card>
123
          </Section>
124

125
          <Section>
126
            <SectionHeader title="Vincular registro" />
127

128
            <LinkRow
129
              icon={
130
                <View
131
                  style={[styles.iconWrap, { backgroundColor: "transparent" }]}
132
                >
133
                  <Text style={styles.moodIconEmoji}>
134
                    {moodDef?.icon ?? "😐"}
135
                  </Text>
136
                </View>
137
              }
138
              label="Humor atual"
139
              sublabel={
140
                isLoadingMood ? "..." : (moodDef?.label ?? "Nenhum registrado")
141
              }
142
              disabled={!latestMood}
143
              value={linkMood && !!latestMood}
144
              onToggle={setLinkMood}
145
            />
146

147
            <LinkRow
148
              icon={
149
                <MaterialIcons
150
                  name="psychology"
151
                  size={40}
152
                  color={Colors.light.disabled}
153
                />
154
              }
155
              label="Prática"
156
              sublabel={"Nenhuma registrada"}
157
              disabled={true}
158
              value={false}
159
              onToggle={() => {
160
                console.log("When we get that");
161
              }}
162
            />
163
          </Section>
164

165
          <Button title="Salvar Registro" onPress={save} />
166
        </View>
167
      </ScrollView>
168
    </KeyboardAvoidingView>
169
  );
170
}
171

172
const styles = StyleSheet.create({
173
  container: {
174
    gap: 24,
175
    paddingHorizontal: Spacing.containerPadding,
176
    paddingVertical: Spacing.sectionGap,
177
    marginBottom: 50,
178
  },
179
  mainCard: {
180
    padding: Spacing.cardGap,
181
  },
182
  // Header
183
  header: {},
184
  headerIcon: {
185
    paddingVertical: 15,
186
    paddingHorizontal: 14,
187
    width: 48,
188
    borderRadius: BorderRadius.md,
189
  },
190
  innerHeaderWrapper: {
191
    flex: 1,
192
    flexDirection: "row",
193
    alignItems: "center",
194
  },
195
  headerTitleSubtitle: {
196
    marginLeft: 10,
197
  },
198
  headerTitle: {
199
    ...Typography.headlineMd,
200
  },
201
  headerSubtitle: {
202
    ...Typography.bodyMd,
203
    color: Colors.light.textSecondary,
204
  },
205
  description: {
206
    ...Typography.bodyMd,
207
    color: Colors.light.textSecondary,
208
    marginTop: 20,
209
  },
210
  keyboardView: {
211
    flex: 1,
212
  },
213
  moodIconEmoji: {
214
    fontSize: 26,
215
  },
216
  iconWrap: {
217
    width: 40,
218
    height: 40,
219
    borderRadius: 20,
220
    alignItems: "center",
221
    justifyContent: "center",
222
    marginTop: 1,
223
  },
224
});