feat: company cascade delete + user management + settings focus fix + bulk delete components
- Company DELETE: cascade non-accounting deps (deals, projects, tickets, persons, leads, instances), block only on accounting (invoices, licenses, expenses, contracts) per GoBD rule. Transaction-wrapped. - User management: GET /api/aos/users + PATCH role + DELETE (guards: no self-delete, no last owner delete, no env-admin delete). - User management UI: table with inline role select, 2FA status, delete button. - Settings focus fix: moved Field component outside render (was causing unmount/remount on each keystroke → focus loss). - Bulk delete: useBulkSelect hook + BulkDeleteDialog + BulkActionBar. - Cleaned all demo/mock data; re-bootstrapped admin account.
This commit is contained in:
1 parent
d492182b4e
commit
47945f6f64
9 files changed
+834
-95
No files matched your search
@@ -0,0 +1,49 @@
|
||||
'use client'
|
||||
|
||||
import { Trash2, X, CheckSquare } from 'lucide-react'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export function BulkActionBar({
|
||||
count,
|
||||
entityLabel,
|
||||
onDelete,
|
||||
onClear,
|
||||
className,
|
||||
}: {
|
||||
count: number
|
||||
entityLabel: string
|
||||
onDelete: () => void
|
||||
onClear: () => void
|
||||
className?: string
|
||||
}) {
|
||||
if (count === 0) return null
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'fixed bottom-4 left-1/2 z-50 flex -translate-x-1/2 items-center gap-3 rounded-lg border border-border bg-background px-4 py-2.5 shadow-lg',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<span className="flex items-center gap-1.5 text-sm font-medium">
|
||||
<CheckSquare className="size-4 text-muted-foreground" />
|
||||
{count} {count === 1 ? entityLabel : `${entityLabel}e`} ausgewählt
|
||||
</span>
|
||||
<div className="h-4 w-px bg-border" />
|
||||
<Button
|
||||
size="sm"
|
||||
variant="default"
|
||||
className="gap-1.5 bg-foreground text-background hover:bg-foreground/90"
|
||||
onClick={onDelete}
|
||||
>
|
||||
<Trash2 className="size-3.5" />
|
||||
Ausgewählte löschen
|
||||
</Button>
|
||||
<Button size="sm" variant="ghost" className="gap-1" onClick={onClear}>
|
||||
<X className="size-3.5" />
|
||||
Auswahl aufheben
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user