eletrotupi / tcc/ frontend/lib/history/mappers.tsdcee93d0c11ceff985805b7785c7db54c2acc4dd
4.5 KB | 163 lines Raw
1
import type { HistoryCard } from "@/lib/history/types";
2
import type { MoodEntry, SleepRecord, Trigger, CareAction } from "@/lib/api";
3
import { getMood } from "@/constants/moods";
4

5

6
export function mapMoodToHistoryCard(mood: MoodEntry): HistoryCard {
7
  const moodLabel = getMood(mood.selectedMood);
8
  const components = mood.moodComponents
9
    .map((c) => c.component.charAt(0) + c.component.slice(1).toLowerCase())
10
    .join(", ");
11

12
  const summary = [components || null, mood.annotation || null]
13
    .filter(Boolean)
14
    .join(" · ");
15

16
  return {
17
    id: `mood-${mood.id}`,
18
    category: "mood",
19
    timestamp: mood.moment.toString(),
20
    title: moodLabel?.label ?? "Humor",
21
    summary: summary || "Sem detalhes",
22
    badge: undefined,
23
    raw: mood,
24
  };
25
}
26

27
// Sleep Records
28

29
function sleepQualityBadge(hours: number): HistoryCard["badge"] {
30
  if (hours >= 7) return { label: "Excelente", variant: "green" };
31
  if (hours >= 5) return { label: "Regular", variant: "yellow" };
32

33
  return {
34
    label: "Ruim",
35
    variant: "red",
36
  };
37
}
38

39
export function mapSleepToHistoryCard(record: SleepRecord): HistoryCard {
40
  const hours = Math.floor(record.average);
41
  const minutes = Math.round((record.average - hours) * 60);
42
  const duration = `${hours}h ${minutes.toString().padStart(2, "0")}min`;
43
  const timestamp = typeof record.createdAt === 'string'
44
    ? record.createdAt
45
    : record.createdAt.toISOString();
46

47
  return {
48
    id: `sleep-${record.id}`,
49
    category: "sleep",
50
    timestamp,
51
    title: "Sono",
52
    summary: [duration, record.annotations].filter(Boolean).join(" · "),
53
    badge: sleepQualityBadge(record.average),
54
    raw: record,
55
  };
56
}
57

58
export function mapTriggerToHistoryCard(record: Trigger): HistoryCard {
59
  return {
60
    id: `trigger-${record.id}`,
61
    category: "trigger",
62
    timestamp: record.moment.toString(),
63
    title: "Gatilho",
64
    summary: [record.category, record.comment].filter(Boolean).join(" · "),
65
    badge: undefined,
66
    raw: record,
67
  };
68
}
69

70
function activityLabel(type?: string): string {
71
  const labels: Record<string, string> = {
72
    WALK: "Caminhada",
73
    YOGA: "Yoga",
74
    GYM: "Academia",
75
    MEDITATION: "Meditação",
76
    SOCIAL: "Momento social",
77
    CREATIVE: "Atividade criativa",
78
    OTHER: "Atividade",
79
  };
80
  return type ? (labels[type] ?? "Atividade") : "Atividade";
81
}
82

83
function appointmentLabel(type?: string): string {
84
  const labels: Record<string, string> = {
85
    ANALYST: "Analista",
86
    PSYCHIATRIST: "Psiquiatra",
87
    GP: "Clínico geral",
88
    NUTRITIONIST: "Nutricionista",
89
    PHYSIOTHERAPIST: "Fisioterapeuta",
90
    OTHER: "Consulta",
91
  };
92
  return type ? (labels[type] ?? "Consulta") : "Consulta";
93
}
94

95
export function mapCareActionToHistoryCard(record: CareAction): HistoryCard {
96
  switch (record.type) {
97
    case "MEDICINE": {
98
      const log = record.medicineLog;
99
      const name = log?.regimen?.name ?? "Medicamento";
100
      const dosage = log?.regimen?.dosage;
101
      return {
102
        id: `care_action-${record.id}`,
103
        category: "care_action",
104
        subtype: "medicine",
105
        timestamp: record.moment.toString(),
106
        title: name,
107
        summary: dosage ?? "Sem dosagem registrada",
108
        raw: record,
109
      };
110
    }
111

112
    case "APPOINTMENT": {
113
      const appt = record.appointment;
114
      const parts = [
115
        appt?.duration ? `${appt.duration} min` : null,
116
        appt?.note ?? null,
117
      ].filter(Boolean);
118
      const linkedCount =
119
        (record.triggerId ? 1 : 0) + (record.moodId ? 1 : 0);
120
      return {
121
        id: `care_action-${record.id}`,
122
        category: "care_action",
123
        subtype: "appointment",
124
        timestamp: record.moment.toString(),
125
        title: `Consulta · ${appointmentLabel(appt?.type)}`,
126
        summary: parts.join(" · ") || "Sem anotações",
127
        badge:
128
          linkedCount > 0
129
            ? {
130
                label: `${linkedCount} vínculo${linkedCount > 1 ? "s" : ""}`,
131
                variant: "blue",
132
              }
133
            : undefined,
134
        raw: record,
135
      };
136
    }
137

138
    case "ACTIVITY": {
139
      const act = record.activity;
140
      return {
141
        id: `care_action-${record.id}`,
142
        category: "care_action",
143
        subtype: "activity",
144
        timestamp: record.moment.toString(),
145
        title: activityLabel(act?.type),
146
        summary: act?.duration
147
          ? `${act.duration} min`
148
          : "Sem duração registrada",
149
        raw: record,
150
      };
151
    }
152

153
    default:
154
      return {
155
        id: `care_action-${record.id}`,
156
        category: "care_action",
157
        timestamp: record.moment.toString(),
158
        title: "Ação de cuidado",
159
        summary: "",
160
        raw: record,
161
      };
162
  }
163
}