npm package: @omnikit-js/ui
Description: React component library for OmniKit serverless platform
Latest version: 0.9.51

# @omnikit-js/ui

React component library for OmniKit serverless platform. Provides server and client components for building full-stack applications with authentication, billing, data display, and file uploads.

## Installation

```bash
npm install @omnikit-js/ui @marcoschwartz/lite-ui
```

## Setup

Import lite-ui styles in your app's layout or entry point:

```tsx
import '@marcoschwartz/lite-ui/styles.css'
```

---

## Server Components

### Billing

Full billing dashboard with subscription management, invoices, payment methods, and plan selection.

```tsx
import '@marcoschwartz/lite-ui/styles.css'
import { Billing } from '@omnikit-js/ui'

export default async function BillingPage() {
  return (
    <Billing
      baseUrl={process.env.OMNIKIT_BASE_URL!}
      apiKey={process.env.OMNIKIT_API_KEY}
      projectId={1}
      userId="123"
    />
  )
}
```

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `baseUrl` | `string` | Yes | OmniKit API base URL |
| `projectId` | `number` | Yes | Project ID |
| `userId` | `string` | Yes | User ID (email fetched automatically) |
| `apiKey` | `string` | No | API Key for authentication |
| `accessToken` | `string` | No | JWT token (alternative to apiKey) |
| `userEmail` | `string` | No | User email (auto-fetched if not provided) |
| `userName` | `string` | No | User name (auto-fetched if not provided) |
| `testMode` | `boolean` | No | Enable Stripe test mode |

**Features:**
- Subscription management with plan switching
- Invoice history with PDF downloads
- Payment method management (add/remove/set default)
- Usage tracking with progress bars
- Plan comparison grid

---

### DataList

Server-side component that fetches and displays data with zero client JavaScript.

```tsx
import { DataList } from '@omnikit-js/ui'

export default async function UsersPage() {
  return (
    <DataList
      table="users"
      baseUrl={process.env.OMNIKIT_BASE_URL!}
      apiKey={process.env.OMNIKIT_API_KEY!}
      columns={[
        'name',
        'email',
        {
          key: 'created_at',
          label: 'Joined',
          render: (value) => new Date(value).toLocaleDateString(),
        },
      ]}
      filter={{ active: true }}
      limit={20}
    />
  )
}
```

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `table` | `string` | Yes | Table name to query |
| `baseUrl` | `string` | Yes | OmniKit API base URL |
| `apiKey` | `string` | No | API Key for authentication |
| `jwt` | `string` | No | JWT token (alternative to apiKey) |
| `columns` | `Column[]` | Yes | Columns to display |
| `filter` | `object` | No | Query filter |
| `sort` | `string` | No | Sort order (e.g., `'name:asc'`) |
| `limit` | `number` | No | Max records to fetch |
| `offset` | `number` | No | Pagination offset |

---

## Client Components

Import client components from `@omnikit-js/ui/client`:

```tsx
import { LoginForm, RegisterForm, FileUploader } from '@omnikit-js/ui/client'
```

### LoginForm

```tsx
import { LoginForm } from '@omnikit-js/ui/client'

<LoginForm
  apiUrl={process.env.NEXT_PUBLIC_API_URL!}
  projectId={1}
  onSuccess={(data) => {
    // data.access_token, data.user
    router.push('/dashboard')
  }}
  onError={(error) => console.error(error)}
  registerLink="/register"
  forgotPasswordLink="/forgot-password"
/>
```

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `apiUrl` | `string` | Yes | OmniKit API base URL |
| `projectId` | `number` | Yes | Project ID |
| `onSuccess` | `function` | No | Callback with login data |
| `onError` | `function` | No | Error callback |
| `showRememberMe` | `boolean` | No | Show remember me checkbox |
| `allowUsername` | `boolean` | No | Allow username instead of email |
| `registerLink` | `string` | No | Link to registration page |
| `forgotPasswordLink` | `string` | No | Link to forgot password page |

