organiza podcasts apis

This commit is contained in:
thierryverse 2025-11-12 16:59:56 +02:00
parent 78ab020d80
commit 0e488c799d
4 changed files with 302 additions and 185 deletions

View file

@ -1,78 +1,167 @@
import type { ChatDetails } from "@/app/dashboard/[search_space_id]/chats/chats-client";
import type {
Chat,
ChatDetails,
} from "@/app/dashboard/[search_space_id]/chats/chats-client";
import { ResearchMode } from "@/components/chat/types";
import { Message } from "@ai-sdk/react";
export const fetchChatDetails = async (
chatId: string,
authToken: string
): Promise<ChatDetails | null> => {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/chats/${Number(
chatId
)}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${authToken}`,
},
}
);
if (!response.ok) {
throw new Error(`Failed to fetch chat details: ${response.statusText}`);
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/chats/${Number(
chatId
)}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${authToken}`,
},
}
);
return await response.json();
} catch (err) {
console.error("Error fetching chat details:", err);
return null;
if (!response.ok) {
throw new Error(`Failed to fetch chat details: ${response.statusText}`);
}
return await response.json();
};
export const fetchChatsBySearchSpace = async (
searchSpaceId: string,
authToken: string
): Promise<ChatDetails[] | null> => {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/chats?search_space_id=${searchSpaceId}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${authToken}`,
},
}
);
if (!response.ok) {
throw new Error(`Failed to fetch chats: ${response.statusText}`);
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/chats?search_space_id=${searchSpaceId}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${authToken}`,
},
}
);
if (!response.ok) {
throw new Error(`Failed to fetch chats: ${response.statusText}`);
}
return await response.json();
} catch (err) {
console.error("Error fetching chats:", err);
return null;
return await response.json();
};
export const deleteChat = async (chatId: number, authToken: string) => {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/chats/${chatId}`,
{
method: "DELETE",
headers: {
Authorization: `Bearer ${authToken}`,
},
}
);
if (!response.ok) {
throw new Error(`Failed to delete chat: ${response.statusText}`);
}
return await response.json();
};
export const createChat = async (
initialMessage: string,
researchMode: ResearchMode,
selectedConnectors: string[],
authToken: string,
searchSpaceId: number
): Promise<Chat | null> => {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/chats`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${authToken}`,
},
body: JSON.stringify({
type: researchMode,
title: "Untitled Chat",
initial_connectors: selectedConnectors,
messages: [
{
role: "user",
content: initialMessage,
},
],
search_space_id: searchSpaceId,
}),
}
);
if (!response.ok) {
throw new Error(`Failed to create chat: ${response.statusText}`);
}
return await response.json();
};
export const updateChat = async (
chatId: string,
messages: Message[],
researchMode: ResearchMode,
selectedConnectors: string[],
authToken: string,
searchSpaceId: number
) => {
const userMessages = messages.filter((msg) => msg.role === "user");
if (userMessages.length === 0) return;
const title = userMessages[0].content;
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/chats/${Number(
chatId
)}`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${authToken}`,
},
body: JSON.stringify({
type: researchMode,
title: title,
initial_connectors: selectedConnectors,
messages: messages,
search_space_id: searchSpaceId,
}),
}
);
if (!response.ok) {
throw new Error(`Failed to update chat: ${response.statusText}`);
}
};
export const fetchChats = async (
searchSpaceId: string,
limit: number,
skip: number,
authToken: string
) => {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/chats?limit=${limit}&skip=${skip}&search_space_id=${searchSpaceId}`,
{
headers: {
Authorization: `Bearer ${authToken}`,
},
method: "GET",
}
);
export const deleteChat = async (chatId: number, authToken: string) => {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/chats/${chatId}`,
{
method: "DELETE",
headers: {
Authorization: `Bearer ${authToken}`,
},
}
);
if (!response.ok) {
throw new Error(`Failed to fetch chats: ${response.status}`);
}
if (!response.ok) {
throw new Error(`Failed to delete chat: ${response.statusText}`);
}
} catch (err) {
console.error("Error deleting chat:", err);
}
return await response.json();
};

View file

@ -0,0 +1,20 @@
const uploadDocument = async (formData: FormData) => {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/documents/fileupload`,
{
method: "POST",
headers: {
Authorization: `Bearer ${window.localStorage.getItem(
"surfsense_bearer_token"
)}`,
},
body: formData,
}
);
if (!response.ok) {
throw new Error("Upload failed");
}
await response.json();
};

View file

