From e23744e81098956088d99e061327d847943a55c3 Mon Sep 17 00:00:00 2001 From: Bayu Lukman Yusuf Date: Mon, 16 Feb 2026 11:14:42 +0700 Subject: [PATCH] home banner --- app/Models/Banner.php | 21 +++ app/Repositories/Member/BannerRepository.php | 95 +++++++++++ app/View/Components/Home/HomeSlider.php | 12 +- composer.json | 1 + composer.lock | 152 +++++++++++++++++- resources/views/account/info.blade.php | 2 +- resources/views/account/orders.blade.php | 32 ++-- .../components/home/home-slider.blade.php | 102 ++++-------- 8 files changed, 327 insertions(+), 90 deletions(-) create mode 100644 app/Models/Banner.php create mode 100644 app/Repositories/Member/BannerRepository.php diff --git a/app/Models/Banner.php b/app/Models/Banner.php new file mode 100644 index 0000000..6fe5fc4 --- /dev/null +++ b/app/Models/Banner.php @@ -0,0 +1,21 @@ +filename) ? Storage::disk("public")->url($this->filename): null; + } +} diff --git a/app/Repositories/Member/BannerRepository.php b/app/Repositories/Member/BannerRepository.php new file mode 100644 index 0000000..21afedf --- /dev/null +++ b/app/Repositories/Member/BannerRepository.php @@ -0,0 +1,95 @@ +where("is_active", true); + }) + ->when(@$params['search'], function($query) use ($params) { + $query->where('caption', 'ilike', '%' . $params['search'] . '%'); + }) + ->orderBy($sortColumn, $sortDir) + ->paginate($limit); + } + + public function create(array $data) + { + if(@$data['image']) { + $path = $this->storeFile($data['image'], 'banner'); + $data['filename'] = $path; + } + + $item = Banner::create($data); + return $item; + } + + public function update(Banner $item, array $data) + { + if(@$data['image']) { + Storage::disk('public')->delete($item->filename); + $path = $this->storeFile($data['image'], 'banner'); + $data['filename'] = $path; + } + $item->update($data); + return $item; + } + + public function delete(Banner $item) + { + Storage::disk('public')->delete($item->filename); + $item->delete(); + } + + public function find($column, $value) + { + $item = Banner::where($column, $value)->firstOrFail(); + return $item; + } + + public function storeFile($file, $dir) + { + $extension = $file->extension(); + $filename = ''; + + while ($filename == '') { + $random = bin2hex(openssl_random_pseudo_bytes(16)) . '.' . $extension; + $exists = Storage::disk('public')->exists($dir . '/' . $random); + if (!$exists) { + $filename = $random; + } + } + $file->storeAs($dir, $filename, "public"); + + if (in_array($extension, ['jpg', 'jpeg', 'png'])) { + $path = Storage::disk('public')->path($dir . '/' . $filename); + + $manager = new ImageManager(new Driver()); + $img = $manager->read($path); + $img->scale(width: 900); + $img->save($path); + } + + return $dir . '/' . $filename; + } +} diff --git a/app/View/Components/Home/HomeSlider.php b/app/View/Components/Home/HomeSlider.php index 21f5e0d..e146bf7 100644 --- a/app/View/Components/Home/HomeSlider.php +++ b/app/View/Components/Home/HomeSlider.php @@ -2,14 +2,18 @@ namespace App\View\Components\Home; +use App\Repositories\Member\BannerRepository; +use Closure; use Illuminate\Contracts\View\View; use Illuminate\View\Component; +use Illuminate\Support\Facades\Log; class HomeSlider extends Component { - public function __construct() + public $items; + public function __construct(BannerRepository $repository) { - // + $this->items = $repository->getList([]); } /** @@ -17,6 +21,8 @@ class HomeSlider extends Component */ public function render(): View|Closure|string { - return view('components.home.home-slider'); + return view('components.home.home-slider', [ + 'items' => $this->items + ]); } } diff --git a/composer.json b/composer.json index 0c7d8ec..1744cbd 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,7 @@ "php": "^8.2", "awobaz/compoships": "^2.5", "cviebrock/eloquent-sluggable": "^12.0", + "intervention/image": "^3.11", "laravel/framework": "^12.0", "laravel/socialite": "^5.24", "laravel/tinker": "^2.10.1", diff --git a/composer.lock b/composer.lock index 9078481..fc2eea2 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d0b608eb451d87c58e31559913a4b6db", + "content-hash": "132ddb45d6897d4128994f20e18e0e96", "packages": [ { "name": "awobaz/compoships", @@ -1326,6 +1326,150 @@ ], "time": "2025-02-03T10:55:03+00:00" }, + { + "name": "intervention/gif", + "version": "4.2.4", + "source": { + "type": "git", + "url": "https://github.com/Intervention/gif.git", + "reference": "c3598a16ebe7690cd55640c44144a9df383ea73c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Intervention/gif/zipball/c3598a16ebe7690cd55640c44144a9df383ea73c", + "reference": "c3598a16ebe7690cd55640c44144a9df383ea73c", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "slevomat/coding-standard": "~8.0", + "squizlabs/php_codesniffer": "^3.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "Intervention\\Gif\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oliver Vogel", + "email": "oliver@intervention.io", + "homepage": "https://intervention.io/" + } + ], + "description": "Native PHP GIF Encoder/Decoder", + "homepage": "https://github.com/intervention/gif", + "keywords": [ + "animation", + "gd", + "gif", + "image" + ], + "support": { + "issues": "https://github.com/Intervention/gif/issues", + "source": "https://github.com/Intervention/gif/tree/4.2.4" + }, + "funding": [ + { + "url": "https://paypal.me/interventionio", + "type": "custom" + }, + { + "url": "https://github.com/Intervention", + "type": "github" + }, + { + "url": "https://ko-fi.com/interventionphp", + "type": "ko_fi" + } + ], + "time": "2026-01-04T09:27:23+00:00" + }, + { + "name": "intervention/image", + "version": "3.11.6", + "source": { + "type": "git", + "url": "https://github.com/Intervention/image.git", + "reference": "5f6d27d9fd56312c47f347929e7ac15345c605a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Intervention/image/zipball/5f6d27d9fd56312c47f347929e7ac15345c605a1", + "reference": "5f6d27d9fd56312c47f347929e7ac15345c605a1", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "intervention/gif": "^4.2", + "php": "^8.1" + }, + "require-dev": { + "mockery/mockery": "^1.6", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^10.0 || ^11.0 || ^12.0", + "slevomat/coding-standard": "~8.0", + "squizlabs/php_codesniffer": "^3.8" + }, + "suggest": { + "ext-exif": "Recommended to be able to read EXIF data properly." + }, + "type": "library", + "autoload": { + "psr-4": { + "Intervention\\Image\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Oliver Vogel", + "email": "oliver@intervention.io", + "homepage": "https://intervention.io" + } + ], + "description": "PHP Image Processing", + "homepage": "https://image.intervention.io", + "keywords": [ + "gd", + "image", + "imagick", + "resize", + "thumbnail", + "watermark" + ], + "support": { + "issues": "https://github.com/Intervention/image/issues", + "source": "https://github.com/Intervention/image/tree/3.11.6" + }, + "funding": [ + { + "url": "https://paypal.me/interventionio", + "type": "custom" + }, + { + "url": "https://github.com/Intervention", + "type": "github" + }, + { + "url": "https://ko-fi.com/interventionphp", + "type": "ko_fi" + } + ], + "time": "2025-12-17T13:38:29+00:00" + }, { "name": "laravel/framework", "version": "v12.21.0", @@ -8942,12 +9086,12 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { "php": "^8.2" }, - "platform-dev": [], - "plugin-api-version": "2.6.0" + "platform-dev": {}, + "plugin-api-version": "2.9.0" } diff --git a/resources/views/account/info.blade.php b/resources/views/account/info.blade.php index ee79701..3466b1b 100644 --- a/resources/views/account/info.blade.php +++ b/resources/views/account/info.blade.php @@ -91,7 +91,7 @@ name="birth_date" data-datepicker='{ "dateFormat": "Y-m-d", - "defaultDate": "{{ auth()->user()->customer->date_of_birth != null ? date('Y-m-d', strtotime(auth()->user()->customer->date_of_birth)) : '' }}" + "defaultDate": "{{ auth()->user()->customer?->date_of_birth != null ? date('Y-m-d', strtotime(auth()->user()->customer->date_of_birth)) : '' }}" }' placeholder="{{ __('account_info.choose_date') }}" type="text" /> diff --git a/resources/views/account/orders.blade.php b/resources/views/account/orders.blade.php index a441a01..0f72383 100644 --- a/resources/views/account/orders.blade.php +++ b/resources/views/account/orders.blade.php @@ -22,20 +22,28 @@ "placeholder": true }, { - "value": "inprogress", - "label": "<div class=\"d-flex align-items-center text-nowrap\"><span class=\"bg-info rounded-circle p-1 me-2\"></span>In progress</div>" + "value": "wait_payment", + "label": "<div class=\"d-flex align-items-center text-nowrap\"><span class=\"bg-warning rounded-circle p-1 me-2\"></span>{{ __('order.status.wait_payment') }}</div>" }, { - "value": "delivered", - "label": "<div class=\"d-flex align-items-center text-nowrap\"><span class=\"bg-success rounded-circle p-1 me-2\"></span>Delivered</div>" + "value": "wait_process", + "label": "<div class=\"d-flex align-items-center text-nowrap\"><span class=\"bg-info rounded-circle p-1 me-2\"></span>{{ __('order.status.wait_process') }}</div>" }, { - "value": "canceled", - "label": "<div class=\"d-flex align-items-center text-nowrap\"><span class=\"bg-danger rounded-circle p-1 me-2\"></span>Canceled</div>" + "value": "on_process", + "label": "<div class=\"d-flex align-items-center text-nowrap\"><span class=\"bg-primary rounded-circle p-1 me-2\"></span>{{ __('order.status.on_process') }}</div>" }, { - "value": "delayed", - "label": "<div class=\"d-flex align-items-center text-nowrap\"><span class=\"bg-warning rounded-circle p-1 me-2\"></span>Delayed</div>" + "value": "on_delivery", + "label": "<div class=\"d-flex align-items-center text-nowrap\"><span class=\"bg-success rounded-circle p-1 me-2\"></span>{{ __('order.status.on_delivery') }}</div>" + }, + { + "value": "closed", + "label": "<div class=\"d-flex align-items-center text-nowrap\"><span class=\"bg-success rounded-circle p-1 me-2\"></span>{{ __('order.status.closed') }}</div>" + }, + { + "value": "cancelled", + "label": "<div class=\"d-flex align-items-center text-nowrap\"><span class=\"bg-danger rounded-circle p-1 me-2\"></span>Cancelled</div>" } ] }' @@ -113,13 +121,13 @@ class="d-flex align-items-center justify-content-end position-relative gap-1 gap-sm-2 ms-n2 ms-sm-0"> - @foreach ($order->details->take(3) as $detail) + @foreach ($order->details->take(1) as $detail) Thumbnail @endforeach - @if ($order->details->count() > 3) - +{{ $order->details->count() - 3 }} - @endif + {{-- @if ($order->details->count() > 1) + +{{ $order->details->count() - 1 }} + @endif --}} diff --git a/resources/views/components/home/home-slider.blade.php b/resources/views/components/home/home-slider.blade.php index 934573d..925ff70 100644 --- a/resources/views/components/home/home-slider.blade.php +++ b/resources/views/components/home/home-slider.blade.php @@ -1,84 +1,46 @@
-
+
- -
-
-
+
+
+
+
-
- - -
-

{{ __('home_slider.new_collection') }}

-

{!! __('home_slider.new_fall_season') !!}

- - {{ __('home_slider.shop_now') }} - - -
- - -
- + "spaceBetween": 24, + "loop": true, + "speed": 400, + "controlSlider": "#heroImages", + "pagination": { + "el": "#sliderBullets", + "clickable": true + }, + "autoplay": { + "delay": 5500, + "disableOnInteraction": false + } + }'> +
+ @foreach ($items as $item) +
+ Image +
+ @endforeach + + +
-
- +
-
- - -
-
-
-
-
-
- Image -
-
- Image -
- -
-