eletrotupi / tcc/ frontend/components/medicine/MedicineRegimenList.tsxf2e8f9009eea845da1d93f97d5e52c5d780b0f0e
3.7 KB | 121 lines Raw
1
import { View, Switch, TouchableOpacity, StyleSheet, ActivityIndicator } from "react-native";
2
import { Text } from "@/components/ui/Text";
3
import { Ionicons } from "@expo/vector-icons";
4
import { router } from "expo-router";
5
import { Button } from "@/components/ui/Button";
6
import { Colors, Typography, Spacing, BorderRadius, Shadows } from "@/constants/theme";
7
import { useMedicineRegimens, useToggleMedicineRegimen } from "@/hooks";
8
import { MedicineRegimen } from "@/lib/api";
9

10
const PERIODICITY_LABELS: Record<string, string> = {
11
  ONCE: "Uma vez",
12
  DAILY: "Diário",
13
  TWICE_DAILY: "2x ao dia",
14
  THREE_TIMES_DAILY: "3x ao dia",
15
  WEEKLY: "Semanal",
16
  BIWEEKLY: "Quinzenal",
17
  MONTHLY: "Mensal",
18
};
19

20
function scheduleSummary(regimen: MedicineRegimen): string {
21
  const times = regimen.scheduledAt.length > 0
22
    ? regimen.scheduledAt.join(" · ")
23
    : null;
24
  const label = PERIODICITY_LABELS[regimen.periodicity] ?? regimen.periodicity;
25
  return times ? `${times} · ${label}` : label;
26
}
27

28
export function MedicineRegimenList() {
29
  const { data, isLoading } = useMedicineRegimens();
30
  const toggleRegimen = useToggleMedicineRegimen();
31

32
  if (isLoading) {
33
    return (
34
      <View style={styles.center}>
35
        <ActivityIndicator color={Colors.light.tint} />
36
      </View>
37
    );
38
  }
39

40
  const regimens = data?.regimens ?? [];
41

42
  return (
43
    <View style={styles.container}>
44
      {regimens.length === 0 ? (
45
        <View style={styles.empty}>
46
          <Text style={styles.emptyText}>Nenhum medicamento cadastrado</Text>
47
        </View>
48
      ) : (
49
        regimens.map((regimen) => (
50
          <TouchableOpacity
51
            key={regimen.id}
52
            style={styles.row}
53
            activeOpacity={0.7}
54
            onPress={() => router.push(`/medicine-regimens/${regimen.id}`)}
55
          >
56
            <View style={styles.iconWrap}>
57
              <Ionicons name="bandage-outline" size={18} color={Colors.light.tint} />
58
            </View>
59
            <View style={styles.info}>
60
              <Text style={styles.name}>{regimen.name}</Text>
61
              <Text style={styles.meta}>
62
                {regimen.dosage} · {scheduleSummary(regimen)}
63
              </Text>
64
            </View>
65
            <Switch
66
              value={regimen.active}
67
              onValueChange={(val) =>
68
                toggleRegimen.mutate({ id: String(regimen.id), active: val })
69
              }
70
              trackColor={{ true: Colors.light.tint, false: Colors.light.divider }}
71
              thumbColor="#fff"
72
            />
73
          </TouchableOpacity>
74
        ))
75
      )}
76

77

78
      <Button
79
        title="Cadastrar outro medicamento"
80
        variant="dashed"
81
        onPress={() => router.push('/care-actions/medicine-new')}
82
      />
83
    </View>
84
  );
85
}
86

87
const styles = StyleSheet.create({
88
  container: { gap: 1 },
89
  center: { padding: Spacing.cardGap, alignItems: "center" },
90
  empty: { padding: Spacing.cardGap },
91
  emptyText: { ...Typography.bodyMd, color: Colors.light.textSecondary },
92
  row: {
93
    flexDirection: "row",
94
    alignItems: "center",
95
    backgroundColor: "#fff",
96
    padding: Spacing.cardGap,
97
    gap: 12,
98
    ...Shadows.sm,
99
    borderRadius: BorderRadius.lg,
100
    marginBottom: 5
101
  },
102
  iconWrap: {
103
    width: 32,
104
    height: 32,
105
    borderRadius: BorderRadius.md,
106
    backgroundColor: Colors.light.tint + "1A",
107
    alignItems: "center",
108
    justifyContent: "center",
109
  },
110
  info: { flex: 1 },
111
  name: { ...Typography.bodyMd, fontWeight: "600" },
112
  meta: { ...Typography.labelSm, color: Colors.light.textSecondary },
113
  addButton: {
114
    flexDirection: "row",
115
    alignItems: "center",
116
    gap: 8,
117
    paddingVertical: Spacing.cardGap,
118
    paddingHorizontal: 4,
119
  },
120
  addText: { ...Typography.bodyMd, color: Colors.light.tint, fontWeight: "600" },
121
});