import React, { useEffect, useState } from 'react'; import { useParams, Link, useNavigate } from 'react-router-dom'; import { PencilSquareIcon, TrashIcon, TagIcon, FolderIcon, } from '@heroicons/react/24/solid'; import ConfirmDialog from '../Shared/ConfirmDialog'; import NoteModal from './NoteModal'; import MarkdownRenderer from '../Shared/MarkdownRenderer'; import { Note } from '../../entities/Note'; import { fetchNoteBySlug, deleteNote as apiDeleteNote, updateNote as apiUpdateNote, } from '../../utils/notesService'; import { createProject, fetchProjects } from '../../utils/projectsService'; import { Project } from '../../entities/Project'; const NoteDetails: React.FC = () => { const { uidSlug } = useParams<{ uidSlug: string }>(); const [note, setNote] = useState(null); const [isNoteModalOpen, setIsNoteModalOpen] = useState(false); const [isConfirmDialogOpen, setIsConfirmDialogOpen] = useState(false); const [noteToDelete, setNoteToDelete] = useState(null); const [isLoading, setIsLoading] = useState(true); const [isError, setIsError] = useState(false); const [projects, setProjects] = useState([]); const navigate = useNavigate(); // Dispatch global modal events useEffect(() => { const fetchNote = async () => { try { setIsLoading(true); const foundNote = await fetchNoteBySlug(uidSlug!); setNote(foundNote || null); if (!foundNote) { setIsError(true); } } catch (err) { setIsError(true); console.error('Error fetching note:', err); } finally { setIsLoading(false); } }; fetchNote(); }, [uidSlug]); // Load projects for the modal useEffect(() => { const loadProjects = async () => { try { const fetchedProjects = await fetchProjects('all', ''); setProjects(fetchedProjects); } catch (error) { console.error('Error loading projects:', error); } }; loadProjects(); }, []); const handleDeleteNote = async () => { if (!noteToDelete) return; try { await apiDeleteNote(noteToDelete.id!); navigate('/notes'); } catch (err) { console.error('Error deleting note:', err); } }; const handleSaveNote = async (updatedNote: Note) => { try { if (updatedNote.id !== undefined) { const savedNote = await apiUpdateNote( updatedNote.id, updatedNote ); setNote(savedNote); } else { console.error('Error: Note ID is undefined.'); } } catch (err) { console.error('Error saving note:', err); } setIsNoteModalOpen(false); }; const handleEditNote = () => { setIsNoteModalOpen(true); }; const handleCreateProject = async (name: string) => { try { const newProject = await createProject({ name, priority: 'low', }); setProjects((prev) => [...prev, newProject]); return newProject; } catch (error) { console.error('Error creating project:', error); throw error; } }; const handleOpenConfirmDialog = (note: Note) => { setNoteToDelete(note); setIsConfirmDialogOpen(true); }; if (isLoading) { return (
Loading note details...
); } if (isError || !note) { return (
{isError ? 'Error loading note details.' : 'Note not found.'}
); } return (
{/* Header Section with Title and Action Buttons */}

{note.title}

{/* Project and Tags under title */} {(note.project || note.Project || (note.tags && note.tags.length > 0) || (note.Tags && note.Tags.length > 0)) && (
{(note.project || note.Project) && (
{ ( note.project || note.Project )?.name }
)} {(note.project || note.Project) && ((note.tags && note.tags.length > 0) || (note.Tags && note.Tags.length > 0)) && ( )} {((note.tags && note.tags.length > 0) || (note.Tags && note.Tags.length > 0)) && (
{(note.tags || note.Tags || []) .map((tag) => tag.name) .join(', ')}
)}
)}
{/* Action Buttons */}
{/* Note Content */}
{/* NoteModal for editing */} {isNoteModalOpen && ( setIsNoteModalOpen(false)} onSave={handleSaveNote} onDelete={async (noteId) => { try { await apiDeleteNote(noteId); navigate('/notes'); } catch (err) { console.error('Error deleting note:', err); } }} note={note} projects={projects} onCreateProject={handleCreateProject} /> )} {/* ConfirmDialog */} {isConfirmDialogOpen && noteToDelete && ( { setIsConfirmDialogOpen(false); setNoteToDelete(null); }} /> )}
); }; export default NoteDetails;