home banner

This commit is contained in:
Bayu Lukman Yusuf 2026-02-16 11:14:42 +07:00
parent 097c9f12ee
commit e23744e810
8 changed files with 327 additions and 90 deletions

21
app/Models/Banner.php Normal file
View File

@ -0,0 +1,21 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Storage;
class Banner extends Model
{
use HasFactory, SoftDeletes;
protected $fillable = ["filename","content_id","content_type","caption","is_active"];
public $appends = ['url'];
public function getUrlAttribute(){
return ($this->filename) ? Storage::disk("public")->url($this->filename): null;
}
}

View File

@ -0,0 +1,95 @@
<?php
namespace App\Repositories\Member;
use App\Models\Banner;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
use Carbon\Carbon;
use Storage;
use Image;
use Intervention\Image\ImageManager;
use Intervention\Image\Drivers\Imagick\Driver;
class BannerRepository
{
public function getList($params)
{
$limit = @$params["limit"] ? (int) @$params["limit"] : 10;
$sortColumn = @$params["sort"]["column"] ? $params["sort"]["column"] : "id";
$sortDir = @$params["sort"]["dir"] ? $params["sort"]["dir"] : "desc";
return Banner::when(@$params["is_active"], function($query){
$query->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;
}
}

View File

@ -2,14 +2,18 @@
namespace App\View\Components\Home; namespace App\View\Components\Home;
use App\Repositories\Member\BannerRepository;
use Closure;
use Illuminate\Contracts\View\View; use Illuminate\Contracts\View\View;
use Illuminate\View\Component; use Illuminate\View\Component;
use Illuminate\Support\Facades\Log;
class HomeSlider extends Component 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 public function render(): View|Closure|string
{ {
return view('components.home.home-slider'); return view('components.home.home-slider', [
'items' => $this->items
]);
} }
} }

View File

@ -12,6 +12,7 @@
"php": "^8.2", "php": "^8.2",
"awobaz/compoships": "^2.5", "awobaz/compoships": "^2.5",
"cviebrock/eloquent-sluggable": "^12.0", "cviebrock/eloquent-sluggable": "^12.0",
"intervention/image": "^3.11",
"laravel/framework": "^12.0", "laravel/framework": "^12.0",
"laravel/socialite": "^5.24", "laravel/socialite": "^5.24",
"laravel/tinker": "^2.10.1", "laravel/tinker": "^2.10.1",

152
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "d0b608eb451d87c58e31559913a4b6db", "content-hash": "132ddb45d6897d4128994f20e18e0e96",
"packages": [ "packages": [
{ {
"name": "awobaz/compoships", "name": "awobaz/compoships",
@ -1326,6 +1326,150 @@
], ],
"time": "2025-02-03T10:55:03+00:00" "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", "name": "laravel/framework",
"version": "v12.21.0", "version": "v12.21.0",
@ -8942,12 +9086,12 @@
], ],
"aliases": [], "aliases": [],
"minimum-stability": "stable", "minimum-stability": "stable",
"stability-flags": [], "stability-flags": {},
"prefer-stable": true, "prefer-stable": true,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": "^8.2" "php": "^8.2"
}, },
"platform-dev": [], "platform-dev": {},
"plugin-api-version": "2.6.0" "plugin-api-version": "2.9.0"
} }

View File

