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;
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
]);
}
}

View File

@ -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",

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",
"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"
}

View File

@ -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" />
<i class="ci-calendar position-absolute top-50 end-0 translate-middle-y me-3"></i>

View File

@ -22,20 +22,28 @@
"placeholder": true
},
{
"value": "inprogress",
"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;"
"value": "wait_payment",
"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",
"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;"
"value": "wait_process",
"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",
"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;"
"value": "on_process",
"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",
"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;"
"value": "on_delivery",
"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">
@foreach ($order->details->take(3) as $detail)
@foreach ($order->details->take(1) as $detail)
<span><img alt="Thumbnail" src="{{ $detail->reference->item->image_url ?? '' }}"
width="50" /></span>
@endforeach
@if ($order->details->count() > 3)
<span class="fw-medium me-1">+{{ $order->details->count() - 3 }}</span>
@endif
{{-- @if ($order->details->count() > 1)
<span class="fw-medium me-1">+{{ $order->details->count() - 1 }}</span>
@endif --}}
<a aria-controls="orderDetails_{{ $order->id }}" aria-label="Show order details"
class="btn btn-icon btn-ghost btn-secondary stretched-link border-0"
data-bs-toggle="offcanvas" href="#orderDetails_{{ $order->id }}">

View File

@ -1,84 +1,46 @@
<section class="bg-body-tertiary">
<div class="container">
<div class="container" style="padding-top:24px;">
<div class="row">
<!-- Titles master slider -->
<div class="col-md-6 col-lg-5 d-flex flex-column">
<div class="py-4 mt-auto">
<div class="swiper pb-1 pt-3 pt-sm-4 py-md-4 py-lg-3"
<!-- Linked images (controlled slider) -->
<div class="col-12">
<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='{
"spaceBetween": 24,
"loop": true,
"speed": 400,
"controlSlider": "#heroImages",
"pagination": {
"el": "#sliderBullets",
"clickable": true
},
"autoplay": {
"delay": 5500,
"disableOnInteraction": false
}
}'>
<div class="swiper-wrapper align-items-center">
<!-- Item -->
<div class="swiper-slide text-center text-md-start">
<p class="fs-xl mb-2 mb-lg-3 mb-xl-4">{{ __('home_slider.new_collection') }}</p>
<h2 class="display-4 text-uppercase mb-4 mb-xl-5">{!! __('home_slider.new_fall_season') !!}</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>
<!-- 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>
"spaceBetween": 24,
"loop": true,
"speed": 400,
"controlSlider": "#heroImages",
"pagination": {
"el": "#sliderBullets",
"clickable": true
},
"autoplay": {
"delay": 5500,
"disableOnInteraction": false
}
}'>
<div class="swiper-wrapper">
@foreach ($items as $item)
<div class="swiper-slide">
<img src="{{ env('WMS_ASSET_URL') . '/' .$item->filename }}" class="w-100"
alt="Image">
</div>
@endforeach
</div>
</div>
</div>
<!-- Slider bullets (pagination) -->
<!-- Slider bullets (pagination) -->
<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">
<div class="swiper-pagination position-static w-auto pb-1" id="sliderBullets"></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>