feat(users): idioma por defecto con banderas SVG + conmutador coherente
- Campo "Idioma por defecto" al crear/editar usuario (columna locale ya existente),
como desplegable Alpine con banderas SVG reales (no emoji, que en Windows se ven
como "ES"/"GB") servidas localmente: public/images/flags/{es,gb}.svg.
- User: locale añadido a fillable. UserForm: propiedad/validación/guardado de locale.
- LanguageSwitcher de la cabecera usa las mismas banderas SVG.
- Regla CSS [x-cloak] en el layout para evitar parpadeo de desplegables Alpine.
Tests: UserLocaleTest (2) — crear/editar persisten el idioma.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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 --}}
|
||||
<style>[x-cloak]{display:none !important;}</style>
|
||||
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
|
||||
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
|
||||
crossorigin=""/>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<div class="flex items-center gap-1"
|
||||
x-on:locale-changed.window="window.location.reload()">
|
||||
@foreach(['en' => '🇬🇧 EN', 'es' => '🇪🇸 ES'] as $code => $label)
|
||||
@foreach(['es' => ['flag' => 'es.svg', 'label' => 'ES'], 'en' => ['flag' => 'gb.svg', 'label' => 'EN']] as $code => $lang)
|
||||
<button wire:click="switchLanguage('{{ $code }}')"
|
||||
class="btn btn-xs {{ $currentLocale === $code ? 'btn-primary' : 'btn-ghost' }}"
|
||||
class="btn btn-xs gap-1.5 {{ $currentLocale === $code ? 'btn-primary' : 'btn-ghost' }}"
|
||||
title="{{ __('Language') }}: {{ __($code === 'en' ? 'English' : 'Spanish') }}">
|
||||
{{ $label }}
|
||||
<img src="{{ asset('images/flags/' . $lang['flag']) }}"
|
||||
class="w-4 h-auto rounded-sm border border-base-300" alt="{{ $lang['label'] }}">
|
||||
{{ $lang['label'] }}
|
||||
</button>
|
||||
@endforeach
|
||||
</div>
|
||||
@@ -291,6 +291,46 @@
|
||||
@error('formRole') <p class="text-error text-xs mt-1">{{ $message }}</p> @enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-start gap-4 mt-4">
|
||||
<label class="w-48 shrink-0 pt-2 text-sm font-medium text-gray-700">
|
||||
Idioma por defecto <span class="text-error">*</span>
|
||||
<p class="text-xs text-gray-400 font-normal mt-0.5">Idioma de la interfaz para este usuario</p>
|
||||
</label>
|
||||
<div class="flex-1">
|
||||
<div x-data="{ open: false }" @click.outside="open = false" class="relative w-full max-w-xs">
|
||||
{{-- Trigger: muestra la bandera + nombre del idioma seleccionado --}}
|
||||
<button type="button" @click="open = !open"
|
||||
class="select select-bordered w-full flex items-center gap-2 text-left">
|
||||
@foreach($languages as $code => $lang)
|
||||
<span x-show="$wire.locale === '{{ $code }}'" class="flex items-center gap-2">
|
||||
<img src="{{ asset('images/flags/' . $lang['flag']) }}"
|
||||
class="w-5 h-auto rounded-sm border border-base-300" alt="{{ $lang['name'] }}">
|
||||
{{ $lang['name'] }}
|
||||
</span>
|
||||
@endforeach
|
||||
</button>
|
||||
|
||||
{{-- Opciones --}}
|
||||
<ul x-show="open" x-transition x-cloak
|
||||
class="absolute z-50 mt-1 w-full bg-base-100 border border-base-300 rounded-box shadow-lg p-1">
|
||||
@foreach($languages as $code => $lang)
|
||||
<li>
|
||||
<button type="button"
|
||||
@click="$wire.set('locale', '{{ $code }}'); open = false"
|
||||
class="w-full flex items-center gap-2 px-3 py-2 rounded-lg hover:bg-base-200 text-left"
|
||||
:class="$wire.locale === '{{ $code }}' ? 'bg-base-200 font-medium' : ''">
|
||||
<img src="{{ asset('images/flags/' . $lang['flag']) }}"
|
||||
class="w-5 h-auto rounded-sm border border-base-300" alt="{{ $lang['name'] }}">
|
||||
{{ $lang['name'] }}
|
||||
</button>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@error('locale') <p class="text-error text-xs mt-1">{{ $message }}</p> @enderror
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- ══════════════════════════════════════════════════════════
|
||||
|
||||
Reference in New Issue
Block a user