- Added ShareModal component to manage user and link sharing for documents. - Created AuthContext to handle user authentication state and token management. - Updated useYjsDocument hook to support sharing via tokens. - Enhanced Yjs document creation to include user information and authentication tokens. - Introduced AuthCallback page to handle authentication redirects and token processing. - Modified EditorPage and KanbanPage to include share functionality. - Created LoginPage with Google and GitHub authentication options. - Added styles for LoginPage. - Defined types for authentication and sharing in respective TypeScript files.
70 lines
2.2 KiB
TypeScript
70 lines
2.2 KiB
TypeScript
import { authFetch, API_BASE_URL } from './client';
|
|
|
|
export type DocumentType = {
|
|
id: string;
|
|
name: string;
|
|
type: "editor" | "kanban";
|
|
created_at: string;
|
|
updated_at: string;
|
|
}
|
|
|
|
export type CreateDocumentRequest = {
|
|
name: string;
|
|
type: "editor" | "kanban";
|
|
}
|
|
|
|
export const documentsApi = {
|
|
// List all documents
|
|
list: async (): Promise<{ documents: DocumentType[]; total: number }> => {
|
|
const response = await authFetch(`${API_BASE_URL}/documents`);
|
|
if (!response.ok) throw new Error("Failed to fetch documents");
|
|
return response.json();
|
|
},
|
|
|
|
// Get a single document
|
|
get: async (id: string): Promise<DocumentType> => {
|
|
const response = await authFetch(`${API_BASE_URL}/documents/${id}`);
|
|
if (!response.ok) throw new Error("Failed to fetch document");
|
|
return response.json();
|
|
},
|
|
|
|
// Create a new document
|
|
create: async (data: CreateDocumentRequest): Promise<DocumentType> => {
|
|
const response = await authFetch(`${API_BASE_URL}/documents`, {
|
|
method: "POST",
|
|
body: JSON.stringify(data),
|
|
});
|
|
if (!response.ok) throw new Error("Failed to create document");
|
|
return response.json();
|
|
},
|
|
|
|
// Delete a document
|
|
delete: async (id: string): Promise<void> => {
|
|
const response = await authFetch(`${API_BASE_URL}/documents/${id}`, {
|
|
method: "DELETE",
|
|
});
|
|
if (!response.ok) throw new Error("Failed to delete document");
|
|
},
|
|
|
|
// Get document Yjs state
|
|
getState: async (id: string): Promise<Uint8Array> => {
|
|
const response = await authFetch(`${API_BASE_URL}/documents/${id}/state`);
|
|
if (!response.ok) throw new Error("Failed to fetch document state");
|
|
const arrayBuffer = await response.arrayBuffer();
|
|
return new Uint8Array(arrayBuffer);
|
|
},
|
|
|
|
// Update document Yjs state
|
|
updateState: async (id: string, state: Uint8Array): Promise<void> => {
|
|
// Create a new ArrayBuffer copy to ensure compatibility
|
|
const buffer = new ArrayBuffer(state.byteLength);
|
|
new Uint8Array(buffer).set(state);
|
|
|
|
const response = await authFetch(`${API_BASE_URL}/documents/${id}/state`, {
|
|
method: "PUT",
|
|
headers: { "Content-Type": "application/octet-stream" },
|
|
body: buffer,
|
|
});
|
|
if (!response.ok) throw new Error("Failed to update document state");
|
|
},
|
|
}; |