Compare commits

..

No commits in common. "0dc2c8d88ce856d5cfa061f0e926a36df7ec8901" and "aa9affa16ded6d4f1c5668eb2c06a9091bba834f" have entirely different histories.

9 changed files with 164 additions and 124 deletions

View File

@ -13,6 +13,7 @@ class ClientController extends Controller
public function __construct(ClientService $userService) {} public function __construct(ClientService $userService) {}
public function dashboard(Request $request): View public function dashboard(Request $request): View
{ {
return view('dashboard'); $clients = Client::all();
return view('dashboard', ['clients' => $clients]);
} }
} }

View File

@ -5,7 +5,6 @@
use App\Models\Client; use App\Models\Client;
use App\Services\ClientService; use App\Services\ClientService;
use App\Livewire\Forms\ClientForm; // 1. Importa seu Form Object use App\Livewire\Forms\ClientForm; // 1. Importa seu Form Object
use Illuminate\Support\Facades\Auth;
use Livewire\Component; use Livewire\Component;
use Livewire\WithFileUploads; use Livewire\WithFileUploads;
use Illuminate\Support\Facades\Crypt; use Illuminate\Support\Facades\Crypt;

View File

@ -1,30 +0,0 @@
<?php
namespace App\Livewire\Admin;
use Livewire\Component;
use Livewire\Attributes\On;
use App\Models\Client;
class DeleteClient extends Component
{
#[On('confirm-delete')]
public function deleteClient($payload)
{
$deletedClient = Client::findOrFail($payload);
if ($deletedClient) {
$deletedClient->delete();
}
$this->dispatch('clientDeleted');
// (Opcional) Envia uma notificação de sucesso
$this->dispatch('notify', message: 'Cliente excluído com sucesso!');
}
public function render()
{
return '<div></div>';
}
}

View File

@ -1,23 +0,0 @@
<?php
namespace App\Livewire\Admin;
use App\Models\Client;
use Livewire\Component;
use Livewire\Attributes\On;
class ShowClient extends Component
{
#[On('clientDeleted')]
public function refreshClientList() {}
public function render()
{
$clients = Client::all();
return view('livewire.admin.show-client', [
'clients' => $clients
]);
}
}

View File

@ -8,6 +8,7 @@
class ClientForm extends Form class ClientForm extends Form
{ {
// 2. ATRIBUTOS REMOVIDOS: Os #[Rule(...)] foram removidos daqui
public $client_name = ''; public $client_name = '';
public $legal_name = ''; public $legal_name = '';
public $cnpj = ''; public $cnpj = '';

View File

@ -4,7 +4,6 @@
use App\Models\Client; use App\Models\Client;
use App\Models\User; use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate; use Illuminate\Support\Facades\Gate;
class ClientService class ClientService
@ -13,10 +12,6 @@ class ClientService
public function __construct(protected Client $client) {} public function __construct(protected Client $client) {}
public function addClient(array $client) public function addClient(array $client)
{ {
if (!Auth::check()) {
return redirect()->to('/login');
}
return Client::create($client); return Client::create($client);
} }
} }

View File

