'use client' import { useEffect, useMemo, useState, useTransition } from 'react' import { formatDistanceToNow } from 'date-fns' import { fr } from 'date-fns/locale/fr' import { enUS } from 'date-fns/locale/en-US' import { History, Loader2, RotateCcw, Trash2, GitBranchPlus } from 'lucide-react' import { toast } from 'sonner' import { getNoteHistory, restoreNoteVersion, deleteNoteHistoryEntry } from '@/app/actions/notes' import { Button } from '@/components/ui/button' import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from '@/components/ui/dialog' import { useLanguage } from '@/lib/i18n' import type { Note, NoteHistoryEntry } from '@/lib/types' import { cn } from '@/lib/utils' interface NoteHistoryModalProps { open: boolean onOpenChange: (open: boolean) => void note: Note | null enabled: boolean onEnableHistory: () => Promise onRestored: (note: Note) => void } function getDateLocale(language: string) { if (language === 'fr') return fr return enUS } export function NoteHistoryModal({ open, onOpenChange, note, enabled, onEnableHistory, onRestored, }: NoteHistoryModalProps) { const { t, language } = useLanguage() const [entries, setEntries] = useState([]) const [selectedId, setSelectedId] = useState(null) const [isLoading, setIsLoading] = useState(false) const [isRestoring, startRestoring] = useTransition() const [isEnabling, startEnabling] = useTransition() useEffect(() => { if (!open || !note || !enabled) return let cancelled = false setIsLoading(true) getNoteHistory(note.id, 50) .then((result) => { if (cancelled) return setEntries(result) setSelectedId(result[0]?.id ?? null) }) .catch((error) => { console.error('Failed to load note history:', error) toast.error(t('general.error')) }) .finally(() => { if (!cancelled) setIsLoading(false) }) return () => { cancelled = true } }, [open, note, enabled, t]) const selectedEntry = useMemo( () => entries.find((entry) => entry.id === selectedId) ?? null, [entries, selectedId] ) const handleRestore = () => { if (!note || !selectedEntry) return startRestoring(async () => { try { const restored = await restoreNoteVersion(note.id, selectedEntry.id) onRestored(restored) toast.success(t('notes.historyRestored') || 'Version restaurée') } catch (error) { console.error('Failed to restore history entry:', error) toast.error(t('general.error')) } }) } const handleEnable = () => { startEnabling(async () => { try { await onEnableHistory() toast.success(t('notes.historyEnabled') || 'History activé') } catch (error) { console.error('Failed to enable history:', error) toast.error(t('general.error')) } }) } const handleDeleteEntry = (entryId: string) => { if (!note) return if (!confirm(t('notes.deleteVersionConfirm') || 'Supprimer cette version définitivement ?')) return startRestoring(async () => { try { await deleteNoteHistoryEntry(note.id, entryId) setEntries((prev) => prev.filter((e) => e.id !== entryId)) if (selectedId === entryId) { setSelectedId(null) } toast.success(t('notes.versionDeleted') || 'Version supprimée') } catch (error) { console.error('Failed to delete history entry:', error) toast.error(t('general.error')) } }) } return ( {t('notes.history') || 'Historique'} {note?.title || t('notes.untitled') || 'Sans titre'} {!enabled ? (

{t('notes.historyDisabledTitle') || 'Historique des versions'}

{t('notes.historyDisabledDesc') || "Suivez les modifications de cette note au fil du temps. Activez l'historique pour commencer à enregistrer des versions."}

) : (
{isLoading ? (
{t('general.loading')}
) : entries.length === 0 ? (

{t('notes.historyEmpty') || 'Aucune version disponible'}

) : (
{entries.map((entry) => (
))}
)}
{selectedEntry ? (

{t('notes.title') || 'Titre'}

{selectedEntry.title || t('notes.untitled') || 'Sans titre'}

{t('notes.content') || 'Contenu'}

                      {selectedEntry.content || ''}
                    
) : (

{t('notes.historySelectVersion') || 'Sélectionnez une version pour prévisualiser son contenu'}

)}
)} {enabled && selectedEntry && ( )}
) }