From f381caaa398c2ba1aa5189541bbb86504d0f5983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=9Cmit=20Tun=C3=A7?= Date: Tue, 30 Dec 2025 22:49:55 +0300 Subject: [PATCH] Implement Localization for Product and ProductCategory Resources: Refactored resource classes and forms to utilize Laravel's localization features, enhancing user experience by providing translated labels and sections. Added English and Turkish language support for product and category management, ensuring consistency across the admin panel. --- .../ProductCategoryResource.php | 11 ++++--- .../Schemas/ProductCategoryForm.php | 11 ++++--- .../Tables/ProductCategoriesTable.php | 9 ++++-- .../Resources/Products/ProductResource.php | 11 ++++--- .../Products/Schemas/ProductForm.php | 25 +++++++++------- .../Products/Tables/ProductsTable.php | 16 ++++++++-- app/Providers/Filament/AdminPanelProvider.php | 2 ++ lang/en/product_categories.php | 22 ++++++++++++++ lang/en/products.php | 29 +++++++++++++++++++ lang/tr/product_categories.php | 22 ++++++++++++++ lang/tr/products.php | 29 +++++++++++++++++++ 11 files changed, 160 insertions(+), 27 deletions(-) create mode 100644 lang/en/product_categories.php create mode 100644 lang/en/products.php create mode 100644 lang/tr/product_categories.php create mode 100644 lang/tr/products.php diff --git a/app/Filament/Admin/Resources/ProductCategories/ProductCategoryResource.php b/app/Filament/Admin/Resources/ProductCategories/ProductCategoryResource.php index 8617ed7..2102ddc 100644 --- a/app/Filament/Admin/Resources/ProductCategories/ProductCategoryResource.php +++ b/app/Filament/Admin/Resources/ProductCategories/ProductCategoryResource.php @@ -20,21 +20,24 @@ class ProductCategoryResource extends Resource protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedTag; - protected static \UnitEnum|string|null $navigationGroup = 'Ürün ve Hizmetler'; + public static function getNavigationGroup(): ?string + { + return __('product_categories.navigation_group'); + } public static function getNavigationLabel(): string { - return 'Kategoriler'; + return __('product_categories.menu_label'); } public static function getModelLabel(): string { - return 'Kategori'; + return __('product_categories.model_label'); } public static function getPluralModelLabel(): string { - return 'Kategoriler'; + return __('product_categories.plural_model_label'); } public static function form(Schema $schema): Schema diff --git a/app/Filament/Admin/Resources/ProductCategories/Schemas/ProductCategoryForm.php b/app/Filament/Admin/Resources/ProductCategories/Schemas/ProductCategoryForm.php index bc315bc..aa089d1 100644 --- a/app/Filament/Admin/Resources/ProductCategories/Schemas/ProductCategoryForm.php +++ b/app/Filament/Admin/Resources/ProductCategories/Schemas/ProductCategoryForm.php @@ -16,13 +16,14 @@ class ProductCategoryForm { return $schema ->schema([ - Section::make('General') + Section::make(__('product_categories.general_section')) ->schema([ TextInput::make('slug') + ->label(__('product_categories.slug')) ->required() ->unique(ignoreRecord: true), Select::make('parent_id') - ->label('Parent Category') + ->label(__('product_categories.parent_category')) ->options(function () { return ProductCategory::all()->mapWithKeys(function ($category) { $title = is_array($category->title) @@ -33,18 +34,20 @@ class ProductCategoryForm }) ->searchable(), TextInput::make('sort_order') + ->label(__('product_categories.sort_order')) ->numeric() ->default(0), Toggle::make('is_active') + ->label(__('product_categories.is_active')) ->default(true), ])->columns(2), - Section::make('Translations') + Section::make(__('product_categories.translations_section')) ->schema([ TranslationTabs::make([ 'title' => [ 'type' => 'text', - 'label' => 'Title', + 'label' => __('product_categories.title'), 'required' => true, ], ]), diff --git a/app/Filament/Admin/Resources/ProductCategories/Tables/ProductCategoriesTable.php b/app/Filament/Admin/Resources/ProductCategories/Tables/ProductCategoriesTable.php index 5f1cce5..ca4299a 100644 --- a/app/Filament/Admin/Resources/ProductCategories/Tables/ProductCategoriesTable.php +++ b/app/Filament/Admin/Resources/ProductCategories/Tables/ProductCategoriesTable.php @@ -17,18 +17,23 @@ class ProductCategoriesTable return $table ->columns([ TextColumn::make('title') + ->label(__('product_categories.title')) ->formatStateUsing(fn ($state) => is_array($state) ? ($state[app()->getLocale()] ?? reset($state)) : $state) ->searchable() ->sortable(), TextColumn::make('slug') + ->label(__('product_categories.slug')) ->searchable(), TextColumn::make('parent.title') // This might fail if parent title is JSON ->formatStateUsing(fn ($state) => is_array($state) ? ($state[app()->getLocale()] ?? reset($state)) : $state) - ->label('Parent'), + ->label(__('product_categories.parent')), TextColumn::make('sort_order') + ->label(__('product_categories.sort_order')) ->sortable(), - ToggleColumn::make('is_active'), + ToggleColumn::make('is_active') + ->label(__('product_categories.is_active')), TextColumn::make('created_at') + ->label(__('product_categories.created_at')) ->dateTime() ->sortable() ->toggleable(isToggledHiddenByDefault: true), diff --git a/app/Filament/Admin/Resources/Products/ProductResource.php b/app/Filament/Admin/Resources/Products/ProductResource.php index 3385c2f..df99819 100644 --- a/app/Filament/Admin/Resources/Products/ProductResource.php +++ b/app/Filament/Admin/Resources/Products/ProductResource.php @@ -20,21 +20,24 @@ class ProductResource extends Resource protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedCube; - protected static \UnitEnum|string|null $navigationGroup = 'Ürün ve Hizmetler'; + public static function getNavigationGroup(): ?string + { + return __('products.navigation_group'); + } public static function getNavigationLabel(): string { - return 'Ürün ve Hizmet Listesi'; + return __('products.menu_label'); } public static function getModelLabel(): string { - return 'Ürün/Hizmet'; + return __('products.model_label'); } public static function getPluralModelLabel(): string { - return 'Ürün ve Hizmetler'; + return __('products.plural_model_label'); } public static function form(Schema $schema): Schema diff --git a/app/Filament/Admin/Resources/Products/Schemas/ProductForm.php b/app/Filament/Admin/Resources/Products/Schemas/ProductForm.php index 1aab03a..df3c05d 100644 --- a/app/Filament/Admin/Resources/Products/Schemas/ProductForm.php +++ b/app/Filament/Admin/Resources/Products/Schemas/ProductForm.php @@ -17,19 +17,21 @@ class ProductForm { return $schema ->schema([ - Section::make('General') + Section::make(__('products.general_section')) ->schema([ TextInput::make('slug') + ->label(__('products.slug')) ->required() ->unique(ignoreRecord: true), Select::make('type') + ->label(__('products.type')) ->options([ - 'product' => 'Product', - 'service' => 'Service', + 'product' => __('products.product'), + 'service' => __('products.service'), ]) ->required(), Select::make('product_category_id') - ->label('Category') + ->label(__('products.category')) ->options(function () { return ProductCategory::all()->mapWithKeys(function ($category) { $title = is_array($category->title) @@ -40,30 +42,33 @@ class ProductForm }) ->searchable(), FileUpload::make('hero_image') + ->label(__('products.hero_image')) ->image() ->directory('products'), TextInput::make('view_template') - ->label('Custom View Path') - ->placeholder('e.g. front.products.custom-page') - ->helperText('Leave empty to use the default landing page.'), + ->label(__('products.view_template')) + ->placeholder(__('products.view_template_placeholder')) + ->helperText(__('products.view_template_helper')), TextInput::make('sort_order') + ->label(__('products.sort_order')) ->numeric() ->default(0), Toggle::make('is_active') + ->label(__('products.is_active')) ->default(true), ])->columns(2), - Section::make('Translations') + Section::make(__('products.translations_section')) ->schema([ TranslationTabs::make([ 'title' => [ 'type' => 'text', - 'label' => 'Title', + 'label' => __('products.title'), 'required' => true, ], 'content' => [ 'type' => 'richtext', - 'label' => 'Content', + 'label' => __('products.content'), ], ]), ]), diff --git a/app/Filament/Admin/Resources/Products/Tables/ProductsTable.php b/app/Filament/Admin/Resources/Products/Tables/ProductsTable.php index 9477677..94e5645 100644 --- a/app/Filament/Admin/Resources/Products/Tables/ProductsTable.php +++ b/app/Filament/Admin/Resources/Products/Tables/ProductsTable.php @@ -17,23 +17,33 @@ class ProductsTable { return $table ->columns([ - ImageColumn::make('hero_image'), + ImageColumn::make('hero_image') + ->label(__('products.hero_image')), TextColumn::make('title') + ->label(__('products.title')) ->formatStateUsing(fn ($state) => is_array($state) ? ($state[app()->getLocale()] ?? reset($state)) : $state) ->searchable() ->sortable(), TextColumn::make('type') + ->label(__('products.type')) ->badge() ->color(fn (string $state): string => match ($state) { 'product' => 'info', 'service' => 'success', default => 'gray', + }) + ->formatStateUsing(fn (string $state): string => match ($state) { + 'product' => __('products.product'), + 'service' => __('products.service'), + default => $state, }), TextColumn::make('category.title') ->formatStateUsing(fn ($state) => is_array($state) ? ($state[app()->getLocale()] ?? reset($state)) : $state) - ->label('Category'), - ToggleColumn::make('is_active'), + ->label(__('products.category')), + ToggleColumn::make('is_active') + ->label(__('products.is_active')), TextColumn::make('sort_order') + ->label(__('products.sort_order')) ->sortable(), ]) ->filters([ diff --git a/app/Providers/Filament/AdminPanelProvider.php b/app/Providers/Filament/AdminPanelProvider.php index aa42f61..c187e4e 100644 --- a/app/Providers/Filament/AdminPanelProvider.php +++ b/app/Providers/Filament/AdminPanelProvider.php @@ -22,6 +22,7 @@ use Illuminate\View\Middleware\ShareErrorsFromSession; use Filament\Navigation\MenuItem; use App\Models\Language; use Illuminate\Support\Facades\Schema; +use App\Http\Middleware\SetLocale; class AdminPanelProvider extends PanelProvider { @@ -67,6 +68,7 @@ class AdminPanelProvider extends PanelProvider SubstituteBindings::class, DisableBladeIconComponents::class, DispatchServingFilamentEvent::class, + SetLocale::class, ]) ->authMiddleware([ Authenticate::class, diff --git a/lang/en/product_categories.php b/lang/en/product_categories.php new file mode 100644 index 0000000..a91babd --- /dev/null +++ b/lang/en/product_categories.php @@ -0,0 +1,22 @@ + 'Products & Services', + 'menu_label' => 'Categories', + 'model_label' => 'Category', + 'plural_model_label' => 'Categories', + + // Form + 'general_section' => 'General Information', + 'slug' => 'Slug', + 'parent_category' => 'Parent Category', + 'sort_order' => 'Sort Order', + 'is_active' => 'Active', + 'translations_section' => 'Translations', + + // Table + 'title' => 'Title', + 'parent' => 'Parent Category', + 'created_at' => 'Created At', +]; + diff --git a/lang/en/products.php b/lang/en/products.php new file mode 100644 index 0000000..2987ce9 --- /dev/null +++ b/lang/en/products.php @@ -0,0 +1,29 @@ + 'Products & Services', + 'menu_label' => 'Product & Service List', + 'model_label' => 'Product/Service', + 'plural_model_label' => 'Products & Services', + + // Form + 'general_section' => 'General Information', + 'slug' => 'Slug', + 'type' => 'Type', + 'product' => 'Product', + 'service' => 'Service', + 'category' => 'Category', + 'hero_image' => 'Hero Image', + 'view_template' => 'Custom View Path', + 'view_template_placeholder' => 'e.g. front.products.custom-page', + 'view_template_helper' => 'Leave empty to use the default landing page.', + 'sort_order' => 'Sort Order', + 'is_active' => 'Active', + 'translations_section' => 'Translations', + 'content' => 'Content', + + // Table + 'title' => 'Title', + 'created_at' => 'Created At', +]; + diff --git a/lang/tr/product_categories.php b/lang/tr/product_categories.php new file mode 100644 index 0000000..b3c2b58 --- /dev/null +++ b/lang/tr/product_categories.php @@ -0,0 +1,22 @@ + 'Ürün ve Hizmetler', + 'menu_label' => 'Kategoriler', + 'model_label' => 'Kategori', + 'plural_model_label' => 'Kategoriler', + + // Form + 'general_section' => 'Genel Bilgiler', + 'slug' => 'Slug (Bağlantı Yolu)', + 'parent_category' => 'Üst Kategori', + 'sort_order' => 'Sıralama', + 'is_active' => 'Aktif', + 'translations_section' => 'Çeviriler', + + // Table + 'title' => 'Başlık', + 'parent' => 'Üst Kategori', + 'created_at' => 'Oluşturulma Tarihi', +]; + diff --git a/lang/tr/products.php b/lang/tr/products.php new file mode 100644 index 0000000..f0b6962 --- /dev/null +++ b/lang/tr/products.php @@ -0,0 +1,29 @@ + 'Ürün ve Hizmetler', + 'menu_label' => 'Ürün ve Hizmet Listesi', + 'model_label' => 'Ürün/Hizmet', + 'plural_model_label' => 'Ürün ve Hizmetler', + + // Form + 'general_section' => 'Genel Bilgiler', + 'slug' => 'Slug (Bağlantı Yolu)', + 'type' => 'Tür', + 'product' => 'Ürün', + 'service' => 'Hizmet', + 'category' => 'Kategori', + 'hero_image' => 'Kapak Görseli', + 'view_template' => 'Özel Görünüm Yolu', + 'view_template_placeholder' => 'örn: front.products.ozel-sayfa', + 'view_template_helper' => 'Varsayılan şablonu kullanmak için boş bırakın.', + 'sort_order' => 'Sıralama', + 'is_active' => 'Aktif', + 'translations_section' => 'Çeviriler', + 'content' => 'İçerik', + + // Table + 'title' => 'Başlık', + 'created_at' => 'Oluşturulma Tarihi', +]; +