refactor: update schedule filtering logic, adjust client page title, and reformat client index view components.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
@section('title', 'Clients')
|
@section('title', 'Clients')
|
||||||
@section('page-title', 'Clients / CRM 👥')
|
@section('page-title', 'Clients👥')
|
||||||
@section('page-subtitle', 'Manage your brand partners and contacts')
|
@section('page-subtitle', 'Manage your brand partners and contacts')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
@@ -22,7 +22,8 @@
|
|||||||
<button @click="open = !open"
|
<button @click="open = !open"
|
||||||
class="flex items-center gap-1.5 text-xs px-3 py-2 rounded-full border transition-colors"
|
class="flex items-center gap-1.5 text-xs px-3 py-2 rounded-full border transition-colors"
|
||||||
:class="open ? 'border-pink-300 bg-pink-50 text-pink-600' : 'border-gray-200 text-gray-500 hover:bg-gray-50'">
|
:class="open ? 'border-pink-300 bg-pink-50 text-pink-600' : 'border-gray-200 text-gray-500 hover:bg-gray-50'">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor" stroke-width="2">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3 4h18M7 10h10M11 16h2" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M3 4h18M7 10h10M11 16h2" />
|
||||||
</svg>
|
</svg>
|
||||||
Filter
|
Filter
|
||||||
@@ -39,23 +40,21 @@
|
|||||||
<div class="flex flex-col sm:flex-row sm:items-center gap-2">
|
<div class="flex flex-col sm:flex-row sm:items-center gap-2">
|
||||||
{{-- Search (fills remaining space on desktop) --}}
|
{{-- Search (fills remaining space on desktop) --}}
|
||||||
<div class="relative flex-1 min-w-0">
|
<div class="relative flex-1 min-w-0">
|
||||||
<span class="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 text-sm pointer-events-none">🔍</span>
|
<span
|
||||||
|
class="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 text-sm pointer-events-none">🔍</span>
|
||||||
<input type="text" placeholder="Filter by name…" class="input-soft pl-9 text-sm py-2 w-full"
|
<input type="text" placeholder="Filter by name…" class="input-soft pl-9 text-sm py-2 w-full"
|
||||||
oninput="filterClients(this.value)" id="search-input">
|
oninput="filterClients(this.value)" id="search-input">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{-- Category dropdown --}}
|
{{-- Category dropdown --}}
|
||||||
<select name="category" class="input-soft text-sm py-2 sm:w-48 shrink-0"
|
<select name="category" class="input-soft text-sm py-2 sm:w-48 shrink-0" onchange="this.form.submit()">
|
||||||
onchange="this.form.submit()">
|
|
||||||
<option value="">All Categories</option>
|
<option value="">All Categories</option>
|
||||||
@foreach($categories as $parent)
|
@foreach($categories as $parent)
|
||||||
<option value="{{ $parent->id }}"
|
<option value="{{ $parent->id }}" {{ request('category') == $parent->id ? 'selected' : '' }}>
|
||||||
{{ request('category') == $parent->id ? 'selected' : '' }}>
|
|
||||||
{{ $parent->icon }} {{ $parent->name }}
|
{{ $parent->icon }} {{ $parent->name }}
|
||||||
</option>
|
</option>
|
||||||
@foreach($parent->children as $child)
|
@foreach($parent->children as $child)
|
||||||
<option value="{{ $child->id }}"
|
<option value="{{ $child->id }}" {{ request('category') == $child->id ? 'selected' : '' }}>
|
||||||
{{ request('category') == $child->id ? 'selected' : '' }}>
|
|
||||||
↳ {{ $child->name }}
|
↳ {{ $child->name }}
|
||||||
</option>
|
</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
@@ -63,8 +62,7 @@
|
|||||||
</select>
|
</select>
|
||||||
|
|
||||||
{{-- Status dropdown --}}
|
{{-- Status dropdown --}}
|
||||||
<select name="status" class="input-soft text-sm py-2 sm:w-36 shrink-0"
|
<select name="status" class="input-soft text-sm py-2 sm:w-36 shrink-0" onchange="this.form.submit()">
|
||||||
onchange="this.form.submit()">
|
|
||||||
<option value="">All Statuses</option>
|
<option value="">All Statuses</option>
|
||||||
@foreach($statuses as $s)
|
@foreach($statuses as $s)
|
||||||
<option value="{{ $s->value }}" {{ request('status') === $s->value ? 'selected' : '' }}>
|
<option value="{{ $s->value }}" {{ request('status') === $s->value ? 'selected' : '' }}>
|
||||||
@@ -87,8 +85,7 @@
|
|||||||
<div class="flex items-start gap-3">
|
<div class="flex items-start gap-3">
|
||||||
@if($client->avatar)
|
@if($client->avatar)
|
||||||
<div class="w-11 h-11 rounded-2xl overflow-hidden shrink-0 shadow-sm ring-2 ring-pink-100">
|
<div class="w-11 h-11 rounded-2xl overflow-hidden shrink-0 shadow-sm ring-2 ring-pink-100">
|
||||||
<img src="{{ \Illuminate\Support\Facades\Storage::url($client->avatar) }}"
|
<img src="{{ \Illuminate\Support\Facades\Storage::url($client->avatar) }}" alt="{{ $client->name }}"
|
||||||
alt="{{ $client->name }}"
|
|
||||||
class="w-full h-full object-cover">
|
class="w-full h-full object-cover">
|
||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
@@ -108,7 +105,8 @@
|
|||||||
<div class="text-xs text-gray-400 truncate">{{ $client->company }}</div>
|
<div class="text-xs text-gray-400 truncate">{{ $client->company }}</div>
|
||||||
@endif
|
@endif
|
||||||
@if($client->category)
|
@if($client->category)
|
||||||
<div class="text-xs mt-0.5" style="color: {{ $client->category->color === '#FDFD96' ? '#8B8000' : $client->category->color }}">
|
<div class="text-xs mt-0.5"
|
||||||
|
style="color: {{ $client->category->color === '#FDFD96' ? '#8B8000' : $client->category->color }}">
|
||||||
{{ $client->category->icon }} {{ $client->category->name }}
|
{{ $client->category->icon }} {{ $client->category->name }}
|
||||||
@if($client->category->parent)
|
@if($client->category->parent)
|
||||||
<span class="text-gray-300 mx-0.5">·</span>
|
<span class="text-gray-300 mx-0.5">·</span>
|
||||||
@@ -124,10 +122,12 @@
|
|||||||
<span class="text-xs bg-pink-50 text-pink-600 px-2 py-0.5 rounded-full">📸 {{ $client->ig_handle }}</span>
|
<span class="text-xs bg-pink-50 text-pink-600 px-2 py-0.5 rounded-full">📸 {{ $client->ig_handle }}</span>
|
||||||
@endif
|
@endif
|
||||||
@if($client->tiktok_handle)
|
@if($client->tiktok_handle)
|
||||||
<span class="text-xs bg-purple-50 text-purple-600 px-2 py-0.5 rounded-full">🎵 {{ $client->tiktok_handle }}</span>
|
<span class="text-xs bg-purple-50 text-purple-600 px-2 py-0.5 rounded-full">🎵
|
||||||
|
{{ $client->tiktok_handle }}</span>
|
||||||
@endif
|
@endif
|
||||||
@if($client->youtube_handle)
|
@if($client->youtube_handle)
|
||||||
<span class="text-xs bg-red-50 text-red-600 px-2 py-0.5 rounded-full">▶️ {{ $client->youtube_handle }}</span>
|
<span class="text-xs bg-red-50 text-red-600 px-2 py-0.5 rounded-full">▶️
|
||||||
|
{{ $client->youtube_handle }}</span>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -139,8 +139,10 @@
|
|||||||
|
|
||||||
@if($client->email || $client->city)
|
@if($client->email || $client->city)
|
||||||
<div class="text-xs text-gray-400 space-y-0.5">
|
<div class="text-xs text-gray-400 space-y-0.5">
|
||||||
@if($client->email) <div class="truncate">✉️ {{ $client->email }}</div> @endif
|
@if($client->email)
|
||||||
@if($client->city) <div>📍 {{ $client->city }}{{ $client->country ? ', '.$client->country : '' }}</div> @endif
|
<div class="truncate">✉️ {{ $client->email }}</div> @endif
|
||||||
|
@if($client->city)
|
||||||
|
<div>📍 {{ $client->city }}{{ $client->country ? ', ' . $client->country : '' }}</div> @endif
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@
|
|||||||
|
|
||||||
<a href="{{ route('clients.index') }}" @click="sidebarOpen = false"
|
<a href="{{ route('clients.index') }}" @click="sidebarOpen = false"
|
||||||
class="nav-item {{ request()->routeIs('clients.*') ? 'active' : '' }}">
|
class="nav-item {{ request()->routeIs('clients.*') ? 'active' : '' }}">
|
||||||
<span class="text-lg shrink-0">👥</span> Clients / CRM
|
<span class="text-lg shrink-0">👥</span> Clients
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="{{ route('client-categories.index') }}" @click="sidebarOpen = false"
|
<a href="{{ route('client-categories.index') }}" @click="sidebarOpen = false"
|
||||||
|
|||||||
@@ -13,11 +13,17 @@
|
|||||||
|
|
||||||
{{-- ── Upcoming Alert Strip ─────────────────────────────────── --}}
|
{{-- ── Upcoming Alert Strip ─────────────────────────────────── --}}
|
||||||
@php
|
@php
|
||||||
$upcomingList = $events->filter(fn($e) => $e->start_time->isFuture() && $e->start_time->diffInHours(now()) <= 24);
|
$startOfMonth = now()->startOfMonth();
|
||||||
|
$endOfMonth = now()->endOfMonth();
|
||||||
|
$upcomingList = $events->filter(function($e) use ($startOfMonth, $endOfMonth) {
|
||||||
|
$start = $e->start_time;
|
||||||
|
$end = $e->end_time ?: $e->start_time;
|
||||||
|
return $start->lte($endOfMonth) && $end->gte($startOfMonth);
|
||||||
|
});
|
||||||
@endphp
|
@endphp
|
||||||
@if($upcomingList->isNotEmpty())
|
@if($upcomingList->isNotEmpty())
|
||||||
<div class="flex gap-2 overflow-x-auto pb-2 mb-4 -mx-4 px-4 lg:mx-0 lg:px-0">
|
<div class="flex gap-2 overflow-x-auto pb-2 mb-4 -mx-4 px-4 lg:mx-0 lg:px-0">
|
||||||
@foreach($upcomingList->take(6) as $event)
|
@foreach($upcomingList as $event)
|
||||||
<div class="shrink-0 flex items-center gap-2 bg-white rounded-2xl border border-pink-100 px-3 py-2 shadow-sm cursor-pointer hover:border-pink-300 transition-colors"
|
<div class="shrink-0 flex items-center gap-2 bg-white rounded-2xl border border-pink-100 px-3 py-2 shadow-sm cursor-pointer hover:border-pink-300 transition-colors"
|
||||||
onclick="openAlertEventModal({{ json_encode(['id' => $event->id, 'title' => $event->title, 'type' => $event->event_type, 'status' => $event->status->value, 'client' => $event->client?->name, 'start' => $event->start_time->format('d M Y H:i'), 'end' => $event->end_time?->format('d M Y H:i'), 'location' => $event->location, 'description' => $event->description, 'notes' => $event->notes, 'has_contract' => $event->has_contract, 'has_content' => $event->has_content]) }})">
|
onclick="openAlertEventModal({{ json_encode(['id' => $event->id, 'title' => $event->title, 'type' => $event->event_type, 'status' => $event->status->value, 'client' => $event->client?->name, 'start' => $event->start_time->format('d M Y H:i'), 'end' => $event->end_time?->format('d M Y H:i'), 'location' => $event->location, 'description' => $event->description, 'notes' => $event->notes, 'has_contract' => $event->has_contract, 'has_content' => $event->has_content]) }})">
|
||||||
<div class="w-1.5 h-8 rounded-full shrink-0" style="background:{{ $event->color }}"></div>
|
<div class="w-1.5 h-8 rounded-full shrink-0" style="background:{{ $event->color }}"></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user