npm package: @ortha/admin-projects
Description: Projects UI plugin for the Ortha admin application — provides project listing and detail pages with a multi-step create wizard, extensible sidebar slots, and responsive grid layout.
Latest version: 0.0.4

# @ortha/admin-projects

Projects UI plugin for the Ortha admin application — provides project listing and detail pages with a multi-step create wizard, extensible sidebar slots, and responsive grid layout.

## Installation

Internal monorepo dependency — import directly:

```ts
import {
    projectsPlugin,
    SLOT_PROJECT_SIDEBAR_ACTIONS
} from '@ortha/admin-projects';
import type { Project } from '@ortha/admin-projects';
```

## Usage

### Registering the plugin

```ts
import { bootstrap } from '@ortha/admin-platform-bootstrap';
import { projectsPlugin } from '@ortha/admin-projects';

bootstrap(document.getElementById('root')!, [
    projectsPlugin()
    // ...other plugins
]);
```

### Using API hooks

```ts
import {
    useProjects,
    useProject,
    useCreateProject,
    useDeleteProject
} from '@ortha/admin-projects';

const ProjectsList = () => {
    const { data: projects } = useProjects();
    const createProject = useCreateProject();
    const deleteProject = useDeleteProject();
};

const ProjectDetail = ({ id }: { id: string }) => {
    const { data: project } = useProject(id);
};
```

### Extending the project sidebar

```ts
import { SLOT_PROJECT_SIDEBAR_ACTIONS } from '@ortha/admin-projects';

// In another plugin's setup():
ctx.slots.fill(SLOT_PROJECT_SIDEBAR_ACTIONS, MyCustomAction, { order: 50 });
```

## Routes

| Path            | Page                | Description               |
| --------------- | ------------------- | ------------------------- |
| `/projects`     | Projects list page  | Grid of project cards     |
| `/projects/:id` | Project detail page | Sidebar + project content |

## API Reference

### Plugin

| Export                         | Kind     | Description                               |
| ------------------------------ | -------- | ----------------------------------------- |
| `projectsPlugin()`             | factory  | Admin plugin — registers project routes   |
| `SLOT_PROJECT_SIDEBAR_ACTIONS` | constant | Slot key for project page sidebar actions |

### Hooks

| Export             | Kind | Description             |
| ------------------ | ---- | ----------------------- |
| `useProjects`      | hook | Projects list query     |
| `useProject`       | hook | Single project query    |
| `useCreateProject` | hook | Create project mutation |
| `useUpdateProject` | hook | Update project mutation |
| `useDeleteProject` | hook | Delete project mutation |

### Query Keys

| Export        | Kind | Description                                |
| ------------- | ---- | ------------------------------------------ |
| `projectsKey` | fn   | Query key factory for projects list cache  |
| `projectKey`  | fn   | Query key factory for single project cache |

### Types

| Export    | Kind | Description    |
| --------- | ---- | -------------- |
| `Project` | type | Project entity |

## Create Project Wizard

The create dialog uses a 3-step wizard:

1. **Project Info** — name, slug, description (validated with JSON Schema)
2. **Team** — user assignment with infinite-scroll search
3. **Content** — collections and pages configuration

Each step has its own AJV validation schema under `validation/`.

## Internal Structure

```
src/lib/
├── projectsPlugin/index.tsx        # Plugin factory — route + slot registration
├── slots/index.ts                  # Slot key constants
├── types/index.ts                  # Project, ProjectStats, ProjectStatus types
├── mocks/index.ts                  # Mock data for dashboard
├── api/
│   ├── useProjects/index.ts        # projectsKey + useProjects query
│   ├── useProject/index.ts         # projectKey + useProject query
│   ├── useCreateProject/index.ts   # CreateProjectBody + mutation
│   ├── useUpdateProject/index.ts   # UpdateProjectBody + mutation
│   └── useDeleteProject/index.ts   # Delete mutation
├── pages/
│   ├── ProjectsPage/index.tsx      # List page — header, stats, grid
│   └── ProjectPage/index.tsx       # Detail page — sidebar + content
├── components/
│   ├── ProjectsPageHeader/         # Page title + subtitle
│   ├── ProjectsStatsBar/           # Grouped stat widgets
│   ├── ProjectsGrid/               # Responsive CSS grid
│   ├── ProjectCard/                # Clickable card with avatar, status, meta
│   ├── ProjectAvatar/              # Initials avatar with deterministic color
│   ├── ProjectStatusChip/          # Active/Inactive status chip
│   ├── ProjectDescription/         # 3-line clamped description
│   ├── ProjectCardMeta/            # Members, collections, pages counters
│   ├── ProjectsEmptyState/         # Empty state with create/import cards
│   ├── ProjectsNavButton/          # Top nav button (fills SLOT_TOPBAR_NAV_MAIN_ACTIONS)
│   ├── CreateProjectDialog/        # 3-step wizard dialog
│   ├── ProjectInfoStep/            # Step 1: name, slug, description
│   ├── TeamStep/                   # Step 2: user assignment
│   ├── ContentStep/                # Step 3: collections & pages
│   ├── ProjectSidebar/             # Icon sidebar with slot support
│   └── index.ts                    # Component barrel exports
├── hooks/
│   ├── useStepValidation/          # Per-step AJV validation
│   └── useUserOptions/             # Infinite-scroll user fetching
└── validation/
    ├── projectInfoSchema/          # JSON Schema for step 1
    ├── teamSchema/                 # JSON Schema for step 2
    └── contentSchema/              # JSON Schema for step 3
```

## Key Patterns

- Route components are lazy-loaded with `React.lazy()`.
- API hooks use TanStack React Query and `httpClient` from `@ortha/admin-platform-core`.
- Forms use `react-hook-form` with `ajvResolver` from `@ortha/admin-utils`.
- Components are granular and single-purpose (avatar, status chip, description, meta).
- Dashboard page uses mock data (no backend integration yet for stats).
- Depends on the `home` plugin (uses the authenticated root layout as parent).

## Dependencies

- `@ortha/admin-platform-core` — `httpClient`, slot constants
- `@ortha/admin-platform-plugin-registry` — plugin types
- `@ortha/admin-users` — `fetchUsers` for team step
- `@ortha/admin-utils` — `ajvResolver`, `handleMutationError`
- `@ortha/design-system` — theme and UI components

## Building

```bash
nx build admin-projects
```