import React, { useState, useEffect, useMemo } from 'react'; import { Link } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { BookOpenIcon, PencilSquareIcon, TrashIcon, MagnifyingGlassIcon, TagIcon, FolderIcon, } from '@heroicons/react/24/solid'; import NoteModal from './Note/NoteModal'; import ConfirmDialog from './Shared/ConfirmDialog'; import { Note } from '../entities/Note'; import { fetchNotes, createNote, updateNote, deleteNote as apiDeleteNote, } from '../utils/notesService'; import { useStore } from '../store/useStore'; import { createProject, fetchProjects } from '../utils/projectsService'; const Notes: React.FC = () => { const { t } = useTranslation(); const [notes, setNotes] = useState([]); const [selectedNote, setSelectedNote] = useState(null); const [isNoteModalOpen, setIsNoteModalOpen] = useState(false); const [isConfirmDialogOpen, setIsConfirmDialogOpen] = useState(false); const [noteToDelete, setNoteToDelete] = useState(null); const [searchQuery, setSearchQuery] = useState(''); const [isLoading, setIsLoading] = useState(true); // Get projects from store const projects = useStore((state) => state.projectsStore.projects); const { setProjects } = useStore((state) => state.projectsStore); // Memoize projects to ensure stable reference const memoizedProjects = useMemo(() => projects || [], [projects]); const [isError, setIsError] = useState(false); const [hoveredNoteId, setHoveredNoteId] = useState(null); useEffect(() => { const loadNotes = async () => { setIsLoading(true); try { const fetchedNotes = await fetchNotes(); setNotes(fetchedNotes); } catch (error) { console.error('Error loading notes:', error); setIsError(true); } finally { setIsLoading(false); } }; loadNotes(); }, []); // Load projects if not available - force load every time for debugging useEffect(() => { const loadProjectsIfNeeded = async () => { try { // Fetch all projects (active and inactive) const fetchedProjects = await fetchProjects('all', ''); setProjects(fetchedProjects); } catch (error) { console.error('Error loading projects:', error); } }; loadProjectsIfNeeded(); }, []); // Remove dependencies to force it to run once const handleDeleteNote = async () => { if (!noteToDelete) return; try { await apiDeleteNote(noteToDelete.id!); setNotes((prev) => prev.filter((note) => note.id !== noteToDelete.id) ); setIsConfirmDialogOpen(false); setNoteToDelete(null); } catch (err) { console.error('Error deleting note:', err); } }; const handleEditNote = (note: Note) => { setSelectedNote(note); setIsNoteModalOpen(true); }; const handleSaveNote = async (noteData: Note) => { try { let updatedNotes; if (noteData.id) { const savedNote = await updateNote(noteData.id, noteData); updatedNotes = notes.map((note) => note.id === noteData.id ? savedNote : note ); } else { const newNote = await createNote(noteData); updatedNotes = [...notes, newNote]; } setNotes(updatedNotes); setIsNoteModalOpen(false); setSelectedNote(null); } catch (err) { console.error('Error saving note:', err); } }; const handleCreateProject = async (name: string) => { try { const newProject = await createProject({ name, priority: 'medium', }); return newProject; } catch (error) { console.error('Error creating project:', error); throw error; } }; const filteredNotes = notes.filter( (note) => note.title.toLowerCase().includes(searchQuery.toLowerCase()) || note.content.toLowerCase().includes(searchQuery.toLowerCase()) ); if (isLoading) { return (
{t('notes.loading')}
); } if (isError) { return (
{t('notes.error')}
); } return (
{/* Notes Header */}

{t('notes.title')}

{/* Search Bar with Icon */}
setSearchQuery(e.target.value)} className="w-full bg-transparent border-none focus:ring-0 focus:outline-none dark:text-white" />
{/* Notes List */} {filteredNotes.length === 0 ? (

{t('notes.noNotesFound')}

) : (
    {filteredNotes.map((note) => (
  • setHoveredNoteId(note.id || null) } onMouseLeave={() => setHoveredNoteId(null)} >
    {note.title} {/* Project and Tags */} {(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(', ')}
    )}
    )}
  • ))}
)} {/* NoteModal */} {isNoteModalOpen && ( { setIsNoteModalOpen(false); }} onSave={handleSaveNote} onDelete={async (noteId) => { try { await apiDeleteNote(noteId); setNotes((prev) => prev.filter((note) => note.id !== noteId) ); setIsNoteModalOpen(false); setSelectedNote(null); } catch (err) { console.error('Error deleting note:', err); } }} note={selectedNote} projects={ projects?.length > 0 ? projects : ([ { id: 1, name: 'Test Project 1', active: true, priority: 'medium', }, { id: 2, name: 'tududi', active: true, priority: 'high', }, ] as any) } onCreateProject={handleCreateProject} /> )} {/* ConfirmDialog */} {isConfirmDialogOpen && noteToDelete && ( setIsConfirmDialogOpen(false)} /> )}
); }; export default Notes;