Merge branch '3.2.5' into 'dev'

Update schedule editor

See merge request TheGamecraft/c-cms!92
This commit is contained in:
Mathieu Lagace
2019-12-22 22:48:43 +00:00
9 changed files with 448 additions and 79 deletions

12
app/EventType.php Normal file
View File

@@ -0,0 +1,12 @@
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class EventType extends Model
{
protected $casts = [
'schedule_model' => 'array',
];
}

View File

@@ -0,0 +1,85 @@
<?php
namespace App\Http\Controllers;
use App\EventType;
use Illuminate\Http\Request;
class EventTypeController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
}
/**
* Display the specified resource.
*
* @param \App\EventType $eventType
* @return \Illuminate\Http\Response
*/
public function show(EventType $eventType)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param \App\EventType $eventType
* @return \Illuminate\Http\Response
*/
public function edit(EventType $eventType)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\EventType $eventType
* @return \Illuminate\Http\Response
*/
public function update(Request $request, EventType $eventType)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param \App\EventType $eventType
* @return \Illuminate\Http\Response
*/
public function destroy(EventType $eventType)
{
//
}
}

View File

@@ -16,8 +16,64 @@ class ScheduleEditorController extends Controller
return view('admin.schedule.editor.course',['periode' => $periode, 'niveau' => $niveau]);
}
public function getTemplate()
public function getTemplate(int $id)
{
return view('admin.schedule.editor.template');
return view('admin.schedule.editor.template',["eventType" => \App\EventType::find($id)]);
}
public function getEventTemplate(int $id)
{
$eventType = \App\EventType::find($id);
return json_encode($eventType);
}
public function test()
{
$evenType = new \App\EventType();
$evenType->name = "Soirée d'instruction régulière";
$evenType->admin_desc = "Veuillez modifier la description admin par défaut";
$evenType->calendar_color = "orange";
$evenType->calendar_icon = "fas fa-book";
$evenType->begin_time = "12:00";
$evenType->end_time = "18:00";
$evenType->location = "Escadron";
$evenType->is_mandatory = true;
$evenType->use_weekly_msg = true;
$evenType->weekly_msg_publication_time = "-5days";
$evenType->use_schedule = true;
$evenType->schedule_model = [
"periodes" => [
0 => [
"name" => "Periode 1",
"begin_time" => "19:00",
"end_time" => "20:10"
],
1 => [
"name" => "Pause",
"begin_time" => "20:10",
"end_time" => "20:30"
],
2 => [
"name" => "Periode 1",
"begin_time" => "20:30",
"end_time" => "21:20"
]
],
"niveaux" => [
0 => [
"name" => "Niveau 1"
],
1 => [
"name" => "Niveau 2"
],
2 => [
"name" => "Niveau 3"
]
]
];
$evenType->is_promoted = true;
//$evenType->save();
}
}

View File

@@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateEventTypesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('event_types', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->text('admin_desc');
$table->string('calendar_color')->default('blue');
$table->string('calendar_icon')->default('<i class="fa fa-question-circle"></i>');
$table->string('begin_time')->default('12:00');
$table->string('end_time')->default('13:00');
$table->string('location')->default('Escadron');
$table->boolean('is_mandatory')->default(false);
$table->boolean('use_weekly_msg')->default(false);
$table->string('weekly_msg_publication_time')->default('-5day');
$table->boolean('use_schedule')->default(false);
$table->text('schedule_model');
$table->boolean('is_promoted')->default(false);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('event_types');
}
}

View File

