208 lines
9.3 KiB
PHP
208 lines
9.3 KiB
PHP
<?php
|
|
|
|
use function Livewire\Volt\{state, computed};
|
|
|
|
state(['search' => '']);
|
|
|
|
$hubs = computed(function () {
|
|
return \App\Models\Hub::with(['locations', 'partners'])
|
|
->when($this->search, fn($q) => $q->where('name', 'like', "%{$this->search}%"))
|
|
->get()
|
|
->map(function ($hub) {
|
|
$retailers = $hub->partners()->where('type', 'Retailer')->count();
|
|
$brokers = $hub->partners()->where('type', 'Estate-Agent')->count();
|
|
|
|
return [
|
|
'id' => $hub->id,
|
|
'name' => $hub->name,
|
|
'slug' => $hub->slug,
|
|
'keyvisual' => $hub->keyvisual_url ?? '/images/default-keyvisual.jpg',
|
|
'emblem' => $hub->emblem_url,
|
|
'is_active' => $hub->is_active,
|
|
'locations_count' => $hub->locations->count(),
|
|
'retailers_count' => $retailers,
|
|
'brokers_count' => $brokers,
|
|
];
|
|
});
|
|
});
|
|
|
|
?>
|
|
|
|
<div class="space-y-6">
|
|
{{-- Header mit Suche --}}
|
|
<div class="flex items-center justify-between">
|
|
<div>
|
|
<flux:heading size="xl">{{ __('Hub-Verwaltung') }} (in Entwicklung)</flux:heading>
|
|
<flux:subheading>{{ __('Regionale Marktplätze & Postleitzahlen-Zuordnung') }}</flux:subheading>
|
|
</div>
|
|
<flux:button variant="primary" icon="plus" :href="route('admin.hubs.create')" wire:navigate>
|
|
{{ __('Neuer Hub') }}
|
|
</flux:button>
|
|
</div>
|
|
|
|
{{-- Info-Banner --}}
|
|
<flux:card class="p-4 bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800">
|
|
<div class="flex items-start gap-3">
|
|
<flux:icon.information-circle class="h-5 w-5 text-blue-600 dark:text-blue-400 flex-shrink-0 mt-0.5" />
|
|
<div class="flex-1">
|
|
<div class="text-sm font-semibold text-blue-900 dark:text-blue-100">
|
|
{{ __('Konzept: Heimatgefühl + Weltmarkt') }}
|
|
</div>
|
|
<div class="text-xs text-blue-700 dark:text-blue-300 mt-1">
|
|
{{ __('Jeder Hub filtert lokale Händler heraus, behält aber globale Hersteller bei. Kunden fühlen sich "zuhause" mit Zugriff auf das volle Sortiment.') }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</flux:card>
|
|
|
|
{{-- Suchfeld --}}
|
|
<flux:input
|
|
wire:model.live.debounce="search"
|
|
placeholder="{{ __('Hub suchen...') }}"
|
|
icon="magnifying-glass"
|
|
/>
|
|
|
|
{{-- Hubs als Karten-Grid --}}
|
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
@forelse($this->hubs as $hub)
|
|
<a href="{{ route('admin.hubs.edit', $hub['id']) }}"
|
|
wire:navigate
|
|
class="block relative overflow-hidden rounded-lg border border-zinc-200 dark:border-zinc-700 hover:shadow-lg hover:border-accent-300 dark:hover:border-accent-700 transition-all group">
|
|
|
|
{{-- Keyvisual Hintergrund --}}
|
|
<div class="relative h-48 bg-cover bg-center"
|
|
style="background-image: linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.6)), url('{{ $hub['keyvisual'] }}')">
|
|
|
|
{{-- Wappen oben rechts --}}
|
|
@if($hub['emblem'])
|
|
<div class="absolute top-3 right-3 w-12 h-12 bg-white rounded-full p-2 shadow-lg">
|
|
<img src="{{ $hub['emblem'] }}" alt="Wappen" class="w-full h-full object-contain" />
|
|
</div>
|
|
@endif
|
|
|
|
{{-- Status Badge oben links --}}
|
|
<div class="absolute top-3 left-3">
|
|
<flux:badge :color="$hub['is_active'] ? 'green' : 'zinc'" size="sm">
|
|
{{ $hub['is_active'] ? __('Aktiv') : __('Inaktiv') }}
|
|
</flux:badge>
|
|
</div>
|
|
|
|
{{-- Hub Name --}}
|
|
<div class="absolute bottom-0 left-0 right-0 p-4">
|
|
<h3 class="text-2xl font-bold text-white group-hover:text-accent-200 transition-colors">
|
|
{{ $hub['name'] }}
|
|
</h3>
|
|
<p class="text-sm text-zinc-200">{{ $hub['slug'] }}</p>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- Metriken --}}
|
|
<div class="p-4 bg-white dark:bg-zinc-900">
|
|
<div class="grid grid-cols-3 gap-2 text-center">
|
|
<div class="p-2 bg-zinc-50 dark:bg-zinc-800 rounded group-hover:bg-accent-50 dark:group-hover:bg-accent-900/20 transition-colors">
|
|
<div class="text-lg font-bold text-zinc-900 dark:text-zinc-100">
|
|
{{ $hub['locations_count'] }}
|
|
</div>
|
|
<div class="text-xs text-zinc-600 dark:text-zinc-400">
|
|
{{ __('PLZs') }}
|
|
</div>
|
|
</div>
|
|
<div class="p-2 bg-zinc-50 dark:bg-zinc-800 rounded group-hover:bg-accent-50 dark:group-hover:bg-accent-900/20 transition-colors">
|
|
<div class="text-lg font-bold text-zinc-900 dark:text-zinc-100">
|
|
{{ $hub['retailers_count'] }}
|
|
</div>
|
|
<div class="text-xs text-zinc-600 dark:text-zinc-400">
|
|
{{ __('Händler') }}
|
|
</div>
|
|
</div>
|
|
<div class="p-2 bg-zinc-50 dark:bg-zinc-800 rounded group-hover:bg-accent-50 dark:group-hover:bg-accent-900/20 transition-colors">
|
|
<div class="text-lg font-bold text-zinc-900 dark:text-zinc-100">
|
|
{{ $hub['brokers_count'] }}
|
|
</div>
|
|
<div class="text-xs text-zinc-600 dark:text-zinc-400">
|
|
{{ __('Makler') }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</a>
|
|
@empty
|
|
<div class="col-span-3">
|
|
<flux:card class="p-12">
|
|
<div class="text-center">
|
|
<flux:icon.map class="w-16 h-16 text-zinc-400 mx-auto mb-4" />
|
|
<flux:heading size="lg" class="mb-2">{{ __('Noch keine Hubs angelegt') }}</flux:heading>
|
|
<flux:subheading class="mb-4">
|
|
{{ __('Erstellen Sie Ihren ersten regionalen Marktplatz') }}
|
|
</flux:subheading>
|
|
<flux:button variant="primary" icon="plus" :href="route('admin.hubs.create')" wire:navigate>
|
|
{{ __('Ersten Hub erstellen') }}
|
|
</flux:button>
|
|
</div>
|
|
</flux:card>
|
|
</div>
|
|
@endforelse
|
|
</div>
|
|
|
|
{{-- Statistik-Übersicht --}}
|
|
@if($this->hubs->isNotEmpty())
|
|
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mt-8">
|
|
<flux:card class="p-4">
|
|
<div class="flex items-center gap-3">
|
|
<div class="p-3 bg-blue-100 dark:bg-blue-900/20 rounded-lg">
|
|
<flux:icon.map class="w-6 h-6 text-blue-600 dark:text-blue-400" />
|
|
</div>
|
|
<div>
|
|
<div class="text-2xl font-bold text-zinc-900 dark:text-zinc-100">
|
|
{{ $this->hubs->count() }}
|
|
</div>
|
|
<div class="text-sm text-zinc-600 dark:text-zinc-400">{{ __('Gesamt Hubs') }}</div>
|
|
</div>
|
|
</div>
|
|
</flux:card>
|
|
|
|
<flux:card class="p-4">
|
|
<div class="flex items-center gap-3">
|
|
<div class="p-3 bg-green-100 dark:bg-green-900/20 rounded-lg">
|
|
<flux:icon.check-circle class="w-6 h-6 text-green-600 dark:text-green-400" />
|
|
</div>
|
|
<div>
|
|
<div class="text-2xl font-bold text-zinc-900 dark:text-zinc-100">
|
|
{{ $this->hubs->where('is_active', true)->count() }}
|
|
</div>
|
|
<div class="text-sm text-zinc-600 dark:text-zinc-400">{{ __('Aktive Hubs') }}</div>
|
|
</div>
|
|
</div>
|
|
</flux:card>
|
|
|
|
<flux:card class="p-4">
|
|
<div class="flex items-center gap-3">
|
|
<div class="p-3 bg-purple-100 dark:bg-purple-900/20 rounded-lg">
|
|
<flux:icon.map-pin class="w-6 h-6 text-purple-600 dark:text-purple-400" />
|
|
</div>
|
|
<div>
|
|
<div class="text-2xl font-bold text-zinc-900 dark:text-zinc-100">
|
|
{{ $this->hubs->sum('locations_count') }}
|
|
</div>
|
|
<div class="text-sm text-zinc-600 dark:text-zinc-400">{{ __('PLZ-Gebiete') }}</div>
|
|
</div>
|
|
</div>
|
|
</flux:card>
|
|
|
|
<flux:card class="p-4">
|
|
<div class="flex items-center gap-3">
|
|
<div class="p-3 bg-orange-100 dark:bg-orange-900/20 rounded-lg">
|
|
<flux:icon.building-storefront class="w-6 h-6 text-orange-600 dark:text-orange-400" />
|
|
</div>
|
|
<div>
|
|
<div class="text-2xl font-bold text-zinc-900 dark:text-zinc-100">
|
|
{{ $this->hubs->sum('retailers_count') }}
|
|
</div>
|
|
<div class="text-sm text-zinc-600 dark:text-zinc-400">{{ __('Partner gesamt') }}</div>
|
|
</div>
|
|
</div>
|
|
</flux:card>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|