2026-03-06 17:22:59 +02:00
import React from 'react' ;
import { Dialog , DialogContent , DialogDescription , DialogFooter , DialogHeader , DialogTitle } from '@/components/ui/dialog' ;
import { RiCheckboxBlankLine , RiCheckboxLine } from '@remixicon/react' ;
import type { Session } from '@opencode-ai/sdk/v2' ;
export type DeleteSessionConfirmState = {
session : Session ;
descendantCount : number ;
archivedBucket : boolean ;
} | null ;
export function SessionDeleteConfirmDialog ( props : {
value : DeleteSessionConfirmState ;
setValue : ( next : DeleteSessionConfirmState ) => void ;
showDeletionDialog : boolean ;
setShowDeletionDialog : ( next : boolean ) => void ;
onConfirm : () => Promise < void > | void ;
}) : React . ReactNode {
const { value , setValue , showDeletionDialog , setShowDeletionDialog , onConfirm } = props ;
return (
< Dialog open = { Boolean ( value )} onOpenChange = {( open ) => { if ( ! open ) setValue ( null ); }}>
< DialogContent showCloseButton = { false } className = "max-w-sm gap-5" >
< DialogHeader >
< DialogTitle >{ value ? . archivedBucket ? 'Delete session?' : 'Archive session?' }</ DialogTitle >
< DialogDescription >
{ value && value . descendantCount > 0
? value . archivedBucket
? `" ${ value . session . title || 'Untitled Session' } " and its ${ value . descendantCount } sub-task ${ value . descendantCount === 1 ? '' : 's' } will be permanently deleted.`
: `" ${ value . session . title || 'Untitled Session' } " and its ${ value . descendantCount } sub-task ${ value . descendantCount === 1 ? '' : 's' } will be archived.`
: value ? . archivedBucket
? `" ${ value ? . session . title || 'Untitled Session' } " will be permanently deleted.`
: `" ${ value ? . session . title || 'Untitled Session' } " will be archived.` }
</ DialogDescription >
</ DialogHeader >
< DialogFooter className = "w-full sm:items-center sm:justify-between" >
< button
type = "button"
onClick = {() => setShowDeletionDialog ( ! showDeletionDialog )}
className = "inline-flex items-center gap-1.5 typography-ui-label text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/50"
aria-pressed = { ! showDeletionDialog }
>
{ ! showDeletionDialog ? < RiCheckboxLine className = "h-4 w-4 text-primary" /> : < RiCheckboxBlankLine className = "h-4 w-4" />}
Never ask
</ button >
< div className = "flex items-center gap-2" >
< button
type = "button"
onClick = {() => setValue ( null )}
className = "inline-flex h-8 items-center justify-center rounded-md border border-border px-3 typography-ui-label text-foreground hover:bg-interactive-hover/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50"
>
Cancel
</ button >
< button
type = "button"
onClick = {() => void onConfirm ()}
className = "inline-flex h-8 items-center justify-center rounded-md bg-destructive px-3 typography-ui-label text-destructive-foreground hover:bg-destructive/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-destructive/50"
>
{ value ? . archivedBucket ? 'Delete' : 'Archive' }
</ button >
2026-04-20 23:32:32 +03:00
</ div >
</ DialogFooter >
</ DialogContent >
</ Dialog >
);
}
export type BulkDeleteSessionsConfirmState = {
sessionCount : number ;
archivedBucket : boolean ;
} | null ;
export function BulkSessionDeleteConfirmDialog ( props : {
value : BulkDeleteSessionsConfirmState ;
setValue : ( next : BulkDeleteSessionsConfirmState ) => void ;
showDeletionDialog : boolean ;
setShowDeletionDialog : ( next : boolean ) => void ;
onConfirm : () => Promise < void > | void ;
}) : React . ReactNode {
const { value , setValue , showDeletionDialog , setShowDeletionDialog , onConfirm } = props ;
const archived = value ? . archivedBucket === true ;
const n = value ? . sessionCount ?? 0 ;
const plural = n === 1 ? '' : 's' ;
const title = archived ? 'Delete sessions?' : 'Archive sessions?' ;
const description = archived
? ` ${ n } session ${ plural } will be permanently deleted.`
: ` ${ n } session ${ plural } will be archived.` ;
return (
< Dialog open = { Boolean ( value )} onOpenChange = {( open ) => { if ( ! open ) setValue ( null ); }}>
< DialogContent showCloseButton = { false } className = "max-w-sm gap-5" >
< DialogHeader >
< DialogTitle >{ title }</ DialogTitle >
< DialogDescription >{ description }</ DialogDescription >
</ DialogHeader >
< DialogFooter className = "w-full sm:items-center sm:justify-between" >
< button
type = "button"
onClick = {() => setShowDeletionDialog ( ! showDeletionDialog )}
className = "inline-flex items-center gap-1.5 typography-ui-label text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/50"
aria-pressed = { ! showDeletionDialog }
>
{ ! showDeletionDialog ? < RiCheckboxLine className = "h-4 w-4 text-primary" /> : < RiCheckboxBlankLine className = "h-4 w-4" />}
Never ask
</ button >
< div className = "flex items-center gap-2" >
< button
type = "button"
onClick = {() => setValue ( null )}
className = "inline-flex h-8 items-center justify-center rounded-md border border-border px-3 typography-ui-label text-foreground hover:bg-interactive-hover/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50"
>
Cancel
</ button >
< button
type = "button"
onClick = {() => void onConfirm ()}
className = "inline-flex h-8 items-center justify-center rounded-md bg-destructive px-3 typography-ui-label text-destructive-foreground hover:bg-destructive/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-destructive/50"
>
{ archived ? 'Delete' : 'Archive' }
</ button >
2026-03-06 17:22:59 +02:00
</ div >
</ DialogFooter >
</ DialogContent >
</ Dialog >
);
}
export type DeleteFolderConfirmState = {
scopeKey : string ;
folderId : string ;
folderName : string ;
subFolderCount : number ;
sessionCount : number ;
} | null ;
export function FolderDeleteConfirmDialog ( props : {
value : DeleteFolderConfirmState ;
setValue : ( next : DeleteFolderConfirmState ) => void ;
onConfirm : () => void ;
}) : React . ReactNode {
const { value , setValue , onConfirm } = props ;
return (
< Dialog open = { Boolean ( value )} onOpenChange = {( open ) => { if ( ! open ) setValue ( null ); }}>
< DialogContent showCloseButton = { false } className = "max-w-sm gap-5" >
< DialogHeader >
< DialogTitle > Delete folder ? </ DialogTitle >
< DialogDescription >
{ value && ( value . subFolderCount > 0 || value . sessionCount > 0 )
? `" ${ value . folderName } " will be deleted ${ value . subFolderCount > 0 ? ` along with ${ value . subFolderCount } sub-folder ${ value . subFolderCount === 1 ? '' : 's' } ` : '' } . Sessions inside will not be deleted.`
: `" ${ value ? . folderName } " will be permanently deleted.` }
</ DialogDescription >
</ DialogHeader >
< DialogFooter >
< button
type = "button"
onClick = {() => setValue ( null )}
className = "inline-flex h-8 items-center justify-center rounded-md border border-border px-3 typography-ui-label text-foreground hover:bg-interactive-hover/50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50"
>
Cancel
</ button >
< button
type = "button"
onClick = { onConfirm }
className = "inline-flex h-8 items-center justify-center rounded-md bg-destructive px-3 typography-ui-label text-destructive-foreground hover:bg-destructive/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-destructive/50"
>
Delete
</ button >
</ DialogFooter >
</ DialogContent >
</ Dialog >
);
}