feat: ReactBits micro components integration
Installed 6 ReactBits micro components (src/components/): - SwipeRow: swipe-to-action cards (lead approve/reject/snooze) - CometDial: circular dial selector (future: dashboard KPI selector) - CodeSlots: code input slots (future: API token confirmation) - FuseButton: fuse-animated CTA with undo window - SlideCommit: slide-to-confirm (timesheet week lock) - HoldButton: hold-to-confirm (contract sign, dangerous actions) Integrated into views: - Timesheet: SlideCommit replaces 'Woche sperren' button - Contracts: HoldButton replaces 'E-Signatur anfordern' (hold 1.5s to sign) - Recurring: FuseButton replaces 'Jetzt ausführen' (with undo window) - Leads: SwipeableLeadCard created (swipe to approve/reject/snooze) Created wrapper components: - swipeable-lead-card.tsx: SwipeRow wrapper for lead cards - hold-to-confirm.tsx: HoldButton wrapper with loading state - fuse-cta.tsx: FuseButton wrapper with toast feedback - slide-to-lock.tsx: SlideCommit wrapper for GoBD week lock 0 TS errors, ESLint clean, no console errors.
This commit is contained in:
1 parent
21e112e5cb
commit
37e976a732
17 files changed
+2884
-25
No files matched your search
@@ -0,0 +1,61 @@
|
||||
'use client'
|
||||
|
||||
import FuseButton from '@/components/FuseButton'
|
||||
import { useState } from 'react'
|
||||
import { toast } from 'sonner'
|
||||
import { Loader2 } from 'lucide-react'
|
||||
|
||||
// FuseButton wrapper for primary CTA actions with undo window.
|
||||
// Used for: create deal, finalize invoice, run recurring, approve estimate.
|
||||
export function FuseCTA({
|
||||
label,
|
||||
doneLabel = 'Erledigt',
|
||||
undoLabel = 'Rückgängig',
|
||||
onCommit,
|
||||
onUndo,
|
||||
disabled,
|
||||
size = 'md',
|
||||
}: {
|
||||
label: string
|
||||
doneLabel?: string
|
||||
undoLabel?: string
|
||||
onCommit: () => void | Promise<void>
|
||||
onUndo?: () => void
|
||||
disabled?: boolean
|
||||
size?: 'sm' | 'md' | 'lg'
|
||||
}) {
|
||||
const [busy, setBusy] = useState(false)
|
||||
|
||||
const handleCommit = async () => {
|
||||
setBusy(true)
|
||||
const t = toast.loading('Wird ausgeführt…')
|
||||
try {
|
||||
await onCommit()
|
||||
toast.success(doneLabel, { id: t })
|
||||
} catch {
|
||||
toast.error('Fehlgeschlagen', { id: t })
|
||||
} finally {
|
||||
setBusy(false)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<FuseButton
|
||||
label={busy ? 'Lädt…' : label}
|
||||
doneLabel={doneLabel}
|
||||
undoLabel={undoLabel}
|
||||
onCommit={handleCommit}
|
||||
onUndo={onUndo}
|
||||
disabled={disabled || busy}
|
||||
size={size}
|
||||
commitOn="fuseEnd"
|
||||
settle="stay"
|
||||
fuse="bottom"
|
||||
fuseThickness={2}
|
||||
undoWindow={4000}
|
||||
color="oklch(0.98 0 0)"
|
||||
background="oklch(0.2 0 0)"
|
||||
fuseColor="oklch(0.5 0 0)"
|
||||
/>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user