@@ -1,8 +1,8 @@
function initScheduleEditor(id, periode, niveau)
function initScheduleEditor(id, eventType)
{
$.ajax({
type: 'GET',
url: '/api/schedule/editor/init?api_token='+api_token,
url: '/api/schedule/editor/init/'+eventType+'?api_token='+api_token,
success: function (template) {
$("#"+id).html(template);
for (let pniveau = 1; pniveau <= 3; pniveau++) {
@@ -16,11 +16,49 @@ function initScheduleEditor(id, periode, niveau)
showNotification('error','Impossible d\'initialiser l\'éditeur d\'horaire ...','top', 'center')
}
})
$('.datetimepicker').datetimepicker({
icons: {
time: "fa fa-clock-o",
date: "fa fa-calendar",
up: "fa fa-chevron-up",
down: "fa fa-chevron-down",
previous: 'fa fa-chevron-left',
next: 'fa fa-chevron-right',
today: 'fa fa-screenshot',
clear: 'fa fa-trash',
close: 'fa fa-remove'
}
});
$('.richeditor').trumbowyg({
lang: 'fr'
});
$('select').selectpicker();
}
function loadTemplate(id)
function switchUseWeeklyMsg()
{
$.get('/api/schedule/editor/init?api_token='+api_token, function ( data ) {$("#"+id).html(data);});
if($('#use_weekly_msg').is(":checked"))
{
$('#collmessagedelasemaine').removeClass('d-none');
}
else
{
$('#collmessagedelasemaine').addClass('d-none');
}
}
function switchUseSchedule()
{
if($('#use_schedule').is(":checked"))
{
$('#collschedule').removeClass('d-none');
}
else
{
$('#collschedule').addClass('d-none');
}
}
function loadCourse(periode,niveau)
@@ -35,4 +73,89 @@ function loadCourse(periode,niveau)
showNotification('error','Impossible de charger les cours ...','top', 'center')
}
})
}
function loadEventType(date)
{
var selectInput = $('#type');
var id = selectInput.val();
$.ajax({
type: 'GET',
url: '/api/schedule/editor/template/'+id+'?api_token='+api_token,
success: function (data) {
var result = JSON.parse(data);
initScheduleEditor("scheduleEditor",id)
$.each(result, function (i, val) {
if(i == "is_mandatory" || i == "use_schedule" || i == "use_weekly_msg")
{
if(val == 1)
{
$('#'+i).prop( "checked", true );
}
else
{
$('#'+i).prop( "checked", false );
}
switchUseSchedule();
switchUseWeeklyMsg();
}
else if(i == "begin_time" || i == "end_time")
{
var foo = $('#'+i);
var mdate = moment(date+" "+val);
foo.data("DateTimePicker").destroy();
foo.datetimepicker({
icons: {
time: "fa fa-clock-o",
date: "fa fa-calendar",
up: "fa fa-chevron-up",
down: "fa fa-chevron-down",
previous: 'fa fa-chevron-left',
next: 'fa fa-chevron-right',
today: 'fa fa-screenshot',
clear: 'fa fa-trash',
close: 'fa fa-remove'
},
date: new Date(mdate)
});
}
else if(i == "weekly_msg_publication_time")
{
var foo = $('#'+i);
var mdate = moment(date+" "+result["begin_time"]);
mdate.subtract(5, 'days');
foo.data("DateTimePicker").destroy();
foo.datetimepicker({
icons: {
time: "fa fa-clock-o",
date: "fa fa-calendar",
up: "fa fa-chevron-up",
down: "fa fa-chevron-down",
previous: 'fa fa-chevron-left',
next: 'fa fa-chevron-right',
today: 'fa fa-screenshot',
clear: 'fa fa-trash',
close: 'fa fa-remove'
},
date: new Date(mdate)
});
}
else if(i == "location" || i == "name")
{
var foo = $('#'+i);
foo.val(val);
}
else if(i == "admin_desc")
{
var foo = $('#'+i);
foo.trumbowyg('html', val);
}
});
},
error: function () {
showNotification('error','Impossible de charger le type d\'évenement ...','top', 'center')
}
})
}

View File

@@ -4,27 +4,27 @@
Niveau/Periode
</b>
</div>
@for($i = 1; $i <= 3; $i++)
@foreach($eventType->schedule_model['niveaux'] as $niveau)
<div class="col border-right border-bottom bg-dark text-white">
<div class="form-group label-floating">
<input type="text" placeholder="Niveau" class="form-control text-white" value="Niveau {{$i}}" />
<input type="text" placeholder="Niveau" class="form-control text-white" value="{{$niveau['name']}}" />
<span class="form-control-feedback">
<i class="material-icons">clear</i>
</span>
</div>
</div>
@endfor
@endforeach
<div class="col-1">
<button class="btn btn-primary btn-fab btn-fab-mini btn-round">
<i class="material-icons">add</i>
</button>
</div>
</div>
@for($j = 1; $j <= 3; $j++)
@foreach($eventType->schedule_model['periodes'] as $periode)
<div class="row">
<div class="col-2 d-inline border-right border-bottom bg-light">
<div class="form-group label-floating">
<input type="text" placeholder="Période" class="form-control" value="Période {{$j}}" />
<input type="text" placeholder="Période" class="form-control" value="{{$periode['name']}}" />
<span class="form-control-feedback">
<i class="material-icons">clear</i>
</span>
@@ -32,28 +32,28 @@
<div class="row">
<div class="col-6">
<div class="form-group label-floating">
<input type="time" class="form-control" value="00:00" />
<input type="time" class="form-control" value="{{$periode['begin_time']}}" />
<span class="form-control-feedback"><i class="material-icons">clear</i></span>
</div>
</div>
<div class="col-6">
<div class="form-group label-floating">
<input type="time" class="form-control" value="00:00" />
<input type="time" class="form-control" value="{{$periode['end_time']}}" />
<span class="form-control-feedback"><i class="material-icons">clear</i></span>
</div>
</div>
</div>
</div>
@for($i = 1; $i <= 3; $i++)
<div id="container-{{$i}}-{{$j}}" niveau="{{$i}}" periode="{{$j}}" class="col scheduleEditor-course">
@foreach($eventType->schedule_model['niveaux'] as $niveau)
<div id="container-{{$loop->index+1}}-{{$loop->parent->index+1}}" niveau="{{$loop->index+1}}" periode="{{$loop->parent->index+1}}" class="col scheduleEditor-course">
@loaderDot
</div>
@endfor
@endforeach
<div class="col-1">
</div>
</div>
@endfor
@endforeach
<div class="row">
<div class="col-2 p-2">
<button class="btn btn-primary btn-fab btn-fab-mini btn-round">

