A React client component that renders a single onboarding step as an interactive card, displaying step metadata and contextual action buttons based on completion/skip state. ## Key Components ### `OnboardingStepCard` The primary exported component. Renders a responsive card (stacked on mobile, horizontal on `md+`) with two columns: - **Left column** — step title and description (truncated with tooltip) - **Right column** — state-driven action area ### `OnboardingStepCardProps` | Prop | Type | Description | |---|---|---| | `step` | `object` | Step metadata: id, title, description, action handlers, and icon factory | | `isCompleted` | `boolean` | Shows COMPLETED badge + secondary action button | | `isSkipped` | `boolean` | Shows SKIPPED badge, no actions | | `isCheckingCompletion` | `boolean` | Renders animated skeleton placeholders | | `onAction` | `() => void \| Promise` | Primary action handler | | `onSkip` | `() => void` | Skip step handler | | `className` | `string?` | Optional additional CSS classes | ### State Machine (Right Column) | Condition | Rendered UI | |---|---| | `isCheckingCompletion` | Pulsing skeleton loaders | | `isCompleted` | COMPLETED badge + repeat-action button | | `isSkipped` | SKIPPED badge only | | default | Skip + primary action buttons | ## Usage Example ```typescript , actionText: 'Connect', completedText: 'Reconnect', onAction: () => router.push('/integrations/psa'), onSkip: () => markSkipped('connect-psa'), }} isCompleted={false} isSkipped={false} isCheckingCompletion={false} onAction={() => router.push('/integrations/psa')} onSkip={() => markSkipped('connect-psa')} /> ``` > **Note:** `handleAction` uses internal `isProcessing` state to disable the button during async operations, preventing duplicate submissions. Both handlers call `e.stopPropagation()` to prevent card-level click bubbling.