sackey e3b2b220d2
Some checks are pending
linter / quality (push) Waiting to run
tests / ci (push) Waiting to run
Enhance UI and functionality across various components
- Increased icon sizes in service items, service orders, users, and technician management for better visibility.
- Added custom loading indicators with appropriate icons in search fields for vehicles, work orders, and technicians.
- Introduced invoice management routes for better organization and access control.
- Created a new test for the estimate PDF functionality to ensure proper rendering and data integrity.
2025-08-16 14:36:58 +00:00

218 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="space-y-6">
<!-- Enhanced Header -->
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4">
<div>
<h1 class="text-3xl font-bold text-zinc-900 dark:text-white dark:text-white">Suppliers</h1>
<p class="mt-2 text-lg text-zinc-600 dark:text-zinc-400 dark:text-gray-300">
Manage {{ number_format($suppliers->total()) }} supplier relationships
</p>
</div>
<div class="flex flex-col sm:flex-row gap-3">
<flux:button wire:navigate href="{{ route('inventory.purchase-orders.create') }}" variant="outline" icon="shopping-cart" size="sm">
New Purchase Order
</flux:button>
<flux:button wire:navigate href="{{ route('inventory.suppliers.create') }}" variant="primary" icon="plus" size="sm">
Add Supplier
</flux:button>
</div>
</div>
<!-- Enhanced Filters -->
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700 border border-zinc-200 dark:border-zinc-700">
<div class="p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-semibold text-zinc-900 dark:text-white dark:text-white">Filter & Search</h3>
<flux:button wire:click="clearFilters" variant="outline" size="xs">
Clear All
</flux:button>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<!-- Enhanced Search -->
<div>
<flux:field>
<flux:label>Search Suppliers</flux:label>
<flux:input
wire:model.live.debounce.300ms="search"
placeholder="Name, email, or phone..."
icon="magnifying-glass"
/>
</flux:field>
</div>
<!-- Status Filter -->
<div>
<flux:field>
<flux:label>Status</flux:label>
<flux:select wire:model.live="statusFilter">
<option value="">All Suppliers</option>
<option value="1"> Active</option>
<option value="0"> Inactive</option>
</flux:select>
</flux:field>
</div>
<!-- Sort Options -->
<div>
<flux:field>
<flux:label>Sort By</flux:label>
<flux:select wire:model.live="sortBy">
<option value="name">Name A-Z</option>
<option value="created_at">Date Added</option>
<option value="contact_email">Email</option>
</flux:select>
</flux:field>
</div>
</div>
<!-- Active Filters Display -->
<div class="mt-4 flex flex-wrap gap-2">
@if($search)
<span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200">
Search: "{{ $search }}"
<button wire:click="$set('search', '')" class="ml-2 text-blue-600 hover:text-blue-800">×</button>
</span>
@endif
@if($statusFilter !== '')
<span class="inline-flex items-center px-3 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200">
Status: {{ $statusFilter ? 'Active' : 'Inactive' }}
<button wire:click="$set('statusFilter', '')" class="ml-2 text-green-600 hover:text-green-800">×</button>
</span>
@endif
</div>
</div>
</div>
<!-- Results Summary -->
<div class="flex items-center justify-between text-sm text-zinc-600 dark:text-zinc-400 dark:text-gray-400">
<div>
Showing {{ $suppliers->firstItem() ?? 0 }} to {{ $suppliers->lastItem() ?? 0 }} of {{ number_format($suppliers->total()) }} suppliers
</div>
<div class="flex items-center space-x-2">
<span>Per page:</span>
<flux:select wire:model.live="perPage" class="w-20">
<option value="10">10</option>
<option value="25">25</option>
<option value="50">50</option>
</flux:select>
</div>
</div>
<!-- Suppliers Table -->
<div class="bg-white dark:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700 overflow-hidden">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-zinc-200 dark:divide-zinc-700">
<thead class="bg-zinc-50 dark:bg-zinc-900">
<tr>
<th wire:click="sortBy('name')" class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-zinc-100 dark:hover:bg-zinc-800">
<div class="flex items-center space-x-1">
<span>Name</span>
@if($sortBy === 'name')
<flux:icon.chevron-up class="w-6 h-6 {{ $sortDirection === 'asc' ? '' : 'rotate-180' }}" />
@endif
</div>
</th>
<th wire:click="sortBy('company_name')" class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 dark:text-gray-400 uppercase tracking-wider cursor-pointer hover:bg-zinc-100 dark:hover:bg-zinc-800">
<div class="flex items-center space-x-1">
<span>Company</span>
@if($sortBy === 'company_name')
<flux:icon.chevron-up class="w-6 h-6 {{ $sortDirection === 'asc' ? '' : 'rotate-180' }}" />
@endif
</div>
</th>
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 dark:text-gray-400 uppercase tracking-wider">Contact</th>
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 dark:text-gray-400 uppercase tracking-wider">Parts</th>
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 dark:text-gray-400 uppercase tracking-wider">Rating</th>
<th class="px-6 py-3 text-left text-xs font-medium text-zinc-500 dark:text-zinc-400 dark:text-gray-400 uppercase tracking-wider">Status</th>
<th class="px-6 py-3 text-right text-xs font-medium text-zinc-500 dark:text-zinc-400 dark:text-gray-400 uppercase tracking-wider">Actions</th>
</tr>
</thead>
<tbody class="bg-white dark:bg-zinc-800 divide-y divide-zinc-200 dark:divide-zinc-700">
@forelse($suppliers as $supplier)
<tr class="hover:bg-zinc-50 dark:hover:bg-zinc-700">
<td class="px-6 py-4 whitespace-nowrap">
<div>
<div class="text-sm font-medium text-zinc-900 dark:text-white dark:text-white">{{ $supplier->name }}</div>
@if($supplier->contact_person && $supplier->contact_person !== $supplier->name)
<div class="text-sm text-zinc-500 dark:text-zinc-400 dark:text-gray-400">Contact: {{ $supplier->contact_person }}</div>
@endif
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-zinc-900 dark:text-white dark:text-white">
{{ $supplier->company_name ?: 'N/A' }}
</div>
@if($supplier->city && $supplier->state)
<div class="text-sm text-zinc-500 dark:text-zinc-400 dark:text-gray-400">
{{ $supplier->city }}, {{ $supplier->state }}
</div>
@endif
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-zinc-900 dark:text-white dark:text-white">
@if($supplier->email)
<div>{{ $supplier->email }}</div>
@endif
@if($supplier->phone)
<div>{{ $supplier->phone }}</div>
@endif
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-900 dark:text-white dark:text-white">
<flux:badge size="sm" color="blue">{{ $supplier->parts_count }} parts</flux:badge>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-zinc-900 dark:text-white dark:text-white">
@if($supplier->rating)
<div class="flex items-center">
<div class="flex items-center">
@for($i = 1; $i <= 5; $i++)
@if($i <= $supplier->rating)
<flux:icon.star class="w-6 h-6 text-yellow-400" />
@else
<flux:icon.star class="w-6 h-6 text-gray-300 dark:text-zinc-600 dark:text-zinc-400" />
@endif
@endfor
</div>
<span class="ml-1 text-sm">{{ number_format($supplier->rating, 1) }}</span>
</div>
@else
<span class="text-gray-400">No rating</span>
@endif
</td>
<td class="px-6 py-4 whitespace-nowrap">
@if($supplier->is_active)
<flux:badge size="sm" color="green">Active</flux:badge>
@else
<flux:badge size="sm" color="red">Inactive</flux:badge>
@endif
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium space-x-2">
<flux:button wire:navigate href="{{ route('inventory.suppliers.edit', $supplier) }}" size="sm" variant="subtle">
Edit
</flux:button>
</td>
</tr>
@empty
<tr>
<td colspan="7" class="px-6 py-12 text-center">
<div class="text-zinc-500 dark:text-zinc-400 dark:text-gray-400">
<flux:icon.building-office class="mx-auto h-12 w-12 mb-4 opacity-40" />
<p class="text-lg font-medium">No suppliers found</p>
<p class="text-sm">Get started by adding your first supplier.</p>
</div>
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
<!-- Pagination -->
@if($suppliers->hasPages())
<div class="bg-zinc-50 dark:bg-zinc-900 px-6 py-3 border-t border-zinc-200 dark:border-zinc-700">
{{ $suppliers->links() }}
</div>
@endif
</div>
</div>