# @hiyve/react-assignments

Assignment editor with activity tracking for Hiyve -- rich text editing, due dates, time estimates, status management, per-user activity sessions, and cloud persistence.

## Installation

```bash
npx @hiyve/cli login
npm install @hiyve/react-assignments
```

## Quick Start

```tsx
import { AssignmentEditor } from '@hiyve/react-assignments';
import { HiyveProvider } from '@hiyve/react';

function TeamAssignment() {
  return (
    <HiyveProvider generateRoomToken={generateRoomToken}>
      <AssignmentEditor
        title="Sprint Task"
        enableAutoSave
        onSave={(assignment) => console.log('Saved:', assignment.id)}
        onStatusChange={(status) => console.log('Status:', status)}
      />
    </HiyveProvider>
  );
}
```

## Components

| Component | Description |
|-----------|-------------|
| `AssignmentEditor` | Full-featured assignment editor with rich text, metadata controls, activity tracking, and auto-save |
| `AssignmentToolbar` | Standalone formatting toolbar (bold, italic, headings, lists, tables, etc.) |
| `AssignmentMetadata` | Metadata panel for due date, time estimate, status, and user assignment |
| `ActivityControlPanel` | Per-user activity controls -- session timer, progress slider, status, and notes |
| `ActivityDashboard` | Team activity overview with stats cards, average progress, and user activity table |
| `FileReferencesPanel` | Display and manage attached file references |
| `AssignmentSession` | Session manager that pairs AssignmentEditor with file loading, creation, and header controls |
| `CreateAssignmentDialog` | Dialog for naming a new assignment before creation |

### CreateAssignmentDialog Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `open` | `boolean` | -- | Whether the dialog is open |
| `onClose` | `() => void` | -- | Called when the dialog is closed |
| `onCreate` | `(fileId: string, fileName: string, fileData: AssignmentFile) => void` | -- | Called after the assignment file is created |
| `defaultName` | `string` | `''` | Pre-filled assignment name |
| `isCreating` | `boolean` | -- | External creating state |
| `error` | `string` | -- | External error message |
| `labels` | `Partial<CreateAssignmentDialogLabels>` | -- | Custom text labels |

```tsx
import { CreateAssignmentDialog } from '@hiyve/react-assignments';

<CreateAssignmentDialog
  open={showDialog}
  onClose={() => setShowDialog(false)}
  onCreate={(fileId, fileName, fileData) => {
    console.log('Created:', fileId);
    setShowDialog(false);
  }}
  defaultName="Design Review"
/>
```

## Hooks

| Hook | Description |
|------|-------------|
| `useAssignmentEditor` | Sets up a rich text editor instance with extensions and content tracking |
| `useAssignmentPersistence` | Manages auto-save, manual save, and save status tracking |
| `useActivityTracker` | Manages per-user activity sessions with timer, notes, and duration tracking |

## Utilities

| Export | Description |
|--------|-------------|
| `createAssignmentFile` | Creates and uploads a new assignment file to the server. Returns `{ fileId, fileData }` |
| `generateAssignmentId` | Creates a unique assignment identifier |
| `isContentEmpty` | Checks whether editor content is empty or whitespace-only |
| `getStatusColor` | Returns the color for a given assignment status |
| `calculateTotalTime` | Sums total time from activity sessions |
| `formatDuration` | Formats minutes as human-readable duration ("2h 30m") |
| `getUserActivity` | Gets or creates a default user activity record |
| `updateUserActivity` | Immutably updates a user's activity data |
| `addSession` | Adds an activity session and recalculates totals |
| `getActivityStats` | Computes team stats (active users, total time, average progress) |
| `getAssignmentEditorStyles` | Returns CSS styles for the editor area |

