Compare commits

..

2 Commits

Author SHA1 Message Date
lukidev 938e7a9f6d
fix|feat|improve: Exibição dos detalhes de cliente | Paginação adicio…
fix|feat|improve: Exibição dos detalhes de cliente | Paginação adicio…
2025-12-11 12:37:04 -03:00
LukiBeg 048bcd47ec fix|feat|improve: Exibição dos detalhes de cliente | Paginação adicionada | Filtro aprimorado. 2025-12-11 12:36:27 -03:00
6 changed files with 137 additions and 20 deletions

View File

@ -12,7 +12,7 @@ class DetailClient extends Component
{ {
public ClientForm $clientForm; public ClientForm $clientForm;
public ?Client $client = null; public Client $client;
#[On('client-detail')] #[On('client-detail')]
public function detailClient($id) public function detailClient($id)

View File

@ -5,22 +5,18 @@
use App\Models\Client; use App\Models\Client;
use Livewire\Component; use Livewire\Component;
use Livewire\Attributes\On; use Livewire\Attributes\On;
use Livewire\WithPagination;
class ShowClient extends Component class ShowClient extends Component
{ {
use WithPagination;
public $filters = ''; public $filters = '';
public $clients;
public function mount()
{
$this->clients = Client::all();
}
#[On('filters-added')] #[On('filters-added')]
public function updatedFilters() public function updatedFilters()
{ {
$this->clients = Client::where('name', 'LIKE', '%' . $this->filters . '%')->get(); $this->resetPage();
} }
#[On('client-deleted')] #[On('client-deleted')]
@ -28,13 +24,24 @@ public function updatedFilters()
#[On('client-added')] #[On('client-added')]
public function refreshClients() public function refreshClients()
{ {
$this->clients = Client::all(); $this->resetPage();
} }
public function render() public function render()
{ {
$query = Client::query();
if (!empty($this->filters)) {
$query->where(function ($q) {
$q->where('name', 'LIKE', '%' . $this->filters . '%')
->orWhere('legal_name', 'LIKE', '%' . $this->filters . '%')
->orWhere('cnpj', 'LIKE', '%' . $this->filters . '%');
});
}
return view('livewire.admin.show-client', [ return view('livewire.admin.show-client', [
'clients' => $this->clients // Adicionando withView() para garantir que a template correta seja usada
'clients' => $query->paginate(10),
]); ]);
} }
} }

View File

@ -2,12 +2,8 @@
@keydown.escape.window="showClientDetails = false" @keydown.escape.window="showClientDetails = false"
x-on:client-detail.window="showClientDetails = true" x-on:client-detail.window="showClientDetails = true"
class="relative z-50" class="relative z-50"
wire:ignore.self
> >
<div x-show="showClientDetails"
x-transition:enter="ease-out duration-300" x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-25"
x-transition:leave="ease-in duration-200" x-transition:leave-start="opacity-0" x-transition:leave-end="opacity-0"
class="fixed inset-0 bg-white/50 transition-opacity"
></div>
<div x-show="showClientDetails" <div x-show="showClientDetails"
x-transition:enter="transform transition ease-in-out duration-300 sm:duration-500" x-transition:enter-start="translate-x-full" x-transition:enter-end="translate-x-0" x-transition:enter="transform transition ease-in-out duration-300 sm:duration-500" x-transition:enter-start="translate-x-full" x-transition:enter-end="translate-x-0"
@ -37,7 +33,7 @@ class="rounded-md text-blue-400 hover:text-white cursor-pointer focus:outline-no
</div> </div>
@if($client) @if($client)
<div class="form-wrapper-modal"> <div class="form-wrapper-modal" wire:key="content-{{ $client->id }}">
<div class="form-grid-container"> <div class="form-grid-container">
<div class="form-main-panel-modal space-y-8"> <div class="form-group"> <div class="form-main-panel-modal space-y-8"> <div class="form-group">
@ -175,7 +171,7 @@ class="rounded-md text-blue-400 hover:text-white cursor-pointer focus:outline-no
</div> </div>
</div> </div>
@else @else
<div class="flex-1 flex items-center justify-center h-full"> <div class="flex-1 flex items-center justify-center h-full" wire:key="loading-state">
<div class="text-gray-500 flex flex-col items-center"> <div class="text-gray-500 flex flex-col items-center">
<svg class="animate-spin h-8 w-8 text-blue-600 mb-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg> <svg class="animate-spin h-8 w-8 text-blue-600 mb-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path></svg>
<span>Carregando...</span> <span>Carregando...</span>

View File

@ -41,8 +41,8 @@ class="text-gray-400 hover:text-gray-600 focus:outline-none">
@foreach ($clients as $client) @foreach ($clients as $client)
<div class="client-card" wire:key="{{ $client->id }}" wire:transition.scale.origin.top.duration.300ms> <div class="client-card" wire:key="{{ $client->id }}" wire:transition.scale.origin.top.duration.300ms>
<div class="client-card-header"> <div class="client-card-header">
<div class="client-avatar"> <div class="client-avatar" x-on:click.prevent="$dispatch('client-detail', { id: '{{ $client->id }}' })">
<img src="{{ asset('storage/' . $client->profile_image_path) }}" x-on:click.prevent="$dispatch('client-detail', { id: '{{ $client->id }}' })" alt="Avatar do Cliente" <img src="{{ asset('storage/' . $client->profile_image_path) }}" alt="Avatar do Cliente"
class="w-32 h-32 rounded-full object-cover cursor-pointer"> class="w-32 h-32 rounded-full object-cover cursor-pointer">
</div> </div>
<div x-data="{ open: false }" @click.outside="open = false" class="client-options-menu"> <div x-data="{ open: false }" @click.outside="open = false" class="client-options-menu">
@ -71,4 +71,9 @@ class="w-32 h-32 rounded-full object-cover cursor-pointer">
</div> </div>
@endforeach @endforeach
</div> </div>
<div class="mt-8">
{{ $clients->links() }}
</div>
</div> </div>

View File

@ -0,0 +1,109 @@
@if ($paginator->hasPages())
<nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" class="flex items-center justify-between mt-6">
<div class="flex justify-between flex-1 sm:hidden">
@if ($paginator->onFirstPage())
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-gray-700 border border-gray-600 cursor-default leading-5 rounded-md">
{!! __('pagination.previous') !!}
</span>
@else
<button wire:click="previousPage" type="button" rel="prev" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-white bg-blue-600 border border-blue-700 leading-5 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 active:bg-blue-800 transition ease-in-out duration-150">
{!! __('pagination.previous') !!}
</button>
@endif
@if ($paginator->hasMorePages())
<button wire:click="nextPage" type="button" rel="next" class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-white bg-blue-600 border border-blue-700 leading-5 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 active:bg-blue-800 transition ease-in-out duration-150">
{!! __('pagination.next') !!}
</button>
@else
<span class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-500 bg-gray-700 border border-gray-600 cursor-default leading-5 rounded-md">
{!! __('pagination.next') !!}
</span>
@endif
</div>
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
<div>
<p class="text-sm text-gray-600 leading-5">
{!! __('Mostrando') !!}
@if ($paginator->firstItem())
<span class="font-medium text-blue-600">{{ $paginator->firstItem() }}</span>
{!! __('a') !!}
<span class="font-medium text-blue-600">{{ $paginator->lastItem() }}</span>
@else
<span class="font-medium text-blue-600">{{ $paginator->count() }}</span>
@endif
{!! __('de') !!}
<span class="font-medium text-blue-600">{{ $paginator->total() }}</span>
{!! __('resultados') !!}
</p>
</div>
<div>
<span class="relative z-0 inline-flex rtl:flex-row-reverse shadow-lg rounded-md bg-white border border-gray-200 p-1">
{{-- Link da Página Anterior --}}
@if ($paginator->onFirstPage())
<span aria-disabled="true" aria-label="{{ __('pagination.previous') }}">
<span class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-400 bg-white border-r border-gray-200 cursor-default rounded-l-md leading-5" aria-hidden="true">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
</svg>
</span>
</span>
@else
<button wire:click="previousPage" type="button" rel="prev" class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-700 bg-white rounded-l-md leading-5 hover:bg-gray-100 focus:z-10 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 active:bg-gray-200 transition ease-in-out duration-150" aria-label="{{ __('pagination.previous') }}">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
</svg>
</button>
@endif
{{-- Elementos de Paginação --}}
@foreach ($elements as $element)
{{-- Separador "Três Pontos" --}}
@if (is_string($element))
<span aria-disabled="true">
<span class="relative inline-flex cursor-pointer items-center px-4 py-2 -ml-px text-sm font-medium text-gray-500 bg-white cursor-default leading-5 border-l border-r border-gray-200">{{ $element }}</span>
</span>
@endif
{{-- Array de Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<span aria-current="page" wire:key="page-span-{{ $page }}">
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-white bg-blue-400 border border-blue-400 cursor-pointer leading-5 shadow-inner rounded-md mx-1">{{ $page }}</span>
</span>
@else
<button wire:click="gotoPage({{ $page }})" type="button" wire:key="page-button-{{ $page }}"
class="relative inline-flex items-center cursor-pointer px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white leading-5 hover:bg-gray-100 focus:z-10 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 active:bg-gray-200 transition ease-in-out duration-150 mx-1 rounded-md">
{{ $page }}
</button>
@endif
@endforeach
@endif
@endforeach
{{-- Link da Próxima Página --}}
@if ($paginator->hasMorePages())
<button wire:click="nextPage" type="button" rel="next" class="relative inline-flex items-center px-2 py-2 cursor-pointer -ml-px text-sm font-medium text-gray-700 bg-white rounded-r-md leading-5 hover:bg-gray-100 focus:z-10 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 active:bg-gray-200 transition ease-in-out duration-150" aria-label="{{ __('pagination.next') }}">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
</svg>
</button>
@else
<span aria-disabled="true" aria-label="{{ __('pagination.next') }}">
<span class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-400 bg-white border-l border-gray-200 cursor-default rounded-r-md leading-5" aria-hidden="true">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
</svg>
</span>
</span>
@endif
</span>
</div>
</div>
</nav>
@endif

View File

@ -5,7 +5,7 @@ import tailwindcss from '@tailwindcss/vite';
export default defineConfig({ export default defineConfig({
plugins: [ plugins: [
laravel({ laravel({
input: ['resources/css/app.css', 'resources/js/app.js', 'resources/images/bg-primary.png', 'resources/images/logo.png', 'resources/images/favicon.png', 'resources/images/newlogo.png', 'resources/images/avatar-nexus.svg' ], input: ['resources/css/app.css', 'resources/js/app.js', 'resources/images/bg-primary.png', 'resources/images/logo.png', 'resources/images/favicon.png', 'resources/images/newlogo.png', 'resources/images/avatar-nexus.svg', ],
refresh: true, refresh: true,
}), }),
tailwindcss(), tailwindcss(),