# Step Library Page — Design

> **Date:** February 24, 2026
> **Status:** Approved
> **Phase:** 2.5 — Feature 1 of 3

---

## What We're Building

Replace the "Coming Soon" stub in `StepLibraryPage` with a fully functional standalone Step Library. Users can browse, search, create, edit, delete, preview, and save steps to their own library.

All backend endpoints and frontend components are already built. This is primarily a wiring and UX integration task.

---

## Scope

**In scope:**
- Full-page Step Library with header, filters, grouped results
- Create step flow (modal with `StepForm`)
- Edit step flow (same modal, pre-filled)
- Delete step with confirmation
- "Save to My Library" for steps you don't own (copies step as private)
- Preview via `StepDetailModal`
- `StepCard` actions adapted for library context (vs. session insert context)

**Out of scope:**
- Rating/reviewing steps from this page (deferred — will come when steps are used in sessions)
- Admin category management (already exists in Admin Panel)
- Session custom step insertion (Feature 2 of 3)

---

## Card Actions by Context

| Ownership | Actions |
|-----------|---------|
| Your own step | Preview · Edit · Delete |
| Team or public step | Preview · Save to My Library |

"Save to My Library" POSTs a new step copying the title, step_type, content, category, and tags — with `visibility: 'private'` and the current user as owner.

---

## Page Layout

```
┌─────────────────────────────────────────────────────────┐
│  Step Library                          [+ Create Step]  │
│  Reusable steps you can insert into any flow            │
├─────────────────────────────────────────────────────────┤
│  [Search...]  [Category ▼]  [Type ▼]  [Rating ▼]  [Sort▼]│
│  Popular Tags: [powershell] [dns] [quick-fix] ...        │
├─────────────────────────────────────────────────────────┤
│  MY STEPS (3)                                      [▲]  │
│  ┌────────────┐ ┌────────────┐                          │
│  │  StepCard  │ │  StepCard  │  (Preview · Edit · Del)  │
│  └────────────┘ └────────────┘                          │
│                                                         │
│  TEAM STEPS (12)                                   [▲]  │
│  ┌────────────┐ ┌────────────┐                          │
│  │  StepCard  │ │  StepCard  │  (Preview · Save)        │
│  └────────────┘ └────────────┘                          │
│                                                         │
│  COMMUNITY (47)                                    [▲]  │
│  ┌────────────┐ ┌────────────┐                          │
│  │  StepCard  │ │  StepCard  │  (Preview · Save)        │
│  └────────────┘ └────────────┘                          │
└─────────────────────────────────────────────────────────┘
```

---

## Component Architecture

### StepLibraryPage (rewritten)
- Owns modal state: `createOpen`, `editingStep`, `deletingStepId`
- Renders page header with "+ Create Step" button
- Renders `StepLibraryBrowser` with page-context props
- Renders `StepFormModal` (create/edit)
- Renders delete confirmation dialog

### StepLibraryBrowser (extend props)
Add props:
```ts
interface StepLibraryBrowserProps {
  onInsert: (step: Step) => void       // existing (used in session context)
  onEdit?: (step: Step) => void        // new — library page only
  onDelete?: (stepId: string) => void  // new — library page only
  onSave?: (step: Step) => void        // new — save to my library
  onCreateNew?: () => void             // existing
  showCreateButton?: boolean           // existing
  currentUserId?: string               // new — to determine ownership
}
```

### StepCard (extend props)
Add props mirroring the browser:
```ts
interface StepCardProps {
  step: StepListItem
  onPreview: (step: StepListItem) => void
  onInsert?: (step: StepListItem) => void   // optional — session context
  onEdit?: (step: StepListItem) => void     // library context
  onDelete?: (stepId: string) => void       // library context
  onSave?: (step: StepListItem) => void     // library context
  currentUserId?: string
}
```

`StepCard` renders actions based on which callbacks are present and whether `step.created_by === currentUserId`.

### StepFormModal (new wrapper component)
Thin modal shell around the existing `StepForm`:
- Fixed header ("Create Step" or "Edit Step")
- Scrollable body with `StepForm`
- Handles create (`stepsApi.create`) and update (`stepsApi.update`) API calls
- Calls `onSuccess(step)` so the browser list can refresh

---

## Data Flow

### Create
1. User clicks "+ Create Step"
2. `StepFormModal` opens in create mode
3. On submit → `stepsApi.create(data)` → `onSuccess` → reload steps

### Edit
1. User clicks Edit on their own step card
2. `stepsApi.get(stepId)` fetches full step (need content fields)
3. `StepFormModal` opens pre-filled with step data
4. On submit → `stepsApi.update(id, data)` → `onSuccess` → reload steps

### Delete
1. User clicks Delete on their own step card
2. Confirmation dialog: "Delete '[title]'? This cannot be undone."
3. On confirm → `stepsApi.delete(id)` → remove from local state

### Save to My Library
1. User clicks "Save to My Library" on a team/public step
2. No confirmation needed — silent copy
3. `stepsApi.create({ ...step fields, visibility: 'private' })` → toast "Saved to My Steps"
4. Reload steps so the copy appears under "My Steps"

---

## Files to Change

| File | Change |
|------|--------|
| `pages/StepLibraryPage.tsx` | Rewrite — wire up browser + modals |
| `components/step-library/StepCard.tsx` | Add `onEdit`, `onDelete`, `onSave`, `currentUserId` props; render contextual buttons |
| `components/step-library/StepLibraryBrowser.tsx` | Add `onEdit`, `onDelete`, `onSave`, `currentUserId` props; pass through to cards; expose refresh trigger |
| `components/step-library/StepFormModal.tsx` | Create — thin modal wrapper around `StepForm` |

No backend changes required.

---

## StepCard Button Layout

**Own step:**
```
[Preview]  [Edit]  [🗑]
```
Edit and Preview are full-width-ish buttons; delete is an icon-only button in red on hover.

**Others' step:**
```
[Preview]  [Save to My Library]
```

Both full-width buttons, same pattern as current Insert layout.
