mirror of
https://github.com/HolgerHatGarKeineNode/einundzwanzig-app.git
synced 2025-12-14 12:06:46 +00:00
🌐 Replace language-selector component, introduce livewire:language.selector and enhance sidebar with dynamic language and country selection options
This commit is contained in:
@@ -99,12 +99,6 @@
|
|||||||
<flux:spacer/>
|
<flux:spacer/>
|
||||||
|
|
||||||
<flux:navlist variant="outline">
|
<flux:navlist variant="outline">
|
||||||
<flux:navlist.item icon="language"
|
|
||||||
:href="route('settings.profile', ['country' => str(session('lang_country', 'de'))->after('-')->lower()])"
|
|
||||||
:current="request()->routeIs('settings.profile')"
|
|
||||||
wire:navigate>
|
|
||||||
{{ __('Sprache wechseln') }}
|
|
||||||
</flux:navlist.item>
|
|
||||||
<flux:navlist.item icon="folder-git-2"
|
<flux:navlist.item icon="folder-git-2"
|
||||||
href="https://gitworkshop.dev/holgerhatgarkeinenode@einundzwanzig.space/einundzwanzig-app"
|
href="https://gitworkshop.dev/holgerhatgarkeinenode@einundzwanzig.space/einundzwanzig-app"
|
||||||
target="_blank">
|
target="_blank">
|
||||||
@@ -114,12 +108,18 @@
|
|||||||
|
|
||||||
<flux:navlist variant="outline">
|
<flux:navlist variant="outline">
|
||||||
<flux:navlist.group>
|
<flux:navlist.group>
|
||||||
<div class="grid gap-4">
|
<div class="grid gap-2">
|
||||||
<div>
|
<div>
|
||||||
|
<flux:heading class="my-2">{{ __('Land auswählen') }}</flux:heading>
|
||||||
<livewire:country.chooser/>
|
<livewire:country.chooser/>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<flux:heading class="my-2">{{ __('Sprache wechseln') }}</flux:heading>
|
||||||
|
<livewire:language.selector/>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@if(auth()->check())
|
@if(auth()->check())
|
||||||
|
<flux:heading class="my-2">{{ __('Zeitzone') }}</flux:heading>
|
||||||
<livewire:timezone.chooser/>
|
<livewire:timezone.chooser/>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ class extends Component {
|
|||||||
<flux:button variant="primary" @click="openNostrLogin" icon="cursor-arrow-ripple"
|
<flux:button variant="primary" @click="openNostrLogin" icon="cursor-arrow-ripple"
|
||||||
class="w-full cursor-pointer">{{ __('Log in mit Nostr') }}</flux:button>
|
class="w-full cursor-pointer">{{ __('Log in mit Nostr') }}</flux:button>
|
||||||
|
|
||||||
<div class="text-center text-2xl text-gray-80 dark:text-gray-2000 mt-6">
|
<div class="text-center text-2xl text-gray-80 dark:text-gray-2000 mt-2">
|
||||||
{{ __('Login with lightning ⚡') }}
|
{{ __('Login with lightning ⚡') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -245,7 +245,7 @@ class extends Component {
|
|||||||
</flux:subheading>
|
</flux:subheading>
|
||||||
@endif--}}
|
@endif--}}
|
||||||
<!-- Language Selection Accordion -->
|
<!-- Language Selection Accordion -->
|
||||||
<x-einundzwanzig.language-selector/>
|
<livewire:language.selector/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ new class extends Component {
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<flux:select variant="listbox" searchable placeholder="{{ __('Wähle dein Land...') }}"
|
<flux:select variant="listbox" searchable placeholder="{{ __('Wähle dein Land...') }}"
|
||||||
wire:model.live.debounce="currentCountry" label="{{ __('Land') }}">
|
wire:model.live.debounce="currentCountry">
|
||||||
<x-slot name="search">
|
<x-slot name="search">
|
||||||
<flux:select.search class="px-4" placeholder="{{ __('Suche dein Land...') }}"/>
|
<flux:select.search class="px-4" placeholder="{{ __('Suche dein Land...') }}"/>
|
||||||
</x-slot>
|
</x-slot>
|
||||||
|
|||||||
68
resources/views/livewire/language/selector.blade.php
Normal file
68
resources/views/livewire/language/selector.blade.php
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use function Livewire\Volt\{state, computed};
|
||||||
|
|
||||||
|
state(['langCountry' => fn() => session('lang_country', config('lang-country.fallback'))]);
|
||||||
|
|
||||||
|
$languages = computed(function () {
|
||||||
|
// Scan lang folder for available languages
|
||||||
|
$availableLanguages = collect(glob(base_path('lang/*.json')))
|
||||||
|
->map(fn($file) => pathinfo($file, PATHINFO_FILENAME))
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$allLanguages = [
|
||||||
|
'de' => ['name' => 'Deutsch', 'countries' => ['de-DE', 'de-AT', 'de-CH']],
|
||||||
|
'en' => ['name' => 'English', 'countries' => ['en-GB', 'en-US', 'en-AU', 'en-CA']],
|
||||||
|
'es' => ['name' => 'Español', 'countries' => ['es-ES', 'es-CL', 'es-CO']],
|
||||||
|
'hu' => ['name' => 'Magyar', 'countries' => ['hu-HU']],
|
||||||
|
'nl' => ['name' => 'Nederlands', 'countries' => ['nl-NL', 'nl-BE']],
|
||||||
|
'pl' => ['name' => 'Polski', 'countries' => ['pl-PL']],
|
||||||
|
'pt' => ['name' => 'Português', 'countries' => ['pt-PT']],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Filter languages based on available JSON files and allowed languages
|
||||||
|
$languages = array_filter($allLanguages, function ($data, $key) use ($availableLanguages) {
|
||||||
|
return in_array($key, $availableLanguages) &&
|
||||||
|
count(array_intersect($data['countries'], config('lang-country.allowed'))) > 0;
|
||||||
|
}, ARRAY_FILTER_USE_BOTH);
|
||||||
|
|
||||||
|
// Build options array
|
||||||
|
$options = [];
|
||||||
|
foreach ($languages as $langCode => $langData) {
|
||||||
|
foreach ($langData['countries'] as $langCountry) {
|
||||||
|
[$lang, $countryCode] = explode('-', $langCountry);
|
||||||
|
$options[] = [
|
||||||
|
'value' => $langCountry,
|
||||||
|
'label' => $langData['name'] . ' (' . strtoupper($countryCode) . ')',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $options;
|
||||||
|
});
|
||||||
|
|
||||||
|
$updateLanguage = function () {
|
||||||
|
return redirect()->route('lang_country.switch', ['lang_country' => $this->langCountry]);
|
||||||
|
};
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<flux:select
|
||||||
|
variant="listbox" searchable
|
||||||
|
wire:model.live="langCountry"
|
||||||
|
wire:change="updateLanguage"
|
||||||
|
:placeholder="__('Sprache wählen')"
|
||||||
|
>
|
||||||
|
@foreach($this->languages as $option)
|
||||||
|
<flux:select.option value="{{ $option['value'] }}">
|
||||||
|
<div class="flex items-center space-x-2">
|
||||||
|
<img alt="{{ str($option['value'])->after('-')->lower() }}"
|
||||||
|
src="{{ asset('vendor/blade-flags/country-'.str($option['value'])->after('-')->lower().'.svg') }}"
|
||||||
|
width="24" height="12"/>
|
||||||
|
<span>{{ $option['label'] }}</span>
|
||||||
|
</div>
|
||||||
|
</flux:select.option>
|
||||||
|
@endforeach
|
||||||
|
</flux:select>
|
||||||
|
</div>
|
||||||
@@ -39,7 +39,7 @@ new class extends Component {
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<flux:select variant="listbox" searchable placeholder="{{ __('Wähle deine Zeitzone...') }}"
|
<flux:select variant="listbox" searchable placeholder="{{ __('Wähle deine Zeitzone...') }}"
|
||||||
wire:model.live.debounce="selectedTimezone" label="{{ __('Zeitzone') }}">
|
wire:model.live.debounce="selectedTimezone">
|
||||||
<x-slot name="search">
|
<x-slot name="search">
|
||||||
<flux:select.search class="px-4" placeholder="{{ __('Suche Zeitzone...') }}"/>
|
<flux:select.search class="px-4" placeholder="{{ __('Suche Zeitzone...') }}"/>
|
||||||
</x-slot>
|
</x-slot>
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class extends Component {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Language Selection Accordion -->
|
<!-- Language Selection Accordion -->
|
||||||
<x-einundzwanzig.language-selector/>
|
<livewire:language.selector/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user