---

### RegisterForm

```tsx
import { RegisterForm } from '@omnikit-js/ui/client'

<RegisterForm
  apiUrl={process.env.NEXT_PUBLIC_API_URL!}
  projectId={1}
  onSuccess={(data) => router.push('/login')}
  loginLink="/login"
/>
```

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `apiUrl` | `string` | Yes | OmniKit API base URL |
| `projectId` | `number` | Yes | Project ID |
| `onSuccess` | `function` | No | Callback with registration data |
| `onError` | `function` | No | Error callback |
| `requireName` | `boolean` | No | Require name field |
| `loginLink` | `string` | No | Link to login page |

---

### ForgotPasswordForm

```tsx
import { ForgotPasswordForm } from '@omnikit-js/ui/client'

<ForgotPasswordForm
  apiUrl={process.env.NEXT_PUBLIC_API_URL!}
  projectId={1}
  onSuccess={() => alert('Check your email!')}
  loginLink="/login"
/>
```

---

### ResetPasswordForm

```tsx
import { ResetPasswordForm } from '@omnikit-js/ui/client'

<ResetPasswordForm
  apiUrl={process.env.NEXT_PUBLIC_API_URL!}
  projectId={1}
  token={searchParams.token}
  onSuccess={() => router.push('/login')}
/>
```

---

### FileUploader

Multi-file uploader with drag-and-drop, progress tracking, and multipart upload support.

```tsx
import { FileUploader } from '@omnikit-js/ui/client'

<FileUploader
  apiUrl={process.env.NEXT_PUBLIC_API_URL!}
  projectId={1}
  bucketId={1}
  apiKey={process.env.NEXT_PUBLIC_API_KEY}
  accept="image/*,application/pdf"
  maxFileSize={50 * 1024 * 1024}
  maxFiles={5}
  onUploadComplete={(file) => console.log('Uploaded:', file)}
  onAllUploadsComplete={(files) => console.log('All done:', files)}
/>
```

| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `apiUrl` | `string` | Yes | OmniKit API base URL |
| `projectId` | `number` | Yes | Project ID |
| `bucketId` | `number` | Yes | Storage bucket ID |
| `apiKey` | `string` | No | API Key for authentication |
| `accessToken` | `string` | No | JWT token (alternative) |
| `accept` | `string` | No | Accepted file types |
| `maxFileSize` | `number` | No | Max file size in bytes |
| `maxFiles` | `number` | No | Max number of files (default: 10) |
| `autoUpload` | `boolean` | No | Start upload automatically (default: true) |
| `onUploadComplete` | `function` | No | Called when a file completes |
| `onAllUploadsComplete` | `function` | No | Called when all files complete |
| `onProgress` | `function` | No | Progress callback |

**Features:**
- Drag and drop support
- Multi-file selection
- Progress bars with speed/ETA
- Automatic multipart upload for large files
- Concurrent uploads with queue management

---

## API Client

For custom data fetching:

```tsx
import { createOmniKitClient } from '@omnikit-js/ui'

const client = createOmniKitClient({
  baseUrl: 'http://localhost:3000/omnikit',
  apiKey: 'your-api-key',
})

// Query
const users = await client.query('users', { filter: { active: true }, limit: 10 })

// CRUD
const user = await client.findById('users', '123')
await client.insert('users', { name: 'John', email: 'john@example.com' })
await client.update('users', '123', { name: 'Jane' })
await client.delete('users', '123')
```

---

## TypeScript

All components are fully typed. Import types as needed:

```tsx
import type {
  BillingProps,
  DataListProps,
  LoginFormProps,
  FileUploaderProps,
  UploadedFile
} from '@omnikit-js/ui'
```

---

## Requirements

- React 18 or 19
- Next.js 13+ (App Router recommended)
- Tailwind CSS v4
- `@marcoschwartz/lite-ui` (peer dependency)

## License

MIT