|null */ public ?array $data = []; #[Locked] public SiteSetting $record; public static function canAccess(): bool { $user = auth()->user(); return $user !== null && $user->isAdmin(); } public function mount(): void { $this->record = SiteSetting::instance(); abort_unless(auth()->user()?->can('update', $this->record), 403); $this->fillForm(); } public function hydrate(): void { abort_unless(auth()->user()?->can('update', $this->record), 403); } protected function fillForm(): void { $this->form->fill($this->record->attributesToArray()); } public function save(): void { try { $this->beginDatabaseTransaction(); $data = $this->form->getState(); $this->record->update($data); } catch (Halt $exception) { $exception->shouldRollbackDatabaseTransaction() ? $this->rollBackDatabaseTransaction() : $this->commitDatabaseTransaction(); return; } catch (Throwable $exception) { $this->rollBackDatabaseTransaction(); throw $exception; } $this->commitDatabaseTransaction(); Notification::make() ->success() ->title('Configurações salvas com sucesso.') ->send(); if ($redirectUrl = $this->getRedirectUrl()) { $this->redirect($redirectUrl, navigate: FilamentView::hasSpaMode($redirectUrl)); } } protected function getRedirectUrl(): ?string { return null; } public function defaultForm(Schema $schema): Schema { return $schema ->operation('edit') ->model($this->record) ->statePath('data'); } public function form(Schema $schema): Schema { return $schema ->components([ Section::make('Marca e hero') ->schema([ TextInput::make('brand_name') ->label('Nome da marca') ->required() ->maxLength(255), PublicImageUploadRules::fileUpload('logo_path', 'Logo da marca', 'content/logo'), PublicImageUploadRules::altTextField('logo_alt', 'logo_path', 'Texto alternativo do logo'), TextInput::make('hero_eyebrow') ->label('Eyebrow do hero') ->maxLength(255), TextInput::make('hero_title') ->label('Título do hero') ->required() ->maxLength(255), Textarea::make('hero_subtitle') ->label('Subtítulo do hero') ->required() ->rows(3), TextInput::make('hero_cta_label') ->label('Texto do CTA principal') ->required() ->maxLength(255), TextInput::make('hero_secondary_cta_label') ->label('Texto do CTA secundário') ->maxLength(255), Textarea::make('hero_note') ->label('Nota do hero') ->rows(2), Textarea::make('about_summary') ->label('Resumo institucional') ->rows(3), ]) ->columns(2), Section::make('Manifesto editorial') ->schema([ TextInput::make('manifesto_title') ->label('Título do manifesto') ->maxLength(255), Textarea::make('manifesto_lead') ->label('Lead do manifesto') ->rows(3), Textarea::make('manifesto_body') ->label('Corpo do manifesto') ->rows(4), ]), Section::make('Método') ->schema([ Textarea::make('method_intro') ->label('Introdução do método') ->rows(2), Repeater::make('method_steps') ->label('Passos do método') ->schema([ TextInput::make('title') ->label('Título') ->required() ->maxLength(255), Textarea::make('body') ->label('Descrição') ->required() ->rows(2), ]) ->defaultItems(0) ->maxItems(4) ->reorderable() ->columnSpanFull(), ]), Section::make('Princípios') ->schema([ TagsInput::make('principles') ->label('Princípios') ->placeholder('Adicionar princípio') ->helperText('Até quatro princípios editoriais.') ->columnSpanFull(), ]), Section::make('Contato') ->schema([ TextInput::make('email') ->label('E-mail') ->email() ->required() ->maxLength(255), TextInput::make('phone') ->label('Telefone') ->required() ->maxLength(255), TextInput::make('city') ->label('Cidade') ->maxLength(255), KeyValue::make('social_links') ->label('Redes sociais') ->keyLabel('Rede') ->valueLabel('URL') ->addActionLabel('Adicionar rede'), ]) ->columns(2), Section::make('Página Sobre') ->schema([ PublicImageUploadRules::fileUpload('about_image_path', 'Imagem da página Sobre', 'content/about'), PublicImageUploadRules::altTextField('about_image_alt', 'about_image_path'), ]) ->columns(2), Section::make('SEO padrão') ->schema([ TextInput::make('default_meta_title') ->label('Meta title padrão') ->required() ->maxLength(255), Textarea::make('default_meta_description') ->label('Meta description padrão') ->required() ->rows(3), PublicImageUploadRules::fileUpload('default_og_image_path', 'Imagem Open Graph padrão', 'content/og'), PublicImageUploadRules::altTextField('default_og_image_alt', 'default_og_image_path'), ]), Section::make('Analytics') ->schema([ Toggle::make('analytics_enabled') ->label('Analytics habilitado') ->default(false), Textarea::make('analytics_script') ->label('Script de analytics') ->rows(4) ->visible(fn (callable $get): bool => (bool) $get('analytics_enabled')), ]), ]); } /** * @return array */ protected function getFormActions(): array { return [ Action::make('save') ->label('Salvar') ->submit('save') ->keyBindings(['mod+s']), ]; } public function content(Schema $schema): Schema { return $schema ->components([ $this->getFormContentComponent(), ]); } public function getFormContentComponent(): Component { return Form::make([EmbeddedSchema::make('form')]) ->id('form') ->livewireSubmitHandler('save') ->footer([ Actions::make($this->getFormActions()) ->alignment($this->getFormActionsAlignment()) ->fullWidth($this->hasFullWidthFormActions()) ->sticky($this->areFormActionsSticky()) ->key('form-actions'), ]); } protected function hasFullWidthFormActions(): bool { return false; } }