admin widget zu dokploy geswitched, viele übersetzungen im Frontend vervollständigt und Anlässe-Seiten mit ChatGPT ausgebaut

This commit is contained in:
Codex Agent
2025-11-19 13:12:35 +01:00
parent 125c624588
commit d8f365ddd6
30 changed files with 2820 additions and 293 deletions

View File

@@ -1,28 +1,28 @@
<x-filament-panels::page>
<div class="space-y-6">
<x-filament::section heading="Application Controls">
<x-filament::section heading="Compose Controls">
<div class="grid gap-4 md:grid-cols-2">
@foreach($applications as $application)
@foreach($composes as $compose)
<div class="rounded-2xl border border-slate-200/70 bg-white/80 p-4 shadow-sm dark:border-white/10 dark:bg-slate-900/60">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-semibold text-slate-700 dark:text-slate-200">{{ $application['label'] }}</p>
<p class="text-xs text-slate-500 dark:text-slate-400">{{ $application['application_id'] }}</p>
<p class="text-sm font-semibold text-slate-700 dark:text-slate-200">{{ $compose['label'] }}</p>
<p class="text-xs text-slate-500 dark:text-slate-400">{{ $compose['compose_id'] }}</p>
</div>
<span class="rounded-full bg-slate-100 px-3 py-1 text-xs font-semibold text-slate-700 dark:bg-slate-800 dark:text-slate-100">
{{ ucfirst($application['status'] ?? 'unknown') }}
{{ ucfirst($compose['status'] ?? 'unknown') }}
</span>
</div>
<div class="mt-4 flex flex-wrap gap-2">
<x-filament::button size="sm" color="warning" wire:click="reload('{{ $application['application_id'] }}')">
Reload
</x-filament::button>
<x-filament::button size="sm" color="gray" wire:click="redeploy('{{ $application['application_id'] }}')">
<x-filament::button size="sm" color="warning" wire:click="redeploy('{{ $compose['compose_id'] }}')">
Redeploy
</x-filament::button>
<x-filament::button size="sm" color="danger" wire:click="stop('{{ $compose['compose_id'] }}')">
Stop
</x-filament::button>
@if($dokployWebUrl)
<x-filament::button tag="a" size="sm" color="gray" href="{{ rtrim($dokployWebUrl, '/') }}/applications/{{ $application['application_id'] }}" target="_blank">
<x-filament::button tag="a" size="sm" color="gray" href="{{ rtrim($dokployWebUrl, '/') }}" target="_blank">
Open in Dokploy
</x-filament::button>
@endif
@@ -39,7 +39,7 @@
<tr class="text-left text-xs uppercase tracking-wide text-slate-500">
<th class="px-3 py-2">When</th>
<th class="px-3 py-2">User</th>
<th class="px-3 py-2">Application</th>
<th class="px-3 py-2">Target</th>
<th class="px-3 py-2">Action</th>
<th class="px-3 py-2">Status</th>
</tr>

View File

