import React, { useState, useEffect, useRef, useCallback } from "react"; import { Task } from "../../entities/Task"; import { useToast } from "../Shared/ToastContext"; import { useTranslation } from "react-i18next"; import { createInboxItemWithStore } from "../../utils/inboxService"; import { isAuthError } from "../../utils/authUtils"; // import UrlPreview from "../Shared/UrlPreview"; // import { UrlTitleResult } from "../../utils/urlService"; interface SimplifiedTaskModalProps { isOpen: boolean; onClose: () => void; onSave: (task: Task) => Promise; initialText?: string; editMode?: boolean; onEdit?: (text: string) => Promise; } const SimplifiedTaskModal: React.FC = ({ isOpen, onClose, onSave, initialText = "", editMode = false, onEdit, }) => { const { t } = useTranslation(); const [inputText, setInputText] = useState(initialText); const modalRef = useRef(null); const [isClosing, setIsClosing] = useState(false); const [isSaving, setIsSaving] = useState(false); const { showSuccessToast, showErrorToast } = useToast(); const nameInputRef = useRef(null); const [saveMode, setSaveMode] = useState<'task' | 'inbox'>('inbox'); // const [urlPreview, setUrlPreview] = useState(null); useEffect(() => { if (isOpen && nameInputRef.current) { nameInputRef.current.focus(); } }, [isOpen]); const handleChange = (e: React.ChangeEvent) => { setInputText(e.target.value); }; const handleSubmit = useCallback(async () => { if (!inputText.trim() || isSaving) return; setIsSaving(true); try { if (editMode && onEdit) { await onEdit(inputText.trim()); setIsClosing(true); setTimeout(() => { onClose(); setIsClosing(false); }, 300); return; // Exit early to prevent creating duplicates } if (saveMode === 'task') { const newTask: Task = { name: inputText.trim(), status: "not_started", }; try { await onSave(newTask); showSuccessToast(t('task.createSuccess')); setInputText(''); handleClose(); } catch (error: any) { // If it's an auth error, don't show error toast (user will be redirected) if (isAuthError(error)) { return; } throw error; } } else { try { await createInboxItemWithStore(inputText.trim()); showSuccessToast(t('inbox.itemAdded')); handleClose(); } catch (error) { console.error('Failed to create inbox item:', error); showErrorToast(t('inbox.addError')); setIsSaving(false); } } } catch (error) { console.error('Failed to save:', error); if (editMode) { showErrorToast(t('inbox.updateError')); } else { showErrorToast(saveMode === 'task' ? t('task.createError') : t('inbox.addError')); } } finally { setIsSaving(false); } }, [inputText, isSaving, editMode, onEdit, saveMode, onSave, showSuccessToast, showErrorToast, t, onClose]); const handleClose = useCallback(() => { setIsClosing(true); setTimeout(() => { onClose(); if (!editMode) { setInputText(""); setSaveMode('inbox'); } setIsClosing(false); }, 300); }, [onClose, editMode]); useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (modalRef.current && !modalRef.current.contains(event.target as Node)) { handleClose(); } }; if (isOpen) { document.addEventListener("mousedown", handleClickOutside); } return () => { document.removeEventListener("mousedown", handleClickOutside); }; }, [isOpen]); useEffect(() => { const handleKeyDown = (event: KeyboardEvent) => { if (event.key === "Escape") { handleClose(); } }; if (isOpen) { document.addEventListener("keydown", handleKeyDown); } return () => { document.removeEventListener("keydown", handleKeyDown); }; }, [isOpen, handleClose]); // Only depend on isOpen and handleClose if (!isOpen) return null; return (
{ if (e.key === 'Enter' && !e.shiftKey && !isSaving) { e.preventDefault(); handleSubmit(); } }} />
{/* URL Preview disabled */} {/* */}
); }; export default SimplifiedTaskModal;