From 92d14196425a82118bd546d9fe50c4b493fdae6f Mon Sep 17 00:00:00 2001 From: mukimovd <41473651-mukimovd@users.noreply.replit.com> Date: Thu, 8 May 2025 00:54:20 +0000 Subject: [PATCH] Restructure components and add annotation system for enhanced reading Refactors component structure, implements AnnotationSystem.tsx, and adds new components related to annotations and authors. Replit-Commit-Author: Agent Replit-Commit-Session-Id: cbacfb18-842a-4116-a907-18c0105ad8ec Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/39b5c689-6e8a-4d5a-9792-69cc81a56534/d1468a00-d93a-40b6-8ef2-3b7ba89b0f76.jpg --- COMPONENT-IMPLEMENTATION-PRIORITY.md | 159 +++++ COMPONENT-STRUCTURE.md | 174 +++++ .../annotation/AnnotationSystem.tsx | 380 +++++++++++ .../annotation/annotation-browser.tsx | 0 .../annotation/annotation-editor.tsx | 0 .../annotation/annotation-filters.tsx | 0 .../src/components/annotation/inline-form.tsx | 0 client/src/components/authors/AuthorChip.tsx | 80 +++ client/src/components/authors/author-card.tsx | 0 .../src/components/authors/author-editor.tsx | 0 .../src/components/authors/author-header.tsx | 0 .../src/components/authors/author-stats.tsx | 0 .../components/authors/related-authors.tsx | 0 client/src/components/blog/blog-editor.tsx | 0 client/src/components/blog/blog-preview.tsx | 0 client/src/components/blog/featured-post.tsx | 0 .../components/blog/publication-scheduler.tsx | 0 client/src/components/blog/tag-manager.tsx | 0 .../src/components/comment/comment-editor.tsx | 0 .../components/comment/comment-filters.tsx | 0 .../src/components/comment/comment-thread.tsx | 0 .../components/comment/moderation-tools.tsx | 0 .../components/dashboard/activity-feed.tsx | 0 .../components/dashboard/content-queue.tsx | 0 .../components/dashboard/dashboard-header.tsx | 0 .../src/components/dashboard/role-badge.tsx | 0 .../src/components/dashboard/stats-card.tsx | 0 .../src/components/dashboard/stats-chart.tsx | 0 .../components/patterns/action-toolbar.tsx | 0 client/src/components/patterns/card-grid.tsx | 0 .../src/components/patterns/empty-states.tsx | 0 .../components/patterns/filter-controls.tsx | 0 .../src/components/patterns/modal-forms.tsx | 0 .../src/components/search/FilterSidebar.tsx | 364 ++++++++++ client/src/components/search/SearchBar.tsx | 172 +++++ .../src/components/search/advanced-search.tsx | 0 client/src/components/search/pagination.tsx | 0 .../src/components/search/results-toggle.tsx | 0 .../src/components/search/search-filters.tsx | 0 .../src/components/search/sort-controls.tsx | 0 client/src/components/ui/autocomplete.tsx | 0 client/src/components/ui/breadcrumbs.tsx | 0 client/src/components/ui/code-highlighter.tsx | 0 client/src/components/ui/color-picker.tsx | 0 .../src/components/ui/comparison-slider.tsx | 0 .../src/components/ui/confirmation-dialog.tsx | 0 .../src/components/ui/date-range-picker.tsx | 0 client/src/components/ui/empty-state.tsx | 0 client/src/components/ui/error-state.tsx | 0 .../src/components/ui/expandable-search.tsx | 0 client/src/components/ui/file-uploader.tsx | 0 client/src/components/ui/file-viewer.tsx | 0 client/src/components/ui/form-wizard.tsx | 0 client/src/components/ui/grid.tsx | 0 client/src/components/ui/language-tag.tsx | 15 + client/src/components/ui/loading-spinner.tsx | 0 client/src/components/ui/masonry.tsx | 0 client/src/components/ui/multi-select.tsx | 0 .../src/components/ui/notification-badge.tsx | 0 client/src/components/ui/rating.tsx | 0 .../components/ui/responsive-container.tsx | 0 client/src/components/ui/rich-text-editor.tsx | 0 client/src/components/ui/share-buttons.tsx | 0 client/src/components/ui/split-pane.tsx | 0 client/src/components/ui/spotlight.tsx | 0 client/src/components/ui/stat-card.tsx | 0 client/src/components/ui/status-indicator.tsx | 0 client/src/components/ui/stepper.tsx | 0 client/src/components/ui/tag-cloud.tsx | 0 client/src/components/ui/tag-input.tsx | 0 client/src/components/ui/timeline.tsx | 0 client/src/components/ui/tree-view.tsx | 0 .../components/ui/typography/code-block.tsx | 0 .../src/components/ui/typography/heading.tsx | 0 .../components/ui/typography/paragraph.tsx | 0 client/src/components/ui/typography/quote.tsx | 0 .../src/components/ui/vertical-navigation.tsx | 0 .../src/components/user/bookmarks-manager.tsx | 0 .../src/components/user/preferences-form.tsx | 0 client/src/components/user/profile-card.tsx | 0 .../src/components/user/reading-progress.tsx | 0 client/src/components/user/user-avatar.tsx | 0 .../work/EnhancedLineNumberedText.tsx | 230 +++++++ .../components/work/EnhancedReadingView.tsx | 630 ++++++++++++++++++ .../src/components/work/LineNumberedText.tsx | 118 ++++ .../src/components/work/ReadingControls.tsx | 165 +++++ client/src/components/work/ReadingView.tsx | 255 +++++++ .../components/work/TranslationSelector.tsx | 300 +++++++++ client/src/components/work/WorkCard.tsx | 149 +++++ .../src/components/work/comparison-view.tsx | 0 client/src/components/work/related-works.tsx | 0 client/src/components/work/work-editor.tsx | 0 client/src/components/work/work-header.tsx | 0 client/src/components/work/work-status.tsx | 0 94 files changed, 3191 insertions(+) create mode 100644 COMPONENT-IMPLEMENTATION-PRIORITY.md create mode 100644 COMPONENT-STRUCTURE.md create mode 100644 client/src/components/annotation/AnnotationSystem.tsx create mode 100644 client/src/components/annotation/annotation-browser.tsx create mode 100644 client/src/components/annotation/annotation-editor.tsx create mode 100644 client/src/components/annotation/annotation-filters.tsx create mode 100644 client/src/components/annotation/inline-form.tsx create mode 100644 client/src/components/authors/AuthorChip.tsx create mode 100644 client/src/components/authors/author-card.tsx create mode 100644 client/src/components/authors/author-editor.tsx create mode 100644 client/src/components/authors/author-header.tsx create mode 100644 client/src/components/authors/author-stats.tsx create mode 100644 client/src/components/authors/related-authors.tsx create mode 100644 client/src/components/blog/blog-editor.tsx create mode 100644 client/src/components/blog/blog-preview.tsx create mode 100644 client/src/components/blog/featured-post.tsx create mode 100644 client/src/components/blog/publication-scheduler.tsx create mode 100644 client/src/components/blog/tag-manager.tsx create mode 100644 client/src/components/comment/comment-editor.tsx create mode 100644 client/src/components/comment/comment-filters.tsx create mode 100644 client/src/components/comment/comment-thread.tsx create mode 100644 client/src/components/comment/moderation-tools.tsx create mode 100644 client/src/components/dashboard/activity-feed.tsx create mode 100644 client/src/components/dashboard/content-queue.tsx create mode 100644 client/src/components/dashboard/dashboard-header.tsx create mode 100644 client/src/components/dashboard/role-badge.tsx create mode 100644 client/src/components/dashboard/stats-card.tsx create mode 100644 client/src/components/dashboard/stats-chart.tsx create mode 100644 client/src/components/patterns/action-toolbar.tsx create mode 100644 client/src/components/patterns/card-grid.tsx create mode 100644 client/src/components/patterns/empty-states.tsx create mode 100644 client/src/components/patterns/filter-controls.tsx create mode 100644 client/src/components/patterns/modal-forms.tsx create mode 100644 client/src/components/search/FilterSidebar.tsx create mode 100644 client/src/components/search/SearchBar.tsx create mode 100644 client/src/components/search/advanced-search.tsx create mode 100644 client/src/components/search/pagination.tsx create mode 100644 client/src/components/search/results-toggle.tsx create mode 100644 client/src/components/search/search-filters.tsx create mode 100644 client/src/components/search/sort-controls.tsx create mode 100644 client/src/components/ui/autocomplete.tsx create mode 100644 client/src/components/ui/breadcrumbs.tsx create mode 100644 client/src/components/ui/code-highlighter.tsx create mode 100644 client/src/components/ui/color-picker.tsx create mode 100644 client/src/components/ui/comparison-slider.tsx create mode 100644 client/src/components/ui/confirmation-dialog.tsx create mode 100644 client/src/components/ui/date-range-picker.tsx create mode 100644 client/src/components/ui/empty-state.tsx create mode 100644 client/src/components/ui/error-state.tsx create mode 100644 client/src/components/ui/expandable-search.tsx create mode 100644 client/src/components/ui/file-uploader.tsx create mode 100644 client/src/components/ui/file-viewer.tsx create mode 100644 client/src/components/ui/form-wizard.tsx create mode 100644 client/src/components/ui/grid.tsx create mode 100644 client/src/components/ui/language-tag.tsx create mode 100644 client/src/components/ui/loading-spinner.tsx create mode 100644 client/src/components/ui/masonry.tsx create mode 100644 client/src/components/ui/multi-select.tsx create mode 100644 client/src/components/ui/notification-badge.tsx create mode 100644 client/src/components/ui/rating.tsx create mode 100644 client/src/components/ui/responsive-container.tsx create mode 100644 client/src/components/ui/rich-text-editor.tsx create mode 100644 client/src/components/ui/share-buttons.tsx create mode 100644 client/src/components/ui/split-pane.tsx create mode 100644 client/src/components/ui/spotlight.tsx create mode 100644 client/src/components/ui/stat-card.tsx create mode 100644 client/src/components/ui/status-indicator.tsx create mode 100644 client/src/components/ui/stepper.tsx create mode 100644 client/src/components/ui/tag-cloud.tsx create mode 100644 client/src/components/ui/tag-input.tsx create mode 100644 client/src/components/ui/timeline.tsx create mode 100644 client/src/components/ui/tree-view.tsx create mode 100644 client/src/components/ui/typography/code-block.tsx create mode 100644 client/src/components/ui/typography/heading.tsx create mode 100644 client/src/components/ui/typography/paragraph.tsx create mode 100644 client/src/components/ui/typography/quote.tsx create mode 100644 client/src/components/ui/vertical-navigation.tsx create mode 100644 client/src/components/user/bookmarks-manager.tsx create mode 100644 client/src/components/user/preferences-form.tsx create mode 100644 client/src/components/user/profile-card.tsx create mode 100644 client/src/components/user/reading-progress.tsx create mode 100644 client/src/components/user/user-avatar.tsx create mode 100644 client/src/components/work/EnhancedLineNumberedText.tsx create mode 100644 client/src/components/work/EnhancedReadingView.tsx create mode 100644 client/src/components/work/LineNumberedText.tsx create mode 100644 client/src/components/work/ReadingControls.tsx create mode 100644 client/src/components/work/ReadingView.tsx create mode 100644 client/src/components/work/TranslationSelector.tsx create mode 100644 client/src/components/work/WorkCard.tsx create mode 100644 client/src/components/work/comparison-view.tsx create mode 100644 client/src/components/work/related-works.tsx create mode 100644 client/src/components/work/work-editor.tsx create mode 100644 client/src/components/work/work-header.tsx create mode 100644 client/src/components/work/work-status.tsx diff --git a/COMPONENT-IMPLEMENTATION-PRIORITY.md b/COMPONENT-IMPLEMENTATION-PRIORITY.md new file mode 100644 index 0000000..d2d5dd1 --- /dev/null +++ b/COMPONENT-IMPLEMENTATION-PRIORITY.md @@ -0,0 +1,159 @@ +# Component Implementation Priority + +Based on the component analysis and the needs of the Tercul platform, the following implementation priority is recommended: + +## Phase 1: Critical UI Components (Week 1) + +### 1. Rich Text Editor (High Priority) +**File**: `components/ui/rich-text-editor.tsx` + +Essential for blog post creation and editing, this component will enable content creators to format their posts with rich text features. + +### 2. Stat Card (High Priority) +**File**: `components/dashboard/stats-card.tsx` + +Needed for dashboard statistics display, this component will provide a consistent way to display metrics throughout the dashboard. + +### 3. Empty State (High Priority) +**File**: `components/ui/empty-state.tsx` + +Used throughout the application to show when data is missing, this component will provide a consistent user experience for empty states. + +### 4. Tag Input (High Priority) +**File**: `components/ui/tag-input.tsx` + +Used for blog post tags, work metadata, and filtering, this component will enable users to add and manage tags. + +## Phase 2: Dashboard Components (Week 2) + +### 1. Dashboard Header +**File**: `components/dashboard/dashboard-header.tsx` + +Provides a consistent header for all dashboard pages with breadcrumbs and actions. + +### 2. Activity Feed +**File**: `components/dashboard/activity-feed.tsx` + +Shows recent editorial activity in the dashboard, enabling editors to track changes. + +### 3. Content Queue +**File**: `components/dashboard/content-queue.tsx` + +Displays pending content that needs review or approval, essential for editorial workflows. + +## Phase 3: Work Management Components (Week 3) + +### 1. Work Editor +**File**: `components/work/work-editor.tsx` + +Enables creation and editing of literary works with specialized features. + +### 2. Work Header +**File**: `components/work/work-header.tsx` + +Provides consistent display of work metadata across the platform. + +### 3. Comparison View +**File**: `components/work/comparison-view.tsx` + +Enables side-by-side comparison of translations with synchronized scrolling. + +## Phase 4: Author Components (Week 4) + +### 1. Author Editor +**File**: `components/authors/author-editor.tsx` + +Enables creation and editing of author profiles with timeline events. + +### 2. Author Card +**File**: `components/authors/author-card.tsx` + +Provides a consistent way to display author information in lists and grids. + +### 3. Author Header +**File**: `components/authors/author-header.tsx` + +Displays author information at the top of author profile pages. + +## Phase 5: Comment and Annotation Components (Week 5) + +### 1. Comment Thread +**File**: `components/comment/comment-thread.tsx` + +Enables threaded discussions on works and blog posts with proper nesting. + +### 2. Annotation Editor +**File**: `components/annotation/annotation-editor.tsx` + +Provides a specialized interface for creating and editing annotations on works. + +### 3. Annotation Browser +**File**: `components/annotation/annotation-browser.tsx` + +Enables users to browse and filter annotations on works. + +## Phase 6: Search and User Components (Week 6) + +### 1. Advanced Search +**File**: `components/search/advanced-search.tsx` + +Provides powerful search capabilities with multiple filters and options. + +### 2. Profile Card +**File**: `components/user/profile-card.tsx` + +Displays user information consistently across the platform. + +### 3. Reading Progress +**File**: `components/user/reading-progress.tsx` + +Tracks and displays user reading progress on works. + +## Phase 7: Blog Components (Week 7) + +### 1. Blog Editor +**File**: `components/blog/blog-editor.tsx` + +Provides a specialized interface for creating and editing blog posts, using the rich text editor. + +### 2. Blog Preview +**File**: `components/blog/blog-preview.tsx` + +Displays blog post previews in lists and grids with consistent styling. + +### 3. Publication Scheduler +**File**: `components/blog/publication-scheduler.tsx` + +Enables scheduling of blog posts for future publication. + +## Phase 8: Pattern Components (Week 8) + +### 1. Modal Forms +**File**: `components/patterns/modal-forms.tsx` + +Provides consistent patterns for forms in modal dialogs throughout the platform. + +### 2. Action Toolbar +**File**: `components/patterns/action-toolbar.tsx` + +Standardizes action button groups for consistent UX across the platform. + +### 3. Card Grid +**File**: `components/patterns/card-grid.tsx` + +Provides a consistent way to display grids of cards (works, authors, blog posts). + +## Implementation Approach + +For each component: + +1. **Define Props Interface**: Start by defining the component's props interface with proper TypeScript types +2. **Create Basic Structure**: Implement the basic component structure with proper HTML semantics +3. **Add Styling**: Apply consistent styling using Tailwind CSS classes +4. **Implement Behavior**: Add state management and event handlers +5. **Test Edge Cases**: Ensure the component handles all edge cases gracefully +6. **Add Accessibility**: Ensure proper ARIA attributes and keyboard navigation +7. **Document Usage**: Add JSDoc comments explaining how to use the component +8. **Create Examples**: Include usage examples in comments or documentation + +This phased approach ensures that the most critical components are implemented first, providing immediate value while building toward a complete component library. diff --git a/COMPONENT-STRUCTURE.md b/COMPONENT-STRUCTURE.md new file mode 100644 index 0000000..62a9e78 --- /dev/null +++ b/COMPONENT-STRUCTURE.md @@ -0,0 +1,174 @@ +# Tercul Component Structure + +## Overview + +The component structure has been reorganized to improve maintainability, scalability, and code reuse. Components are organized by their domain and functionality. + +## Directory Structure + +### UI Components (`/components/ui`) +Basic, reusable UI components with minimal business logic. These serve as building blocks for more complex components. + +- **Typography Components** (`/components/ui/typography`) + - heading.tsx - For h1-h6 headings with consistent styling + - paragraph.tsx - For text content with various styles + - quote.tsx - For blockquotes and citations + - code-block.tsx - For code snippets + +- **Data Display Components** + - stat-card.tsx - For displaying statistics + - timeline.tsx - For chronological events visualization + - tree-view.tsx - For hierarchical data + - tag-cloud.tsx - For tag visualization + - file-viewer.tsx - For previewing documents + - code-highlighter.tsx - For syntax highlighting + +- **Feedback Components** + - empty-state.tsx - For when no data is available + - error-state.tsx - For error handling + - loading-spinner.tsx - For loading indicators + - status-indicator.tsx - For success/failure states + - confirmation-dialog.tsx - For user confirmations + +- **Navigation Components** + - stepper.tsx - For multi-step processes + - vertical-navigation.tsx - For side navigation + - breadcrumbs.tsx - For navigation trails + +- **Form Components** + - rich-text-editor.tsx - For content creation + - tag-input.tsx - For adding/managing tags + - date-range-picker.tsx - For date selection + - file-uploader.tsx - For file uploads + - multi-select.tsx - For multiple selections + - autocomplete.tsx - For search suggestions + - form-wizard.tsx - For multi-step forms + +- **Layout Components** + - grid.tsx - For grid layouts + - masonry.tsx - For pinterest-style layouts + - split-pane.tsx - For resizable panels + - spotlight.tsx - For featured content + - responsive-container.tsx - For responsive design + +- **Specialized Components** + - color-picker.tsx - For color selection + - rating.tsx - For rating inputs + - comparison-slider.tsx - For before/after comparisons + - share-buttons.tsx - For social sharing + - expandable-search.tsx - For search interfaces + - notification-badge.tsx - For alerts/notifications + +### Domain-Specific Components + +#### Blog Components (`/components/blog`) +Components specific to the blog functionality. + +- blog-editor.tsx - For creating/editing blog posts +- blog-preview.tsx - For displaying blog post cards +- tag-manager.tsx - For managing post tags +- publication-scheduler.tsx - For scheduling posts +- featured-post.tsx - For highlighting posts + +#### Dashboard Components (`/components/dashboard`) +Components for the editorial dashboard. + +- stats-card.tsx - For dashboard statistics +- activity-feed.tsx - For recent activities +- content-queue.tsx - For approval workflows +- stats-chart.tsx - For data visualization +- dashboard-header.tsx - For dashboard navigation +- role-badge.tsx - For user role indication + +#### Work Components (`/components/work`) +Components for literary works management and display. + +- work-editor.tsx - For creating/editing works +- work-header.tsx - For work metadata display +- work-status.tsx - For publication status +- related-works.tsx - For similar works +- comparison-view.tsx - For comparing translations +- EnhancedReadingView.tsx - Enhanced reading experience +- LineNumberedText.tsx - Text with line numbers +- EnhancedLineNumberedText.tsx - Advanced text display +- TranslationSelector.tsx - For selecting translations +- ReadingControls.tsx - Reading interface controls +- ReadingView.tsx - Main reading component +- WorkCard.tsx - Work preview card + +#### Author Components (`/components/authors`) +Components for author profiles and management. + +- author-editor.tsx - For creating/editing authors +- author-card.tsx - Author preview card +- author-header.tsx - Author profile header +- author-stats.tsx - Author statistics +- related-authors.tsx - Similar authors +- AuthorTimeline.tsx - Author timeline component +- AuthorChip.tsx - Small author reference + +#### Comment Components (`/components/comment`) +Components for the comment system. + +- comment-thread.tsx - Threaded comments +- comment-editor.tsx - For writing comments +- moderation-tools.tsx - For moderating comments +- comment-filters.tsx - For filtering comments + +#### Annotation Components (`/components/annotation`) +Components for the annotation system. + +- AnnotationSystem.tsx - Main annotation component +- annotation-editor.tsx - For creating annotations +- annotation-browser.tsx - For browsing annotations +- inline-form.tsx - For inline annotation creation +- annotation-filters.tsx - For filtering annotations + +#### User Components (`/components/user`) +Components for user profiles and management. + +- profile-card.tsx - User profile display +- user-avatar.tsx - User avatar with status +- reading-progress.tsx - Reading progress tracker +- bookmarks-manager.tsx - Bookmarks interface +- preferences-form.tsx - User settings + +#### Search Components (`/components/search`) +Components for search functionality. + +- SearchBar.tsx - Main search input +- advanced-search.tsx - Advanced search interface +- search-filters.tsx - Search filter controls +- results-toggle.tsx - Grid/list view toggle +- pagination.tsx - Result pagination +- sort-controls.tsx - Result sorting +- FilterSidebar.tsx - Sidebar with filters + +#### Pattern Components (`/components/patterns`) +Reusable component patterns and combinations. + +- empty-states.tsx - Empty state patterns +- modal-forms.tsx - Modal dialog forms +- action-toolbar.tsx - Action button groups +- filter-controls.tsx - Standardized filters +- card-grid.tsx - Grid of cards + +### Layout Components (`/components/layout`) +Components for page layout. + +- PageLayout.tsx - Standard page wrapper +- DashboardLayout.tsx - Dashboard layout +- Footer.tsx - Site footer +- NavHeader.tsx - Navigation header + +## Implementation Status + +Most components are currently empty placeholder files. The implementation priority should follow the order outlined in the COMPONENT-IMPLEMENTATION-PLAN.md document. + +## Key Benefits of This Structure + +1. **Separation of Concerns**: UI components are separate from domain-specific components +2. **Reusability**: Common patterns are extracted into reusable components +3. **Discoverability**: Developers can easily find components by their domain +4. **Maintainability**: Related components are grouped together +5. **Scalability**: New domains can be added without affecting existing structure diff --git a/client/src/components/annotation/AnnotationSystem.tsx b/client/src/components/annotation/AnnotationSystem.tsx new file mode 100644 index 0000000..4af3854 --- /dev/null +++ b/client/src/components/annotation/AnnotationSystem.tsx @@ -0,0 +1,380 @@ +import { useState, useEffect, useRef } from 'react'; +import { Annotation } from '@/lib/types'; +import { Button } from '@/components/ui/button'; +import { Textarea } from '@/components/ui/textarea'; +import { Card, CardContent, CardHeader, CardTitle, CardFooter } from '@/components/ui/card'; +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; +import { useToast } from '@/hooks/use-toast'; +import { apiRequest, queryClient } from '@/lib/queryClient'; +import { MessageSquare, X, ThumbsUp, MessageCircle, Edit, Trash } from 'lucide-react'; + +interface AnnotationSystemProps { + workId: number; + selectedLineNumber: number | null; + onClose: () => void; + translationId?: number; +} + +export function AnnotationSystem({ + workId, + selectedLineNumber, + onClose, + translationId +}: AnnotationSystemProps) { + const { toast } = useToast(); + const [annotations, setAnnotations] = useState([]); + const [isLoading, setIsLoading] = useState(true); + const [newAnnotation, setNewAnnotation] = useState(''); + const [isSubmitting, setIsSubmitting] = useState(false); + const [editingAnnotationId, setEditingAnnotationId] = useState(null); + const [editText, setEditText] = useState(''); + + const annotationRef = useRef(null); + + // Mock user data - in a real app this would come from auth + const currentUser = { + id: 1, + name: 'Anonymous', + avatar: null + }; + + // Fetch annotations for the selected line + useEffect(() => { + if (!selectedLineNumber) return; + + setIsLoading(true); + + // Simulate API call to get annotations for the selected line + setTimeout(() => { + // These would be fetched from the API in a real app + const mockAnnotations: Annotation[] = [ + { + id: 1, + workId, + translationId, + lineNumber: selectedLineNumber, + userId: 2, + userName: 'Literary Scholar', + userAvatar: null, + content: 'This line demonstrates the poet\'s use of alliteration, creating a rhythmic pattern that emphasizes the emotional tone.', + createdAt: new Date(Date.now() - 1000000), + likes: 5, + liked: false + }, + { + id: 2, + workId, + translationId, + lineNumber: selectedLineNumber, + userId: 3, + userName: 'Translator', + userAvatar: null, + content: 'The original meaning in Russian contains a wordplay that is difficult to capture in English. A more literal translation might read as...', + createdAt: new Date(Date.now() - 5000000), + likes: 12, + liked: true + } + ]; + + setAnnotations(mockAnnotations); + setIsLoading(false); + }, 600); + }, [workId, selectedLineNumber, translationId]); + + // Submit new annotation + const handleSubmitAnnotation = async () => { + if (!newAnnotation.trim() || !selectedLineNumber) return; + + setIsSubmitting(true); + + try { + // In a real app, this would be an API call + // Mock API response + const newAnnotationObj: Annotation = { + id: Date.now(), + workId, + translationId, + lineNumber: selectedLineNumber, + userId: currentUser.id, + userName: currentUser.name, + userAvatar: currentUser.avatar, + content: newAnnotation, + createdAt: new Date(), + likes: 0, + liked: false + }; + + // Optimistically update UI + setAnnotations(prev => [newAnnotationObj, ...prev]); + setNewAnnotation(''); + + toast({ + description: "Annotation added successfully", + }); + + // In a real app, this would invalidate the query cache + // queryClient.invalidateQueries({ queryKey: [`/api/works/${workId}/annotations/${selectedLineNumber}`] }); + } catch (error) { + toast({ + title: "Error", + description: "Failed to add annotation", + variant: "destructive", + }); + } finally { + setIsSubmitting(false); + } + }; + + // Like an annotation + const handleLikeAnnotation = async (annotationId: number) => { + try { + // Optimistically update UI + setAnnotations(prev => + prev.map(anno => + anno.id === annotationId + ? { ...anno, liked: !anno.liked, likes: anno.liked ? anno.likes - 1 : anno.likes + 1 } + : anno + ) + ); + + // In a real app, this would be an API call + // await apiRequest('POST', `/api/annotations/${annotationId}/like`, { userId: currentUser.id }); + } catch (error) { + // Revert optimistic update if there's an error + setAnnotations(prev => [...prev]); + toast({ + title: "Error", + description: "Failed to update like", + variant: "destructive", + }); + } + }; + + // Delete annotation + const handleDeleteAnnotation = async (annotationId: number) => { + try { + // Optimistically update UI + const filteredAnnotations = annotations.filter(anno => anno.id !== annotationId); + setAnnotations(filteredAnnotations); + + // In a real app, this would be an API call + // await apiRequest('DELETE', `/api/annotations/${annotationId}`); + + toast({ + description: "Annotation deleted", + }); + } catch (error) { + // Revert optimistic update if there's an error + toast({ + title: "Error", + description: "Failed to delete annotation", + variant: "destructive", + }); + } + }; + + // Start editing an annotation + const handleStartEdit = (annotation: Annotation) => { + setEditingAnnotationId(annotation.id); + setEditText(annotation.content); + }; + + // Save edited annotation + const handleSaveEdit = async (annotationId: number) => { + if (!editText.trim()) return; + + try { + // Optimistically update UI + setAnnotations(prev => + prev.map(anno => + anno.id === annotationId + ? { ...anno, content: editText } + : anno + ) + ); + + // Reset edit state + setEditingAnnotationId(null); + setEditText(''); + + // In a real app, this would be an API call + // await apiRequest('PATCH', `/api/annotations/${annotationId}`, { content: editText }); + + toast({ + description: "Annotation updated", + }); + } catch (error) { + toast({ + title: "Error", + description: "Failed to update annotation", + variant: "destructive", + }); + } + }; + + // Cancel editing + const handleCancelEdit = () => { + setEditingAnnotationId(null); + setEditText(''); + }; + + // If no line is selected, don't render anything + if (!selectedLineNumber) return null; + + return ( +
+
+
+ +

+ Line {selectedLineNumber} Annotations +

+
+ +
+ +
+ {/* New annotation form */} +
+