npm package: @package-uploader/ui
Description: React UI for uploading and browsing courses on LMS platforms
Latest version: 1.1.10

# @package-uploader/ui

React UI for uploading and browsing courses on LMS platforms. Includes drag-and-drop upload, folder navigation, and course launching.

## Features

- **Drag-and-drop upload**: Upload multiple course ZIPs at once
- **Folder browser**: Navigate folder hierarchy, select destination
- **Document browser**: Search and filter uploaded courses
- **Course launcher**: One-click launch via shared links
- **Server included**: Express server serves UI on single port

## Installation

```bash
npm install @package-uploader/ui
```

## Quick Start

### Option 1: Run with Server (Recommended)

The package includes a complete server/UI setup:

```bash
# Clone the repository
git clone <repo>
cd package.uploader

# Install all dependencies
npm install
cd server && npm install && cd ..
cd ui && npm install && cd ..

# Configure environment
cp server/.env.example server/.env
# Edit server/.env with your LMS credentials

# Build and run
cd server
npm run build
npm start
```

Open http://localhost:3002 in your browser.

### Option 2: Development Mode

```bash
# Terminal 1: Run server
cd server
npm run dev

# Terminal 2: Run UI (with hot reload)
cd ui
npm run dev
```

UI runs on http://localhost:5173, API on http://localhost:3002.

## Server Configuration

Create `server/.env`:

```bash
# LMS API Configuration
UPLOADER_BASE_URL=https://your-lms.example.com
UPLOADER_API_KEY=your-api-key

# Patch-Adams Integration (optional)
PATCH_ADAMS_ENABLED=true
PATCH_ADAMS_DOMAIN=https://cdn.example.com/rise-overrides

# Server Port
PORT=3002
```

## API Endpoints

The server exposes these endpoints:

### Folders

```
GET /api/folders              # List all folders
GET /api/folders/:id          # Get folder by ID
GET /api/folders/:id/subfolders  # List subfolders
```

### Documents

```
GET /api/documents            # List all documents
GET /api/documents?folderId=X # List documents in folder
GET /api/documents/:id        # Get document by ID
GET /api/documents/:id/launch # Get launch URL
```

### Upload

```
POST /api/upload              # Upload new course
  - file: ZIP file (multipart)
  - folderId: Target folder ID
  - title: Document title (optional)
  - description: Description (optional)

POST /api/upload/version      # Upload new version
  - file: ZIP file (multipart)
  - documentId: Target document ID
  - note: Version note (optional)
```

### Health Check

```
GET /api/health               # Server status
```

## UI Pages

### Upload Page (`/`)

- Drag-and-drop zone for ZIP files
- Folder tree for destination selection
- Upload queue with status tracking
- Batch upload support

### Browse Page (`/browse`)

- Document grid view
- Search by name
- Filter by folder
- One-click course launch
- View document details

## Components

### `DropZone`

```tsx
import DropZone from './components/DropZone';

<DropZone onFilesAdded={(files) => handleFiles(files)} />
```

### `FolderSelect`

```tsx
import FolderSelect from './components/FolderSelect';

<FolderSelect
  selectedId={selectedFolderId}
  onSelect={(id) => setSelectedFolderId(id)}
/>
```

### `FileList`

```tsx
import FileList from './components/FileList';

<FileList
  files={uploadQueue}
  onRemove={(index) => removeFile(index)}
  onRetry={(index) => retryUpload(index)}
/>
```

## Deployment

### Docker

```dockerfile
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app

# Install dependencies
COPY package*.json ./
COPY server/package*.json ./server/
COPY ui/package*.json ./ui/
RUN npm install && cd server && npm install && cd ../ui && npm install

# Copy source
COPY . .

# Build
RUN cd ui && npm run build
RUN cd server && npm run build

# Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/server/dist ./dist
COPY --from=builder /app/server/package*.json ./
COPY --from=builder /app/ui/dist ./ui/dist
RUN npm ci --production
EXPOSE 3002
CMD ["node", "dist/index.js"]
```

### Docker Compose

```yaml
version: '3.8'
services:
  package-uploader:
    build: .
    ports:
      - "3002:3002"
    environment:
      - UPLOADER_BASE_URL=https://your-lms.example.com
      - UPLOADER_API_KEY=your-api-key
      - PATCH_ADAMS_ENABLED=true
      - PATCH_ADAMS_DOMAIN=https://cdn.example.com/rise-overrides
```

### Manual Deployment

```bash
# Build UI
cd ui && npm run build

# Build Server
cd server && npm run build

# The server will serve UI from ../ui/dist
# Deploy server/dist + ui/dist together
```

## Integration with CI/CD

### GitHub Actions

```yaml
name: Build and Deploy
on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 18

      - name: Install dependencies
        run: |
          npm install
          cd server && npm install
          cd ../ui && npm install

      - name: Build
        run: |
          cd ui && npm run build
          cd ../server && npm run build

      - name: Deploy
        run: # Your deployment steps
```

## Project Structure

```
package.uploader/
├── package.json          # @package-uploader/core (npm package)
├── src/                  # Core library source
├── server/
│   ├── package.json      # Server package (private)
│   ├── src/index.ts      # Express server
│   └── .env.example      # Environment template
└── ui/
    ├── package.json      # @package-uploader/ui (npm package)
    ├── src/
    │   ├── App.tsx
    │   ├── pages/
    │   │   ├── UploadPage.tsx
    │   │   └── BrowsePage.tsx
    │   └── components/
    │       ├── DropZone.tsx
    │       ├── FileList.tsx
    │       └── FolderSelect.tsx
    └── index.html
```

## Dependencies

### UI
- React 18+
- React Router DOM
- react-dropzone

### Server
- Express
- Multer (file uploads)
- @package-uploader/core
- dotenv

## License

MIT