Update UI elements and text content
This commit is contained in:
parent
6b49d32102
commit
fafc4fb71e
@ -2,22 +2,27 @@
|
||||
|
||||
namespace App\Livewire\Boarding;
|
||||
|
||||
use App\Actions\Server\InstallDocker;
|
||||
use App\Enums\ProxyTypes;
|
||||
use App\Models\PrivateKey;
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use App\Models\Team;
|
||||
use Illuminate\Support\Collection;
|
||||
use Livewire\Attributes\Url;
|
||||
use Livewire\Component;
|
||||
|
||||
class Index extends Component
|
||||
{
|
||||
protected $listeners = ['serverInstalled' => 'validateServer'];
|
||||
public string $currentState = 'welcome';
|
||||
|
||||
#[Url()]
|
||||
public string $state = 'welcome';
|
||||
|
||||
#[Url()]
|
||||
public ?string $selectedServerType = null;
|
||||
public ?Collection $privateKeys = null;
|
||||
|
||||
#[Url()]
|
||||
public ?int $selectedExistingPrivateKey = null;
|
||||
public ?string $privateKeyType = null;
|
||||
public ?string $privateKey = null;
|
||||
@ -27,6 +32,8 @@ class Index extends Component
|
||||
public ?PrivateKey $createdPrivateKey = null;
|
||||
|
||||
public ?Collection $servers = null;
|
||||
|
||||
#[Url()]
|
||||
public ?int $selectedExistingServer = null;
|
||||
public ?string $remoteServerName = null;
|
||||
public ?string $remoteServerDescription = null;
|
||||
@ -38,7 +45,9 @@ class Index extends Component
|
||||
public ?Server $createdServer = null;
|
||||
|
||||
public Collection $projects;
|
||||
public ?int $selectedExistingProject = null;
|
||||
|
||||
#[Url()]
|
||||
public ?int $selectedProject = null;
|
||||
public ?Project $createdProject = null;
|
||||
|
||||
public bool $dockerInstallationStarted = false;
|
||||
@ -62,13 +71,33 @@ public function mount()
|
||||
$this->remoteServerDescription = 'Created by Coolify';
|
||||
$this->remoteServerHost = 'coolify-testing-host';
|
||||
}
|
||||
if ($this->state === 'create-project') {
|
||||
$this->getProjects();
|
||||
}
|
||||
if ($this->state === 'create-resource') {
|
||||
$this->selectExistingServer();
|
||||
$this->selectExistingProject();
|
||||
}
|
||||
if ($this->state === 'private-key') {
|
||||
$this->setServerType('remote');
|
||||
}
|
||||
if ($this->state === 'create-server') {
|
||||
$this->selectExistingPrivateKey();
|
||||
}
|
||||
if ($this->state === 'validate-server') {
|
||||
$this->selectExistingServer();
|
||||
}
|
||||
if ($this->state === 'select-existing-server') {
|
||||
$this->selectExistingServer();
|
||||
}
|
||||
|
||||
}
|
||||
public function explanation()
|
||||
{
|
||||
if (isCloud()) {
|
||||
return $this->setServerType('remote');
|
||||
}
|
||||
$this->currentState = 'select-server-type';
|
||||
$this->state = 'select-server-type';
|
||||
}
|
||||
|
||||
public function restartBoarding()
|
||||
@ -89,6 +118,7 @@ public function setServerType(string $type)
|
||||
$this->selectedServerType = $type;
|
||||
if ($this->selectedServerType === 'localhost') {
|
||||
$this->createdServer = Server::find(0);
|
||||
$this->selectedExistingServer = 0;
|
||||
if (!$this->createdServer) {
|
||||
return $this->dispatch('error', 'Localhost server is not found. Something went wrong during installation. Please try to reinstall or contact support.');
|
||||
}
|
||||
@ -106,10 +136,10 @@ public function setServerType(string $type)
|
||||
$this->servers = Server::ownedByCurrentTeam(['name'])->where('id', '!=', 0)->get();
|
||||
if ($this->servers->count() > 0) {
|
||||
$this->selectedExistingServer = $this->servers->first()->id;
|
||||
$this->currentState = 'select-existing-server';
|
||||
$this->state = 'select-existing-server';
|
||||
return;
|
||||
}
|
||||
$this->currentState = 'private-key';
|
||||
$this->state = 'private-key';
|
||||
}
|
||||
}
|
||||
public function selectExistingServer()
|
||||
@ -117,12 +147,12 @@ public function selectExistingServer()
|
||||
$this->createdServer = Server::find($this->selectedExistingServer);
|
||||
if (!$this->createdServer) {
|
||||
$this->dispatch('error', 'Server is not found.');
|
||||
$this->currentState = 'private-key';
|
||||
$this->state = 'private-key';
|
||||
return;
|
||||
}
|
||||
$this->selectedExistingPrivateKey = $this->createdServer->privateKey->id;
|
||||
$this->serverPublicKey = $this->createdServer->privateKey->publicKey();
|
||||
$this->currentState = 'validate-server';
|
||||
$this->state = 'validate-server';
|
||||
}
|
||||
public function getProxyType()
|
||||
{
|
||||
@ -130,7 +160,7 @@ public function getProxyType()
|
||||
$this->selectProxy(ProxyTypes::TRAEFIK_V2->value);
|
||||
// $proxyTypeSet = $this->createdServer->proxy->type;
|
||||
// if (!$proxyTypeSet) {
|
||||
// $this->currentState = 'select-proxy';
|
||||
// $this->state = 'select-proxy';
|
||||
// return;
|
||||
// }
|
||||
$this->getProjects();
|
||||
@ -139,12 +169,12 @@ public function selectExistingPrivateKey()
|
||||
{
|
||||
$this->createdPrivateKey = PrivateKey::find($this->selectedExistingPrivateKey);
|
||||
$this->privateKey = $this->createdPrivateKey->private_key;
|
||||
$this->currentState = 'create-server';
|
||||
$this->state = 'create-server';
|
||||
}
|
||||
public function createNewServer()
|
||||
{
|
||||
$this->selectedExistingServer = null;
|
||||
$this->currentState = 'private-key';
|
||||
$this->state = 'private-key';
|
||||
}
|
||||
public function setPrivateKey(string $type)
|
||||
{
|
||||
@ -153,7 +183,7 @@ public function setPrivateKey(string $type)
|
||||
if ($type === 'create') {
|
||||
$this->createNewPrivateKey();
|
||||
}
|
||||
$this->currentState = 'create-private-key';
|
||||
$this->state = 'create-private-key';
|
||||
}
|
||||
public function savePrivateKey()
|
||||
{
|
||||
@ -168,7 +198,7 @@ public function savePrivateKey()
|
||||
'team_id' => currentTeam()->id
|
||||
]);
|
||||
$this->createdPrivateKey->save();
|
||||
$this->currentState = 'create-server';
|
||||
$this->state = 'create-server';
|
||||
}
|
||||
public function saveServer()
|
||||
{
|
||||
@ -196,7 +226,8 @@ public function saveServer()
|
||||
$this->createdServer->settings->is_cloudflare_tunnel = $this->isCloudflareTunnel;
|
||||
$this->createdServer->settings->save();
|
||||
$this->createdServer->addInitialNetwork();
|
||||
$this->currentState = 'validate-server';
|
||||
$this->selectedExistingServer = $this->createdServer->id;
|
||||
$this->state = 'validate-server';
|
||||
}
|
||||
public function installServer()
|
||||
{
|
||||
@ -223,7 +254,7 @@ public function validateServer()
|
||||
$dockerVersion = instant_remote_process(["docker version|head -2|grep -i version| awk '{print $2}'"], $this->createdServer, true);
|
||||
$dockerVersion = checkMinimumDockerEngineVersion($dockerVersion);
|
||||
if (is_null($dockerVersion)) {
|
||||
$this->currentState = 'validate-server';
|
||||
$this->state = 'validate-server';
|
||||
throw new \Exception('Docker not found or old version is installed.');
|
||||
}
|
||||
$this->createdServer->settings()->update([
|
||||
@ -249,14 +280,14 @@ public function getProjects()
|
||||
{
|
||||
$this->projects = Project::ownedByCurrentTeam(['name'])->get();
|
||||
if ($this->projects->count() > 0) {
|
||||
$this->selectedExistingProject = $this->projects->first()->id;
|
||||
$this->selectedProject = $this->projects->first()->id;
|
||||
}
|
||||
$this->currentState = 'create-project';
|
||||
$this->state = 'create-project';
|
||||
}
|
||||
public function selectExistingProject()
|
||||
{
|
||||
$this->createdProject = Project::find($this->selectedExistingProject);
|
||||
$this->currentState = 'create-resource';
|
||||
$this->createdProject = Project::find($this->selectedProject);
|
||||
$this->state = 'create-resource';
|
||||
}
|
||||
public function createNewProject()
|
||||
{
|
||||
@ -264,7 +295,7 @@ public function createNewProject()
|
||||
'name' => "My first project",
|
||||
'team_id' => currentTeam()->id
|
||||
]);
|
||||
$this->currentState = 'create-resource';
|
||||
$this->state = 'create-resource';
|
||||
}
|
||||
public function showNewResource()
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ protected function rules() {
|
||||
}
|
||||
|
||||
public function mount() {
|
||||
$this->oauth_settings_map = OauthSetting::all()->reduce(function($carry, $setting) {
|
||||
$this->oauth_settings_map = OauthSetting::all()->sortBy('provider')->reduce(function($carry, $setting) {
|
||||
$carry[$setting->provider] = $setting;
|
||||
return $carry;
|
||||
}, []);
|
||||
|
@ -9,7 +9,7 @@
|
||||
"auth.confirm_password": "Confirm password",
|
||||
"auth.forgot_password": "Forgot password",
|
||||
"auth.forgot_password_send_email": "Send password reset email",
|
||||
"auth.register_now": "Register a new account",
|
||||
"auth.register_now": "Register",
|
||||
"auth.logout": "Logout",
|
||||
"auth.register": "Register",
|
||||
"auth.registration_disabled": "Registration is disabled. Please contact the administrator.",
|
||||
|
@ -11,6 +11,9 @@ body {
|
||||
@apply text-sm antialiased scrollbar;
|
||||
}
|
||||
|
||||
.button {
|
||||
@apply px-3 py-1.5 text-sm font-normal normal-case rounded bg-neutral-200 hover:bg-neutral-300 dark:bg-coolgray-200 dark:text-white dark:hover:bg-coolgray-100 dark:disabled:bg-coolgray-100/40 dark:disabled:text-neutral-800 min-w-fit flex items-center justify-center;
|
||||
}
|
||||
button[isError]:not(:disabled) {
|
||||
@apply bg-red-600 hover:bg-red-700;
|
||||
}
|
||||
@ -19,9 +22,7 @@ button[isHighlighted]:not(:disabled) {
|
||||
@apply bg-coollabs hover:bg-coollabs-100;
|
||||
}
|
||||
|
||||
.button {
|
||||
@apply px-3 py-1.5 text-sm font-normal normal-case rounded dark:bg-coolgray-200 dark:text-white dark:hover:bg-coolgray-100 dark:disabled:bg-coolgray-100/40 dark:disabled:text-neutral-800 min-w-fit flex items-center justify-center;
|
||||
}
|
||||
|
||||
|
||||
h1 {
|
||||
@apply text-2xl font-bold dark:text-white text-neutral-800;
|
||||
@ -82,6 +83,7 @@ tr td:first-child {
|
||||
input {
|
||||
@apply pr-10;
|
||||
}
|
||||
|
||||
.input {
|
||||
@apply block w-full py-1.5 rounded border-0 text-sm ring-inset ring-1 dark:bg-coolgray-100 dark:text-white text-black focus:ring-2 dark:focus:ring-coolgray-300 dark:ring-coolgray-300 dark:read-only:text-neutral-500 dark:read-only:ring-0 dark:read-only:bg-coolgray-100/40 dark:placeholder:text-neutral-700;
|
||||
}
|
||||
@ -89,12 +91,15 @@ .input {
|
||||
option {
|
||||
@apply text-white;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
@apply flex items-center gap-2 text-success;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
@apply flex items-center gap-2 text-error;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
@apply relative flex cursor-pointer select-none dark:hover:text-white dark:hover:bg-coollabs items-center px-2 py-1.5 text-xs justify-center outline-none transition-colors data-[disabled]:pointer-events-none data-[disabled]:opacity-50 gap-2
|
||||
}
|
||||
@ -115,8 +120,6 @@ .badge-error {
|
||||
@apply bg-error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[type='checkbox']:checked {
|
||||
background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='black' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
|
||||
}
|
||||
@ -126,11 +129,11 @@ .menu {
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
@apply flex items-center w-full gap-2 px-4 py-1 min-w-48 hover:bg-coolgray-100 dark:hover:text-white;
|
||||
@apply flex items-center w-full gap-2 py-1 pl-2 dark:hover:bg-coolgray-100 dark:hover:text-white hover:bg-neutral-300;
|
||||
}
|
||||
|
||||
.menu-item-active {
|
||||
@apply rounded-none dark:bg-coolgray-200 dark:text-warning;
|
||||
@apply text-black rounded-none dark:bg-coolgray-200 dark:text-warning bg-neutral-200;
|
||||
}
|
||||
|
||||
.icon {
|
||||
@ -170,15 +173,21 @@ .icon:hover {
|
||||
}
|
||||
|
||||
.box {
|
||||
@apply flex p-2 transition-colors cursor-pointer min-h-[4rem] bg-coolgray-100 hover:bg-coollabs-100 hover:text-white hover:no-underline;
|
||||
@apply flex p-2 transition-colors cursor-pointer min-h-[4rem] dark:bg-coolgray-100 bg-neutral-50 hover:bg-neutral-200 dark:hover:bg-coollabs-100 dark:hover:text-white hover:no-underline;
|
||||
}
|
||||
|
||||
.box-without-bg {
|
||||
@apply flex p-2 transition-colors hover:text-white hover:no-underline min-h-[4rem];
|
||||
@apply flex p-2 transition-colors dark:hover:text-white hover:no-underline min-h-[4rem];
|
||||
}
|
||||
|
||||
.box-title {
|
||||
@apply font-bold text-black dark:text-white group-hover:dark:text-white;
|
||||
}
|
||||
.box-description {
|
||||
@apply text-xs font-bold text-neutral-500 group-hover:dark:text-white group-hover:text-black;
|
||||
}
|
||||
.description {
|
||||
@apply text-xs font-bold text-neutral-500 group-hover:text-white;
|
||||
@apply text-xs font-bold text-neutral-500 group-hover:dark:text-white group-hover:text-black;
|
||||
}
|
||||
|
||||
.lds-heart {
|
||||
@ -224,8 +233,9 @@ .buyme {
|
||||
}
|
||||
|
||||
.title {
|
||||
@apply hidden pb-0 lg:block lg:pb-8 ;
|
||||
@apply hidden pb-0 lg:block lg:pb-8;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
@apply pt-2 pb-10;
|
||||
}
|
||||
@ -237,4 +247,3 @@ .fullscreen {
|
||||
.toast {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
|
@ -1,29 +1,15 @@
|
||||
<x-layout-simple>
|
||||
<div class="min-h-screen hero">
|
||||
<div class="w-96 min-w-fit">
|
||||
<div class="flex flex-col items-center pb-8">
|
||||
<div class="text-5xl font-extrabold tracking-tight text-center text-white">Coolify</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<h1>{{ __('auth.login') }}</h1>
|
||||
@if ($is_registration_enabled)
|
||||
@if (config('coolify.waitlist'))
|
||||
<a href="/waitlist"
|
||||
class="text-xs text-center text-white normal-case bg-transparent border-none rounded no-animation hover:no-underline btn btn-sm bg-coollabs-gradient">
|
||||
Join the waitlist
|
||||
</a>
|
||||
@else
|
||||
<a href="/register"
|
||||
class="text-xs text-center text-white normal-case bg-transparent border-none rounded no-animation hover:no-underline btn btn-sm bg-coollabs-gradient">
|
||||
{{ __('auth.register_now') }}
|
||||
</a>
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
<form action="/login" method="POST" class="flex flex-col gap-2">
|
||||
@csrf
|
||||
@env('local')
|
||||
<section class="bg-gray-50 dark:bg-base">
|
||||
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0">
|
||||
<a class="flex items-center mb-6 text-5xl font-extrabold tracking-tight text-gray-900 dark:text-white">
|
||||
Coolify
|
||||
</a>
|
||||
<div
|
||||
class="w-full bg-white rounded shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-base dark:border-coolgray-200">
|
||||
<div class="p-6 space-y-4 md:space-y-6 sm:p-8">
|
||||
<form action="/login" method="POST" class="flex flex-col gap-2">
|
||||
@csrf
|
||||
@env('local')
|
||||
<x-forms.input value="test@example.com" type="email" name="email" required
|
||||
label="{{ __('input.email') }}" autofocus />
|
||||
|
||||
@ -33,40 +19,59 @@ class="text-xs text-center text-white normal-case bg-transparent border-none rou
|
||||
{{ __('auth.forgot_password') }}?
|
||||
</a>
|
||||
@else
|
||||
<x-forms.input type="email" name="email" required label="{{ __('input.email') }}" autofocus />
|
||||
<x-forms.input type="email" name="email" required label="{{ __('input.email') }}"
|
||||
autofocus />
|
||||
<x-forms.input type="password" name="password" required label="{{ __('input.password') }}" />
|
||||
<a href="/forgot-password" class="text-xs">
|
||||
{{ __('auth.forgot_password') }}?
|
||||
</a>
|
||||
@endenv
|
||||
<x-forms.button type="submit">{{ __('auth.login') }}</x-forms.button>
|
||||
@foreach ($enabled_oauth_providers as $provider_setting)
|
||||
<x-forms.button type="button" onclick="document.location.href='/auth/{{$provider_setting->provider}}/redirect'">
|
||||
{{ __("auth.login.$provider_setting->provider") }}
|
||||
</x-forms.button>
|
||||
@endforeach
|
||||
@if (!$is_registration_enabled)
|
||||
<div class="text-center ">{{ __('auth.registration_disabled') }}</div>
|
||||
@endif
|
||||
@if ($errors->any())
|
||||
<div class="text-xs text-center text-error">
|
||||
@foreach ($errors->all() as $error)
|
||||
<p>{{ $error }}</p>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
@if (session('status'))
|
||||
<div class="mb-4 font-medium text-green-600">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
@if (session('error'))
|
||||
<div class="mb-4 font-medium text-red-600">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
</form>
|
||||
@endenv
|
||||
<x-forms.button class="mt-10" type="submit">{{ __('auth.login') }}</x-forms.button>
|
||||
@if ($is_registration_enabled)
|
||||
<a href="/register"
|
||||
class="button bg-coollabs-gradient">
|
||||
{{ __('auth.register_now') }}
|
||||
</a>
|
||||
@endif
|
||||
@if ($enabled_oauth_providers->isNotEmpty())
|
||||
<div class="relative">
|
||||
<div class="absolute inset-0 flex items-center" aria-hidden="true">
|
||||
<div class="w-full border-t dark:border-coolgray-200"></div>
|
||||
</div>
|
||||
<div class="relative flex justify-center">
|
||||
<span class="px-2 text-sm dark:text-neutral-500 dark:bg-base">or</span>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@foreach ($enabled_oauth_providers as $provider_setting)
|
||||
<x-forms.button type="button"
|
||||
onclick="document.location.href='/auth/{{ $provider_setting->provider }}/redirect'">
|
||||
{{ __("auth.login.$provider_setting->provider") }}
|
||||
</x-forms.button>
|
||||
@endforeach
|
||||
@if (!$is_registration_enabled)
|
||||
<div class="text-center text-neutral-500">{{ __('auth.registration_disabled') }}</div>
|
||||
@endif
|
||||
@if ($errors->any())
|
||||
<div class="text-xs text-center text-error">
|
||||
@foreach ($errors->all() as $error)
|
||||
<p>{{ $error }}</p>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
@if (session('status'))
|
||||
<div class="mb-4 font-medium text-green-600">
|
||||
{{ session('status') }}
|
||||
</div>
|
||||
@endif
|
||||
@if (session('error'))
|
||||
<div class="mb-4 font-medium text-red-600">
|
||||
{{ session('error') }}
|
||||
</div>
|
||||
@endif
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</x-layout-simple>
|
||||
|
@ -1,48 +1,53 @@
|
||||
<x-layout-simple>
|
||||
<div class="flex items-center justify-center min-h-screen ">
|
||||
<div class="w-1/2">
|
||||
<div class="flex flex-col items-center pb-8">
|
||||
<div class="text-5xl font-bold tracking-tight text-center text-white">Coolify</div>
|
||||
<x-version />
|
||||
<section class="bg-gray-50 dark:bg-base">
|
||||
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0">
|
||||
<a class="flex items-center mb-6 text-5xl font-extrabold tracking-tight text-gray-900 dark:text-white">
|
||||
Coolify
|
||||
</a>
|
||||
<div
|
||||
class="w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-base dark:border-coolgray-200">
|
||||
<div class="p-6 space-y-4 md:space-y-6 sm:p-8">
|
||||
<h1 class="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white">
|
||||
Create an account
|
||||
</h1>
|
||||
<form action="/register" method="POST" class="flex flex-col gap-2">
|
||||
@csrf
|
||||
@env('local')
|
||||
<x-forms.input required value="test3 normal user" type="text" name="name"
|
||||
label="{{ __('input.name') }}" />
|
||||
<x-forms.input required value="test3@example.com" type="email" name="email"
|
||||
label="{{ __('input.email') }}" />
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required value="password" type="password" name="password"
|
||||
label="{{ __('input.password') }}" />
|
||||
<x-forms.input required value="password" type="password" name="password_confirmation"
|
||||
label="{{ __('input.password.again') }}" />
|
||||
</div>
|
||||
@else
|
||||
<x-forms.input required type="text" name="name" label="{{ __('input.name') }}" />
|
||||
<x-forms.input required type="email" name="email" label="{{ __('input.email') }}" />
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required type="password" name="password"
|
||||
label="{{ __('input.password') }}" />
|
||||
<x-forms.input required type="password" name="password_confirmation"
|
||||
label="{{ __('input.password.again') }}" />
|
||||
</div>
|
||||
@endenv
|
||||
<x-forms.button class="mb-4" type="submit">Register</x-forms.button>
|
||||
<a href="/login" class="button bg-coollabs-gradient">
|
||||
{{ __('auth.already_registered') }}
|
||||
</a>
|
||||
</form>
|
||||
@if ($errors->any())
|
||||
<div class="text-xs text-center text-error">
|
||||
@foreach ($errors->all() as $error)
|
||||
<p>{{ $error }}</p>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<h1>{{ __('auth.register') }}</h1>
|
||||
<a href="/login"
|
||||
class="text-xs text-center text-white normal-case bg-transparent border-none rounded no-animation hover:no-underline btn btn-sm bg-coollabs-gradient">
|
||||
{{ __('auth.already_registered') }}
|
||||
</a>
|
||||
</div>
|
||||
<form action="/register" method="POST" class="flex flex-col gap-2">
|
||||
@csrf
|
||||
@env('local')
|
||||
<x-forms.input required value="test3 normal user" type="text" name="name"
|
||||
label="{{ __('input.name') }}" />
|
||||
<x-forms.input required value="test3@example.com" type="email" name="email"
|
||||
label="{{ __('input.email') }}" />
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required value="password" type="password" name="password"
|
||||
label="{{ __('input.password') }}" />
|
||||
<x-forms.input required value="password" type="password" name="password_confirmation"
|
||||
label="{{ __('input.password.again') }}" />
|
||||
</div>
|
||||
@else
|
||||
<x-forms.input required type="text" name="name" label="{{ __('input.name') }}" />
|
||||
<x-forms.input required type="email" name="email" label="{{ __('input.email') }}" />
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required type="password" name="password" label="{{ __('input.password') }}" />
|
||||
<x-forms.input required type="password" name="password_confirmation"
|
||||
label="{{ __('input.password.again') }}" />
|
||||
</div>
|
||||
@endenv
|
||||
<x-forms.button type="submit">{{ __('auth.register') }}</x-forms.button>
|
||||
</form>
|
||||
@if ($errors->any())
|
||||
<div class="text-xs text-center text-error">
|
||||
@foreach ($errors->all() as $error)
|
||||
<p>{{ $error }}</p>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</x-layout-simple>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
|
||||
<div class="box-border col-span-2 min-w-[24rem] min-h-[21rem]">
|
||||
<h1 class="text-5xl font-bold">{{ $title }}</h1>
|
||||
<div class="py-6 ">
|
||||
<div class="py-6">
|
||||
@isset($question)
|
||||
<p class="text-base">
|
||||
<p class="text-base dark:text-neutral-400">
|
||||
{{ $question }}
|
||||
</p>
|
||||
@endisset
|
||||
|
@ -1 +1 @@
|
||||
<span class="inline-block text-warning">{{ $text }}</span>
|
||||
<span class="inline-block font-bold text-warning">{{ $text }}</span>
|
||||
|
@ -1,5 +1,6 @@
|
||||
@props(['text' => null])
|
||||
<div class="inline-flex items-center justify-center" {{ $attributes }}>
|
||||
<div>{{ $text }}</div>
|
||||
<svg class="w-4 h-4 mx-1 ml-3 text-warning animate-spin" xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
@ -7,5 +8,4 @@
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">
|
||||
</path>
|
||||
</svg>
|
||||
<div>{{ $text }}</div>
|
||||
</div>
|
||||
|
@ -1,11 +1,14 @@
|
||||
<div class="flex items-center h-16 pt-2 lg:pt-4 shrink-0">
|
||||
<a href="/" class="flex items-center w-12 h-12 -mx-1 text-xl font-bold text-white"><img
|
||||
class="transition rounded " src="{{ asset('coolify-transparent.png') }}"></a>
|
||||
</div>
|
||||
<nav class="flex flex-col flex-1">
|
||||
<nav class="flex flex-col flex-1 pl-4 border-r dark:border-coolgray-300 dark:bg-coolgray-100 bg-neutral-50">
|
||||
<div class="flex w-full px-2 pt-6 pb-4">
|
||||
<div class="flex flex-col">
|
||||
<div class="text-2xl font-bold tracking-wide dark:text-white">Coolify</div>
|
||||
<x-version />
|
||||
</div>
|
||||
<button onclick="changeTheme()">Dark/light</button>
|
||||
</div>
|
||||
<ul role="list" class="flex flex-col flex-1 gap-y-7">
|
||||
<li class="flex-1">
|
||||
<ul role="list" class="flex flex-col h-full -mx-2 space-y-1">
|
||||
<li class="flex-1 ">
|
||||
<ul role="list" class="flex flex-col h-full space-y-1.5">
|
||||
<li>
|
||||
<a title="Dashboard" href="/"
|
||||
class="{{ request()->is('/') ? 'menu-item-active menu-item' : 'menu-item' }}">
|
||||
@ -278,8 +281,8 @@ class="flex h-6 w-6 shrink-0 items-center justify-center rounded-lg border text-
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li> --}}
|
||||
{{-- <li class="mt-auto -mx-6">
|
||||
</li>
|
||||
<li class="mt-auto -mx-6">
|
||||
<a href="#"
|
||||
class="flex items-center px-6 py-3 text-sm font-semibold leading-6 text-gray-900 gap-x-4 hover:bg-gray-50">
|
||||
<img class="w-8 h-8 rounded-full bg-gray-50"
|
||||
|
@ -1,2 +1,2 @@
|
||||
<a {{ $attributes->merge(['class' => 'text-xs cursor-pointer opacity-60 hover:opacity-100 hover:text-white z-[60]']) }}
|
||||
<a {{ $attributes->merge(['class' => 'text-xs cursor-pointer opacity-60 hover:opacity-100 dark:hover:text-white hover:text-black z-[60]']) }}
|
||||
href="https://github.com/coollabsio/coolify/releases/tag/v{{ config('version') }}">v{{ config('version') }}</a>
|
||||
|
@ -10,7 +10,7 @@
|
||||
<div class="relative z-50 lg:hidden" :class="open ? 'block' : 'hidden'" role="dialog" aria-modal="true">
|
||||
<div class="fixed inset-0 bg-black/80"></div>
|
||||
<div class="fixed inset-0 flex">
|
||||
<div class="relative flex flex-1 w-full mr-16 max-w-56 ">
|
||||
<div class="relative flex flex-1 w-full mr-16 max-w-48 ">
|
||||
<div class="absolute top-0 flex justify-center w-16 pt-5 left-full">
|
||||
<button type="button" class="-m-2.5 p-2.5" x-on:click="open = !open">
|
||||
<span class="sr-only">Close sidebar</span>
|
||||
@ -21,21 +21,20 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col px-6 pb-2 overflow-y-auto dark:bg-coolgray-100 gap-y-5 scrollbar">
|
||||
<div class="flex flex-col pb-2 overflow-y-auto min-w-48 dark:bg-coolgray-100 gap-y-5 scrollbar">
|
||||
<x-navbar />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hidden lg:fixed lg:inset-y-0 lg:z-50 lg:flex lg:w-56 lg:flex-col">
|
||||
<div class="flex flex-col px-4 overflow-y-auto grow gap-y-5 scrollbar">
|
||||
<div class="hidden lg:fixed lg:inset-y-0 lg:z-50 lg:flex lg:w-48 lg:flex-col">
|
||||
<div class="flex flex-col overflow-y-auto grow gap-y-5 scrollbar">
|
||||
<x-navbar />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="sticky top-0 z-40 flex items-center px-4 py-4 gap-x-6 sm:px-6 lg:hidden">
|
||||
<div class="sticky top-0 z-40 flex items-center px-4 py-4 gap-x-6 sm:px-6 lg:hidden">
|
||||
<button type="button" class="-m-2.5 p-2.5 dark:text-warning lg:hidden" x-on:click="open = !open">
|
||||
<span class="sr-only">Open sidebar</span>
|
||||
<svg class="w-6 h-6" xmlns="http://www.w3.org/2000/svg" width="200" height="200" viewBox="0 0 24 24">
|
||||
@ -52,7 +51,7 @@ class="sticky top-0 z-40 flex items-center px-4 py-4 gap-x-6 sm:px-6 lg:hidden">
|
||||
</a> --}}
|
||||
</div>
|
||||
|
||||
<main class="lg:pl-56">
|
||||
<main class="lg:pl-48">
|
||||
<div>
|
||||
<div class="p-4 sm:px-6 lg:px-8 lg:py-6">
|
||||
{{ $slot }}
|
||||
|
@ -38,10 +38,9 @@
|
||||
@section('body')
|
||||
|
||||
<body>
|
||||
{{-- <button onclick="changeTheme()" class="fixed z-50 left-52">Dark/light</button> --}}
|
||||
@livewire('wire-elements-modal')
|
||||
<x-toast />
|
||||
<x-version class="fixed left-7 bottom-1" />
|
||||
{{-- <x-version class="fixed left-7 bottom-1" /> --}}
|
||||
<script data-navigate-once>
|
||||
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia(
|
||||
'(prefers-color-scheme: dark)').matches)) {
|
||||
|
@ -1,350 +1,335 @@
|
||||
@php use App\Enums\ProxyTypes; @endphp
|
||||
<div>
|
||||
<div>
|
||||
@if ($currentState === 'welcome')
|
||||
<section class="bg-gray-50 dark:bg-base">
|
||||
<div class="flex flex-col items-center justify-center px-6 py-8 mx-auto max-w-7xl md:h-screen lg:py-0">
|
||||
@if ($state === 'welcome')
|
||||
<h1 class="text-5xl font-bold">Welcome to Coolify</h1>
|
||||
<p class="py-6 text-xl text-center">Let me help you set up the basics.</p>
|
||||
<div class="flex justify-center ">
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="$set('currentState','explanation')">Get
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="$set('state','explanation')">Get
|
||||
Started
|
||||
</x-forms.button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'explanation')
|
||||
<x-boarding-step title="What is Coolify?">
|
||||
<x-slot:question>
|
||||
Coolify is an all-in-one application to automate tasks on your servers, deploy application with Git
|
||||
integrations, deploy databases and services, monitor these resources with notifications and alerts
|
||||
without vendor lock-in
|
||||
and <a href="https://coolify.io" class="text-white hover:underline">much much more</a>.
|
||||
<br><br>
|
||||
<span class="text-xl">
|
||||
<x-highlighted text="Self-hosting with superpowers!" /></span>
|
||||
</x-slot:question>
|
||||
<x-slot:explanation>
|
||||
<p><x-highlighted text="Task automation:" /> You don't need to manage your servers anymore. Coolify does
|
||||
it for you.</p>
|
||||
<p><x-highlighted text="No vendor lock-in:" /> All configurations are stored on your servers, so
|
||||
everything works without a connection to Coolify (except integrations and automations).</p>
|
||||
<p><x-highlighted text="Monitoring:" />You can get notified on your favourite platforms (Discord,
|
||||
Telegram, Email, etc.) when something goes wrong, or an action is needed from your side.</p>
|
||||
</x-slot:explanation>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="explanation">Next
|
||||
</x-forms.button>
|
||||
</x-slot:actions>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
@if ($currentState === 'select-server-type')
|
||||
<x-boarding-step title="Server">
|
||||
<x-slot:question>
|
||||
Do you want to deploy your resources to your <x-highlighted text="Localhost" />
|
||||
or to a <x-highlighted text="Remote Server" />?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:target="setServerType('localhost')"
|
||||
wire:click="setServerType('localhost')">Localhost
|
||||
</x-forms.button>
|
||||
<div>
|
||||
@if ($state === 'explanation')
|
||||
<x-boarding-step title="What is Coolify?">
|
||||
<x-slot:question>
|
||||
Coolify is an all-in-one application to automate tasks on your servers, deploy application with
|
||||
Git
|
||||
integrations, deploy databases and services, monitor these resources with notifications and
|
||||
alerts
|
||||
without vendor lock-in
|
||||
and <a href="https://coolify.io" class="text-white hover:underline">much much more</a>.
|
||||
<br><br>
|
||||
<span class="text-xl">
|
||||
<x-highlighted text="Self-hosting with superpowers!" /></span>
|
||||
</x-slot:question>
|
||||
<x-slot:explanation>
|
||||
<p><x-highlighted text="Task automation:" /> You don't need to manage your servers anymore.
|
||||
Coolify does
|
||||
it for you.</p>
|
||||
<p><x-highlighted text="No vendor lock-in:" /> All configurations are stored on your servers, so
|
||||
everything works without a connection to Coolify (except integrations and automations).</p>
|
||||
<p><x-highlighted text="Monitoring:" />You can get notified on your favourite platforms
|
||||
(Discord,
|
||||
Telegram, Email, etc.) when something goes wrong, or an action is needed from your side.</p>
|
||||
</x-slot:explanation>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="explanation">Next
|
||||
</x-forms.button>
|
||||
</x-slot:actions>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
@if ($state === 'select-server-type')
|
||||
<x-boarding-step title="Server">
|
||||
<x-slot:question>
|
||||
Do you want to deploy your resources to your <x-highlighted text="Localhost" />
|
||||
or to a <x-highlighted text="Remote Server" />?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:target="setServerType('localhost')"
|
||||
wire:click="setServerType('localhost')">Localhost
|
||||
</x-forms.button>
|
||||
|
||||
<x-forms.button class="justify-center w-64 box " wire:target="setServerType('remote')"
|
||||
wire:click="setServerType('remote')">Remote Server
|
||||
</x-forms.button>
|
||||
@if (!$serverReachable)
|
||||
Localhost is not reachable with the following public key.
|
||||
<br /> <br />
|
||||
Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for user
|
||||
'root' or skip the boarding process and add a new private key manually to Coolify and to the
|
||||
server.
|
||||
<br />
|
||||
Check this <a target="_blank" class="underline"
|
||||
href="https://coolify.io/docs/server/openssh">documentation</a> for further help.
|
||||
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
|
||||
<x-forms.button class="w-64 box" wire:target="setServerType('localhost')"
|
||||
wire:click="setServerType('localhost')">Check again
|
||||
<x-forms.button class="justify-center w-64 box " wire:target="setServerType('remote')"
|
||||
wire:click="setServerType('remote')">Remote Server
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Servers are the main building blocks, as they will host your applications, databases,
|
||||
services, called resources. Any CPU intensive process will use the server's CPU where you
|
||||
are deploying your resources.</p>
|
||||
<p>Localhost is the server where Coolify is running on. It is not recommended to use one server
|
||||
for everything.</p>
|
||||
<p>Remote Server is a server reachable through SSH. It can be hosted at home, or from any cloud
|
||||
provider.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'private-key')
|
||||
<x-boarding-step title="SSH Key">
|
||||
<x-slot:question>
|
||||
Do you have your own SSH Private Key?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:target="setPrivateKey('own')"
|
||||
wire:click="setPrivateKey('own')">Yes
|
||||
</x-forms.button>
|
||||
<x-forms.button class="justify-center w-64 box" wire:target="setPrivateKey('create')"
|
||||
wire:click="setPrivateKey('create')">No (create one for me)
|
||||
</x-forms.button>
|
||||
@if (count($privateKeys) > 0)
|
||||
<form wire:submit='selectExistingPrivateKey' class="flex flex-col w-full gap-4 pr-10">
|
||||
<x-forms.select label="Existing SSH Keys" id='selectedExistingPrivateKey'>
|
||||
@foreach ($privateKeys as $privateKey)
|
||||
<option wire:key="{{ $loop->index }}" value="{{ $privateKey->id }}">
|
||||
{{ $privateKey->name }}</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
<x-forms.button type="submit">Use this SSH Key</x-forms.button>
|
||||
</form>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>SSH Keys are used to connect to a remote server through a secure shell, called SSH.</p>
|
||||
<p>You can use your own ssh private key, or you can let Coolify to create one for you.</p>
|
||||
<p>In both ways, you need to add the public version of your ssh private key to the remote
|
||||
server's
|
||||
<code class="text-warning">~/.ssh/authorized_keys</code> file.
|
||||
</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'select-existing-server')
|
||||
<x-boarding-step title="Select a server">
|
||||
<x-slot:question>
|
||||
There are already servers available for your Team. Do you want to use one of them?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div>
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="createNewServer">No (create one
|
||||
for
|
||||
me)
|
||||
@if (!$serverReachable)
|
||||
Localhost is not reachable with the following public key.
|
||||
<br /> <br />
|
||||
Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for
|
||||
user
|
||||
'root' or skip the boarding process and add a new private key manually to Coolify and to the
|
||||
server.
|
||||
<br />
|
||||
Check this <a target="_blank" class="underline"
|
||||
href="https://coolify.io/docs/server/openssh">documentation</a> for further help.
|
||||
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
|
||||
<x-forms.button class="w-64 box" wire:target="setServerType('localhost')"
|
||||
wire:click="setServerType('localhost')">Check again
|
||||
</x-forms.button>
|
||||
</div>
|
||||
<div>
|
||||
<form wire:submit='selectExistingServer' class="flex flex-col w-full gap-4 lg:w-96">
|
||||
<x-forms.select label="Existing servers" class="w-96" id='selectedExistingServer'>
|
||||
@foreach ($servers as $server)
|
||||
<option wire:key="{{ $loop->index }}" value="{{ $server->id }}">
|
||||
{{ $server->name }}</option>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Servers are the main building blocks, as they will host your applications, databases,
|
||||
services, called resources. Any CPU intensive process will use the server's CPU where you
|
||||
are deploying your resources.</p>
|
||||
<p><x-highlighted text="Localhost" /> is the server where Coolify is running on. It is not
|
||||
recommended to use one server
|
||||
for everything.</p>
|
||||
<p><x-highlighted text="A remote server" /> is a server reachable through SSH. It can be hosted
|
||||
at home, or from any cloud
|
||||
provider.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($state === 'private-key')
|
||||
<x-boarding-step title="SSH Key">
|
||||
<x-slot:question>
|
||||
Do you have your own SSH Private Key?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:target="setPrivateKey('own')"
|
||||
wire:click="setPrivateKey('own')">Yes
|
||||
</x-forms.button>
|
||||
<x-forms.button class="justify-center w-64 box" wire:target="setPrivateKey('create')"
|
||||
wire:click="setPrivateKey('create')">No (create one for me)
|
||||
</x-forms.button>
|
||||
@if (count($privateKeys) > 0)
|
||||
<form wire:submit='selectExistingPrivateKey' class="flex flex-col w-full gap-4 pr-10">
|
||||
<x-forms.select label="Existing SSH Keys" id='selectedExistingPrivateKey'>
|
||||
@foreach ($privateKeys as $privateKey)
|
||||
<option wire:key="{{ $loop->index }}" value="{{ $privateKey->id }}">
|
||||
{{ $privateKey->name }}</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
<x-forms.button type="submit">Use this Server</x-forms.button>
|
||||
<x-forms.button type="submit">Use this SSH Key</x-forms.button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@if (!$serverReachable)
|
||||
This server is not reachable with the following public key.
|
||||
<br /> <br />
|
||||
Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for user
|
||||
'root' or skip the boarding process and add a new private key manually to Coolify and to the
|
||||
server.
|
||||
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
|
||||
<x-forms.button class="w-64 box" wire:target="validateServer" wire:click="validateServer">Check
|
||||
again
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Private Keys are used to connect to a remote server through a secure shell, called SSH.</p>
|
||||
<p>You can use your own private key, or you can let Coolify to create one for you.</p>
|
||||
<p>In both ways, you need to add the public version of your private key to the remote server's
|
||||
<code>~/.ssh/authorized_keys</code> file.
|
||||
</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'create-private-key')
|
||||
<x-boarding-step title="Create Private Key">
|
||||
<x-slot:question>
|
||||
Please let me know your key details.
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<form wire:submit='savePrivateKey' class="flex flex-col w-full gap-4 pr-10">
|
||||
<x-forms.input required placeholder="Choose a name for your Private Key. Could be anything."
|
||||
label="Name" id="privateKeyName" />
|
||||
<x-forms.input placeholder="Description, so others will know more about this."
|
||||
label="Description" id="privateKeyDescription" />
|
||||
<x-forms.textarea required placeholder="-----BEGIN OPENSSH PRIVATE KEY-----" label="Private Key"
|
||||
id="privateKey" />
|
||||
@if ($privateKeyType === 'create')
|
||||
<x-forms.textarea rows="7" readonly label="Public Key" id="publicKey" />
|
||||
<span class="font-bold text-warning">ACTION REQUIRED: Copy the 'Public Key' to your server's
|
||||
~/.ssh/authorized_keys
|
||||
file.</span>
|
||||
@endif
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
</form>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Private Keys are used to connect to a remote server through a secure shell, called SSH.</p>
|
||||
<p>You can use your own private key, or you can let Coolify to create one for you.</p>
|
||||
<p>In both ways, you need to add the public version of your private key to the remote server's
|
||||
<code>~/.ssh/authorized_keys</code> file.
|
||||
</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'create-server')
|
||||
<x-boarding-step title="Create Server">
|
||||
<x-slot:question>
|
||||
Please let me know your server details.
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<form wire:submit='saveServer' class="flex flex-col w-full gap-4 pr-10">
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required placeholder="Choose a name for your Server. Could be anything."
|
||||
label="Name" id="remoteServerName" />
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>SSH Keys are used to connect to a remote server through a secure shell, called SSH.</p>
|
||||
<p>You can use your own ssh private key, or you can let Coolify to create one for you.</p>
|
||||
<p>In both ways, you need to add the public version of your ssh private key to the remote
|
||||
server's
|
||||
<code class="text-warning">~/.ssh/authorized_keys</code> file.
|
||||
</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($state === 'select-existing-server')
|
||||
<x-boarding-step title="Select a server">
|
||||
<x-slot:question>
|
||||
There are already servers available for your Team. Do you want to use one of them?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div>
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="createNewServer">No (create
|
||||
one
|
||||
for
|
||||
me)
|
||||
</x-forms.button>
|
||||
</div>
|
||||
<div>
|
||||
<form wire:submit='selectExistingServer' class="flex flex-col w-full gap-4 lg:w-96">
|
||||
<x-forms.select label="Existing servers" class="w-96" id='selectedExistingServer'>
|
||||
@foreach ($servers as $server)
|
||||
<option wire:key="{{ $loop->index }}" value="{{ $server->id }}">
|
||||
{{ $server->name }}</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
<x-forms.button type="submit">Use this Server</x-forms.button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@if (!$serverReachable)
|
||||
This server is not reachable with the following public key.
|
||||
<br /> <br />
|
||||
Please make sure you have the correct public key in your ~/.ssh/authorized_keys file for
|
||||
user
|
||||
'root' or skip the boarding process and add a new private key manually to Coolify and to the
|
||||
server.
|
||||
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
|
||||
<x-forms.button class="w-64 box" wire:target="validateServer"
|
||||
wire:click="validateServer">Check
|
||||
again
|
||||
</x-forms.button>
|
||||
@endif
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Private Keys are used to connect to a remote server through a secure shell, called SSH.</p>
|
||||
<p>You can use your own private key, or you can let Coolify to create one for you.</p>
|
||||
<p>In both ways, you need to add the public version of your private key to the remote server's
|
||||
<code>~/.ssh/authorized_keys</code> file.
|
||||
</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($state === 'create-private-key')
|
||||
<x-boarding-step title="Create Private Key">
|
||||
<x-slot:question>
|
||||
Please let me know your key details.
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<form wire:submit='savePrivateKey' class="flex flex-col w-full gap-4 pr-10">
|
||||
<x-forms.input required placeholder="Choose a name for your Private Key. Could be anything."
|
||||
label="Name" id="privateKeyName" />
|
||||
<x-forms.input placeholder="Description, so others will know more about this."
|
||||
label="Description" id="remoteServerDescription" />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required placeholder="127.0.0.1" label="IP Address" id="remoteServerHost" />
|
||||
<x-forms.input required placeholder="Port number of your server. Default is 22."
|
||||
label="Port" id="remoteServerPort" />
|
||||
<x-forms.input required readonly
|
||||
placeholder="Username to connect to your server. Default is root." label="Username"
|
||||
id="remoteServerUser" />
|
||||
</div>
|
||||
<div class="w-64">
|
||||
<x-forms.checkbox
|
||||
helper="If you are using Cloudflare Tunnels, enable this. It will proxy all ssh requests to your server through Cloudflare.<br><span class='text-warning'>Coolify does not install/setup Cloudflare (cloudflared) on your server.</span>"
|
||||
id="isCloudflareTunnel" label="Cloudflare Tunnel" />
|
||||
</div>
|
||||
<x-forms.button type="submit">Continue</x-forms.button>
|
||||
</form>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Username should be <x-highlighted text="root" /> for now. We are working on to use
|
||||
non-root users.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'validate-server')
|
||||
<x-boarding-step title="Validate & Configure Server">
|
||||
<x-slot:question>
|
||||
I need to validate your server (connection, Docker Engine, etc) and configure if something is
|
||||
missing for me. Are you okay with this?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-slide-over closeWithX fullScreen>
|
||||
<x-slot:title>Validate & configure</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:server.validate-and-install :server="$this->createdServer" />
|
||||
</x-slot:content>
|
||||
<x-forms.button @click="slideOverOpen=true" class="font-bold box w-96"
|
||||
wire:click.prevent='installServer' isHighlighted>
|
||||
Let's do it!
|
||||
</x-forms.button>
|
||||
</x-slide-over>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>This will install the latest Docker Engine on your server, configure a few things to be able
|
||||
to run optimal.<br><br>Minimum Docker Engine version is: 22<br><br>To manually install Docker
|
||||
Engine, check <a target="_blank" class="underline text-warning"
|
||||
href="https://docs.docker.com/engine/install/#server">this
|
||||
documentation</a>.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
{{-- <div>
|
||||
@if ($currentState === 'select-proxy')
|
||||
<x-boarding-step title="Select a Proxy">
|
||||
<x-slot:question>
|
||||
If you would like to attach any kind of domain to your resources, you need a proxy.
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-forms.button wire:click="selectProxy" class="w-64 box">
|
||||
Decide later
|
||||
</x-forms.button>
|
||||
<x-forms.button class="w-32 box" wire:click="selectProxy('{{ ProxyTypes::TRAEFIK_V2 }}')">
|
||||
Traefik
|
||||
v2
|
||||
</x-forms.button>
|
||||
<x-forms.button disabled class="w-32 box">
|
||||
Nginx
|
||||
</x-forms.button>
|
||||
<x-forms.button disabled class="w-32 box">
|
||||
Caddy
|
||||
</x-forms.button>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>This will install the latest Docker Engine on your server, configure a few things to be able
|
||||
to run optimal.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div> --}}
|
||||
<div>
|
||||
@if ($currentState === 'create-project')
|
||||
<x-boarding-step title="Project">
|
||||
<x-slot:question>
|
||||
@if (count($projects) > 0)
|
||||
You already have some projects. Do you want to use one of them or should I create a new one for
|
||||
you?
|
||||
@else
|
||||
Let's create an initial project for you. You can change all the details later on.
|
||||
@endif
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="createNewProject">Create new
|
||||
project!</x-forms.button>
|
||||
<div>
|
||||
label="Description" id="privateKeyDescription" />
|
||||
<x-forms.textarea required placeholder="-----BEGIN OPENSSH PRIVATE KEY-----"
|
||||
label="Private Key" id="privateKey" />
|
||||
@if ($privateKeyType === 'create')
|
||||
<x-forms.textarea rows="7" readonly label="Public Key" id="publicKey" />
|
||||
<span class="font-bold text-warning">ACTION REQUIRED: Copy the 'Public Key' to your
|
||||
server's
|
||||
~/.ssh/authorized_keys
|
||||
file.</span>
|
||||
@endif
|
||||
<x-forms.button type="submit">Save</x-forms.button>
|
||||
</form>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Private Keys are used to connect to a remote server through a secure shell, called SSH.</p>
|
||||
<p>You can use your own private key, or you can let Coolify to create one for you.</p>
|
||||
<p>In both ways, you need to add the public version of your private key to the remote server's
|
||||
<code>~/.ssh/authorized_keys</code> file.
|
||||
</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($state === 'create-server')
|
||||
<x-boarding-step title="Create Server">
|
||||
<x-slot:question>
|
||||
Please let me know your server details.
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<form wire:submit='saveServer' class="flex flex-col w-full gap-4 pr-10">
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required placeholder="Choose a name for your Server. Could be anything."
|
||||
label="Name" id="remoteServerName" />
|
||||
<x-forms.input placeholder="Description, so others will know more about this."
|
||||
label="Description" id="remoteServerDescription" />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required placeholder="127.0.0.1" label="IP Address"
|
||||
id="remoteServerHost" />
|
||||
<x-forms.input required placeholder="Port number of your server. Default is 22."
|
||||
label="Port" id="remoteServerPort" />
|
||||
<x-forms.input required readonly
|
||||
placeholder="Username to connect to your server. Default is root."
|
||||
label="Username" id="remoteServerUser" />
|
||||
</div>
|
||||
<div class="w-64">
|
||||
<x-forms.checkbox
|
||||
helper="If you are using Cloudflare Tunnels, enable this. It will proxy all ssh requests to your server through Cloudflare.<br><span class='text-warning'>Coolify does not install/setup Cloudflare (cloudflared) on your server.</span>"
|
||||
id="isCloudflareTunnel" label="Cloudflare Tunnel" />
|
||||
</div>
|
||||
<x-forms.button type="submit">Continue</x-forms.button>
|
||||
</form>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Username should be <x-highlighted text="root" /> for now. We are working on to use
|
||||
non-root users.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($state === 'validate-server')
|
||||
<x-boarding-step title="Validate & Configure Server">
|
||||
<x-slot:question>
|
||||
I need to validate your server (connection, Docker Engine, etc) and configure if something is
|
||||
missing for me. Are you okay with this?
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-slide-over closeWithX fullScreen>
|
||||
<x-slot:title>Validate & configure</x-slot:title>
|
||||
<x-slot:content>
|
||||
<livewire:server.validate-and-install :server="$this->createdServer" />
|
||||
</x-slot:content>
|
||||
<x-forms.button @click="slideOverOpen=true" class="font-bold box w-96"
|
||||
wire:click.prevent='installServer' isHighlighted>
|
||||
Let's do it!
|
||||
</x-forms.button>
|
||||
</x-slide-over>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>This will install the latest Docker Engine on your server, configure a few things to be able
|
||||
to run optimal.<br><br>Minimum Docker Engine version is: 22<br><br>To manually install
|
||||
Docker
|
||||
Engine, check <a target="_blank" class="underline text-warning"
|
||||
href="https://docs.docker.com/engine/install/#server">this
|
||||
documentation</a>.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($state === 'create-project')
|
||||
<x-boarding-step title="Project">
|
||||
<x-slot:question>
|
||||
@if (count($projects) > 0)
|
||||
<form wire:submit='selectExistingProject' class="flex flex-col w-full gap-4 lg:w-96">
|
||||
<x-forms.select label="Existing projects" class="w-96"
|
||||
id='selectedExistingProject'>
|
||||
@foreach ($projects as $project)
|
||||
<option wire:key="{{ $loop->index }}" value="{{ $project->id }}">
|
||||
{{ $project->name }}</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
<x-forms.button type="submit">Use this Project</x-forms.button>
|
||||
</form>
|
||||
You already have some projects. Do you want to use one of them or should I create a new one
|
||||
for
|
||||
you?
|
||||
@else
|
||||
Let's create an initial project for you. You can change all the details later on.
|
||||
@endif
|
||||
</div>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Projects contain several resources combined into one virtual group. There are no
|
||||
limitations on the number of projects you can add.</p>
|
||||
<p>Each project should have at least one environment, this allows you to create a production &
|
||||
staging version of the same application, but grouped separately.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<x-forms.button class="justify-center w-64 box" wire:click="createNewProject">Create new
|
||||
project!</x-forms.button>
|
||||
<div>
|
||||
@if (count($projects) > 0)
|
||||
<form wire:submit='selectExistingProject' class="flex flex-col w-full gap-4 lg:w-96">
|
||||
<x-forms.select label="Existing projects" class="w-96" id='selectedProject'>
|
||||
@foreach ($projects as $project)
|
||||
<option wire:key="{{ $loop->index }}" value="{{ $project->id }}">
|
||||
{{ $project->name }}</option>
|
||||
@endforeach
|
||||
</x-forms.select>
|
||||
<x-forms.button type="submit">Use this Project</x-forms.button>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>Projects contain several resources combined into one virtual group. There are no
|
||||
limitations on the number of projects you can add.</p>
|
||||
<p>Each project should have at least one environment, this allows you to create a production &
|
||||
staging version of the same application, but grouped separately.</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div>
|
||||
@if ($state === 'create-resource')
|
||||
<x-boarding-step title="Resources">
|
||||
<x-slot:question>
|
||||
Let's go to the new resource page, where you can create your first resource.
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<div class="items-center justify-center w-64 box" wire:click="showNewResource">Let's do
|
||||
it!</div>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>A resource could be an application, a database or a service (like WordPress).</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div class="flex justify-center gap-2 pt-4">
|
||||
<a wire:click='skipBoarding'>Skip boarding process</a>
|
||||
<a wire:click='restartBoarding'>Restart boarding process</a>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
@if ($currentState === 'create-resource')
|
||||
<x-boarding-step title="Resources">
|
||||
<x-slot:question>
|
||||
Let's go to the new resource page, where you can create your first resource.
|
||||
</x-slot:question>
|
||||
<x-slot:actions>
|
||||
<div class="items-center justify-center w-64 box" wire:click="showNewResource">Let's do
|
||||
it!</div>
|
||||
</x-slot:actions>
|
||||
<x-slot:explanation>
|
||||
<p>A resource could be an application, a database or a service (like WordPress).</p>
|
||||
</x-slot:explanation>
|
||||
</x-boarding-step>
|
||||
@endif
|
||||
</div>
|
||||
<div class="flex justify-center gap-2 pt-4">
|
||||
<a wire:click='skipBoarding'>Skip boarding process</a>
|
||||
<a wire:click='restartBoarding'>Restart boarding process</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<h1 class="title">Dashboard</h1>
|
||||
{{-- <div class="subtitle">Your self-hosted environment</div> --}}
|
||||
@if (request()->query->get('success'))
|
||||
<div class="mb-10 text-white rounded alert-success">
|
||||
<div class="mb-10 rounded dark:text-white alert-success">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 stroke-current shrink-0" fill="none"
|
||||
viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
||||
@ -22,26 +22,26 @@
|
||||
@if (data_get($project, 'environments')->count() === 1)
|
||||
<a class="flex flex-col flex-1 mx-6 hover:no-underline"
|
||||
href="{{ route('project.resource.index', ['project_uuid' => data_get($project, 'uuid'), 'environment_name' => data_get($project, 'environments.0.name', 'production')]) }}">
|
||||
<div class="font-bold text-white">{{ $project->name }}</div>
|
||||
<div class="description">
|
||||
<div class="box-title">{{ $project->name }}</div>
|
||||
<div class="box-description">
|
||||
{{ $project->description }}</div>
|
||||
</a>
|
||||
@else
|
||||
<a class="flex flex-col flex-1 mx-6 hover:no-underline"
|
||||
href="{{ route('project.show', ['project_uuid' => data_get($project, 'uuid')]) }}">
|
||||
<div class="font-bold text-white">{{ $project->name }}</div>
|
||||
<div class="description">
|
||||
<div class="box-title">{{ $project->name }}</div>
|
||||
<div class="box-description">
|
||||
{{ $project->description }}</div>
|
||||
</a>
|
||||
@endif
|
||||
<div class="flex items-center">
|
||||
<a class="mx-4 rounded group-hover:text-white hover:no-underline"
|
||||
<div class="flex items-center group">
|
||||
<a class="mx-4 rounded hover:no-underline"
|
||||
href="{{ route('project.resource.create', ['project_uuid' => data_get($project, 'uuid'), 'environment_name' => data_get($project, 'environments.0.name', 'production')]) }}">
|
||||
<span class="font-bold hover:text-warning">+ Add Resource</span>
|
||||
<span class="p-2 font-bold group-hover:dark:text-white group-hover:text-black dark:hover:bg-coollabs hover:bg-neutral-300">+ Add Resource</span>
|
||||
</a>
|
||||
<a class="mx-4 rounded group-hover:text-white"
|
||||
<a class="mx-4 rounded group-hover:dark:text-white group-hover:text-black"
|
||||
href="{{ route('project.edit', ['project_uuid' => data_get($project, 'uuid')]) }}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon hover:text-warning" viewBox="0 0 24 24"
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon hover:text-coollabs" viewBox="0 0 24 24"
|
||||
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
|
||||
stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
@ -54,9 +54,9 @@
|
||||
</div>
|
||||
@empty
|
||||
<div>
|
||||
No projects found. Add your first server <a class="text-white underline"
|
||||
No projects found. Add your first server <a class="underline dark:text-white"
|
||||
onclick="newEmptyProject.showModal()">here</a> or
|
||||
go to the <a class="text-white underline" href="{{ route('onboarding') }}">onboarding page.</a>
|
||||
go to the <a class="underline dark:text-white" href="{{ route('onboarding') }}">onboarding page.</a>
|
||||
<livewire:project.add-empty />
|
||||
</div>
|
||||
@endforelse
|
||||
@ -71,10 +71,10 @@
|
||||
'border-red-500' => !$server->settings->is_reachable,
|
||||
])>
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold text-white">
|
||||
<div class="box-title">
|
||||
{{ $server->name }}
|
||||
</div>
|
||||
<div class="description">
|
||||
<div class="box-description">
|
||||
{{ $server->description }}</div>
|
||||
<div class="flex gap-1 text-xs text-error">
|
||||
@if (!$server->settings->is_reachable)
|
||||
@ -93,8 +93,9 @@
|
||||
@empty
|
||||
<div>
|
||||
No servers found.
|
||||
Add your first server <a class="text-white underline" href="{{ route('server.create') }}">here</a> or
|
||||
go to the <a class="text-white underline" href="{{ route('onboarding') }}">onboarding page.</a>
|
||||
Add your first server <a class="underline dark:text-white" href="{{ route('server.create') }}">here</a>
|
||||
or
|
||||
go to the <a class="underline dark:text-white" href="{{ route('onboarding') }}">onboarding page.</a>
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
@ -116,15 +117,15 @@
|
||||
'border-yellow-500' => data_get($deployment, 'status') === 'in_progress',
|
||||
])>
|
||||
<div class="flex flex-col mx-6">
|
||||
<div class="font-bold text-white">
|
||||
<div class="box-title">
|
||||
{{ data_get($deployment, 'application_name') }}
|
||||
</div>
|
||||
@if (data_get($deployment, 'pull_request_id') !== 0)
|
||||
<div class="description">
|
||||
<div class="box-description">
|
||||
PR #{{ data_get($deployment, 'pull_request_id') }}
|
||||
</div>
|
||||
@endif
|
||||
<div class="description">
|
||||
<div class="box-description">
|
||||
{{ str(data_get($deployment, 'status'))->headline() }}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -12,7 +12,7 @@
|
||||
</x-slide-over>
|
||||
@endif
|
||||
</div>
|
||||
<div class="subtitle">All your projects.</div>
|
||||
<div class="subtitle">All your projects are here.</div>
|
||||
<div class="grid gap-2 lg:grid-cols-2">
|
||||
@if ($servers === 0)
|
||||
<div>
|
||||
|
@ -52,7 +52,7 @@ class="items-center justify-center box">+ Add New Resource</a>
|
||||
<a class="h-24 box group" :href="item.hrefLink">
|
||||
<div class="flex flex-col w-full px-4 mx-2">
|
||||
<div class="flex gap-2">
|
||||
<div class="pb-2 font-bold text-white" x-text="item.name"></div>
|
||||
<div class="pb-2 box-title" x-text="item.name"></div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div title="running" class="mt-1 bg-success badge "></div>
|
||||
</template>
|
||||
@ -66,16 +66,16 @@ class="items-center justify-center box">+ Add New Resource</a>
|
||||
<div title="degraded" class="mt-1 bg-warning badge "></div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="max-w-full truncate description" x-text="item.description"></div>
|
||||
<div class="max-w-full truncate description" x-text="item.fqdn"></div>
|
||||
<div class="max-w-full truncate box-description" x-text="item.description"></div>
|
||||
<div class="max-w-full truncate box-description" x-text="item.fqdn"></div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
|
||||
<div class="flex gap-1 pt-1 group-hover:dark:text-white group-hover:text-black group min-h-6">
|
||||
<template x-for="tag in item.tags">
|
||||
<div class="px-2 py-1 cursor-pointer description bg-coolgray-100 hover:bg-coolgray-300"
|
||||
<div class="px-2 py-1 cursor-pointer box-description dark:bg-coolgray-100 dark:hover:bg-coolgray-300 bg-neutral-100 hover:bg-neutral-200"
|
||||
@click.prevent="gotoTag(tag.name)" x-text="tag.name"></div>
|
||||
</template>
|
||||
<div class="flex items-center px-2 text-xs cursor-pointer text-neutral-500/20 group-hover:text-white hover:bg-coolgray-300"
|
||||
<div class="flex items-center px-2 text-xs cursor-pointer dark:text-neutral-500/20 text-neutral-500 group-hover:text-neutral-700 group-hover:dark:text-white dark:hover:bg-coolgray-300 hover:bg-neutral-200"
|
||||
@click.prevent="goto(item)">Add tag</div>
|
||||
</div>
|
||||
</span>
|
||||
@ -85,7 +85,7 @@ class="items-center justify-center box">+ Add New Resource</a>
|
||||
<a class="h-24 box group" :href="item.hrefLink">
|
||||
<div class="flex flex-col px-4 mx-2">
|
||||
<div class="flex gap-2">
|
||||
<div class="pb-2 font-bold text-white" x-text="item.name"></div>
|
||||
<div class="pb-2 font-bold box-title" x-text="item.name"></div>
|
||||
<template x-if="item.status.startsWith('running')">
|
||||
<div title="running" class="mt-1 bg-success badge "></div>
|
||||
</template>
|
||||
@ -99,10 +99,10 @@ class="items-center justify-center box">+ Add New Resource</a>
|
||||
<div title="degraded" class="mt-1 bg-warning badge "></div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="max-w-full truncate description" x-text="item.description"></div>
|
||||
<div class="max-w-full truncate box-description" x-text="item.description"></div>
|
||||
</div>
|
||||
</a>
|
||||
<div class="flex gap-1 pt-1 group-hover:text-white group min-h-6">
|
||||
<div class="flex gap-1 pt-1 group-hover:dark:text-white group-hover:text-black group min-h-6">
|
||||
<template x-for="tag in item.tags">
|
||||
<div class="px-2 py-1 cursor-pointer description bg-coolgray-100 hover:bg-coolgray-300"
|
||||
@click.prevent="gotoTag(tag.name)" x-text="tag.name"></div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<x-forms.button >+ Add</x-forms.button>
|
||||
</a>
|
||||
</div>
|
||||
<div class="subtitle">All your projects.</div>
|
||||
<div class="subtitle">All your servers are here.</div>
|
||||
|
||||
<div class="grid gap-2 lg:grid-cols-2">
|
||||
@forelse ($servers as $server)
|
||||
|
@ -4,14 +4,14 @@
|
||||
</div>
|
||||
<div class="pb-4 ">Email settings for password resets, invitations, shared with Pro+ subscribers etc.</div>
|
||||
<form wire:submit='submitFromFields' class="pb-4">
|
||||
<div class="flex flex-col items-end w-full gap-2 xl:flex-row">
|
||||
<div class="flex gap-2">
|
||||
<x-forms.input required id="settings.smtp_from_name" helper="Name used in emails." label="From Name" />
|
||||
<x-forms.input required id="settings.smtp_from_address" helper="Email address used in emails."
|
||||
label="From Address" />
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
@if (isEmailEnabled($settings) && auth()->user()->isAdminFromSession() && isTestEmailEnabled($settings))
|
||||
{{-- @if (isEmailEnabled($settings) && auth()->user()->isAdminFromSession() && isTestEmailEnabled($settings))
|
||||
<x-modal-input buttonTitle="Send Test Email" title="Send Test Email">
|
||||
<form wire:submit='submit' class="flex flex-col gap-2">
|
||||
<x-forms.input placeholder="test@example.com" id="emails" label="Recipients" required />
|
||||
@ -21,16 +21,21 @@
|
||||
</x-forms.button>
|
||||
</form>
|
||||
</x-modal-input>
|
||||
@endif
|
||||
@endif --}}
|
||||
</div>
|
||||
</form>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="p-4 border border-coolgray-500">
|
||||
<h3>SMTP Server</h3>
|
||||
<div class="w-32">
|
||||
<x-forms.checkbox instantSave id="settings.smtp_enabled" label="Enabled" />
|
||||
</div>
|
||||
<form wire:submit='submit' class="flex flex-col">
|
||||
<div class="flex gap-2">
|
||||
<h3>SMTP Server</h3>
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
</div>
|
||||
<div class="w-32">
|
||||
<x-forms.checkbox instantSave id="settings.smtp_enabled" label="Enabled" />
|
||||
</div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||
<x-forms.input required id="settings.smtp_host" placeholder="smtp.mailgun.org" label="Host" />
|
||||
@ -45,30 +50,25 @@
|
||||
label="Timeout" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end gap-4 pt-6">
|
||||
</form>
|
||||
</div>
|
||||
<div class="p-4 border border-coolgray-500">
|
||||
<form wire:submit='submitResend' class="flex flex-col">
|
||||
<div class="flex gap-2">
|
||||
<h3>Resend</h3>
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="p-4 border border-coolgray-500">
|
||||
<h3>Resend</h3>
|
||||
<div class="w-32">
|
||||
<x-forms.checkbox instantSave='instantSaveResend' id="settings.resend_enabled" label="Enabled" />
|
||||
</div>
|
||||
<form wire:submit='submitResend' class="flex flex-col">
|
||||
<div class="w-32">
|
||||
<x-forms.checkbox instantSave='instantSaveResend' id="settings.resend_enabled" label="Enabled" />
|
||||
</div>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex flex-col w-full gap-2 xl:flex-row">
|
||||
<x-forms.input type="password" id="settings.resend_api_key" placeholder="API key" required
|
||||
label="Host" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end gap-4 pt-6">
|
||||
<x-forms.button type="submit">
|
||||
Save
|
||||
</x-forms.button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -10,7 +10,7 @@
|
||||
@click.prevent="activeTab = 'smtp'; window.location.hash = 'smtp'" href="#">Transactional
|
||||
Email</a>
|
||||
<a :class="activeTab === 'auth' && 'text-white'"
|
||||
@click.prevent="activeTab = 'auth'; window.location.hash = 'auth'" href="#">Authentication</a>
|
||||
@click.prevent="activeTab = 'auth'; window.location.hash = 'auth'" href="#">Authentication (OAuth)</a>
|
||||
</div>
|
||||
<div class="w-full pl-8">
|
||||
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
||||
|
Loading…
Reference in New Issue
Block a user