feat(ST-1110.5): unify demo write-button pattern to disabled+tooltip

Convert all !isDemo && <Button> patterns to <DemoTooltip show={isDemo}>
<Button disabled={isDemo}> so demo visitors see app capabilities.
Affects: pbi-list, story-panel, story-dialog, task-list, sprint-backlog,
token-manager, product-list, activate-product-button, leave-product-button,
settings page.
This commit is contained in:
Janpeter Visser 2026-04-29 18:27:39 +02:00
parent 84f0a2add4
commit 5e0308d42e
12 changed files with 180 additions and 134 deletions

View file

@ -2,13 +2,15 @@
import { useState, useTransition } from 'react'
import { Button } from '@/components/ui/button'
import { DemoTooltip } from '@/components/shared/demo-tooltip'
import { leaveProductAction } from '@/actions/products'
interface LeaveProductButtonProps {
productId: string
isDemo?: boolean
}
export function LeaveProductButton({ productId }: LeaveProductButtonProps) {
export function LeaveProductButton({ productId, isDemo = false }: LeaveProductButtonProps) {
const [confirming, setConfirming] = useState(false)
const [isPending, startTransition] = useTransition()
@ -32,13 +34,16 @@ export function LeaveProductButton({ productId }: LeaveProductButtonProps) {
}
return (
<Button
variant="outline"
size="sm"
className="shrink-0 border-error/40 text-error hover:bg-error/10"
onClick={() => setConfirming(true)}
>
Verlaten
</Button>
<DemoTooltip show={isDemo}>
<Button
variant="outline"
size="sm"
className="shrink-0 border-error/40 text-error hover:bg-error/10"
disabled={isDemo}
onClick={() => !isDemo && setConfirming(true)}
>
Verlaten
</Button>
</DemoTooltip>
)
}

View file

@ -4,6 +4,7 @@ import { useState, useActionState, useTransition } from 'react'
import { useFormStatus } from 'react-dom'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { DemoTooltip } from '@/components/shared/demo-tooltip'
import { createApiTokenAction, revokeApiTokenAction } from '@/actions/api-tokens'
interface Token {
@ -18,12 +19,14 @@ interface TokenManagerProps {
isDemo: boolean
}
function CreateSubmitButton() {
function CreateSubmitButton({ isDemo }: { isDemo: boolean }) {
const { pending } = useFormStatus()
return (
<Button type="submit" disabled={pending}>
{pending ? 'Aanmaken…' : 'Token aanmaken'}
</Button>
<DemoTooltip show={isDemo}>
<Button type="submit" disabled={isDemo || pending}>
{pending ? 'Aanmaken…' : 'Token aanmaken'}
</Button>
</DemoTooltip>
)
}
@ -80,21 +83,19 @@ export function TokenManager({ tokens, isDemo }: TokenManagerProps) {
)}
{/* Create form */}
{!isDemo && (
<div className="bg-surface-container-low border border-border rounded-xl p-5 space-y-4">
<h2 className="text-sm font-medium text-foreground">Nieuw token aanmaken</h2>
<form action={formAction} className="flex gap-2">
<Input name="label" placeholder="Label (optioneel)" className="flex-1" />
<CreateSubmitButton />
</form>
{typeof state?.error === 'string' && (
<p className="text-xs text-error">{state.error}</p>
)}
<p className="text-xs text-muted-foreground">
Maximaal 10 actieve tokens. Je hebt er nu {activeTokens.length}.
</p>
</div>
)}
<div className="bg-surface-container-low border border-border rounded-xl p-5 space-y-4">
<h2 className="text-sm font-medium text-foreground">Nieuw token aanmaken</h2>
<form action={formAction} className="flex gap-2">
<Input name="label" placeholder="Label (optioneel)" className="flex-1" disabled={isDemo} />
<CreateSubmitButton isDemo={isDemo} />
</form>
{typeof state?.error === 'string' && (
<p className="text-xs text-error">{state.error}</p>
)}
<p className="text-xs text-muted-foreground">
Maximaal 10 actieve tokens. Je hebt er nu {activeTokens.length}.
</p>
</div>
{/* Active tokens */}
<div className="space-y-2">
@ -111,16 +112,17 @@ export function TokenManager({ tokens, isDemo }: TokenManagerProps) {
Aangemaakt {new Date(token.created_at).toLocaleDateString('nl-NL')}
</p>
</div>
{!isDemo && (
<DemoTooltip show={isDemo}>
<Button
size="sm"
variant="ghost"
className="text-error hover:bg-error/10 shrink-0"
onClick={() => handleRevoke(token.id)}
disabled={isDemo}
onClick={() => !isDemo && handleRevoke(token.id)}
>
Intrekken
</Button>
)}
</DemoTooltip>
</div>
))}
</div>