mirror of https://github.com/4xmen/xshop.git
added setting to panel
parent
58bc5e97d1
commit
22a302f975
@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Admin;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Requests\SettingSaveRequest;
|
||||||
|
use App\Models\Category;
|
||||||
|
use App\Models\Group;
|
||||||
|
use App\Models\Setting;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class SettingController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Display a listing of the resource.
|
||||||
|
*/
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
$settings = Setting::where('active', 1)
|
||||||
|
->orderBy('section')->get(); //ESH// just active setting`s show
|
||||||
|
$cats = Category::all(['id','name']);
|
||||||
|
$groups = Group::all(['id','name']);
|
||||||
|
return view('admin.commons.setting',
|
||||||
|
compact('settings', 'cats','groups'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for creating a new resource.
|
||||||
|
*/
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store a newly created resource in storage.
|
||||||
|
*/
|
||||||
|
public function store(SettingSaveRequest $request)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
$set = new Setting();
|
||||||
|
$set->title = $request->title;
|
||||||
|
$set->key = $request->key;
|
||||||
|
$set->section = $request->section;
|
||||||
|
$set->type = $request->type;
|
||||||
|
$set->size = $request->size;
|
||||||
|
$set->save();
|
||||||
|
return redirect()->back()->with(['message' => __('Setting added to website')]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the specified resource.
|
||||||
|
*/
|
||||||
|
public function show(Setting $setting)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the form for editing the specified resource.
|
||||||
|
*/
|
||||||
|
public function edit(Setting $setting)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the specified resource in storage.
|
||||||
|
*/
|
||||||
|
public function update(Request $request)
|
||||||
|
{
|
||||||
|
$all = $request->all();
|
||||||
|
foreach ($all as $key => $val) {
|
||||||
|
$set = Setting::where('key', $key)->first();
|
||||||
|
if ($set != null && !$request->hasFile($key)) {
|
||||||
|
|
||||||
|
$set->value = validateSettingRequest($set,$val);
|
||||||
|
$set->save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$files = $request->allFiles();
|
||||||
|
if (isset($files['file'])) {
|
||||||
|
foreach ($files['file'] as $index => $file) {
|
||||||
|
if ($file->extension() == 'mp4' || $file->extension() == 'mp3'){
|
||||||
|
$file->move(public_path('upload/media/'), str_replace('_','.',$index) );//store('/images/'.,['disk' => 'public']);
|
||||||
|
}else{
|
||||||
|
$file->move(public_path('upload/images/'), str_replace('_','.',$index) );//store('/images/'.,['disk' => 'public']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return redirect()->back()->with(['message' => __('Setting of website updated')]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the specified resource from storage.
|
||||||
|
*/
|
||||||
|
public function destroy(Setting $setting)
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class SettingSaveRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*/
|
||||||
|
public function authorize(): bool
|
||||||
|
{
|
||||||
|
return auth()->check() && auth()->user()->hasRole('developer');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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','min:3', 'max:255'],
|
||||||
|
'key' => ['required', 'string', 'alpha_dash', 'max:255', "unique:settings,key,".$this->id],
|
||||||
|
'type' => ['required', 'string'],
|
||||||
|
'section' => ['required', 'string', 'max:255', 'min:2'],
|
||||||
|
'size' => ['required','integer','min:1','max:12']
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 328 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 11 KiB |
@ -0,0 +1,59 @@
|
|||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
// Get all section group items
|
||||||
|
let sectionGroupItems = document.querySelectorAll('.section-group-item');
|
||||||
|
|
||||||
|
// Get all sections
|
||||||
|
let sections = document.querySelectorAll('#setting-sections section');
|
||||||
|
|
||||||
|
// Hide all sections initially
|
||||||
|
sections?.forEach(section => {
|
||||||
|
section.style.display = 'none';
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Show/hide sections on click
|
||||||
|
sectionGroupItems?.forEach(item => {
|
||||||
|
item.addEventListener('click', function (event) {
|
||||||
|
try {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
let targetId = this.getAttribute('href').slice(1);
|
||||||
|
sections.forEach(section => {
|
||||||
|
if (section.id === targetId) {
|
||||||
|
section.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
section.style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sectionGroupItems.forEach(link => {
|
||||||
|
link.classList.remove('active');
|
||||||
|
});
|
||||||
|
this.classList.add('active');
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show section based on hash in URL
|
||||||
|
let hash = window.location.hash.slice(1);
|
||||||
|
if (hash) {
|
||||||
|
sections.forEach(section => {
|
||||||
|
if (section.id === hash) {
|
||||||
|
section.style.display = 'block';
|
||||||
|
} else {
|
||||||
|
section.style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Show the first section on page load
|
||||||
|
document.querySelector('.section-group-item').dispatchEvent(new Event('click'));
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
@ -0,0 +1,139 @@
|
|||||||
|
@extends('layouts.app')
|
||||||
|
@section('title')
|
||||||
|
{{__("Setting")}} -
|
||||||
|
@endsection
|
||||||
|
@section('content')
|
||||||
|
<div class="row">
|
||||||
|
<div class="mb-5 pb-5">
|
||||||
|
<div class="row">
|
||||||
|
{{-- list side bar start--}}
|
||||||
|
<div class="col-xl-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>
|
||||||
|
{{__("Recommends")}}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="item-list mb-3">
|
||||||
|
<h3 class="p-3">
|
||||||
|
<i class="ri-file-2-line"></i>
|
||||||
|
{{__("Sections")}}
|
||||||
|
</h3>
|
||||||
|
<div class="p-2">
|
||||||
|
|
||||||
|
<div class="section-group">
|
||||||
|
@foreach(\App\Models\Setting::groupBy('section')->pluck('section')->toArray() as $sec)
|
||||||
|
<a href="#{{$sec}}" class="section-group-item">
|
||||||
|
{{$sec}}
|
||||||
|
</a>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-list mb-3">
|
||||||
|
<h3 class="p-3">
|
||||||
|
<i class="ri-add-line"></i>
|
||||||
|
{{__("Add new setting")}}
|
||||||
|
</h3>
|
||||||
|
@if(auth()->user()->hasRole('developer'))
|
||||||
|
<form class="p-2 m-3 mt-0" method="post" action="{{route('admin.setting.store')}}">
|
||||||
|
@csrf
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="section">
|
||||||
|
{{__('Section')}}
|
||||||
|
</label>
|
||||||
|
<input name="section" type="text"
|
||||||
|
class="form-control @error('section') is-invalid @enderror"
|
||||||
|
placeholder="{{__('Section')}}"
|
||||||
|
value="{{old('section',$setting->section??null)}}"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="type">
|
||||||
|
{{__('Type')}}
|
||||||
|
</label>
|
||||||
|
<select name="type" id="type"
|
||||||
|
class="form-control @error('type') is-invalid @enderror">
|
||||||
|
@foreach(\App\Models\Setting::$settingTypes as $type)
|
||||||
|
<option value="text"
|
||||||
|
@if (old('type') == $type ) selected @endif >{{__($type)}} </option>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<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')}}"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="key">
|
||||||
|
{{__('Key')}}
|
||||||
|
</label>
|
||||||
|
<input name="key" type="text"
|
||||||
|
class="form-control @error('key') is-invalid @enderror"
|
||||||
|
placeholder="{{__('Key')}}" value="{{old('key')}}"/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="size">
|
||||||
|
{{__('Size')}}
|
||||||
|
</label>
|
||||||
|
<input name="size" type="number"
|
||||||
|
class="form-control @error('size') is-invalid @enderror"
|
||||||
|
placeholder="{{__('Size')}}" value="{{old('size',12)}}"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label> </label>
|
||||||
|
<input name="" type="submit" class="btn w-100 btn-primary mt-2"
|
||||||
|
value="{{__('Add to setting')}}"/>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="col-xl-9 ps-xl-0" id="setting-sections">
|
||||||
|
<form action="{{route('admin.setting.update')}}" method="post" enctype="multipart/form-data">
|
||||||
|
@csrf
|
||||||
|
@foreach(\App\Models\Setting::groupBy('section')->pluck('section')->toArray() as $sec)
|
||||||
|
<section id="{{$sec}}">
|
||||||
|
<div class="row">
|
||||||
|
@foreach($settings as $setting)
|
||||||
|
@if($setting->section == $sec)
|
||||||
|
@include('components.setting-field')
|
||||||
|
@endif
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
@endforeach
|
||||||
|
<button class="action-btn circle-btn"
|
||||||
|
data-bs-toggle="tooltip"
|
||||||
|
data-bs-placement="top"
|
||||||
|
data-bs-custom-class="custom-tooltip"
|
||||||
|
data-bs-title="{{__("Add another one")}}"
|
||||||
|
href="{{getRoute('create')}}"
|
||||||
|
>
|
||||||
|
<i class="ri-save-2-line"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="mb-5">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endsection
|
@ -0,0 +1,102 @@
|
|||||||
|
<div class="setting-field col-md-{{$setting->size}}">
|
||||||
|
<label for="{{$setting->key}}">
|
||||||
|
{{$setting->title}}
|
||||||
|
|
||||||
|
{{-- // WIP translate--}}
|
||||||
|
</label>
|
||||||
|
|
||||||
|
@switch($setting->type)
|
||||||
|
@case('LONGTEXT')
|
||||||
|
<textarea name="{{$setting->key}}" @if($setting->ltr) dir="ltr" @endif id="{{$setting->key}}"
|
||||||
|
class="form-control"
|
||||||
|
rows="5">{{old($setting->key, $setting->value)}}</textarea>
|
||||||
|
@break
|
||||||
|
@case('CODE')
|
||||||
|
<textarea dir="ltr" name="{{$setting->key}}" id="{{$setting->key}}"
|
||||||
|
class="form-control"
|
||||||
|
rows="5">{{old($setting->key, $setting->value)}}</textarea>
|
||||||
|
@break
|
||||||
|
@case('EDITOR')
|
||||||
|
<textarea name="{{$setting->key}}" id="{{$setting->key}}"
|
||||||
|
class="form-control ckeditorx"
|
||||||
|
rows="5">{{old($setting->key, $setting->value)}}</textarea>
|
||||||
|
@break
|
||||||
|
@case('CHECKBOX')
|
||||||
|
<select name="{{$setting->key}}" id="{{$setting->key}}"
|
||||||
|
class="form-control @error('status') is-invalid @enderror">
|
||||||
|
<option value="1"
|
||||||
|
@if (old($setting->key, $setting->value??0) == '1' ) selected @endif >{{__("True")}} </option>
|
||||||
|
<option value="0"
|
||||||
|
@if (old($setting->key, $setting->value??0) == '0' ) selected @endif >{{__("False")}} </option>
|
||||||
|
</select>
|
||||||
|
@break
|
||||||
|
@case('CATEGORY')
|
||||||
|
<searchable-select
|
||||||
|
@error('category_id') :err="true" @enderror
|
||||||
|
:items='@json($cats)'
|
||||||
|
title-field="name"
|
||||||
|
value-field="id"
|
||||||
|
xlang="{{config('app.locale')}}"
|
||||||
|
xid="{{$setting->key}}"
|
||||||
|
xname="{{$setting->key}}"
|
||||||
|
@error('category_id') :err="true" @enderror
|
||||||
|
xvalue='{{old($setting->key,$setting->value??null)}}'
|
||||||
|
:close-on-Select="true"></searchable-select>
|
||||||
|
@break
|
||||||
|
@case('GROUP')
|
||||||
|
<searchable-select
|
||||||
|
@error('category_id') :err="true" @enderror
|
||||||
|
:items='@json($groups)'
|
||||||
|
title-field="name"
|
||||||
|
value-field="id"
|
||||||
|
xlang="{{config('app.locale')}}"
|
||||||
|
xid="{{$setting->key}}"
|
||||||
|
xname="{{$setting->key}}"
|
||||||
|
@error('category_id') :err="true" @enderror
|
||||||
|
xvalue='{{old($setting->key,$setting->value??null)}}'
|
||||||
|
:close-on-Select="true"></searchable-select>
|
||||||
|
@break
|
||||||
|
@case('FILE')
|
||||||
|
<div class="row">
|
||||||
|
@php($ext = strtolower(pathinfo(str_replace('_','.',$setting->key), PATHINFO_EXTENSION)))
|
||||||
|
<div class="col-md-5 ">
|
||||||
|
<input type="file" accept=".{{pathinfo(str_replace('_','.',$setting->key), PATHINFO_EXTENSION)}}" class="form-control" name="file[{{$setting->key}}]" id="{{$setting->key}}">
|
||||||
|
</div>
|
||||||
|
@if(!in_array($ext, ['svg','jpg','png','gif','webp'] ) )
|
||||||
|
<div class="col-md-2">
|
||||||
|
<a class="btn btn-primary w-100" href="{{asset('upload/file/'.str_replace('_','.',$setting->key))}}?{{time()}}">
|
||||||
|
<i class="ri-download-2-line"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
<div class="col-md-5">
|
||||||
|
@if($ext == 'mp4')
|
||||||
|
<video controls src="{{asset('upload/file/'.str_replace('_','.',$setting->key))}}?{{time()}}" class="img-fluid" style="max-height: 150px;max-width: 45%" ></video>
|
||||||
|
<br>
|
||||||
|
@elseif($ext == 'mp3')
|
||||||
|
<audio controls src="{{asset('upload/file/'.str_replace('_','.',$setting->key))}}?{{time()}}" class="img-fluid" style="max-height: 150px;max-width: 45%" ></audio>
|
||||||
|
<br>
|
||||||
|
@elseif(in_array($ext, ['svg','jpg','png','gif','webp'] ) )
|
||||||
|
<img src="{{asset('upload/images/'.str_replace('_','.',$setting->key))}}?{{time()}}"
|
||||||
|
class="img-fluid" style="max-height: 150px;max-width: 45%" alt="{{$setting->key}}">
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
@break
|
||||||
|
@default
|
||||||
|
@if($setting->key == 'optimize')
|
||||||
|
<select class="form-control" name="{{$setting->key}}" id="{{$setting->key}}">
|
||||||
|
<option value="1"
|
||||||
|
@if (old($setting->key, $setting->value??'webp') == 'jpg' ) selected @endif >{{__("jpg")}} </option>
|
||||||
|
<option value="0"
|
||||||
|
@if (old($setting->key, $setting->value??'webp') == 'webp' ) selected @endif >{{__("webp")}} </option>
|
||||||
|
</select>
|
||||||
|
@else
|
||||||
|
<input type="text" id="{{$setting->key}}"
|
||||||
|
name="{{$setting->key}}" class="form-control"
|
||||||
|
value="{{old($setting->key, $setting->value)}}" @if($setting->ltr) dir="ltr" @endif>
|
||||||
|
@endif
|
||||||
|
@endswitch
|
||||||
|
|
||||||
|
</div>
|
Loading…
Reference in New Issue