@ -3,35 +3,42 @@
- 'showQuestion' controla a visibilidade. - 'showQuestion' controla a visibilidade.
- '@sure.window' é o evento que dispara a abertura. - '@sure.window' é o evento que dispara a abertura.
--> -->
<div x-data="{showQuestion: false, clientId: null}" @sure.window="showQuestion = true; clientId = $event.detail.id" <div x-data="{showQuestion: false}"
x-cloak {{-- x-cloak é bom para evitar "piscadas" na tela --}}> @sure.window="showQuestion = true"
x-cloak {{-- x-cloak é bom para evitar "piscadas" na tela --}}
>
<!-- <!--
1. O OVERLAY (Fundo) 1. O OVERLAY (Fundo)
Copiado 1-para-1 do seu 'create-user' Copiado 1-para-1 do seu 'create-user'
--> -->
<div x-show="showQuestion" class="modal-overlay" x-transition:enter.duration.300ms <div x-show="showQuestion"
x-transition:leave.duration.300ms> class="modal-overlay"
x-transition:enter.duration.300ms
x-transition:leave.duration.300ms
>
<!-- <!--
2. O CONTAINER (Card) 2. O CONTAINER (Card)
Copiado 1-para-1 do seu 'create-user' Copiado 1-para-1 do seu 'create-user'
--> -->
<div x-on:click.outside="showQuestion = false" x-show="showQuestion" x-transition:enter="transition-enter" <div x-on:click.outside="showQuestion = false"
x-transition:enter-start="transition-enter-start" x-transition:enter-end="transition-enter-end" x-show="showQuestion"
x-transition:leave="transition-leave" x-transition:leave-start="transition-leave-start" x-transition:enter="transition-enter"
x-transition:leave-end="transition-leave-end" class="modal-container max-w-sm" {{-- Adicionei 'max-w-sm' x-transition:enter-start="transition-enter-start"
para um modal de alerta menor --}}> x-transition:enter-end="transition-enter-end"
x-transition:leave="transition-leave"
x-transition:leave-start="transition-leave-start"
x-transition:leave-end="transition-leave-end"
class="modal-container max-w-sm" {{-- Adicionei 'max-w-sm' para um modal de alerta menor --}}
>
<!-- 3. O NOVO CONTEÚDO (Confirmação) --> <!-- 3. O NOVO CONTEÚDO (Confirmação) -->
<!-- Ícone de Alerta --> <!-- Ícone de Alerta -->
<div <div class="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10">
class="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-red-100 sm:mx-0 sm:h-10 sm:w-10"> <svg class="h-6 w-6 text-red-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<svg class="h-6 w-6 text-red-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" <path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round"
d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z" />
</svg> </svg>
</div> </div>
@ -40,12 +47,12 @@ class="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-
<h3 class="modal-title" id="modal-title"> <h3 class="modal-title" id="modal-title">
Confirmar Exclusão Confirmar Exclusão
</h3> </h3>
<!-- Descrição --> <!-- Descrição -->
<div class="mt-2"> <div class="mt-2">
<p class="text-sm text-gray-500"> <p class="text-sm text-gray-500">
Você tem certeza que deseja excluir este cliente? Você tem certeza que deseja excluir este cliente?
Todos os seus dados serão removidos permanentemente. Todos os seus dados serão removidos permanentemente.
Esta ação não pode ser desfeita. Esta ação não pode ser desfeita.
</p> </p>
</div> </div>
@ -53,17 +60,24 @@ class="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-
<!-- Botões (usando a estrutura do 'create-user') --> <!-- Botões (usando a estrutura do 'create-user') -->
<div class="form-footer mt-5 sm:mt-4 sm:flex sm:flex-row-reverse"> <div class="form-footer mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
<!-- <!--
O botão "Sim, Excluir" deve vir primeiro no HTML O botão "Sim, Excluir" deve vir primeiro no HTML
para o 'flex-row-reverse' funcionar. para o 'flex-row-reverse' funcionar.
--> -->
<button type="button" @click="$dispatch('confirm-delete', [clientId]); showQuestion = false" <button type="button"
class="btn-submit bg-red-600 hover:bg-red-700 focus:ring-red-500 w-full sm:w-auto"> {{--
Aqui, ele dispara o evento 'confirm-delete'
(que seu Livewire pode ouvir) e fecha o modal.
--}}
@click="$dispatch('confirm-delete'); showQuestion = false"
class="btn-submit bg-red-600 hover:bg-red-700 focus:ring-red-500 w-full sm:w-auto">
Sim, Excluir Sim, Excluir
</button> </button>
<button type="button" @click="showQuestion = false" class="btn-cancel mt-3 sm:mt-0 w-full sm:w-auto"> <button type="button"
@click="showQuestion = false"
class="btn-cancel mt-3 sm:mt-0 w-full sm:w-auto">
Cancelar Cancelar
</button> </button>
</div> </div>

View File