@ -91,7 +91,7 @@
name="birth_date" name="birth_date"
data-datepicker='{ data-datepicker='{
"dateFormat": "Y-m-d", "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" /> placeholder="{{ __('account_info.choose_date') }}" type="text" />
<i class="ci-calendar position-absolute top-50 end-0 translate-middle-y me-3"></i> <i class="ci-calendar position-absolute top-50 end-0 translate-middle-y me-3"></i>

View File

@ -22,20 +22,28 @@
"placeholder": true "placeholder": true
}, },
{ {
"value": "inprogress", "value": "wait_payment",
"label": "&lt;div class=\"d-flex align-items-center text-nowrap\"&gt;&lt;span class=\"bg-info rounded-circle p-1 me-2\"&gt;&lt;/span&gt;In progress&lt;/div&gt;" "label": "&lt;div class=\"d-flex align-items-center text-nowrap\"&gt;&lt;span class=\"bg-warning rounded-circle p-1 me-2\"&gt;&lt;/span&gt;{{ __('order.status.wait_payment') }}&lt;/div&gt;"
}, },
{ {
"value": "delivered", "value": "wait_process",
"label": "&lt;div class=\"d-flex align-items-center text-nowrap\"&gt;&lt;span class=\"bg-success rounded-circle p-1 me-2\"&gt;&lt;/span&gt;Delivered&lt;/div&gt;" "label": "&lt;div class=\"d-flex align-items-center text-nowrap\"&gt;&lt;span class=\"bg-info rounded-circle p-1 me-2\"&gt;&lt;/span&gt;{{ __('order.status.wait_process') }}&lt;/div&gt;"
}, },
{ {
"value": "canceled", "value": "on_process",
"label": "&lt;div class=\"d-flex align-items-center text-nowrap\"&gt;&lt;span class=\"bg-danger rounded-circle p-1 me-2\"&gt;&lt;/span&gt;Canceled&lt;/div&gt;" "label": "&lt;div class=\"d-flex align-items-center text-nowrap\"&gt;&lt;span class=\"bg-primary rounded-circle p-1 me-2\"&gt;&lt;/span&gt;{{ __('order.status.on_process') }}&lt;/div&gt;"
}, },
{ {
"value": "delayed", "value": "on_delivery",
"label": "&lt;div class=\"d-flex align-items-center text-nowrap\"&gt;&lt;span class=\"bg-warning rounded-circle p-1 me-2\"&gt;&lt;/span&gt;Delayed&lt;/div&gt;" "label": "&lt;div class=\"d-flex align-items-center text-nowrap\"&gt;&lt;span class=\"bg-success rounded-circle p-1 me-2\"&gt;&lt;/span&gt;{{ __('order.status.on_delivery') }}&lt;/div&gt;"
},
{
"value": "closed",
"label": "&lt;div class=\"d-flex align-items-center text-nowrap\"&gt;&lt;span class=\"bg-success rounded-circle p-1 me-2\"&gt;&lt;/span&gt;{{ __('order.status.closed') }}&lt;/div&gt;"
},
{
"value": "cancelled",
"label": "&lt;div class=\"d-flex align-items-center text-nowrap\"&gt;&lt;span class=\"bg-danger rounded-circle p-1 me-2\"&gt;&lt;/span&gt;Cancelled&lt;/div&gt;"
} }
] ]
}' }'
@ -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"> 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)
<span><img alt="Thumbnail" src="{{ $detail->reference->item->image_url ?? '' }}" <span><img alt="Thumbnail" src="{{ $detail->reference->item->image_url ?? '' }}"
width="50" /></span> width="50" /></span>
@endforeach @endforeach
@if ($order->details->count() > 3) {{-- @if ($order->details->count() > 1)
<span class="fw-medium me-1">+{{ $order->details->count() - 3 }}</span> <span class="fw-medium me-1">+{{ $order->details->count() - 1 }}</span>
@endif @endif --}}
<a aria-controls="orderDetails_{{ $order->id }}" aria-label="Show order details" <a aria-controls="orderDetails_{{ $order->id }}" aria-label="Show order details"
class="btn btn-icon btn-ghost btn-secondary stretched-link border-0" class="btn btn-icon btn-ghost btn-secondary stretched-link border-0"
data-bs-toggle="offcanvas" href="#orderDetails_{{ $order->id }}"> data-bs-toggle="offcanvas" href="#orderDetails_{{ $order->id }}">

View File

