feat: implement language selector component with responsive design for improved user experience across devices
This commit is contained in:
@@ -5,7 +5,10 @@ namespace App\Services;
|
||||
use App\Models\HeaderTemplate;
|
||||
use App\Models\SectionTemplate;
|
||||
use App\Models\FooterTemplate;
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Filament\Forms\Components\{
|
||||
TextInput, Textarea, Select, Checkbox, CheckboxList,
|
||||
Radio, Toggle, ToggleButtons, DateTimePicker, DatePicker,
|
||||
@@ -294,11 +297,15 @@ class TemplateService
|
||||
*/
|
||||
protected static function getSelectOptions(string $fieldName): array
|
||||
{
|
||||
return config("template-options.{$fieldName}", [
|
||||
$defaults = [
|
||||
'option_1' => __('Option 1'),
|
||||
'option_2' => __('Option 2'),
|
||||
'option_3' => __('Option 3'),
|
||||
]);
|
||||
];
|
||||
|
||||
$options = config("template-options.{$fieldName}", $defaults);
|
||||
|
||||
return is_array($options) ? $options : $defaults;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,6 +383,15 @@ class TemplateService
|
||||
}
|
||||
|
||||
// Handle custom blade components: {custom.component_name} or {custom.component-name}
|
||||
if (str_contains($html, '{custom.language-selector}')) {
|
||||
$desktopLanguage = view('components.custom.language-selector', [
|
||||
'variant' => 'default',
|
||||
])->render();
|
||||
|
||||
$html = str_replace('{custom.language-selector}', $desktopLanguage, $html);
|
||||
$html = self::injectOffcanvasLanguageSelector($html);
|
||||
}
|
||||
|
||||
preg_match_all('/\{custom\.([a-z][a-z_-]*)\}/i', $html, $customMatches);
|
||||
if (!empty($customMatches[0])) {
|
||||
foreach ($customMatches[0] as $index => $fullMatch) {
|
||||
@@ -383,8 +399,12 @@ class TemplateService
|
||||
if ($componentName) {
|
||||
// Normalize component name to lowercase for consistent file system access
|
||||
$componentName = strtolower($componentName);
|
||||
|
||||
if ($componentName === 'language-selector') {
|
||||
continue;
|
||||
}
|
||||
$viewPath = "components.custom.{$componentName}";
|
||||
if (view()->exists($viewPath)) {
|
||||
if (View::exists($viewPath)) {
|
||||
try {
|
||||
$renderedComponent = view($viewPath)->render();
|
||||
// Ensure rendered component is properly formatted
|
||||
@@ -392,7 +412,7 @@ class TemplateService
|
||||
$html = str_replace($fullMatch, $renderedComponent, $html);
|
||||
} catch (\Exception $e) {
|
||||
// Log the error for debugging
|
||||
\Log::error("Custom component render error: {$viewPath}", [
|
||||
Log::error("Custom component render error: {$viewPath}", [
|
||||
'error' => $e->getMessage(),
|
||||
'trace' => $e->getTraceAsString()
|
||||
]);
|
||||
@@ -502,10 +522,10 @@ class TemplateService
|
||||
// Handle setting.* placeholders - get value from Setting model
|
||||
if ($type === 'setting' && $field) {
|
||||
$value = setting($field, '');
|
||||
|
||||
|
||||
// Get setting type to determine if it's a file/image
|
||||
$settingModel = \App\Models\Setting::where('key', $field)->where('is_active', true)->first();
|
||||
if ($settingModel && in_array($settingModel->type, ['file', 'image'])) {
|
||||
$settingModel = Setting::findActiveByKey($field);
|
||||
if ($settingModel && in_array($settingModel->type, ['file', 'image'], true)) {
|
||||
// For file/image settings, use file type for formatting
|
||||
$type = 'file';
|
||||
}
|
||||
@@ -660,5 +680,32 @@ class TemplateService
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject mobile language selector at the top of the first offcanvas menu body.
|
||||
*/
|
||||
protected static function injectOffcanvasLanguageSelector(string $html): string
|
||||
{
|
||||
if (str_contains($html, 'offcanvas-language-mobile-wrap')) {
|
||||
return $html;
|
||||
}
|
||||
|
||||
$mobileLanguage = view('components.custom.language-selector', [
|
||||
'variant' => 'offcanvas',
|
||||
'class' => 'offcanvas-language-mobile',
|
||||
])->render();
|
||||
|
||||
$injection = '<div class="xl:!hidden lg:!hidden pb-4 mb-2 border-b border-white/10 offcanvas-language-mobile-wrap">'
|
||||
. $mobileLanguage
|
||||
. '</div>';
|
||||
|
||||
$pattern = '/(<div[^>]*class="[^"]*offcanvas-body[^"]*"[^>]*>)/i';
|
||||
|
||||
if (preg_match($pattern, $html)) {
|
||||
return preg_replace($pattern, '$1' . $injection, $html, 1);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user