Initial commit

This commit is contained in:
Ronald Huynen
2026-03-23 21:37:59 +01:00
commit 2547717edb
2193 changed files with 972171 additions and 0 deletions

View File

@@ -0,0 +1,233 @@
<div class="my-4">
<!-- Search/Filter Section -->
<form wire:submit.prevent="applySearch" class="mb-6">
<div class="flex flex-col md:flex-row md:space-x-12">
<div class="w-full md:w-2/4 md:flex-none space-y-4">
<div>
<x-jetstream.label for="search" value="{{ __('Keywords') }}" />
<x-jetstream.input :clearable="true" class="text-theme-primary placeholder-theme-light text-sm"
placeholder="{{ __('Search by name or location') }}" right-icon="search"
wire:model="searchInput" />
@error('search')
<div class="mb-3 text-sm text-red-700" role="alert">
{{ __($message) }}
</div>
@enderror
</div>
<div>
<x-jetstream.label for="filterType" value="{{ __('Select by interaction') }}" />
<x-select wire:model="filterTypeInput" multiselect placeholder="{{ __('All interactions') }}">
<x-select.option label="{{ __('Stars') }}" value="stars" />
<x-select.option label="{{ __('Bookmarks') }}" value="bookmarks" />
<x-select.option label="{{ __('Transactions') }}" value="transactions" />
<x-select.option label="{{ __('Conversations') }}" value="conversations" />
</x-select>
</div>
</div>
</div>
<div class="mt-6 mb-6 md:mb-12 lg:mb-18">
<x-jetstream.secondary-button class="my-3" type="submit" wire:loading.attr="disabled" wire:target="applySearch">
<span wire:loading.remove wire:target="applySearch">{{ __('Search') }}</span>
<span wire:loading wire:target="applySearch">{{ __('Searching...') }}</span>
</x-jetstream.secondary-button>
<x-jetstream.secondary-button class="my-3 ml-4" wire:click.prevent="resetSearch" wire:loading.attr="disabled" wire:target="resetSearch">
{{ __('Clear all') }}
</x-jetstream.secondary-button>
</div>
</form>
<!-- General error section -->
@if (session('error'))
<div class="relative mt-6 rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700" role="alert">
<strong class="font-bold">{{ __('Error') }}!</strong>
<span class="block sm:inline">{{ session('error') }}</span>
</div>
@endif
<!-- Results table -->
<div class="relative mb-6 mt-6">
<div wire:loading>
<span> {{ __('Loading...') }} </span>
</div>
</div>
<div class="bg-white shadow-sm rounded-lg overflow-hidden">
<table class="min-w-full divide-y divide-gray-200" id="contacts">
<thead class="bg-gray-50">
<tr>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 tracking-wider align-middle">
<button wire:click="sortBy('name')" class="uppercase flex items-center hover:text-gray-700 focus:outline-none">
{{ __('Contact') }}
@if($sortField === 'name')
<x-icon class="ml-1 h-4 w-4" name="{{ $sortAsc ? 'chevron-up' : 'chevron-down' }}" />
@endif
</button>
</th>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 tracking-wider align-middle">
<button wire:click="sortBy('has_star')" class="uppercase flex items-center hover:text-gray-700 focus:outline-none">
{{ __('Saved') }}
@if($sortField === 'has_star')
<x-icon class="ml-1 h-4 w-4" name="{{ $sortAsc ? 'chevron-up' : 'chevron-down' }}" />
@endif
</button>
</th>
<th class="px-3 py-3 text-left text-xs font-medium text-gray-500 tracking-wider align-middle hidden md:table-cell">
<button wire:click="sortBy('transaction_count')" class="uppercase flex items-center hover:text-gray-700 focus:outline-none">
{{ __('Exchanges') }}
@if($sortField === 'transaction_count')
<x-icon class="ml-1 h-4 w-4" name="{{ $sortAsc ? 'chevron-up' : 'chevron-down' }}" />
@endif
</button>
</th>
<th class="px-3 py-3 text-right text-xs font-medium text-gray-500 tracking-wider align-middle hidden xl:table-cell">
<button wire:click="sortBy('last_interaction')" class="uppercase flex items-center justify-end ml-auto hover:text-gray-700 focus:outline-none">
{{ __('Last interaction') }}
@if($sortField === 'last_interaction')
<x-icon class="ml-1 h-4 w-4" name="{{ $sortAsc ? 'chevron-up' : 'chevron-down' }}" />
@endif
</button>
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@if ($contacts && $contacts->count() > 0)
@foreach ($contacts as $contact)
<tr onclick="window.location='{{ url($contact['profile_path']) }}'"
class="cursor-pointer hover:bg-gray-50">
<td class="px-3 py-4 text-sm">
<div class="flex items-center">
<div class="flex-shrink-0">
<img alt="profile"
class="h-10 w-10 md:h-12 md:w-12 lg:h-16 lg:w-16 rounded-full profile-photo object-cover outline outline-1 outline-offset-0 outline-gray-600"
src="{{ Storage::url($contact['profile_photo']) }}" />
</div>
<div class="ml-3 min-w-0 flex-1">
<div class="text-sm font-medium text-gray-900 truncate">
{{ $contact['name'] }}
</div>
@if ($contact['full_name'] != $contact['name'])
<div class="text-xs text-gray-500 font-normal truncate">
{{ $contact['full_name'] }}
</div>
@endif
<div class="text-xs text-gray-500 font-normal truncate">
{{ $contact['location'] }}
</div>
@if($contact['profile_type_name'] === 'Organization')
<div class="text-xs font-normal mt-1">
<span class="bg-theme-brand px-1 text-gray-100">
{{ __('Organization') }}
</span>
</div>
@elseif($contact['profile_type_name'] === 'Bank')
<div class="text-xs font-normal mt-1">
<span class="bg-theme-brand px-1 text-gray-100">
{{ __('Bank') }}
</span>
</div>
@elseif($contact['profile_type_name'] === 'Admin')
<div class="text-xs font-normal mt-1">
<span class="bg-theme-brand px-1 text-gray-100">
{{ __('Admin') }}
</span>
</div>
@endif
</div>
</div>
</td>
<td class="px-3 py-4 text-sm text-gray-500">
<div class="flex justify-start items-center space-x-2">
@if ($contact['has_star'])
<x-icon class="h-5 w-5 text-yellow-500" name="star" solid
title="{{ __('Has stars') }}" />
@endif
@if ($contact['has_bookmark'])
<x-icon class="h-5 w-5 text-yellow-500" name="bookmark" solid
title="{{ __('Has bookmarks') }}" />
@endif
@if (!$contact['has_star'] && !$contact['has_bookmark'])
<span class="text-gray-300"></span>
@endif
</div>
</td>
<td class="px-3 py-4 text-sm text-gray-500 hidden md:table-cell">
<div class="flex justify-start items-center space-x-3 text-xs">
@if ($contact['transaction_count'] > 0)
<span class="text-theme-primary font-medium">
<x-icon class="h-4 w-4 inline text-theme-primary" name="clock" />
{{ $contact['transaction_count'] }}
</span>
@endif
@if ($contact['message_count'] > 0)
<span class="text-theme-primary font-medium">
<x-icon class="h-4 w-4 inline text-theme-primary" name="chat-bubble-left-right" />
{{ $contact['message_count'] }}
</span>
@endif
</div>
</td>
<td class="px-3 py-4 whitespace-nowrap text-right text-sm text-gray-500 hidden xl:table-cell">
<div class="leading-tight">
<div>{{ \Carbon\Carbon::parse($contact['last_interaction'])->translatedFormat('d M') }}</div>
<div>{{ \Carbon\Carbon::parse($contact['last_interaction'])->translatedFormat('Y') }}</div>
</div>
</td>
</tr>
@endforeach
@else
<tr>
<td colspan="4" class="px-6 py-12 text-center text-gray-500">
<span wire:loading>
{{ __('One moment, collecting all your contacts...') }}
</span>
<span wire:loading.remove>
{{ __('No contacts found') }}
</span>
</td>
</tr>
@endif
</tbody>
</table>
<!-- Pagination -->
@if($contacts && $contacts->hasPages())
<div class="px-6 py-3 border-t border-gray-200">
{{ $contacts->links('livewire.long-paginator') }}
</div>
@endif
</div>
<!-- Results count and per-page selector -->
@if ($contacts && $contacts->total() > 0)
<div class="mt-4 flex items-center justify-between">
<div class="flex items-center">
<select class="w-20 rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-primary-500 focus:outline-none focus:ring focus:ring-primary-500 sm:text-sm"
wire:model.live="perPage">
<option value="15">15</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
<span class="ml-2 text-sm text-gray-500">{{ __('per page') }}</span>
</div>
<div class="text-sm text-gray-500">
{{ trans_choice('messages.contacts_found', $contacts->total(), ['count' => $contacts->total()]) }}
</div>
</div>
@endif
@push('scripts')
{{-- Scroll to top when clicking paginator --}}
<script>
document.addEventListener('scroll-to-top', event => {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
</script>
@endpush
</div>