From e39a47fa1f464d8bd254eeb241b6c427611d26d5 Mon Sep 17 00:00:00 2001 From: isaacclad Date: Sat, 6 Jun 2026 17:13:46 +0000 Subject: [PATCH] Land on account overview and import hosted sites. Route launcher and home hub entry to the account overview instead of the control panel, label the sidebar app launcher, and extend hosting:import to sync hosted_sites with platform_id matching for existing accounts. Co-authored-by: Cursor --- app/Console/Commands/ImportHostingCommand.php | 47 ++++++++++++++++++- .../Hosting/HostingProductController.php | 5 +- app/Models/HostingAccount.php | 1 + .../views/hosting/accounts-list.blade.php | 2 +- resources/views/partials/launcher.blade.php | 18 +++++-- resources/views/partials/sidebar.blade.php | 4 +- 6 files changed, 69 insertions(+), 8 deletions(-) diff --git a/app/Console/Commands/ImportHostingCommand.php b/app/Console/Commands/ImportHostingCommand.php index 6a653ea..d692622 100644 --- a/app/Console/Commands/ImportHostingCommand.php +++ b/app/Console/Commands/ImportHostingCommand.php @@ -3,6 +3,7 @@ namespace App\Console\Commands; use App\Models\CustomerHostingOrder; +use App\Models\HostedSite; use App\Models\HostingAccount; use App\Models\HostingAccountMember; use App\Models\HostingBillingInvoice; @@ -72,6 +73,9 @@ class ImportHostingCommand extends Command foreach ($payload['hosting_accounts'] ?? [] as $row) { $this->importAccount($row, $commit); } + foreach ($payload['hosted_sites'] ?? [] as $row) { + $this->importSite($row, $commit); + } foreach ($payload['customer_hosting_orders'] ?? [] as $row) { $this->importCustomerOrder($row, $commit); } @@ -90,6 +94,10 @@ class ImportHostingCommand extends Command }); $this->info(($commit ? 'Imported' : 'Would import').' '.count($this->accountMap).' hosting account(s).'); + $siteCount = count($payload['hosted_sites'] ?? []); + if ($siteCount > 0) { + $this->info(($commit ? 'Imported' : 'Would import')." {$siteCount} hosted site(s)."); + } return self::SUCCESS; } @@ -134,7 +142,18 @@ class ImportHostingCommand extends Command } if ($commit) { - $account = HostingAccount::updateOrCreate(['platform_id' => $platformId], $row); + $account = HostingAccount::query()->where('platform_id', $platformId)->first(); + + if (! $account && ($row['username'] ?? '') !== '') { + $account = HostingAccount::query()->where('username', $row['username'])->first(); + } + + if ($account) { + $account->update($row); + } else { + $account = HostingAccount::create($row); + } + $this->accountMap[$platformId] = $account->id; } else { $this->accountMap[$platformId] = $platformId; @@ -142,6 +161,32 @@ class ImportHostingCommand extends Command } } + /** @param array $row */ + private function importSite(array $row, bool $commit): void + { + $platformAccountId = (int) ($row['platform_hosting_account_id'] ?? 0); + $localAccountId = $this->accountMap[$platformAccountId] ?? null; + + if (! $localAccountId) { + $this->warn("Skipping site {$row['domain']}: unknown hosting account #{$platformAccountId}"); + + return; + } + + unset($row['platform_hosting_account_id'], $row['platform_id']); + $row['hosting_account_id'] = $localAccountId; + $row['domain_id'] = null; + + if ($commit) { + HostedSite::withTrashed()->updateOrCreate( + ['hosting_account_id' => $localAccountId, 'domain' => $row['domain']], + $row + ); + } else { + $this->line(" site {$row['domain']} → account {$localAccountId}"); + } + } + /** @param array $row */ private function importCustomerOrder(array $row, bool $commit): void { diff --git a/app/Http/Controllers/Hosting/HostingProductController.php b/app/Http/Controllers/Hosting/HostingProductController.php index b8a92a3..d207d36 100644 --- a/app/Http/Controllers/Hosting/HostingProductController.php +++ b/app/Http/Controllers/Hosting/HostingProductController.php @@ -76,10 +76,11 @@ class HostingProductController extends Controller ]); } - // Single account - redirect directly to panel + // Single account — account overview (matches monolith; panel via Control Panel) if ($allAccounts->count() === 1) { $account = $allAccounts->first(); - return redirect()->route('hosting.panel.index', $account); + + return redirect()->route('hosting.accounts.show', $account); } // Multiple accounts - show list page diff --git a/app/Models/HostingAccount.php b/app/Models/HostingAccount.php index 782e0a8..4246efd 100644 --- a/app/Models/HostingAccount.php +++ b/app/Models/HostingAccount.php @@ -35,6 +35,7 @@ class HostingAccount extends Model public const GRACE_PERIOD_MONTHS = 3; protected $fillable = [ + 'platform_id', 'user_id', 'hosting_product_id', 'hosting_node_id', diff --git a/resources/views/hosting/accounts-list.blade.php b/resources/views/hosting/accounts-list.blade.php index 03211b3..6504aa9 100644 --- a/resources/views/hosting/accounts-list.blade.php +++ b/resources/views/hosting/accounts-list.blade.php @@ -10,7 +10,7 @@
@foreach($accounts as $account) -
diff --git a/resources/views/partials/launcher.blade.php b/resources/views/partials/launcher.blade.php index 7031a61..c26873d 100644 --- a/resources/views/partials/launcher.blade.php +++ b/resources/views/partials/launcher.blade.php @@ -4,6 +4,7 @@ // from public/images/launcher-icons/. Omits the current app (matched by // APP_URL host). To replicate elsewhere, copy this file + the config + // the launcher-icons folder verbatim. + $sidebar = (bool) ($sidebar ?? false); $selfHost = parse_url((string) config('app.url'), PHP_URL_HOST); $launcherApps = array_values(array_filter( config('ladill_launcher.apps', []), @@ -13,17 +14,28 @@ @if (! empty($launcherApps))