added adv xcontroller

added disable date picker
pull/44/head
A1Gard 3 months ago
parent 342f1f91c4
commit a20dc80748

@ -0,0 +1,132 @@
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Controllers\XController;
use App\Http\Requests\AdvSaveRequest;
use App\Models\Access;
use App\Models\Adv;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Helper;
use function App\Helpers\hasCreateRoute;
class AdvController extends XController
{
// protected $_MODEL_ = Adv::class;
// protected $SAVE_REQUEST = AdvSaveRequest::class;
protected $cols = ['title','link'];
protected $extra_cols = ['id','image'];
protected $searchable = ['title','link'];
protected $listView = 'admin.advs.adv-list';
protected $formView = 'admin.advs.adv-form';
protected $buttons = [
'edit' =>
['title' => "Edit", 'class' => 'btn-outline-primary', 'icon' => 'ri-edit-2-line'],
'show' =>
['title' => "Detail", 'class' => 'btn-outline-light', 'icon' => 'ri-eye-line'],
'destroy' =>
['title' => "Remove", 'class' => 'btn-outline-danger delete-confirm', 'icon' => 'ri-close-line'],
];
public function __construct()
{
parent::__construct(Adv::class, AdvSaveRequest::class);
}
/**
* @param $adv Adv
* @param $request AdvSaveRequest
* @return Adv
*/
public function save($adv, $request)
{
$adv->title = $request->input('title');
$adv->max_click = $request->input('max_click');
$adv->link = $request->input('link');
$adv->expire = date('Y-m-d',$request->input('expire'));
$adv->user_id = auth()->id();
$adv->status = $request->input('status');
if ($request->has('image')){
$adv->image = $this->storeFile('image',$adv, 'ad');
}
$adv->save();
return $adv;
}
/**
* Show the form for creating a new resource.
*/
public function create()
{
//
return view($this->formView);
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Adv $item)
{
//
return view($this->formView, compact('item'));
}
public function bulk(Request $request)
{
// dd($request->all());
$data = explode('.', $request->input('action'));
$action = $data[0];
$ids = $request->input('id');
switch ($action) {
case 'delete':
$msg = __(':COUNT items deleted successfully', ['COUNT' => count($ids)]);
$this->_MODEL_::destroy($ids);
break;
/**restore*/
case 'restore':
$msg = __(':COUNT items restored successfully', ['COUNT' => count($ids)]);
foreach ($ids as $id) {
$this->_MODEL_::withTrashed()->find($id)->restore();
}
break;
/*restore**/
default:
$msg = __('Unknown bulk action : :ACTION', ["ACTION" => $action]);
}
return $this->do_bulk($msg, $action, $ids);
}
public function destroy(Adv $item)
{
return parent::delete($item);
}
public function update(Request $request, Adv $item)
{
return $this->bringUp($request, $item);
}
/**restore*/
public function restore($item)
{
return parent::restoreing(Adv::withTrashed()->where('id', $item)->first());
}
/*restore**/
}

@ -0,0 +1,33 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class AdvSaveRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return auth()->check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
//
'title' => ['required', 'string', 'max:255','min:5'],
'link' => ['required', 'string', 'max:255','min:5'],
'status' => ['required', 'boolean'],
'image' => ['nullable', 'image', 'mimes:jpeg,png,jpg,gif,svg', 'max:2048'],
'max_click' => ['required','numeric'],
];
}
}

@ -12,9 +12,9 @@ class Adv extends Model
public function imgUrl()
{
if ($this->image == null) {
return null;
return asset('assets/upload/logo.svg');
}
return \Storage::url('advs/' . $this->image);
return \Storage::url('ad/' . $this->image);
}
}

