mirror of
https://github.com/openclassify/openclassify.git
synced 2026-04-14 11:12:09 -05:00
22
This commit is contained in:
parent
aa7d2e27c0
commit
08d0b68349
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Modules\Admin\Filament\Pages;
|
||||
|
||||
use App\Support\HomeSlideDefaults;
|
||||
use App\Support\CountryCodeManager;
|
||||
use App\Settings\GeneralSettings;
|
||||
use BackedEnum;
|
||||
@ -22,13 +23,13 @@ class ManageGeneralSettings extends SettingsPage
|
||||
{
|
||||
protected static string $settings = GeneralSettings::class;
|
||||
|
||||
protected static ?string $title = 'General Settings';
|
||||
protected static ?string $title = 'Genel Ayarlar';
|
||||
|
||||
protected static ?string $navigationLabel = 'General Settings';
|
||||
protected static ?string $navigationLabel = 'Genel Ayarlar';
|
||||
|
||||
protected static string | BackedEnum | null $navigationIcon = 'heroicon-o-cog-6-tooth';
|
||||
|
||||
protected static string | UnitEnum | null $navigationGroup = 'Settings';
|
||||
protected static string | UnitEnum | null $navigationGroup = 'Ayarlar';
|
||||
|
||||
protected static ?int $navigationSort = 1;
|
||||
|
||||
@ -37,35 +38,35 @@ class ManageGeneralSettings extends SettingsPage
|
||||
return $schema
|
||||
->components([
|
||||
TextInput::make('site_name')
|
||||
->label('Site Name')
|
||||
->label('Site Adı')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Textarea::make('site_description')
|
||||
->label('Site Description')
|
||||
->label('Site Açıklaması')
|
||||
->rows(3)
|
||||
->maxLength(500),
|
||||
Repeater::make('home_slides')
|
||||
->label('Home Slider')
|
||||
->label('Ana Sayfa Slider')
|
||||
->schema([
|
||||
TextInput::make('badge')
|
||||
->label('Badge')
|
||||
->label('Rozet')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
TextInput::make('title')
|
||||
->label('Title')
|
||||
->label('Başlık')
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Textarea::make('subtitle')
|
||||
->label('Subtitle')
|
||||
->label('Alt Başlık')
|
||||
->rows(2)
|
||||
->required()
|
||||
->maxLength(500),
|
||||
TextInput::make('primary_button_text')
|
||||
->label('Primary Button Text')
|
||||
->label('Birincil Buton Metni')
|
||||
->required()
|
||||
->maxLength(120),
|
||||
TextInput::make('secondary_button_text')
|
||||
->label('Secondary Button Text')
|
||||
->label('İkincil Buton Metni')
|
||||
->required()
|
||||
->maxLength(120),
|
||||
])
|
||||
@ -73,39 +74,39 @@ class ManageGeneralSettings extends SettingsPage
|
||||
->minItems(1)
|
||||
->collapsible()
|
||||
->reorderableWithButtons()
|
||||
->addActionLabel('Add Slide')
|
||||
->addActionLabel('Slide Ekle')
|
||||
->itemLabel(fn (array $state): ?string => filled($state['title'] ?? null) ? (string) $state['title'] : 'Slide')
|
||||
->afterStateHydrated(fn (Repeater $component, $state) => $component->state($this->normalizeHomeSlides($state)))
|
||||
->dehydrateStateUsing(fn ($state) => $this->normalizeHomeSlides($state)),
|
||||
FileUpload::make('site_logo')
|
||||
->label('Site Logo')
|
||||
->label('Site Logosu')
|
||||
->image()
|
||||
->disk('public')
|
||||
->directory('settings')
|
||||
->visibility('public'),
|
||||
TextInput::make('sender_name')
|
||||
->label('Sender Name')
|
||||
->label('Gönderici Adı')
|
||||
->required()
|
||||
->maxLength(120),
|
||||
TextInput::make('sender_email')
|
||||
->label('Sender Email')
|
||||
->label('Gönderici E-postası')
|
||||
->email()
|
||||
->required()
|
||||
->maxLength(255),
|
||||
Select::make('default_language')
|
||||
->label('Default Language')
|
||||
->label('Varsayılan Dil')
|
||||
->options($this->localeOptions())
|
||||
->required()
|
||||
->searchable(),
|
||||
CountryCodeSelect::make('default_country_code')
|
||||
->label('Default Country')
|
||||
->label('Varsayılan Ülke')
|
||||
->default('+90')
|
||||
->required()
|
||||
->helperText('Used as default country in panel forms.'),
|
||||
->helperText('Panel formlarında varsayılan ülke olarak kullanılır.'),
|
||||
TagsInput::make('currencies')
|
||||
->label('Currencies')
|
||||
->placeholder('USD')
|
||||
->helperText('Add 3-letter currency codes like USD, EUR, TRY.')
|
||||
->label('Para Birimleri')
|
||||
->placeholder('TRY')
|
||||
->helperText('TRY, USD, EUR gibi 3 harfli para birimi kodları ekleyin.')
|
||||
->required()
|
||||
->rules(['array', 'min:1'])
|
||||
->afterStateHydrated(fn (TagsInput $component, $state) => $component->state($this->normalizeCurrencies($state)))
|
||||
@ -125,19 +126,19 @@ class ManageGeneralSettings extends SettingsPage
|
||||
->defaultCountry(CountryCodeManager::defaultCountryIso2())
|
||||
->nullable()
|
||||
->formatAsYouType()
|
||||
->helperText('Use international format, e.g. +905551112233.'),
|
||||
->helperText('Uluslararası format kullanın. Örnek: +905551112233'),
|
||||
Toggle::make('enable_google_maps')
|
||||
->label('Enable Google Maps')
|
||||
->label('Google Maps Aktif')
|
||||
->default(false),
|
||||
TextInput::make('google_maps_api_key')
|
||||
->label('Google Maps API Key')
|
||||
->label('Google Maps API Anahtarı')
|
||||
->password()
|
||||
->revealable()
|
||||
->nullable()
|
||||
->maxLength(255)
|
||||
->helperText('Required to enable map fields in listing forms.'),
|
||||
->helperText('İlan formlarındaki harita alanlarını açmak için gereklidir.'),
|
||||
Toggle::make('enable_google_login')
|
||||
->label('Enable Google Login')
|
||||
->label('Google ile Giriş Aktif')
|
||||
->default(false),
|
||||
TextInput::make('google_client_id')
|
||||
->label('Google Client ID')
|
||||
@ -150,7 +151,7 @@ class ManageGeneralSettings extends SettingsPage
|
||||
->nullable()
|
||||
->maxLength(255),
|
||||
Toggle::make('enable_facebook_login')
|
||||
->label('Enable Facebook Login')
|
||||
->label('Facebook ile Giriş Aktif')
|
||||
->default(false),
|
||||
TextInput::make('facebook_client_id')
|
||||
->label('Facebook Client ID')
|
||||
@ -163,7 +164,7 @@ class ManageGeneralSettings extends SettingsPage
|
||||
->nullable()
|
||||
->maxLength(255),
|
||||
Toggle::make('enable_apple_login')
|
||||
->label('Enable Apple Login')
|
||||
->label('Apple ile Giriş Aktif')
|
||||
->default(false),
|
||||
TextInput::make('apple_client_id')
|
||||
->label('Apple Client ID')
|
||||
@ -183,14 +184,6 @@ class ManageGeneralSettings extends SettingsPage
|
||||
$labels = [
|
||||
'en' => 'English',
|
||||
'tr' => 'Türkçe',
|
||||
'ar' => 'العربية',
|
||||
'zh' => '中文',
|
||||
'es' => 'Español',
|
||||
'fr' => 'Français',
|
||||
'de' => 'Deutsch',
|
||||
'pt' => 'Português',
|
||||
'ru' => 'Русский',
|
||||
'ja' => '日本語',
|
||||
];
|
||||
|
||||
return collect(config('app.available_locales', ['en']))
|
||||
@ -215,47 +208,11 @@ class ManageGeneralSettings extends SettingsPage
|
||||
|
||||
private function defaultHomeSlides(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'badge' => 'OpenClassify Marketplace',
|
||||
'title' => 'İlan ücreti ödemeden ürününü hızla sat!',
|
||||
'subtitle' => 'Buy and sell everything in your area',
|
||||
'primary_button_text' => 'İncele',
|
||||
'secondary_button_text' => 'Post Listing',
|
||||
],
|
||||
];
|
||||
return HomeSlideDefaults::defaults();
|
||||
}
|
||||
|
||||
private function normalizeHomeSlides(mixed $state): array
|
||||
{
|
||||
$slides = is_array($state) ? $state : [];
|
||||
$fallbackSlide = $this->defaultHomeSlides()[0];
|
||||
|
||||
$normalized = collect($slides)
|
||||
->filter(fn ($slide): bool => is_array($slide))
|
||||
->map(function (array $slide) use ($fallbackSlide): ?array {
|
||||
$badge = trim((string) ($slide['badge'] ?? ''));
|
||||
$title = trim((string) ($slide['title'] ?? ''));
|
||||
$subtitle = trim((string) ($slide['subtitle'] ?? ''));
|
||||
$primaryButtonText = trim((string) ($slide['primary_button_text'] ?? ''));
|
||||
$secondaryButtonText = trim((string) ($slide['secondary_button_text'] ?? ''));
|
||||
|
||||
if ($title === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'badge' => $badge !== '' ? $badge : $fallbackSlide['badge'],
|
||||
'title' => $title,
|
||||
'subtitle' => $subtitle !== '' ? $subtitle : $fallbackSlide['subtitle'],
|
||||
'primary_button_text' => $primaryButtonText !== '' ? $primaryButtonText : $fallbackSlide['primary_button_text'],
|
||||
'secondary_button_text' => $secondaryButtonText !== '' ? $secondaryButtonText : $fallbackSlide['secondary_button_text'],
|
||||
];
|
||||
})
|
||||
->filter(fn ($slide): bool => is_array($slide))
|
||||
->values()
|
||||
->all();
|
||||
|
||||
return $normalized !== [] ? $normalized : $this->defaultHomeSlides();
|
||||
return HomeSlideDefaults::normalize($state);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Support\CountryCodeManager;
|
||||
use App\Support\HomeSlideDefaults;
|
||||
use App\Settings\GeneralSettings;
|
||||
use BezhanSalleh\LanguageSwitch\LanguageSwitch;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
@ -36,9 +37,9 @@ class AppServiceProvider extends ServiceProvider
|
||||
View::addNamespace('app', resource_path('views'));
|
||||
|
||||
$fallbackName = config('app.name', 'OpenClassify');
|
||||
$fallbackLocale = config('app.locale', 'en');
|
||||
$fallbackLocale = config('app.locale', 'tr');
|
||||
$fallbackCurrencies = $this->normalizeCurrencies(config('app.currencies', ['USD']));
|
||||
$fallbackDescription = 'The marketplace for buying and selling everything.';
|
||||
$fallbackDescription = 'Alım satım için hızlı ve güvenli ilan platformu.';
|
||||
$fallbackHomeSlides = $this->defaultHomeSlides();
|
||||
$fallbackGoogleMapsApiKey = env('GOOGLE_MAPS_API_KEY');
|
||||
$fallbackGoogleClientId = env('GOOGLE_CLIENT_ID');
|
||||
@ -100,7 +101,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
$appleClientId = trim((string) ($settings->apple_client_id ?: $fallbackAppleClientId));
|
||||
$appleClientSecret = trim((string) ($settings->apple_client_secret ?: $fallbackAppleClientSecret));
|
||||
$defaultCountryCode = CountryCodeManager::normalizeCountryCode($settings->default_country_code ?? $fallbackDefaultCountryCode);
|
||||
$homeSlides = $this->normalizeHomeSlides($settings->home_slides ?? [], $fallbackHomeSlides);
|
||||
$homeSlides = $this->normalizeHomeSlides($settings->home_slides ?? []);
|
||||
|
||||
$generalSettings = [
|
||||
'site_name' => trim((string) ($settings->site_name ?: $fallbackName)),
|
||||
@ -178,14 +179,6 @@ class AppServiceProvider extends ServiceProvider
|
||||
$localeLabels = [
|
||||
'en' => 'English',
|
||||
'tr' => 'Türkçe',
|
||||
'ar' => 'العربية',
|
||||
'zh' => '中文',
|
||||
'es' => 'Español',
|
||||
'fr' => 'Français',
|
||||
'de' => 'Deutsch',
|
||||
'pt' => 'Português',
|
||||
'ru' => 'Русский',
|
||||
'ja' => '日本語',
|
||||
];
|
||||
|
||||
LanguageSwitch::configureUsing(function (LanguageSwitch $switch) use ($availableLocales, $localeLabels): void {
|
||||
@ -260,56 +253,11 @@ class AppServiceProvider extends ServiceProvider
|
||||
|
||||
private function defaultHomeSlides(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'badge' => 'OpenClassify Marketplace',
|
||||
'title' => 'İlan ücreti ödemeden ürününü hızla sat!',
|
||||
'subtitle' => 'Buy and sell everything in your area',
|
||||
'primary_button_text' => 'İncele',
|
||||
'secondary_button_text' => 'Post Listing',
|
||||
],
|
||||
];
|
||||
return HomeSlideDefaults::defaults();
|
||||
}
|
||||
|
||||
private function normalizeHomeSlides(mixed $slides, array $fallbackSlides): array
|
||||
private function normalizeHomeSlides(mixed $slides): array
|
||||
{
|
||||
if (! is_array($slides)) {
|
||||
return $fallbackSlides;
|
||||
}
|
||||
|
||||
$fallbackSlide = $fallbackSlides[0] ?? [
|
||||
'badge' => 'OpenClassify Marketplace',
|
||||
'title' => 'İlan ücreti ödemeden ürününü hızla sat!',
|
||||
'subtitle' => 'Buy and sell everything in your area',
|
||||
'primary_button_text' => 'İncele',
|
||||
'secondary_button_text' => 'Post Listing',
|
||||
];
|
||||
|
||||
$normalized = collect($slides)
|
||||
->filter(fn ($slide): bool => is_array($slide))
|
||||
->map(function (array $slide) use ($fallbackSlide): ?array {
|
||||
$badge = trim((string) ($slide['badge'] ?? ''));
|
||||
$title = trim((string) ($slide['title'] ?? ''));
|
||||
$subtitle = trim((string) ($slide['subtitle'] ?? ''));
|
||||
$primaryButtonText = trim((string) ($slide['primary_button_text'] ?? ''));
|
||||
$secondaryButtonText = trim((string) ($slide['secondary_button_text'] ?? ''));
|
||||
|
||||
if ($title === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'badge' => $badge !== '' ? $badge : $fallbackSlide['badge'],
|
||||
'title' => $title,
|
||||
'subtitle' => $subtitle !== '' ? $subtitle : $fallbackSlide['subtitle'],
|
||||
'primary_button_text' => $primaryButtonText !== '' ? $primaryButtonText : $fallbackSlide['primary_button_text'],
|
||||
'secondary_button_text' => $secondaryButtonText !== '' ? $secondaryButtonText : $fallbackSlide['secondary_button_text'],
|
||||
];
|
||||
})
|
||||
->filter(fn ($slide): bool => is_array($slide))
|
||||
->values()
|
||||
->all();
|
||||
|
||||
return $normalized !== [] ? $normalized : $fallbackSlides;
|
||||
return HomeSlideDefaults::normalize($slides);
|
||||
}
|
||||
}
|
||||
|
||||
77
app/Support/HomeSlideDefaults.php
Normal file
77
app/Support/HomeSlideDefaults.php
Normal file
@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace App\Support;
|
||||
|
||||
final class HomeSlideDefaults
|
||||
{
|
||||
/**
|
||||
* @return array<int, array{badge: string, title: string, subtitle: string, primary_button_text: string, secondary_button_text: string}>
|
||||
*/
|
||||
public static function defaults(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'badge' => 'Vitrin İlanları',
|
||||
'title' => 'İlan ücreti ödemeden ürününü dakikalar içinde yayına al.',
|
||||
'subtitle' => 'Mahallendeki alıcılarla hızlıca buluş, pazarlığı doğrudan mesajla tamamla.',
|
||||
'primary_button_text' => 'İlanları İncele',
|
||||
'secondary_button_text' => 'İlan Ver',
|
||||
],
|
||||
[
|
||||
'badge' => 'Günün Fırsatları',
|
||||
'title' => 'Elektronikten araca kadar her kategoride canlı ilanlar seni bekliyor.',
|
||||
'subtitle' => 'Kategorilere göz at, favorilerine ekle ve satıcılarla tek tıkla iletişime geç.',
|
||||
'primary_button_text' => 'Kategorileri Gör',
|
||||
'secondary_button_text' => 'Hemen Başla',
|
||||
],
|
||||
[
|
||||
'badge' => 'Yerel Alışveriş',
|
||||
'title' => 'Konumuna en yakın ikinci el fırsatları tek ekranda keşfet.',
|
||||
'subtitle' => 'Şehrini seç, sana en yakın ilanları filtrele ve güvenle alışveriş yap.',
|
||||
'primary_button_text' => 'Yakındaki İlanlar',
|
||||
'secondary_button_text' => 'Ücretsiz İlan Ver',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, array{badge: string, title: string, subtitle: string, primary_button_text: string, secondary_button_text: string}>
|
||||
*/
|
||||
public static function normalize(mixed $slides): array
|
||||
{
|
||||
$defaults = self::defaults();
|
||||
$source = is_array($slides) ? $slides : [];
|
||||
|
||||
$normalized = collect($source)
|
||||
->filter(fn ($slide): bool => is_array($slide))
|
||||
->values()
|
||||
->map(function (array $slide, int $index) use ($defaults): ?array {
|
||||
$fallback = $defaults[$index] ?? $defaults[array_key_last($defaults)];
|
||||
$badge = trim((string) ($slide['badge'] ?? ''));
|
||||
$title = trim((string) ($slide['title'] ?? ''));
|
||||
$subtitle = trim((string) ($slide['subtitle'] ?? ''));
|
||||
$primaryButtonText = trim((string) ($slide['primary_button_text'] ?? ''));
|
||||
$secondaryButtonText = trim((string) ($slide['secondary_button_text'] ?? ''));
|
||||
|
||||
if ($title === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'badge' => $badge !== '' ? $badge : $fallback['badge'],
|
||||
'title' => $title,
|
||||
'subtitle' => $subtitle !== '' ? $subtitle : $fallback['subtitle'],
|
||||
'primary_button_text' => $primaryButtonText !== '' ? $primaryButtonText : $fallback['primary_button_text'],
|
||||
'secondary_button_text' => $secondaryButtonText !== '' ? $secondaryButtonText : $fallback['secondary_button_text'],
|
||||
];
|
||||
})
|
||||
->filter(fn ($slide): bool => is_array($slide))
|
||||
->values();
|
||||
|
||||
return $normalized
|
||||
->concat(collect($defaults)->slice($normalized->count()))
|
||||
->take(count($defaults))
|
||||
->values()
|
||||
->all();
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Support\HomeSlideDefaults;
|
||||
use App\Settings\GeneralSettings;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
@ -10,51 +11,13 @@ class HomeSliderSettingsSeeder extends Seeder
|
||||
public function run(): void
|
||||
{
|
||||
$settings = app(GeneralSettings::class);
|
||||
$fallbackSlide = $this->defaultHomeSlides()[0];
|
||||
|
||||
$slides = is_array($settings->home_slides ?? null) ? $settings->home_slides : [];
|
||||
|
||||
$normalized = collect($slides)
|
||||
->filter(fn ($slide): bool => is_array($slide))
|
||||
->map(function (array $slide) use ($fallbackSlide): ?array {
|
||||
$title = trim((string) ($slide['title'] ?? ''));
|
||||
|
||||
if ($title === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$badge = trim((string) ($slide['badge'] ?? ''));
|
||||
$subtitle = trim((string) ($slide['subtitle'] ?? ''));
|
||||
$primaryButtonText = trim((string) ($slide['primary_button_text'] ?? ''));
|
||||
$secondaryButtonText = trim((string) ($slide['secondary_button_text'] ?? ''));
|
||||
|
||||
return [
|
||||
'badge' => $badge !== '' ? $badge : $fallbackSlide['badge'],
|
||||
'title' => $title,
|
||||
'subtitle' => $subtitle !== '' ? $subtitle : $fallbackSlide['subtitle'],
|
||||
'primary_button_text' => $primaryButtonText !== '' ? $primaryButtonText : $fallbackSlide['primary_button_text'],
|
||||
'secondary_button_text' => $secondaryButtonText !== '' ? $secondaryButtonText : $fallbackSlide['secondary_button_text'],
|
||||
];
|
||||
})
|
||||
->filter(fn ($slide): bool => is_array($slide))
|
||||
->values()
|
||||
->all();
|
||||
|
||||
$settings->home_slides = $normalized !== [] ? $normalized : $this->defaultHomeSlides();
|
||||
$settings->home_slides = HomeSlideDefaults::normalize($settings->home_slides ?? []);
|
||||
|
||||
$settings->save();
|
||||
}
|
||||
|
||||
private function defaultHomeSlides(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'badge' => 'OpenClassify Marketplace',
|
||||
'title' => 'İlan ücreti ödemeden ürününü hızla sat!',
|
||||
'subtitle' => 'Buy and sell everything in your area',
|
||||
'primary_button_text' => 'İncele',
|
||||
'secondary_button_text' => 'Post Listing',
|
||||
],
|
||||
];
|
||||
return HomeSlideDefaults::defaults();
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user