# 🎯 Textarea Input - Exemplos de Integração no PraFrota

## 📋 Uso em FormConfig

Exemplos de como adicionar campos de textarea em diferentes domínios do PraFrota:

### 🚛 Exemplo 1: Observações em Veículos

```typescript
// projects/idt_app/src/app/domain/vehicles/vehicles.component.ts
export class VehiclesComponent extends BaseDomainComponent<Vehicle> {
  
  getVehicleFormConfig(): TabFormConfig {
    return {
      title: 'Dados do Veículo',
      entityType: 'vehicle',
      fields: [],
      subTabs: [
        {
          id: 'observacoes',
          label: 'Observações',
          fields: [
            {
              key: 'observacoes_gerais',
              label: 'Observações Gerais',
              type: 'textarea-input',
              required: false,
              maxLength: 800,
              rows: 5,
              placeholder: 'Descreva o estado geral do veículo, problemas identificados, recomendações, etc.',
              autoResize: true,
              showCharCounter: true
            },
            {
              key: 'historico_manutencao',
              label: 'Histórico de Manutenção',
              type: 'textarea-input',
              required: false,
              maxLength: 1200,
              rows: 6,
              placeholder: 'Registre o histórico de manutenções, peças trocadas, serviços realizados...',
              autoResize: true,
              showCharCounter: true
            },
            {
              key: 'instrucoes_uso',
              label: 'Instruções de Uso',
              type: 'textarea-input',
              required: false,
              maxLength: 600,
              rows: 4,
              placeholder: 'Instruções específicas para operação deste veículo...',
              autoResize: true,
              showCharCounter: true
            }
          ]
        }
      ]
    };
  }
}
```

### 👨‍✈️ Exemplo 2: Notas em Motoristas

```typescript
// projects/idt_app/src/app/domain/drivers/drivers.component.ts
export class DriversComponent extends BaseDomainComponent<Driver> {
  
  getDriverFormConfig(): TabFormConfig {
    return {
      title: 'Dados do Motorista',
      entityType: 'driver',
      fields: [],
      subTabs: [
        {
          id: 'observacoes',
          label: 'Observações',
          fields: [
            {
              key: 'observacoes_comportamento',
              label: 'Observações de Comportamento',
              type: 'textarea-input',
              required: false,
              maxLength: 500,
              rows: 4,
              placeholder: 'Registre observações sobre comportamento, pontualidade, cuidado com veículos...',
              autoResize: true,
              showCharCounter: true
            },
            {
              key: 'historico_ocorrencias',
              label: 'Histórico de Ocorrências',
              type: 'textarea-input',
              required: false,
              maxLength: 1000,
              rows: 6,
              placeholder: 'Histórico de acidentes, multas, elogios, treinamentos realizados...',
              autoResize: true,
              showCharCounter: true
            },
            {
              key: 'competencias_especiais',
              label: 'Competências Especiais',
              type: 'textarea-input',
              required: false,
              maxLength: 400,
              rows: 3,
              placeholder: 'Experiência com tipos específicos de carga, rotas, equipamentos...',
              autoResize: true,
              showCharCounter: true
            }
          ]
        }
      ]
    };
  }
}
```

### 🗺️ Exemplo 3: Descrições em Rotas

```typescript
// projects/idt_app/src/app/domain/routes/routes.component.ts
export class RoutesComponent extends BaseDomainComponent<Route> {
  
  getRouteFormConfig(): TabFormConfig {
    return {
      title: 'Dados da Rota',
      entityType: 'route',
      fields: [],
      subTabs: [
        {
          id: 'instrucoes',
          label: 'Instruções',
          fields: [
            {
              key: 'instrucoes_motorista',
              label: 'Instruções para o Motorista',
              type: 'textarea-input',
              required: true,
              maxLength: 1000,
              rows: 6,
              placeholder: 'Instruções detalhadas: pontos de atenção, horários especiais, contatos importantes...',
              autoResize: true,
              showCharCounter: true
            },
            {
              key: 'observacoes_rota',
              label: 'Observações da Rota',
              type: 'textarea-input',
              required: false,
              maxLength: 600,
              rows: 4,
              placeholder: 'Características especiais da rota, dificuldades, pontos de referência...',
              autoResize: true,
              showCharCounter: true
            },
            {
              key: 'restricoes_horarios',
              label: 'Restrições e Horários',
              type: 'textarea-input',
              required: false,
              maxLength: 400,
              rows: 3,
              placeholder: 'Restrições de circulação, horários de entrega, janelas de tempo...',
              autoResize: true,
              showCharCounter: true
            }
          ]
        }
      ]
    };
  }
}
```