View File

@@ -10,21 +10,100 @@
<div class="card-body ">
<form action="/admin/schedule/event/add" method="POST">
@csrf
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label for="type">Type d'événement</label>
<select class="form-control selectpicker" data-style="btn btn-link" name="type" id="type" onchange="switchType('{{$date}}')" required>
@foreach (\App\ComplementaryActivity::all() as $item)
<option value="{{$item->id}}">{{$item->name}}</option>
@endforeach
</select>
<div class="row" id="container">
<div id="accordion" class="col-12" role="tablist">
<div class="card card-collapse">
<div class="card-header" role="tab" id="headingOne">
<h5 class="mb-0">
<a data-toggle="collapse" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
<b>Information générale</b>
<i class="material-icons">keyboard_arrow_down</i>
</a>
</h5>
</div>
<div id="collapseOne" class="collapse show" role="tabpanel" aria-labelledby="headingOne" data-parent="#accordion">
<div class="row mt-3">
<div class="col-md-12">
<div class="form-group">
<label for="name">Nom de l'événement</label>
<input type="text" name="name" id="name" class="form-control" placeholder="" aria-describedby="nameHelp" required>
<small id="nameHelp" class="text-muted">Veuillez entrer le nom de l'événement</small>
</div>
</div>
<div class="col-lg-3 col-md-4">
<div class="form-group">
<label class="label-control">Date et Heure de début</label>
<input name="begin_time" type="text" id="begin_time" class="form-control datetimepicker" required/>
</div>
</div>
<div class="col-lg-3 col-md-4">
<div class="form-group">
<label class="label-control">Date et Heure de fin</label>
<input name="end_time" type="text" id="end_time" class="form-control datetimepicker" required/>
</div>
</div>
<div class="col-lg-6 col-md-4">
<div class="form-group">
<label for="name">Lieux</label>
<input type="text" name="location" id="location" class="form-control" placeholder="" aria-describedby="nameHelp" required>
<small id="nameHelp" class="text-muted">Veuillez entrer le lieu de l'événement</small>
</div>
</div>
<div class="col-md-12 mt-4">
<label class="mb-0" for="desc">Description</label>
<div class="form-group">
<textarea class="form-control richeditor" name="admin_desc" id="admin_desc" rows="6" required></textarea>
</div>
</div>
</div>
</div>
</div>
<div class="card card-collapse" id="collmessagedelasemaine">
<div class="card-header" role="tab" id="headingTwo">
<h5 class="mb-0">
<a class="collapsed" data-toggle="collapse" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
<b>Message de la semaine</b>
<i class="material-icons">keyboard_arrow_down</i>
</a>
</h5>
</div>
<div id="collapseTwo" class="collapse" role="tabpanel" aria-labelledby="headingTwo" data-parent="#accordion">
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="label-control">Date et heure de publication des messages de la semaine</label>
<input name="date_msg" type="text" id="weekly_msg_publication_time" class="form-control datetimepicker"/>
</div>
</div>
<div class="col-md-12">
<label class="mb-0" for="desc">Message de le semaine</label>
<div class="form-group">
<textarea class="form-control richeditor" name="msg" id="msg" rows="6">{{\App\Config::getData('default_weekly_msg')}}</textarea>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card card-collapse" id="collschedule">
<div class="card-header" role="tab" id="headingThree">
<h5 class="mb-0">
<a class="collapsed" data-toggle="collapse" href="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
<b>Horaire</b>
<i class="material-icons">keyboard_arrow_down</i>
</a>
</h5>
</div>
<div id="collapseThree" class="collapse" role="tabpanel" aria-labelledby="headingThree" data-parent="#accordion">
<div class="card-body" style="overflow: scroll">
<div id="scheduleEditor" class="m-3" style="width: 90vw">
@loaderDot
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row" id="container">
</div>
<button type="submit" class="btn btn-primary mt-5">Sauvegarder</button>
</form>
@@ -37,12 +116,21 @@
<h4 class="card-title">Options</h4>
</div>
<div class="card-body ">
<div class="form-group">
<label for="type">Type d'événement</label>
<small class="text-muted d-block">Choisir le type d'activité supprimera vos modification actuel</small>
<select class="form-control selectpicker" data-style="btn btn-link" name="type" id="type" onchange="loadEventType('{{$date}}')" required>
@foreach (\App\EventType::all() as $item)
<option value="{{$item->id}}">{{$item->name}}</option>
@endforeach
</select>
</div>
<div class="form-group">
<label class="m-0" for="type">Activité obligatoire</label>
<small class="text-muted d-block">L'activité est-elle obligatoire pour tout les cadets ?</small>
<div class="togglebutton">
<label>
<input type="checkbox" checked="">
<input id="is_mandatory" name="is_mandatory" type="checkbox">
<span class="toggle"></span>
L'activité est obligatoire
</label>
@@ -53,7 +141,7 @@
<small class="text-muted d-block">Inclure des messages de la semaine avec l'activité ?</small>
<div class="togglebutton">
<label>
<input id="msg_toggle" type="checkbox" checked="">
<input id="use_weekly_msg" type="checkbox" name="use_weekly_msg" onchange="switchUseWeeklyMsg()">
<span class="toggle"></span>
Avec message de la semaine
</label>
@@ -64,7 +152,7 @@
<small class="text-muted d-block">Inclure un horaire avec l'activité ?</small>
<div class="togglebutton">
<label>
<input type="checkbox" checked="" id="schedule_toggle">
<input type="checkbox" id="use_schedule" name="use_schedule" checked onchange="switchUseSchedule()">
<span class="toggle"></span>
Avec horaire
</label>
@@ -81,49 +169,9 @@
<script src="/js/plugins/schedule/editor.js"></script>
<script src="/js/plugins/autocomplete.js"></script>
<script>
switchType('{{$date}}')
$('.datetimepicker').datetimepicker({
icons: {
time: "fa fa-clock-o",
date: "fa fa-calendar",
up: "fa fa-chevron-up",
down: "fa fa-chevron-down",
previous: 'fa fa-chevron-left',
next: 'fa fa-chevron-right',
today: 'fa fa-screenshot',
clear: 'fa fa-trash',
close: 'fa fa-remove'
}
});
$('select').selectpicker();
</script>
<script>
$('#msg_toggle').change(
function () {
if($(this).is(":checked"))
{
$('#collmessagedelasemaine').removeClass('d-none');
}
else
{
$('#collmessagedelasemaine').addClass('d-none');
}
}
)
$('#schedule_toggle').change(
function () {
if($(this).is(":checked"))
{
$('#collschedule').removeClass('d-none');
}
else
{
$('#collschedule').addClass('d-none');
}
}
)
</script>
<script>
initScheduleEditor("scheduleEditor",3,4);
$(function () {
console.log('Document READY loading schedule editor');
loadEventType('{{$date}}');
})
</script>
@endsection

