# Adding New React Tools to Stirling PDF

This guide covers how to add new PDF tools to the React frontend.

## Overview

When adding tools, follow this systematic approach using the established patterns and architecture.

## 1. Create Tool Structure

Create these files in the correct directories:
```
frontend/editor/src/hooks/tools/[toolName]/
  ├── use[ToolName]Parameters.ts     # Parameter definitions and validation
  └── use[ToolName]Operation.ts      # Tool operation logic using useToolOperation

frontend/editor/src/components/tools/[toolName]/
  └── [ToolName]Settings.tsx         # Settings UI component (if needed)

frontend/editor/src/tools/
  └── [ToolName].tsx                 # Main tool component
```

## 2. Implementation Pattern

Use `useBaseTool` for simplified hook management. This is the recommended approach for all new tools:

**Parameters Hook** (`use[ToolName]Parameters.ts`):
```typescript
import { BaseParameters } from '../../../types/parameters';
import { useBaseParameters, BaseParametersHook } from '../shared/useBaseParameters';

export interface [ToolName]Parameters extends BaseParameters {
  // Define your tool-specific parameters here
  someOption: boolean;
}

export const defaultParameters: [ToolName]Parameters = {
  someOption: false,
};

export const use[ToolName]Parameters = (): BaseParametersHook<[ToolName]Parameters> => {
  return useBaseParameters({
    defaultParameters,
    endpointName: 'your-endpoint-name',
    validateFn: (params) => true, // Add validation logic
  });
};
```

**Operation Hook** (`use[ToolName]Operation.ts`):
```typescript
import { useTranslation } from 'react-i18next';
import { ToolType, useToolOperation } from '../shared/useToolOperation';
import { createStandardErrorHandler } from '../../../utils/toolErrorHandler';

export const build[ToolName]FormData = (parameters: [ToolName]Parameters, file: File): FormData => {
  const formData = new FormData();
  formData.append('fileInput', file);
  // Add parameters to formData
  return formData;
};

export const [toolName]OperationConfig = {
  toolType: ToolType.singleFile, // or ToolType.multiFile (buildFormData's file parameter will need to be updated)
  buildFormData: build[ToolName]FormData,
  operationType: '[toolName]',
  endpoint: '/api/v1/category/endpoint-name',
  filePrefix: 'processed_', // Will be overridden with translation
  defaultParameters,
} as const;

export const use[ToolName]Operation = () => {
  const { t } = useTranslation();
  return useToolOperation({
    ...[toolName]OperationConfig,
    filePrefix: t('[toolName].filenamePrefix', 'processed') + '_',
    getErrorMessage: createStandardErrorHandler(t('[toolName].error.failed', 'Operation failed'))
  });
};
```

**Main Component** (`[ToolName].tsx`):
```typescript
import { useTranslation } from "react-i18next";
import { createToolFlow } from "../components/tools/shared/createToolFlow";
import { use[ToolName]Parameters } from "../hooks/tools/[toolName]/use[ToolName]Parameters";
import { use[ToolName]Operation } from "../hooks/tools/[toolName]/use[ToolName]Operation";
import { useBaseTool } from "../hooks/tools/shared/useBaseTool";
import { BaseToolProps, ToolComponent } from "../types/tool";

const [ToolName] = (props: BaseToolProps) => {
  const { t } = useTranslation();
  const base = useBaseTool('[toolName]', use[ToolName]Parameters, use[ToolName]Operation, props);

  return createToolFlow({
    files: {
      selectedFiles: base.selectedFiles,
      isCollapsed: base.hasResults,
      placeholder: t("[toolName].files.placeholder", "Select files to get started"),
    },
    steps: [
      // Add settings steps if needed
    ],
    executeButton: {
      text: t("[toolName].submit", "Process"),
      isVisible: !base.hasResults,
      loadingText: t("loading"),
      onClick: base.handleExecute,
      disabled: !base.params.validateParameters() || !base.hasFiles || !base.endpointEnabled,
    },
    review: {
      isVisible: base.hasResults,
      operation: base.operation,
      title: t("[toolName].results.title", "Results"),
      onFileClick: base.handleThumbnailClick,
      onUndo: base.handleUndo,
    },
  });
};

[ToolName].tool = () => use[ToolName]Operation;
export default [ToolName] as ToolComponent;
```

**Note**: Some existing tools (like AddPassword, Compress) use a legacy pattern with manual hook management. **Always use the Modern Pattern above for new tools** - it's cleaner, more maintainable, and includes automation support.

## 3. Register Tool in System
Update these files to register your new tool:

**Tool Registry** (`frontend/editor/src/data/useTranslatedToolRegistry.tsx`):
1. Add imports at the top:
```typescript
import [ToolName] from "../tools/[ToolName]";
import { [toolName]OperationConfig } from "../hooks/tools/[toolName]/use[ToolName]Operation";
import [ToolName]Settings from "../components/tools/[toolName]/[ToolName]Settings";
```

