From 4e787e126bd97de366e118ab126f6ead140b156b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petrekanics=20M=C3=A1t=C3=A9?= Date: Wed, 1 Oct 2025 17:22:34 +0200 Subject: [PATCH 1/3] feature add language switcher and translations --- .../SendDatabaseTestNotification.php | 8 +- .../SendDiscordTestNotification.php | 6 +- .../SendGotifyTestNotification.php | 6 +- .../SendHealthCheckTestNotification.php | 6 +- .../SendMailTestNotification.php | 4 +- .../SendNtfyTestNotification.php | 6 +- .../SendPushoverTestNotification.php | 6 +- .../SendSlackTestNotification.php | 6 +- .../SendTelegramTestNotification.php | 4 +- .../SendWebhookTestNotification.php | 6 +- app/Console/Commands/OoklaListServers.php | 2 +- app/Console/Commands/ResultFixStatuses.php | 10 +- app/Console/Commands/UserChangeRole.php | 10 +- app/Console/Commands/UserResetPassword.php | 6 +- app/Enums/ResultService.php | 2 +- app/Enums/ResultStatus.php | 2 +- app/Enums/UserRole.php | 2 +- app/Filament/Exports/ResultExporter.php | 27 +- .../Pages/Settings/DataIntegrationPage.php | 45 +-- .../Pages/Settings/NotificationPage.php | 186 ++++++----- .../Pages/Settings/ThresholdsPage.php | 19 +- .../ApiTokenResource/Pages/ListApiTokens.php | 6 +- app/Filament/Widgets/StatsOverviewWidget.php | 24 +- app/Providers/Filament/AdminPanelProvider.php | 31 +- app/Rules/Cron.php | 2 +- composer.json | 1 + composer.lock | 77 ++++- lang/en/translations.php | 290 ++++++++++++++++++ package-lock.json | 6 + 29 files changed, 624 insertions(+), 182 deletions(-) create mode 100644 lang/en/translations.php diff --git a/app/Actions/Notifications/SendDatabaseTestNotification.php b/app/Actions/Notifications/SendDatabaseTestNotification.php index 6611ad491..2c50f39f0 100644 --- a/app/Actions/Notifications/SendDatabaseTestNotification.php +++ b/app/Actions/Notifications/SendDatabaseTestNotification.php @@ -14,15 +14,15 @@ public function handle(User $user) { $user->notify( Notification::make() - ->title('Test database notification received!') - ->body('You say pong') + ->title(__('translations.notifications.database.received')) + ->body(__('translations.notifications.database.pong')) ->success() ->toDatabase(), ); Notification::make() - ->title('Test database notification sent.') - ->body('I say ping') + ->title(__('translations.notifications.database.sent')) + ->body(__('translations.notifications.database.ping')) ->success() ->send(); } diff --git a/app/Actions/Notifications/SendDiscordTestNotification.php b/app/Actions/Notifications/SendDiscordTestNotification.php index edad6d239..dda8ad924 100644 --- a/app/Actions/Notifications/SendDiscordTestNotification.php +++ b/app/Actions/Notifications/SendDiscordTestNotification.php @@ -14,7 +14,7 @@ public function handle(array $webhooks) { if (! count($webhooks)) { Notification::make() - ->title('You need to add Discord urls!') + ->title(__('translations.notifications.discord.add')) ->warning() ->send(); @@ -24,13 +24,13 @@ public function handle(array $webhooks) foreach ($webhooks as $webhook) { WebhookCall::create() ->url($webhook['url']) - ->payload(['content' => '👋 Testing the Discord notification channel.']) + ->payload(['content' => __('translations.notifications.discord.payload')]) ->doNotSign() ->dispatch(); } Notification::make() - ->title('Test Discord notification sent.') + ->title(__('translations.notifications.discord.sent')) ->success() ->send(); } diff --git a/app/Actions/Notifications/SendGotifyTestNotification.php b/app/Actions/Notifications/SendGotifyTestNotification.php index fdd6405de..54fde0766 100644 --- a/app/Actions/Notifications/SendGotifyTestNotification.php +++ b/app/Actions/Notifications/SendGotifyTestNotification.php @@ -14,7 +14,7 @@ public function handle(array $webhooks) { if (! count($webhooks)) { Notification::make() - ->title('You need to add Gotify urls!') + ->title(__('translations.notifications.gotfy.add')) ->warning() ->send(); @@ -24,13 +24,13 @@ public function handle(array $webhooks) foreach ($webhooks as $webhook) { WebhookCall::create() ->url($webhook['url']) - ->payload(['message' => '👋 Testing the Gotify notification channel.']) + ->payload(['message' => __('translations.notifications.gotfy.payload')]) ->doNotSign() ->dispatch(); } Notification::make() - ->title('Test Gotify notification sent.') + ->title(__('translations.notifications.gotfy.sent')) ->success() ->send(); } diff --git a/app/Actions/Notifications/SendHealthCheckTestNotification.php b/app/Actions/Notifications/SendHealthCheckTestNotification.php index f37e20fad..ceccf15ac 100644 --- a/app/Actions/Notifications/SendHealthCheckTestNotification.php +++ b/app/Actions/Notifications/SendHealthCheckTestNotification.php @@ -14,7 +14,7 @@ public function handle(array $webhooks) { if (! count($webhooks)) { Notification::make() - ->title('You need to add HealthCheck.io urls!') + ->title(__('translations.notifications.health_check.add')) ->warning() ->send(); @@ -24,13 +24,13 @@ public function handle(array $webhooks) foreach ($webhooks as $webhook) { WebhookCall::create() ->url($webhook['url']) - ->payload(['message' => '👋 Testing the HealthCheck.io notification channel.']) + ->payload(['message' => __('translations.notifications.health_check.payload')]) ->doNotSign() ->dispatch(); } Notification::make() - ->title('Test HealthCheck.io notification sent.') + ->title(__('translations.notifications.health_check.sent')) ->success() ->send(); } diff --git a/app/Actions/Notifications/SendMailTestNotification.php b/app/Actions/Notifications/SendMailTestNotification.php index df293ef6b..e5139436a 100644 --- a/app/Actions/Notifications/SendMailTestNotification.php +++ b/app/Actions/Notifications/SendMailTestNotification.php @@ -15,7 +15,7 @@ public function handle(array $recipients) { if (! count($recipients)) { Notification::make() - ->title('You need to add mail recipients!') + ->title(__('translations.notifications.mail.add')) ->warning() ->send(); @@ -28,7 +28,7 @@ public function handle(array $recipients) } Notification::make() - ->title('Test mail notification sent.') + ->title(__('translations.notifications.mail.sent')) ->success() ->send(); } diff --git a/app/Actions/Notifications/SendNtfyTestNotification.php b/app/Actions/Notifications/SendNtfyTestNotification.php index 8975febaa..ae1812375 100644 --- a/app/Actions/Notifications/SendNtfyTestNotification.php +++ b/app/Actions/Notifications/SendNtfyTestNotification.php @@ -14,7 +14,7 @@ public function handle(array $webhooks) { if (! count($webhooks)) { Notification::make() - ->title('You need to add ntfy urls!') + ->title(__('translations.notifications.ntfy.add')) ->warning() ->send(); @@ -26,7 +26,7 @@ public function handle(array $webhooks) ->url($webhook['url']) ->payload([ 'topic' => $webhook['topic'], - 'message' => '👋 Testing the ntfy notification channel.', + 'message' => __('translations.notifications.ntfy.payload'), ]) ->doNotSign(); @@ -42,7 +42,7 @@ public function handle(array $webhooks) } Notification::make() - ->title('Test ntfy notification sent.') + ->title(__('translations.notifications.ntfy.sent')) ->success() ->send(); } diff --git a/app/Actions/Notifications/SendPushoverTestNotification.php b/app/Actions/Notifications/SendPushoverTestNotification.php index d37b0594d..a2c9f865e 100644 --- a/app/Actions/Notifications/SendPushoverTestNotification.php +++ b/app/Actions/Notifications/SendPushoverTestNotification.php @@ -14,7 +14,7 @@ public function handle(array $webhooks) { if (! count($webhooks)) { Notification::make() - ->title('You need to add Pushover URLs!') + ->title(__('translations.notifications.pushover.add')) ->warning() ->send(); @@ -27,14 +27,14 @@ public function handle(array $webhooks) ->payload([ 'token' => $webhook['api_token'], 'user' => $webhook['user_key'], - 'message' => '👋 Testing the Pushover notification channel.', + 'message' => __('translations.notifications.pushover.payload'), ]) ->doNotSign() ->dispatch(); } Notification::make() - ->title('Test Pushover notification sent.') + ->title(__('translations.notifications.pushover.sent')) ->success() ->send(); } diff --git a/app/Actions/Notifications/SendSlackTestNotification.php b/app/Actions/Notifications/SendSlackTestNotification.php index 95db18439..640e0e080 100644 --- a/app/Actions/Notifications/SendSlackTestNotification.php +++ b/app/Actions/Notifications/SendSlackTestNotification.php @@ -14,7 +14,7 @@ public function handle(array $webhooks) { if (! count($webhooks)) { Notification::make() - ->title('You need to add Slack URLs!') + ->title(__('translations.notifications.slack.add')) ->warning() ->send(); @@ -24,13 +24,13 @@ public function handle(array $webhooks) foreach ($webhooks as $webhook) { WebhookCall::create() ->url($webhook['url']) - ->payload(['text' => '👋 Testing the Slack notification channel.']) + ->payload(['text' => __('translations.notifications.slack.payload')]) ->doNotSign() ->dispatch(); } Notification::make() - ->title('Test Slack notification sent.') + ->title(__('translations.notifications.slack.sent')) ->success() ->send(); } diff --git a/app/Actions/Notifications/SendTelegramTestNotification.php b/app/Actions/Notifications/SendTelegramTestNotification.php index c7c64a815..72a96812d 100644 --- a/app/Actions/Notifications/SendTelegramTestNotification.php +++ b/app/Actions/Notifications/SendTelegramTestNotification.php @@ -15,7 +15,7 @@ public function handle(array $recipients) { if (! count($recipients)) { Notification::make() - ->title('You need to add Telegram recipients!') + ->title(__('translations.notifications.telegram.add')) ->warning() ->send(); @@ -28,7 +28,7 @@ public function handle(array $recipients) } Notification::make() - ->title('Test Telegram notification sent.') + ->title(__('translations.notifications.telegram.sent')) ->success() ->send(); } diff --git a/app/Actions/Notifications/SendWebhookTestNotification.php b/app/Actions/Notifications/SendWebhookTestNotification.php index 834a1d0cc..995f003b9 100644 --- a/app/Actions/Notifications/SendWebhookTestNotification.php +++ b/app/Actions/Notifications/SendWebhookTestNotification.php @@ -17,7 +17,7 @@ public function handle(array $webhooks) { if (! count($webhooks)) { Notification::make() - ->title('You need to add webhook URLs!') + ->title(__('translations.notifications.webhook.add')) ->warning() ->send(); @@ -32,7 +32,7 @@ public function handle(array $webhooks) ->url($webhook['url']) ->payload([ 'result_id' => Str::uuid(), - 'site_name' => 'Webhook Notification Testing', + 'site_name' => __('translations.notifications.webhook.payload'), 'isp' => $fakeResult->data['isp'], 'ping' => $fakeResult->ping, 'download' => $fakeResult->download, @@ -46,7 +46,7 @@ public function handle(array $webhooks) } Notification::make() - ->title('Test webhook notification sent.') + ->title(__('translations.notifications.webhook.sent')) ->success() ->send(); } diff --git a/app/Console/Commands/OoklaListServers.php b/app/Console/Commands/OoklaListServers.php index 5710a1bee..584eb9a73 100644 --- a/app/Console/Commands/OoklaListServers.php +++ b/app/Console/Commands/OoklaListServers.php @@ -40,7 +40,7 @@ public function handle(): void ); if ($response->failed()) { - $this->fail('There was an issue retrieving a list of speedtest servers, check the logs.'); + $this->fail(__('translations.ookla_error')); } $fields = ['id', 'sponsor', 'name', 'country', 'distance']; diff --git a/app/Console/Commands/ResultFixStatuses.php b/app/Console/Commands/ResultFixStatuses.php index 16aa20f64..5188ae74d 100644 --- a/app/Console/Commands/ResultFixStatuses.php +++ b/app/Console/Commands/ResultFixStatuses.php @@ -30,11 +30,11 @@ public function handle(): void { $this->newLine(); - $this->info('This will check each result and correct the status to "completed" or "failed" based on the data column.'); - $this->info('📖 Read the docs: https://docs.speedtest-tracker.dev/other/commands'); + $this->info(__('translations.status_fix.info_1')); + $this->info(__('translations.status_fix.info_2')); - if (! $this->confirm('Do you want to continue?')) { - $this->fail('Command cancelled.'); + if (! $this->confirm(__('translations.confirm'))) { + $this->fail(__('translations.fail')); } /** @@ -63,6 +63,6 @@ public function handle(): void 'status' => ResultStatus::Failed, ]); - $this->line('✅ finished!'); + $this->line(__('translations.status_fix.finished')); } } diff --git a/app/Console/Commands/UserChangeRole.php b/app/Console/Commands/UserChangeRole.php index e21db8f96..38dae7fee 100644 --- a/app/Console/Commands/UserChangeRole.php +++ b/app/Console/Commands/UserChangeRole.php @@ -31,7 +31,7 @@ class UserChangeRole extends Command public function handle(): void { $email = text( - label: 'What is the email address?', + label: __('translations.user_change.what_is_the_email_address'), required: true, validate: fn (string $value) => match (true) { ! User::firstWhere('email', $value) => 'User not found.', @@ -40,10 +40,10 @@ public function handle(): void ); $role = select( - label: 'What role should the user have?', + label: __('translations.user_change.what_role'), options: [ - 'admin' => 'Admin', - 'user' => 'User', + 'admin' => __('translations.Admin'), + 'user' => __('translations.User'), ], default: 'user' ); @@ -53,6 +53,6 @@ public function handle(): void 'role' => $role, ]); - info('User role updated.'); + info(__('translations.user_change.info')); } } diff --git a/app/Console/Commands/UserResetPassword.php b/app/Console/Commands/UserResetPassword.php index b6fb784e1..0de28023b 100644 --- a/app/Console/Commands/UserResetPassword.php +++ b/app/Console/Commands/UserResetPassword.php @@ -32,7 +32,7 @@ class UserResetPassword extends Command public function handle(): void { $email = text( - label: 'What is the email address?', + label: __('translations.user_change.welcome_email'), required: true, validate: fn (string $value) => match (true) { ! User::firstWhere('email', $value) => 'User not found.', @@ -41,7 +41,7 @@ public function handle(): void ); $password = password( - label: 'What is the new password?', + label: __('translations.user_change.what_is_password'), required: true, ); @@ -50,6 +50,6 @@ public function handle(): void 'password' => Hash::make($password), ]); - info('The password for "'.$email.'" has been updated.'); + info(__('translations.user_change.password_updated_info', ['email' => $email])); } } diff --git a/app/Enums/ResultService.php b/app/Enums/ResultService.php index b324633a3..01531836d 100644 --- a/app/Enums/ResultService.php +++ b/app/Enums/ResultService.php @@ -12,6 +12,6 @@ enum ResultService: string implements HasLabel public function getLabel(): ?string { - return Str::title($this->name); + return Str::title(__('translations.'.$this->name)); } } diff --git a/app/Enums/ResultStatus.php b/app/Enums/ResultStatus.php index 8b554f426..b1fbb1da7 100644 --- a/app/Enums/ResultStatus.php +++ b/app/Enums/ResultStatus.php @@ -33,6 +33,6 @@ public function getColor(): ?string public function getLabel(): ?string { - return Str::title($this->name); + return Str::title(__('translations.'.$this->name)); } } diff --git a/app/Enums/UserRole.php b/app/Enums/UserRole.php index 69884c8e8..f0cc85ab2 100644 --- a/app/Enums/UserRole.php +++ b/app/Enums/UserRole.php @@ -21,6 +21,6 @@ public function getColor(): ?string public function getLabel(): ?string { - return Str::title($this->name); + return Str::title(__('translations.'.$this->name)); } } diff --git a/app/Filament/Exports/ResultExporter.php b/app/Filament/Exports/ResultExporter.php index 15ff08118..5f1b18329 100644 --- a/app/Filament/Exports/ResultExporter.php +++ b/app/Filament/Exports/ResultExporter.php @@ -22,14 +22,15 @@ public function getFormats(): array public static function getColumns(): array { $columns = [ - ExportColumn::make('id')->label('ID'), + ExportColumn::make('id') + ->label(__('translations.id')), ExportColumn::make('service')->state(fn (Result $r) => $r->service->getLabel()), ExportColumn::make('status')->state(fn (Result $r) => $r->status->getLabel()), - ExportColumn::make('scheduled')->state(fn (Result $r) => $r->scheduled ? 'Yes' : 'No'), - ExportColumn::make('healthy')->state(fn (Result $r) => $r->healthy ? 'Yes' : 'No'), - ExportColumn::make('created_at'), - ExportColumn::make('updated_at'), - ExportColumn::make('comments'), + ExportColumn::make('scheduled')->state(fn (Result $r) => $r->scheduled ? __('translations.yes') : __('translations.no')), + ExportColumn::make('healthy')->state(fn (Result $r) => $r->healthy ? __('translations.yes') : __('translations.no')), + ExportColumn::make('created_at')->label(__('translations.created_at')), + ExportColumn::make('updated_at')->label(__('translations.updated_at')), + ExportColumn::make('comments')->label(__('translations.comments')), ]; $columns = array_merge($columns, self::generateDataColumns()); @@ -78,10 +79,20 @@ protected static function flatten(array $array, string $prefix = ''): array public static function getCompletedNotificationBody(Export $export): string { - $body = 'Your result export has completed and '.number_format($export->successful_rows).' '.str('row')->plural($export->successful_rows).' exported.'; + $body = __('translations.export_completed', [ + 'count' => number_format($export->successful_rows), + 'rows' => trans_choice('translations.row', $export->successful_rows, [ + 'count' => number_format($export->successful_rows), + ]), + ]); if ($failedRowsCount = $export->getFailedRowsCount()) { - $body .= ' '.number_format($failedRowsCount).' '.str('row')->plural($failedRowsCount).' failed to export.'; + $body .= __('translations.failed_export', [ + 'count' => $failedRowsCount, + 'rows' => trans_choice('translations.row', $export->$failedRowsCount, [ + 'count' => number_format($export->$failedRowsCount), + ]), + ]); } return $body; diff --git a/app/Filament/Pages/Settings/DataIntegrationPage.php b/app/Filament/Pages/Settings/DataIntegrationPage.php index 16a48284e..9ee4df493 100644 --- a/app/Filament/Pages/Settings/DataIntegrationPage.php +++ b/app/Filament/Pages/Settings/DataIntegrationPage.php @@ -22,15 +22,24 @@ class DataIntegrationPage extends SettingsPage { protected static ?string $navigationIcon = 'heroicon-o-circle-stack'; - protected static ?string $navigationGroup = 'Settings'; - protected static ?int $navigationSort = 2; - protected static ?string $title = 'Data Integration'; + protected static string $settings = DataIntegrationSettings::class; - protected static ?string $navigationLabel = 'Data Integration'; + public static function getNavigationGroup(): string + { + return __('translations.settings'); + } - protected static string $settings = DataIntegrationSettings::class; + public function getTitle(): string + { + return __('translations.data_integration'); + } + + public static function getNavigationLabel(): string + { + return __('translations.data_integration'); + } public static function canAccess(): bool { @@ -51,11 +60,11 @@ public function form(Form $form): Form { return $form ->schema([ - Section::make('InfluxDB v2') - ->description('When enabled, all new Speedtest results will also be sent to InfluxDB.') + Section::make(__('translations.infoluxdb')) + ->description(__('translations.infoluxdb_description')) ->schema([ Forms\Components\Toggle::make('influxdb_v2_enabled') - ->label('Enable') + ->label(__('translations.enable')) ->reactive() ->columnSpanFull(), @@ -63,39 +72,39 @@ public function form(Form $form): Form ->hidden(fn (Forms\Get $get) => $get('influxdb_v2_enabled') !== true) ->schema([ TextInput::make('influxdb_v2_url') - ->label('URL') + ->label(__('translations.url')) ->placeholder('http://your-influxdb-instance') ->maxLength(255) ->required(fn (Forms\Get $get) => $get('influxdb_v2_enabled') === true) ->columnSpan(['md' => 1]), TextInput::make('influxdb_v2_org') - ->label('Org') + ->label(__('translations.org')) ->maxLength(255) ->required(fn (Forms\Get $get) => $get('influxdb_v2_enabled') === true) ->columnSpan(['md' => 1]), TextInput::make('influxdb_v2_bucket') - ->placeholder('speedtest-tracker') - ->label('Bucket') + ->placeholder(__('translations.speedtest_tracker')) + ->label(__('translations.bucket')) ->maxLength(255) ->required(fn (Forms\Get $get) => $get('influxdb_v2_enabled') === true) ->columnSpan(['md' => 2]), TextInput::make('influxdb_v2_token') - ->label('Token') + ->label(__('translations.token')) ->maxLength(255) ->password() ->required(fn (Forms\Get $get) => $get('influxdb_v2_enabled') === true) ->autocomplete(false) ->columnSpan(['md' => 2]), Checkbox::make('influxdb_v2_verify_ssl') - ->label('Verify SSL') + ->label(__('translations.verify_ssl')) ->columnSpanFull(), // Button to send old data to InfluxDB Actions::make([ Action::make('Export current results') - ->label('Export current results') + ->label(__('translations.export_current_results')) ->action(function () { Notification::make() - ->title('Starting bulk data write to Influxdb') + ->title(__('translations.starting_bulk_data_write_to_influxdb')) ->info() ->send(); @@ -108,10 +117,10 @@ public function form(Form $form): Form // Button to test InfluxDB connection Actions::make([ Action::make('Test connection') - ->label('Test connection') + ->label(__('translations.test_connection')) ->action(function () { Notification::make() - ->title('Sending test data to Influxdb') + ->title(__('translations.sending_test_data_to_influxdb')) ->info() ->send(); diff --git a/app/Filament/Pages/Settings/NotificationPage.php b/app/Filament/Pages/Settings/NotificationPage.php index 83f8e03ca..3f511542c 100755 --- a/app/Filament/Pages/Settings/NotificationPage.php +++ b/app/Filament/Pages/Settings/NotificationPage.php @@ -30,15 +30,24 @@ class NotificationPage extends SettingsPage { protected static ?string $navigationIcon = 'heroicon-o-bell'; - protected static ?string $navigationGroup = 'Settings'; - protected static ?int $navigationSort = 3; - protected static ?string $title = 'Notifications'; + protected static string $settings = NotificationSettings::class; - protected static ?string $navigationLabel = 'Notifications'; + public static function getNavigationGroup(): string + { + return __('translations.settings'); + } - protected static string $settings = NotificationSettings::class; + public function getTitle(): string + { + return __('translations.notifications.label'); + } + + public static function getNavigationLabel(): string + { + return __('translations.notifications.label'); + } public static function canAccess(): bool { @@ -59,11 +68,11 @@ public function form(Form $form): Form { return $form ->schema([ - Section::make('Database') - ->description('Notifications sent to this channel will show up under the 🔔 icon in the header.') + Section::make(__('translations.database')) + ->description(__('translations.database_description')) ->schema([ Toggle::make('database_enabled') - ->label('Enable database notifications') + ->label(__('translations.enable_database_notifications')) ->reactive() ->columnSpanFull(), Grid::make([ @@ -72,17 +81,18 @@ public function form(Form $form): Form ->hidden(fn (Forms\Get $get) => $get('database_enabled') !== true) ->schema([ Fieldset::make('Triggers') + ->label(__('translations.triggers')) ->schema([ Toggle::make('database_on_speedtest_run') - ->label('Notify on every speedtest run') + ->label(__('translations.notify_on_every_speedtest_run')) ->columnSpanFull(), Toggle::make('database_on_threshold_failure') - ->label('Notify on threshold failures') + ->label(__('translations.notify_on_threshold_failures')) ->columnSpanFull(), ]), Actions::make([ Action::make('test database') - ->label('Test database channel') + ->label(__('translations.test_database_channel')) ->action(fn () => SendDatabaseTestNotification::run(user: Auth::user())), ]), ]), @@ -93,10 +103,10 @@ public function form(Form $form): Form 'md' => 2, ]), - Section::make('Mail') + Section::make(__('translations.mail')) ->schema([ Toggle::make('mail_enabled') - ->label('Enable mail notifications') + ->label(__('translations.enable_mail_notifications')) ->reactive() ->columnSpanFull(), Grid::make([ @@ -105,18 +115,20 @@ public function form(Form $form): Form ->hidden(fn (Forms\Get $get) => $get('mail_enabled') !== true) ->schema([ Fieldset::make('Triggers') + ->label(__('translations.triggers')) ->schema([ Toggle::make('mail_on_speedtest_run') - ->label('Notify on every speedtest run') + ->label(__('translations.notify_on_every_speedtest_run')) ->columnSpanFull(), Toggle::make('mail_on_threshold_failure') - ->label('Notify on threshold failures') + ->label(__('translations.notify_on_threshold_failures')) ->columnSpanFull(), ]), Repeater::make('mail_recipients') - ->label('Recipients') + ->label(__('translations.recipients')) ->schema([ Forms\Components\TextInput::make('email_address') + ->label(__('translations.email_address')) ->placeholder('your@email.com') ->email() ->required(), @@ -124,7 +136,7 @@ public function form(Form $form): Form ->columnSpanFull(), Actions::make([ Action::make('test mail') - ->label('Test mail channel') + ->label(__('translations.test_mail_channel')) ->action(fn (Forms\Get $get) => SendMailTestNotification::run(recipients: $get('mail_recipients'))) ->hidden(fn (Forms\Get $get) => ! count($get('mail_recipients'))), ]), @@ -136,10 +148,10 @@ public function form(Form $form): Form 'md' => 2, ]), - Section::make('Webhook') + Section::make(__('translations.webhook')) ->schema([ Toggle::make('webhook_enabled') - ->label('Enable webhook notifications') + ->label(__('translations.enable_webhook_notifications')) ->reactive() ->columnSpanFull(), Grid::make([ @@ -148,18 +160,20 @@ public function form(Form $form): Form ->hidden(fn (Forms\Get $get) => $get('webhook_enabled') !== true) ->schema([ Fieldset::make('Triggers') + ->label('translations.triggers') ->schema([ Toggle::make('webhook_on_speedtest_run') - ->label('Notify on every speedtest run') + ->label(__('notify_on_every_speedtest_run')) ->columnSpan(2), Toggle::make('webhook_on_threshold_failure') - ->label('Notify on threshold failures') + ->label(__('notify_on_threshold_failures')) ->columnSpan(2), ]), Repeater::make('webhook_urls') - ->label('Recipients') + ->label(__('translations.recipients')) ->schema([ Forms\Components\TextInput::make('url') + ->label(__('translations.url')) ->placeholder('https://webhook.site/longstringofcharacters') ->maxLength(2000) ->required() @@ -168,7 +182,7 @@ public function form(Form $form): Form ->columnSpanFull(), Actions::make([ Action::make('test webhook') - ->label('Test webhook channel') + ->label(__('translations.test_webhook_channel')) ->action(fn (Forms\Get $get) => SendWebhookTestNotification::run(webhooks: $get('webhook_urls'))) ->hidden(fn (Forms\Get $get) => ! count($get('webhook_urls'))), ]), @@ -180,10 +194,10 @@ public function form(Form $form): Form 'md' => 2, ]), - Section::make('Pushover') + Section::make(__('translations.pushover')) ->schema([ Toggle::make('pushover_enabled') - ->label('Enable Pushover webhook notifications') + ->label(__('translations.enable_pushover_webhook_notifications')) ->reactive() ->columnSpanFull(), Grid::make([ @@ -192,38 +206,39 @@ public function form(Form $form): Form ->hidden(fn (Forms\Get $get) => $get('pushover_enabled') !== true) ->schema([ Fieldset::make('Triggers') + ->label(__('translations.triggers')) ->schema([ Toggle::make('pushover_on_speedtest_run') - ->label('Notify on every speedtest run') + ->label(__('translations.notify_on_every_speedtest_run')) ->columnSpanFull(), Toggle::make('pushover_on_threshold_failure') - ->label('Notify on threshold failures') + ->label(__('translations.notify_on_threshold_failures')) ->columnSpanFull(), ]), Repeater::make('pushover_webhooks') - ->label('Pushover Webhooks') + ->label(__('translations.pushover_webhooks')) ->schema([ Forms\Components\TextInput::make('url') - ->label('URL') + ->label(__('translations.url')) ->placeholder('http://api.pushover.net/1/messages.json') ->maxLength(2000) ->required() ->url(), Forms\Components\TextInput::make('user_key') - ->label('User Key') - ->placeholder('Your Pushover User Key') + ->label(__('translations.user_key')) + ->placeholder(__('translations.your_pushover_user_key')) ->maxLength(200) ->required(), Forms\Components\TextInput::make('api_token') - ->label('API Token') - ->placeholder('Your Pushover API Token') + ->label(__('translations.api_token')) + ->placeholder(__('translations.your_pushover_api_token')) ->maxLength(200) ->required(), ]) ->columnSpanFull(), Actions::make([ Action::make('test pushover') - ->label('Test Pushover webhook') + ->label(__('translations.test_pushover_webhook')) ->action(fn (Forms\Get $get) => SendPushoverTestNotification::run( webhooks: $get('pushover_webhooks') )) @@ -237,10 +252,10 @@ public function form(Form $form): Form 'md' => 2, ]), - Section::make('Discord') + Section::make(__('translations.discord')) ->schema([ Toggle::make('discord_enabled') - ->label('Enable Discord webhook notifications') + ->label(__('translations.enable_discord_webhook_notifications')) ->reactive() ->columnSpanFull(), Grid::make([ @@ -249,18 +264,20 @@ public function form(Form $form): Form ->hidden(fn (Forms\Get $get) => $get('discord_enabled') !== true) ->schema([ Fieldset::make('Triggers') + ->label(__('translations.triggers')) ->schema([ Toggle::make('discord_on_speedtest_run') - ->label('Notify on every speedtest run') + ->label(__('translations.notify_on_every_speedtest_run')) ->columnSpanFull(), Toggle::make('discord_on_threshold_failure') - ->label('Notify on threshold failures') + ->label(__('translations.notify_on_threshold_failures')) ->columnSpanFull(), ]), Repeater::make('discord_webhooks') - ->label('Webhooks') + ->label(__('translations.webhooks')) ->schema([ Forms\Components\TextInput::make('url') + ->label(__('translations.url')) ->placeholder('https://discord.com/api/webhooks/longstringofcharacters') ->maxLength(2000) ->required() @@ -269,7 +286,7 @@ public function form(Form $form): Form ->columnSpanFull(), Actions::make([ Action::make('test discord') - ->label('Test Discord webhook') + ->label(__('translations.test_discord_webhook')) ->action(fn (Forms\Get $get) => SendDiscordTestNotification::run(webhooks: $get('discord_webhooks'))) ->hidden(fn (Forms\Get $get) => ! count($get('discord_webhooks'))), ]), @@ -281,10 +298,10 @@ public function form(Form $form): Form 'md' => 2, ]), - Section::make('Gotify') + Section::make(__('translations.gotify')) ->schema([ Toggle::make('gotify_enabled') - ->label('Enable Gotify webhook notifications') + ->label(__('translations.gotify_enabled')) ->reactive() ->columnSpanFull(), Grid::make([ @@ -295,16 +312,17 @@ public function form(Form $form): Form Fieldset::make('Triggers') ->schema([ Toggle::make('gotify_on_speedtest_run') - ->label('Notify on every speedtest run') + ->label(__('translations.notify_on_every_speedtest_run')) ->columnSpanFull(), Toggle::make('gotify_on_threshold_failure') - ->label('Notify on threshold failures') + ->label(__('translations.notify_on_threshold_failures')) ->columnSpanFull(), ]), Repeater::make('gotify_webhooks') - ->label('Webhooks') + ->label(__('translations.webhooks')) ->schema([ Forms\Components\TextInput::make('url') + ->label(__('translations.url')) ->placeholder('https://example.com/message?token=') ->maxLength(2000) ->required() @@ -313,7 +331,7 @@ public function form(Form $form): Form ->columnSpanFull(), Actions::make([ Action::make('test gotify') - ->label('Test Gotify webhook') + ->label(__('translations.test_gotify_webhook')) ->action(fn (Forms\Get $get) => SendgotifyTestNotification::run(webhooks: $get('gotify_webhooks'))) ->hidden(fn (Forms\Get $get) => ! count($get('gotify_webhooks'))), ]), @@ -325,10 +343,10 @@ public function form(Form $form): Form 'md' => 2, ]), - Section::make('Slack') + Section::make(__('translations.slack')) ->schema([ Toggle::make('slack_enabled') - ->label('Enable Slack webhook notifications') + ->label(__('translations.slack_enabled')) ->reactive() ->columnSpanFull(), Grid::make([ @@ -337,18 +355,20 @@ public function form(Form $form): Form ->hidden(fn (Forms\Get $get) => $get('slack_enabled') !== true) ->schema([ Fieldset::make('Triggers') + ->label('translations.triggers') ->schema([ Toggle::make('slack_on_speedtest_run') - ->label('Notify on every speedtest run') + ->label(__('translations.notify_on_every_speedtest_run')) ->columnSpanFull(), Toggle::make('slack_on_threshold_failure') - ->label('Notify on threshold failures') + ->label(__('translations.notify_on_threshold_failures')) ->columnSpanFull(), ]), Repeater::make('slack_webhooks') - ->label('Webhooks') + ->label(__('translations.webhooks')) ->schema([ Forms\Components\TextInput::make('url') + ->label(__('translations.url')) ->placeholder('https://hooks.slack.com/services/abc/xyz') ->maxLength(2000) ->required() @@ -357,7 +377,7 @@ public function form(Form $form): Form ->columnSpanFull(), Actions::make([ Action::make('test Slack') - ->label('Test slack webhook') + ->label(__('translations.test_slack_webhook')) ->action(fn (Forms\Get $get) => SendSlackTestNotification::run(webhooks: $get('slack_webhooks'))) ->hidden(fn (Forms\Get $get) => ! count($get('slack_webhooks'))), ]), @@ -369,10 +389,10 @@ public function form(Form $form): Form 'md' => 2, ]), - Section::make('Ntfy') + Section::make(__('translations.ntfy')) ->schema([ Toggle::make('ntfy_enabled') - ->label('Enable Ntfy webhook notifications') + ->label(__('translations.ntfy_enabled')) ->reactive() ->columnSpanFull(), Grid::make([ @@ -381,41 +401,43 @@ public function form(Form $form): Form ->hidden(fn (Forms\Get $get) => $get('ntfy_enabled') !== true) ->schema([ Fieldset::make('Triggers') + ->label('translations.triggers') ->schema([ Toggle::make('ntfy_on_speedtest_run') - ->label('Notify on every speedtest run') + ->label(__('translations.notify_on_every_speedtest_run')) ->columnSpanFull(), Toggle::make('ntfy_on_threshold_failure') - ->label('Notify on threshold failures') + ->label(__('translations.notify_on_threshold_failures')) ->columnSpanFull(), ]), Repeater::make('ntfy_webhooks') - ->label('Webhooks') + ->label(__('translations.webhooks')) ->schema([ Forms\Components\TextInput::make('url') + ->label(__('translations.url')) ->maxLength(2000) - ->placeholder('Your ntfy server url') + ->placeholder(__('translations.your_ntfy_server_url')) ->required() ->url(), Forms\Components\TextInput::make('topic') - ->label('Topic') - ->placeholder('Your ntfy Topic') + ->label(__('translations.topic')) + ->placeholder(__('translations.your_ntfy_topic')) ->maxLength(200) ->required(), Forms\Components\TextInput::make('username') - ->label('Username') - ->placeholder('Username for Basic Auth (optional)') + ->label(__('translations.username')) + ->placeholder(__('translations.username_placeholder')) ->maxLength(200), Forms\Components\TextInput::make('password') - ->label('Password') - ->placeholder('Password for Basic Auth (optional)') + ->label(__('translations.password')) + ->placeholder(__('translations.password_placeholder')) ->password() ->maxLength(200), ]) ->columnSpanFull(), Actions::make([ Action::make('test ntfy') - ->label('Test Ntfy webhook') + ->label(__('translations.test_ntfy_webhook')) ->action(fn (Forms\Get $get) => SendNtfyTestNotification::run(webhooks: $get('ntfy_webhooks'))) ->hidden(fn (Forms\Get $get) => ! count($get('ntfy_webhooks'))), ]), @@ -427,10 +449,10 @@ public function form(Form $form): Form 'md' => 2, ]), - Section::make('Healthcheck.io') + Section::make(__('translations.healthcheck_io')) ->schema([ Toggle::make('healthcheck_enabled') - ->label('Enable healthcheck.io webhook notifications') + ->label(__('translations.healthcheck_enabled')) ->reactive() ->columnSpanFull(), Grid::make([ @@ -439,19 +461,21 @@ public function form(Form $form): Form ->hidden(fn (Forms\Get $get) => $get('healthcheck_enabled') !== true) ->schema([ Fieldset::make('Triggers') + ->label('translations.triggers') ->schema([ Toggle::make('healthcheck_on_speedtest_run') - ->label('Notify on every speedtest run') + ->label(__('translations.notify_on_every_speedtest_run')) ->columnSpanFull(), Toggle::make('healthcheck_on_threshold_failure') - ->label('Notify on threshold failures') - ->helperText('Threshold notifications will be sent to the /fail path of the URL.') + ->label(__('translations.notify_on_threshold_failures')) + ->helperText(__('translations.threshold_helper_text')) ->columnSpanFull(), ]), Repeater::make('healthcheck_webhooks') - ->label('webhooks') + ->label(__('translations.webhooks')) ->schema([ Forms\Components\TextInput::make('url') + ->label(__('translations.url')) ->placeholder('https://hc-ping.com/your-uuid-here') ->maxLength(2000) ->required() @@ -460,7 +484,7 @@ public function form(Form $form): Form ->columnSpanFull(), Actions::make([ Action::make('test healthcheck') - ->label('Test healthcheck.io webhook') + ->label(__('translations.test_healthcheck_webhook')) ->action(fn (Forms\Get $get) => SendHealthCheckTestNotification::run(webhooks: $get('healthcheck_webhooks'))) ->hidden(fn (Forms\Get $get) => ! count($get('healthcheck_webhooks'))), ]), @@ -472,10 +496,10 @@ public function form(Form $form): Form 'md' => 2, ]), - Section::make('Telegram') + Section::make(__('translations.telegram')) ->schema([ Toggle::make('telegram_enabled') - ->label('Enable telegram notifications') + ->label(__('translations.enable_telegram')) ->reactive() ->columnSpanFull(), Grid::make([ @@ -484,33 +508,35 @@ public function form(Form $form): Form ->hidden(fn (Forms\Get $get) => $get('telegram_enabled') !== true) ->schema([ Fieldset::make('Options') + ->label(__('translations.options')) ->schema([ Toggle::make('telegram_disable_notification') - ->label('Send the message silently to the user') + ->label(__('translations.telegram_disable_notification')) ->columnSpanFull(), ]), Fieldset::make('Triggers') + ->label(__('translations.triggers')) ->schema([ Toggle::make('telegram_on_speedtest_run') - ->label('Notify on every speedtest run') + ->label(__('translations.notify_on_every_speedtest_run')) ->columnSpanFull(), Toggle::make('telegram_on_threshold_failure') - ->label('Notify on threshold failures') + ->label(__('translations.notify_on_threshold_failures')) ->columnSpanFull(), ]), Repeater::make('telegram_recipients') - ->label('Recipients') + ->label(__('translations.recipients')) ->schema([ Forms\Components\TextInput::make('telegram_chat_id') ->placeholder('12345678910') - ->label('Telegram Chat ID') + ->label('') ->maxLength(50) ->required(), ]) ->columnSpanFull(), Actions::make([ Action::make('test telegram') - ->label('Test Telegram channel') + ->label(__('translations.test_telegram_webhook')) ->action(fn (Forms\Get $get) => SendTelegramTestNotification::run(recipients: $get('telegram_recipients'))) ->hidden(fn (Forms\Get $get) => ! count($get('telegram_recipients')) || blank(config('telegram.bot'))), ]), diff --git a/app/Filament/Pages/Settings/ThresholdsPage.php b/app/Filament/Pages/Settings/ThresholdsPage.php index e6d5b4f1c..372439f49 100644 --- a/app/Filament/Pages/Settings/ThresholdsPage.php +++ b/app/Filament/Pages/Settings/ThresholdsPage.php @@ -18,15 +18,24 @@ class ThresholdsPage extends SettingsPage { protected static ?string $navigationIcon = 'heroicon-o-exclamation-triangle'; - protected static ?string $navigationGroup = 'Settings'; - protected static ?int $navigationSort = 4; - protected static ?string $title = 'Thresholds'; + protected static string $settings = ThresholdSettings::class; - protected static ?string $navigationLabel = 'Thresholds'; + public static function getNavigationGroup(): string + { + return __('translations.settings'); + } - protected static string $settings = ThresholdSettings::class; + public function getTitle(): string + { + return __('translations.thresholds'); + } + + public static function getNavigationLabel(): string + { + return __('translations.thresholds'); + } public static function canAccess(): bool { diff --git a/app/Filament/Resources/ApiTokenResource/Pages/ListApiTokens.php b/app/Filament/Resources/ApiTokenResource/Pages/ListApiTokens.php index 2f5cda512..2e6d59dfc 100644 --- a/app/Filament/Resources/ApiTokenResource/Pages/ListApiTokens.php +++ b/app/Filament/Resources/ApiTokenResource/Pages/ListApiTokens.php @@ -16,7 +16,7 @@ protected function getHeaderActions(): array { return [ Action::make('createToken') - ->label('Create API Token') + ->label(__('translations.create_api_token')) ->form(ApiTokenResource::getTokenFormSchema()) ->action(function (array $data): void { $token = auth()->user()->createToken( @@ -26,8 +26,8 @@ protected function getHeaderActions(): array ); Notification::make() - ->title('Token Created') - ->body('Your token: `'.explode('|', $token->plainTextToken)[1].'`') + ->title(__('translations.token_created')) + ->body(__('translations.your_token').': `'.explode('|', $token->plainTextToken)[1].'`') ->success() ->persistent() ->send(); diff --git a/app/Filament/Widgets/StatsOverviewWidget.php b/app/Filament/Widgets/StatsOverviewWidget.php index 5aaf55e85..29364c595 100644 --- a/app/Filament/Widgets/StatsOverviewWidget.php +++ b/app/Filament/Widgets/StatsOverviewWidget.php @@ -24,11 +24,11 @@ protected function getCards(): array if (blank($this->result)) { return [ - Stat::make('Latest download', '-') + Stat::make(__('translations.latest_download'), '-') ->icon('heroicon-o-arrow-down-tray'), - Stat::make('Latest upload', '-') + Stat::make(__('translations.latest_upload'), '-') ->icon('heroicon-o-arrow-up-tray'), - Stat::make('Latest ping', '-') + Stat::make(__('translations.latest_ping'), '-') ->icon('heroicon-o-clock'), ]; } @@ -42,11 +42,11 @@ protected function getCards(): array if (! $previous) { return [ - Stat::make('Latest download', fn (): string => ! blank($this->result) ? Number::toBitRate(bits: $this->result->download_bits, precision: 2) : 'n/a') + Stat::make(__('translations.latest_download'), fn (): string => ! blank($this->result) ? Number::toBitRate(bits: $this->result->download_bits, precision: 2) : 'n/a') ->icon('heroicon-o-arrow-down-tray'), - Stat::make('Latest upload', fn (): string => ! blank($this->result) ? Number::toBitRate(bits: $this->result->upload_bits, precision: 2) : 'n/a') + Stat::make(__('translations.latest_upload'), fn (): string => ! blank($this->result) ? Number::toBitRate(bits: $this->result->upload_bits, precision: 2) : 'n/a') ->icon('heroicon-o-arrow-up-tray'), - Stat::make('Latest ping', fn (): string => ! blank($this->result) ? number_format($this->result->ping, 2).' ms' : 'n/a') + Stat::make(__('translations.latest_ping'), fn (): string => ! blank($this->result) ? number_format($this->result->ping, 2).' ms' : 'n/a') ->icon('heroicon-o-clock'), ]; } @@ -56,19 +56,19 @@ protected function getCards(): array $pingChange = percentChange($this->result->ping, $previous->ping, 2); return [ - Stat::make('Latest download', fn (): string => ! blank($this->result) ? Number::toBitRate(bits: $this->result->download_bits, precision: 2) : 'n/a') + Stat::make(__('translations.latest_download'), fn (): string => ! blank($this->result) ? Number::toBitRate(bits: $this->result->download_bits, precision: 2) : 'n/a') ->icon('heroicon-o-arrow-down-tray') - ->description($downloadChange > 0 ? $downloadChange.'% faster' : abs($downloadChange).'% slower') + ->description($downloadChange > 0 ? $downloadChange.'% '.__('translations.faster') : abs($downloadChange).'% '.__('translations.slower')) ->descriptionIcon($downloadChange > 0 ? 'heroicon-m-arrow-trending-up' : 'heroicon-m-arrow-trending-down') ->color($downloadChange > 0 ? 'success' : 'danger'), - Stat::make('Latest upload', fn (): string => ! blank($this->result) ? Number::toBitRate(bits: $this->result->upload_bits, precision: 2) : 'n/a') + Stat::make(__('translations.latest_upload'), fn (): string => ! blank($this->result) ? Number::toBitRate(bits: $this->result->upload_bits, precision: 2) : 'n/a') ->icon('heroicon-o-arrow-up-tray') - ->description($uploadChange > 0 ? $uploadChange.'% faster' : abs($uploadChange).'% slower') + ->description($uploadChange > 0 ? $uploadChange.'% '.__('translations.faster') : abs($uploadChange).'% '.__('translations.slower')) ->descriptionIcon($uploadChange > 0 ? 'heroicon-m-arrow-trending-up' : 'heroicon-m-arrow-trending-down') ->color($uploadChange > 0 ? 'success' : 'danger'), - Stat::make('Latest ping', fn (): string => ! blank($this->result) ? number_format($this->result->ping, 2).' ms' : 'n/a') + Stat::make(__('translations.latest_ping'), fn (): string => ! blank($this->result) ? number_format($this->result->ping, 2).' ms' : 'n/a') ->icon('heroicon-o-clock') - ->description($pingChange > 0 ? $pingChange.'% slower' : abs($pingChange).'% faster') + ->description($pingChange > 0 ? $pingChange.'% '.__('translations.slower') : abs($pingChange).'% '.__('translations.faster')) ->descriptionIcon($pingChange > 0 ? 'heroicon-m-arrow-trending-up' : 'heroicon-m-arrow-trending-down') ->color($pingChange > 0 ? 'danger' : 'success'), ]; diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 15d972dee..7ea66aeef 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -3,6 +3,7 @@ namespace App\Providers\Filament; use App\Services\GitHub\Repository; +use BezhanSalleh\FilamentLanguageSwitch\LanguageSwitch; use Filament\FontProviders\LocalFontProvider; use Filament\Http\Middleware\Authenticate; use Filament\Http\Middleware\DisableBladeIconComponents; @@ -18,10 +19,19 @@ use Illuminate\Routing\Middleware\SubstituteBindings; use Illuminate\Session\Middleware\AuthenticateSession; use Illuminate\Session\Middleware\StartSession; +use Illuminate\Support\Facades\File; use Illuminate\View\Middleware\ShareErrorsFromSession; class AdminPanelProvider extends PanelProvider { + public function boot() + { + LanguageSwitch::configureUsing(function (LanguageSwitch $switch) { + $switch + ->locales(collect(File::directories(lang_path()))->map(fn ($dir) => basename($dir))->toArray()); + }); + } + public function panel(Panel $panel): Panel { return $panel @@ -63,25 +73,30 @@ public function panel(Panel $panel): Panel ]) ->navigationGroups([ NavigationGroup::make() - ->label('Settings'), + ->label(__('translations.settings')), NavigationGroup::make() - ->label('Links') + ->label(__('translations.links')) ->collapsible(false), ]) ->navigationItems([ - NavigationItem::make('Documentation') + NavigationItem::make() + ->label(fn () => __('translations.documentation')) ->url('https://docs.speedtest-tracker.dev/', shouldOpenInNewTab: true) ->icon('heroicon-o-book-open') - ->group('Links'), - NavigationItem::make('Donate') + ->group(fn () => __('translations.links')) + ->sort(97), + NavigationItem::make() + ->label(fn () => __('translations.donate')) ->url('https://github.com/sponsors/alexjustesen', shouldOpenInNewTab: true) ->icon('heroicon-o-banknotes') - ->group('Links'), + ->group(fn () => __('translations.links')) + ->sort(98), NavigationItem::make(config('speedtest.build_version')) ->url('https://github.com/alexjustesen/speedtest-tracker', shouldOpenInNewTab: true) ->icon('tabler-brand-github') - ->badge(fn (): string => Repository::updateAvailable() ? 'Update Available!' : 'Up to Date') - ->group('Links'), + ->badge(fn (): string => Repository::updateAvailable() ? __('translations.update_available') : __('translations.up_to_date')) + ->group(fn () => __('translations.links')) + ->sort(99), ]); } } diff --git a/app/Rules/Cron.php b/app/Rules/Cron.php index 570c0aff2..2600d77b0 100644 --- a/app/Rules/Cron.php +++ b/app/Rules/Cron.php @@ -16,7 +16,7 @@ class Cron implements ValidationRule public function validate(string $attribute, mixed $value, Closure $fail): void { if (! CronExpression::isValidExpression($value)) { - $fail('Cron expression is not valid'); + $fail(__('translations.cron_invalid')); } } } diff --git a/composer.json b/composer.json index 469a4a7b6..0c1bbcb35 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,7 @@ "license": "MIT", "require": { "php": "^8.2", + "bezhansalleh/filament-language-switch": "^3.1", "chrisullyott/php-filesize": "^4.2.1", "dragonmantank/cron-expression": "^3.4.0", "filament/filament": "^3.3.39", diff --git a/composer.lock b/composer.lock index cec2a619c..e63ea79bb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4bb84e3f3ce8356e7452962ad3f813e9", + "content-hash": "8dc4ac39d39c2589f788bc4e6107f52a", "packages": [ { "name": "anourvalar/eloquent-serialize", @@ -72,6 +72,81 @@ }, "time": "2025-07-30T15:45:57+00:00" }, + { + "name": "bezhansalleh/filament-language-switch", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/bezhanSalleh/filament-language-switch.git", + "reference": "e16645113d92cccb842f55675cdf3f7ded09150f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bezhanSalleh/filament-language-switch/zipball/e16645113d92cccb842f55675cdf3f7ded09150f", + "reference": "e16645113d92cccb842f55675cdf3f7ded09150f", + "shasum": "" + }, + "require": { + "filament/filament": "^3.0", + "php": "^8.1|^8.2|^8.3", + "spatie/laravel-package-tools": "^1.9" + }, + "require-dev": { + "laravel/pint": "^1.0", + "nunomaduro/collision": "^6.0|^7.0|8.0", + "orchestra/testbench": "^7.0|^8.0|^9.0", + "pestphp/pest": "^2.34", + "pestphp/pest-plugin-laravel": "^2.3", + "spatie/laravel-ray": "^1.26" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "BezhanSalleh\\FilamentLanguageSwitch\\FilamentLanguageSwitchServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "BezhanSalleh\\FilamentLanguageSwitch\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bezhan Salleh", + "email": "bezhan_salleh@yahoo.com", + "role": "Developer" + } + ], + "description": "Zero config Language Switch(Changer/Localizer) plugin for filamentphp admin", + "homepage": "https://github.com/bezhansalleh/filament-language-switch", + "keywords": [ + "bezhanSalleh", + "filament-language-changer", + "filament-language-switch", + "filament-locale-changer", + "filament-localizer", + "filament-plugin", + "filamentphp", + "laravel" + ], + "support": { + "issues": "https://github.com/bezhanSalleh/filament-language-switch/issues", + "source": "https://github.com/bezhanSalleh/filament-language-switch/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/bezhanSalleh", + "type": "github" + } + ], + "time": "2025-06-11T17:21:20+00:00" + }, { "name": "blade-ui-kit/blade-heroicons", "version": "2.6.0", diff --git a/lang/en/translations.php b/lang/en/translations.php new file mode 100644 index 000000000..f2b9d6788 --- /dev/null +++ b/lang/en/translations.php @@ -0,0 +1,290 @@ + 'Admin', + 'User' => 'User', + 'abilities' => 'Abilities', + 'active_tokens' => 'Active tokens', + 'all_tokens' => 'All tokens', + 'api_token' => 'API Token', + 'api_tokens' => 'API Tokens', + 'average' => 'Average', + 'average_ms' => 'Average (ms)', + 'Benchmarking' => 'Benchmarking', + 'bucket' => 'Bucket', + 'Checking' => 'Checking', + 'comment' => 'Comment', + 'comments' => 'Comments', + 'Completed' => 'Completed', + 'create_api_token' => 'Create API Token', + 'created_at' => 'Created at', + 'created_from' => 'Created from', + 'created_until' => 'Created until', + 'cron_invalid' => 'Cron expression is not valid', + 'data_integration' => 'Data integration', + 'database' => 'Database', + 'database_description' => 'Notifications sent to this channel will show up under the 🔔 icon in the header.', + 'details' => 'Details', + 'dashboard' => 'Dashboard', + 'discord' => 'Discord', + 'documentation' => 'Documentation', + 'donate' => 'Donate', + 'download' => 'Download', + 'download_latency' => 'Download Latency', + 'download_latency_high' => 'Download latency high', + 'download_latency_iqm' => 'Download latency iqm', + 'download_latency_jitter' => 'Download latency jitter', + 'download_latency_low' => 'Download latency low', + 'download_mbps' => 'Download (Mbps)', + 'download_ms' => 'Download (ms)', + 'email' => 'Email', + 'email_address' => 'Email address', + 'enable' => 'Enable', + 'enable_database_notifications' => 'Enable database notifications', + 'enable_discord_webhook_notifications' => 'Enable Discord webhook notifications', + 'enable_mail_notifications' => 'Enable mail notifications', + 'enable_pushover_webhook_notifications' => 'Enable Pushover webhook notifications', + 'enable_telegram' => 'Enable telegram notifications', + 'enable_webhook_notifications' => 'Enable webhook notifications', + 'error_message' => 'Error message', + 'expired_tokens' => 'Expired tokens', + 'expires_at' => 'Expires at', + 'expires_at_helper_text' => 'Leave empty for no expiration', + 'export_all_results' => 'Export all Results', + 'export_all_results_description' => 'This will export all columns for all results.', + 'export_completed' => 'Your result export has completed and :count :rows exported.', + 'export_current_results' => 'Export current results', + 'Failed' => 'Failed', + 'failed_export' => ' :count :rows failed to exported.', + 'Faker' => 'faker', + 'faster' => 'faster', + 'general_settings' => [ + 'label' => 'General settings', + 'description' => 'The general application settings can be set here', + 'app_settings' => 'App settings', + 'speedtest_settings' => 'Speedtest settings', + 'api_settings' => 'Api settings', + 'app_name' => 'App name', + 'asset_url' => 'Asset url', + 'app_timezone' => 'App timezone', + 'chart_begin_at_zero' => 'Chart begin at zero', + 'chart_datetime_format' => 'Chart datetime format', + 'datetime_format' => 'Datetime format', + 'display_timezone' => 'Display timezone', + 'public_dashboard' => 'Public dashboard', + 'speedtest_skip_ips' => 'Speedtest skip ips', + 'speedtest_schedule' => 'Speedtest schedule', + 'speedtest_schedule_description' => 'Enter valid cron expressions. Example: * * * * * runs every minute.', + 'speedtest_servers' => 'Speedtest servers', + 'speedtest_blocked_servers' => 'Speedtest blocked servers', + 'speedtest_interface' => 'Speedtest interface', + 'speedtest_checkinternet_url' => 'Speedtest check internet url', + 'threshold_enabled' => 'Threshold enabled', + 'threshold_download' => 'Threshold download', + 'threshold_upload' => 'Threshold upload', + 'threshold_ping' => 'Threshold ping', + 'prune_results_older_than' => 'Prune results older than', + 'api_rate_limit' => 'Api rate limit', + ], + 'gotify' => 'Gotify', + 'gotify_enabled' => 'Enable Gotify webhook notifications', + 'healthcheck_enabled' => 'Enable healthcheck.io webhook notifications', + 'healthcheck_io' => 'Healthcheck.io', + 'healthy' => 'Healthy', + 'high' => 'High', + 'high_ms' => 'High (ms)', + 'id' => 'ID', + 'infoluxdb' => 'InfluxDB v2', + 'infoluxdb_description' => 'When enabled, all new Speedtest results will also be sent to InfluxDB.', + 'ip_address' => 'IP Address', + 'iqm' => 'IQM', + 'isp' => 'ISP', + 'jitter' => 'Jitter', + 'last_24h' => 'Last 24h', + 'last_month' => 'Last month', + 'last_used_at' => 'Last used at', + 'last_week' => 'Last week', + 'latest_download' => 'Latest download', + 'latest_ping' => 'Latest ping', + 'latest_upload' => 'Latest upload', + 'links' => 'Links', + 'list_servers' => 'List servers', + 'list_servers_description' => 'Grant this token permission to list available servers.', + 'low' => 'Low', + 'low_ms' => 'Low (ms)', + 'mail' => 'E-mail', + 'message' => 'Message', + 'ms' => 'ms', + 'name' => 'Name', + 'next_speedtest_at' => 'Next speedtest at:', + 'no' => 'No', + 'no_speedtests_scheduled' => 'No speedtests scheduled.', + 'notifications' => [ + 'label' => 'Notifications', + 'database' => [ + 'ping' => 'I say ping', + 'pong' => 'You say pong', + 'received' => 'Test database notification received!', + 'sent' => 'Test database notification sent.', + ], + 'discord' => [ + 'add' => 'You need to add Discord urls!', + 'sent' => 'Test Discord notification sent.', + 'payload' => '👋 Testing the Discord notification channel.', + ], + 'health_check' => [ + 'add' => 'You need to add HealthCheck.io urls!', + 'sent' => 'Test HealthCheck.io notification sent.', + 'payload' => '👋 Testing the HealthCheck.io notification channel.', + ], + 'gotfy' => [ + 'add' => 'You need to add Gotify urls!', + 'sent' => 'Test Gotify notification sent.', + 'payload' => '👋 Testing the Gotify notification channel.', + ], + 'mail' => [ + 'add' => 'You need to add mail recipients!', + 'sent' => 'Test mail notification sent.', + ], + 'ntfy' => [ + 'add' => 'You need to add ntfy urls!', + 'sent' => 'Test ntfy notification sent.', + 'payload' => '👋 Testing the ntfy notification channel.', + ], + 'pushover' => [ + 'add' => 'You need to add Pushover URLs!', + 'sent' => 'Test Pushover notification sent.', + 'payload' => '👋 Testing the Pushover notification channel.', + ], + 'slack' => [ + 'add' => 'You need to add Slack URLs!', + 'sent' => 'Test Slack notification sent.', + 'payload' => '👋 Testing the Slack notification channel.', + ], + 'telegram' => [ + 'add' => 'You need to add Telegram recipients!', + 'sent' => 'Test Telegram notification sent.', + ], + 'webhook' => [ + 'add' => 'You need to add webhook URLs!', + 'sent' => 'Test webhook notification sent.', + 'payload' => 'Webhook Notification Testing', + ], + ], + 'notify_on_every_speedtest_run' => 'Notify on every speedtest run', + 'notify_on_threshold_failures' => 'Notify on threshold failures', + 'ntfy' => 'Ntfy', + 'ntfy_enabled' => 'Enable Ntfy webhook notifications', + 'only_healthy_speedtests' => 'Only healthy speedtests', + 'only_manual_speedtests' => 'Only manual speedtests', + 'only_scheduled_speedtests' => 'Only scheduled speedtests', + 'only_unhealthy_speedtests' => 'Only unhealthy speedtests', + 'Ookla' => 'ookla', + 'ookla_error' => 'There was an issue retrieving a list of speedtest servers, check the logs.', + 'options' => 'Options', + 'org' => 'Org', + 'packet_loss' => 'Packet loss', + 'password' => 'Password', + 'password_confirmation' => 'Password Confirmation', + 'password_placeholder' => 'Password for Basic Auth (optional)', + 'ping' => 'Ping', + 'ping_details' => 'Ping details', + 'ping_high' => 'Ping high', + 'ping_jitter' => 'Ping jitter', + 'ping_low' => 'Ping low', + 'ping_ms' => 'Ping (ms)', + 'platform' => 'Platform', + 'pushover' => 'Pushover', + 'pushover_webhooks' => 'Pushover Webhooks', + 'read_results' => 'Read results', + 'read_results_description' => 'Grant this token permission to read results and statistics.', + 'recipients' => 'Recipients', + 'results' => 'Results', + 'result_overview' => 'Result overview', + 'role' => 'Role', + 'row' => '{1} :count row|[2,*] :count rows', + 'run_speedtest' => 'Run speedtest', + 'run_speedtest_description' => 'Grant this token permission to run speedtests.', + 'Running' => 'Running', + 'scheduled' => 'Scheduled', + 'sending_test_data_to_influxdb' => 'Sending test data to Influxdb', + 'server_&_metadata' => 'Server & Metadata', + 'server_host' => 'Server Host', + 'server_id' => 'Server ID', + 'server_location' => 'Server Location', + 'server_name' => 'Server Name', + 'service' => 'Service', + 'settings' => 'Settings', + 'Skipped' => 'Skipped', + 'slack' => 'Slack', + 'slack_enabled' => 'Enable Slack webhook notifications', + 'slower' => 'slower', + 'speedtest_tracker' => 'speedtest-tracker', + 'Started' => 'Started', + 'starting_bulk_data_write_to_influxdb' => 'Starting bulk data write to Influxdb', + 'status' => 'Status', + 'status_fix' => [ + 'confirm' => 'Do you want to continue?', + 'fail' => 'Command cancelled.', + 'finished' => '✅ finished!', + 'info_1' => 'This will check each result and correct the status to "completed" or "failed" based on the data column.', + 'info_2' => '📖 Read the docs: https://docs.speedtest-tracker.dev/other/commands', + ], + 'telegram' => 'Telegram', + 'telegram_chat_id' => 'Telegram Chat ID', + 'telegram_disable_notification' => 'Send the message silently to the user', + 'test_connection' => 'Test connection', + 'test_database_channel' => 'Test database channel', + 'test_discord_webhook' => 'Test Discord webhook', + 'test_gotify_webhook' => 'Test Gotify webhook', + 'test_healthcheck_webhook' => 'Test healthcheck.io webhook', + 'test_mail_channel' => 'Test mail channel', + 'test_ntfy_webhook' => 'Test Ntfy webhook', + 'test_pushover_webhook' => 'Test Pushover webhook', + 'test_slack_webhook' => 'Test Slack webhook', + 'test_telegram_channel' => 'Test telegram channel', + 'test_webhook_channel' => 'Test webhook channel', + 'threshold_helper_text' => 'Threshold notifications will be sent to the /fail path of the URL.', + 'thresholds' => 'Thresholds', + 'token' => 'Token', + 'token_created' => 'Token created', + 'token_status' => 'Token Status', + 'topic' => 'Topic', + 'triggers' => 'Triggers', + 'truncate' => 'Truncate', + 'truncate_results' => 'Truncate Results', + 'truncate_results_description' => 'Are you sure you want to truncate all results data? This can\'t be undone . ', + 'update_comments' => 'Update comments', + 'updated_at' => 'Updated at', + 'update_available' => 'Update available!', + 'upload' => 'Upload', + 'upload_latency' => 'Upload Latency', + 'upload_latency_high' => 'Upload latency high', + 'upload_latency_jitter' => 'Upload latency jitter', + 'upload_ms' => 'Upload(ms)', + 'up_to_date' => 'Up to date', + 'url' => 'URL', + 'users' => 'Users', + 'user_change' => [ + 'info' => 'User role updated.', + 'password_updated_info' => 'The password for :email has been updated.', + 'what_is_password' => 'What is the new password?', + 'what_is_the_email_address' => 'What is the email address?', + 'what_role' => 'What role should the user have?', + ], + 'user_key' => 'User Key', + 'username' => 'Username', + 'username_placeholder' => 'Username for Basic Auth(optional)', + 'verify_ssl' => 'Verify SSL', + 'view_on_speedtest_net' => 'View on Speedtest . net', + 'Waiting' => 'Waiting', + 'webhook' => 'Webhook', + 'webhooks' => 'Webhooks', + 'yes' => 'Yes', + 'your_ntfy_server_url' => 'Your ntfy server url', + 'your_ntfy_topic' => 'Your ntfy Topic', + 'your_pushover_api_token' => 'Your Pushover API Token', + 'your_pushover_user_key' => 'Your Pushover User Key', + 'your_token' => 'Your Token', + +]; diff --git a/package-lock.json b/package-lock.json index 656d6858d..b2298796a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1081,6 +1081,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001741", @@ -1856,6 +1857,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -2340,6 +2342,7 @@ "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -2450,6 +2453,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -2521,6 +2525,7 @@ "integrity": "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -2625,6 +2630,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, From 00dd9ab07c3eae2a837838f1e51f326acd889b69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petrekanics=20M=C3=A1t=C3=A9?= Date: Thu, 2 Oct 2025 07:23:46 +0200 Subject: [PATCH 2/3] remove language switcher package and update hr translation --- app/Providers/Filament/AdminPanelProvider.php | 10 +-- composer.json | 1 - composer.lock | 77 +------------------ lang/en/passwords.php | 6 +- 4 files changed, 5 insertions(+), 89 deletions(-) diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 7ea66aeef..494ada6b2 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -3,7 +3,6 @@ namespace App\Providers\Filament; use App\Services\GitHub\Repository; -use BezhanSalleh\FilamentLanguageSwitch\LanguageSwitch; use Filament\FontProviders\LocalFontProvider; use Filament\Http\Middleware\Authenticate; use Filament\Http\Middleware\DisableBladeIconComponents; @@ -19,18 +18,11 @@ use Illuminate\Routing\Middleware\SubstituteBindings; use Illuminate\Session\Middleware\AuthenticateSession; use Illuminate\Session\Middleware\StartSession; -use Illuminate\Support\Facades\File; use Illuminate\View\Middleware\ShareErrorsFromSession; class AdminPanelProvider extends PanelProvider { - public function boot() - { - LanguageSwitch::configureUsing(function (LanguageSwitch $switch) { - $switch - ->locales(collect(File::directories(lang_path()))->map(fn ($dir) => basename($dir))->toArray()); - }); - } + public function boot() {} public function panel(Panel $panel): Panel { diff --git a/composer.json b/composer.json index 0c1bbcb35..469a4a7b6 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,6 @@ "license": "MIT", "require": { "php": "^8.2", - "bezhansalleh/filament-language-switch": "^3.1", "chrisullyott/php-filesize": "^4.2.1", "dragonmantank/cron-expression": "^3.4.0", "filament/filament": "^3.3.39", diff --git a/composer.lock b/composer.lock index e63ea79bb..cec2a619c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8dc4ac39d39c2589f788bc4e6107f52a", + "content-hash": "4bb84e3f3ce8356e7452962ad3f813e9", "packages": [ { "name": "anourvalar/eloquent-serialize", @@ -72,81 +72,6 @@ }, "time": "2025-07-30T15:45:57+00:00" }, - { - "name": "bezhansalleh/filament-language-switch", - "version": "3.1.1", - "source": { - "type": "git", - "url": "https://github.com/bezhanSalleh/filament-language-switch.git", - "reference": "e16645113d92cccb842f55675cdf3f7ded09150f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/bezhanSalleh/filament-language-switch/zipball/e16645113d92cccb842f55675cdf3f7ded09150f", - "reference": "e16645113d92cccb842f55675cdf3f7ded09150f", - "shasum": "" - }, - "require": { - "filament/filament": "^3.0", - "php": "^8.1|^8.2|^8.3", - "spatie/laravel-package-tools": "^1.9" - }, - "require-dev": { - "laravel/pint": "^1.0", - "nunomaduro/collision": "^6.0|^7.0|8.0", - "orchestra/testbench": "^7.0|^8.0|^9.0", - "pestphp/pest": "^2.34", - "pestphp/pest-plugin-laravel": "^2.3", - "spatie/laravel-ray": "^1.26" - }, - "type": "library", - "extra": { - "laravel": { - "providers": [ - "BezhanSalleh\\FilamentLanguageSwitch\\FilamentLanguageSwitchServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "BezhanSalleh\\FilamentLanguageSwitch\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bezhan Salleh", - "email": "bezhan_salleh@yahoo.com", - "role": "Developer" - } - ], - "description": "Zero config Language Switch(Changer/Localizer) plugin for filamentphp admin", - "homepage": "https://github.com/bezhansalleh/filament-language-switch", - "keywords": [ - "bezhanSalleh", - "filament-language-changer", - "filament-language-switch", - "filament-locale-changer", - "filament-localizer", - "filament-plugin", - "filamentphp", - "laravel" - ], - "support": { - "issues": "https://github.com/bezhanSalleh/filament-language-switch/issues", - "source": "https://github.com/bezhanSalleh/filament-language-switch/tree/3.1.1" - }, - "funding": [ - { - "url": "https://github.com/bezhanSalleh", - "type": "github" - } - ], - "time": "2025-06-11T17:21:20+00:00" - }, { "name": "blade-ui-kit/blade-heroicons", "version": "2.6.0", diff --git a/lang/en/passwords.php b/lang/en/passwords.php index 6c82e5827..6e2f40cfb 100644 --- a/lang/en/passwords.php +++ b/lang/en/passwords.php @@ -13,8 +13,8 @@ | */ - 'reset' => 'Your password has been reset!', - 'sent' => 'We have emailed your password reset link!', - 'password' => 'The password and confirmation must match and contain at least six characters.', + 'reset' => 'Vaša lozinka je poništena!', + 'sent' => 'Poslali smo vam poveznicu za poništavanje lozinke e-mailom!', + 'password' => 'Lozinka i potvrda moraju se podudarati i sadržavati najmanje šest znakova.', ]; From b1e3550df8a1044fabfb09654fa8ac4d3a373baa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petrekanics=20M=C3=A1t=C3=A9?= Date: Thu, 2 Oct 2025 16:35:07 +0200 Subject: [PATCH 3/3] remove empty function --- app/Providers/Filament/AdminPanelProvider.php | 2 -- lang/en/passwords.php | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index 494ada6b2..52a6191fd 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -22,8 +22,6 @@ class AdminPanelProvider extends PanelProvider { - public function boot() {} - public function panel(Panel $panel): Panel { return $panel diff --git a/lang/en/passwords.php b/lang/en/passwords.php index 6e2f40cfb..6c82e5827 100644 --- a/lang/en/passwords.php +++ b/lang/en/passwords.php @@ -13,8 +13,8 @@ | */ - 'reset' => 'Vaša lozinka je poništena!', - 'sent' => 'Poslali smo vam poveznicu za poništavanje lozinke e-mailom!', - 'password' => 'Lozinka i potvrda moraju se podudarati i sadržavati najmanje šest znakova.', + 'reset' => 'Your password has been reset!', + 'sent' => 'We have emailed your password reset link!', + 'password' => 'The password and confirmation must match and contain at least six characters.', ];