## AssignmentEditor Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `title` | `string` | `'Assignment'` | Header title |
| `initialTitle` | `string` | -- | Pre-filled title for the assignment |
| `initialContent` | `JSONContent` | -- | Pre-filled editor content |
| `initialAssignment` | `AssignmentFile` | -- | Pre-populated assignment data (populates all fields) |
| `placeholder` | `string` | `'Describe the assignment details...'` | Placeholder when editor is empty |
| `showHeader` | `boolean` | `true` | Show the panel header |
| `showToolbar` | `boolean` | `true` | Show the formatting toolbar |
| `showTitleInput` | `boolean` | `true` | Show the title input field |
| `showMetadata` | `boolean` | `false` | Show the metadata panel with due date, time, status, and assignees |
| `showTabs` | `boolean` | `false` | Show the tab bar (Editor / Activity / My Activity) |
| `maxHeight` | `number \| string` | -- | Maximum height before scrolling |
| `minHeight` | `number \| string` | -- | Minimum height of the editor |
| `disabled` | `boolean` | `false` | Disable the entire panel |
| `readOnly` | `boolean` | `false` | Make the editor read-only |
| `enableAutoSave` | `boolean` | `false` | Enable auto-save to file storage |
| `autoSaveInterval` | `number` | `3000` | Auto-save interval in milliseconds |
| `fileId` | `string` | -- | Existing file ID (for editing a saved assignment) |
| `fileLocation` | `string` | `'/Assignments'` | Storage folder path |
| `enableTableSupport` | `boolean` | `true` | Enable table editing |
| `enableTaskLists` | `boolean` | `true` | Enable task list (checkbox) support |
| `enableHighlight` | `boolean` | `true` | Enable text highlighting |
| `enableActivityTracking` | `boolean` | `false` | Enable per-user activity tracking with session timers |
| `labels` | `Partial<AssignmentEditorLabels>` | -- | Label overrides for i18n |
| `icons` | `Partial<AssignmentEditorIcons>` | -- | Icon overrides |
| `colors` | `Partial<AssignmentEditorColors>` | -- | Color overrides |
| `styles` | `Partial<AssignmentEditorStyles>` | -- | Style overrides |
| `sx` | `SxProps<Theme>` | -- | MUI sx prop for the container |
| `onChange` | `(content: JSONContent) => void` | -- | Called when content changes |
| `onTitleChange` | `(title: string) => void` | -- | Called when the title changes |
| `onSave` | `(assignment: AssignmentFile) => void` | -- | Called after a successful save |
| `onSaveError` | `(error: Error) => void` | -- | Called when a save fails |
| `onAutoSave` | `(fileId: string) => void` | -- | Called after a successful auto-save |
| `onFocus` | `() => void` | -- | Called when editor is focused |
| `onBlur` | `() => void` | -- | Called when editor is blurred |
| `onStatusChange` | `(status: AssignmentStatus) => void` | -- | Called when assignment status changes |

## Imperative Handle (Ref)

`AssignmentEditor` exposes a ref for external control:

```tsx
import { useRef } from 'react';
import { AssignmentEditor, type AssignmentEditorRef } from '@hiyve/react-assignments';

function AssignmentsPanel() {
  const editorRef = useRef<AssignmentEditorRef>(null);

  return (
    <div>
      <button
        onClick={() => editorRef.current?.save()}
        disabled={editorRef.current?.isSaving}
      >
        Save Now
      </button>
      <AssignmentEditor ref={editorRef} enableAutoSave />
    </div>
  );
}
```

The ref provides: `save()`, `isSaving`, `hasUnsavedChanges`, `lastSaved`, `fileId`, `addFileReferences(refs)`, and `removeFileReference(fileId)`.

## Using Hooks Directly

For custom editor UIs, use the hooks independently:

```tsx
import { useAssignmentEditor, useAssignmentPersistence, useActivityTracker } from '@hiyve/react-assignments';

function CustomAssignmentEditor() {
  const { editor, content, isEmpty, getHTML, focus } = useAssignmentEditor({
    placeholder: 'Describe the assignment details...',
    onUpdate: (content) => console.log('Changed'),
  });

  const { startSession, endSession, currentSession } = useActivityTracker({
    userId: currentUser.id,
  });

  // Render your own UI around the editor instance
}
```

