|null */ public ?array $data = []; public static function canAccess(): bool { return Auth::user()?->can('settings.view') ?? false; } public static function getNavigationGroup(): string|UnitEnum|null { return __('panel.groups.administration'); } public static function getNavigationLabel(): string { return __('maintenance.title'); } public function getTitle(): string|Htmlable { return __('maintenance.title'); } public function getSubheading(): string|Htmlable|null { return __('maintenance.subheading'); } /** * A red badge in the sidebar while the site is down — this is not * something anyone should be able to forget about. */ public static function getNavigationBadge(): ?string { return Maintenance::isEnabled() ? __('maintenance.badge') : null; } public static function getNavigationBadgeColor(): ?string { return 'danger'; } public function mount(): void { $this->form->fill([ 'message' => Maintenance::messages(), 'until' => Maintenance::until()?->toDateTimeString(), ]); } public function form(Schema $schema): Schema { return $schema ->statePath('data') ->components([ Section::make(__('maintenance.notice')) ->description(__('maintenance.notice_hint')) ->schema([ Tabs::make('message') ->tabs(collect(config('locales.supported')) ->map(fn (array $meta, string $locale) => Tab::make($locale) ->label(trim(($meta['flag'] ?? '').' '.($meta['native'] ?? $locale))) ->schema([ Textarea::make("message.{$locale}") ->hiddenLabel() ->rows(3) ->placeholder(__('maintenance.default_message', [], $locale)) ->maxLength(500), ])) ->values() ->all()) ->columnSpanFull(), DateTimePicker::make('until') ->label(__('maintenance.until')) ->helperText(__('maintenance.until_hint')) ->seconds(false) ->minDate(now()), ]), ]); } /** * @return array */ protected function getHeaderActions(): array { return [ Action::make('enable') ->label(__('maintenance.enable')) ->icon('heroicon-o-exclamation-triangle') ->color('danger') ->requiresConfirmation() ->modalDescription(__('maintenance.enable_confirm')) ->visible(fn () => ! Maintenance::isEnabled() && $this->canToggle()) ->action(function (): void { $data = $this->form->getState(); Maintenance::enable( message: array_filter($data['message'] ?? [], fn ($v) => filled($v)), until: filled($data['until'] ?? null) ? CarbonImmutable::parse($data['until']) : null, ); Notification::make() ->warning() ->title(__('maintenance.enabled_notice')) ->send(); }), Action::make('disable') ->label(__('maintenance.disable')) ->icon('heroicon-o-check-circle') ->color('success') ->requiresConfirmation() ->visible(fn () => Maintenance::isEnabled() && $this->canToggle()) ->action(function (): void { Maintenance::disable(); Notification::make() ->success() ->title(__('maintenance.disabled_notice')) ->send(); }), Action::make('save') ->label(__('maintenance.save_message')) ->color('gray') ->visible(fn () => $this->canToggle()) ->action(function (): void { $data = $this->form->getState(); $messages = array_filter($data['message'] ?? [], fn ($v) => filled($v)); // Saving the wording must not itself take the site down. if (Maintenance::isEnabled()) { Maintenance::enable( message: $messages, until: filled($data['until'] ?? null) ? CarbonImmutable::parse($data['until']) : null, ); } else { Setting::set(Maintenance::KEY, [ ...Maintenance::state(), 'enabled' => false, 'message' => $messages, ]); } Notification::make() ->success() ->title(__('maintenance.message_saved')) ->send(); }), ]; } public function isEnabled(): bool { return Maintenance::isEnabled(); } public function startedAt(): ?string { return Maintenance::startedAt()?->diffForHumans(); } public function endsAt(): ?string { return Maintenance::until()?->isoFormat('LLL'); } public function canToggle(): bool { return Auth::user()?->can('settings.maintenance') ?? false; } }