@@ -1,52 +1,54 @@
<x-filament-widgets::widget>
<x-filament::section heading="Infra Status (Dokploy)">
<div class="grid gap-4 md:grid-cols-2">
@forelse($applications as $application)
@forelse($composes as $compose)
<div class="rounded-2xl border border-slate-200/70 bg-white/80 p-4 shadow-sm dark:border-white/10 dark:bg-slate-900/60">
<div class="flex items-center justify-between">
<div>
<p class="text-sm font-semibold text-slate-600 dark:text-slate-200">{{ $application['label'] }}</p>
<p class="text-xs text-slate-500 dark:text-slate-400">{{ $application['app_name'] ?? $application['application_id'] }}</p>
<p class="text-[11px] text-slate-400 dark:text-slate-500">{{ $application['application_id'] }}</p>
<p class="text-sm font-semibold text-slate-600 dark:text-slate-200">{{ $compose['label'] }}</p>
<p class="text-xs text-slate-500 dark:text-slate-400">{{ $compose['name'] }}</p>
<p class="text-[11px] text-slate-400 dark:text-slate-500">{{ $compose['compose_id'] }}</p>
</div>
<span @class([
'rounded-full px-3 py-1 text-xs font-semibold',
'bg-emerald-100 text-emerald-800' => $application['status'] === 'running',
'bg-amber-100 text-amber-800' => in_array($application['status'], ['deploying', 'idle']),
'bg-rose-100 text-rose-800' => in_array($application['status'], ['unreachable', 'error']),
'bg-slate-100 text-slate-600' => ! in_array($application['status'], ['running', 'deploying', 'idle', 'unreachable', 'error']),
'bg-emerald-100 text-emerald-800' => $compose['status'] === 'done',
'bg-amber-100 text-amber-800' => in_array($compose['status'], ['deploying', 'pending']),
'bg-rose-100 text-rose-800' => in_array($compose['status'], ['unreachable', 'error', 'failed']),
'bg-slate-100 text-slate-600' => ! in_array($compose['status'], ['done', 'deploying', 'pending', 'unreachable', 'error', 'failed']),
])>
{{ ucfirst($application['status']) }}
{{ ucfirst($compose['status']) }}
</span>
</div>
@if(isset($application['error']))
<p class="mt-3 text-xs text-rose-600 dark:text-rose-400">{{ $application['error'] }}</p>
@if(isset($compose['error']))
<p class="mt-3 text-xs text-rose-600 dark:text-rose-400">{{ $compose['error'] }}</p>
@else
<dl class="mt-3 grid grid-cols-3 gap-2 text-xs">
<div>
<dt class="text-slate-500 dark:text-slate-400">CPU</dt>
<dd class="font-semibold text-slate-900 dark:text-white">
{{ isset($application['cpu']) ? $application['cpu'].'%' : '—' }}
</dd>
</div>
<div>
<dt class="text-slate-500 dark:text-slate-400">Memory</dt>
<dd class="font-semibold text-slate-900 dark:text-white">
{{ isset($application['memory']) ? $application['memory'].'%' : '—' }}
</dd>
</div>
<div>
<dt class="text-slate-500 dark:text-slate-400">Last Deploy</dt>
<dd class="font-semibold text-slate-900 dark:text-white">
{{ $application['last_deploy'] ? \Illuminate\Support\Carbon::parse($application['last_deploy'])->diffForHumans() : '—' }}
</dd>
</div>
</dl>
<div class="mt-3 space-y-1">
<p class="text-xs font-semibold text-slate-500 dark:text-slate-400">Services</p>
@forelse($compose['services'] as $service)
<div class="flex items-center justify-between rounded-lg bg-slate-50 px-3 py-1 text-[11px] font-medium text-slate-700 dark:bg-slate-800 dark:text-slate-200">
<span>{{ $service['name'] }}</span>
<span @class([
'rounded-full px-2 py-0.5 text-[10px] uppercase tracking-wide',
'bg-emerald-200/70 text-emerald-900' => in_array($service['status'], ['running', 'done']),
'bg-amber-200/70 text-amber-900' => in_array($service['status'], ['starting', 'deploying']),
'bg-rose-200/70 text-rose-900' => in_array($service['status'], ['error', 'failed', 'unhealthy']),
'bg-slate-200/70 text-slate-900' => ! in_array($service['status'], ['running', 'done', 'starting', 'deploying', 'error', 'failed', 'unhealthy']),
])>
{{ strtoupper($service['status'] ?? 'N/A') }}
</span>
</div>
@empty
<p class="text-xs text-slate-500 dark:text-slate-400">No services reported.</p>
@endforelse
</div>
<p class="mt-3 text-xs text-slate-500 dark:text-slate-400">
Last deploy: {{ $compose['last_deploy'] ? \Illuminate\Support\Carbon::parse($compose['last_deploy'])->diffForHumans() : '—' }}
</p>
@endif
</div>
@empty
<p class="text-sm text-slate-500 dark:text-slate-300">No Dokploy applications configured.</p>
<p class="text-sm text-slate-500 dark:text-slate-300">No Dokploy compose stacks configured.</p>
@endforelse
</div>
</x-filament::section>