@ -2,49 +2,78 @@ import type { PodcastItem } from "@/app/dashboard/[search_space_id]/podcasts/pod
import type { GeneratePodcastRequest } from "@/components/chat/ChatPanel/ChatPanelContainer";
export const getPodcastByChatId = async (chatId: string, authToken: string) => {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/podcasts/by-chat/${Number(chatId)}`,
{
headers: {
Authorization: `Bearer ${authToken}`,
},
method: "GET",
}
);
const response = await fetch(
`${
process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL
}/api/v1/podcasts/by-chat/${Number(chatId)}`,
{
headers: {
Authorization: `Bearer ${authToken}`,
},
method: "GET",
}
);
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.detail || "Failed to fetch podcast");
}
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.detail || "Failed to fetch podcast");
}
return (await response.json()) as PodcastItem | null;
} catch (err: any) {
console.error("Error fetching podcast:", err);
return null;
}
return (await response.json()) as PodcastItem | null;
};
export const generatePodcast = async (request: GeneratePodcastRequest, authToken: string) => {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/podcasts/generate/`,
{
method: "POST",
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify(request),
}
);
export const generatePodcast = async (
request: GeneratePodcastRequest,
authToken: string
) => {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/podcasts/generate/`,
{
method: "POST",
headers: {
Authorization: `Bearer ${authToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify(request),
}
);
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.detail || "Failed to generate podcast");
}
} catch (error) {
console.error("Error generating podcast:", error);
}
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.detail || "Failed to generate podcast");
}
return await response.json();
};
export const loadPodcast = async (podcast: PodcastItem, authToken: string) => {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/podcasts/${podcast.id}/stream`,
{
headers: {
Authorization: `Bearer ${authToken}`,
},
signal: controller.signal,
}
);
if (!response.ok) {
throw new Error(`Failed to fetch audio stream: ${response.statusText}`);
}
const blob = await response.blob();
const objectUrl = URL.createObjectURL(blob);
return objectUrl;
} catch (error) {
if (error instanceof DOMException && error.name === "AbortError") {
throw new Error("Request timed out. Please try again.");
}
throw error;
} finally {
clearTimeout(timeoutId);
}
};

View file

@ -1,112 +1,91 @@
export const fetchSearchSpaces = async () => {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces`,
{
headers: {
Authorization: `Bearer ${localStorage.getItem(
"surfsense_bearer_token"
)}`,
},
method: "GET",
}
);
if (!response.ok) {
throw new Error("Not authenticated");
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces`,
{
headers: {
Authorization: `Bearer ${localStorage.getItem(
"surfsense_bearer_token"
)}`,
},
method: "GET",
}
);
const data = await response.json();
return data;
} catch (err: any) {
console.error("Error fetching search spaces:", err);
return null;
if (!response.ok) {
throw new Error("Not authenticated");
}
return await response.json();
};
export const handleDeleteSearchSpace = async (id: number) => {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces/${id}`,
{
method: "DELETE",
headers: {
Authorization: `Bearer ${localStorage.getItem(
"surfsense_bearer_token"
)}`,
},
}
);
if (!response.ok) {
throw new Error("Failed to delete search space");
export const deleteSearchSpace = async (id: number) => {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces/${id}`,
{
method: "DELETE",
headers: {
Authorization: `Bearer ${localStorage.getItem(
"surfsense_bearer_token"
)}`,
},
}
} catch (error) {
console.error("Error deleting search space:", error);
return;
);
if (!response.ok) {
throw new Error("Failed to delete search space");
}
return await response.json();
};
export const handleCreateSearchSpace = async (data: {
export const createSearchSpace = async (data: {
name: string;
description: string;
}) => {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${localStorage.getItem(
"surfsense_bearer_token"
)}`,
},
body: JSON.stringify(data),
}
);
if (!response.ok) {
throw new Error("Failed to create search space");
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${localStorage.getItem(
"surfsense_bearer_token"
)}`,
},
body: JSON.stringify(data),
}
);
const result = await response.json();
return result;
} catch (error) {
console.error("Error creating search space:", error);
throw error;
if (!response.ok) {
throw new Error("Failed to create search space");
}
return await response.json();
};
export const fetchSearchSpace = async (searchSpaceId: string) => {
try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces/${searchSpaceId}`,
{
headers: {
Authorization: `Bearer ${localStorage.getItem(
"surfsense_bearer_token"
)}`,
},
method: "GET",
}
);
if (response.status === 401) {
// Clear token and redirect to home
localStorage.removeItem("surfsense_bearer_token");
window.location.href = "/";
throw new Error("Unauthorized: Redirecting to login page");
const response = await fetch(
`${process.env.NEXT_PUBLIC_FASTAPI_BACKEND_URL}/api/v1/searchspaces/${searchSpaceId}`,
{
headers: {
Authorization: `Bearer ${localStorage.getItem(
"surfsense_bearer_token"
)}`,
},
method: "GET",
}
);
if (!response.ok) {
throw new Error(`Failed to fetch search space: ${response.status}`);
}
const data = await response.json();
return data;
} catch (err: any) {
console.error("Error fetching search space:", err);
if (response.status === 401) {
// Clear token and redirect to home
localStorage.removeItem("surfsense_bearer_token");
window.location.href = "/";
throw new Error("Unauthorized: Redirecting to login page");
}
if (!response.ok) {
throw new Error(`Failed to fetch search space: ${response.status}`);
}
return await response.json();
};