Files
ladill-hosting/resources/views/hosting/dashboard.blade.php
T
isaaccladandCursor e3fd235139
Deploy Ladill Hosting / deploy (push) Successful in 26s
Unify SSO and surface legacy ResellerClub hosting orders on the dashboard.
Add silent OAuth and session keepalive, and show imported RC orders alongside
native hosting accounts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-07 06:33:16 +00:00

125 lines
7.8 KiB
PHP

@extends('layouts.hosting')
@section('title', 'Overview — Ladill Hosting')
@section('content')
<div class="mx-auto max-w-5xl">
<div class="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
<div>
<h1 class="text-xl font-semibold tracking-tight text-slate-900">Overview</h1>
<p class="mt-0.5 text-sm text-slate-500">Your shared hosting at a glance.</p>
</div>
<a href="{{ route('hosting.single-domain') }}" class="inline-flex items-center justify-center rounded-lg bg-indigo-600 px-4 py-2 text-sm font-semibold text-white transition hover:bg-indigo-700">
New hosting
</a>
</div>
<div class="mt-6 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
@foreach([
['Active accounts', $activeCount, route('hosting.accounts.index')],
['Expiring (30 days)', $expiringCount, route('hosting.accounts.index')],
['Pending orders', $pendingOrderCount, route('hosting.single-domain')],
['Linked domains', $linkedDomains, route('hosting.accounts.index')],
] as [$label, $value, $link])
<a href="{{ $link }}" class="rounded-2xl border border-slate-200 bg-white p-5 transition hover:border-indigo-200">
<p class="text-xs font-medium uppercase tracking-wide text-slate-400">{{ $label }}</p>
<p class="mt-2 text-2xl font-semibold text-slate-900">{{ $value }}</p>
</a>
@endforeach
</div>
<div class="mt-6 rounded-2xl border border-slate-200 bg-white">
<div class="flex items-center justify-between border-b border-slate-100 px-5 py-3.5">
<h2 class="text-sm font-semibold text-slate-900">Hosting accounts</h2>
@if ($accounts->count() + ($recentLegacyOrders ?? collect())->count() > 5)
<a href="{{ route('hosting.accounts.index') }}" class="text-xs font-medium text-indigo-600 hover:underline">View all</a>
@endif
</div>
@if ($recent->isEmpty() && ($recentLegacyOrders ?? collect())->isEmpty())
<div class="px-5 py-12 text-center">
<p class="text-sm font-semibold text-slate-700">No hosting accounts yet</p>
<p class="mx-auto mt-1 max-w-sm text-xs text-slate-400">Choose a plan to get started single domain, multi domain, or WordPress hosting.</p>
<div class="mt-5 flex flex-wrap justify-center gap-2">
<a href="{{ route('hosting.single-domain') }}" class="rounded-lg border border-slate-200 px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">Single Domain</a>
<a href="{{ route('hosting.multi-domain') }}" class="rounded-lg border border-slate-200 px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">Multi Domain</a>
<a href="{{ route('hosting.wordpress') }}" class="inline-flex items-center rounded-lg border border-slate-200 px-4 py-2 text-sm font-medium text-slate-700 hover:bg-slate-50">
@include('partials.wordpress-icon', ['class' => 'mr-1.5 h-4 w-4'])
WordPress
</a>
</div>
</div>
@else
<div class="divide-y divide-slate-50">
@foreach ($recent as $account)
@php
$sharedDeveloperAccess = (int) $account->user_id !== (int) auth()->id();
$accountUrl = $sharedDeveloperAccess
? route('hosting.panel.index', $account)
: route('hosting.accounts.show', $account);
@endphp
<a href="{{ $accountUrl }}" class="flex items-center justify-between px-5 py-3.5 transition hover:bg-slate-50">
<div class="min-w-0">
<p class="truncate text-sm font-medium text-slate-900">{{ $account->linkedDomainLabel() ?? $account->username }}</p>
<p class="mt-0.5 text-xs text-slate-400">
{{ $account->username }}
· {{ $account->product?->name ?? 'Hosting' }}
· {{ $account->sites->count() }} {{ Str::plural('domain', $account->sites->count()) }}
@if ($account->expires_at)
· Expires {{ $account->expires_at->format('d M Y') }}
@endif
</p>
</div>
<span @class([
'shrink-0 rounded-full px-2.5 py-1 text-[11px] font-medium capitalize',
'bg-emerald-50 text-emerald-700' => $account->status === 'active',
'bg-red-50 text-red-700' => $account->status === 'suspended',
'bg-slate-100 text-slate-600' => ! in_array($account->status, ['active', 'suspended'], true),
])>{{ $account->status }}</span>
</a>
@endforeach
@foreach ($recentLegacyOrders ?? [] as $order)
<a href="{{ route('hosting.legacy.show', $order) }}" class="flex items-center justify-between px-5 py-3.5 transition hover:bg-slate-50">
<div class="min-w-0">
<p class="truncate text-sm font-medium text-slate-900">{{ $order->domain_name ?: 'Legacy hosting' }}</p>
<p class="mt-0.5 text-xs text-slate-400">
{{ $order->cpanel_username ?: 'Legacy account' }}
· {{ $order->plan_name ?? 'Legacy hosting' }}
· Legacy
@if ($order->expires_at)
· Expires {{ $order->expires_at->format('d M Y') }}
@endif
</p>
</div>
<span @class([
'shrink-0 rounded-full px-2.5 py-1 text-[11px] font-medium capitalize',
'bg-emerald-50 text-emerald-700' => $order->status === 'active',
'bg-red-50 text-red-700' => $order->status === 'suspended',
'bg-slate-100 text-slate-600' => ! in_array($order->status, ['active', 'suspended'], true),
])>{{ $order->status }}</span>
</a>
@endforeach
</div>
@endif
</div>
@if ($pendingOrders->isNotEmpty())
<div class="mt-6 rounded-2xl border border-slate-200 bg-white">
<div class="flex items-center justify-between border-b border-slate-100 px-5 py-3.5">
<h2 class="text-sm font-semibold text-slate-900">Pending orders</h2>
</div>
<div class="divide-y divide-slate-50">
@foreach ($pendingOrders as $order)
<a href="{{ route('hosting.orders.show', $order) }}" class="flex items-center justify-between px-5 py-3.5 transition hover:bg-slate-50">
<div class="min-w-0">
<p class="truncate text-sm font-medium text-slate-900">{{ $order->domain_name ?: ($order->product?->name ?? 'Hosting order') }}</p>
<p class="mt-0.5 text-xs text-slate-400">{{ $order->product?->name ?? 'Hosting' }}</p>
</div>
<span class="shrink-0 rounded-full bg-amber-50 px-2.5 py-1 text-[11px] font-medium text-amber-700">
{{ \App\Models\CustomerHostingOrder::customerFacingStatusLabelFor($order->status) }}
</span>
</a>
@endforeach
</div>
</div>
@endif
</div>
@endsection