124 lines
7.4 KiB
PHP
124 lines
7.4 KiB
PHP
<div class="space-y-5">
|
|
{{-- Header --}}
|
|
<div class="flex flex-wrap items-center gap-4 rounded-xl border border-line bg-surface p-5 shadow-panel">
|
|
<span class="grid h-14 w-14 shrink-0 place-items-center rounded-xl border border-accent/25 bg-accent/10 text-accent">
|
|
<x-icon name="settings" class="h-6 w-6" />
|
|
</span>
|
|
<div class="min-w-0 flex-1">
|
|
<p class="font-mono text-[11px] uppercase tracking-[0.2em] text-accent-text">{{ __('system.eyebrow') }}</p>
|
|
<h2 class="mt-0.5 truncate font-display text-xl font-semibold text-ink">{{ __('system.heading') }}</h2>
|
|
<p class="truncate font-mono text-[11px] text-ink-3">{{ __('system.subheading') }}</p>
|
|
</div>
|
|
<span @class([
|
|
'inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 font-mono text-[11px]',
|
|
'border-online/30 text-online' => $hasTls,
|
|
'border-warning/30 text-warning' => ! $hasTls,
|
|
])>
|
|
<x-status-dot :status="$hasTls ? 'online' : 'warning'" />{{ $hasTls ? __('system.https_active') : __('system.https_plain') }}
|
|
</span>
|
|
</div>
|
|
|
|
{{-- Domain & TLS --}}
|
|
<x-panel :title="__('system.tls_title')" :subtitle="__('system.tls_subtitle')">
|
|
{{-- Current TLS state --}}
|
|
@if ($hasTls)
|
|
<div class="mb-4 flex items-start gap-3 rounded-md border border-online/25 bg-online/5 p-3">
|
|
<x-icon name="shield" class="mt-0.5 h-4 w-4 shrink-0 text-online" />
|
|
<div class="min-w-0">
|
|
<p class="text-sm text-ink">{{ __('system.tls_active_title') }}</p>
|
|
<p class="mt-0.5 font-mono text-[11px] text-ink-3">{{ __('system.tls_active_body_pre') }}
|
|
<a href="{{ $panelUrl }}" class="break-all text-accent-text hover:underline">{{ $panelUrl }}</a> ·
|
|
{{ __('system.tls_active_body_post') }}</p>
|
|
</div>
|
|
</div>
|
|
@else
|
|
<div class="mb-4 flex items-start gap-3 rounded-md border border-warning/25 bg-warning/5 p-3">
|
|
<x-icon name="alert" class="mt-0.5 h-4 w-4 shrink-0 text-warning" />
|
|
<div class="min-w-0">
|
|
<p class="text-sm text-ink">{{ __('system.tls_bare_title') }}</p>
|
|
<p class="mt-0.5 font-mono text-[11px] text-ink-3">{{ __('system.tls_bare_body') }}</p>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
{{-- Restart-required notice (shown after a successful save) --}}
|
|
@if ($restartPending)
|
|
<div class="mb-4 flex items-start gap-3 rounded-md border border-warning/30 bg-warning/10 p-3">
|
|
<x-icon name="alert" class="mt-0.5 h-4 w-4 shrink-0 text-warning" />
|
|
<div class="min-w-0">
|
|
<p class="text-sm text-ink">{{ __('system.restart_title') }}</p>
|
|
<p class="mt-0.5 font-mono text-[11px] leading-relaxed text-ink-3">{{ __('system.restart_body') }}</p>
|
|
<code class="mt-2 block overflow-x-auto rounded border border-line bg-void px-2.5 py-1.5 font-mono text-[11px] text-accent-text">docker compose -f docker-compose.prod.yml restart</code>
|
|
<p class="mt-2 font-mono text-[11px] leading-relaxed text-ink-4">{{ __('system.restart_lockout_hint') }}</p>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
{{-- Editable panel domain. Saving persists it and asks for a restart; on restart
|
|
app URL, the Reverb endpoint, Caddy's cert and the secure cookie re-derive from it. --}}
|
|
<div class="space-y-3">
|
|
<div>
|
|
<label for="domainInput" class="mb-1 block text-sm text-ink-2">{{ __('system.domain') }}</label>
|
|
<div class="flex flex-col gap-2 sm:flex-row">
|
|
<input wire:model="domainInput" id="domainInput" type="text" autocomplete="off"
|
|
autocapitalize="off" spellcheck="false"
|
|
placeholder="{{ __('system.domain_placeholder') }}"
|
|
class="h-9 w-full rounded-md border border-line bg-inset px-3 font-mono text-sm text-ink placeholder:text-ink-4 focus:border-accent/40 focus:outline-none" />
|
|
<x-btn variant="secondary" wire:click="confirmDomain" wire:loading.attr="disabled" class="shrink-0">
|
|
<x-icon name="check" class="h-3.5 w-3.5" /> {{ __('common.save') }}
|
|
</x-btn>
|
|
</div>
|
|
@error('domainInput')
|
|
<p class="mt-1.5 font-mono text-[11px] text-offline">{{ $message }}</p>
|
|
@enderror
|
|
<p class="mt-1.5 font-mono text-[11px] leading-relaxed text-ink-4">{{ __('system.domain_help') }}</p>
|
|
</div>
|
|
|
|
{{-- Current access address (read-only status) --}}
|
|
<dl class="divide-y divide-line overflow-hidden rounded-md border border-line">
|
|
<div class="flex items-center justify-between gap-3 px-4 py-2.5">
|
|
<dt class="shrink-0 text-sm text-ink-2">{{ __('system.access_address') }}</dt>
|
|
<dd class="min-w-0 truncate font-mono text-sm text-ink">
|
|
@if ($panelUrl)
|
|
<a href="{{ $panelUrl }}" class="text-accent-text hover:underline">{{ $panelUrl }}</a>
|
|
@else
|
|
{{ __('system.access_bare_ip') }}
|
|
@endif
|
|
</dd>
|
|
</div>
|
|
</dl>
|
|
</div>
|
|
</x-panel>
|
|
|
|
{{-- Release-Kanal --}}
|
|
<x-panel :title="__('system.channel_title')" :subtitle="__('system.channel_subtitle')">
|
|
<div class="space-y-4">
|
|
{{-- Segmented control --}}
|
|
<div role="radiogroup" aria-label="{{ __('system.channel_radiogroup_label') }}" class="inline-flex w-full max-w-md rounded-md border border-line bg-inset p-1">
|
|
@foreach ($channels as $key => $desc)
|
|
<button type="button"
|
|
role="radio"
|
|
aria-checked="{{ $channel === $key ? 'true' : 'false' }}"
|
|
wire:click="confirmChannel('{{ $key }}')"
|
|
@class([
|
|
'inline-flex h-9 flex-1 items-center justify-center gap-1.5 rounded font-mono text-xs uppercase tracking-wider transition-colors',
|
|
'bg-accent/15 text-accent-text shadow-[inset_0_0_0_1px_var(--color-accent)]' => $channel === $key,
|
|
'text-ink-3 hover:bg-raised hover:text-ink-2' => $channel !== $key,
|
|
])>
|
|
@if ($channel === $key)<x-icon name="git-branch" class="h-3.5 w-3.5" />@endif{{ $key }}
|
|
</button>
|
|
@endforeach
|
|
</div>
|
|
|
|
{{-- Per-channel description --}}
|
|
<div class="flex items-start gap-3 rounded-md border border-line bg-raised/40 p-3">
|
|
<x-icon name="git-branch" class="mt-0.5 h-4 w-4 shrink-0 text-accent-text" />
|
|
<div class="min-w-0">
|
|
<p class="text-sm text-ink">{{ __('system.channel_current') }} <span class="font-mono text-accent-text">{{ $channel }}</span></p>
|
|
<p class="mt-0.5 font-mono text-[11px] text-ink-3">{{ $channels[$channel] ?? '' }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</x-panel>
|
|
</div>
|