# EasyCropUpload
Um componente React para upload de imagens com funcionalidade de crop usando `react-easy-crop`.
## 🏗️ Arquitetura Refatorada
Este componente foi refatorado para uma arquitetura modular, dividindo responsabilidades em hooks customizados e componentes menores para melhor reutilização e manutenibilidade.
### 📁 Estrutura Modular
```
src/components/EasyCropUpload/
├── hooks/ # 🎣 Lógica de negócio
│ ├── useImageCropper.ts # Crop, zoom, rotação
│ ├── useImageFile.ts # Gerenciamento de arquivos
│ ├── useImageUpload.ts # Processo de upload
│ ├── useCategories.ts # Gerenciamento de categorias
│ └── index.ts # Exportações centralizadas
├── components/ # 🧩 Componentes UI reutilizáveis
│ ├── ImageCropper.tsx # Interface de crop interativa
│ ├── ExistingImagePreview.tsx # Preview de imagens existentes
│ └── ImagePreview.tsx # Preview da imagem cropada
├── utils/ # 🛠 Utilitários puros
│ └── imageDownload.ts # Funções de download
├── EasyCropUploadRefactored.tsx # 📋 Componente principal refatorado
├── index.tsx # 📄 Componente original (compatibilidade)
├── styles.ts # 💄 Estilos compartilhados
├── README.md # 📚 Esta documentação
└── REFACTORING.md # 📋 Detalhes da refatoração
```
### 🎯 Hooks Customizados
#### `useImageCropper`
- ✅ Gerencia estado do crop (posição, zoom, rotação)
- ✅ Controla área cropada em pixels
- ✅ Gera imagem cropada com alta qualidade
- ✅ Reset completo do cropper
#### `useImageFile`
- ✅ Gerencia upload e informações do arquivo
- ✅ Controla estado de imagens existentes
- ✅ Validação de tamanho e tipo de arquivo
- ✅ Inicialização de imagens do formulário
#### `useImageUpload`
- ✅ Processa upload para o servidor
- ✅ Validação de categorias obrigatórias
- ✅ Criação de FormData otimizado
- ✅ Estados de loading e erro
#### `useCategories`
- ✅ Gerencia categorias selecionadas
- ✅ Controla categorias filhas
- ✅ Sincronização com formulário
- ✅ Reset de estados
### 🧩 Componentes UI
#### `ImageCropper`
Interface completa para crop com controles de zoom, rotação e área de seleção.
#### `ExistingImagePreview`
Preview de imagens já salvas com opções de download e exclusão.
#### `ImagePreview`
Preview simples da imagem cropada antes do upload final.
## ✨ Características
- **🎯 Arquitetura Modular**: Dividido em hooks e componentes reutilizáveis
- **🖱️ Drag & Drop**: Interface de arrastar e soltar para seleção de arquivos
- **✂️ Crop Interativo**: Permite redimensionar, rotacionar e fazer zoom na imagem
- **👁️ Preview em Tempo Real**: Visualização da área selecionada para crop
- **🏷️ Suporte a Categorias**: Integração com sistema de categorização
- **✅ Validação de Arquivos**: Controle de tamanho máximo e tipos permitidos
- **📱 Responsivo**: Layout adaptável para diferentes tamanhos de tela
- **🧪 Testável**: Hooks podem ser testados isoladamente
- **🔄 Reutilizável**: Componentes podem ser usados em diferentes contextos
## 🚀 Uso Básico
### Componente Refatorado (Recomendado)
```tsx
import React from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import EasyCropUpload from './components/EasyCropUpload/EasyCropUploadRefactored';
const MyComponent = () => {
const methods = useForm();
const handleSave = async (formData: FormData) => {
// Sua lógica de upload aqui
const response = await uploadFile(formData);
return response;
};
return (
<FormProvider {...methods}>
<EasyCropUpload
isView={false}
showCategory={true}
aspectRatio={16 / 9}
maxFileSize={5}
onSave={handleSave}
/>
</FormProvider>
);
};
```
### Usando Hooks Individualmente
```tsx
import React from 'react';
import {
useImageCropper,
useImageFile,
useImageUpload,
useCategories
} from './components/EasyCropUpload/hooks';
const CustomImageUpload = () => {
const cropper = useImageCropper();
const imageFile = useImageFile();
const upload = useImageUpload();
const categories = useCategories();
// Implemente sua lógica customizada usando os hooks
// Cada hook gerencia uma parte específica da funcionalidade
return (
// Sua UI customizada
);
};
```
## 🔧 Props
| Prop | Tipo | Padrão | Descrição |
| ----------------- | ---------- | ----------------- | ----------------------------------------------------------- |
| `isView` | `boolean` | - | Se true, componente fica em modo de visualização (readonly) |
| `showCategory` | `boolean` | `false` | Habilita seleção de categorias |
| `aspectRatio` | `number` | `16/9` | Proporção do crop (largura/altura) |
| `maxFileSize` | `number` | `5` | Tamanho máximo do arquivo em MB |
| `compress` | `boolean` | `true` | Se deve comprimir a imagem |
| `keyFileId` | `string` | `'image_file_id'` | Chave para ID do arquivo no formulário |
| `keyImageFile` | `string` | `'image_file'` | Chave para dados do arquivo |
| `keyImageName` | `string` | `'image_name'` | Chave para nome do arquivo |
| `keyImageTooltip` | `string` | `'image_toltip'` | Chave para tooltip |
| `onSave` | `function` | - | Função callback para salvar a imagem cropada |
## 💾 Função onSave
A função `onSave` recebe um `FormData` e deve retornar uma Promise com o seguinte formato:
```tsx
type SaveResponse = {
file_id: string;
reference: string;
[key: string]: unknown;
};
const handleSave = async (formData: FormData): Promise<SaveResponse> => {
// Implementação do upload
};
```
## 🎛️ Controles de Crop
- **🔍 Zoom**: Controle deslizante de 1x a 3x
- **🔄 Rotação**: Controle deslizante de 0° a 360°
- **📐 Área de Crop**: Redimensionável e movível na imagem
- **👁️ Preview**: Visualização da imagem cropada antes do upload
## 🏷️ Categorias
Quando `showCategory={true}`, o componente permite:
- ✅ Seleção de categorias principais
- ✅ Seleção de subcategorias
- ✅ Validação obrigatória de pelo menos uma categoria
- ✅ Modal para gerenciamento de categorias
## 🚀 Migração e Benefícios
### Migração Simples
```tsx
// ❌ Antes (componente original)
import EasyCropUpload from './components/EasyCropUpload';
// ✅ Depois (componente refatorado - mesma API)
import EasyCropUpload from './components/EasyCropUpload/EasyCropUploadRefactored';
```
### 🎯 Benefícios da Refatoração
#### 🔄 **Reutilização Máxima**
- Hooks podem ser usados individualmente em outros componentes
- Componentes UI reutilizáveis em diferentes contextos
- Utilitários como funções puras completamente independentes
#### 🧪 **Testabilidade Aprimorada**
- Hooks podem ser testados isoladamente
- Componentes menores são mais fáceis de testar
- Lógica de negócio separada da apresentação
#### 🏗️ **Manutenibilidade**
- Responsabilidades bem definidas
- Código mais organizado e legível
- Alterações podem ser feitas em partes específicas
#### 📐 **Arquitetura Limpa**
- Separação clara entre lógica (hooks) e UI (componentes)
- Princípio da responsabilidade única
- Inversão de dependência
## 💡 Exemplo Completo
```tsx
import React from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import EasyCropUpload from './components/EasyCropUpload/EasyCropUploadRefactored';
const ImageUploadForm = () => {
const methods = useForm();
const handleImageSave = async (formData: FormData) => {
try {
const response = await fetch('/api/upload', {
method: 'POST',
body: formData,
});
const result = await response.json();
return {
file_id: result.id,
reference: result.url,
...result,
};
} catch (error) {
console.error('Upload failed:', error);
throw error;
}
};
return (
<FormProvider {...methods}>
<form>
<h2>Upload de Imagem com Crop</h2>
<EasyCropUpload
isView={false}
showCategory={true}
aspectRatio={16 / 9}
maxFileSize={10}
compress={true}
onSave={handleImageSave}
/>
<button type="submit">Salvar Formulário</button>
</form>
</FormProvider>
);
};
export default ImageUploadForm;
```
## 📦 Dependências
- **react-easy-crop**: Biblioteca para crop de imagens interativo
- **react-dropzone**: Funcionalidade drag & drop otimizada
- **react-hook-form**: Gerenciamento de formulários performático
- **react-dom**: Para portais (modais)
- **date-fns**: Formatação de datas
## 🔄 Compatibilidade e Migração
### ✅ Totalmente Compatível
- **API idêntica** ao componente original
- **Mesmo comportamento** e funcionalidades
- **Drop-in replacement** sem quebrar código existente
- **Performance melhorada** com arquitetura otimizada
### 📈 Melhorias em Relação ao Original
- **Modularidade**: Componentes e hooks reutilizáveis
- **Testabilidade**: Cada parte pode ser testada isoladamente
- **Manutenibilidade**: Código mais organizado e focado
- **Extensibilidade**: Fácil adicionar novas funcionalidades
- **Performance**: Renderizações otimizadas e menos re-renders
### 🛠️ Desenvolvimento e Testes
```bash
# Executar testes dos hooks
npm test -- --testPathPattern=EasyCropUpload/hooks
# Executar testes dos componentes
npm test -- --testPathPattern=EasyCropUpload/components
```
## 📚 Documentação Adicional
- **[REFACTORING.md](./REFACTORING.md)**: Detalhes técnicos da refatoração
- **Exemplos de uso**: Veja os testes unitários para exemplos práticos
- **Tipos TypeScript**: Todos os hooks e componentes são tipados
---
> **💡 Dica**: Para aproveitar ao máximo a modularidade, considere usar os hooks individuais em componentes customizados quando precisar de funcionalidades específicas sem toda a UI completa.