service = $service->load(['user', 'product', 'product.server', 'product.server.settings', 'product.settings', 'properties']); $this->loadServiceData(); } protected function loadServiceData(): void { $server = $this->service->product->server; if (!$server || $server->extension !== 'ManualServers') { Notification::make() ->title('Invalid Server') ->body('This service does not use the ManualServers extension.') ->danger() ->send(); $this->redirect(ManualServersQueue::getUrl()); return; } $config = $server->settings->pluck('value', 'key')->toArray(); $extension = new ManualServers($config); $data = $extension->getServiceData($this->service); $this->deployStatus = $data['status']; $this->processData = $data['processes']; $this->credentialData = $data['credentials']; $this->credentialFields = $data['credential_fields']; $this->feedback = $data['feedback']; } public function getTitle(): string { return 'Manual Server #' . $this->service?->id; } public static function canAccess(): bool { return auth()->check() && auth()->user()->can('viewAny', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class); } protected function getHeaderActions(): array { return []; } public function toggleProcess(int $index): void { abort_unless(auth()->user()?->can('manage', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class), 403); $server = $this->service->product->server; $config = $server->settings->pluck('value', 'key')->toArray(); $extension = new ManualServers($config); $currentStatus = $this->processData[$index]['completed'] ?? false; $extension->updateProcessStatus($this->service, $index, !$currentStatus); $this->service->refresh(); $this->loadServiceData(); Notification::make() ->title(!$currentStatus ? 'Setup Step Completed' : 'Setup Step Reverted') ->success() ->send(); } public function deployAction(): Action { $fields = []; foreach ($this->credentialFields as $field) { $type = $field['type'] ?? 'text'; if ($type === 'textarea') { $fields[] = Textarea::make($field['name']) ->label($field['label']) ->required(); } elseif ($type === 'password') { $fields[] = TextInput::make($field['name']) ->label($field['label']) ->password() ->required(); } else { $fields[] = TextInput::make($field['name']) ->label($field['label']) ->required(); } } return Action::make('deploy') ->label('Deploy Server') ->color('success') ->requiresConfirmation() ->modalHeading('Deploy Manual Server') ->modalDescription('Enter the server credentials to provide to the client.') ->form($fields) ->action(function (array $data): void { abort_unless(auth()->user()?->can('deploy', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class), 403); $server = $this->service->product->server; $config = $server->settings->pluck('value', 'key')->toArray(); $extension = new ManualServers($config); $extension->deployService($this->service, $data); $this->service->refresh(); $this->loadServiceData(); Notification::make() ->title('Server Deployed') ->body('Server credentials have been saved and the server is now marked as deployed.') ->success() ->send(); }) ->visible(fn () => auth()->user()?->can('deploy', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class) && $this->areAllProcessesCompleted() && $this->deployStatus !== 'deployed'); } public function editCredentialsAction(): Action { $fields = []; foreach ($this->credentialFields as $field) { $type = $field['type'] ?? 'text'; $defaultValue = $this->credentialData[$field['name']] ?? ''; if ($type === 'textarea') { $fields[] = Textarea::make($field['name']) ->label($field['label']) ->default($defaultValue) ->required(); } elseif ($type === 'password') { $fields[] = TextInput::make($field['name']) ->label($field['label']) ->default($defaultValue) ->password() ->required(); } else { $fields[] = TextInput::make($field['name']) ->label($field['label']) ->default($defaultValue) ->required(); } } return Action::make('editCredentials') ->label('Edit Server Credentials') ->color('warning') ->modalHeading('Edit Server Credentials') ->modalDescription('Update the server credentials that were provided to the client.') ->form($fields) ->action(function (array $data): void { abort_unless(auth()->user()?->can('credentials', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class), 403); $this->service->properties()->updateOrCreate( ['key' => 'credentials_data'], ['value' => json_encode($data)] ); $this->service->refresh(); $this->loadServiceData(); Notification::make() ->title('Server Credentials Updated') ->body('The server credentials have been updated successfully.') ->success() ->send(); }) ->visible(fn () => auth()->user()?->can('credentials', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class) && $this->deployStatus === 'deployed' && !empty($this->credentialData)); } public function reverseDeploymentAction(): Action { return Action::make('reverseDeployment') ->label('Reverse Deployment') ->color('danger') ->requiresConfirmation() ->modalHeading('Reverse Deployment') ->modalDescription('This will set the server back to pending, clear credentials, and reset all setup steps.') ->action(function (): void { abort_unless(auth()->user()?->can('manage', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class), 403); $server = $this->service->product->server; $config = $server->settings->pluck('value', 'key')->toArray(); $extension = new ManualServers($config); $extension->reverseDeployment($this->service, true); $this->service->refresh(); $this->loadServiceData(); Notification::make() ->title('Deployment Reversed') ->body('Server is set back to pending and setup steps are reset.') ->success() ->send(); }) ->visible(fn () => auth()->user()?->can('manage', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class) && $this->deployStatus === 'deployed'); } public function feedbackAction(): Action { return Action::make('feedback') ->label('Send Message to Client') ->color('info') ->modalHeading('Send Message to Client') ->modalDescription('Send a message or instructions to the client regarding their manual server.') ->form([ Textarea::make('feedback') ->label('Message') ->placeholder('e.g. Please point your domain to 1.2.3.4') ->default($this->feedback) ->rows(5), ]) ->action(function (array $data): void { abort_unless(auth()->user()?->can('message', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class), 403); $this->service->properties()->updateOrCreate( ['key' => 'feedback'], ['value' => $data['feedback'] ?? ''] ); $this->service->refresh(); $this->loadServiceData(); Notification::make() ->title('Message Sent') ->body('The message has been sent to the client and will be visible on their server page.') ->success() ->send(); }) ->visible(fn () => auth()->user()?->can('message', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class)); } public function initializeProcesses(): void { abort_unless(auth()->user()?->can('manage', \Paymenter\Extensions\Servers\ManualServers\ManualServers::class), 403); $server = $this->service->product->server; $config = $server->settings->pluck('value', 'key')->toArray(); $extension = new ManualServers($config); $extension->createServer($this->service); $this->service->refresh(); $this->loadServiceData(); Notification::make() ->title('Setup Steps Initialized') ->body('The manual server setup steps have been configured and are ready to track.') ->success() ->send(); } public function areAllProcessesCompleted(): bool { if (empty($this->processData)) return false; foreach ($this->processData as $process) { if (!($process['completed'] ?? false)) { return false; } } return true; } }