aki-008 commited on
Commit
1423ea9
·
1 Parent(s): eccafb0

chore: noteservice added

Browse files
Files changed (1) hide show
  1. Frontend/src/api/notesService.ts +118 -0
Frontend/src/api/notesService.ts ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Frontend/src/api/notesService.ts
2
+ import API from "./api"; // Your existing Axios instance
3
+ import { type AxiosResponse } from "axios";
4
+
5
+ // Interface matching the Backend Pydantic model "NoteInfo"
6
+ export interface Note {
7
+ id: number;
8
+ filename: string;
9
+ created_at: string;
10
+ }
11
+
12
+ export interface ChatMessage {
13
+ role: "user" | "assistant";
14
+ content: string;
15
+ }
16
+
17
+ // 1. Fetch the list of PDFs for the Sidebar
18
+ export const fetchNotes = async (): Promise<Note[]> => {
19
+ const response: AxiosResponse<Note[]> = await API.get("/notes/");
20
+ return response.data;
21
+ };
22
+
23
+ // 2. Upload a new PDF
24
+ export const uploadNote = async (file: File): Promise<Note> => {
25
+ const formData = new FormData();
26
+ formData.append("file", file); // Must match backend: file: UploadFile
27
+
28
+ const response = await API.post("/notes/upload_notes", formData, {
29
+ headers: {
30
+ "Content-Type": "multipart/form-data",
31
+ },
32
+ });
33
+
34
+ // The backend returns complex data, but we just need the basics for the list update
35
+ // Mapping the response to our Note interface structure locally if needed,
36
+ // or you can adjust the backend response.
37
+ // For now, we assume the backend returns the created doc info or we construct it.
38
+ return {
39
+ id: response.data.doc_id,
40
+ filename: response.data.filename,
41
+ created_at: new Date().toISOString(), // Optimistic timestamp
42
+ };
43
+ };
44
+
45
+ // 3. Get the URL for the PDF content (for the viewer)
46
+ // We don't use Axios here because we want a direct URL for the iframe/object
47
+ export const getNoteContentUrl = (noteId: number): string => {
48
+ const token = localStorage.getItem("token");
49
+ // We append the token as a query param or handle auth differently for iframes.
50
+ // Since standard Bearer auth is hard with simple <iframe src="...">,
51
+ // we will fetch the blob via JS and create an ObjectURL in the component.
52
+ return `/api/v1/notes/${noteId}/content`;
53
+ };
54
+
55
+ // 4. Fetch the Blob directly (Better for Auth)
56
+ export const fetchNoteBlob = async (noteId: number): Promise<Blob> => {
57
+ const response = await API.get(`/notes/${noteId}/content`, {
58
+ responseType: "blob",
59
+ });
60
+ return response.data;
61
+ };
62
+
63
+ // 5. Create or Get Chat Session
64
+ export const createChatSession = async (
65
+ pdfId: number,
66
+ name: string = "New Chat"
67
+ ) => {
68
+ const response = await API.post("/notes/sessions", { pdf_id: pdfId, name });
69
+ return response.data;
70
+ };
71
+
72
+ // 6. Get Chat History
73
+ export const fetchChatHistory = async (sessionId: string) => {
74
+ const response = await API.get(`/notes/history/${sessionId}`);
75
+ return response.data;
76
+ };
77
+
78
+ // 7. Stream Chat (Special Handling using fetch API)
79
+ export const streamChatRequest = async (
80
+ sessionId: string,
81
+ userMessage: string,
82
+ onChunk: (chunk: string) => void,
83
+ onError: (err: any) => void
84
+ ) => {
85
+ const token = localStorage.getItem("token");
86
+
87
+ try {
88
+ const response = await fetch(
89
+ `http://localhost:8000/api/v1/notes/chat/${sessionId}?user_prompt=${encodeURIComponent(
90
+ userMessage
91
+ )}`,
92
+ {
93
+ method: "POST",
94
+ headers: {
95
+ Authorization: `Bearer ${token}`,
96
+ "Content-Type": "application/json",
97
+ },
98
+ // Note: Your backend expects query params for user_prompt based on the route signature:
99
+ // @router.post("/chat/{session_id}") async def chat_session(..., user_prompt: str, ...)
100
+ // It is NOT a JSON body in your current backend code (check notes.py:207).
101
+ }
102
+ );
103
+
104
+ if (!response.body) throw new Error("No response body");
105
+
106
+ const reader = response.body.getReader();
107
+ const decoder = new TextDecoder("utf-8");
108
+
109
+ while (true) {
110
+ const { done, value } = await reader.read();
111
+ if (done) break;
112
+ const chunk = decoder.decode(value, { stream: true });
113
+ onChunk(chunk);
114
+ }
115
+ } catch (err) {
116
+ onError(err);
117
+ }
118
+ };