@ -14,11 +14,11 @@ return new class extends Migration
Schema::create('advs', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->timestamp('expire');
$table->date('expire');
$table->string('image');
$table->unsignedInteger('max_click')->default(0);
$table->unsignedInteger('click')->default(0);
$table->boolean('active')->default(true);
$table->boolean('status')->default(0);
$table->string('link');
$table->unsignedBigInteger('user_id');
$table->softDeletes();

@ -346,6 +346,14 @@ export default {
default: false,
type: Boolean,
},
xmax: {
default: null,
type: Number,
},
xmin: {
default: null,
type: Number,
},
},
mounted() {
this.pDate = new persianDate();
@ -364,7 +372,7 @@ export default {
this.current = new Date(parseInt(this.modelValue));
this.val = this.modelValue;
}
}else{
} else {
if (this.xvalue == null || this.xvalue == '' || this.xvalue == 'null') {
dt = new Date();
this.val = null;
@ -375,7 +383,8 @@ export default {
}
}
// tab fix
this.tabIndex = parseInt(this.defTab);
} else {
@ -388,8 +397,8 @@ export default {
// }
},
computed: {
vals(){
return JSON.stringify([this.startDate,this.endDate]);
vals() {
return JSON.stringify([this.startDate, this.endDate]);
},
// get input class
getClass: function () {
@ -513,10 +522,10 @@ export default {
},
},
methods: {
onMouseEnter(obj){
onMouseEnter(obj) {
this.hoverDate = obj.unix;
},
onMouseLeave(){
onMouseLeave() {
this.hoverDate = null;
},
// clear input
@ -532,6 +541,12 @@ export default {
},
// handle select
select(obj) {
if (this.xmax != null && obj.unix > this.xmax) {
return;
}
if (this.xmin != null && obj.unix < this.xmin) {
return;
}
if (this.isSwiping) {
return false;
}
@ -694,19 +709,26 @@ export default {
},
// is selected this td
isActive(obj) {
let r = '';
if (obj.unix == this.startDate) {
return 'active-selected';
r = 'active-selected';
}
if (this.endDate != null){
if (obj.unix > this.startDate && obj.unix <= this.endDate){
return 'active-selected';
if (this.endDate != null) {
if (obj.unix > this.startDate && obj.unix <= this.endDate) {
r = 'active-selected';
}
}else if (this.startDate != null && this.hoverDate != null){
if (obj.unix > this.startDate && obj.unix <= this.hoverDate){
return 'active-selected';
} else if (this.startDate != null && this.hoverDate != null) {
if (obj.unix > this.startDate && obj.unix <= this.hoverDate) {
r = 'active-selected';
}
}
return '';
if (this.xmax != null && obj.unix > this.xmax) {
r += ' disabled-date';
}
if (this.xmin != null && obj.unix < this.xmin) {
r += ' disabled-date';
}
return r;
},
// select hour
pickHour(i, ignore = false) {
@ -882,16 +904,16 @@ export default {
}
},
convertToHuman(unix){
if (unix == null || unix == ''){
return '';
}
let dt = new Date(unix * 1000);
if (this.tabIndex == 0){
return this.pDate.parseHindi( this.pDate.convertDate2Persian(dt).join('/'));
}else{
return dt.getFullYear() + '-' + dt.getMonth() + '-' + dt.getDate();
}
convertToHuman(unix) {
if (unix == null || unix == '') {
return '';
}
let dt = new Date(unix * 1000);
if (this.tabIndex == 0) {
return this.pDate.parseHindi(this.pDate.convertDate2Persian(dt).join('/'));
} else {
return dt.getFullYear() + '-' + dt.getMonth() + '-' + dt.getDate();
}
},
// hide modal
hideModal() {

@ -143,16 +143,16 @@
>
AM
</div>
<div :class="`vuejs-btn ${mode == 'PM'?'active-selected':''}`"
@click="changeMode('PM')"
@touchend="changeMode('PM')"
<div :class="`vuejs-btn ${mode == 'PM'?'active-selected':''}`"
@click="changeMode('PM')"
@touchend="changeMode('PM')"
>
PM
</div>
</div>
<div id="time">
{{pDate.make2number(cTime[0])}} :
{{pDate.make2number(cTime[1])}}
{{ pDate.make2number(cTime[0]) }} :
{{ pDate.make2number(cTime[1]) }}
</div>
<div id="clock-container">
<div class="wrapper">
@ -282,6 +282,14 @@ export default {
default: null,
type: Number,
},
xmax: {
default: null,
type: Number,
},
xmin: {
default: null,
type: Number,
},
xshow: {
default: 'pdate', // show value
type: String,
@ -339,7 +347,7 @@ export default {
},
mounted() {
this.pDate = new persianDate();
let dt ;
let dt;
// check value changed by user or not, then ignore xvalue
if (this.val == null) {
@ -354,7 +362,7 @@ export default {
this.current = new Date(parseInt(this.modelValue));
this.val = this.modelValue;
}
}else{
} else {
dt = new Date(parseInt(this.xvalue) * 1000);
if (this.xvalue == null || this.xvalue == '' || this.xvalue == 'null') {
dt = new Date();
@ -365,6 +373,8 @@ export default {
this.val = this.xvalue;
}
}
// tab fix
this.tabIndex = parseInt(this.defTab);
} else {
@ -377,7 +387,7 @@ export default {
// }
},
computed: {
selectedDateTime(){
selectedDateTime() {
// fullData[xshow]
const dt = new Date(this.val * 1000);
return this.makeDateObject(dt)[this.xshow];
@ -517,6 +527,13 @@ export default {
},
// handle select
select(obj) {
if (this.xmax != null && obj.unix > this.xmax) {
return;
}
if (this.xmin != null && obj.unix < this.xmin) {
return;
}
if (this.isSwiping) {
return false;
}
@ -533,7 +550,7 @@ export default {
this.val = obj.unix;
this.fullData = obj;
this.current = this.val = obj.unix;
if (this.closeOnSelect){
if (this.closeOnSelect) {
this.canCloseModal = true;
this.hideModal();
}
@ -619,7 +636,7 @@ export default {
this.current = Math.floor(dt / 1000);
},
makeDateObject(dt, cls) {
dt.setHours(this.cTime[0],this.cTime[1]);
dt.setHours(this.cTime[0], this.cTime[1]);
return {
day: this.pDate.make2number(dt.getDate()), // day
pDay: this.pDate.convertDate2Persian(dt)[2], // persian date
@ -669,18 +686,25 @@ export default {
// is selected this td
isActive(obj) {
let dt = new Date(this.val * 1000);
let r = '';
if (dt.getFullYear() + '-' + dt.getMonth() + '-' + dt.getDate() == obj.date) {
return 'active-selected';
r = 'active-selected';
}
if (this.xmax != null && obj.unix > this.xmax) {
r += ' disabled-date';
}
return '';
if (this.xmin != null && obj.unix < this.xmin) {
r += ' disabled-date';
}
return r;
},
// select hour
pickHour(i, ignore = false) {
let dt = new Date(this.val * 1000);
if (ignore){
if (ignore) {
dt.setHours(i);
}else{
dt.setHours((this.mode == 'AM'? i : (i + 12) ));
} else {
dt.setHours((this.mode == 'AM' ? i : (i + 12)));
}
dt.setMinutes(this.cTime[1]);
this.val = Math.floor(dt.getTime() / 1000);
@ -804,7 +828,7 @@ export default {
triggerSwipe(direction) {
// Update content padding based on swipe direction
let y = parseInt(this.peDate[0]);
if (this.tabIndex == 1){
if (this.tabIndex == 1) {
y = parseInt(this.geDate[1]);
}
switch (direction) {
@ -826,29 +850,29 @@ export default {
// change mode am/pm
changeMode(mode){
changeMode(mode) {
// ignore AM while AM
if (this.mode == 'AM' && mode == 'AM'){
return ;
if (this.mode == 'AM' && mode == 'AM') {
return;
}
// ignore PM while PM
if (this.mode == 'PM' && mode == 'PM'){
return ;
if (this.mode == 'PM' && mode == 'PM') {
return;
}
if (mode == 'AM'){
if (mode == 'AM') {
if (this.cTime[0] == 12){
if (this.cTime[0] == 12) {
this.pickHour(12);
}else{
} else {
this.pickHour(this.cTime[0] - 12, true);
}
}else{
} else {
this.pickHour(this.cTime[0] + 12, true);
}
},
selfUpdate(){
selfUpdate() {
let dt;
// check value changed by user or not, then ignore xvalue
if (this.val == null) {
@ -1169,21 +1193,27 @@ export default {
border-radius: 2px;
}
#modes{
#modes {
position: absolute;
left: 5px;
top: 5px;
}
#modes .vuejs-btn{
#modes .vuejs-btn {
padding: 5px;
width: 40px;
text-align: center;
padding-top: 10px;
}
#time{
#time {
position: absolute;
right: 5px;
top: 5px;
font-size: 25px;
}
.disabled-date {
background: silver;
}
</style>

@ -0,0 +1,120 @@
@extends('admin.templates.panel-form-template')
@section('title')
@if(isset($item))
{{__("Edit adv")}} [{{$item->title}}]
@else
{{__("Add new adv")}}
@endif -
@endsection
@section('form')
<div class="row">
<div class="col-lg-3">
@include('components.err')
<div class="item-list mb-3">
<h3 class="p-3">
<i class="ri-message-3-line"></i>
{{__("Tips")}}
</h3>
<ul>
<li>
{{__("Max click zero is unlimited")}}
</li>
<li>
{{__("If not choose expire expire time will be unlimited")}}
</li>
</ul>
</div>
@if (isset($item))
<div class="item-list mb-3">
<h3 class="p-3">
<i class="ri-image-2-line"></i>
{{__("Image")}}
</h3>
<div class="pb-4">
<img src="{{$item->imgUrl()}}" class="img-fluid" alt="{{$item->title}}">
</div>
</div>
@endif
</div>
<div class="col-lg-9 ps-xl-1 ps-xxl-1">
<div class="general-form ">
<h1>
@if(isset($item))
{{__("Edit adv")}} [{{$item->title}}]
@else
{{__("Add new adv")}}
@endif
</h1>
<div class="row">
<div class="col-md-6 mt-3">
<div class="form-group">
<label for="title">
{{__('Title')}}
</label>
<input name="title" type="text" class="form-control @error('title') is-invalid @enderror" placeholder="{{__('Title')}}" value="{{old('title',$item->title??null)}}" />
</div>
</div>
<div class="col-md-6 mt-3">
<div class="form-group">
<label for="link">
{{__('Link')}}
</label>
<input name="link" type="url" class="form-control @error('link') is-invalid @enderror" placeholder="{{__('Link')}}" value="{{old('link',$item->link??null)}}" />
</div>
</div>
<div class="col-md-3 mt-3">
<div class="form-group">
<label for="status">
{{__('Status')}}
</label>
<select name="status" id="status"
class="form-control @error('status') is-invalid @enderror">
<option value="1"
@if (old('status',$item->status??null) == '1' ) selected @endif >{{__("Published")}} </option>
<option value="0"
@if (old('status',$item->status??null) == '0' ) selected @endif >{{__("Draft")}} </option>
</select>
</div>
</div>
<div class="col-md-4 mt-3">
<div class="form-group">
<label for="image">
{{__('Image')}}
</label>
<input name="image" type="file" class="form-control @error('image') is-invalid @enderror" placeholder="{{__('Image')}}" accept="image/*" />
</div>
</div>
<div class="col-md-5 mt-3">
<div class="form-group">
<label for="max_click">
{{__('Max click')}}
</label>
<input name="max_click" type="number" class="form-control @error('max_click') is-invalid @enderror" placeholder="{{__('Max click')}}" value="{{old('max_click',$item->max_click??0)}}" />
</div>
</div>
<div class="col-12 mt-3">
<label for="dp">
{{__("Expire")}}
</label>
{{-- WIP for lang change def tab--}}
<vue-datetime-picker-input :xmin="{{strtotime('yesterday')}}"
xid="dp" xname="expire" xshow="date" xtitle="Expire date" def-tab="1"
@if(isset($item)) :xvalue="{{strtotime($item->expire)}}" @endif
></vue-datetime-picker-input>
</div>
<div class="col-md-12">
<label> &nbsp; </label>
<input name="" type="submit" class="btn btn-primary mt-2" value="{{__('Save')}}" />
</div>
</div>
</div>
</div>
</div>
@endsection

@ -0,0 +1,15 @@
@extends('admin.templates.panel-list-template')
@section('list-title')
<i class="ri-user-3-line"></i>
{{__("Advs list")}}
@endsection
@section('title')
{{__("Advs list")}} -
@endsection
@section('filter')
{{-- Other filters --}}
@endsection
@section('bulk')
{{-- <option value="-"> - </option> --}}
@endsection

@ -85,7 +85,7 @@
</a>
</li>
<li>
<a>
<a href="{{route('admin.adv.index')}}">
<i class="ri-threads-line"></i>
{{__("Advertise")}}
</a>

@ -91,6 +91,19 @@ Route::prefix(config('app.panel.prefix'))->name('admin.')->group(
Route::post('bulk', [\App\Http\Controllers\Admin\ClipController::class, "bulk"])->name('bulk');
Route::get('trashed', [\App\Http\Controllers\Admin\ClipController::class, "trashed"])->name('trashed');
});
Route::prefix('adv')->name('adv.')->group(
function () {
Route::get('', [\App\Http\Controllers\Admin\AdvController::class, 'index'])->name('index');
Route::get('create', [\App\Http\Controllers\Admin\AdvController::class, 'create'])->name('create');
Route::post('store', [\App\Http\Controllers\Admin\AdvController::class, 'store'])->name('store');
Route::get('show/{item}', [\App\Http\Controllers\Admin\AdvController::class, 'show'])->name('show');
Route::get('edit/{item}', [\App\Http\Controllers\Admin\AdvController::class, 'edit'])->name('edit');
Route::post('update/{item}', [\App\Http\Controllers\Admin\AdvController::class, 'update'])->name('update');
Route::get('delete/{item}', [\App\Http\Controllers\Admin\AdvController::class, 'destroy'])->name('destroy');
Route::get('restore/{item}', [\App\Http\Controllers\Admin\AdvController::class, 'restore'])->name('restore');
Route::post('bulk', [\App\Http\Controllers\Admin\AdvController::class, "bulk"])->name('bulk');
Route::get('trashed', [\App\Http\Controllers\Admin\AdvController::class, "trashed"])->name('trashed');
});
Route::prefix('galleries')->name('gallery.')->group(
function () {
Route::get('', [\App\Http\Controllers\Admin\GalleryController::class, 'index'])->name('index');

Loading…
Cancel
Save