## Activity Tracking

Track per-user work sessions with timers, progress, and notes:

```tsx
import { AssignmentEditor } from '@hiyve/react-assignments';

<AssignmentEditor
  title="Design Review"
  showMetadata
  showTabs
  enableActivityTracking
  initialAssignment={{
    id: 'task-1',
    title: 'Design Review',
    status: 'in_progress',
    dueDate: '2026-03-01',
    timeHours: 2,
    timeMinutes: 0,
    assignedTo: [],
    content: { type: 'doc', content: [] },
    fileReferences: [],
    userActivities: {},
    authorId: 'user-123',
    lastModified: new Date().toISOString(),
    modifiedBy: 'user-123',
    createdAt: new Date().toISOString(),
    updatedAt: new Date().toISOString(),
  }}
  onStatusChange={(status) => console.log('Status:', status)}
/>
```

The Activity tab shows individual session controls. The Activity Dashboard tab displays team-wide stats including active users, total time spent, and average progress.

## Activity Utilities

```tsx
import {
  calculateTotalTime,
  formatDuration,
  getActivityStats,
  getStatusColor,
} from '@hiyve/react-assignments';

const totalMinutes = calculateTotalTime(userActivity.sessions);
const display = formatDuration(totalMinutes); // "2h 30m"
const stats = getActivityStats(userActivities);
const color = getStatusColor('in_progress');
```

## Session Management

`AssignmentSession` provides a complete session workflow -- creating new assignments, loading saved assignments from file storage, and editing with auto-save:

```tsx
import { AssignmentSession } from '@hiyve/react-assignments';

<AssignmentSession
  labels={{
    emptyState: { message: 'No assignment open', createButton: 'Create New' },
    header: { newSession: 'New Assignment' },
  }}
  assignmentEditorProps={{
    enableAutoSave: true,
    autoSaveInterval: 5000,
  }}
  onError={(error) => console.error('Assignment error:', error)}
/>
```

## Customization

All visual aspects of the editor are customizable through `labels`, `icons`, `colors`, and `styles` props. Pass a partial object -- unspecified keys use defaults.

### Labels (i18n)

```tsx
import { AssignmentEditor } from '@hiyve/react-assignments';

<AssignmentEditor
  labels={{
    title: 'Tarea',
    placeholder: 'Escribe tu tarea...',
    save: 'Guardar',
    saving: 'Guardando...',
    saved: 'Guardado',
    bold: 'Negrita',
    italic: 'Cursiva',
    dueDate: 'Fecha limite',
    status: 'Estado',
  }}
/>
```

### Icons

```tsx
import { AssignmentEditor } from '@hiyve/react-assignments';
import { FaBold, FaItalic } from 'react-icons/fa';

<AssignmentEditor
  icons={{
    bold: <FaBold />,
    italic: <FaItalic />,
  }}
/>
```

### Colors

```tsx
import { AssignmentEditor, defaultAssignmentEditorColors } from '@hiyve/react-assignments';

// Light theme
<AssignmentEditor
  colors={{
    headerBackground: '#f5f5f5',
    editorBackground: '#ffffff',
    editorText: '#212121',
    toolbarBackground: '#fafafa',
    toolbarButtonActive: '#1976d2',
  }}
/>
```

### Styles

```tsx
import { AssignmentEditor } from '@hiyve/react-assignments';

// Compact layout
<AssignmentEditor
  styles={{
    toolbarButtonSize: 28,
    editorPadding: 12,
    editorFontSize: '0.875rem',
    borderRadius: 8,
  }}
/>
```

**Defaults and merge functions:**