2. Add tool entry in the `allTools` object:
```typescript
[toolName]: {
  icon: <LocalIcon icon="your-icon-name" width="1.5rem" height="1.5rem" />,
  name: t("home.[toolName].title", "Tool Name"),
  component: [ToolName],
  description: t("home.[toolName].desc", "Tool description"),
  categoryId: ToolCategoryId.STANDARD_TOOLS, // or appropriate category
  subcategoryId: SubcategoryId.APPROPRIATE_SUBCATEGORY,
  maxFiles: -1, // or specific number
  endpoints: ["endpoint-name"],
  operationConfig: [toolName]OperationConfig,
  settingsComponent: [ToolName]Settings, // if settings exist
},
```

## 4. Add Tooltips (Optional but Recommended)
Create user-friendly tooltips to help non-technical users understand your tool. **Use simple, clear language - avoid technical jargon:**

**Tooltip Hook** (`frontend/editor/src/components/tooltips/use[ToolName]Tips.ts`):
```typescript
import { useTranslation } from 'react-i18next';
import { TooltipContent } from '../../types/tips';

export const use[ToolName]Tips = (): TooltipContent => {
  const { t } = useTranslation();

  return {
    header: {
      title: t("[toolName].tooltip.header.title", "Tool Overview")
    },
    tips: [
      {
        title: t("[toolName].tooltip.description.title", "What does this tool do?"),
        description: t("[toolName].tooltip.description.text", "Simple explanation in everyday language that non-technical users can understand."),
        bullets: [
          t("[toolName].tooltip.description.bullet1", "Easy-to-understand benefit 1"),
          t("[toolName].tooltip.description.bullet2", "Easy-to-understand benefit 2")
        ]
      }
      // Add more tip sections as needed
    ]
  };
};
```

**Add tooltip to your main component:**
```typescript
import { use[ToolName]Tips } from "../components/tooltips/use[ToolName]Tips";

const [ToolName] = (props: BaseToolProps) => {
  const tips = use[ToolName]Tips();

  // In your steps array:
  steps: [
    {
      title: t("[toolName].steps.settings", "Settings"),
      tooltip: tips, // Add this line
      content: <[ToolName]Settings ... />
    }
  ]
```

## 5. Add Translations
Update translation files. **Important: Only update `en-US` files** - other languages are handled separately.

**File to update:** `frontend/editor/public/locales/en-US/translation.toml`

**Required Translation Keys**:
```toml
{
  "home": {
    "[toolName]": {
      "title": "Tool Name",
      "desc": "Tool description"
    }
  },
  "[toolName]": {
    "title": "Tool Name",
    "submit": "Process",
    "filenamePrefix": "processed",
    "files": {
      "placeholder": "Select files to get started"
    },
    "steps": {
      "settings": "Settings"
    },
    "options": {
      "title": "Tool Options",
      "someOption": "Option Label",
      "someOption.desc": "Option description",
      "note": "General information about the tool."
    },
    "results": {
      "title": "Results"
    },
    "error": {
      "failed": "Operation failed"
    },
    "tooltip": {
      "header": {
        "title": "Tool Overview"
      },
      "description": {
        "title": "What does this tool do?",
        "text": "Simple explanation in everyday language",
        "bullet1": "Easy-to-understand benefit 1",
        "bullet2": "Easy-to-understand benefit 2"
      }
    }
  }
}
```

**Translation Notes:**
- **Only update `en-US/translation.toml`** - other locale files are managed separately
- Use descriptive keys that match your component's `t()` calls
- Include tooltip translations if you created tooltip hooks
- Add `options.*` keys if your tool has settings with descriptions

**Tooltip Writing Guidelines:**
- **Use simple, everyday language** - avoid technical terms like "converts interactive elements"
- **Focus on benefits** - explain what the user gains, not how it works internally
- **Use concrete examples** - "text boxes become regular text" vs "form fields are flattened"
- **Answer user questions** - "What does this do?", "When should I use this?", "What's this option for?"
- **Keep descriptions concise** - 1-2 sentences maximum per section
- **Use bullet points** for multiple benefits or features

## 6. Testing Your Tool
- Verify tool appears in UI with correct icon and description
- Test with various file sizes and types
- Confirm translations work
- Check error handling
- Test undo functionality
- Verify results display correctly

## Tool Development Patterns

### Three Tool Patterns:

**Pattern 1: Single-File Tools** (Individual processing)
- Backend processes one file per API call
- Set `multiFileEndpoint: false`
- Examples: Compress, Rotate

**Pattern 2: Multi-File Tools** (Batch processing)
- Backend accepts `MultipartFile[]` arrays in single API call
- Set `multiFileEndpoint: true`
- Examples: Split, Merge, Overlay

**Pattern 3: Complex Tools** (Custom processing)
- Tools with complex routing logic or non-standard processing
- Provide `customProcessor` for full control
- Examples: Convert, OCR
