Files
ladill-servers/resources/views/hosting/order.blade.php
T
isaaccladandCursor b6c8ac343f Extract Ladill Servers as standalone app at servers.ladill.com.
VPS and dedicated server ordering, managed panels, SSO, billing, and launcher integration — forked from hosting infrastructure with server-focused routes and dashboard.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-06 19:18:30 +00:00

256 lines
18 KiB
PHP

<x-user-layout>
<x-slot name="title">{{ $order->domain_name }} - Order Details</x-slot>
@php
$statusColors = [
'pending_payment' => 'bg-amber-50 text-amber-700 border-amber-200',
'pending_approval' => 'bg-amber-50 text-amber-700 border-amber-200',
'approved' => 'bg-blue-50 text-blue-700 border-blue-200',
'provisioning' => 'bg-blue-50 text-blue-700 border-blue-200',
'active' => 'bg-emerald-50 text-emerald-700 border-emerald-200',
'suspended' => 'bg-red-50 text-red-700 border-red-200',
'cancelled' => 'bg-gray-100 text-gray-500 border-gray-200',
'expired' => 'bg-gray-100 text-gray-500 border-gray-200',
'failed' => 'bg-red-50 text-red-700 border-red-200',
];
$statusLabels = collect([
'pending_payment', 'pending_approval', 'approved', 'provisioning',
'active', 'suspended', 'cancelled', 'expired', 'failed',
])->mapWithKeys(fn (string $status) => [
$status => \App\Models\CustomerHostingOrder::customerFacingStatusLabelFor($status),
])->all();
$statusColors['approved'] = 'bg-amber-50 text-amber-700 border-amber-200';
$backRoute = match ($order->product?->type) {
'single_domain' => route('hosting.single-domain'),
'multi_domain' => route('hosting.multi-domain'),
'wordpress' => route('hosting.wordpress'),
default => route('hosting.single-domain'),
};
@endphp
<div class="space-y-6" x-data="{ showCancelModal: false }">
{{-- Page Header --}}
<div class="flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between">
<div>
<a href="{{ $backRoute }}" class="mb-2 inline-flex items-center gap-1 text-sm text-gray-500 hover:text-gray-700">
<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 19.5 8.25 12l7.5-7.5"/></svg>
Back to {{ $order->product?->type === 'wordpress' ? 'WordPress Hosting' : ($order->product?->type === 'multi_domain' ? 'Multi Domain Hosting' : 'Single Domain Hosting') }}
</a>
<h1 class="text-2xl font-semibold tracking-tight text-gray-900">{{ $order->domain_name }}</h1>
<p class="mt-1 text-sm text-gray-500">{{ $order->product?->name ?? 'Hosting Order' }}</p>
</div>
<div class="flex items-center gap-2">
<span class="inline-flex items-center rounded-lg border px-3 py-1.5 text-sm font-medium {{ $statusColors[$order->status] ?? 'bg-gray-100 text-gray-500 border-gray-200' }}">
{{ $statusLabels[$order->status] ?? ucfirst($order->status) }}
</span>
</div>
</div>
<div class="grid gap-6 lg:grid-cols-3">
{{-- Main Content --}}
<div class="space-y-6 lg:col-span-2">
{{-- Order Details --}}
<div class="rounded-xl border border-gray-200 bg-white">
<div class="border-b border-gray-100 px-5 py-4">
<h2 class="text-sm font-semibold text-gray-900">Order Details</h2>
</div>
<div class="divide-y divide-gray-100">
<div class="flex items-center justify-between px-5 py-3">
<span class="text-sm text-gray-500">Domain</span>
<span class="text-sm font-medium text-gray-900">{{ $order->domain_name }}</span>
</div>
<div class="flex items-center justify-between px-5 py-3">
<span class="text-sm text-gray-500">Plan</span>
<span class="text-sm font-medium text-gray-900">{{ $order->product?->name ?? '-' }}</span>
</div>
<div class="flex items-center justify-between px-5 py-3">
<span class="text-sm text-gray-500">Billing Cycle</span>
<span class="text-sm font-medium text-gray-900">{{ ucfirst($order->billing_cycle) }}</span>
</div>
<div class="flex items-center justify-between px-5 py-3">
<span class="text-sm text-gray-500">Amount</span>
<span class="text-sm font-medium text-gray-900">{{ strtoupper($order->currency) }} {{ number_format($order->amount_paid, 2) }}</span>
</div>
<div class="flex items-center justify-between px-5 py-3">
<span class="text-sm text-gray-500">Created</span>
<span class="text-sm font-medium text-gray-900">{{ $order->created_at->format('M d, Y H:i') }}</span>
</div>
@if ($order->expires_at)
<div class="flex items-center justify-between px-5 py-3">
<span class="text-sm text-gray-500">Expires</span>
<span class="text-sm font-medium text-gray-900">{{ $order->expires_at->format('M d, Y') }}</span>
</div>
@endif
</div>
</div>
{{-- Server Details (if active) --}}
@if ($order->isActive() && ($order->server_ip || $order->server_username || $order->control_panel_url))
<div class="rounded-xl border border-gray-200 bg-white">
<div class="border-b border-gray-100 px-5 py-4">
<h2 class="text-sm font-semibold text-gray-900">Server Details</h2>
</div>
<div class="divide-y divide-gray-100">
@if ($order->server_ip)
<div class="flex items-center justify-between px-5 py-3">
<span class="text-sm text-gray-500">IP Address</span>
<span class="font-mono text-sm font-medium text-gray-900">{{ $order->server_ip }}</span>
</div>
@endif
@if ($order->server_username)
<div class="flex items-center justify-between px-5 py-3">
<span class="text-sm text-gray-500">Username</span>
<span class="font-mono text-sm font-medium text-gray-900">{{ $order->server_username }}</span>
</div>
@endif
@if ($order->hostingNode)
<div class="flex items-center justify-between px-5 py-3">
<span class="text-sm text-gray-500">Server</span>
<span class="text-sm font-medium text-gray-900">{{ $order->hostingNode->hostname }}</span>
</div>
@endif
@if ($order->control_panel_url)
<div class="flex items-center justify-between px-5 py-3">
<span class="text-sm text-gray-500">Control Panel</span>
<a href="{{ $order->control_panel_url }}" target="_blank" class="text-sm font-medium text-blue-600 hover:text-blue-700">
Open cPanel
</a>
</div>
@endif
</div>
</div>
@endif
{{-- Plan Resources --}}
@if ($order->product)
<div class="rounded-xl border border-gray-200 bg-white">
<div class="border-b border-gray-100 px-5 py-4">
<h2 class="text-sm font-semibold text-gray-900">Plan Resources</h2>
</div>
<div class="grid grid-cols-2 gap-4 p-5 sm:grid-cols-4">
<div class="text-center">
<p class="text-2xl font-bold text-gray-900">{{ $order->product->formatDiskSize() }}</p>
<p class="text-xs text-gray-500">Storage</p>
</div>
<div class="text-center">
<p class="text-2xl font-bold text-gray-900">{{ $order->product->formatBandwidth() }}</p>
<p class="text-xs text-gray-500">Bandwidth</p>
</div>
<div class="text-center">
<p class="text-2xl font-bold text-gray-900">{{ $order->product->max_domains ?? '∞' }}</p>
<p class="text-xs text-gray-500">Domains</p>
</div>
<div class="text-center">
<p class="text-2xl font-bold text-gray-900">{{ $order->product->max_databases ?? '∞' }}</p>
<p class="text-xs text-gray-500">Databases</p>
</div>
</div>
</div>
@endif
</div>
{{-- Sidebar --}}
<div class="space-y-6">
{{-- Quick Actions --}}
<div class="rounded-xl border border-gray-200 bg-white">
<div class="border-b border-gray-100 px-5 py-4">
<h2 class="text-sm font-semibold text-gray-900">Quick Actions</h2>
</div>
<div class="space-y-2 p-5">
@if ($order->control_panel_url && $order->isActive())
<a href="{{ $order->control_panel_url }}" target="_blank"
class="flex w-full items-center justify-center gap-2 rounded-lg bg-gray-900 px-4 py-2.5 text-sm font-medium text-white transition hover:bg-gray-800">
<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="M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"/></svg>
Open Control Panel
</a>
@endif
<a href="{{ ladill_account_url('/support-tickets/create') }}"
class="flex w-full items-center justify-center gap-2 rounded-lg border border-gray-200 bg-white px-4 py-2.5 text-sm font-medium text-gray-700 transition hover:bg-gray-50">
<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="M9.879 7.519c1.171-1.025 3.071-1.025 4.242 0 1.172 1.025 1.172 2.687 0 3.712-.203.179-.43.326-.67.442-.745.361-1.45.999-1.45 1.827v.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-9 5.25h.008v.008H12v-.008Z"/></svg>
Get Support
</a>
@if ($order->canBeCancelled())
<button @click="showCancelModal = true" type="button"
class="flex w-full items-center justify-center gap-2 rounded-lg border border-red-200 bg-white px-4 py-2.5 text-sm font-medium text-red-600 transition hover:bg-red-50">
<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="M6 18 18 6M6 6l12 12"/></svg>
Cancel Order
</button>
@endif
</div>
</div>
{{-- Status Timeline --}}
<div class="rounded-xl border border-gray-200 bg-white">
<div class="border-b border-gray-100 px-5 py-4">
<h2 class="text-sm font-semibold text-gray-900">Status</h2>
</div>
<div class="p-5">
<div class="space-y-3">
<div class="flex items-center gap-3">
<div class="flex h-6 w-6 items-center justify-center rounded-full {{ $order->created_at ? 'bg-emerald-100' : 'bg-gray-100' }}">
<svg class="h-3 w-3 {{ $order->created_at ? 'text-emerald-600' : 'text-gray-400' }}" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 0 1 0 1.414l-8 8a1 1 0 0 1-1.414 0l-4-4a1 1 0 0 1 1.414-1.414L8 12.586l7.293-7.293a1 1 0 0 1 1.414 0Z" clip-rule="evenodd"/></svg>
</div>
<div>
<p class="text-sm font-medium text-gray-900">Order Placed</p>
<p class="text-xs text-gray-500">{{ $order->created_at->format('M d, Y H:i') }}</p>
</div>
</div>
<div class="flex items-center gap-3">
<div class="flex h-6 w-6 items-center justify-center rounded-full {{ $order->approved_at ? 'bg-emerald-100' : 'bg-gray-100' }}">
@if ($order->approved_at)
<svg class="h-3 w-3 text-emerald-600" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 0 1 0 1.414l-8 8a1 1 0 0 1-1.414 0l-4-4a1 1 0 0 1 1.414-1.414L8 12.586l7.293-7.293a1 1 0 0 1 1.414 0Z" clip-rule="evenodd"/></svg>
@else
<div class="h-2 w-2 rounded-full bg-gray-300"></div>
@endif
</div>
<div>
<p class="text-sm font-medium {{ $order->approved_at ? 'text-gray-900' : 'text-gray-400' }}">Approved</p>
@if ($order->approved_at)
<p class="text-xs text-gray-500">{{ $order->approved_at->format('M d, Y H:i') }}</p>
@endif
</div>
</div>
<div class="flex items-center gap-3">
<div class="flex h-6 w-6 items-center justify-center rounded-full {{ $order->provisioned_at ? 'bg-emerald-100' : 'bg-gray-100' }}">
@if ($order->provisioned_at)
<svg class="h-3 w-3 text-emerald-600" fill="currentColor" viewBox="0 0 20 20"><path fill-rule="evenodd" d="M16.707 5.293a1 1 0 0 1 0 1.414l-8 8a1 1 0 0 1-1.414 0l-4-4a1 1 0 0 1 1.414-1.414L8 12.586l7.293-7.293a1 1 0 0 1 1.414 0Z" clip-rule="evenodd"/></svg>
@else
<div class="h-2 w-2 rounded-full bg-gray-300"></div>
@endif
</div>
<div>
<p class="text-sm font-medium {{ $order->provisioned_at ? 'text-gray-900' : 'text-gray-400' }}">Provisioned</p>
@if ($order->provisioned_at)
<p class="text-xs text-gray-500">{{ $order->provisioned_at->format('M d, Y H:i') }}</p>
@endif
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{{-- Cancel Modal --}}
<template x-teleport="body">
<div x-show="showCancelModal" x-cloak class="fixed inset-0 z-50 overflow-y-auto sm:flex sm:items-center sm:justify-center sm:p-4" @keydown.escape.window="showCancelModal = false">
<div x-show="showCancelModal" x-transition class="fixed inset-0 bg-gray-900/50 backdrop-blur-sm hidden sm:block" @click="showCancelModal = false"></div>
<div x-show="showCancelModal" x-transition class="relative min-h-full sm:min-h-0 w-full sm:max-w-md sm:rounded-xl sm:border sm:border-gray-200 bg-white p-6 shadow-xl" @click.stop>
<button @click="showCancelModal = false" type="button" class="absolute top-3 right-3 z-10 flex h-8 w-8 items-center justify-center rounded-full text-gray-400 hover:bg-gray-100 hover:text-gray-600 sm:hidden"><svg class="h-5 w-5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12"/></svg></button>
<h3 class="text-lg font-semibold text-gray-900">Cancel Order</h3>
<p class="mt-2 text-sm text-gray-500">Are you sure you want to cancel this order? This action cannot be undone.</p>
<form action="{{ route('hosting.orders.cancel', $order) }}" method="POST" class="mt-4">
@csrf
<div class="flex items-center justify-end gap-3">
<button @click="showCancelModal = false" type="button" class="rounded-lg px-4 py-2 text-sm font-medium text-gray-500 hover:text-gray-700">Keep Order</button>
<button type="submit" class="rounded-lg bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-700">Cancel Order</button>
</div>
</form>
</div>
</div>
</template>
</div>
</x-user-layout>