@ -5,7 +5,128 @@
<livewire:admin.create-user /> <livewire:admin.create-user />
<livewire:admin.add-client /> <livewire:admin.add-client />
<livewire:admin.show-users /> <livewire:admin.show-users />
<livewire:admin.delete-client />
<x-are-you-sure /> <x-are-you-sure />
<livewire:admin.show-client />
<div class="container grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
@foreach ($clients as $client)
<div class="client-card">
<div class="client-card-header">
<div class="client-avatar">
<img src="{{ Vite::asset('resources/images/mr-distribuidora.svg') }}" alt="Avatar do Cliente"
class="w-32 h-32 rounded-full object-cover">
</div>
<div x-data="{ open: false }" @click.outside="open = false" class="client-options-menu">
<button @click="open = !open" class="client-options-button">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400 hover:text-gray-700"
viewBox="0 0 20 20" fill="currentColor">
<path
d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
</svg>
</button>
<ul x-show="open" class="client-options-list" x-transition>
<li><a href="#" class="client-option-item">Ver Detalhes</a></li>
<li><a href="#" class="client-option-item">Editar Cliente</a></li>
<li>
<a href="#" class="client-option-item text-red-600" x-on:click.prevent="$dispatch('sure')">
Excluir Cliente
</a>
</li>
</ul>
</div>
</div>
<div class="client-card-name">
{{ $client->name }}
</div>
</div>
@endforeach
<div class="client-card">
<div class="client-card-header">
<div class="client-avatar">
<img src="{{ Vite::asset('resources/images/maissaude.svg') }}" alt="Avatar do Cliente"
class="w-32 h-32 rounded-full object-cover">
</div>
<div x-data="{ open: false }" @click.outside="open = false" class="client-options-menu">
<button @click="open = !open" class="client-options-button">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400 hover:text-gray-700"
viewBox="0 0 20 20" fill="currentColor">
<path
d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
</svg>
</button>
<ul x-show="open" class="client-options-list" x-transition>
<li><a href="#" class="client-option-item">Ver Detalhes</a></li>
<li><a href="#" class="client-option-item">Editar Cliente</a></li>
<li><a href="#" class="client-option-item text-red-600">Excluir Cliente</a></li>
</ul>
</div>
</div>
<div class="client-card-name">
Cliente 2
</div>
</div>
<div class="client-card">
<div class="client-card-header">
<div class="client-avatar">
<img src="{{ Vite::asset('resources/images/logo.png') }}" alt="Avatar do Cliente"
class="w-32 h-32 rounded-full object-cover">
</div>
<div x-data="{ open: false }" @click.outside="open = false" class="client-options-menu">
<button @click="open = !open" class="client-options-button">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400 hover:text-gray-700"
viewBox="0 0 20 20" fill="currentColor">
<path
d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
</svg>
</button>
<ul x-show="open" class="client-options-list" x-transition>
<li><a href="#" class="client-option-item">Ver Detalhes</a></li>
<li><a href="#" class="client-option-item">Editar Cliente</a></li>
<li><a href="#" class="client-option-item text-red-600">Excluir Cliente</a></li>
</ul>
</div>
</div>
<div class="client-card-name">
Cliente 3
</div>
</div>
<div class="client-card">
<div class="client-card-header">
<div class="client-avatar">
<img src="{{ Vite::asset('resources/images/logo.png') }}" alt="Avatar do Cliente"
class="w-32 h-32 rounded-full object-cover">
</div>
<div x-data="{ open: false }" @click.outside="open = false" class="client-options-menu">
<button @click="open = !open" class="client-options-button">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400 hover:text-gray-700"
viewBox="0 0 20 20" fill="currentColor">
<path
d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
</svg>
</button>
<ul x-show="open" class="client-options-list" x-transition>
<li><a href="#" class="client-option-item">Ver Detalhes</a></li>
<li><a href="#" class="client-option-item">Editar Cliente</a></li>
<li><a href="#" class="client-option-item text-red-600">Excluir Cliente</a></li>
</ul>
</div>
</div>
<div class="client-card-name">
Cliente 4
</div>
</div>
</div>
@endsection @endsection

View File

@ -1,38 +0,0 @@
<div class="container grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
@foreach ($clients as $client)
<div class="client-card">
<div class="client-card-header">
<div class="client-avatar">
<img src="{{ Vite::asset('resources/images/mr-distribuidora.svg') }}" alt="Avatar do Cliente"
class="w-32 h-32 rounded-full object-cover">
</div>
<div x-data="{ open: false }" @click.outside="open = false" class="client-options-menu">
<button @click="open = !open" class="client-options-button">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-400 hover:text-gray-700"
viewBox="0 0 20 20" fill="currentColor">
<path
d="M10 6a2 2 0 110-4 2 2 0 010 4zM10 12a2 2 0 110-4 2 2 0 010 4zM10 18a2 2 0 110-4 2 2 0 010 4z" />
</svg>
</button>
<ul x-show="open" class="client-options-list" x-transition>
<li><a href="#" class="client-option-item">Ver Detalhes</a></li>
<li><a href="#" class="client-option-item">Editar Cliente</a></li>
<li>
<a href="#" class="client-option-item text-red-600"
x-on:click.prevent="$dispatch('sure', { id: '{{ $client->id }}' })">
Excluir Cliente
</a>
</li>
</ul>
</div>
</div>
<div class="client-card-name">
{{ $client->name }}
</div>
</div>
@endforeach
</div>