Add customer contact inquiry system, automated receipt emails, admin communication inbox, and customer profile management

This commit is contained in:
2026-11-02 09:56:24 +01:00
parent 387241f971
commit 9fd39bd7d6
28 changed files with 2426 additions and 8 deletions
@@ -0,0 +1,239 @@
@extends('layouts.admin')
@section('title', 'Klantprofiel: ' . $customerName . ' | Jouwdriedee Beheer')
@section('content')
<div class="space-y-6 max-w-6xl mx-auto" x-data="{ tab: 'communications' }">
<!-- Header Section -->
<div class="flex flex-col sm:flex-row sm:items-center justify-between pb-6 border-b border-slate-200/80 gap-4">
<div>
<a href="{{ route('admin.customers.index') }}" class="text-xs text-slate-500 hover:text-slate-900 font-medium inline-flex items-center space-x-1 mb-1 transition">
<i data-lucide="arrow-left" class="w-3.5 h-3.5"></i>
<span>Terug naar Klantenoverzicht</span>
</a>
<div class="flex items-center space-x-2 mt-0.5">
<h1 class="text-2xl font-bold tracking-tight text-slate-900">{{ $customerName }}</h1>
@if($user)
<span class="px-2 py-0.5 rounded-full text-[10px] font-semibold bg-emerald-50 text-emerald-700 border border-emerald-200/60">
Geregistreerd account (#{{ $user->id }})
</span>
@else
<span class="px-2 py-0.5 rounded-full text-[10px] font-semibold bg-slate-100 text-slate-600 border border-slate-200/60">
Gastkoper
</span>
@endif
</div>
<p class="text-xs text-slate-500 mt-0.5">
{{ $email }} @if($customerPhone) &bull; {{ $customerPhone }} @endif
</p>
</div>
<div class="flex items-center space-x-2">
<a href="{{ route('admin.communications.index') }}" class="px-3.5 py-2 rounded-xl bg-white hover:bg-slate-50 text-slate-700 text-xs font-medium transition flex items-center space-x-1.5 border border-slate-200/80 shadow-2xs">
<i data-lucide="inbox" class="w-3.5 h-3.5 text-slate-400"></i>
<span>Alle Communicatie</span>
</a>
<a href="mailto:{{ $email }}" class="px-3.5 py-2 rounded-xl bg-slate-900 hover:bg-slate-800 text-white text-xs font-medium transition flex items-center space-x-1.5 shadow-xs">
<i data-lucide="mail" class="w-3.5 h-3.5 text-slate-400"></i>
<span>E-mail Sturen</span>
</a>
</div>
</div>
<!-- Quick Stats Cards -->
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4">
<div class="p-4 rounded-2xl bg-white border border-slate-200/80 shadow-2xs flex items-center justify-between">
<div>
<span class="text-[11px] font-semibold text-slate-400 uppercase tracking-wider block">Communicatie Dossier</span>
<span class="text-xl font-bold text-slate-900 mt-0.5 block">{{ $communications->count() }} vragen / berichten</span>
</div>
<div class="w-10 h-10 rounded-xl bg-indigo-50 text-indigo-600 flex items-center justify-center">
<i data-lucide="message-square" class="w-5 h-5"></i>
</div>
</div>
<div class="p-4 rounded-2xl bg-white border border-slate-200/80 shadow-2xs flex items-center justify-between">
<div>
<span class="text-[11px] font-semibold text-slate-400 uppercase tracking-wider block">Bestellingen</span>
<span class="text-xl font-bold text-slate-900 mt-0.5 block">{{ $orders->count() }} orders</span>
</div>
<div class="w-10 h-10 rounded-xl bg-sky-50 text-sky-600 flex items-center justify-center">
<i data-lucide="shopping-cart" class="w-5 h-5"></i>
</div>
</div>
<div class="p-4 rounded-2xl bg-white border border-slate-200/80 shadow-2xs flex items-center justify-between">
<div>
<span class="text-[11px] font-semibold text-slate-400 uppercase tracking-wider block">Totale Omzet</span>
<span class="text-xl font-bold text-slate-900 mt-0.5 block">&euro; {{ number_format($totalSpent, 2, ',', '.') }}</span>
</div>
<div class="w-10 h-10 rounded-xl bg-emerald-50 text-emerald-600 flex items-center justify-center">
<i data-lucide="receipt" class="w-5 h-5"></i>
</div>
</div>
</div>
<!-- Segmented Navigation Tabs -->
<div class="flex items-center space-x-1.5 p-1 bg-slate-100/80 rounded-xl max-w-max text-xs font-medium">
<button
type="button"
@click="tab = 'communications'"
:class="tab === 'communications' ? 'bg-white text-slate-900 font-semibold shadow-2xs' : 'text-slate-600 hover:text-slate-900'"
class="px-3.5 py-1.5 rounded-lg transition flex items-center space-x-1.5 cursor-pointer"
>
<i data-lucide="message-square" class="w-3.5 h-3.5"></i>
<span>Communicatie &amp; Vragen</span>
<span class="px-1.5 py-0.2 rounded-md text-[10px] bg-slate-200/60 text-slate-700">
{{ $communications->count() }}
</span>
</button>
<button
type="button"
@click="tab = 'orders'"
:class="tab === 'orders' ? 'bg-white text-slate-900 font-semibold shadow-2xs' : 'text-slate-600 hover:text-slate-900'"
class="px-3.5 py-1.5 rounded-lg transition flex items-center space-x-1.5 cursor-pointer"
>
<i data-lucide="shopping-bag" class="w-3.5 h-3.5"></i>
<span>Bestelgeschiedenis</span>
<span class="px-1.5 py-0.2 rounded-md text-[10px] bg-slate-200/60 text-slate-700">
{{ $orders->count() }}
</span>
</button>
</div>
<!-- TAB 1: COMMUNICATIE & VRAGEN BINNEN DIT KLANTPROFIEL -->
<div x-show="tab === 'communications'" class="space-y-4">
@if($communications->isEmpty())
<div class="p-12 text-center rounded-2xl bg-white border border-slate-200/80 shadow-xs space-y-2">
<div class="w-10 h-10 rounded-xl bg-slate-100 text-slate-400 flex items-center justify-center mx-auto mb-1">
<i data-lucide="message-square-off" class="w-5 h-5"></i>
</div>
<h3 class="text-sm font-semibold text-slate-800">Geen communicatie gevonden</h3>
<p class="text-xs text-slate-500 max-w-sm mx-auto">
Deze klant heeft nog geen vragen gesteld via het contactformulier.
</p>
</div>
@else
<div class="space-y-3">
@foreach($communications as $comm)
<div class="p-5 rounded-2xl bg-white border border-slate-200/80 shadow-2xs space-y-3 hover:border-slate-300 transition">
<!-- Header regel -->
<div class="flex flex-col sm:flex-row sm:items-center justify-between pb-2.5 border-b border-slate-100 gap-2">
<div class="flex items-center space-x-2">
<span class="font-mono text-xs text-slate-400">#{{ $comm->id }}</span>
<h3 class="font-bold text-slate-900 text-sm">{{ $comm->subject }}</h3>
</div>
<div class="flex items-center space-x-3">
<span class="px-2.5 py-0.5 rounded-full text-[10px] font-semibold
@if($comm->status === 'new') bg-sky-50 text-sky-700 border border-sky-200/80
@elseif($comm->status === 'in_progress') bg-amber-50 text-amber-700 border border-amber-200/80
@elseif($comm->status === 'resolved') bg-emerald-50 text-emerald-700 border border-emerald-200/80
@else bg-slate-100 text-slate-600 border border-slate-200/60
@endif">
{{ $comm->status_label }}
</span>
<span class="text-xs text-slate-400 font-mono">
{{ $comm->created_at->format('d-m-Y H:i') }}
</span>
</div>
</div>
<!-- Vraag tekst -->
<div class="text-xs text-slate-700 leading-relaxed bg-slate-50 p-3 rounded-xl border border-slate-100">
{{ $comm->message }}
</div>
<!-- Footer info & link naar communicatiedossier -->
<div class="flex flex-col sm:flex-row sm:items-center justify-between pt-1 gap-2 text-xs">
<div class="flex items-center space-x-3 text-slate-500">
@if($comm->order)
<span>Betreft: <a href="{{ route('admin.orders.show', $comm->order) }}" class="font-mono text-indigo-600 hover:underline">#{{ $comm->order->order_number }}</a></span>
<span>&bull;</span>
@endif
<span>{{ $comm->replies->count() }} antwoord(en) verzonden</span>
</div>
<a href="{{ route('admin.communications.show', $comm) }}" class="inline-flex items-center space-x-1.5 px-3 py-1.5 rounded-lg bg-slate-900 hover:bg-slate-800 text-white text-xs font-medium transition shadow-xs self-start sm:self-auto">
<span>Open Bericht &amp; Beantwoord</span>
<i data-lucide="arrow-right" class="w-3.5 h-3.5"></i>
</a>
</div>
</div>
@endforeach
</div>
@endif
</div>
<!-- TAB 2: BESTELGESCHIEDENIS BINNEN DIT KLANTPROFIEL -->
<div x-show="tab === 'orders'" class="space-y-4">
@if($orders->isEmpty())
<div class="p-12 text-center rounded-2xl bg-white border border-slate-200/80 shadow-xs space-y-2">
<div class="w-10 h-10 rounded-xl bg-slate-100 text-slate-400 flex items-center justify-center mx-auto mb-1">
<i data-lucide="shopping-cart" class="w-5 h-5"></i>
</div>
<h3 class="text-sm font-semibold text-slate-800">Nog geen bestellingen</h3>
<p class="text-xs text-slate-500 max-w-sm mx-auto">
Deze klant heeft nog geen geplaatste orders in het systeem.
</p>
</div>
@else
<div class="rounded-2xl bg-white border border-slate-200/80 overflow-hidden shadow-2xs">
<table class="w-full text-left text-xs text-slate-700">
<thead class="bg-slate-50/80 text-[11px] uppercase tracking-wider text-slate-500 font-semibold border-b border-slate-200/70">
<tr>
<th class="py-3 px-4">Order #</th>
<th class="py-3 px-4">Datum</th>
<th class="py-3 px-4">Items</th>
<th class="py-3 px-4">Totaal</th>
<th class="py-3 px-4">Status</th>
<th class="py-3 px-4 text-right">Details</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-100 font-medium">
@foreach($orders as $order)
<tr class="hover:bg-slate-50/60 transition">
<td class="py-3.5 px-4 font-mono font-bold text-slate-900">
{{ $order->order_number }}
</td>
<td class="py-3.5 px-4 text-slate-500">
{{ $order->created_at->format('d-m-Y H:i') }}
</td>
<td class="py-3.5 px-4">
{{ $order->items->count() }} prints
</td>
<td class="py-3.5 px-4 font-bold text-slate-900">
{{ $order->formatted_total }}
</td>
<td class="py-3.5 px-4">
<span class="px-2 py-0.5 rounded-full text-[10px] font-semibold
@if($order->status === 'completed' || $order->status === 'shipped') bg-emerald-50 text-emerald-700 border border-emerald-200/60
@elseif($order->status === 'printed' || $order->status === 'processing') bg-sky-50 text-sky-700 border border-sky-200/60
@elseif($order->status === 'cancelled') bg-rose-50 text-rose-700 border border-rose-200/60
@else bg-amber-50 text-amber-700 border border-amber-200/60
@endif">
{{ $order->status_label }}
</span>
</td>
<td class="py-3.5 px-4 text-right">
<a href="{{ route('admin.orders.show', $order) }}" class="inline-flex items-center space-x-1 px-2.5 py-1 rounded-lg bg-slate-100 hover:bg-slate-900 text-slate-700 hover:text-white text-xs font-medium transition">
<span>Order bekijken</span>
<i data-lucide="chevron-right" class="w-3 h-3"></i>
</a>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endif
</div>
</div>
@endsection