public static function fullToolbar(): array
{
return [
- [ 'header' => [2, 3, false] ],
+ [ 'header' => [3, 4, false] ],
'link',
'bold',
'italic',
--- /dev/null
+<?php
+
+
+namespace App\Helpers;
+
+
+class StreamingPlatforms
+{
+ /**
+ * @param $url
+ * @return string|null
+ */
+ public static function youtubeEmbed($url): ?string
+ {
+ $video_id = null;
+ if (preg_match('%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/\s]{11})%i', $url, $match)) {
+ $video_id = $match[1];
+ return "https://www.youtube-nocookie.com/embed/$video_id";
+ }
+ return null;
+ }
+
+}
public function show($slug, LaboArticleRepository $repository)
{
-
$actu = $repository->forSlug($slug);
-
\View::share('actu', $actu);
return view('actu-labos.show');
}
namespace App\Http\Controllers;
use App\Models\AdCampaign;
+use App\Repositories\AdCampaignRepository;
use Illuminate\Http\Request;
class AdCampaignController extends Controller
/**
* @return \Illuminate\View\View
- * @todo : Always last 3 ?
*
*/
public function index()
->orderByDesc('id')
->take(3)
->published()
+ ->visible()
->get();
\View::share('campaigns', $campaigns);
return view('com-campaigns.index');
}
+ public function show($slug, AdCampaignRepository $repository)
+ {
+ $campaign = $repository->forSlug($slug);
+ \View::share('campaign', $campaign);
+
+ return view('com-campaigns.show');
+
+ }
+
+
}
class AdCampaignController extends ModuleController
{
protected $moduleName = 'adCampaigns';
+
+ protected $indexOptions = [
+// 'reorder' => true
+ ];
}
+
+
public function index()
{
- \View::share('podcast', Podcast::published()->orderByDesc('id')->first());
+ \View::share('podcast', Podcast::published()->visible()->orderByDesc('id')->first());
return view('podcasts.index');
}
}
namespace App\Models;
+use A17\Twill\Models\Behaviors\HasBlocks;
use A17\Twill\Models\Behaviors\HasSlug;
use A17\Twill\Models\Behaviors\HasMedias;
use A17\Twill\Models\Behaviors\HasPosition;
use A17\Twill\Models\Model;
use Laravel\Scout\Searchable;
+/**
+ * Class AdCampaign
+ * @package App\Models
+ * @property string $url
+ */
class AdCampaign extends Model implements Sortable
{
- use HasSlug, HasMedias, HasPosition;
+ use HasSlug, HasMedias, HasPosition, HasBlocks;
use Searchable;
protected $fillable = [
'title',
'description',
'position',
- 'url',
'publish_start_date',
'publish_end_date',
'organization'
];
public $appends = [
- 'image'
+ 'image',
+ 'url'
];
public $slugAttributes = [
{
return $this->image('image', 'preview');
}
+
+
+ /**
+ * @return string
+ */
+ public function getUrlAttribute(): string
+ {
+ return route('com-campaign.show', ['slug' => $this->slug]) ?? '#';
+ }
}
* Class LaboArticle
* @package App\Models
* @property string $content
- * @property string $link
+ * @property string $url
* @property string $preview
*/
class LaboArticle extends Model implements Sortable
/**
* @return string
*/
- public function getLinkAttribute(): string
+ public function getUrlAttribute(): string
{
return route('actus-labos.show', ['slug' => $this->slug]);
}
class Podcast extends Model
{
- use HasSlug, HasMedias, HasFiles, HasBlocks;
+ use HasSlug, HasMedias, HasFiles;
protected $fillable = [
'published',
namespace App\Repositories;
+use A17\Twill\Repositories\Behaviors\HandleBlocks;
use A17\Twill\Repositories\Behaviors\HandleSlugs;
use A17\Twill\Repositories\Behaviors\HandleMedias;
use A17\Twill\Repositories\ModuleRepository;
class AdCampaignRepository extends ModuleRepository
{
- use HandleSlugs, HandleMedias;
+ use HandleSlugs, HandleMedias, HandleBlocks;
public function __construct(AdCampaign $model)
{
class PodcastRepository extends ModuleRepository
{
- use HandleSlugs, HandleMedias, HandleFiles, HandleBlocks, HandleRepeaters;
+ use HandleSlugs, HandleMedias, HandleFiles, HandleBlocks;
public function __construct(Podcast $model)
'title' => 'Invité',
'icon' => 'image',
'component' => 'a17-block-guest'
+ ],
+ 'youtube' => [
+ 'title' => 'Vidéo YouTube',
+ 'icon' => 'video',
+ 'component' => 'a17-block-youtube'
]
],
'crops' => [
],
],
+ 'content' => [
+ 'default' => [
+ [
+ 'name' => 'default',
+ 'ratio' => 0
+ ]
+
+ ]
+ ],
+
'image' => [
'desktop' => [
[
--- /dev/null
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+class DropUrlColFromAdCampaigns extends Migration
+{
+ /**
+ * Run the migrations.
+ *
+ * @return void
+ */
+ public function up()
+ {
+ Schema::table('ad_campaigns', function (Blueprint $table) {
+ $table->dropColumn('url');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('ad_campaigns', function (Blueprint $table) {
+ $table->string('url')->nullable();
+ });
+ }
+}
//
//
//
+//
+//
/* harmony default export */ __webpack_exports__["default"] = ({
name: "CampaignHit",
props: ['hit', 'flip']
return _vm.hit
? _c("div", { staticClass: "box p-1" }, [
_c("div", [
- _c(
- "h3",
- [
- _vm.hit._highlightResult === undefined
- ? _c("span", { domProps: { innerHTML: _vm._s(_vm.hit.title) } })
- : _vm._e(),
- _vm._v(" "),
- _c("ais-highlight", {
- attrs: { attribute: "title", hit: _vm.hit }
- })
- ],
- 1
- )
+ _c("a", { attrs: { href: _vm.hit.url } }, [
+ _c(
+ "h3",
+ [
+ _vm.hit._highlightResult === undefined
+ ? _c("span", {
+ domProps: { innerHTML: _vm._s(_vm.hit.title) }
+ })
+ : _vm._e(),
+ _vm._v(" "),
+ _c("ais-highlight", {
+ attrs: { attribute: "title", hit: _vm.hit }
+ })
+ ],
+ 1
+ )
+ ])
]),
_vm._v(" "),
- _c("div", { staticClass: "row" }, [
- _c("div", { class: { "col-sm-6": true, "order-2": _vm.flip } }, [
- _c("img", {
- staticClass: "w-100",
- attrs: { src: _vm.hit.image, alt: "" }
- })
- ]),
+ _c("div", [
+ _c("img", {
+ class: {
+ "mw-40 mx-1": true,
+ "float-left": !_vm.flip,
+ "float-right": _vm.flip
+ },
+ attrs: { src: _vm.hit.image, alt: "" }
+ }),
_vm._v(" "),
- _c("div", { class: { "col-sm-6": true, "order-1": _vm.flip } }, [
- _c("div", {
- staticClass: "pb-2",
- domProps: { innerHTML: _vm._s(_vm.hit.description) }
- }),
- _vm._v(" "),
- _c(
- "a",
- {
- class: {
- "click-here": true,
- "bottom-right": !_vm.flip,
- "bottom-left": _vm.flip
- },
- attrs: { href: _vm.hit.url, target: "_blank" }
+ _c("div", {
+ staticClass: "pb-2",
+ domProps: { innerHTML: _vm._s(_vm.hit.description) }
+ }),
+ _vm._v(" "),
+ _c(
+ "a",
+ {
+ class: {
+ "click-here": true,
+ "bottom-right": !_vm.flip,
+ "bottom-left": _vm.flip
},
- [_vm._v("Lire ici")]
- )
- ])
+ attrs: { href: _vm.hit.url }
+ },
+ [_vm._v("Lire ici")]
+ )
])
])
: _vm._e()
font-family: "Avenir Next Demi", sans-serif;
}
+div.youtube-block iframe {
+ display: block;
+ margin: 1rem auto;
+ max-width: 100%;
+}
+
body {
margin-bottom: 4rem;
}
div.pill-box div {
box-shadow: 0 2px 0 rgba(90, 97, 105, 0.11), 0 4px 8px rgba(90, 97, 105, 0.12), 0 10px 10px rgba(90, 97, 105, 0.06), 0 7px 70px rgba(90, 97, 105, 0.1);
background-color: white;
+ overflow: hidden;
+ position: relative;
}
.header-logo {
.click-here.bottom-left,
div.pill-box div > a.bottom-left {
- left: 25px;
+ left: 10px;
position: absolute;
bottom: 0;
}
.click-here.bottom-right,
div.pill-box div > a.bottom-right {
- right: 25px;
+ right: 10px;
position: absolute;
bottom: 0;
}
color: white !important;
}
-article > .content {
+article h2 {
+ font-size: 22px;
+ text-align: center;
+}
+
+article .content {
max-width: 800px;
font-size: larger;
margin: auto;
color: inherit !important;
}
+.block-img {
+ max-width: 100%;
+ max-height: 350px;
+ display: block;
+ margin: auto;
+}
+
+.mw-40 {
+ max-width: 40%;
+}
+
//
//
//
+//
+//
/* harmony default export */ __webpack_exports__["default"] = ({
name: "CampaignHit",
props: ['hit', 'flip']
return _vm.hit
? _c("div", { staticClass: "box p-1" }, [
_c("div", [
- _c(
- "h3",
- [
- _vm.hit._highlightResult === undefined
- ? _c("span", { domProps: { innerHTML: _vm._s(_vm.hit.title) } })
- : _vm._e(),
- _vm._v(" "),
- _c("ais-highlight", {
- attrs: { attribute: "title", hit: _vm.hit }
- })
- ],
- 1
- )
+ _c("a", { attrs: { href: _vm.hit.url } }, [
+ _c(
+ "h3",
+ [
+ _vm.hit._highlightResult === undefined
+ ? _c("span", {
+ domProps: { innerHTML: _vm._s(_vm.hit.title) }
+ })
+ : _vm._e(),
+ _vm._v(" "),
+ _c("ais-highlight", {
+ attrs: { attribute: "title", hit: _vm.hit }
+ })
+ ],
+ 1
+ )
+ ])
]),
_vm._v(" "),
- _c("div", { staticClass: "row" }, [
- _c("div", { class: { "col-sm-6": true, "order-2": _vm.flip } }, [
- _c("img", {
- staticClass: "w-100",
- attrs: { src: _vm.hit.image, alt: "" }
- })
- ]),
+ _c("div", [
+ _c("img", {
+ class: {
+ "mw-40 mx-1": true,
+ "float-left": !_vm.flip,
+ "float-right": _vm.flip
+ },
+ attrs: { src: _vm.hit.image, alt: "" }
+ }),
_vm._v(" "),
- _c("div", { class: { "col-sm-6": true, "order-1": _vm.flip } }, [
- _c("div", {
- staticClass: "pb-2",
- domProps: { innerHTML: _vm._s(_vm.hit.description) }
- }),
- _vm._v(" "),
- _c(
- "a",
- {
- class: {
- "click-here": true,
- "bottom-right": !_vm.flip,
- "bottom-left": _vm.flip
- },
- attrs: { href: _vm.hit.url, target: "_blank" }
+ _c("div", {
+ staticClass: "pb-2",
+ domProps: { innerHTML: _vm._s(_vm.hit.description) }
+ }),
+ _vm._v(" "),
+ _c(
+ "a",
+ {
+ class: {
+ "click-here": true,
+ "bottom-right": !_vm.flip,
+ "bottom-left": _vm.flip
},
- [_vm._v("Lire ici")]
- )
- ])
+ attrs: { href: _vm.hit.url }
+ },
+ [_vm._v("Lire ici")]
+ )
])
])
: _vm._e()
<div class="box p-1" v-if="hit">
<div>
+ <a :href="hit.url">
<h3>
<span v-if="hit._highlightResult === undefined" v-html="hit.title"></span>
<ais-highlight attribute="title" :hit="hit" />
</h3>
+ </a>
</div>
- <div class="row">
- <div :class="{'col-sm-6': true, 'order-2' : flip}">
- <img class="w-100" :src="hit.image" alt="">
- </div>
- <div :class="{'col-sm-6': true, 'order-1' : flip}">
- <div v-html="hit.description" class="pb-2"></div>
- <a :href="hit.url" target="_blank" :class="{'click-here': true, 'bottom-right': !flip, 'bottom-left': flip}">Lire ici</a>
- </div>
+ <div>
+
+ <img :class="{'mw-40 mx-1': true, 'float-left': !flip, 'float-right': flip} " :src="hit.image" alt="">
+
+ <div v-html="hit.description" class="pb-2"></div>
+ <a :href="hit.url" :class="{'click-here': true, 'bottom-right': !flip, 'bottom-left': flip}">Lire ici</a>
+
+
</div>
</div>
--- /dev/null
+//YOUTUBE
+
+div.youtube-block {
+ iframe {
+ display: block;
+ margin: 1rem auto;
+ max-width: 100%;
+ }
+
+}
@import "covers";
@import "pill_boxes";
@import "title_dots";
+@import "blocks";
body {
margin-bottom: 4rem;
0 10px 10px rgba(90, 97, 105, 0.06),
0 7px 70px rgba(90, 97, 105, 0.1);
background-color: white;
+ overflow: hidden;
+ position: relative;
}
.header-logo {
&.bottom {
&-left {
- left:25px;
+ left:10px;
position: absolute;
bottom: 0;
}
&-right {
- right:25px;
+ right:10px;
position: absolute;
bottom: 0;
}
}
article {
- > .content {
+ h2 {
+ font-size: 22px;
+ text-align: center;
+
+ }
+ .content {
max-width: 800px;
font-size: larger;
margin: auto;
}
}
+
+.block-img {
+ max-width: 100%;
+ max-height: 350px;
+ display: block;
+ margin: auto;
+}
+
+.mw-40{
+ max-width: 40%;
+}
<div class="col-sm-6 mb-3">
@component('components.simple-preview', ['actu' => $actus->shift()])
@endcomponent
- <x-pill-box class="mb-3" slug="actu-labos-3"></x-pill-box>
+ <x-pill-box class="mt-3" slug="actu-labos-3"></x-pill-box>
</div>
@section('content')
<div class="container psq-labos">
<x-back></x-back>
- <h1>{{$actu->title}}</h1>
+ <h1>L'actu des labos</h1>
- <article>
- <img src="{{$actu->image('image')}}" class="top-img" alt="">
- <p class="chapo">{{$actu->chapo}}</p>
- <div class="content">
- {!! $actu->content !!}
+ <article class="row">
+ <div class="col-sm-4">
+ <img src="{{$actu->image('image')}}" class="top-img mb-4" alt="">
+ <x-pill-box slug="article-actu-labos"></x-pill-box>
</div>
+
+ <div class="col-sm-8">
+ <h2>{{$actu->title}}</h2>
+ <div class="chapo">{{$actu->chapo}}</div>
+ <div class="content">
+ {!! $actu->content !!}
+ </div>
+
+ </div>
+
</article>
'label' => 'Description',
'maxlength' => 400
])
- @formField('input', [
- 'name' => 'url',
- 'label' => 'Lien',
- 'maxlength' => 255
- ])
+
@formField('medias', [
'name' => 'image',
'label' => 'Image',
])
+ @formField('block_editor', ['blocks' => ['image', 'text', 'youtube']])
@stop
--- /dev/null
+
+@formField('medias', [
+ 'name' => 'content', // role
+ 'label' => 'Image',
+ 'withVideoUrl' => false,
+ 'translated' => false,
+])
+
--- /dev/null
+@formField('input', [
+ 'name' => 'url',
+ 'label' => 'URL',
+ 'maxlength' => 250,
+ 'translated' => false,
+])
<div class="row">
<div class="col-md-8 mb-4">
- <campaign-hit :hit='@json($campaigns->pop())'></campaign-hit>
+ <campaign-hit :hit='@json($campaigns->shift())'></campaign-hit>
</div>
<div class="col-md-4 mb-4">
<x-pill-box slug="campagnes-et-com-1">
</x-pill-box>
</div>
<div class="col-md-8 mb-4">
- <campaign-hit :hit='@json($campaigns->pop())' :flip="true"></campaign-hit>
+ <campaign-hit :hit='@json($campaigns->shift())' :flip="true"></campaign-hit>
</div>
</div>
<div class="row">
<div class="col-md-12">
- <campaign-hit :hit='@json($campaigns->pop())'></campaign-hit>
+ <campaign-hit :hit='@json($campaigns->shift())'></campaign-hit>
</div>
</div>
--- /dev/null
+@extends('layouts.app')
+
+@section('content')
+
+ <article class="container psq-com-campaign">
+ <x-back></x-back>
+
+ <h1>MARKETING & COM : LES CAMPAGNES DE LA SEMAINE</h1>
+
+ <div class="content">
+ <h2>{{$campaign->title}}</h2>
+ <div class="chapo">
+ {!! $campaign->description !!}
+ </div>
+ {!! $campaign->renderBlocks() !!}
+ </div>
+
+ </article>
+
+@endsection
@if($actu)
<div class="box p-2">
<div class="row simple-preview">
+ <div class="col-12">
+ <a href="{{$actu->url}}">
+ <h2>{{$actu->title}}</h2>
+ </a>
+ </div>
<div class="col-4">
<img src="{{$actu->image('image')}}" alt="" class="w-100">
</div>
<div class="col-8">
- <a href="{{$actu->link}}">
- <h2>{{$actu->title}}</h2>
- </a>
<p class="chapo ">{{$actu->chapo}}</p>
{{ $actu->preview }}
- <a href="{{$actu->link}}" class="click-here">Lire la suite</a>
+ <a href="{{$actu->url}}" class="click-here">Lire la suite</a>
</div>
</div>
--- /dev/null
+<img src="{{$block->image('content', 'default')}}" alt="" class="block-img">
--- /dev/null
+@php
+$url = \App\Helpers\StreamingPlatforms::youtubeEmbed($block->input('url'));
+@endphp
+<div class="youtube-block">
+ @if($url === null)
+ <p class="text-danger">URL Invalide !</p>
+ @else
+ <iframe width="560" height="315" src="{{$url}}" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
+ @endif
+</div>
+
Route::get('search', 'FileController@search')->name('archives');
- Route::get('campagnes-et-communication', 'AdCampaignController@index');
- Route::get('campagnes-et-communication/archives', 'AdCampaignController@search');
+ Route::prefix('campagnes-et-communication')->group(function() {
+ Route::get('/', 'AdCampaignController@index')->name('com-campaign.index');
+ Route::get('archives', 'AdCampaignController@search')->name('com-campaign.search');
+ Route::get('{slug}', 'AdCampaignController@show')->name('com-campaign.show');
+ });
Route::get('podcasts', 'PodcastController@index');