CluPilotCloud/resources/views/livewire/admin/host-create.blade.php

154 lines
9.8 KiB
PHP

<div class="space-y-6">
{{-- Kopf wie auf der Einstellungsseite: Augenbraue, Titel, ein Satz
darunter. Die Seite hatte vorher einen Zurück-Link an dieser Stelle und
darunter eine sechsteilige Anleitung der Auftrag der Seite, vier
Felder auszufüllen, ging darin unter. --}}
<header class="animate-rise">
<p class="lbl">{{ __('hosts.takeover.eyebrow') }}</p>
<h1 class="mt-[7px] text-[23px] font-bold leading-[1.12] tracking-[-0.03em] text-ink min-[901px]:text-[30px]">
@if ($command === null)
{{ __('hosts.create_title') }}
@else
{{ __('hosts.takeover.title', ['name' => $createdName]) }}
@endif
</h1>
<p class="mt-2 max-w-[76ch] text-sm leading-relaxed text-muted">
{{ $command === null ? __('hosts.create_sub') : __('hosts.takeover.subtitle') }}
</p>
</header>
<div class="flex flex-col gap-6 lg:flex-row lg:items-start lg:gap-8">
{{-- Der Ablauf als Schiene, nicht als Wand. Sie beantwortet „wo stehe
ich" auf einen Blick und überlässt dem Hauptteil die Arbeit. --}}
<x-admin.takeover-rail :current="$command === null ? 3 : 4"
class="animate-rise [animation-delay:40ms]" />
<div class="min-w-0 flex-1 space-y-8 lg:max-w-[820px]">
@if ($command === null)
@if ($missingSettings)
<x-ui.alert variant="warning" class="animate-rise [animation-delay:60ms]">
<p class="font-medium">{{ __('hosts.takeover.missing_title') }}</p>
<p class="mt-1">{{ __('hosts.takeover.missing_body', ['settings' => implode(', ', $missingSettings)]) }}</p>
</x-ui.alert>
@endif
{{-- Die zwei Schritte beim Anbieter. Sie stehen VOR dem
Formular, weil sie vorher erledigt sein müssen: der
Einmal-Code beginnt mit dem Speichern abzulaufen. --}}
<section class="animate-rise [animation-delay:60ms]">
<h2 class="text-md font-bold tracking-[-0.01em] text-ink">{{ __('hosts.takeover.requirements_title') }}</h2>
<p class="mt-1 max-w-[70ch] text-sm leading-relaxed text-muted">{{ __('hosts.takeover.requirements_sub') }}</p>
<x-ui.panel class="mt-4">
<x-ui.row :label="__('hosts.takeover.s1_title')">
<p class="text-sm leading-relaxed text-muted">{{ __('hosts.takeover.s1_body') }}</p>
</x-ui.row>
<x-ui.row :label="__('hosts.takeover.s2_title')">
<p class="text-sm leading-relaxed text-muted">{{ __('hosts.takeover.s2_body') }}</p>
</x-ui.row>
</x-ui.panel>
</section>
<form wire:submit="save" class="animate-rise [animation-delay:80ms]">
<h2 class="text-md font-bold tracking-[-0.01em] text-ink">{{ __('hosts.takeover.form_title') }}</h2>
<p class="mt-1 max-w-[70ch] text-sm leading-relaxed text-muted">{{ __('hosts.takeover.form_sub') }}</p>
<x-ui.panel class="mt-4">
<x-ui.row :label="__('hosts.field.name')" :hint="__('hosts.field.name_hint')" for="name">
<x-ui.input name="name" wire:model="name" autofocus />
</x-ui.row>
<x-ui.row :label="__('hosts.field.datacenter')" for="datacenter">
<select id="datacenter" wire:model="datacenter"
class="block w-full rounded border border-line bg-surface px-3 py-2 text-sm text-ink transition">
{{-- The building too, where it is known: two
entries both reading "Falkenstein (fsn)" are
not a choice anybody can make, and placing a
second machine for redundancy is exactly when
it matters which hall it lands in. --}}
@foreach ($datacenters as $dc)
<option value="{{ $dc->code }}">{{ $dc->name }} ({{ $dc->code }})@if ($dc->facility) · {{ $dc->facility }}@endif</option>
@endforeach
</select>
@error('datacenter') <p class="mt-1 text-xs text-danger">{{ $message }}</p> @enderror
</x-ui.row>
<x-ui.row :label="__('hosts.field.public_ip')" for="public_ip">
<x-ui.input name="public_ip" wire:model="public_ip" inputmode="numeric" placeholder="203.0.113.10" />
</x-ui.row>
<x-ui.row :label="__('hosts.field.root_password')" :hint="__('hosts.field.root_password_hint')" for="root_password">
<x-ui.input name="root_password" wire:model="root_password" type="password" autocomplete="off" />
</x-ui.row>
</x-ui.panel>
<div class="mt-4 flex items-center justify-end gap-3">
<a href="{{ route('admin.hosts') }}" wire:navigate>
<x-ui.button variant="secondary" type="button">{{ __('hosts.cancel') }}</x-ui.button>
</a>
<x-ui.button variant="primary" type="submit" wire:loading.attr="disabled">
<span wire:loading.remove wire:target="save">{{ __('hosts.save') }}</span>
<span wire:loading wire:target="save">{{ __('hosts.save') }}…</span>
</x-ui.button>
</div>
</form>
@else
{{-- Ab hier ist die Befehlszeile die Hauptsache. Sie bekommt die
volle Breite und steht ganz oben; alles andere ordnet sich
unter. --}}
<section class="animate-rise [animation-delay:60ms]">
<h2 class="text-md font-bold tracking-[-0.01em] text-ink">{{ __('hosts.takeover.command_title') }}</h2>
<p class="mt-1 max-w-[70ch] text-sm leading-relaxed text-muted">{{ __('hosts.takeover.command_sub') }}</p>
<div x-data="{ copied: false }" class="mt-4 overflow-hidden rounded-lg border border-accent-border bg-surface shadow-xs">
<div class="flex items-center justify-between gap-3 border-b border-line bg-accent-subtle px-4 py-2.5">
<p class="min-w-0 text-xs font-medium text-accent-text">{{ __('hosts.takeover.once_title') }}</p>
<button type="button"
class="inline-flex shrink-0 items-center gap-1.5 rounded border border-line bg-surface px-2.5 py-1 text-xs font-medium text-body transition hover:text-ink"
x-on:click="navigator.clipboard.writeText($refs.command.textContent.trim()); copied = true; setTimeout(() => copied = false, 2000)">
<x-ui.icon name="copy" class="size-4" x-show="!copied" />
<x-ui.icon name="check" class="size-4" x-show="copied" x-cloak />
<span x-text="copied ? @js(__('hosts.takeover.copied')) : @js(__('hosts.takeover.copy'))">{{ __('hosts.takeover.copy') }}</span>
</button>
</div>
{{-- Umbrechen statt waagerecht rollen: aus einem Kasten
mit Rollbalken markiert jemand die Hälfte und merkt
es erst auf der Maschine. --}}
<pre class="max-h-64 overflow-y-auto px-4 py-3.5 font-mono text-xs leading-relaxed text-ink break-all whitespace-pre-wrap"
x-ref="command">{{ $command }}</pre>
</div>
<p class="mt-2 text-xs leading-relaxed text-muted">{{ __('hosts.takeover.once_body') }}</p>
</section>
<section class="animate-rise [animation-delay:80ms]">
<h2 class="text-md font-bold tracking-[-0.01em] text-ink">{{ __('hosts.takeover.after_title') }}</h2>
<x-ui.panel class="mt-4">
<x-ui.row :label="__('hosts.takeover.s5_title')">
<p class="text-sm leading-relaxed text-muted">{{ __('hosts.takeover.s5_body') }}</p>
<p class="mt-1 text-xs leading-relaxed text-muted">{{ __('hosts.takeover.s5_hint', ['url' => $archiveUrl]) }}</p>
</x-ui.row>
<x-ui.row :label="__('hosts.takeover.s6_title')">
<p class="text-sm leading-relaxed text-muted">{{ __('hosts.takeover.s6_body') }}</p>
<div class="mt-3">
<a href="{{ route('admin.hosts.show', ['host' => $createdUuid]) }}" wire:navigate>
<x-ui.button variant="primary" size="sm">
<x-slot:icon><x-ui.icon name="activity" class="size-4" /></x-slot:icon>
{{ __('hosts.takeover.watch') }}
</x-ui.button>
</a>
</div>
</x-ui.row>
</x-ui.panel>
</section>
@endif
<p class="max-w-[76ch] text-xs leading-relaxed text-muted animate-rise [animation-delay:100ms]">
{{ __('hosts.takeover.footnote') }}
</p>
</div>
</div>
</div>