--- name: customer-ui-components description: Componentes de UI para clientes seguindo o padrão de components do Easy Budget. --- # Componentes de UI para Clientes Esta skill define os componentes Blade específicos para a gestão de clientes no Easy Budget, seguindo o padrão de components estabelecido no sistema. ## Estrutura de Components ``` resources/views/components/ ├── customer/ │ ├── customer-card.blade.php # Card resumido de cliente │ ├── customer-details.blade.php # Detalhes completos do cliente │ ├── customer-form.blade.php # Formulário de criação/edição │ ├── customer-status.blade.php # Badge de status do cliente │ ├── customer-contact.blade.php # Informações de contato │ ├── customer-address.blade.php # Endereço do cliente │ ├── customer-actions.blade.php # Ações disponíveis para cliente │ ├── customer-filters.blade.php # Filtros específicos para clientes │ ├── customer-interactions.blade.php # Histórico de interações │ └── customer-summary.blade.php # Resumo do cliente └── ... ``` ## 1. Customer Card Component Componente para exibição resumida de clientes em listas e dashboards. ### Uso Básico ```blade ``` ### Parâmetros | Parâmetro | Tipo | Descrição | Padrão | |-----------|------|-----------|--------| | `customer` | `Customer` | Modelo do cliente | Obrigatório | | `showType` | `bool` | Exibir tipo de cliente (PF/PJ) | `true` | | `showStatus` | `bool` | Exibir status do cliente | `true` | | `variant` | `string` | Estilo do card (primary, secondary, etc.) | `primary` | ### Estrutura ```blade @props([ 'customer', 'showType' => true, 'showStatus' => true, 'variant' => 'primary' ])
@if($customer->type === 'pf') @else @endif
{{ $customer->display_name }}
{{ $customer->created_at->format('d/m/Y') }}
@if($showStatus) @endif
@if($showType)
{{ $customer->type === 'pf' ? 'Pessoa Física' : 'Pessoa Jurídica' }}
@endif @if($customer->contact)
E-mail:
{{ $customer->contact->email }}
@endif @if($customer->address)
Endereço:
{{ $customer->address->city }}/{{ $customer->address->state }}
@endif
Total de Orçamentos
{{ $customer->budgets->count() }}
``` ## 2. Customer Details Component Componente para exibição detalhada de informações do cliente. ### Uso Básico ```blade ``` ### Parâmetros | Parâmetro | Tipo | Descrição | Padrão | |-----------|------|-----------|--------| | `customer` | `Customer` | Modelo do cliente | Obrigatório | | `showContact` | `bool` | Exibir informações de contato | `true` | | `showAddress` | `bool` | Exibir endereço | `true` | | `collapsible` | `bool` | Permitir colapsar seções | `false` | ### Estrutura ```blade @props([ 'customer', 'showContact' => true, 'showAddress' => true, 'collapsible' => false ])
{{ $customer->display_name }}
{{ $customer->type === 'pf' ? 'Pessoa Física' : 'Pessoa Jurídica' }}
@if($customer->commonData)
{{ $customer->type === 'pf' ? 'Dados Pessoais' : 'Dados Empresariais' }}
@if($customer->type === 'pf')
{{ $customer->commonData->first_name }} {{ $customer->commonData->last_name }}
{{ $customer->commonData->birth_date?->format('d/m/Y') ?? 'Não informado' }}
@if($customer->commonData->cpf)
{{ \App\Helpers\DocumentHelper::formatCpf($customer->commonData->cpf) }}
@endif
@else
{{ $customer->commonData->company_name }}
@if($customer->commonData->cnpj)
{{ \App\Helpers\DocumentHelper::formatCnpj($customer->commonData->cnpj) }}
@endif @if($customer->commonData->cpf)
{{ \App\Helpers\DocumentHelper::formatCpf($customer->commonData->cpf) }}
@endif
@endif
@if($customer->commonData->areaOfActivity)
{{ $customer->commonData->areaOfActivity->name }}
@endif @if($customer->commonData->profession)
{{ $customer->commonData->profession->name }}
@endif @if($customer->commonData->description)
{{ $customer->commonData->description }}
@endif
@endif @if($showContact && $customer->contact) @endif @if($showAddress && $customer->address) @endif
``` ## 3. Customer Status Component Componente para exibição do status do cliente com cores e ícones apropriados. ### Uso Básico ```blade ``` ### Parâmetros | Parâmetro | Tipo | Descrição | Padrão | |-----------|------|-----------|--------| | `customer` | `Customer` | Modelo do cliente | Obrigatório | | `showIcon` | `bool` | Exibir ícone ao lado do status | `true` | | `size` | `string` | Tamanho do badge (sm, md, lg) | `md` | ### Estrutura ```blade @props([ 'customer', 'showIcon' => true, 'size' => 'md' ]) @php $status = $customer->status; $color = match($status) { 'active' => '#198754', // Verde 'inactive' => '#6c757d', // Cinza 'pending' => '#ffc107', // Amarelo default => '#6c757d' }; $icon = match($status) { 'active' => 'check-circle', 'inactive' => 'x-circle', 'pending' => 'clock', default => 'circle' }; $description = match($status) { 'active' => 'Ativo', 'inactive' => 'Inativo', 'pending' => 'Pendente', default => 'Status Desconhecido' }; $sizeClass = match($size) { 'sm' => 'badge-sm', 'lg' => 'badge-lg', default => 'badge-md' }; @endphp @if($showIcon) @endif {{ $description }} ``` ## 4. Customer Contact Component Componente para exibição de informações de contato do cliente. ### Uso Básico ```blade ``` ### Parâmetros | Parâmetro | Tipo | Descrição | Padrão | |-----------|------|-----------|--------| | `contact` | `Contact` | Modelo de contato | Obrigatório | | `showBusiness` | `bool` | Exibir contatos comerciais | `true` | | `showWebsite` | `bool` | Exibir website | `true` | ### Estrutura ```blade @props([ 'contact', 'showBusiness' => true, 'showWebsite' => true ])
Informações de Contato
{{ $contact->email }}
@if($contact->phone)
{{ $contact->phone }}
@endif
@if($showBusiness)
@if($contact->email_business)
{{ $contact->email_business }}
@endif @if($contact->phone_business)
{{ $contact->phone_business }}
@endif
@endif
@if($showWebsite && $contact->website) @endif
``` ## 5. Customer Address Component Componente para exibição de endereço do cliente. ### Uso Básico ```blade ``` ### Parâmetros | Parâmetro | Tipo | Descrição | Padrão | |-----------|------|-----------|--------| | `address` | `Address` | Modelo de endereço | Obrigatório | ### Estrutura ```blade @props(['address'])
Endereço
{{ $address->address }}, {{ $address->address_number }} @if($address->address_complement) - {{ $address->address_complement }} @endif
{{ $address->neighborhood }}
{{ $address->cep }}
{{ $address->city }}
{{ $address->state }}
@if($address->country && $address->country !== 'Brasil')
{{ $address->country }}
@endif
``` ## 6. Customer Form Component Componente para formulário de criação e edição de clientes. ### Uso Básico ```blade ``` ### Parâmetros | Parâmetro | Tipo | Descrição | Padrão | |-----------|------|-----------|--------| | `customer` | `Customer|null` | Modelo do cliente (para edição) | `null` | | `areasOfActivity` | `Collection` | Áreas de atuação disponíveis | Obrigatório | | `professions` | `Collection` | Profissões disponíveis | Obrigatório | | `type` | `string` | Tipo de cliente (pf/pj) | `pf` | ### Estrutura ```blade @props([ 'customer' => null, 'areasOfActivity' => [], 'professions' => [], 'type' => 'pf' ])
@csrf @if(isset($customer)) @method('PUT') @endif
type ?? $type) == 'pf') ? 'checked' : '' }} required> type ?? $type) == 'pj') ? 'checked' : '' }} required>
{{ $type === 'pf' ? 'Dados Pessoais' : 'Dados Empresariais' }}
@if($type === 'pf')
@error('first_name')
{{ $message }}
@enderror
@error('last_name')
{{ $message }}
@enderror
@error('birth_date')
{{ $message }}
@enderror
@error('cpf')
{{ $message }}
@enderror
@else
@error('company_name')
{{ $message }}
@enderror
@error('cnpj')
{{ $message }}
@enderror
@error('cpf')
{{ $message }}
@enderror
@endif
@error('area_of_activity_id')
{{ $message }}
@enderror
@error('profession_id')
{{ $message }}
@enderror
@error('description')
{{ $message }}
@enderror
Informações de Contato
@error('email')
{{ $message }}
@enderror
@error('phone')
{{ $message }}
@enderror
@error('email_business')
{{ $message }}
@enderror
@error('phone_business')
{{ $message }}
@enderror
@error('website')
{{ $message }}
@enderror
Endereço
@error('address')
{{ $message }}
@enderror
@error('address_number')
{{ $message }}
@enderror
@error('address_complement')
{{ $message }}
@enderror
@error('neighborhood')
{{ $message }}
@enderror
@error('cep')
{{ $message }}
@enderror
@error('city')
{{ $message }}
@enderror
@error('state')
{{ $message }}
@enderror
@error('country')
{{ $message }}
@enderror
Cancelar
@push('scripts') @endpush ``` ## 7. Customer Actions Component Componente para exibição de ações disponíveis para um cliente. ### Uso Básico ```blade ``` ### Parâmetros | Parâmetro | Tipo | Descrição | Padrão | |-----------|------|-----------|--------| | `customer` | `Customer` | Modelo do cliente | Obrigatório | | `showBudget` | `bool` | Exibir botão de novo orçamento | `true` | | `showInvoice` | `bool` | Exibir botão de nova fatura | `true` | | `showSendEmail` | `bool` | Exibir botão de envio de e-mail | `true` | ### Estrutura ```blade @props([ 'customer', 'showBudget' => true, 'showInvoice' => true, 'showSendEmail' => true ])
Visualizar Editar @if($showBudget) Orçamento @endif @if($showInvoice) Fatura @endif @if($showSendEmail) @endif
``` ## 8. Customer Filters Component Componente para filtros específicos de listagem de clientes. ### Uso Básico ```blade ``` ### Parâmetros | Parâmetro | Tipo | Descrição | Padrão | |-----------|------|-----------|--------| | `filters` | `array` | Filtros atuais | `[]` | | `showType` | `bool` | Exibir filtro por tipo | `true` | | `showStatus` | `bool` | Exibir filtro por status | `true` | | `showDateRange` | `bool` | Exibir filtro por período | `true` | ### Estrutura ```blade @props([ 'filters' => [], 'showType' => true, 'showStatus' => true, 'showDateRange' => true ])
@if($showType)
@endif @if($showStatus)
@endif @if($showDateRange)
até
@endif
Limpar
``` ## 9. Customer Interactions Component Componente para exibição do histórico de interações do cliente. ### Uso Básico ```blade ``` ### Parâmetros | Parâmetro | Tipo | Descrição | Padrão | |-----------|------|-----------|--------| | `customer` | `Customer` | Modelo do cliente | Obrigatório | | `showRecent` | `bool` | Exibir apenas interações recentes | `true` | | `limit` | `int` | Limite de interações a exibir | `10` | ### Estrutura ```blade @props([ 'customer', 'showRecent' => true, 'limit' => 10 ])
Histórico de Interações
@if($customer->activities->isNotEmpty())
@foreach($customer->activities->take($limit) as $activity)
{{ $activity->description }}
{{ $activity->created_at->diffForHumans() }}

