diff --git a/src/components/fragments/FragmentEditor.tsx b/src/components/fragments/FragmentEditor.tsx index 2acf5932..469fe7bf 100644 --- a/src/components/fragments/FragmentEditor.tsx +++ b/src/components/fragments/FragmentEditor.tsx @@ -13,6 +13,7 @@ import type { FrozenSection } from '@/lib/api/types' import { RefinementPanel } from '@/components/refinement/RefinementPanel' import { copyFragmentToClipboard } from '@/lib/fragment-clipboard' import { CropDialog } from '@/components/fragments/CropDialog' +import { useConfirm } from '@/components/ui/confirm-dialog' import { Hint, EmptyHint, MetaLabel } from '@/components/ui/prose-text' export interface FragmentPrefill { @@ -37,6 +38,7 @@ export function FragmentEditor({ onSaved, }: FragmentEditorProps) { const queryClient = useQueryClient() + const confirm = useConfirm() const [name, setName] = useState('') const [description, setDescription] = useState('') const [content, setContent] = useState('') @@ -541,8 +543,8 @@ export function FragmentEditor({ size="sm" variant="ghost" className="h-7 text-xs gap-1 text-muted-foreground hover:text-foreground" - onClick={() => { - if (confirm('Archive this fragment?')) { + onClick={async () => { + if (await confirm({ title: 'Archive this fragment?', confirmText: 'Archive' })) { archiveMutation.mutate() } }} @@ -578,8 +580,8 @@ export function FragmentEditor({ size="sm" variant="ghost" className="h-7 text-xs gap-1 text-destructive/70 hover:text-destructive" - onClick={() => { - if (confirm('Permanently delete this fragment? This cannot be undone.')) { + onClick={async () => { + if (await confirm({ title: 'Permanently delete this fragment?', description: 'This cannot be undone.', confirmText: 'Delete', destructive: true })) { deleteMutation.mutate() } }} diff --git a/src/components/prose/ProseBlock.tsx b/src/components/prose/ProseBlock.tsx index 2d108c10..17caaf8e 100644 --- a/src/components/prose/ProseBlock.tsx +++ b/src/components/prose/ProseBlock.tsx @@ -11,6 +11,7 @@ import { type ThoughtStep } from './InlineGenerationInput' import { buildAnnotationHighlighter, formatDialogue, composeTextTransforms, stripEmphasisInDialogue, type Annotation } from '@/lib/character-mentions' import { RefreshCw, Undo2, PenLine, Bug, Trash2, GitBranch, MessageSquare, ChevronLeft, ChevronRight, Info, BookOpen, Volume2, Square } from 'lucide-react' import { Caption } from '@/components/ui/prose-text' +import { useConfirm } from '@/components/ui/confirm-dialog' import { useTtsSettings, useIsReadingFragment, playFragment, stopTts } from '@/lib/tts' interface ProseBlockProps { @@ -119,6 +120,7 @@ export const ProseBlock = memo(function ProseBlock({ void isFirst void isLast const queryClient = useQueryClient() + const confirm = useConfirm() const [actionMode, setActionMode] = useState<'regenerate' | null>(null) const [showUndo, setShowUndo] = useState(false) const [isStreamingAction, setIsStreamingAction] = useState(false) @@ -693,8 +695,8 @@ export const ProseBlock = memo(function ProseBlock({ + + + + )} + + + ) +} diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index ea0c9e8d..4c6d16d4 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -6,6 +6,7 @@ import { } from '@tanstack/react-router' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import { TooltipProvider } from '@/components/ui/tooltip' +import { ConfirmProvider } from '@/components/ui/confirm-dialog' import { ThemeProvider } from '@/lib/theme' import { HelpProvider } from '@/hooks/use-help' import { HelpPanel } from '@/components/help/HelpPanel' @@ -111,12 +112,14 @@ function RootComponent() { - - - - - - + + + + + + + + diff --git a/src/routes/index.tsx b/src/routes/index.tsx index d8219949..42f906e1 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -38,6 +38,7 @@ import { ProviderList, ProviderPanel } from '@/components/settings/ProviderManag import { AboutSection } from '@/components/settings/AboutPanel' import { DesktopUpdatesControls } from '@/components/settings/DesktopUpdatesPanel' import { SectionHeading } from '@/components/settings/primitives' +import { useConfirm } from '@/components/ui/confirm-dialog' const THEME_OPTIONS = [ { value: 'light' as const, label: 'Light', Icon: Sun }, @@ -49,6 +50,7 @@ export const Route = createFileRoute('/')({ component: StoryListPage }) function StoryListPage() { const queryClient = useQueryClient() + const confirm = useConfirm() const navigate = useNavigate() const { theme, setTheme } = useTheme() const [open, setOpen] = useState(false) @@ -661,8 +663,8 @@ function StoryListPage() { key={story.id} story={story} isRecent={i === 0 && sortedStories.length > 1} - onDelete={() => { - if (confirm(`Delete "${story.name}"?`)) { + onDelete={async () => { + if (await confirm({ title: `Delete "${story.name}"?`, description: 'This permanently deletes the story and all its fragments.', confirmText: 'Delete', destructive: true })) { deleteMutation.mutate(story.id) } }}