From f794d1f08319c9353f82d0f6c25ac289b42e91e2 Mon Sep 17 00:00:00 2001 From: cyberali Date: Sat, 20 Jul 2024 17:59:03 +0330 Subject: [PATCH] feat: Implement home page API endpoint - Add HomeController with index method to provide home page data - Fetch and include menu with items, limiting selected fields for optimization - Fetch and include latest 6 sliders using SliderResource - Fetch and include top 8 parent categories with their products using CategoryResource - Fetch and include active advertisements with available clicks using AdvResource - Fetch and include latest 8 posts using PostResource - Return all collected data as a successful JSON response --- .../Controllers/Api/Web/HomeController.php | 38 ++++++++++++++++++ app/Http/Resources/AdvResource.php | 28 +++++++++++++ app/Http/Resources/CategoryResource.php | 39 +++++++++++++++++++ app/Http/Resources/PostResource.php | 38 ++++++++++++++++++ app/Http/Resources/ProductResource.php | 39 +++++++++++++++++++ app/Http/Resources/SliderResource.php | 32 +++++++++++++++ app/Models/Category.php | 2 +- routes/api.php | 16 ++++---- 8 files changed, 224 insertions(+), 8 deletions(-) create mode 100644 app/Http/Controllers/Api/Web/HomeController.php create mode 100644 app/Http/Resources/AdvResource.php create mode 100644 app/Http/Resources/CategoryResource.php create mode 100644 app/Http/Resources/PostResource.php create mode 100644 app/Http/Resources/ProductResource.php create mode 100644 app/Http/Resources/SliderResource.php diff --git a/app/Http/Controllers/Api/Web/HomeController.php b/app/Http/Controllers/Api/Web/HomeController.php new file mode 100644 index 0000000..1bfdada --- /dev/null +++ b/app/Http/Controllers/Api/Web/HomeController.php @@ -0,0 +1,38 @@ + function ($query) { + $query->select(['id', 'title', 'menuable_id', 'menuable_type', 'kind', 'meta', 'parent', 'sort', 'user_id', 'menu_id']); + }])->first(['id', 'name']); + $data['slider'] = SliderResource::collection(Slider::take(6)->get()); + $data['categories'] = CategoryResource::collection(Category::with('products')->whereNull('parent_id')->orderBy('sort')->take(8)->get()); + $data['adv'] = AdvResource::collection( + Adv::query() + ->where('status', true) + ->whereColumn('click', '<', 'max_click') + ->get() + ); + $data['post'] = PostResource::collection(Post::orderByDesc('created_at')->take(8)->get()); + return success($data); + } +} diff --git a/app/Http/Resources/AdvResource.php b/app/Http/Resources/AdvResource.php new file mode 100644 index 0000000..5cb703a --- /dev/null +++ b/app/Http/Resources/AdvResource.php @@ -0,0 +1,28 @@ + + */ + public function toArray(Request $request): array + { + /** + * @var $this Adv + */ + return [ + 'id' => $this->id, + 'image' => $this->imgUrl, + 'title' => $this->title, + 'link' => $this->link, + ]; + } +} diff --git a/app/Http/Resources/CategoryResource.php b/app/Http/Resources/CategoryResource.php new file mode 100644 index 0000000..5129d19 --- /dev/null +++ b/app/Http/Resources/CategoryResource.php @@ -0,0 +1,39 @@ + + */ + public function toArray(Request $request, $data = null): array + { + /** + * @var $this Category + */ + $request->merge([ + 'loadCategory' => false + ]); + return [ + 'id' => $this->id, + 'name' => $this->name, + 'slug' => $this->slug, + 'subtitle' => $this->subtitle, + 'description' => $this->description, + 'sort' => $this->sort, + 'image' => $this->image, + 'bg' => $this->bg, + 'products' => $this->when($request->input('loadProduct' , true) , ProductResource::collection($this->products)->additional(['request' => $request['loadCategory']]) ) + ]; + } +} diff --git a/app/Http/Resources/PostResource.php b/app/Http/Resources/PostResource.php new file mode 100644 index 0000000..74a5795 --- /dev/null +++ b/app/Http/Resources/PostResource.php @@ -0,0 +1,38 @@ + + */ + public function toArray(Request $request): array + { + /** + * @var $this Post + */ + return [ + 'id' => $this->id, + 'slug' => $this->slug, + 'subtitle' => $this->subtitle, + 'body' => $this->body, + 'group' => $this->load('groups'), + 'author' => $this->load('author'), + 'view' => $this->view, + 'is_pinned' => $this->is_pinned, + 'hash' => $this->hash, + 'like' => $this->like, + 'dislike' => $this->dislike, + 'icon' => $this->icon, + 'created_at' => $this->created_at, + + ]; + } +} diff --git a/app/Http/Resources/ProductResource.php b/app/Http/Resources/ProductResource.php new file mode 100644 index 0000000..85b50b7 --- /dev/null +++ b/app/Http/Resources/ProductResource.php @@ -0,0 +1,39 @@ + + */ + public function toArray(Request $request): array + { + /** + * @var $this Product + */ + $request->merge([ + 'loadProduct' => false + ]); + return [ + 'id' => $this->id, + 'slug' => $this->slug, + 'description' => $this->description, + 'table' => $this->table, + 'sku' => $this->sku, + 'virtual' => $this->virtual, + 'downloadable' => $this->downloadable, + 'price' => $this->price, + 'buy_price' => $this->buy_price, + 'average_rating' => $this->average_rating, + 'view' => $this->view, + 'category' => $this->when($request->input('loadCategory', true), new CategoryResource($this->category)) + ]; + } +} diff --git a/app/Http/Resources/SliderResource.php b/app/Http/Resources/SliderResource.php new file mode 100644 index 0000000..cebf359 --- /dev/null +++ b/app/Http/Resources/SliderResource.php @@ -0,0 +1,32 @@ + + */ + public function toArray(Request $request): array + { + /** + * @var $this Slider + */ + return [ + 'id' => $this->id, + 'body' => $this->body, + 'image' => $this->imgUrl(), + 'tag' => $this->tag, + 'user_id' => $this->user_id, + 'status' => $this->status, + 'data' => $this->data, + 'user' => $this->load('author') + ]; + } +} diff --git a/app/Models/Category.php b/app/Models/Category.php index c8cdebc..7493554 100644 --- a/app/Models/Category.php +++ b/app/Models/Category.php @@ -83,7 +83,7 @@ class Category extends Model public function products() { - return $this->belongsToMany(Product::class); + return $this->hasMany(Product::class); } diff --git a/routes/api.php b/routes/api.php index cdaa0f3..c99478e 100644 --- a/routes/api.php +++ b/routes/api.php @@ -9,12 +9,12 @@ Route::get('/user', function (Request $request) { Route::get('', function () { - return 'xshop api:'.config('app.name'); + return 'xshop api:' . config('app.name'); }); Route::get('/clear', function () { - if (!auth()->check()){ + if (!auth()->check()) { return abort(403); } Artisan::call('cache:clear'); @@ -33,9 +33,11 @@ Route::prefix('v1')->name('v1.')->group( return 'xShop api v1'; }); - Route::get('states', [\App\Http\Controllers\Api\StateController::class,'index'])->name('state.index'); - Route::get('state/{state}', [\App\Http\Controllers\Api\StateController::class,'show'])->name('state.show'); - Route::get('category/props/{category}', [\App\Http\Controllers\Api\CategoryController::class,'props'])->name('category.prop'); - Route::post('morph/search', [\App\Http\Controllers\Api\MorphController::class,'search'])->name('morph.search'); - Route::post('visitor/display', [\App\Http\Controllers\Api\VisitorController::class,'display'])->name('visitor.display'); + Route::get('states', [\App\Http\Controllers\Api\StateController::class, 'index'])->name('state.index'); + Route::get('state/{state}', [\App\Http\Controllers\Api\StateController::class, 'show'])->name('state.show'); + Route::get('category/props/{category}', [\App\Http\Controllers\Api\CategoryController::class, 'props'])->name('category.prop'); + Route::post('morph/search', [\App\Http\Controllers\Api\MorphController::class, 'search'])->name('morph.search'); + Route::post('visitor/display', [\App\Http\Controllers\Api\VisitorController::class, 'display'])->name('visitor.display'); + + Route::apiResource('web', \App\Http\Controllers\Api\Web\HomeController::class)->only('index'); });