{{ $activity->metadata }}

{{ $activity->action_type }}
@endforeach
@else

Nenhuma interação registrada

@endif
``` ## 10. Customer Summary Component Componente para exibição de resumo do cliente. ### Uso Básico ```blade ``` ### Parâmetros | Parâmetro | Tipo | Descrição | Padrão | |-----------|------|-----------|--------| | `customer` | `Customer` | Modelo do cliente | Obrigatório | | `showStats` | `bool` | Exibir estatísticas | `true` | | `showLastInteraction` | `bool` | Exibir última interação | `true` | ### Estrutura ```blade @props([ 'customer', 'showStats' => true, 'showLastInteraction' => true ])
@if($showStats)
Orçamentos
{{ $customer->budgets->count() }}
Faturas
{{ $customer->invoices->count() }}
Valor Total
R$ {{ number_format($customer->invoices->sum('total'), 2, ',', '.') }}
@endif
@if($showLastInteraction && $customer->activities->isNotEmpty())
Última Interação
{{ $customer->activities->first()->description }}

{{ $customer->activities->first()->metadata }}

{{ $customer->activities->first()->created_at->format('d/m/Y H:i') }}
{{ $customer->activities->first()->action_type }}
@endif
``` ## 11. Integração com Padrões Existentes ### Uso em Views ```blade {{-- Dashboard --}} {{-- Listagem --}} {{-- Formulários --}} {{-- Ações --}} ``` ### Estilos CSS ```css /* Customer Components Styles */ .customer-form .btn-check:checked + .btn { background-color: #0d6efd; border-color: #0d6efd; color: white; } .customer-form .btn-check:checked + .btn-secondary { background-color: #6c757d; border-color: #6c757d; } .customer-actions .btn { transition: all 0.2s ease; } .customer-actions .btn:hover { transform: translateY(-1px); box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .customer-summary .card { border-left: 4px solid #0d6efd; } ``` ## 12. JavaScript Interatividade ### Formulário de Cliente ```javascript // customer-form.js document.addEventListener('DOMContentLoaded', function() { // Alternar campos conforme tipo de cliente const typeRadios = document.querySelectorAll('input[name="type"]'); const cpfField = document.querySelector('input[name="cpf"]'); const cnpjField = document.querySelector('input[name="cnpj"]'); function toggleFields() { const selectedType = document.querySelector('input[name="type"]:checked').value; if (selectedType === 'pf') { cnpjField.closest('.row').style.display = 'none'; cpfField.closest('.row').style.display = 'block'; } else { cnpjField.closest('.row').style.display = 'block'; cpfField.closest('.row').style.display = 'block'; } } typeRadios.forEach(radio => { radio.addEventListener('change', toggleFields); }); // Inicializar campos toggleFields(); }); ``` ## 13. Validação e Segurança ### Autorização ```php // CustomerPolicy.php public function view(User $user, Customer $customer) { return $user->tenant_id === $customer->tenant_id; } public function update(User $user, Customer $customer) { return $user->tenant_id === $customer->tenant_id; } public function delete(User $user, Customer $customer) { return $user->tenant_id === $customer->tenant_id && $customer->budgets->isEmpty() && $customer->invoices->isEmpty(); } ``` ### Validations ```blade {{-- Customer Card com validação de permissões --}} @can('view', $customer) @endcan {{-- Customer Actions com validação de status --}} @can('update', $customer) @endcan ``` Este padrão de components para clientes garante consistência visual, reutilização de código e manutenibilidade, seguindo os mesmos princípios estabelecidos nos outros components do sistema.