SarahXia0405 commited on
Commit
88959ff
·
verified ·
1 Parent(s): af32ce1

Update web/src/lib/api.ts

Browse files
Files changed (1) hide show
  1. web/src/lib/api.ts +98 -41
web/src/lib/api.ts CHANGED
@@ -1,61 +1,118 @@
1
- // --- Feedback API (NEW) ---
2
- export type FeedbackRating = 'helpful' | 'not_helpful';
 
 
3
 
4
- export interface FeedbackParams {
5
- user: User;
6
-
7
- rating: FeedbackRating;
8
 
9
- // which assistant msg is being rated (optional but recommended)
10
- assistantMessageId?: string;
 
 
 
 
 
11
 
12
- // texts
13
- assistantText: string;
14
- userText?: string;
 
 
15
 
16
- // UI details
17
- tags?: string[]; // optional: structured tags
18
- comment?: string; // optional free-text
 
 
 
19
 
20
- // context
21
- refs?: string[]; // optional
22
- learningMode?: LearningMode;
23
- docType?: FileType | string;
 
24
 
25
- timestampMs?: number;
 
 
 
 
 
 
26
  }
27
 
28
- export async function apiFeedback(params: FeedbackParams) {
29
- const res = await fetch('/api/feedback', {
 
 
 
 
 
 
30
  method: 'POST',
31
  headers: { 'Content-Type': 'application/json' },
32
  body: JSON.stringify({
33
  user_id: params.user.email,
34
- rating: params.rating,
35
- assistant_message_id: params.assistantMessageId ?? null,
36
-
37
- assistant_text: params.assistantText,
38
- user_text: (params.userText ?? '').trim(),
 
39
 
40
- // If your backend supports tags, send tags directly.
41
- // If not, still safe to send; FastAPI will reject unknown fields unless you allow extra.
42
- // So: by default send tags ONLY if you add backend field. Otherwise comment-merge in UI layer.
43
- tags: params.tags ?? [],
 
 
 
44
 
45
- comment: (params.comment ?? '').trim(),
46
- refs: params.refs ?? [],
 
 
 
 
 
 
 
47
 
48
- learning_mode: params.learningMode ? modeMap[params.learningMode] : undefined,
49
- doc_type:
50
- typeof params.docType === 'string'
51
- ? params.docType
52
- : params.docType
53
- ? docTypeMap[params.docType]
54
- : undefined,
55
 
56
- timestamp_ms: params.timestampMs ?? Date.now(),
 
 
 
 
 
 
 
 
 
57
  }),
58
  });
 
 
59
 
60
- return mustJson<{ ok: boolean }>(res);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
 
1
+ // web/src/lib/api.ts
2
+ export type LearningMode = 'concept' | 'socratic' | 'exam' | 'assignment' | 'summary';
3
+ export type Language = 'auto' | 'en' | 'zh';
4
+ export type FileType = 'syllabus' | 'lecture-slides' | 'literature-review' | 'other';
5
 
6
+ export interface User {
7
+ name: string;
8
+ email: string; // use email as user_id
9
+ }
10
 
11
+ const modeMap: Record<LearningMode, string> = {
12
+ concept: 'Concept Explainer',
13
+ socratic: 'Socratic Tutor',
14
+ exam: 'Exam Prep / Quiz',
15
+ assignment: 'Assignment Helper',
16
+ summary: 'Quick Summary',
17
+ };
18
 
19
+ const langMap: Record<Language, string> = {
20
+ auto: 'Auto',
21
+ en: 'English',
22
+ zh: '简体中文',
23
+ };
24
 
25
+ const docTypeMap: Record<FileType, string> = {
26
+ syllabus: 'Syllabus',
27
+ 'lecture-slides': 'Lecture Slides',
28
+ 'literature-review': 'Literature Review / Paper',
29
+ other: 'Other',
30
+ };
31
 
32
+ async function mustJson<T>(res: Response): Promise<T> {
33
+ if (res.ok) return (await res.json()) as T;
34
+ const txt = await res.text().catch(() => '');
35
+ throw new Error(`${res.status} ${res.statusText}${txt ? ` — ${txt}` : ''}`);
36
+ }
37
 
38
+ export async function apiLogin(user: User) {
39
+ const res = await fetch('/api/login', {
40
+ method: 'POST',
41
+ headers: { 'Content-Type': 'application/json' },
42
+ body: JSON.stringify({ name: user.name, user_id: user.email }),
43
+ });
44
+ return mustJson<{ ok: boolean; user: { name: string; user_id: string } }>(res);
45
  }
46
 
47
+ export async function apiChat(params: {
48
+ user: User;
49
+ message: string;
50
+ learningMode: LearningMode;
51
+ language: Language;
52
+ docType?: string; // optional override
53
+ }) {
54
+ const res = await fetch('/api/chat', {
55
  method: 'POST',
56
  headers: { 'Content-Type': 'application/json' },
57
  body: JSON.stringify({
58
  user_id: params.user.email,
59
+ message: params.message,
60
+ learning_mode: modeMap[params.learningMode],
61
+ language_preference: langMap[params.language],
62
+ doc_type: params.docType ?? 'Syllabus',
63
+ }),
64
+ });
65
 
66
+ return mustJson<{
67
+ reply: string;
68
+ refs?: Array<{ source_file?: string; section?: string }>;
69
+ latency_ms?: number;
70
+ session_status_md?: string;
71
+ }>(res);
72
+ }
73
 
74
+ export async function apiUpload(params: {
75
+ user: User;
76
+ file: File;
77
+ fileType: FileType;
78
+ }) {
79
+ const fd = new FormData();
80
+ fd.append('user_id', params.user.email);
81
+ fd.append('doc_type', docTypeMap[params.fileType]);
82
+ fd.append('file', params.file);
83
 
84
+ const res = await fetch('/api/upload', { method: 'POST', body: fd });
85
+ return mustJson<{ ok: boolean; added_chunks: number; status_md: string }>(res);
86
+ }
 
 
 
 
87
 
88
+ export async function apiExport(params: {
89
+ user: User;
90
+ learningMode: LearningMode;
91
+ }) {
92
+ const res = await fetch('/api/export', {
93
+ method: 'POST',
94
+ headers: { 'Content-Type': 'application/json' },
95
+ body: JSON.stringify({
96
+ user_id: params.user.email,
97
+ learning_mode: modeMap[params.learningMode],
98
  }),
99
  });
100
+ return mustJson<{ markdown: string }>(res);
101
+ }
102
 
103
+ export async function apiSummary(params: {
104
+ user: User;
105
+ learningMode: LearningMode;
106
+ language: Language;
107
+ }) {
108
+ const res = await fetch('/api/summary', {
109
+ method: 'POST',
110
+ headers: { 'Content-Type': 'application/json' },
111
+ body: JSON.stringify({
112
+ user_id: params.user.email,
113
+ learning_mode: modeMap[params.learningMode],
114
+ language_preference: langMap[params.language],
115
+ }),
116
+ });
117
+ return mustJson<{ markdown: string }>(res);
118
  }