File size: 4,499 Bytes
9e7d4f7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
export const BACKEND_URL = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1' 
  ? "http://127.0.0.1:8000" 
  : "https://amogh1221-serinity.hf.space";

// Helper to get token
export function getToken() {
  return localStorage.getItem('serinity_token');
}

// Global fetch wrapper for auth
export async function authFetch(url, options = {}) {
  const token = getToken();
  const headers = { ...options.headers };
  
  if (token) {
    headers['Authorization'] = `Bearer ${token}`;
  }
  
  // Don't override FormData headers
  if (!(options.body instanceof FormData) && !headers['Content-Type']) {
    headers['Content-Type'] = 'application/json';
  }

  const res = await fetch(url, { ...options, headers });
  
  // Handle unauthorized globaly
  if (res.status === 401) {
    localStorage.removeItem('serinity_token');
    window.dispatchEvent(new Event('unauthorized'));
    throw new Error('Unauthorized');
  }
  
  return res;
}

/**
 * Fetches the list of patients associated with the logged-in user.
 * @returns {Promise<Array>} List of patient objects.
 */
export async function fetchPatientsList() {
  const res = await authFetch(`${BACKEND_URL}/patients`, { cache: "no-store" });
  return res.json();
}

/**
 * Loads the dashboard data for a specific patient.
 * @param {string} patientId 
 * @returns {Promise<Object>} Dashboard overview data.
 */
export async function loadDashboard(patientId) {
  const res = await authFetch(`${BACKEND_URL}/patients/${patientId}/dashboard`, { cache: "no-store" });
  if (!res.ok) throw new Error("Dashboard load failed");
  return res.json();
}

/**
 * Resets a patient's historical profile and sessions.
 * @param {string} patientId 
 */
export async function resetPatientProfile(patientId) {
  return authFetch(`${BACKEND_URL}/patients/${patientId}/reset`, { method: "POST" });
}

/**
 * Deletes a patient profile completely.
 * @param {string} patientId 
 */
export async function deletePatientProfile(patientId) {
  return authFetch(`${BACKEND_URL}/patients/${patientId}`, { method: "DELETE" });
}

/**
 * Creates a new patient profile linked to the user.
 * @param {Object} data 
 * @returns {Promise<Object>} The created patient data.
 */
export async function createPatientProfile(data) {
  const res = await authFetch(`${BACKEND_URL}/patients/create`, {
    method: "POST",
    body: JSON.stringify(data)
  });
  return res.json();
}

export async function pingHealth() {
  // health doesn't need auth, but authFetch is safe to use
  return fetch(`${BACKEND_URL}/health`);
}

export async function startSessionReq(patientId) {
  const res = await authFetch(`${BACKEND_URL}/start`, {
    method: "POST",
    body: JSON.stringify({ patient_id: patientId })
  });
  if (!res.ok) {
    let errorDetail = `HTTP Error ${res.status}`;
    try {
      const data = await res.json();
      errorDetail = data.detail || errorDetail;
    } catch(e) {}
    throw new Error(errorDetail);
  }
  return res.json();
}

export async function sendChatText(sessionId, patientId, message, emotion) {
  const res = await authFetch(`${BACKEND_URL}/chat_text`, {
    method: "POST",
    body: JSON.stringify({
      message: message,
      session_id: sessionId,
      patient_id: patientId,
      emotion: emotion
    })
  });
  if (!res.ok) {
    let errorDetail = `HTTP Error ${res.status}`;
    try {
      const data = await res.json();
      errorDetail = data.detail || errorDetail;
    } catch(e) {}
    throw new Error(errorDetail);
  }
  return res.json();
}

export async function transcribeAudio(audioBlob) {
  const formData = new FormData();
  formData.append('audio', audioBlob, 'recording.webm');
  
  // Custom headers because authFetch handles FormData correctly if Content-Type is omitted
  const res = await authFetch(`${BACKEND_URL}/transcribe`, {
    method: "POST",
    body: formData
  });
  return res.json();
}

export async function endSessionReq(sessionId, patientId) {
  return authFetch(`${BACKEND_URL}/end_session`, {
    method: "POST",
    body: JSON.stringify({
      session_id: sessionId,
      patient_id: patientId
    })
  });
}

export async function getActiveSession(patientId) {
  const res = await authFetch(`${BACKEND_URL}/patients/${patientId}/active_session`, { cache: "no-store" });
  return res.json();
}

export async function getSessionMessages(sessionId) {
  const res = await authFetch(`${BACKEND_URL}/sessions/${sessionId}/messages`, { cache: "no-store" });
  return res.json();
}