record = CompanyProfileModel::firstOrNew([ 'company_id' => auth()->user()->currentCompany->id, ]); abort_unless(static::canView($this->record), 404); $this->fillForm(); } public function fillForm(): void { $data = $this->record->attributesToArray(); $this->form->fill($data); } public function save(): void { try { $data = $this->form->getState(); $this->handleRecordUpdate($this->record, $data); } catch (Halt $exception) { return; } $this->getSavedNotification()->send(); } protected function updateTimezone(string $countryCode): void { $model = \App\Models\Setting\Localization::firstOrFail(); $timezones = Timezone::getTimezonesForCountry($countryCode); if (! empty($timezones)) { $model->update([ 'timezone' => $timezones[0], ]); } } protected function getTimezoneChangeNotification(): Notification { return Notification::make() ->info() ->title('Timezone Update Required') ->body('You have changed your country or state. Please update your timezone to ensure accurate date and time information.') ->actions([ \Filament\Notifications\Actions\Action::make('updateTimezone') ->label('Update Timezone') ->url(Localization::getUrl()), ]) ->persistent() ->send(); } protected function getSavedNotification(): Notification { return Notification::make() ->success() ->title(__('filament-panels::resources/pages/edit-record.notifications.saved.title')); } public function form(Form $form): Form { return $form ->schema([ $this->getIdentificationSection(), $this->getNeedsAddressCompletionAlert(), $this->getLocationDetailsSection(), $this->getLegalAndComplianceSection(), ]) ->model($this->record) ->statePath('data') ->operation('edit'); } protected function getIdentificationSection(): Component { return Section::make('Identification') ->schema([ Group::make() ->schema([ TextInput::make('email') ->email() ->localizeLabel() ->maxLength(255) ->softRequired(), TextInput::make('phone_number') ->tel() ->localizeLabel(), ])->columns(1), FileUpload::make('logo') ->openable() ->maxSize(2048) ->localizeLabel() ->visibility('public') ->disk('public') ->directory('logos/company') ->imageResizeMode('contain') ->imageCropAspectRatio('1:1') ->panelAspectRatio('1:1') ->panelLayout('integrated') ->removeUploadedFileButtonPosition('center bottom') ->uploadButtonPosition('center bottom') ->uploadProgressIndicatorPosition('center bottom') ->getUploadedFileNameForStorageUsing( static fn (TemporaryUploadedFile $file): string => (string) str($file->getClientOriginalName()) ->prepend(Auth::user()->currentCompany->id . '_'), ) ->extraAttributes(['class' => 'w-32 h-32']) ->acceptedFileTypes(['image/png', 'image/jpeg']), ])->columns(); } protected function getNeedsAddressCompletionAlert(): Component { return SimpleAlert::make('needsAddressCompletion') ->warning() ->border() ->icon('heroicon-o-exclamation-triangle') ->title('Address Information Incomplete') ->description('Please complete the required address information for proper business operations.') ->visible(fn (CompanyProfileModel $record) => $record->address->isIncomplete()) ->columnSpanFull(); } protected function getLocationDetailsSection(): Component { return Section::make('Address Information') ->relationship('address') ->schema([ Hidden::make('type') ->default('general'), TextInput::make('address_line_1') ->label('Address Line 1') ->softRequired() ->maxLength(255), TextInput::make('address_line_2') ->label('Address Line 2') ->maxLength(255), CountrySelect::make('country') ->clearStateField() ->softRequired(), Select::make('state_id') ->localizeLabel('State / Province') ->searchable() ->options(static fn (Get $get) => State::getStateOptions($get('country'))), TextInput::make('city') ->localizeLabel('City / Town') ->softRequired() ->maxLength(255), TextInput::make('postal_code') ->label('Postal Code / Zip Code') ->maxLength(255), ]) ->columns(2); } protected function getLegalAndComplianceSection(): Component { return Section::make('Legal & Compliance') ->schema([ Select::make('entity_type') ->localizeLabel() ->options(EntityType::class) ->softRequired(), TextInput::make('tax_id') ->localizeLabel('Tax ID') ->maxLength(50), ])->columns(); } protected function handleRecordUpdate(CompanyProfileModel $record, array $data): CompanyProfileModel { $record->fill($data); $keysToWatch = [ 'logo', ]; if ($record->isDirty($keysToWatch)) { $this->dispatch('companyProfileUpdated'); } $record->save(); return $record; } /** * @return array */ protected function getFormActions(): array { return [ $this->getSaveFormAction(), ]; } protected function getSaveFormAction(): Action { return Action::make('save') ->label(__('filament-panels::resources/pages/edit-record.form.actions.save.label')) ->submit('save') ->keyBindings(['mod+s']); } public static function canView(Model $record): bool { try { return authorize('update', $record)->allowed(); } catch (AuthorizationException $exception) { return $exception->toResponse()->allowed(); } } }