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

127 lines
7.7 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 ($createdUuid === 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">
{{ $createdUuid === 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="$createdUuid === null ? 2 : 3"
class="animate-rise [animation-delay:40ms]" />
<div class="min-w-0 flex-1 space-y-8 lg:max-w-[820px]">
@if ($createdUuid === 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
{{-- Der eine Schritt beim Anbieter. Er steht VOR dem Formular,
weil er vorher erledigt sein muss: unmittelbar nach dem
Speichern meldet sich CluPilot an der Maschine an.
Hier standen zwei Zeilen — die zweite hieß „Rettungssystem
starten" und gehörte zum Bootstrap-Weg, den diese Seite
nicht geht. --}}
<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.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.datacenter')" for="datacenter">
<select id="datacenter" wire:model.live="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.name')" :hint="$previewFqdn ? __('hosts.field.name_hint', ['fqdn' => $previewFqdn]) : null">
{{-- Kein Feld mehr. Ein selbst getippter Name ist eine
Fehlerquelle ohne Gegenwert: er muss eindeutig
sein, DNS-tauglich, und er sagt nichts, was das
Rechenzentrum nicht schon sagt. --}}
<p class="font-mono text-sm font-semibold text-ink">{{ $previewName ?? __('hosts.unknown') }}</p>
</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" autofocus />
</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
{{-- Hier stand die Befehlszeile, die der Betreiber im
Rettungssystem einfügen sollte. Sie gehört zum
Bootstrap-Weg; beim Speichern läuft die
Provisionierungs-Pipeline, und die meldet sich selbst an.
Es gibt also nichts mehr zu kopieren nur noch etwas
anzusehen. --}}
<section class="animate-rise [animation-delay:60ms]">
<h2 class="text-md font-bold tracking-[-0.01em] text-ink">{{ __('hosts.takeover.s3_title') }}</h2>
<p class="mt-1 max-w-[70ch] text-sm leading-relaxed text-muted">{{ __('hosts.takeover.s3_body') }}</p>
<div class="mt-5">
<a href="{{ route('admin.hosts.show', ['host' => $createdUuid]) }}" wire:navigate>
<x-ui.button variant="primary">
<x-slot:icon><x-ui.icon name="activity" class="size-4" /></x-slot:icon>
{{ __('hosts.takeover.watch') }}
</x-ui.button>
</a>
</div>
</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>