Refactor code for consistency and clarity; update seeder comments, enhance error handling, and improve API routes. Added 'original' field to ProductMediaResource and adjusted various formatting issues across multiple files.

This commit is contained in:
Mekan1206
2026-02-20 15:33:29 +05:00
parent a8599d9c79
commit 1e84ceab3c
27 changed files with 314 additions and 51 deletions

View File

@@ -3,9 +3,9 @@
namespace App\Exceptions; namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable; use Throwable;
use Symfony\Component\HttpKernel\Exception\HttpException;
class Handler extends ExceptionHandler class Handler extends ExceptionHandler
{ {

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Http\Controllers\Api\V1\Category\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class SelectedCategoryResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @return array<string, mixed>
*/
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'name' => $this->name,
'description' => $this->description,
'is_visible' => $this->is_visible,
'categories' => CategoryResource::collection($this->whenLoaded('categories')),
];
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace App\Http\Controllers\Api\V1\Category;
use App\Http\Controllers\Api\V1\Category\Resources\SelectedCategoryResource;
use App\Http\Controllers\Controller;
use App\Models\Ecommerce\Product\Category\SelectedCategory;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class SelectedCategoryController extends Controller
{
/**
* Selected Categories (index)
*/
public function index(Request $request): JsonResponse
{
$selectedCategories = SelectedCategory::query()
->where('is_visible', true)
->with(['categories' => function ($query) {
$query->where('is_visible', true)->ordered()->with(['media']);
}])
->get();
return response()->json(SelectedCategoryResource::collection($selectedCategories));
}
/**
* Selected Categories (show)
*/
public function show(SelectedCategory $selectedCategory): JsonResponse
{
$selectedCategory->load('categories');
return response()->json(new SelectedCategoryResource($selectedCategory));
}
}

View File

@@ -14,7 +14,7 @@ class OrderPaymentController extends Controller
public function index(): JsonResponse public function index(): JsonResponse
{ {
return response()->rest( return response()->rest(
PaymentType::all(['id', 'name']) PaymentType::query()->where('is_enabled', true)->get(['id', 'name'])
->map(fn ($paymentType) => [ ->map(fn ($paymentType) => [
'id' => $paymentType->id, 'id' => $paymentType->id,
'name' => $paymentType->name, 'name' => $paymentType->name,

View File

@@ -15,6 +15,7 @@ class ProductMediaResource extends JsonResource
public function toArray(Request $request): array public function toArray(Request $request): array
{ {
return [ return [
'original' => $this->getUrl(),
'thumbnail' => $this->getUrl('thumb400x400'), 'thumbnail' => $this->getUrl('thumb400x400'),
'images_400x400' => $this->getUrl('thumb400x400'), 'images_400x400' => $this->getUrl('thumb400x400'),
'images_800x800' => $this->getUrl('thumb800x800'), 'images_800x800' => $this->getUrl('thumb800x800'),

View File

@@ -0,0 +1,31 @@
<?php
namespace App\Models\Ecommerce\Product\Category;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Spatie\Translatable\HasTranslations;
class SelectedCategory extends Model
{
use HasFactory;
use HasTranslations;
protected $fillable = [
'name',
'description',
'is_visible',
];
public $translatable = ['name', 'description'];
protected $casts = [
'is_visible' => 'boolean',
];
public function categories(): BelongsToMany
{
return $this->belongsToMany(Category::class, 'category_selected_category');
}
}

View File

@@ -2,11 +2,11 @@
namespace App\Models\Ecommerce\Product\Order; namespace App\Models\Ecommerce\Product\Order;
use App\Models\Concerns\HasSchemalessAttributes;
use App\Models\Ecommerce\Product\Order\Concerns\HasPayments; use App\Models\Ecommerce\Product\Order\Concerns\HasPayments;
use App\Models\Ecommerce\Product\Order\Concerns\HasShipping; use App\Models\Ecommerce\Product\Order\Concerns\HasShipping;
use App\Models\Ecommerce\Product\Order\Concerns\HasStatus; use App\Models\Ecommerce\Product\Order\Concerns\HasStatus;
use App\Models\Ecommerce\Product\Order\Status\OrderStatus; use App\Models\Ecommerce\Product\Order\Status\OrderStatus;
use App\Models\Concerns\HasSchemalessAttributes;
use App\Models\System\Settings\Location\Province; use App\Models\System\Settings\Location\Province;
use App\Models\System\Settings\Payments\PaymentType; use App\Models\System\Settings\Payments\PaymentType;
use App\Models\User; use App\Models\User;
@@ -20,10 +20,10 @@ class Order extends Model
{ {
use HasFactory; use HasFactory;
use HasPayments; use HasPayments;
use HasSchemalessAttributes;
use HasShipping; use HasShipping;
use HasStatus; use HasStatus;
use SoftDeletes; use SoftDeletes;
use HasSchemalessAttributes;
/** /**
* The attributes that are mass assignable. * The attributes that are mass assignable.

View File

@@ -0,0 +1,120 @@
<?php
namespace App\Nova\Resources\Ecommerce\Product\Category;
use App\Models\Ecommerce\Product\Category\SelectedCategory as SelectedCategoryModel;
use App\Nova\Resource;
use Laravel\Nova\Fields\BelongsToMany;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Textarea;
use Laravel\Nova\Http\Requests\NovaRequest;
use Trin4ik\NovaSwitcher\NovaSwitcher;
class SelectedCategory extends Resource
{
/**
* The model the resource corresponds to.
*
* @var class-string<SelectedCategoryModel>
*/
public static $model = SelectedCategoryModel::class;
/**
* The single value that should be used to represent the resource when being displayed.
*
* @var string
*/
public static $title = 'name';
/**
* The columns that should be searched.
*
* @var array
*/
public static $search = [
'id', 'name',
];
/**
* Get the displayable label of the resource.
*/
public static function label(): string
{
return __('Sections');
}
/**
* Get the displayable singular label of the resource.
*/
public static function singularLabel(): string
{
return __('Section');
}
/**
* Get the fields displayed by the resource.
*
* @return array
*/
public function fields(NovaRequest $request)
{
return [
ID::make()->sortable(),
Text::make(__('Name'), 'name')
->sortable()
->translatable()
->rules('required'),
Textarea::make(__('Description'), 'description')
->translatable()
->nullable(),
NovaSwitcher::make(__('Is Visible'), 'is_visible')
->default(true),
BelongsToMany::make(__('Categories'), 'categories', Category::class),
];
}
/**
* Get the cards available for the request.
*
* @return array
*/
public function cards(NovaRequest $request)
{
return [];
}
/**
* Get the filters available for the resource.
*
* @return array
*/
public function filters(NovaRequest $request)
{
return [];
}
/**
* Get the lenses available for the resource.
*
* @return array
*/
public function lenses(NovaRequest $request)
{
return [];
}
/**
* Get the actions available for the resource.
*
* @return array
*/
public function actions(NovaRequest $request)
{
return [];
}
}

View File

@@ -15,6 +15,7 @@ use App\Nova\Resources\Ecommerce\Payout\PayoutResource;
use App\Nova\Resources\Ecommerce\Product\Attribute\Attribute; use App\Nova\Resources\Ecommerce\Product\Attribute\Attribute;
use App\Nova\Resources\Ecommerce\Product\Brand\Brand; use App\Nova\Resources\Ecommerce\Product\Brand\Brand;
use App\Nova\Resources\Ecommerce\Product\Category\Category; use App\Nova\Resources\Ecommerce\Product\Category\Category;
use App\Nova\Resources\Ecommerce\Product\Category\SelectedCategory;
use App\Nova\Resources\Ecommerce\Product\Collection\Collection; use App\Nova\Resources\Ecommerce\Product\Collection\Collection;
use App\Nova\Resources\Ecommerce\Product\Coupon\Coupon; use App\Nova\Resources\Ecommerce\Product\Coupon\Coupon;
use App\Nova\Resources\Ecommerce\Product\Inventory\Inventory; use App\Nova\Resources\Ecommerce\Product\Inventory\Inventory;
@@ -158,6 +159,7 @@ class NovaServiceProvider extends NovaApplicationServiceProvider
MenuItem::resource(Category::class), MenuItem::resource(Category::class),
MenuItem::resource(Brand::class), MenuItem::resource(Brand::class),
MenuItem::resource(Attribute::class), MenuItem::resource(Attribute::class),
MenuItem::resource(SelectedCategory::class),
])->icon('color-swatch'), ])->icon('color-swatch'),
])->icon('shopping-bag')->collapsedByDefault(), ])->icon('shopping-bag')->collapsedByDefault(),

View File

@@ -3,7 +3,6 @@
namespace App\Repositories\Ecommerce\Product\Category; namespace App\Repositories\Ecommerce\Product\Category;
use App\Models\Ecommerce\Product\Category\Category; use App\Models\Ecommerce\Product\Category\Category;
use App\Repositories\System\Cache\CacheRepository;
use Illuminate\Http\Request; use Illuminate\Http\Request;
class CategoryRepository class CategoryRepository

View File

@@ -1,9 +1,10 @@
<?php <?php
namespace App\Support; namespace App\Support;
use Spatie\MediaLibrary\Support\FileNamer\FileNamer;
use Spatie\MediaLibrary\Conversions\Conversion;
use Illuminate\Support\Str; use Illuminate\Support\Str;
use Spatie\MediaLibrary\Conversions\Conversion;
use Spatie\MediaLibrary\Support\FileNamer\FileNamer;
class ShortFileNamer extends FileNamer class ShortFileNamer extends FileNamer
{ {
@@ -15,9 +16,6 @@ class ShortFileNamer extends FileNamer
return Str::random(10); return Str::random(10);
} }
/**
*
*/
public function conversionFileName(string $fileName, Conversion $conversion): string public function conversionFileName(string $fileName, Conversion $conversion): string
{ {
return $conversion->getName(); return $conversion->getName();

View File

@@ -0,0 +1,24 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('selected_categories', function (Blueprint $table) {
$table->id();
$table->jsonb('name');
$table->jsonb('description')->nullable();
$table->boolean('is_visible')->default(true);
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('selected_categories');
}
};

View File

@@ -0,0 +1,23 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('category_selected_category', function (Blueprint $table) {
$table->id();
$table->foreignId('selected_category_id')->constrained()->cascadeOnDelete();
$table->foreignId('category_id')->constrained()->cascadeOnDelete();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('category_selected_category');
}
};

View File

@@ -33,26 +33,26 @@ class DatabaseSeeder extends Seeder
public function run(): void public function run(): void
{ {
$this->call([ $this->call([
PaymentTypeSeeder::class, // PaymentTypeSeeder::class,
UsersTableSeeder::class, UsersTableSeeder::class,
BrandsSeeder::class, // BrandsSeeder::class,
CustomersTableSeeder::class, // CustomersTableSeeder::class,
SellersTableSeeder::class, // SellersTableSeeder::class,
ProductsTableSeeder::class, // ProductsTableSeeder::class,
ProductPricesSeeder::class, // ProductPricesSeeder::class,
CategoriesTableSeeder::class, // CategoriesTableSeeder::class,
AddressSeeder::class, // AddressSeeder::class,
PropertiesTableSeeder::class, // PropertiesTableSeeder::class,
FavoritesSeeder::class, // FavoritesSeeder::class,
SectionsSeeder::class, // SectionsSeeder::class,
ProductCategoryRelationshipsSeeder::class, // ProductCategoryRelationshipsSeeder::class,
ProductBarcodesSeeder::class, // ProductBarcodesSeeder::class,
ProductPropertiesSeeder::class, // ProductPropertiesSeeder::class,
ProductPropertyValuesSeeder::class, // ProductPropertyValuesSeeder::class,
ProductStocksSeeder::class, // ProductStocksSeeder::class,
MediaSeeder::class, // MediaSeeder::class,
OrderSeeder::class, // OrderSeeder::class,
OrderAddressSeeder::class, // OrderAddressSeeder::class,
]); ]);
} }
} }

View File

@@ -5,7 +5,6 @@ namespace Database\Seeders;
use App\Models\System\Settings\Payments\PaymentType; use App\Models\System\Settings\Payments\PaymentType;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
class PaymentTypeSeeder extends Seeder class PaymentTypeSeeder extends Seeder
{ {
/** /**

View File

@@ -24,7 +24,7 @@ class UsersTableSeeder extends Seeder
*/ */
public function seedStarterKit(): void public function seedStarterKit(): void
{ {
$this->seedRoles(); // $this->seedRoles();
collect([ collect([
[ [
@@ -39,7 +39,7 @@ class UsersTableSeeder extends Seeder
$user->assignRole('admin'); $user->assignRole('admin');
}); });
$this->createChannels(); // $this->createChannels();
} }
public function seedRoles(): void public function seedRoles(): void

View File

@@ -35,7 +35,7 @@ class MediaSeeder extends Seeder
} }
DB::table($table)->insert([ DB::table($table)->insert([
"id" => $data['id'], 'id' => $data['id'],
'model_type' => $modelType, 'model_type' => $modelType,
'model_id' => $data['model_id'], 'model_id' => $data['model_id'],
'uuid' => $data['uuid'], 'uuid' => $data['uuid'],

View File

@@ -2,7 +2,6 @@
namespace Database\Seeders\New; namespace Database\Seeders\New;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use JsonMachine\Items; use JsonMachine\Items;

View File

@@ -2,7 +2,6 @@
namespace Database\Seeders\New; namespace Database\Seeders\New;
use App\Models\Ecommerce\Product\Order\Payment\OrderPayment;
use App\Models\Ecommerce\Product\Order\Shipping\OrderShipping; use App\Models\Ecommerce\Product\Order\Shipping\OrderShipping;
use App\Models\Ecommerce\Product\Order\Status\OrderStatus; use App\Models\Ecommerce\Product\Order\Status\OrderStatus;
use Illuminate\Database\Seeder; use Illuminate\Database\Seeder;

View File

@@ -363,6 +363,7 @@
"Seller": "Satyjy", "Seller": "Satyjy",
"View products": "Harytlary gör", "View products": "Harytlary gör",
"Sections": "Bölümler", "Sections": "Bölümler",
"Section": "Bölüm",
"Product count": "Haryt sany", "Product count": "Haryt sany",
"Count": "Sany", "Count": "Sany",
"Shipping rates": "Eltip bermek nyrhnamasy", "Shipping rates": "Eltip bermek nyrhnamasy",

View File

@@ -6,6 +6,7 @@ use App\Http\Controllers\Api\V1\Brand\BrandController;
use App\Http\Controllers\Api\V1\Carousel\CarouselController; use App\Http\Controllers\Api\V1\Carousel\CarouselController;
use App\Http\Controllers\Api\V1\CartController; use App\Http\Controllers\Api\V1\CartController;
use App\Http\Controllers\Api\V1\Category\CategoryController; use App\Http\Controllers\Api\V1\Category\CategoryController;
use App\Http\Controllers\Api\V1\Category\SelectedCategoryController;
use App\Http\Controllers\Api\V1\Channel\ChannelController; use App\Http\Controllers\Api\V1\Channel\ChannelController;
use App\Http\Controllers\Api\V1\Collection\CollectionController; use App\Http\Controllers\Api\V1\Collection\CollectionController;
use App\Http\Controllers\Api\V1\ContactMessageController; use App\Http\Controllers\Api\V1\ContactMessageController;
@@ -64,6 +65,10 @@ Route::get('categories', [CategoryController::class, 'index']);
Route::get('categories/{category}', [CategoryController::class, 'show'])->where(['category' => '[0-9]+']); Route::get('categories/{category}', [CategoryController::class, 'show'])->where(['category' => '[0-9]+']);
Route::get('categories/{category}/products', [CategoryController::class, 'products'])->where(['category' => '[0-9]+']); Route::get('categories/{category}/products', [CategoryController::class, 'products'])->where(['category' => '[0-9]+']);
// Selected Categories...
Route::get('selected-categories', [SelectedCategoryController::class, 'index']);
Route::get('selected-categories/{selectedCategory}', [SelectedCategoryController::class, 'show'])->where(['selectedCategory' => '[0-9]+']);
// Collections... // Collections...
Route::get('collections', [CollectionController::class, 'index']); Route::get('collections', [CollectionController::class, 'index']);
Route::get('collections-paginated', [CollectionController::class, 'paginated']); Route::get('collections-paginated', [CollectionController::class, 'paginated']);