import React, { useState, useEffect, useRef, useCallback } from 'react'; import TagInput from '../../TagInput'; // Adjust the import path import { Note } from '../../entities/Note'; // Import the centralized Note type import { useDataContext } from '../../contexts/DataContext'; // Use DataContext interface NoteModalProps { isOpen: boolean; onClose: () => void; note?: Note | null; // If null, it's for new note creation onSave?: (note: Note) => void; // Optional callback for saving } const NoteModal: React.FC = ({ isOpen, onClose, note }) => { const { createNote, updateNote } = useDataContext(); // Use create and update methods from DataContext const [formData, setFormData] = useState( note || { title: '', content: '', tags: [], } ); const [availableTags, setAvailableTags] = useState([]); const [error, setError] = useState(null); const modalRef = useRef(null); // Fetch available tags when the modal opens useEffect(() => { if (isOpen) { const fetchAvailableTags = async () => { try { const response = await fetch('/api/tags', { credentials: 'include', headers: { Accept: 'application/json', }, }); if (response.ok) { const data = await response.json(); setAvailableTags(data.map((tag: { name: string }) => tag.name)); } else { console.error('Failed to fetch available tags'); } } catch (err) { console.error('Error fetching available tags:', err); } }; fetchAvailableTags(); } }, [isOpen]); // Close modal if clicked outside useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (modalRef.current && !modalRef.current.contains(event.target as Node)) { onClose(); } }; if (isOpen) { document.addEventListener('mousedown', handleClickOutside); } return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [isOpen, onClose]); // Handle input change const handleChange = ( e: React.ChangeEvent ) => { const { name, value } = e.target; setFormData((prev) => ({ ...prev, [name]: value, })); }; // Handle tags change const handleTagsChange = useCallback((newTags: string[]) => { setFormData((prev) => ({ ...prev, tags: newTags.map((tagName) => ({ id: null, name: tagName })), })); }, []); // Handle form submit const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!formData.title.trim() || !formData.content.trim()) { setError('Title and Content are required.'); return; } try { if (note?.id) { await updateNote(note.id, formData); // Call updateNote if editing } else { await createNote(formData); // Call createNote if creating } onClose(); // Close modal after saving } catch (err) { console.error('Error saving note:', err); setError('Failed to save note.'); } }; if (!isOpen) return null; return (
{/* Note Title */}
{/* Note Content */}