diff --git a/app/Livewire/UserForm.php b/app/Livewire/UserForm.php index 74da087..bf8f073 100644 --- a/app/Livewire/UserForm.php +++ b/app/Livewire/UserForm.php @@ -36,6 +36,9 @@ class UserForm extends Component // Permisos public string $formRole = ''; + // Preferencias + public string $locale = 'es'; + // Notas public string $notes = ''; @@ -43,6 +46,12 @@ class UserForm extends Component public $roles; public $companies; + /** Idiomas disponibles (cΓ³digo => nombre + archivo de bandera). */ + public array $languages = [ + 'es' => ['name' => 'EspaΓ±ol', 'flag' => 'es.svg'], + 'en' => ['name' => 'English', 'flag' => 'gb.svg'], + ]; + public function mount(?User $user = null): void { abort_unless(Auth::user()->can('create users') || Auth::user()->can('edit users'), 403); @@ -65,6 +74,7 @@ class UserForm extends Component $this->email = $user->email; $this->notes = $user->notes ?? ''; $this->formRole = $user->roles->first()?->name ?? $this->formRole; + $this->locale = $user->locale ?? $this->locale; } } @@ -83,6 +93,7 @@ class UserForm extends Component 'phone' => 'nullable|string|max:30', 'email' => "required|email|max:255|unique:users,email,{$id}", 'formRole' => 'required|exists:roles,name', + 'locale' => 'required|in:' . implode(',', array_keys($this->languages)), ]; if (!$this->user) { @@ -103,6 +114,7 @@ class UserForm extends Component 'companyId' => 'empresa', 'formPassword'=> 'contraseΓ±a', 'formRole' => 'rol', + 'locale' => 'idioma', ]; public function copyCompanyAddress(): void @@ -139,6 +151,7 @@ class UserForm extends Component 'phone' => $this->phone ?: null, 'email' => $this->email, 'notes' => $this->notes ?: null, + 'locale' => $this->locale, ]; if ($this->formPassword !== '') { diff --git a/app/Models/User.php b/app/Models/User.php index 872e730..9ffa03d 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -25,6 +25,7 @@ class User extends Authenticatable 'email', 'password', 'status', 'valid_from', 'valid_until', 'company_id', 'phone', 'address', 'notes', + 'locale', ]; /** diff --git a/public/images/flags/es.svg b/public/images/flags/es.svg new file mode 100644 index 0000000..d8fb9a2 --- /dev/null +++ b/public/images/flags/es.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/images/flags/gb.svg b/public/images/flags/gb.svg new file mode 100644 index 0000000..5985f56 --- /dev/null +++ b/public/images/flags/gb.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index fa86edb..eea89b6 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -15,6 +15,9 @@ @vite(['resources/css/app.css', 'resources/js/app.js']) @livewireStyles + {{-- Evita el parpadeo de elementos Alpine (x-cloak) antes de inicializar --}} + + diff --git a/resources/views/livewire/language-switcher.blade.php b/resources/views/livewire/language-switcher.blade.php index fb6e852..225b6fc 100644 --- a/resources/views/livewire/language-switcher.blade.php +++ b/resources/views/livewire/language-switcher.blade.php @@ -1,10 +1,12 @@
- @foreach(['en' => 'πŸ‡¬πŸ‡§ EN', 'es' => 'πŸ‡ͺπŸ‡Έ ES'] as $code => $label) + @foreach(['es' => ['flag' => 'es.svg', 'label' => 'ES'], 'en' => ['flag' => 'gb.svg', 'label' => 'EN']] as $code => $lang) @endforeach
\ No newline at end of file diff --git a/resources/views/livewire/user-form.blade.php b/resources/views/livewire/user-form.blade.php index 67bd563..b087011 100644 --- a/resources/views/livewire/user-form.blade.php +++ b/resources/views/livewire/user-form.blade.php @@ -291,6 +291,46 @@ @error('formRole')

{{ $message }}

@enderror + +
+ +
+
+ {{-- Trigger: muestra la bandera + nombre del idioma seleccionado --}} + + + {{-- Opciones --}} +
    + @foreach($languages as $code => $lang) +
  • + +
  • + @endforeach +
+
+ @error('locale')

{{ $message }}

@enderror +
+
{{-- ══════════════════════════════════════════════════════════ diff --git a/tests/Feature/UserLocaleTest.php b/tests/Feature/UserLocaleTest.php new file mode 100644 index 0000000..cfa34f8 --- /dev/null +++ b/tests/Feature/UserLocaleTest.php @@ -0,0 +1,74 @@ +create(); + $admin->givePermissionTo(['create users', 'edit users']); + return $admin; + } + + private function company(): Company + { + return Company::create(['name' => 'ACME', 'estado' => 'activo', 'type' => 'constructor']); + } + + public function test_creating_a_user_persists_the_selected_locale(): void + { + $admin = $this->admin(); + $company = $this->company(); + + Livewire::actingAs($admin) + ->test(UserForm::class) + ->set('firstName', 'Ada') + ->set('lastName', 'Lovelace') + ->set('email', 'ada@example.com') + ->set('companyId', $company->id) + ->set('formRole', 'Tecnico') + ->set('formPassword', 'Password123') + ->set('locale', 'en') + ->call('save'); + + $this->assertDatabaseHas('users', ['email' => 'ada@example.com', 'locale' => 'en']); + } + + public function test_editing_a_user_loads_and_updates_the_locale(): void + { + $admin = $this->admin(); + $company = $this->company(); + $target = User::factory()->create([ + 'locale' => 'es', + 'company_id' => $company->id, + 'first_name' => 'Bob', + 'last_name' => 'Stone', + ]); + $target->assignRole('Tecnico'); + + Livewire::actingAs($admin) + ->test(UserForm::class, ['user' => $target]) + ->assertSet('locale', 'es') + ->set('locale', 'en') + ->call('save'); + + $this->assertEquals('en', $target->fresh()->locale); + } +}