Compare commits

..

No commits in common. "7f4a23d090e9bd4fde7e7282371c51fcd36e715f" and "4343ef1c443525156e235691c2130c8ec4f7d4af" 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>
@ -58,12 +65,19 @@ class="mx-auto flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-
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"
{{--
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"> 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>