### 💰 Exemplo 4: Justificativas Financeiras

```typescript
// projects/idt_app/src/app/domain/finances/account-payable/account-payable.component.ts
export class AccountPayableComponent extends BaseDomainComponent<AccountPayable> {
  
  getAccountPayableFormConfig(): TabFormConfig {
    return {
      title: 'Conta a Pagar',
      entityType: 'account-payable',
      fields: [],
      subTabs: [
        {
          id: 'detalhes',
          label: 'Detalhes',
          fields: [
            {
              key: 'justificativa',
              label: 'Justificativa da Despesa',
              type: 'textarea-input',
              required: true,
              maxLength: 800,
              rows: 5,
              placeholder: 'Justifique a necessidade desta despesa, qual problema resolve, benefícios esperados...',
              autoResize: true,
              showCharCounter: true
            },
            {
              key: 'observacoes_pagamento',
              label: 'Observações de Pagamento',
              type: 'textarea-input',
              required: false,
              maxLength: 400,
              rows: 3,
              placeholder: 'Informações sobre forma de pagamento, condições especiais, contatos...',
              autoResize: true,
              showCharCounter: true
            }
          ]
        }
      ]
    };
  }
}
```

### 📝 Exemplo 5: Relatórios e Feedbacks

```typescript
// Componente genérico para relatórios
export class ReportFormComponent {
  
  getReportFormConfig(): TabFormConfig {
    return {
      title: 'Relatório de Operação',
      entityType: 'report',
      fields: [],
      subTabs: [
        {
          id: 'relatorio',
          label: 'Relatório',
          fields: [
            {
              key: 'resumo_executivo',
              label: 'Resumo Executivo',
              type: 'textarea-input',
              required: true,
              maxLength: 300,
              rows: 3,
              placeholder: 'Resumo objetivo dos principais pontos do relatório...',
              autoResize: true,
              showCharCounter: true,
              resizable: false
            },
            {
              key: 'detalhes_operacao',
              label: 'Detalhes da Operação',
              type: 'textarea-input',
              required: true,
              maxLength: 1500,
              rows: 8,
              placeholder: 'Descreva detalhadamente o que aconteceu durante a operação...',
              autoResize: true,
              showCharCounter: true
            },
            {
              key: 'problemas_identificados',
              label: 'Problemas Identificados',
              type: 'textarea-input',
              required: false,
              maxLength: 800,
              rows: 5,
              placeholder: 'Liste e descreva os problemas encontrados durante a operação...',
              autoResize: true,
              showCharCounter: true
            },
            {
              key: 'recomendacoes',
              label: 'Recomendações',
              type: 'textarea-input',
              required: false,
              maxLength: 600,
              rows: 4,
              placeholder: 'Suas recomendações para melhorar processos, evitar problemas...',
              autoResize: true,
              showCharCounter: true
            }
          ]
        }
      ]
    };
  }
}
```

## 🔧 Configurações Personalizadas

### Campo Compacto para Comentários Rápidos

```typescript
{
  key: 'comentario_rapido',
  label: 'Comentário',
  type: 'textarea-input',
  required: false,
  maxLength: 150,
  rows: 2,
  placeholder: 'Comentário breve...',
  autoResize: true,
  showCharCounter: true,
  resizable: false
}
```

### Campo Expandido para Descrições Detalhadas

```typescript
{
  key: 'descricao_detalhada',
  label: 'Descrição Detalhada',
  type: 'textarea-input',
  required: true,
  maxLength: 2000,
  rows: 10,
  placeholder: 'Forneça uma descrição completa e detalhada...',
  autoResize: false,
  showCharCounter: true,
  resizable: true
}
```

### Campo ReadOnly para Informações do Sistema

```typescript
{
  key: 'info_sistema',
  label: 'Informações do Sistema',
  type: 'textarea-input',
  readOnly: true,
  rows: 3,
  showCharCounter: false,
  autoResize: false,
  resizable: false
}
```

## 🎨 Integração com Validação Customizada

