Add Znakopis feature with document and sentence management

- Implemented Znakopis page with document and sentence CRUD operations
- Added backend routes for documents and sentences
- Created UI components for sentence editing and display
- Added sentence store for state management
- Integrated select component for document selection
- Updated README with Phase 3 completion status
- Removed obsolete fix-colors.md file
This commit is contained in:
2026-01-17 18:50:53 +01:00
parent 2b768d4c13
commit 8bdd4f6368
17 changed files with 1654 additions and 190 deletions

View File

@@ -0,0 +1,125 @@
import api from './api';
export interface DocumentToken {
id: string;
tokenIndex: number;
termId: string | null;
displayText: string;
isPunctuation: boolean;
term?: any;
}
export interface Sentence {
id: string;
sentenceIndex: number;
rawText: string | null;
tokens: DocumentToken[];
}
export interface DocumentPage {
id: string;
pageIndex: number;
title: string | null;
sentences: Sentence[];
}
export interface Document {
id: string;
title: string;
description: string | null;
visibility: string;
createdAt: string;
updatedAt: string;
pages: DocumentPage[];
}
export interface CreateDocumentData {
title: string;
description?: string;
visibility?: 'PRIVATE' | 'SHARED' | 'PUBLIC';
}
export interface UpdateDocumentData {
title?: string;
description?: string;
visibility?: 'PRIVATE' | 'SHARED' | 'PUBLIC';
}
export interface CreateSentenceData {
tokens: {
termId: string | null;
displayText: string;
isPunctuation: boolean;
}[];
}
export const documentApi = {
// Get all documents for the current user
async getDocuments(): Promise<Document[]> {
const response = await api.get('/api/documents');
return response.data.documents;
},
// Get a single document by ID
async getDocument(id: string): Promise<Document> {
const response = await api.get(`/api/documents/${id}`);
return response.data.document;
},
// Create a new document
async createDocument(data: CreateDocumentData): Promise<Document> {
const response = await api.post('/api/documents', data);
return response.data.document;
},
// Update a document
async updateDocument(id: string, data: UpdateDocumentData): Promise<Document> {
const response = await api.patch(`/api/documents/${id}`, data);
return response.data.document;
},
// Delete a document
async deleteDocument(id: string): Promise<void> {
await api.delete(`/api/documents/${id}`);
},
// Create a new page in a document
async createPage(documentId: string, title?: string): Promise<DocumentPage> {
const response = await api.post(`/api/${documentId}/pages`, { title });
return response.data.page;
},
// Create a new sentence on a page
async createSentence(
documentId: string,
pageIndex: number,
data: CreateSentenceData
): Promise<Sentence> {
const response = await api.post(
`/api/${documentId}/pages/${pageIndex}/sentences`,
data
);
return response.data.sentence;
},
// Update sentence tokens (reorder, add, remove)
async updateSentenceTokens(
sentenceId: string,
tokens: {
termId: string | null;
displayText: string;
isPunctuation: boolean;
}[]
): Promise<Sentence> {
const response = await api.patch(`/api/sentences/${sentenceId}/tokens`, {
tokens,
});
return response.data.sentence;
},
// Delete a sentence
async deleteSentence(sentenceId: string): Promise<void> {
await api.delete(`/api/sentences/${sentenceId}`);
},
};