gestion sliders

This commit is contained in:
Olivier Legat 2021-04-14 17:33:55 +02:00
parent 7414d7a2b3
commit cedb0b7a4d
22 changed files with 1066 additions and 19 deletions

2
.gitignore vendored
View file

@ -1,10 +1,10 @@
/node_modules
/integration
/public/hot
/public/storage
/public/images/content
/public/images/gammes
/public/images/produits
/public/images/slides
/storage/*.key
/vendor
.env

View file

@ -0,0 +1,123 @@
<?php
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Models\Slider;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class SlidersController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$sliders = Slider::all();
return view('bo.sliders.index', compact('sliders'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
return view('bo.sliders.create');
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$label = $request->label;
$slug = $request->slug;
if (empty($slug)) {
$slug = Str::slug($label);
}
$commentaire = $request->commentaire;
$request->validate([
'label' => 'required|string|max:255',
'slug' => 'sometimes|unique:sliders',
]);
$slider = new Slider();
$slider->label = $label;
$slider->slug = $slug;
$slider->commentaire = $commentaire;
$slider->save();
return redirect()->route('bo.sliders.edit', $slider->id)->with('success', 'Slider créé !');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$slider = Slider::findOrFail($id);
return view('bo.sliders.edit', compact('slider'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$slider = Slider::findOrFail($id);
$label = $request->label;
$slug = $request->slug;
$commentaire = $request->commentaire;
$request->validate([
'label' => 'required|string|max:255',
'slug' => 'required|unique:sliders,slug,' . $slider->id,
]);
$slider->label = $label;
$slider->slug = $slug;
$slider->commentaire = $commentaire;
$slider->save();
return redirect()->route('bo.sliders.edit', $slider->id)->with('success', 'Modifications enregistrées !');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}

View file

@ -0,0 +1,247 @@
<?php
namespace App\Http\Controllers\Bo;
use App\Http\Controllers\Controller;
use App\Models\Slide;
use App\Models\Slider;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
class SlidesController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$slides = Slide::orderBy('order', 'ASC')->get();;
return view('bo.slides.index', compact('slides'));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$sliders = Slider::all();
return view('bo.slides.create', compact('sliders'));
}
/**
* Store a newly created resource in storage.
*
* @todo : validation des dates
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$title = $request->title;
$picture = $request->picture;
$text = $request->text;
$linkLabel = $request->link_label;
$link = $request->link;
$newTab = $request->link_new_tab === null ? 0 : 1;
$sliderId = $request->slider_id;
if (empty($request->date_start_date)) {
$date_start = null;
} else {
if(emty($request->date_start_time)) {
$date_start = $request->date_start_date . " 00:00";
} else {
$date_start = $request->date_start_date . " " . $request->date_start_time;
}
}
if (empty($request->date_end_date)) {
$date_end = null;
} else {
if(empty($request->date_end_time)) {
$date_end = $request->date_end_date . " 23:59";
} else {
$date_end = $request->date_end_date . " " . $request->date_end_time;
}
}
$request->validate([
'title' => 'required|max:255',
'picture' => 'image|mimes:jpeg,png,jpg|max:2048|dimensions:max-width=' .
config('theme.slide_image_maxwidth') . ',max-height=' .
config('theme.slide_image_maxheight'),
'link_label' => 'sometimes|max:255',
'link' => 'sometimes|max:255',
]);
$slide = new Slide();
$slide->title = $title;
$slide->text = $text;
$slide->link_label = $linkLabel;
$slide->link = $link;
$slide->link_new_tab = $newTab;
$slide->date_start = $date_start;
$slide->date_end = $date_end;
$slide->slider_id = $sliderId;
$slide->order = $this->getLastOrder();
$slide->save();
if ($picture !== null) {
$imageName = $slide->id . '.' . $picture->extension();
$picture->move(public_path('images/slides'), $imageName);
$slide->picture = $imageName;
$slide->save();
}
return redirect()->route('bo.slides.edit', $slide->id)->with('success', 'Slide créé !');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$slide = Slide::findOrFail($id);
$sliders = Slider::all();
return view('bo.slides.edit', compact('slide','sliders'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$title = $request->title;
$picture = $request->picture;
$text = $request->text;
$linkLabel = $request->link_label;
$link = $request->link;
$newTab = $request->link_new_tab === null ? 0 : 1;
$sliderId = $request->slider_id;
if (empty($request->date_start_date)) {
$date_start = null;
} else {
if (empty($request->date_start_time)) {
$date_start = $request->date_start_date . " 00:00";
} else {
$date_start = $request->date_start_date . " " . $request->date_start_time;
}
}
if (empty($request->date_end_date)) {
$date_end = null;
} else {
if (empty($request->date_end_time)) {
$date_end = $request->date_end_date . " 23:59";
} else {
$date_end = $request->date_end_date . " " . $request->date_end_time;
}
}
$request->validate([
'title' => 'required|max:255',
'picture' => 'image|mimes:jpeg,png,jpg|max:2048|dimensions:max-width=' .
config('theme.slide_image_maxwidth') . ',max-height=' .
config('theme.slide_image_maxheight'),
'link_label' => 'sometimes|max:255',
'link' => 'sometimes|max:255',
]);
$slide = Slide::findOrFail($id);
$slide->title = $title;
$slide->text = $text;
$slide->link_label = $linkLabel;
$slide->link = $link;
$slide->link_new_tab = $newTab;
$slide->date_start = $date_start;
$slide->date_end = $date_end;
$slide->slider_id = $sliderId;
$slide->save();
if ($picture !== null) {
if(file_exists(public_path() . 'images/slides/' . $slide->picture))
unlink(public_path() . 'images/slides/' . $slide->picture);
$imageName = $slide->id . '.' . $picture->extension();
$picture->move(public_path('images/slides'), $imageName);
$slide->picture = $imageName;
$slide->save();
}
return redirect()->route('bo.slides.edit', $slide->id)->with('success', 'Modifications enregistrées !');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$s = Slide::findOrFail($id);
$s->delete();
return redirect()->route('bo.slides.index');
}
public function changeOrder($id, $action)
{
$current = Slide::findOrFail($id);
if ($action === 'up'){
$tmp = Slide::where('order', '<', $current->order)->orderBy('order', 'DESC')->first();
$newOrder = $tmp->order;
$tmp->order = $current->order;
$current->order = $newOrder;
}else{
$tmp = Slide::where('order', '>', $current->order)->orderBy('order', 'ASC')->first();
$newOrder = $tmp->order;
$tmp->order = $current->order;
$current->order = $newOrder;
}
$tmp->save();
$current->save();
return back();
//return redirect()->route('bo.slides.index');
}
/**
* retreive order position to put a new slide to
*/
private function getLastOrder()
{
$order = Slide::select('order')->orderBy('order', 'DESC')->first();
if ($order === NULL)
return 1;
return $order->order + 1;
}
}