```typescript
// Validator personalizado para textarea
export class TextareaValidators {
  
  static minimumWords(minWords: number): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      if (!control.value) return null;
      
      const wordCount = control.value.trim().split(/\s+/).length;
      return wordCount < minWords 
        ? { minimumWords: { required: minWords, actual: wordCount } }
        : null;
    };
  }
  
  static forbiddenWords(forbiddenWords: string[]): ValidatorFn {
    return (control: AbstractControl): ValidationErrors | null => {
      if (!control.value) return null;
      
      const text = control.value.toLowerCase();
      const foundWords = forbiddenWords.filter(word => 
        text.includes(word.toLowerCase())
      );
      
      return foundWords.length > 0
        ? { forbiddenWords: { words: foundWords } }
        : null;
    };
  }
}

// Uso no FormBuilder
this.form = this.fb.group({
  observacoes: ['', [
    Validators.required,
    Validators.maxLength(500),
    TextareaValidators.minimumWords(10),
    TextareaValidators.forbiddenWords(['teste', 'exemplo'])
  ]]
});
```

## 📊 Casos de Uso por Domínio

### **Veículos** 🚛
```typescript
// Campos comuns para veículos
const vehicleTextareaFields = {
  observacoes_gerais: { maxLength: 800, rows: 5 },
  historico_manutencao: { maxLength: 1200, rows: 6 },
  instrucoes_uso: { maxLength: 600, rows: 4 },
  problemas_conhecidos: { maxLength: 500, rows: 4 }
};
```

### **Motoristas** 👨‍✈️
```typescript
// Campos comuns para motoristas
const driverTextareaFields = {
  observacoes_comportamento: { maxLength: 500, rows: 4 },
  historico_ocorrencias: { maxLength: 1000, rows: 6 },
  competencias_especiais: { maxLength: 400, rows: 3 },
  feedback_clientes: { maxLength: 600, rows: 4 }
};
```

### **Rotas** 🗺️
```typescript
// Campos comuns para rotas
const routeTextareaFields = {
  instrucoes_motorista: { maxLength: 1000, rows: 6, required: true },
  observacoes_rota: { maxLength: 600, rows: 4 },
  restricoes_horarios: { maxLength: 400, rows: 3 },
  pontos_atencao: { maxLength: 500, rows: 4 }
};
```

### **Financeiro** 💰
```typescript
// Campos comuns para financeiro
const financeTextareaFields = {
  justificativa: { maxLength: 800, rows: 5, required: true },
  observacoes_pagamento: { maxLength: 400, rows: 3 },
  condicoes_especiais: { maxLength: 300, rows: 2 },
  notas_aprovacao: { maxLength: 500, rows: 4 }
};
```

## 🚀 Scripts de Geração Automática

```bash
# Script para incluir textarea automaticamente
npm run create:domain:express -- maintenance "Manutenção" 5 --textarea --commit

# Ou criar manualmente com prompt
node scripts/create-domain.js
# Pergunta: Incluir campos de texto longo (textarea)? (s/n): s
```

## 📝 Checklist de Implementação

- [ ] ✅ Adicionar campo `type: 'textarea-input'` no FormConfig
- [ ] ✅ Definir `maxLength` apropriado para o contexto
- [ ] ✅ Configurar número de `rows` inicial
- [ ] ✅ Escolher se deve ter `autoResize`
- [ ] ✅ Definir se precisa de `showCharCounter`
- [ ] ✅ Configurar `placeholder` descritivo
- [ ] ✅ Aplicar validações necessárias
- [ ] ✅ Testar comportamento responsivo
- [ ] ✅ Verificar integração com service (API)

## 🎯 Boas Práticas

### **Para Observações**
- Máximo 500-800 caracteres
- 4-5 rows iniciais
- Auto-resize habilitado
- Contador sempre visível

### **Para Instruções**
- Máximo 1000-1500 caracteres
- 6-8 rows iniciais
- Auto-resize habilitado
- Campo obrigatório se crítico

### **Para Comentários**
- Máximo 200-300 caracteres
- 2-3 rows iniciais
- Auto-resize habilitado
- Não redimensionável

### **Para Descrições Técnicas**
- Máximo 1500-2000 caracteres
- 8-10 rows iniciais
- Auto-resize desabilitado
- Redimensionamento manual permitido

---

**💡 Dica**: O textarea-input está totalmente integrado ao sistema de formulários do PraFrota. Use `type: 'textarea-input'` em qualquer TabFormConfig para campos de texto longo! 📝🚛 