Syed Hasnain

Plan Approval Card

Component

About

A proposed agent plan with inline step editing, a start countdown, and cancel controls.

Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Plan Approval Card to your project and fits it to your theme.

Code

How Plan Approval Card is used: the demo's code. The component's own source comes with a free account.

Usage.tsx

import * as React from 'react'
import PlanApprovalCard, { type PlanApprovalStep } from '@/components/ui/plan-approval-card'

const initialSteps: PlanApprovalStep[] = [
  { id: 'gather', label: 'Gather relevant information from trusted sources.' },
  { id: 'verify', label: 'Review key details and verify the available information.' },
  { id: 'themes', label: 'Identify common themes and highlight useful insights.' },
  { id: 'outline', label: 'Organize the findings into a clear outline.' },
  { id: 'summary', label: 'Create a concise summary with links to sources.' },
]

const duration = 12

export default function Demo() {
  const [steps, setSteps] = React.useState(initialSteps)
  const [seconds, setSeconds] = React.useState(9)
  const [paused, setPaused] = React.useState(false)
  const [status, setStatus] = React.useState('')

  React.useEffect(() => {
    if (paused) return
    const timer = setTimeout(() => {
      if (seconds > 0) return setSeconds((value) => value - 1)
      setStatus('Starting research…')
      setTimeout(() => {
        setStatus('')
        setSeconds(duration)
      }, 2200)
    }, 1000)
    return () => clearTimeout(timer)
  }, [paused, seconds])

  return (
    <div className="flex w-full max-w-lg flex-col items-center gap-3">
      <PlanApprovalCard
        className="w-full"
        countdownDuration={duration}
        countdownSeconds={paused || status ? undefined : seconds}
        disabled={Boolean(status)}
        onCancel={() => {
          setPaused(true)
          setStatus('Plan cancelled.')
        }}
        onEdit={() => setPaused(true)}
        onStart={() => setStatus('Starting research…')}
        onStepsChange={setSteps}
        steps={steps}
        title="Research a topic"
      />
      <output aria-live="polite" className="min-h-5 text-xs leading-5 text-muted-foreground">
        {status}
      </output>
    </div>
  )
}

Dependencies

More by Syed Hasnain

View all
  • Color Picker

    Color Picker

    76
  • Cost Meter

    Cost Meter

    29
  • Quota Banner

    Quota Banner

    21
  • Message Scroller

    Message Scroller

    21
  • Commit

    Commit

    17
  • Image Generation Loader

    Image Generation Loader

    15
  • Attachments

    Attachments

    15
  • Citations

    Citations

    14

Explore more

Part of Pasta UI — browse the full library on 21st.dev.