View file

@ -4,6 +4,7 @@ namespace App\Http\Controllers;
use App\Models\Content;
use App\Models\Product;
use App\Models\Slider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
@ -16,7 +17,10 @@ class HomeController extends Controller
//star products
$products = Product::where('status', 1)->where('star', 1)->get();
return view('home', compact('content', 'products'));
$slider = Slider::where('slug','home')->first();
$slides = $slider->showableSlides;
return view('home', compact('content', 'products', 'slides'));
}
/**

25
app/Models/Slide.php Normal file
View file

@ -0,0 +1,25 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Slide extends Model
{
use HasFactory;
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'date_start' => 'datetime',
'date_end' => 'datetime',
];
public function slider() {
return $this->belongsTo(Slider::class);
}
}

31
app/Models/Slider.php Normal file
View file

@ -0,0 +1,31 @@
<?php
namespace App\Models;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Slider extends Model
{
use HasFactory;
public function slides()
{
return $this->hasMany(Slide::class, 'slider_id')->orderBy('order', 'ASC');
}
public function showableSlides()
{
$now = Carbon::now();
return $this->hasMany(Slide::class, 'slider_id')
->orderBy('order', 'ASC')->where(function ($q) use ($now) {
$q->whereDate('date_start', '<=', $now)
->orWhereNull('date_start');
})->where(function ($q) use ($now) {
$q->whereDate('date_end', '>=', $now)
->orWhereNull('date_end');
});
}
}

View file

@ -0,0 +1,39 @@
<?php
use Database\Seeders\SlidersSeeder;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateSlidersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('sliders', function (Blueprint $table) {
$table->id();
$table->string('label');
$table->string('slug');
$table->unique('slug');
$table->string('commentaire')->nullable();
$table->timestamps();
});
$seeder = new SlidersSeeder();
$seeder->run();
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('sliders');
}
}

View file

@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateSlidesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('slides', function (Blueprint $table) {
$table->id();
$table->foreignId('slider_id')->default(1)->constrained('sliders');
$table->string('title');
$table->text('text')->nullable();
$table->string('picture')->nullable();
$table->string('link_label')->nullable();
$table->string('link')->nullable();
$table->boolean('link_new_tab')->default(false);
$table->integer('order')->default(1);
$table->timestamp('date_start')->nullable();
$table->timestamp('date_end')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('slides');
}
}

View file

@ -0,0 +1,24 @@
<?php
namespace Database\Seeders;
use App\Models\Slider;
use Illuminate\Support\Str;
use Illuminate\Database\Seeder;
class SlidersSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$homeslider = new Slider();
$homeslider->label = "Home";
$homeslider->slug = Str::slug($homeslider->label);
$homeslider->commentaire = 'Slider de la home';
$homeslider->save();
}
}

View file

@ -23,8 +23,8 @@
<tbody>
@foreach ($promotions as $promotion)
<tr>
<td>{{$promotion->discountType->label}}</>
<td>{{$promotion->discount_value}}</>
<td>{{$promotion->discountType->label}}</td>
<td>{{$promotion->discount_value}}</td>
<td>{{$promotion->date_start}}</td>
<td>{{$promotion->date_end}}</td>
<td style="display: flex;">

View file

@ -0,0 +1,36 @@
@extends('layouts.bo-layout')
@section('content')
<form action="{{route('bo.sliders.store')}}" method="POST" enctype="multipart/form-data">
@csrf
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2"><a href="{{route('bo.sliders.index')}}" class="h2 text-decoration-none"><</a> Sliders <small class="text-muted">Création</small></h1>
<div class="btn-toolbar mb-2 mb-md-0">
<button type="submit" class="btn btn-sm btn-primary">Enregistrer</a>
</div>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="form-group">
<label for="name">Label *</label>
<input type="text" id="label" name="label" class="form-control" placeholder="Label * " value="{{ old('label') }}" required>
</div>
<div class="form-group">
<label for="name">Slug</label>
<input type="text" id="slug" name="slug" class="form-control" placeholder="Slug" value="{{ old('slug') }}">
<small class="text-muted"> laisser vide pour une génération automatique </small>
</div>
<div class="form-group">
<label for="name">Commentaire</label>
<input type="text" id="commentaire" name="commentaire" class="form-control" placeholder="Commentaire" value="{{ old('commentaire') }}">
</div>
</form>
@endsection

View file

@ -0,0 +1,90 @@
@extends('layouts.bo-layout')
@section('content')
<form action="{{ route('bo.sliders.update', $slider->id) }}" method="POST" enctype="multipart/form-data">
@method('PUT')
@csrf
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2"><a href="{{route('bo.sliders.index')}}" class="h2 text-decoration-none"><</a> Slider <small class="text-muted">Edition</small></h1>
@if (session('success'))
<span class="float-center text-success">{{ session('success') }}</span>
@endif
<div class="btn-toolbar mb-2 mb-md-0">
<button type="submit" class="btn btn-sm btn-primary">Enregistrer</a>
</div>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="form-row">
<div class="form-group col">
<label for="name">Label *</label>
<input type="text" id="label" name="label" class="form-control" placeholder="Label * " value="{{ old('label',$slider->label) }}" required>
</div>
<div class="form-group col">
<label for="name">Slug</label>
<input type="text" id="slug" name="slug" class="form-control" placeholder="Slug" value="{{ old('slug',$slider->slug) }}" required>
</div>
</div>
<div class="form-group">
<label for="name">Commentaire</label>
<input type="text" id="commentaire" name="commentaire" class="form-control" placeholder="Commentaire" value="{{ old('commentaire',$slider->commentaire) }}">
</div>
</form>
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h2><small class="text-muted">Slides</small></h2>
</div>
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Titre</th>
<th scope="col">Texte</th>
<th scope="col">Image</th>
<th scope="col">Lien</th>
<th scope="col">Début</th>
<th scope="col">Fin</th>
<th scope="col">Slider de regroupement</th>
<th scope="col">Ordre</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@foreach($slider->slides as $slide)
<tr>
<td>{{$slide->title}}</td>
<td>{!! $slide->text !!}</td>
<td><img src="{{ asset('/images/slides/' . $slide->picture) }}" height="50px"></td>
<td><a href="{{$slide->link}}" target="_slide">{{ $slide->link_label }}</a></td>
<td>{{$slide->date_start}}</td>
<td>{{$slide->date_end}}</td>
<td>{{$slide->slider->label}}</td>
<td>
@if ($loop->first)
<a href="{{route('bo.slides.change-order', ['id' => $slide->id, 'action' => 'down'])}}" class="btn-link text-decoration-none">
<i name="down_arrow" class="icon-size far fa-arrow-alt-circle-down fa-2x"></i>
</a>
@elseif($loop->last)
<a href="{{route('bo.slides.change-order', ['id' => $slide->id, 'action' => 'up'])}}" class="btn-link text-decoration-none">
<i name="up_arrow" class="icon-size far fa-arrow-alt-circle-up fa-2x"></i>
</a>
@else
<a href="{{route('bo.slides.change-order', ['id' => $slide->id, 'action' => 'up'])}}" class="btn-link text-decoration-none">
<i name="up_arrow" class="icon-size far fa-arrow-alt-circle-up fa-2x"></i>
</a>
<a href="{{route('bo.slides.change-order', ['id' => $slide->id, 'action' => 'down'])}}" class="btn-link text-decoration-none">
<i name="down_arrow" class="icon-size far fa-arrow-alt-circle-down fa-2x"></i>
</a>
@endif
</td>
<td><a href="{{route('bo.slides.edit', ['slide' => $slide->id])}}" class="btn btn-sm btn-primary">Éditer</a></td>
</tr>
@endforeach
</tbody>
</table>
@endsection

View file

@ -0,0 +1,40 @@
@extends('layouts.bo-layout')
@section('content')
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Sliders <small class="text-muted">Liste</small></h1>
@if ($errors->any())
@foreach($errors->all() as $error)
<span class="float-center text-danger">{{ $error }}</span>
@endforeach
@endif
<a href="{{route('bo.sliders.create')}}" class="btn btn-primary float-right">Créer un slider</a>
</div>
<table class="table">
<thead>
<th scope="col">Label</th>
<th scope="col">Slug</th>
<th scope="col">Commentaire</th>
<th></th>
</thead>
<tbody>
@foreach ($sliders as $slider)
<tr>
<td>{{$slider->label}}</td>
<td>{{$slider->slug}}</td>
<td>{{$slider->commentaire}}</td>
<td class="text-center">
<a href="{{route('bo.sliders.edit', $slider->id)}}" class="btn btn-sm btn-primary">Éditer</a>
<form action="{{route('bo.sliders.destroy', $slider->id)}}" method="POST" class="d-inline">
@method('DELETE')
@csrf
<input type="submit" class="btn btn-sm btn-danger" value="Supprimer"
onclick="return confirm('Êtes-vous sûr(e) ?')">
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
@endsection

View file

@ -0,0 +1,110 @@
@extends('layouts.bo-layout')
@section('content')
<form action="{{route('bo.slides.store')}}" method="POST" enctype="multipart/form-data">
@csrf
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2"><a href="{{route('bo.slides.index')}}" class="h2 text-decoration-none"><</a> Slides <small class="text-muted">Création</small></h1>
<div class="btn-toolbar mb-2 mb-md-0">
<button type="submit" class="btn btn-sm btn-primary">Enregistrer</a>
</div>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="form-group">
<label for="name">Titre *</label>
<input type="text" id="title" name="title" class="form-control" placeholder="Titre * " value="{{ old('title') }}" required>
</div>
<div class="form-group">
<label for="name">Texte</label>
<textarea class="form-control" id="text" name="text" placeholder="Texte">{{ old('text') }}</textarea>
</div>
<div class="form-group">
<label for="picture">Image <small class="text-muted">- JPEG/PNG, 2Mo max. Dimensions {{ Config::get('theme.slide_image_maxwidth') }} px par {{ Config::get('theme.slide_image_maxheight') }} px</small></label></br>
<input type="file" id="picture" name="picture" accept="image/png, image/jpeg">
</div>
<div class="form-row">
<div class="form-group col">
<label for="slider_id">Slider de regroupement</label>
<select class="custom-select" id="slider_id" name="slider_id">
@foreach($sliders as $slider)
<option value="{{$slider->id}}">{{$slider->label}}</option>
@endforeach
</select>
</div>
<div class="form-group col"></div>
<div class="form-group col"></div>
<div class="form-group col"></div>
</div>
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h2><small class="text-muted">Période de parution</small></h2>
</div>
<div class="form-row">
<div class="form-group col">
<label for="date_start_date">Début <small class="text-muted"> de l'affichage</small></label>
<input type="date" id="date_start_date" name="date_start_date" class="form-control" value="{{ old('date_start_date') }}">
<input type="time" id="date_start_time" name="date_start_time" class="form-control" value="{{ old('date_start_time') }}">
<small class="text-muted">Laisser vide pour un affichage immédiat</small>
</div>
<div class="form-group col">
<label for="date_end_date">Fin <small class="text-muted"> de l'affichage' </small></label>
<input type="date" id="date_end_date" name="date_end_date" class="form-control" value="{{ old('date_end_date') }}">
<input type="time" id="date_end_time" name="date_end_time" class="form-control" value="{{ old('date_end_time') }}">
<small class="text-muted">Laisser vide pour un affichage permanent</small>
</div>
</div>
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h2><small class="text-muted">Options de lien</small></h2>
</div>
<div class="form-group">
<label for="name">Texte du lien</label>
<input type="text" class="form-control" name="link_label" placeholder="Texte du lien" value="{{ old('link_label') }}">
</div>
<div class="form-group">
<label for="name">Cible du lien</label>
<input type="text" class="form-control" name="link" placeholder="Cible du Lien" value="{{ old('link') }}">
</div>
<div class="form-group text-center">
<input class="form-check-input" type="checkbox" id="new_tab_cb" name="link_new_tab" @if (old('link_new_tab') !== null)checked @endif>
<label class="form-check-label" for="new_tab_cb">Ouvrir dans un nouvel onglet</label>
</div>
</form>
@endsection
@section('scripts')
<script type="text/javascript">
var editorConfig = {
removePlugins: ["Image", "ImageCaption", "ImageStyle", "ImageToolbar", "ImageUpload"],
toolbar: [ 'heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', '|', 'blockQuote', 'insertTable', '|', 'undo', 'redo' ],
heading: {
options: [
{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
{ model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
{ model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' },
{ model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3' },
{ model: 'heading4', view: 'h4', title: 'Heading 4', class: 'ck-heading_heading4' }
]
},
table: {
contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ]
}
};
ClassicEditor
.create( document.querySelector( '#text' ), editorConfig)
.catch( error => {
console.error( error );
} );
</script>
@endsection

View file

@ -0,0 +1,129 @@
@extends('layouts.bo-layout')
@section('content')
<form action="{{route('bo.slides.update', $slide->id)}}" method="POST" enctype="multipart/form-data">
@method('PUT')
@csrf
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2"><a href="{{route('bo.slides.index')}}" class="h2 text-decoration-none"><</a> Slides <small class="text-muted">Création</small></h1>
@if (session('success'))
<span class="float-center text-success">{{ session('success') }}</span>
@endif
<div class="btn-toolbar mb-2 mb-md-0">
<button type="submit" class="btn btn-sm btn-primary">Enregistrer</a>
</div>
</div>
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="form-group">
<label for="name">Titre *</label>
<input type="text" id="title" name="title" class="form-control" placeholder="Titre * " value="{{ old('title', $slide->title) }}" required>
</div>
<div class="form-group">
<label for="name">Texte</label>
<textarea class="form-control" id="text" name="text" placeholder="Texte">{{ old('text', $slide->text) }}</textarea>
</div>
<div class="form-group">
<label for="picture">Image <small class="text-muted">- JPEG/PNG, 2Mo max. Dimensions {{ Config::get('theme.slide_image_maxwidth') }} px par {{ Config::get('theme.slide_image_maxheight') }} px</small></label></br>
<input type="file" id="picture" name="picture" accept="image/png, image/jpeg">
@if ($slide->picture !== null)
<br/>
<br/>
<img src="/images/slides/{{$slide->picture}}" alt="{{$slide->title}}" style="max-height: 100px;">
@endif
</div>
<div class="form-row">
<div class="form-group col">
<label for="slider_id">Slider de regroupement</label>
<select class="custom-select" id="slider_id" name="slider_id">
@foreach($sliders as $slider)
<option value="{{$slider->id}}" @if ($slider->id === $slide->slider_id) selected @endif>{{$slider->label}}</option>
@endforeach
</select>
</div>
<div class="form-group col"></div>
<div class="form-group col"></div>
<div class="form-group col"></div>
</div>
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h2><small class="text-muted">Période de parution</small></h2>
</div>
<div class="form-row">
<div class="form-group col">
<label for="date_start_date">Début <small class="text-muted"> de l'affichage</small></label>
@if($slide->date_start !== null)
<input type="date" id="date_start_date" name="date_start_date" class="form-control" value="{{ old('date_start_date', date_format($slide->date_start, "Y-m-d")) }}">
<input type="time" id="date_start_time" name="date_start_time" class="form-control" value="{{ old('date_start_time', date_format($slide->date_start, "H:i")) }}">
@else
<input type="date" id="date_start_date" name="date_start_date" class="form-control" value="{{ old('date_start_date') }}">
<input type="time" id="date_start_time" name="date_start_time" class="form-control" value="{{ old('date_start_time') }}">
@endif
<small class="text-muted">Laisser vide pour un affichage immédiat</small>
</div>
<div class="form-group col">
<label for="date_end_date">Fin <small class="text-muted"> de l'affichage' </small></label>
@if($slide->date_end !== null)
<input type="date" id="date_end_date" name="date_end_date" class="form-control" value="{{ old('date_end_date', date_format($slide->date_end, "Y-m-d")) }}">
<input type="time" id="date_end_time" name="date_end_time" class="form-control" value="{{ old('date_end_time', date_format($slide->date_end, "H:i")) }}">
@else
<input type="date" id="date_end_date" name="date_end_date" class="form-control" value="{{ old('date_end_date') }}">
<input type="time" id="date_end_time" name="date_end_time" class="form-control" value="{{ old('date_end_time') }}">
@endif
<small class="text-muted">Laisser vide pour un affichage permanent</small>
</div>
</div>
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h2><small class="text-muted">Options de lien</small></h2>
</div>
<div class="form-group">
<label for="name">Texte du lien</label>
<input type="text" class="form-control" name="link_label" placeholder="Texte du lien" value="{{ old('link_label', $slide->link_label) }}">
</div>
<div class="form-group">
<label for="name">Cible du lien</label>
<input type="text" class="form-control" name="link" placeholder="Cible du Lien" value="{{ old('link', $slide->link) }}">
</div>
<div class="form-group text-center">
<input class="form-check-input" type="checkbox" id="new_tab_cb" name="link_new_tab" @if (old('link_new_tab', $slide->link_new_tab) !== 0)checked @endif>
<label class="form-check-label" for="new_tab_cb">Ouvrir dans un nouvel onglet</label>
</div>
</form>
@endsection
@section('scripts')
<script type="text/javascript">
var editorConfig = {
removePlugins: ["Image", "ImageCaption", "ImageStyle", "ImageToolbar", "ImageUpload"],
toolbar: [ 'heading', '|', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', '|', 'blockQuote', 'insertTable', '|', 'undo', 'redo' ],
heading: {
options: [
{ model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' },
{ model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' },
{ model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' },
{ model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3' },
{ model: 'heading4', view: 'h4', title: 'Heading 4', class: 'ck-heading_heading4' }
]
},
table: {
contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells' ]
}
};
ClassicEditor
.create( document.querySelector( '#text' ), editorConfig)
.catch( error => {
console.error( error );
} );
</script>
@endsection

View file

@ -0,0 +1,69 @@
@extends('layouts.bo-layout')
@section('content')
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
<h1 class="h2">Slides <small class="text-muted">Liste</small></h1>
@if ($errors->any())
@foreach($errors->all() as $error)
<span class="float-center text-danger">{{ $error }}</span>
@endforeach
@endif
<a href="{{route('bo.slides.create')}}" class="btn btn-primary float-right">Créer un slide</a>
</div>
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Titre</th>
<th scope="col">Texte</th>
<th scope="col">Image</th>
<th scope="col">Lien</th>
<th scope="col">Début</th>
<th scope="col">Fin</th>
<th scope="col">Slider de regroupement</th>
<th scope="col">Ordre</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
@foreach($slides as $slide)
<tr>
<td>{{$slide->title}}</td>
<td>{!! $slide->text !!}</td>
<td><img src="{{ asset('/images/slides/' . $slide->picture) }}" height="50px"></td>
<td><a href="{{$slide->link}}" target="_slide">{{ $slide->link_label }}</a></td>
<td>{{$slide->date_start}}</td>
<td>{{$slide->date_end}}</td>
<td><a href="{{route('bo.sliders.edit', $slide->slider->id) }}">{{$slide->slider->label}}</a></td>
<td>
@if ($loop->first)
<a href="{{route('bo.slides.change-order', ['id' => $slide->id, 'action' => 'down'])}}" class="btn-link text-decoration-none">
<i name="down_arrow" class="icon-size far fa-arrow-alt-circle-down fa-2x"></i>
</a>
@elseif($loop->last)
<a href="{{route('bo.slides.change-order', ['id' => $slide->id, 'action' => 'up'])}}" class="btn-link text-decoration-none">
<i name="up_arrow" class="icon-size far fa-arrow-alt-circle-up fa-2x"></i>
</a>
@else
<a href="{{route('bo.slides.change-order', ['id' => $slide->id, 'action' => 'up'])}}" class="btn-link text-decoration-none">
<i name="up_arrow" class="icon-size far fa-arrow-alt-circle-up fa-2x"></i>
</a>
<a href="{{route('bo.slides.change-order', ['id' => $slide->id, 'action' => 'down'])}}" class="btn-link text-decoration-none">
<i name="down_arrow" class="icon-size far fa-arrow-alt-circle-down fa-2x"></i>
</a>
@endif
</td>
<td>
<a href="{{route('bo.slides.edit', ['slide' => $slide->id])}}" class="btn btn-sm btn-primary">Éditer</a>
<form action="{{route('bo.slides.destroy', $slide->id)}}" method="POST" class="d-inline">
@method('DELETE')
@csrf
<input type="submit" class="btn btn-sm btn-danger" value="Supprimer"
onclick="return confirm('Êtes-vous sûr(e) ?')">
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
@endsection

View file

@ -14,7 +14,7 @@
<div class="">
<div class="form-message__title title">Félicitations</div>
<div class="form-message__text">Votre compte a bien été créé !<br>Vous allez recevoir un mail de confirmation<br>sur l’adresse {{ $mail }}</div>
<a class="form-message__btn btn btn_blue" href="login.php">Connexion</a>
<a class="form-message__btn btn btn_blue" href="{{ route('auth.connexion') }}">Connexion</a>
</div>
</div>
</div>

View file

@ -10,7 +10,7 @@
<div class="breadrumbs content"><div class="breadrumbs__inner"></div></div> {{-- sert de spacer car ici pas de breadcrumb --}}
{{-- Slider --}}
@yield('main-slider', view('partials.main-slider'))
@include('partials.main-slider')
{{-- Fin du Slider --}}
<div class="tc-text content section">

View file

@ -2,17 +2,27 @@
<div class="mainslider__wrapper wrapper">
<div class="swiper-container">
<div class="swiper-wrapper">
<?php for($i = 0; $i < 3; $i++) : ?>
<div class="swiper-slide">
<div class="mainslider__item mainslider-item" style="background-image: url({{ asset(config('app.theme').'/img/demo/mainslider_demo.jpg')}});">
<div class="mainslider-item__block">
<div class="mainslider-item__title title title_medium">Des saveurs qui donnent envie</div>
<div class="mainslider-item__text">Cras scelerisque imperdiet nisl, non malesuada felis. Fusce ullamcorper mi sed dapibus dignissim. Maecenas pellentesque auctor sem nec volutpat...</div>
<div class="mainslider-item__btn btn">Accédez à la boutique</div>
</div>
</div>
</div>
<?php endfor ?>
@foreach ($slides as $slide)
<div class="swiper-slide">
@if(!empty($slide->picture))
<div class="mainslider__item mainslider-item" style="background-image: url({{ asset('images/slides/'.$slide->picture)}});">
@else
<div class="mainslider__item mainslider-item" style="background-image: url({{ asset(config('app.theme').'/img/demo/mainslider_demo.jpg')}});">
@endif
<div class="mainslider-item__block">
<div class="mainslider-item__title title title_medium">{{ $slide->title }}</div>
<div class="mainslider-item__text">{!! $slide->text !!}</div>
@if(!empty($slide->link_label))
<div class="mainslider-item__btn btn">
<a href="{{ $slide->link }}" @if($slide->link_new_tab) target="_slise" @endif>
{{ $slide->link_label}}
</a>
</div>
@endif
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>

View file

@ -18,4 +18,7 @@ return [
'enum_product_types' => [
'foodProduct' => 'Alimentaire',
],
'slide_image_maxwidth' => '1180',
'slide_image_maxheight' => '449',
];

View file

@ -66,6 +66,24 @@
</li>
</ul>
<div class="accordion" id="accordionMenu">
<div class="card">
<div class="card-header" id="headingSliders">
<h2 class="mb-0">
<button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#collapseSliders" aria-expanded="true" aria-controls="collapseOne">
<i class="fas fa-tv"></i> Sliders
</button>
</h2>
</div>
<div id="collapseSliders" class="collapse {{ ( request()->routeIs('bo.sliders*') || request()->routeIs('bo.slides*') ) ? 'show' : '' }}" aria-labelledby="headingSliders" tata-parent="#accordionMenu">
<div class="card-body">
<ul class="nav flex-column mb-2">
<li class="nav-item"><a class="nav-link" href="{{route('bo.sliders.index')}}">Sliders</a></li>
<li class="nav-item"><a class="nav-link" href="{{route('bo.slides.index')}}">Slides</a></li>
</ul>
</div>
</div>
</div>
<div class="card">
<div class="card-header" id="headingPages">
<h2 class="mb-0">

View file

@ -83,8 +83,13 @@ Route::namespace('App\Http\Controllers\Bo')
Route::get('/products/create/{product_type}', [\App\Http\Controllers\Bo\ProductsController::class, 'create'])
->name('products.create');
Route::resource('ranges', RangesController::class);
Route::resource('promotions', PromotionsController::class);
Route::resources([
'ranges' => RangesController::class,
'promotions' => PromotionsController::class,
'sliders'=> SlidersController::class,
'slides' => SlidesController::class,
]);
Route::get('/slide/change-order/{id}/{action}', [App\Http\Controllers\Bo\SlidesController::class,'changeOrder'])->name('slides.change-order');
Route::get('/customer-info/{id}', [OrdersController::class, 'getCustomerInfo'])->name('get-customer-info');