View File

@@ -7,15 +7,26 @@
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 13a3 3 0 11-6 0 3 3 0 016 0z"></path>
</svg>
</div>
@php
$currentLocale = app()->getLocale();
$occasionRouteName = $currentLocale === 'en' ? 'occasions.type' : 'anlaesse.type';
$occasionSlugs = [
'hochzeit' => $currentLocale === 'en' ? 'wedding' : 'hochzeit',
'geburtstag' => $currentLocale === 'en' ? 'birthday' : 'geburtstag',
'firmenevent' => $currentLocale === 'en' ? 'corporate-event' : 'firmenevent',
'konfirmation' => $currentLocale === 'en' ? 'confirmation' : 'konfirmation',
];
@endphp
<nav class="hidden md:flex space-x-6 items-center">
<a href="{{ route('marketing.home', ['locale' => app()->getLocale()]) }}#how-it-works" class="text-gray-600 hover:text-gray-900">{{ __('marketing.nav.how_it_works') }}</a>
<a href="{{ route('marketing.home', ['locale' => app()->getLocale()]) }}#features" class="text-gray-600 hover:text-gray-900">{{ __('marketing.nav.features') }}</a>
<div x-data="{ open: false }" @mouseenter="open = true" @mouseleave="open = false" @click.away="open = false" class="relative">
<button class="text-gray-600 hover:text-gray-900" @click.stop="open = !open">{{ __('marketing.nav.occasions') }}</button>
<div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 transform scale-95" x-transition:enter-end="opacity-100 transform scale-100" x-transition:leave="transition ease-in duration-150" x-transition:leave-start="opacity-100 transform scale-100" x-transition:leave-end="opacity-0 transform scale-95" class="absolute top-full left-0 mt-2 bg-white border rounded shadow-lg z-10">
<a href="{{ route('anlaesse.type', ['locale' => app()->getLocale(), 'type' => 'hochzeit']) }}" class="block px-4 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 transition">{{ __('marketing.nav.occasions_types.weddings') }}</a>
<a href="{{ route('anlaesse.type', ['locale' => app()->getLocale(), 'type' => 'geburtstag']) }}" class="block px-4 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 transition">{{ __('marketing.nav.occasions_types.birthdays') }}</a>
<a href="{{ route('anlaesse.type', ['locale' => app()->getLocale(), 'type' => 'firmenevent']) }}" class="block px-4 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 transition">{{ __('marketing.nav.occasions_types.corporate') }}</a>
<a href="{{ route($occasionRouteName, ['locale' => $currentLocale, 'type' => $occasionSlugs['hochzeit']]) }}" class="block px-4 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 transition">{{ __('marketing.nav.occasions_types.weddings') }}</a>
<a href="{{ route($occasionRouteName, ['locale' => $currentLocale, 'type' => $occasionSlugs['geburtstag']]) }}" class="block px-4 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 transition">{{ __('marketing.nav.occasions_types.birthdays') }}</a>
<a href="{{ route($occasionRouteName, ['locale' => $currentLocale, 'type' => $occasionSlugs['firmenevent']]) }}" class="block px-4 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 transition">{{ __('marketing.nav.occasions_types.corporate') }}</a>
<a href="{{ route($occasionRouteName, ['locale' => $currentLocale, 'type' => $occasionSlugs['konfirmation']]) }}" class="block px-4 py-2 text-gray-600 hover:text-gray-900 hover:bg-gray-50 transition">{{ __('marketing.nav.occasions_types.confirmation') }}</a>
</div>
</div>
<a href="{{ route('blog', ['locale' => app()->getLocale()]) }}" class="text-gray-600 hover:text-gray-900">{{ __('marketing.nav.blog') }}</a>