View File

@@ -19,8 +19,9 @@ Route::middleware('auth:api')->group(function () {
Route::get('/schedule/events/modal/full/{id}/{db_type}','ScheduleController@loadModalFull')->middleware('perm:schedule_see');
Route::get('/schedule/events/add/modal/{type}/{date}','ScheduleController@loadModalDefautType')->middleware('perm:schedule_add');
Route::get('/schedule/editor/init','ScheduleEditorController@getTemplate')->middleware('perm:schedule_edit');
Route::get('/schedule/editor/init/{id}','ScheduleEditorController@getTemplate')->middleware('perm:schedule_edit');
Route::get('/schedule/editor/course/{niveau}/{periode}','ScheduleEditorController@getCourseEmpty')->middleware('perm:schedule_edit');
Route::get('/schedule/editor/template/{id}','ScheduleEditorController@getEventTemplate')->middleware('perm:schedule_add');
Route::post('/schedule/event/delete/{id}','ScheduleController@delete')->middleware('perm:schedule_delete');
/** Booking */

View File

@@ -15,7 +15,7 @@ use Illuminate\Support\Facades\Storage;
/* Basic Auth Route */
Auth::routes();
Route::get('logout', 'Auth\LoginController@logout')->name('logout');
Route::get("/test",'OCOMController@create');
Route::get("/test/{id}",'ScheduleEditorController@getEventTemplate');
/** Public Route */