Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions frontend/chat-ui/src/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '';
const API_KEY = import.meta.env.VITE_API_KEY || '';

async function request(method, path, body) {
const headers = { 'x-api-key': API_KEY };
const options = { method, headers };
if (body !== undefined) {
headers['Content-Type'] = 'application/json';
options.body = JSON.stringify(body);
}

const res = await fetch(`${API_BASE_URL}${path}`, options);
const text = await res.text();
let data = null;
if (text) {
try {
data = JSON.parse(text);
} catch (err) {
throw err;
}
}
if (!res.ok) {
const error = new Error(data?.message || `Request failed with status ${res.status}`);
error.status = res.status;
error.data = data;
throw error;
}
return data;
}

export const get = (path) => request('GET', path);
export const post = (path, body) => request('POST', path, body);
export const put = (path, body) => request('PUT', path, body);
export const del = (path) => request('DELETE', path);

export default { get, post, put, del };
12 changes: 2 additions & 10 deletions frontend/chat-ui/src/components/InputBox.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useState, useRef } from 'react';
import { useStore } from '../store';

const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '';
import { post } from '../api';

export default function InputBox() {
const { state, dispatch } = useStore();
Expand Down Expand Up @@ -29,14 +28,7 @@ export default function InputBox() {
data: fileData,
};
}
await fetch(`${API_BASE_URL}/messages/${state.currentConversation.id}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': import.meta.env.VITE_API_KEY,
},
body: JSON.stringify(payload),
});
await post(`/messages/${state.currentConversation.id}`, payload);
dispatch({ type: 'ADD_MESSAGE', message: { id: Date.now().toString(), ...payload } });
setText('');
setFile(null);
Expand Down
32 changes: 5 additions & 27 deletions frontend/chat-ui/src/components/Sidebar.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import React, { useEffect } from 'react';
import { useStore } from '../store';

const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || '';
import { get, post } from '../api';

export default function Sidebar() {
const { state, dispatch } = useStore();

useEffect(() => {
const load = async () => {
try {
const res = await fetch(`${API_BASE_URL}/conversations`, {
headers: { 'x-api-key': import.meta.env.VITE_API_KEY }
});
const data = await res.json();
const data = await get('/conversations');
dispatch({ type: 'SET_CONVERSATIONS', conversations: data });
} catch (e) {
console.error(e);
Expand All @@ -23,15 +19,7 @@ export default function Sidebar() {

const newChat = async () => {
try {
const res = await fetch(`${API_BASE_URL}/conversations`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': import.meta.env.VITE_API_KEY,
},
body: JSON.stringify({}),
});
const convo = await res.json();
const convo = await post('/conversations', {});
dispatch({ type: 'SET_CURRENT_CONVERSATION', conversation: convo });
dispatch({ type: 'SET_MESSAGES', messages: [] });
} catch (e) {
Expand All @@ -41,10 +29,7 @@ export default function Sidebar() {

const openConversation = async (c) => {
try {
const res = await fetch(`${API_BASE_URL}/messages/${c.id}`, {
headers: { 'x-api-key': import.meta.env.VITE_API_KEY },
});
const msgs = await res.json();
const msgs = await get(`/messages/${c.id}`);
dispatch({ type: 'SET_CURRENT_CONVERSATION', conversation: c });
dispatch({ type: 'SET_MESSAGES', messages: msgs });
} catch (e) {
Expand All @@ -54,14 +39,7 @@ export default function Sidebar() {

const togglePin = async (c) => {
try {
await fetch(`${API_BASE_URL}/conversations/${c.id}/pin`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': import.meta.env.VITE_API_KEY,
},
body: JSON.stringify({ pinned: !c.pinned }),
});
await post(`/conversations/${c.id}/pin`, { pinned: !c.pinned });
const updated = { ...c, pinned: !c.pinned };
dispatch({
type: 'SET_CONVERSATIONS',
Expand Down