Migrate to HTMX (#114)

Dropped Livewire
Added HTMX
Added Blade code lint
Drop Mysql and Redis
Migrate to SQLite
This commit is contained in:
Saeed Vaziry
2024-03-06 17:02:59 +01:00
committed by GitHub
parent 5b2c419e91
commit b2083fc6b2
486 changed files with 8609 additions and 8707 deletions

View File

@ -1,5 +1,5 @@
<x-app-layout>
<x-slot name="pageTitle">{{ __("Create Server") }}</x-slot>
<livewire:servers.create-server />
@include("servers.partials.create-server")
</x-app-layout>

View File

@ -1,5 +1,5 @@
<x-app-layout>
<x-slot name="pageTitle">{{ __("Servers") }}</x-slot>
<livewire:servers.servers-list />
@include("servers.partials.servers-list")
</x-app-layout>

View File

@ -1,5 +0,0 @@
<x-server-layout :server="$server">
<x-slot name="pageTitle">{{ $server->name }} Logs</x-slot>
<livewire:server-logs.logs-list :server="$server"/>
</x-server-layout>

View File

@ -0,0 +1,251 @@
<x-container x-data="">
<x-card>
<x-slot name="title">{{ __("Create new Server") }}</x-slot>
<x-slot name="description">
{{ __("Use this form to create a new server") }}
</x-slot>
@php
$oldProvider = old("provider", request()->input("provider") ?? "");
@endphp
<form
id="create-server-form"
hx-post="{{ route("servers.create") }}"
hx-swap="outerHTML"
hx-trigger="submit"
hx-select="#create-server-form"
hx-ext="disable-element"
hx-disable-element="#btn-create-server"
class="mt-6 space-y-6"
>
@csrf
<div>
<x-input-label>
{{ __("Select a server provider") }}
</x-input-label>
<div class="mt-1 grid grid-cols-6 gap-2">
@foreach (config("core.server_providers") as $p)
<x-server-provider-item
hx-get="{{ route('servers.create', ['provider' => $p]) }}"
hx-select="#create-server-form"
hx-target="#create-server-form"
:active="old('provider', $provider) == $p"
>
<div class="flex w-full flex-col items-center justify-center text-center">
<img src="{{ asset("static/images/" . $p . ".svg") }}" class="h-7" alt="Server" />
<span class="md:text-normal mt-2 hidden text-sm md:block">
{{ $p }}
</span>
</div>
</x-server-provider-item>
@endforeach
<input type="hidden" name="provider" value="{{ old("provider", $provider) }}" />
</div>
@error("provider")
<x-input-error class="mt-2" :messages="$message" />
@enderror
</div>
@if ($provider == "custom")
@include("servers.partials.public-key")
@else
<div>
<x-input-label for="server_provider" value="Provider Profile" />
<div class="mt-1 flex items-center">
<x-select-input id="server_provider" name="server_provider" class="w-full">
<option value="" disabled selected>
{{ __("Select") }}
</option>
@foreach ($serverProviders as $sp)
<option value="{{ $sp->id }}" @if($sp->id == old('server_provider')) selected @endif>
{{ $sp->profile }}
</option>
@endforeach
</x-select-input>
<x-secondary-button
:href="route('server-providers', ['provider' => $provider])"
class="ml-2 flex-none"
>
{{ __("Connect") }}
</x-secondary-button>
</div>
@error("server_provider")
<x-input-error class="mt-2" :messages="$message" />
@enderror
@if (count($serverProviders) == 0)
<x-input-error class="mt-2" :messages="__('You have not connected to any providers!')" />
@endif
</div>
@endif
<div>
<x-input-label for="name" :value="__('Name')" />
<x-text-input
value="{{ old('name') }}"
id="name"
name="name"
type="text"
class="mt-1 block w-full"
autocomplete="name"
/>
@error("name")
<x-input-error class="mt-2" :messages="$message" />
@enderror
</div>
@if ($provider !== "custom")
<div class="grid grid-cols-1 gap-3 lg:grid-cols-2">
<div>
<x-input-label for="plan" value="Plan" />
<x-select-input id="plan" name="plan" class="mt-1 w-full">
<option value="" disabled selected>
{{ __("Select") }}
</option>
@foreach (config("serverproviders")[$provider]["plans"] as $value)
<option
value="{{ $value["value"] }}"
@if($value['value'] == old('plan')) selected @endif
>
{{ $value["title"] }}
</option>
@endforeach
</x-select-input>
@error("plan")
<x-input-error class="mt-2" :messages="$message" />
@enderror
</div>
<div>
<x-input-label for="region" value="Region" />
<x-select-input id="region" name="region" class="mt-1 w-full">
<option value="" disabled selected>
{{ __("Select") }}
</option>
@foreach (config("serverproviders")[$provider]["regions"] as $key => $value)
<option
value="{{ $value["value"] }}"
@if($value['value'] == old('region')) selected @endif
>
{{ $value["title"] }}
</option>
@endforeach
</x-select-input>
@error("region")
<x-input-error class="mt-2" :messages="$message" />
@enderror
</div>
</div>
@endif
@if ($provider == "custom")
<div class="grid grid-cols-2 gap-3">
<div>
<x-input-label for="ip" :value="__('SSH IP Address')" />
<x-text-input
value="{{ old('ip') }}"
id="ip"
name="ip"
type="text"
class="mt-1 block w-full"
autocomplete="ip"
/>
@error("ip")
<x-input-error class="mt-2" :messages="$message" />
@enderror
</div>
<div>
<x-input-label for="port" :value="__('SSH Port')" />
<x-text-input
value="{{ old('port') }}"
id="port"
name="port"
type="text"
class="mt-1 block w-full"
autocomplete="port"
/>
@error("port")
<x-input-error class="mt-2" :messages="$message" />
@enderror
</div>
</div>
@endif
<div>
<x-input-label for="os" value="Operating System" />
<x-select-input id="os" name="os" class="mt-1 w-full">
@foreach (config("core.operating_systems") as $operatingSystem)
<option value="{{ $operatingSystem }}" @if($operatingSystem == old('os')) selected @endif>
{{ str($operatingSystem)->replace("_", " ")->ucfirst() }}
LTS
</option>
@endforeach
</x-select-input>
@error("os")
<x-input-error class="mt-2" :messages="$message" />
@enderror
</div>
<div>
<x-input-label for="type" value="Server Type" />
<x-select-input id="type" name="type" class="mt-1 w-full">
@foreach (config("core.server_types") as $serverType)
<option value="{{ $serverType }}" @if($serverType == old('type')) selected @endif>
{{ $serverType }}
</option>
@endforeach
</x-select-input>
@error("type")
<x-input-error class="mt-2" :messages="$message" />
@enderror
</div>
<div class="grid grid-cols-1 gap-3 lg:grid-cols-3">
<div>
<x-input-label for="webserver" value="Webserver" />
<x-select-input id="webserver" name="webserver" class="mt-1 w-full">
@foreach (config("core.webservers") as $ws)
<option value="{{ $ws }}" @if($ws == old('webserver')) selected @endif>
{{ $ws }}
</option>
@endforeach
</x-select-input>
@error("webserver")
<x-input-error class="mt-2" :messages="$message" />
@enderror
</div>
<div>
<x-input-label for="database" value="Database" />
<x-select-input id="database" name="database" class="mt-1 w-full">
@foreach (config("core.databases") as $db)
<option value="{{ $db }}" @if($db == old('database')) selected @endif>
{{ $db }}
</option>
@endforeach
</x-select-input>
@error("database")
<x-input-error class="mt-2" :messages="$message" />
@enderror
</div>
<div>
<x-input-label for="php" value="PHP" />
<x-select-input id="php" name="php" class="mt-1 w-full">
@foreach (config("core.php_versions") as $p)
<option value="{{ $p }}" @if($p == old('php')) selected @endif>
{{ $p }}
</option>
@endforeach
</x-select-input>
@error("php")
<x-input-error class="mt-2" :messages="$message" />
@enderror
</div>
</div>
</form>
<x-slot name="actions">
<x-primary-button id="btn-create-server" form="create-server-form">
{{ __("Create") }}
</x-primary-button>
</x-slot>
</x-card>
</x-container>

View File

@ -0,0 +1,12 @@
<div x-data="">
<x-danger-button x-on:click="$dispatch('open-modal', 'delete-server')">
{{ __("Delete Server") }}
</x-danger-button>
<x-confirmation-modal
name="delete-server"
action="{{ route('servers.delete', $server) }}"
:title="__('Confirm')"
:description="__('Are you sure that you want to delete this server?')"
method="delete"
/>
</div>

View File

@ -0,0 +1,15 @@
<x-card>
<x-slot name="title">
<span class="text-red-600">{{ __("Installation Failed!") }}</span>
</x-slot>
<x-slot name="description">
{{ __("Your server installation failed") }}
</x-slot>
<div class="text-center">
{{ __("The installation has been failed on step:") }}
<span class="font-bold">{{ $server->progress_step }} ({{ $server->progress }}%)</span>
</div>
<div class="mt-5 flex items-center justify-center">
@include("servers.partials.delete-server")
</div>
</x-card>

View File

@ -0,0 +1,22 @@
<x-card>
<x-slot name="title">{{ __("Installing") }}</x-slot>
<x-slot name="description">
{{ __("The server is being installed") }}
</x-slot>
<div
class="relative flex h-6 overflow-hidden rounded bg-primary-200 text-xs dark:bg-primary-500 dark:bg-opacity-10"
>
<div
style="width: {{ $server->progress }}%"
class="flex flex-col justify-center whitespace-nowrap bg-primary-500 text-center text-white shadow-none"
></div>
<span
class="{{ $server->progress >= 40 ? "text-white" : "text-black dark:text-white" }} absolute left-0 right-0 top-1 text-center font-semibold"
>
{{ $server->progress }}%
</span>
</div>
<div class="mt-3 text-center">
<span class="font-bold">{{ $server->progress_step }}</span>
</div>
</x-card>

View File

@ -0,0 +1,45 @@
@php
$key = str(file_get_contents(storage_path(config("core.ssh_public_key_name"))))->replace("\n", "");
@endphp
<div>
<div>
<div
class="rounded-sm border-l-4 border-yellow-500 bg-yellow-100 px-4 py-3 text-yellow-700 dark:bg-yellow-500 dark:bg-opacity-10 dark:text-yellow-500"
>
Your server needs to have a new unused installation of supported operating systems and must have a root
user. To get started, add our public key to /root/.ssh/authorized_keys file by running the bellow command on
your server as root.
</div>
</div>
</div>
<div>
<div class="flex items-center justify-between">
<x-input-label for="pk">
{{ __("Run this command on your server as root user") }}
</x-input-label>
<x-input-label
class="cursor-pointer"
x-data="{ copied: false }"
x-clipboard.raw="mkdir -p /root/.ssh && touch /root/.ssh/authorized_keys && echo '{{ $key }}' >> /root/.ssh/authorized_keys"
>
<div x-show="copied" class="flex items-center">
{{ __("Copied") }}
</div>
<div
x-show="!copied"
x-on:click="
copied = true
setTimeout(() => {
copied = false
}, 2000)
"
>
{{ __("Copy") }}
</div>
</x-input-label>
</div>
<x-textarea id="pk" name="pk" class="mt-1" rows="5" disabled>
mkdir -p /root/.ssh && touch /root/.ssh/authorized_keys && echo '{{ $key }}' >> /root/.ssh/authorized_keys
</x-textarea>
</div>

View File

@ -0,0 +1,88 @@
<div>
<x-card-header>
<x-slot name="title">
{{ __("Server Overview") }}
</x-slot>
<x-slot name="description">
{{ __("You can see an overview about your server here") }}
</x-slot>
</x-card-header>
<div
class="@if($server->webserver() && $server->database()) grid-cols-3 @else grid-cols-2 @endif mx-auto grid rounded-md border border-gray-200 bg-white dark:border-gray-700 dark:bg-gray-800"
>
@if ($server->webserver())
<div class="border-r border-gray-200 p-5 dark:border-gray-900">
<div class="flex items-center justify-center md:justify-start">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="h-8 w-8 text-primary-500"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 21a9.004 9.004 0 008.716-6.747M12 21a9.004 9.004 0 01-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 017.843 4.582M12 3a8.997 8.997 0 00-7.843 4.582m15.686 0A11.953 11.953 0 0112 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0121 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0112 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 013 12c0-1.605.42-3.113 1.157-4.418"
/>
</svg>
<div class="ml-2 hidden md:block">{{ __("Sites") }}</div>
</div>
<div class="mt-3 text-center text-3xl font-bold text-gray-600 dark:text-gray-400 md:text-left">
{{ $server->sites()->count() }}
</div>
</div>
@endif
@if ($server->database())
<div class="border-r border-gray-200 p-5 dark:border-gray-900">
<div class="flex items-center justify-center md:justify-start">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="h-8 w-8 text-primary-500"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125"
/>
</svg>
<div class="ml-2 hidden md:block">
{{ __("Databases") }}
</div>
</div>
<div class="mt-3 text-center text-3xl font-bold text-gray-600 dark:text-gray-400 md:text-left">
{{ $server->databases()->count() }}
</div>
</div>
@endif
<div class="p-5">
<div class="flex items-center justify-center md:justify-start">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="h-8 w-8 text-primary-500"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 6v6h4.5m4.5 0a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<div class="ml-2 hidden md:block">{{ __("Cron Jobs") }}</div>
</div>
<div class="mt-3 text-center text-3xl font-bold text-gray-600 dark:text-gray-400 md:text-left">
{{ $server->cronJobs()->count() }}
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,17 @@
<div>
@if ($server->status == \App\Enums\ServerStatus::READY)
<x-status status="success">{{ $server->status }}</x-status>
@endif
@if ($server->status == \App\Enums\ServerStatus::INSTALLING)
<x-status status="warning">{{ $server->status }}</x-status>
@endif
@if ($server->status == \App\Enums\ServerStatus::DISCONNECTED)
<x-status status="disabled">{{ $server->status }}</x-status>
@endif
@if ($server->status == \App\Enums\ServerStatus::INSTALLATION_FAILED)
<x-status status="danger">{{ $server->status }}</x-status>
@endif
</div>

View File

@ -0,0 +1,48 @@
<x-container>
<x-card-header>
<x-slot name="title">Servers</x-slot>
<x-slot name="description">Here you can see your servers list and manage them</x-slot>
<x-slot name="aside">
<x-primary-button :href="route('servers.create')">
{{ __("Create a Server") }}
</x-primary-button>
</x-slot>
</x-card-header>
<x-live id="live-servers-list">
@if (count($servers) > 0)
<div class="space-y-3">
@foreach ($servers as $server)
<a href="{{ route("servers.show", ["server" => $server]) }}" class="block">
<x-item-card>
<div class="flex-none">
<img
src="{{ asset("static/images/" . $server->provider . ".svg") }}"
class="h-10 w-10"
alt=""
/>
</div>
<div class="ml-3 flex flex-grow flex-col items-start justify-center">
<span class="mb-1">{{ $server->name }}</span>
<span class="text-sm text-gray-400">
{{ $server->ip }}
</span>
</div>
<div class="flex items-center">
<div class="inline">
@include("servers.partials.server-status", ["server" => $server])
</div>
</div>
</x-item-card>
</a>
@endforeach
</div>
@else
<x-simple-card>
<div class="text-center">
{{ __("You don't have any servers yet!") }}
</div>
</x-simple-card>
@endif
</x-live>
</x-container>

View File

@ -0,0 +1,19 @@
<div class="space-y-6">
<x-live id="live-server">
@if ($server->status === \App\Enums\ServerStatus::INSTALLING)
@include("servers.partials.installing", ["server" => $server])
@endif
@if ($server->status === \App\Enums\ServerStatus::INSTALLATION_FAILED)
@include("servers.partials.installation-failed", ["server" => $server])
@endif
@if (in_array($server->status, [\App\Enums\ServerStatus::READY, \App\Enums\ServerStatus::DISCONNECTED]))
<div class="space-y-10">
@include("servers.partials.server-overview", ["server" => $server])
</div>
@endif
</x-live>
@include("server-logs.partials.logs-list")
</div>

View File

@ -0,0 +1,15 @@
@if ($status == \App\Enums\ServerStatus::READY)
<x-status status="success">{{ $status }}</x-status>
@endif
@if ($status == \App\Enums\ServerStatus::INSTALLING)
<x-status status="warning">{{ $status }}</x-status>
@endif
@if ($status == \App\Enums\ServerStatus::DISCONNECTED)
<x-status status="disabled">{{ $status }}</x-status>
@endif
@if ($status == \App\Enums\ServerStatus::INSTALLATION_FAILED)
<x-status status="danger">{{ $status }}</x-status>
@endif

View File

@ -1,5 +1,5 @@
<x-server-layout :server="$server">
<x-slot name="pageTitle">{{ $server->name }}</x-slot>
<livewire:servers.show-server :server="$server" />
@include("servers.partials.show-server")
</x-server-layout>