| Default | Merge Function |
|---------|---------------|
| `defaultAssignmentEditorLabels` | `mergeAssignmentEditorLabels` |
| `defaultAssignmentEditorIcons` | `mergeAssignmentEditorIcons` |
| `defaultAssignmentEditorColors` | `mergeAssignmentEditorColors` |
| `defaultAssignmentEditorStyles` | `mergeAssignmentEditorStyles` |
| `defaultActivityDashboardLabels` | `mergeActivityDashboardLabels` |
| `defaultActivityControlPanelLabels` | `mergeActivityControlPanelLabels` |
| `defaultAssignmentSessionLabels` | `mergeAssignmentSessionLabels` |
| `defaultCreateAssignmentDialogLabels` | `mergeCreateAssignmentDialogLabels` |

## Features

- Rich text formatting (bold, italic, strikethrough, highlight, code)
- Headings (H1, H2, H3)
- Lists (bullet, numbered, task/checkbox)
- Tables with full editing
- Assignment metadata: due date, time estimates, status, user assignment
- Per-user activity tracking with session timer and notes
- Team activity dashboard with stats and progress overview
- File reference attachments
- Auto-save to file storage with debouncing
- Undo/redo history
- Read-only mode with ownership-based access control
- Dark theme matching other Hiyve components

## Constants

| Constant | Description |
|----------|-------------|
| `DEFAULT_AUTO_SAVE_INTERVAL` | Default auto-save interval (3000ms) |
| `ACTIVITY_SAVE_INTERVAL` | Activity tracking save interval (30000ms) |
| `CONTENT_CHANGE_DEBOUNCE` | Content change debounce delay (500ms) |
| `DEFAULT_FILE_LOCATION` | Default storage folder (`'/Assignments'`) |
| `DEFAULT_PLACEHOLDER` | Default placeholder text |
| `DEFAULT_TABLE_DIMENSIONS` | Default rows/columns for new tables |
| `ASSIGNMENT_FILE_EXTENSION` | File extension for assignment files |
| `ASSIGNMENT_FILE_MIME_TYPE` | MIME type for assignment files |
| `ASSIGNMENT_STATUSES` | Array of all valid assignment statuses |
| `EMPTY_CONTENT` | Empty document structure |

## Key Types

| Type | Description |
|------|-------------|
| `AssignmentFile` | Full assignment data model (content, metadata, user activities) |
| `AssignmentFileClient` | Interface for file persistence operations (`uploadFile`, `modifyFile`) |
| `AssignmentEditorRef` | Imperative handle: `save()`, `isSaving`, `hasUnsavedChanges`, `lastSaved`, `fileId`, `addFileReferences`, `removeFileReference` |
| `CreateAssignmentDialogProps` | Props for `CreateAssignmentDialog` |
| `CreateAssignmentDialogLabels` | Customizable text labels for `CreateAssignmentDialog` |
| `CreateAssignmentFileOptions` | Options for `createAssignmentFile` (`name`, `ownerId`, `ownerName?`, `initialContent?`, `location?`) |
| `CreateAssignmentFileResult` | Return type of `createAssignmentFile` (`fileId`, `fileData`) |
| `AssignmentStatus` | `'not_started' \| 'in_progress' \| 'on_hold' \| 'completed'` |
| `JSONContent` | Editor content format (structured JSON) |

## Assignment Status Values

```ts
type AssignmentStatus = 'not_started' | 'in_progress' | 'on_hold' | 'completed';
```

## Requirements

- **`@hiyve/react`** (`^2.0.0`) -- components must be rendered inside `HiyveProvider`
- **`@hiyve/react-collaboration`** (`^1.0.0`) -- optional, needed for `AssignmentSession`
- **`@hiyve/utilities`** (`^1.0.0`)
- **`@mui/material`** (`^5.0.0 || ^6.0.0`) and **`@mui/icons-material`**
- **`@emotion/react`** (`^11.0.0`) and **`@emotion/styled`** (`^11.0.0`)
- **`react`** (`^18.0.0`)

Rich text editor dependencies are bundled with the package -- no separate installation needed.

## License

Proprietary - Hiyve SDK
