Files
ladill-servers/resources/views/hosting/panel/settings.blade.php
T
isaaccladandCursor 817afb0c2b
Deploy Ladill Servers / deploy (push) Successful in 29s
Unify primary buttons with gradient pill design across the app.
Add shared btn-primary components and plus icons on create/new actions for a consistent Ladill UI.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-08 22:49:50 +00:00

169 lines
10 KiB
PHP

<x-hosting-panel-layout :account="$account">
<x-slot name="title">Settings - {{ $account->username }}</x-slot>
<x-slot name="header">Settings</x-slot>
@php
$serverIp = $account->node?->ip_address ?? '161.97.138.149';
$sftpCommand = "sftp {$account->username}@{$serverIp}";
@endphp
<div class="space-y-6">
@if(session('success'))
<div class="rounded-lg border border-emerald-200 bg-emerald-50 p-4">
<p class="text-sm text-emerald-800">{{ session('success') }}</p>
</div>
@endif
@if(session('error'))
<div class="rounded-lg border border-red-200 bg-red-50 p-4">
<p class="text-sm text-red-800">{{ session('error') }}</p>
</div>
@endif
@if($canChangePassword)
<div class="rounded-xl border border-slate-200 bg-white p-6">
<h3 class="mb-4 text-base font-semibold text-slate-900">SFTP Password</h3>
<p class="mb-4 text-sm text-slate-600">Change the shared SFTP password for this hosting account. Team developers do not see or manage this password.</p>
<form action="{{ route('hosting.panel.settings.password', $account) }}" method="POST" class="max-w-md space-y-4">
@csrf
<div>
<label class="mb-1 block text-sm font-medium text-slate-700">New Password</label>
<input type="password" name="password" required minlength="8" class="w-full rounded-lg border border-slate-200 px-4 py-2.5 text-sm focus:border-indigo-500 focus:ring-indigo-500">
</div>
<div>
<label class="mb-1 block text-sm font-medium text-slate-700">Confirm Password</label>
<input type="password" name="password_confirmation" required minlength="8" class="w-full rounded-lg border border-slate-200 px-4 py-2.5 text-sm focus:border-indigo-500 focus:ring-indigo-500">
</div>
<button type="submit" class="btn-primary">
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15.75 5.25a3 3 0 013 3m3 0a6 6 0 01-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1121.75 8.25z"/></svg>
Change Password
</button>
</form>
</div>
@endif
<div class="rounded-xl border border-slate-200 bg-white p-6">
<div class="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
<div>
<h3 class="text-base font-semibold text-slate-900">SFTP Key Access</h3>
@if ($teamMembership)
<p class="mt-2 text-sm text-slate-600">Add your SSH public key to connect over SFTP as <span class="font-mono text-slate-900">{{ $account->username }}</span>. Removing you from the team automatically removes this key.</p>
@else
<p class="mt-2 text-sm text-slate-600">Owners connect with the shared account password. Team developers add their own SSH public key here after they sign in.</p>
@endif
</div>
@if ($teamMembership?->ssh_key_installed_at)
<span class="inline-flex items-center rounded-full bg-emerald-50 px-3 py-1 text-xs font-medium text-emerald-700">
Key active
</span>
@endif
</div>
@if ($teamMembership)
<form action="{{ route('hosting.panel.settings.ssh-key', $account) }}" method="POST" class="mt-5 space-y-4">
@csrf
<div>
<label for="ssh_public_key" class="mb-1 block text-sm font-medium text-slate-700">SSH Public Key</label>
<textarea id="ssh_public_key" name="ssh_public_key" rows="5" required class="w-full rounded-lg border border-slate-200 px-4 py-3 font-mono text-sm focus:border-indigo-500 focus:ring-indigo-500" placeholder="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... your@email.com">{{ old('ssh_public_key', $teamMembership->ssh_public_key) }}</textarea>
<p class="mt-2 text-xs text-slate-500">Use an OpenSSH public key for SFTP access to this hosting account.</p>
<x-input-error :messages="$errors->get('ssh_public_key')" class="mt-2" />
</div>
<button type="submit" class="btn-primary">
Save SFTP Key
</button>
@if ($teamMembership->ssh_key_installed_at)
<p class="text-xs text-slate-500">Last installed {{ $teamMembership->ssh_key_installed_at->diffForHumans() }}.</p>
@endif
</form>
@if ($teamMembership->hasSshAccessKey())
<x-confirm-dialog
name="remove-sftp-key"
title="Remove SFTP key?"
message="Remove your SFTP key access for this hosting account?"
:action="route('hosting.panel.settings.ssh-key.destroy', $account)"
method="DELETE"
confirm-label="Remove key"
class="mt-3"
>
<x-slot:trigger>
<button type="button" class="inline-flex items-center rounded-lg border border-slate-300 px-5 py-2.5 text-sm font-medium text-slate-700 transition hover:border-slate-400 hover:text-slate-900">
Remove SFTP Key
</button>
</x-slot:trigger>
</x-confirm-dialog>
@endif
@else
<div class="mt-5 rounded-xl bg-slate-50 px-4 py-4 text-sm text-slate-600">
Developers on your team use their own SSH keys instead of the shared password, so removing them from the team immediately cuts off SFTP access.
</div>
@endif
</div>
<div class="rounded-xl border border-slate-200 bg-white p-6">
<div class="flex items-center gap-3 mb-5">
<div class="flex h-10 w-10 items-center justify-center rounded-lg bg-indigo-50">
<svg class="h-5 w-5 text-indigo-600" fill="none" stroke="currentColor" stroke-width="1.5" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M7.5 7.5h-.75A2.25 2.25 0 004.5 9.75v7.5a2.25 2.25 0 002.25 2.25h7.5a2.25 2.25 0 002.25-2.25v-7.5a2.25 2.25 0 00-2.25-2.25h-.75m-6 3.75l3 3m0 0l3-3m-3 3V1.5m6 9h.75a2.25 2.25 0 012.25 2.25v7.5a2.25 2.25 0 01-2.25 2.25h-7.5a2.25 2.25 0 01-2.25-2.25v-.75"/></svg>
</div>
<div>
<h3 class="text-base font-semibold text-slate-900">SFTP Connection</h3>
<p class="text-sm text-slate-500">Connect with any SFTP client</p>
</div>
</div>
<div class="mb-5 rounded-lg border border-slate-200 bg-slate-50 p-4">
<div class="flex items-center justify-between gap-4">
<code class="flex-1 overflow-x-auto font-mono text-sm text-slate-800">{{ $sftpCommand }}</code>
<button type="button" onclick="navigator.clipboard.writeText('{{ $sftpCommand }}'); this.textContent = 'Copied!'; setTimeout(() => this.textContent = 'Copy', 1500);" class="btn-primary btn-primary-sm flex-shrink-0">Copy</button>
</div>
</div>
<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
<div class="rounded-lg border border-slate-100 bg-slate-50/50 px-4 py-3">
<p class="text-xs font-medium text-slate-500">Host</p>
<p class="mt-1 font-mono text-sm text-slate-900">{{ $serverIp }}</p>
</div>
<div class="rounded-lg border border-slate-100 bg-slate-50/50 px-4 py-3">
<p class="text-xs font-medium text-slate-500">Port</p>
<p class="mt-1 font-mono text-sm text-slate-900">22</p>
</div>
<div class="rounded-lg border border-slate-100 bg-slate-50/50 px-4 py-3">
<p class="text-xs font-medium text-slate-500">Username</p>
<p class="mt-1 font-mono text-sm text-slate-900">{{ $account->username }}</p>
</div>
<div class="rounded-lg border border-slate-100 bg-slate-50/50 px-4 py-3">
<p class="text-xs font-medium text-slate-500">Authentication</p>
<p class="mt-1 text-sm text-slate-900">{{ $teamMembership ? 'SSH key' : 'Password' }}</p>
</div>
</div>
</div>
<div class="rounded-xl border border-slate-200 bg-white p-6">
<h3 class="mb-4 text-base font-semibold text-slate-900">Account Information</h3>
<div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
<div>
<p class="text-xs font-medium text-slate-500">Account Type</p>
<p class="mt-1 text-sm text-slate-900">{{ ucfirst($account->type) }} Hosting</p>
</div>
<div>
<p class="text-xs font-medium text-slate-500">Product</p>
<p class="mt-1 text-sm text-slate-900">{{ $account->product->name ?? 'N/A' }}</p>
</div>
<div>
<p class="text-xs font-medium text-slate-500">PHP Version</p>
<p class="mt-1 text-sm text-slate-900">{{ $account->php_version ?? '8.2' }}</p>
</div>
<div>
<p class="text-xs font-medium text-slate-500">Status</p>
<span class="inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium {{ $account->status === 'active' ? 'bg-emerald-100 text-emerald-800' : 'bg-slate-100 text-slate-800' }}">
{{ ucfirst($account->status) }}
</span>
</div>
</div>
</div>
</div>
</x-hosting-panel-layout>