'use client'; import { useState, useRef, useEffect } from 'react'; import { Card } from '@/components/ui/Card'; import { TagInput } from '@/components/ui/TagInput'; import { TaskStatus, TaskPriority } from '@/lib/types'; import { CreateTaskData } from '@/clients/tasks-client'; import { getAllPriorities } from '@/lib/status-config'; interface QuickAddTaskProps { status: TaskStatus; onSubmit: (data: CreateTaskData) => Promise; onCancel: () => void; // Contexte pour les swimlanes swimlaneContext?: { type: 'tag' | 'priority'; value: string; // nom du tag ou clé de la priorité }; } export function QuickAddTask({ status, onSubmit, onCancel, swimlaneContext }: QuickAddTaskProps) { // Fonction pour initialiser les données selon le contexte const getInitialFormData = (): CreateTaskData => { const baseData: CreateTaskData = { title: '', description: '', status, priority: 'medium' as TaskPriority, tags: [], dueDate: undefined }; // Pré-remplir selon le contexte de swimlane if (swimlaneContext) { if (swimlaneContext.type === 'tag' && swimlaneContext.value !== 'Sans tag') { baseData.tags = [swimlaneContext.value]; } else if (swimlaneContext.type === 'priority') { baseData.priority = swimlaneContext.value as TaskPriority; } } return baseData; }; const [formData, setFormData] = useState(getInitialFormData()); const [isSubmitting, setIsSubmitting] = useState(false); const [activeField, setActiveField] = useState<'title' | 'description' | 'tags' | 'date' | null>('title'); const titleRef = useRef(null); // Focus automatique sur le titre useEffect(() => { titleRef.current?.focus(); }, []); const handleSubmit = async () => { const trimmedTitle = formData.title.trim(); console.log('handleSubmit called:', { trimmedTitle, isSubmitting }); if (!trimmedTitle || isSubmitting) return; setIsSubmitting(true); try { console.log('Submitting task:', { ...formData, title: trimmedTitle }); await onSubmit({ ...formData, title: trimmedTitle }); // Réinitialiser pour la prochaine tâche (en gardant le contexte) setFormData(getInitialFormData()); setActiveField('title'); setIsSubmitting(false); titleRef.current?.focus(); } catch (error) { console.error('Erreur lors de la création:', error); setIsSubmitting(false); } }; const handleKeyDown = (e: React.KeyboardEvent, field: string) => { console.log('Key pressed:', e.key, 'field:', field, 'title:', formData.title); // Seulement intercepter les touches spécifiques qu'on veut gérer if (e.key === 'Enter') { e.preventDefault(); e.stopPropagation(); if (field === 'title' && formData.title.trim()) { console.log('Calling handleSubmit from title'); handleSubmit(); } else if (field === 'tags') { // TagInput gère ses propres événements Enter } else if (formData.title.trim()) { // Permettre création depuis n'importe quel champ si titre rempli console.log('Calling handleSubmit from other field'); handleSubmit(); } } else if (e.key === 'Escape') { e.preventDefault(); onCancel(); } else if (e.key === 'Tab' && !e.metaKey && !e.ctrlKey) { // Navigation entre les champs seulement si pas de modificateur e.preventDefault(); const fields = ['title', 'description', 'tags', 'date']; const currentIndex = fields.indexOf(activeField || 'title'); const nextField = fields[(currentIndex + 1) % fields.length] as typeof activeField; setActiveField(nextField); } // Laisser passer tous les autres événements (y compris les raccourcis système) }; const handleTagsChange = (tags: string[]) => { setFormData(prev => ({ ...prev, tags })); }; const handleBlur = (e: React.FocusEvent) => { // Vérifier si le focus reste dans le composant setTimeout(() => { const currentTarget = e.currentTarget; const relatedTarget = e.relatedTarget as Node | null; // Si le focus sort complètement du composant ET qu'il n'y a pas de titre if (currentTarget && (!relatedTarget || !currentTarget.contains(relatedTarget)) && !formData.title.trim()) { onCancel(); } }, 100); }; return (
{/* Header avec titre et priorité */}
setFormData(prev => ({ ...prev, title: e.target.value }))} onKeyDown={(e) => handleKeyDown(e, 'title')} onFocus={() => setActiveField('title')} placeholder="Titre de la tâche..." disabled={isSubmitting} className="flex-1 bg-transparent border-none outline-none text-[var(--foreground)] font-mono text-sm font-medium placeholder-[var(--muted-foreground)] leading-tight" /> {/* Indicateur de priorité */}
{/* Description */}