23-01-2026

This commit is contained in:
Kevin Adametz 2026-01-23 17:33:10 +01:00
parent 07959c0ba2
commit 854ce02bf6
166 changed files with 32909 additions and 1262 deletions

View file

@ -0,0 +1,208 @@
<?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>

View file

@ -0,0 +1,482 @@
<?php
use function Livewire\Volt\{state, mount, computed};
state([
'hubId' => null,
'activeTab' => 'identity',
'importMethod' => 'single',
// Identität
'name' => '',
'slug' => '',
'keyvisual' => null,
'emblem' => null,
'is_active' => false,
// PLZ-Management
'zipSearch' => '',
'newZipCode' => '',
'newCityName' => '',
'rangeStart' => '',
'rangeEnd' => '',
'csvFile' => null,
]);
mount(function ($hubId = null) {
if ($hubId) {
$hub = \App\Models\Hub::findOrFail($hubId);
$this->hubId = $hub->id;
$this->name = $hub->name;
$this->slug = $hub->slug;
$this->is_active = $hub->is_active;
}
});
// Auto-generate slug from name
$updatedName = function ($value) {
if (!$this->hubId) { // Only auto-generate for new hubs
$this->slug = \Illuminate\Support\Str::slug($value);
}
};
$locations = computed(function () {
if (!$this->hubId) return collect();
return \App\Models\HubLocation::where('hub_id', $this->hubId)
->when($this->zipSearch, fn($q) => $q->where('zip_code', 'like', "%{$this->zipSearch}%")
->orWhere('city_name', 'like', "%{$this->zipSearch}%"))
->orderBy('zip_code')
->paginate(50);
});
$partners = computed(function () {
if (!$this->hubId) return collect();
return \App\Models\Partner::where('hub_id', $this->hubId)
->get();
});
// Dummy save function
$save = function () {
// In production: Validation und Speicherung
session()->flash('message', __('Hub gespeichert (Dummy-Funktion)'));
};
// Dummy functions für PLZ-Management
$addSingleZip = function () {
session()->flash('message', __('PLZ hinzugefügt (Dummy-Funktion)'));
};
$addZipRange = function () {
session()->flash('message', __('PLZ-Bereich importiert (Dummy-Funktion)'));
};
$importCsv = function () {
session()->flash('message', __('CSV importiert (Dummy-Funktion)'));
};
$deleteLocation = function ($id) {
session()->flash('message', __('PLZ gelöscht (Dummy-Funktion)'));
};
?>
<div class="space-y-6">
{{-- Header --}}
<div class="flex items-center justify-between">
<div>
<flux:heading size="xl">
{{ $hubId ? __('Hub bearbeiten') : __('Neuer Hub') }} (in Entwicklung)
</flux:heading>
<flux:subheading>{{ $name ?: __('Regionalen Marktplatz konfigurieren') }}</flux:subheading>
</div>
<div class="flex gap-2">
<flux:button variant="ghost" :href="route('admin.hubs.index')" wire:navigate>
{{ __('Zurück') }}
</flux:button>
<flux:button variant="primary" icon="check" wire:click="save">
{{ __('Speichern') }}
</flux:button>
</div>
</div>
{{-- Flash Message --}}
@if (session()->has('message'))
<flux:card class="p-4 bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800">
<div class="flex items-center gap-3">
<flux:icon.check-circle class="h-5 w-5 text-green-600 dark:text-green-400" />
<span class="text-sm text-green-900 dark:text-green-100">{{ session('message') }}</span>
</div>
</flux:card>
@endif
{{-- Tabs --}}
<flux:tabs wire:model.live="activeTab" variant="segmented">
<flux:tab name="identity" icon="identification">{{ __('Identität & Design') }}</flux:tab>
<flux:tab name="geography" icon="map">{{ __('Geografie & PLZ') }}</flux:tab>
<flux:tab name="partners" icon="user-group">{{ __('Partner-Monitor') }}</flux:tab>
</flux:tabs>
{{-- TAB 1: Identität & Design --}}
@if($activeTab === 'identity')
<flux:card class="p-6 space-y-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
{{-- Basis-Informationen --}}
<div class="space-y-6">
<flux:field>
<flux:label>{{ __('Hub-Name') }} <span class="text-red-500">*</span></flux:label>
<flux:input wire:model.live="name" placeholder="Ostwestfalen-Lippe" />
<flux:description>{{ __('Wird dem Kunden angezeigt, z.B. "Region Ostwestfalen-Lippe"') }}</flux:description>
</flux:field>
<flux:field>
<flux:label>{{ __('URL-Slug') }} <span class="text-red-500">*</span></flux:label>
<flux:input wire:model="slug" placeholder="owl" />
<flux:description>{{ __('Für saubere URLs, z.B. b2in.de/region/owl') }}</flux:description>
</flux:field>
<flux:field>
<flux:label>{{ __('Status') }}</flux:label>
<flux:checkbox wire:model="is_active">
{{ __('Hub ist aktiv und für Kunden sichtbar') }}
</flux:checkbox>
<flux:description>
{{ __('Inaktive Hubs sind im "Coming Soon"-Modus') }}
</flux:description>
</flux:field>
</div>
{{-- Vorschau --}}
<div class="p-4 bg-zinc-50 dark:bg-zinc-800 rounded-lg">
<h4 class="font-semibold mb-3 text-zinc-900 dark:text-zinc-100">{{ __('Vorschau: Kunden-Landingpage') }}</h4>
<div class="relative h-48 rounded-lg overflow-hidden bg-zinc-200 dark:bg-zinc-700 shadow-lg">
@if($keyvisual)
<img src="{{ $keyvisual }}" class="w-full h-full object-cover" alt="Keyvisual" />
@else
<div class="flex items-center justify-center h-full">
<div class="text-center">
<flux:icon.photo class="w-12 h-12 text-zinc-400 mx-auto mb-2" />
<p class="text-sm text-zinc-500">{{ __('Keyvisual hochladen') }}</p>
</div>
</div>
@endif
<div class="absolute bottom-0 left-0 right-0 p-4 bg-gradient-to-t from-black/80 to-transparent">
<h3 class="text-xl font-bold text-white">
{{ $name ?: __('Ihr Hub-Name') }}
</h3>
<p class="text-sm text-zinc-200">
{{ __('Die besten Marken Europas, von Händlern aus Ihrer Nachbarschaft') }}
</p>
</div>
@if($emblem)
<div class="absolute top-3 right-3 w-12 h-12 bg-white rounded-full p-2 shadow-lg">
<img src="{{ $emblem }}" alt="Emblem" class="w-full h-full object-contain" />
</div>
@endif
</div>
</div>
</div>
<flux:separator />
{{-- Keyvisual Upload --}}
<flux:field>
<flux:label>{{ __('Keyvisual (Hintergrundbild)') }}</flux:label>
{{-- <flux:input type="file" wire:model="keyvisual" accept="image/*" /> --}}
<flux:description>
{{ __('Atmosphärisches Regionalbild für emotionalen Einstieg') }}
<br>
<span class="text-xs">
{{ __('Beispiele: Hermannsdenkmal (OWL), Skyline (Frankfurt), Hafen (Hamburg)') }}
{{ __('Empfohlen: 1920x800px, max. 2MB') }}
</span>
</flux:description>
</flux:field>
{{-- Wappen Upload --}}
<flux:field>
<flux:label>{{ __('Wappen / Emblem') }}</flux:label>
{{-- <flux:input type="file" wire:model="emblem" accept="image/*" /> --}}
<flux:description>
{{ __('Offizielles Wappen oder Logo der Region für Vertrauen & Offizialität') }}
<br>
<span class="text-xs">
{{ __('Beispiele: Sparrenburg-Logo, Landeswappen') }}
{{ __('Empfohlen: 256x256px, PNG mit transparentem Hintergrund') }}
</span>
</flux:description>
</flux:field>
</flux:card>
@endif
{{-- TAB 2: Geografie & PLZ --}}
@if($activeTab === 'geography')
<div class="space-y-6">
{{-- Info-Box --}}
<flux:card class="p-4 bg-yellow-50 dark:bg-yellow-900/20 border-yellow-200 dark:border-yellow-800">
<div class="flex items-start gap-3">
<flux:icon.light-bulb class="h-5 w-5 text-yellow-600 dark:text-yellow-400 flex-shrink-0 mt-0.5" />
<div class="flex-1">
<div class="text-sm font-semibold text-yellow-900 dark:text-yellow-100">
{{ __('Die Mapping-Engine') }}
</div>
<div class="text-xs text-yellow-700 dark:text-yellow-300 mt-1">
{{ __('Hier ordnen Sie Postleitzahlen diesem Hub zu. Gibt ein Kunde seine PLZ ein, wird er automatisch diesem regionalen Marktplatz zugewiesen und sieht lokale Händler.') }}
</div>
</div>
</div>
</flux:card>
{{-- PLZ-Import Tools --}}
<flux:card class="p-6">
<flux:heading size="lg" class="mb-4">{{ __('Postleitzahlen hinzufügen') }}</flux:heading>
<flux:tabs wire:model.live="importMethod" variant="segmented">
<flux:tab name="single" icon="plus">{{ __('Einzeln') }}</flux:tab>
<flux:tab name="range" icon="arrows-right-left">{{ __('Bereich') }}</flux:tab>
<flux:tab name="csv" icon="document">{{ __('CSV-Import') }}</flux:tab>
</flux:tabs>
<div class="mt-6">
{{-- Einzelne PLZ --}}
@if($importMethod === 'single')
<div class="space-y-4">
<div class="grid grid-cols-2 gap-4">
<flux:field>
<flux:label>{{ __('Postleitzahl') }} <span class="text-red-500">*</span></flux:label>
<flux:input wire:model="newZipCode" placeholder="33602" />
</flux:field>
<flux:field>
<flux:label>{{ __('Stadt') }} <span class="text-red-500">*</span></flux:label>
<flux:input wire:model="newCityName" placeholder="Bielefeld" />
</flux:field>
</div>
<flux:button wire:click="addSingleZip" icon="plus">
{{ __('PLZ hinzufügen') }}
</flux:button>
</div>
@endif
{{-- PLZ-Bereich --}}
@if($importMethod === 'range')
<div class="space-y-4">
<div class="grid grid-cols-2 gap-4">
<flux:field>
<flux:label>{{ __('Von PLZ') }} <span class="text-red-500">*</span></flux:label>
<flux:input wire:model="rangeStart" placeholder="33000" />
</flux:field>
<flux:field>
<flux:label>{{ __('Bis PLZ') }} <span class="text-red-500">*</span></flux:label>
<flux:input wire:model="rangeEnd" placeholder="33999" />
</flux:field>
</div>
<flux:button wire:click="addZipRange" icon="arrows-right-left">
{{ __('Bereich importieren') }}
</flux:button>
<flux:description>
⚠️ {{ __('Generiert automatisch alle PLZs im Bereich. Kann bei großen Bereichen mehrere Minuten dauern!') }}
</flux:description>
</div>
@endif
{{-- CSV-Import --}}
@if($importMethod === 'csv')
<div class="space-y-4">
<flux:field>
<flux:label>{{ __('CSV-Datei') }} <span class="text-red-500">*</span></flux:label>
<flux:input type="file" wire:model="csvFile" accept=".csv" />
<flux:description>
{{ __('Format: PLZ,Stadt (eine Zeile pro Eintrag)') }}
<br>
<span class="text-xs">{{ __('Beispiel:') }}</span>
<code class="text-xs bg-zinc-100 dark:bg-zinc-800 px-2 py-1 rounded">
33602,Bielefeld<br>33603,Bielefeld<br>33604,Bielefeld
</code>
</flux:description>
</flux:field>
<flux:button wire:click="importCsv" icon="arrow-up-tray">
{{ __('CSV importieren') }}
</flux:button>
</div>
@endif
</div>
</flux:card>
{{-- PLZ-Liste --}}
<flux:card>
<div class="p-6">
<div class="flex items-center justify-between mb-4">
<flux:heading size="lg">
{{ __('Zugeordnete Postleitzahlen') }}
@if($hubId)
<span class="text-sm font-normal text-zinc-600 dark:text-zinc-400">
({{ $this->locations->total() }} {{ __('gesamt') }})
</span>
@endif
</flux:heading>
<flux:input
wire:model.live.debounce="zipSearch"
placeholder="{{ __('PLZ oder Stadt suchen...') }}"
icon="magnifying-glass"
class="w-64"
/>
</div>
@if($hubId)
<flux:table>
<flux:table.columns>
<flux:table.column>{{ __('PLZ') }}</flux:table.column>
<flux:table.column>{{ __('Stadt') }}</flux:table.column>
<flux:table.column class="text-right w-32">{{ __('Aktion') }}</flux:table.column>
</flux:table.columns>
<flux:table.rows>
@forelse($this->locations as $location)
<flux:table.row :key="$location->id">
<flux:table.cell>
<span class="font-mono">{{ $location->zip_code }}</span>
</flux:table.cell>
<flux:table.cell>{{ $location->city_name }}</flux:table.cell>
<flux:table.cell class="text-right">
<flux:button
variant="ghost"
size="sm"
icon="trash"
wire:click="deleteLocation({{ $location->id }})"
/>
</flux:table.cell>
</flux:table.row>
@empty
<flux:table.row>
<flux:table.cell colspan="3" class="text-center py-8">
<flux:icon.map-pin class="w-12 h-12 text-zinc-400 mx-auto mb-2" />
<p class="text-zinc-600 dark:text-zinc-400">
{{ __('Noch keine PLZs zugeordnet') }}
</p>
</flux:table.cell>
</flux:table.row>
@endforelse
</flux:table.rows>
</flux:table>
{{-- Pagination --}}
@if($this->locations->hasPages())
<div class="mt-4 border-t border-zinc-200 dark:border-zinc-700 pt-4">
{{ $this->locations->links() }}
</div>
@endif
@else
<div class="text-center py-8 text-zinc-600 dark:text-zinc-400">
{{ __('Speichern Sie zuerst den Hub, um PLZs hinzuzufügen') }}
</div>
@endif
</div>
</flux:card>
</div>
@endif
{{-- TAB 3: Partner-Monitor --}}
@if($activeTab === 'partners')
<flux:card class="p-6">
<flux:heading size="lg" class="mb-4">
{{ __('Partner in diesem Hub') }}
@if($hubId)
<span class="text-sm font-normal text-zinc-600 dark:text-zinc-400">
({{ $this->partners->count() }} {{ __('Partner') }})
</span>
@endif
</flux:heading>
{{-- Info --}}
<flux:card class="p-4 mb-4 bg-zinc-50 dark:bg-zinc-800 border-0">
<div class="text-sm text-zinc-600 dark:text-zinc-400">
<strong>{{ __('Logik:') }}</strong>
<ul class="list-disc ml-5 mt-2 space-y-1">
<li>{{ __('Händler (Retailer) → Werden diesem Hub fest zugeordnet') }}</li>
<li>{{ __('Hersteller (Manufacturer) → Sind "Hub-agnostisch", in allen Hubs sichtbar') }}</li>
<li>{{ __('Makler (Estate-Agent) → Werden Hub zugeordnet für regionale Kundenakquise') }}</li>
</ul>
</div>
</flux:card>
@if($hubId)
<flux:table>
<flux:table.columns>
<flux:table.column>{{ __('Name') }}</flux:table.column>
<flux:table.column>{{ __('Typ') }}</flux:table.column>
<flux:table.column>{{ __('Stadt') }}</flux:table.column>
<flux:table.column>{{ __('Lieferradius') }}</flux:table.column>
<flux:table.column class="text-center">{{ __('Status') }}</flux:table.column>
<flux:table.column class="text-right">{{ __('Aktion') }}</flux:table.column>
</flux:table.columns>
<flux:table.rows>
@forelse($this->partners as $partner)
<flux:table.row :key="$partner->id">
<flux:table.cell>
<div class="font-semibold text-zinc-900 dark:text-zinc-100">
{{ $partner->company_name }}
</div>
@if($partner->display_name && $partner->display_name !== $partner->company_name)
<div class="text-xs text-zinc-500">{{ $partner->display_name }}</div>
@endif
</flux:table.cell>
<flux:table.cell>
@php
$typeColors = [
'Retailer' => 'blue',
'Manufacturer' => 'purple',
'Estate-Agent' => 'green',
];
@endphp
<flux:badge :color="$typeColors[$partner->type] ?? 'zinc'" size="sm">
{{ $partner->type }}
</flux:badge>
</flux:table.cell>
<flux:table.cell>
{{ $partner->city ?? '-' }}
</flux:table.cell>
<flux:table.cell>
@if($partner->delivery_radius_km)
<span class="text-sm">{{ $partner->delivery_radius_km }} km</span>
@else
<span class="text-sm text-zinc-400">-</span>
@endif
</flux:table.cell>
<flux:table.cell class="text-center">
<flux:badge :color="$partner->is_active ? 'green' : 'zinc'" size="sm">
{{ $partner->is_active ? __('Aktiv') : __('Inaktiv') }}
</flux:badge>
</flux:table.cell>
<flux:table.cell class="text-right">
<flux:button variant="ghost" size="sm" icon="eye">
{{ __('Details') }}
</flux:button>
</flux:table.cell>
</flux:table.row>
@empty
<flux:table.row>
<flux:table.cell colspan="6" class="text-center py-8">
<flux:icon.user-group class="w-12 h-12 text-zinc-400 mx-auto mb-2" />
<p class="text-zinc-600 dark:text-zinc-400">
{{ __('Noch keine Partner in diesem Hub') }}
</p>
<p class="text-xs text-zinc-500 mt-2">
{{ __('Partner werden automatisch beim Onboarding zugeordnet (basierend auf PLZ)') }}
</p>
</flux:table.cell>
</flux:table.row>
@endforelse
</flux:table.rows>
</flux:table>
@else
<div class="text-center py-8 text-zinc-600 dark:text-zinc-400">
{{ __('Speichern Sie zuerst den Hub, um Partner-Zuordnungen zu sehen') }}
</div>
@endif
</flux:card>
@endif
</div>