eletrotupi / tcc/ frontend/app/care-actions/appointment.tsxc901c35af9c84b6a29e5185545ced1129f33b8f4
5.4 KB | 173 lines Raw
1
import {
2
  View,
3
  StyleSheet,
4
  KeyboardAvoidingView,
5
  ScrollView,
6
  TouchableOpacity,
7
} from "react-native";
8
import { Text } from "@/components/ui/Text";
9
import { useState } from "react";
10
import { router } from "expo-router";
11

12
import { Card } from "@/components/ui/Cards";
13
import { TextArea } from "@/components/ui/Input";
14
import { Button } from "@/components/ui/Button";
15
import { Section, SectionHeader } from "@/components/ui/Sections";
16
import { CategoryChips, CategoryOption } from "@/components/ui/CategoryChips";
17
import { Spacing, Typography, Colors, BorderRadius, Shadows } from "@/constants/theme";
18
import { Ionicons } from "@expo/vector-icons";
19
import { useCreateCareAction } from "@/hooks";
20
import { AppointmentType } from "@/lib/api";
21
import { useCareActionLinkStore } from "@/stores";
22

23
const APPOINTMENT_TYPES: CategoryOption<AppointmentType>[] = [
24
  { label: 'Analista', value: 'ANALYST', icon: <Ionicons name="person-outline" size={16} color={Colors.light.tint} /> },
25
  { label: 'Psiquiatra', value: 'PSYCHIATRIST', icon: <Ionicons name="medical-outline" size={16} color={Colors.light.tint} /> },
26
  { label: 'Clínico', value: 'GP', icon: <Ionicons name="fitness-outline" size={16} color={Colors.light.tint} /> },
27
  { label: 'Nutricionista', value: 'NUTRITIONIST', icon: <Ionicons name="nutrition-outline" size={16} color={Colors.light.tint} /> },
28
  { label: 'Outro', value: 'OTHER', icon: <Ionicons name="help-outline" size={16} color={Colors.light.tint} /> },
29
];
30

31
const DURATIONS = [30, 45, 50, 60];
32

33
export default function AppointmentCareAction() {
34
  const [appointmentType, setAppointmentType] = useState<AppointmentType>('ANALYST');
35
  const [appointmentDuration, setAppointmentDuration] = useState<number>(50);
36
  const [appointmentNote, setAppointmentNote] = useState('');
37

38
  const createCareAction = useCreateCareAction();
39

40
  const handleSave = async () => {
41
    const result = await createCareAction.mutateAsync({
42
      type: 'APPOINTMENT',
43
      moment: new Date(),
44
      appointment: {
45
        type: appointmentType,
46
        duration: appointmentDuration,
47
        note: appointmentNote || undefined,
48
      },
49
    });
50
    useCareActionLinkStore.getState().setPending(result.careAction.id);
51
    router.replace('/care-actions/post-appointment');
52
  };
53

54
  return (
55
    <KeyboardAvoidingView behavior="height" style={styles.keyboardView}>
56
      <ScrollView scrollEventThrottle={16}>
57
        <View style={styles.container}>
58
          <View style={styles.header}>
59
            <Text style={styles.headerTitle}>Registrar consulta</Text>
60
            <Text style={styles.headerSubtitle}>
61
              Informe os detalhes da consulta ou sessão
62
            </Text>
63
          </View>
64

65
          <Section>
66
            <SectionHeader title="Tipo de consulta" />
67
            <CategoryChips
68
              options={APPOINTMENT_TYPES}
69
              active={appointmentType}
70
              onChange={setAppointmentType}
71
            />
72
          </Section>
73

74
          <Section>
75
            <SectionHeader title="Duração (min)" />
76
            <View style={styles.durationRow}>
77
              {DURATIONS.map((d) => (
78
                <TouchableOpacity
79
                  key={d}
80
                  style={[
81
                    styles.durationChip,
82
                    appointmentDuration === d && styles.durationChipActive,
83
                  ]}
84
                  onPress={() => setAppointmentDuration(d)}
85
                  activeOpacity={0.7}
86
                >
87
                  <Text
88
                    style={[
89
                      styles.durationLabel,
90
                      appointmentDuration === d && styles.durationLabelActive,
91
                    ]}
92
                  >
93
                    {d}
94
                  </Text>
95
                </TouchableOpacity>
96
              ))}
97
            </View>
98
          </Section>
99

100
          <Section>
101
            <SectionHeader title="Notas (opcional)" />
102
            <Card style={{ padding: Spacing.cardGap }}>
103
              <TextArea
104
                label="Como foi a consulta?"
105
                variant="darkGhost"
106
                value={appointmentNote}
107
                onChangeText={setAppointmentNote}
108
                minRows={4}
109
                placeholder="Descreva brevemente..."
110
              />
111
            </Card>
112
          </Section>
113

114
          <Button
115
            title="Salvar"
116
            onPress={handleSave}
117
            loading={createCareAction.isPending}
118
            style={{ ...Shadows.lg }}
119
          />
120
        </View>
121
      </ScrollView>
122
    </KeyboardAvoidingView>
123
  );
124
}
125

126
const styles = StyleSheet.create({
127
  keyboardView: {
128
    flex: 1,
129
  },
130
  container: {
131
    gap: 24,
132
    paddingHorizontal: Spacing.containerPadding,
133
    paddingVertical: Spacing.sectionGap,
134
    marginBottom: 50,
135
  },
136
  header: {
137
    gap: 8,
138
  },
139
  headerTitle: {
140
    ...Typography.headlineMd,
141
  },
142
  headerSubtitle: {
143
    ...Typography.bodyMd,
144
    color: Colors.light.textSecondary,
145
  },
146
  durationRow: {
147
    flexDirection: 'row',
148
    gap: 10,
149
    flexWrap: 'wrap',
150
  },
151
  durationChip: {
152
    paddingHorizontal: 20,
153
    paddingVertical: 12,
154
    borderRadius: BorderRadius.full,
155
    backgroundColor: '#fff',
156
    borderWidth: 1.5,
157
    borderColor: Colors.light.divider,
158
    minWidth: 64,
159
    alignItems: 'center',
160
  },
161
  durationChipActive: {
162
    backgroundColor: Colors.light.tint + '1A',
163
    borderColor: Colors.light.tint,
164
  },
165
  durationLabel: {
166
    fontSize: 16,
167
    fontWeight: '600',
168
    color: Colors.light.text,
169
  },
170
  durationLabelActive: {
171
    color: Colors.light.text,
172
  },
173
});