@ -1,84 +1,46 @@
<section class="bg-body-tertiary"> <section class="bg-body-tertiary">
<div class="container"> <div class="container" style="padding-top:24px;">
<div class="row"> <div class="row">
<!-- Titles master slider -->
<div class="col-md-6 col-lg-5 d-flex flex-column"> <!-- Linked images (controlled slider) -->
<div class="py-4 mt-auto"> <div class="col-12">
<div class="swiper pb-1 pt-3 pt-sm-4 py-md-4 py-lg-3" <div class="position-relative ms-md-n4">
<div class="ratio" style="--cz-aspect-ratio: calc(9 / 17 * 100%)"></div>
<div class="swiper position-absolute top-0 start-0 w-100 user-select-none"
id="heroImages"
data-swiper='{ data-swiper='{
"spaceBetween": 24, "spaceBetween": 24,
"loop": true, "loop": true,
"speed": 400, "speed": 400,
"controlSlider": "#heroImages", "controlSlider": "#heroImages",
"pagination": { "pagination": {
"el": "#sliderBullets", "el": "#sliderBullets",
"clickable": true "clickable": true
}, },
"autoplay": { "autoplay": {
"delay": 5500, "delay": 5500,
"disableOnInteraction": false "disableOnInteraction": false
} }
}'> }'>
<div class="swiper-wrapper align-items-center"> <div class="swiper-wrapper">
@foreach ($items as $item)
<!-- Item --> <div class="swiper-slide">
<div class="swiper-slide text-center text-md-start"> <img src="{{ env('WMS_ASSET_URL') . '/' .$item->filename }}" class="w-100"
<p class="fs-xl mb-2 mb-lg-3 mb-xl-4">{{ __('home_slider.new_collection') }}</p> alt="Image">
<h2 class="display-4 text-uppercase mb-4 mb-xl-5">{!! __('home_slider.new_fall_season') !!}</h2> </div>
<a class="btn btn-lg btn-outline-dark" href="{{ route('second', ['shop', 'catalog-fashion']) }}"> @endforeach
{{ __('home_slider.shop_now') }}
<i class="ci-arrow-up-right fs-lg ms-2 me-n1"></i>
</a>
</div>
<!-- Item -->
<div class="swiper-slide text-center text-md-start">
<p class="fs-xl mb-2 mb-lg-3 mb-xl-4">{{ __('home_slider.ready_for_party') }}</p>
<h2 class="display-4 text-uppercase mb-4 mb-xl-5">{{ __('home_slider.choose_outfits') }}</h2>
<a class="btn btn-lg btn-outline-dark" href="{{ route('second', ['shop', 'catalog-fashion']) }}">
{{ __('home_slider.shop_now') }}
<i class="ci-arrow-up-right fs-lg ms-2 me-n1"></i>
</a>
</div>
</div> </div>
</div> </div>
</div>
<!-- Slider bullets (pagination) --> <!-- Slider bullets (pagination) -->
<div <div
class="d-flex justify-content-center justify-content-md-start pb-4 pb-xl-5 mt-n1 mt-md-auto mb-md-3 mb-lg-4"> class="d-flex justify-content-center justify-content-md-start pb-4 pb-xl-5 mt-n1 mt-md-auto mb-md-3 mb-lg-4">
<div class="swiper-pagination position-static w-auto pb-1" id="sliderBullets"></div> <div class="swiper-pagination position-static w-auto pb-1" id="sliderBullets"></div>
</div> </div>
</div>
<!-- Linked images (controlled slider) -->
<div class="col-md-6 col-lg-7 align-self-end">
<div class="position-relative ms-md-n4">
<div class="ratio" style="--cz-aspect-ratio: calc(662 / 770 * 100%)"></div>
<div class="swiper position-absolute top-0 start-0 w-100 h-100 user-select-none"
id="heroImages"
data-swiper='{
"allowTouchMove": false,
"loop": true,
"effect": "fade",
"fadeEffect": {
"crossFade": true
}
}'>
<div class="swiper-wrapper">
<div class="swiper-slide">
<img src="{{ asset('img/home/banner.png') }}" class="rtl-flip"
alt="Image">
</div>
<div class="swiper-slide">
<img src="{{ asset('img/home/stick.png') }}" class="rtl-flip"
alt="Image">
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>