Merge branch 'trunk'
13
.env.example
|
|
@ -21,6 +21,13 @@ DB_DATABASE_2016=legaulois2016
|
|||
DB_USERNAME_2016=
|
||||
DB_PASSWORD_2016=
|
||||
|
||||
## DATABASE OPINSTA
|
||||
DB_DATABASE_OPINSTA=
|
||||
DB_USERNAME_OPINSTA=
|
||||
DB_PASSWORD_OPINSTA=
|
||||
DB_HOST_OPINSTA=
|
||||
DB_PORT_OPINSTA=
|
||||
|
||||
## MIGRATION
|
||||
MIGRATIONPAGINATION=20000
|
||||
|
||||
|
|
@ -85,3 +92,9 @@ MERCANET_ENV=
|
|||
|
||||
# BYPASS THE CRM JUST LOGIN (needs debug mode)
|
||||
NOCRM=false
|
||||
|
||||
#OP INSTA
|
||||
## Démarre le à d-m-Y 0h00
|
||||
OPINSTA_START=
|
||||
## Fin le à d-m-Y 23h59
|
||||
OPINSTA_END=
|
||||
|
|
|
|||
9
app/Exceptions/InstaApiLimitReachedException.php
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class InstaApiLimitReachedException extends Exception
|
||||
{
|
||||
}
|
||||
99
app/Http/Controllers/Fo/OpInstaController.php
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\OpInsta\InstaMedia;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class OpInstaController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show OpInsta page
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
$this->assertConfigIsValid();
|
||||
$has_started = $this->hasStarted();
|
||||
|
||||
$instaMediaList = InstaMedia::query()->orderBy('id')->get()
|
||||
->map(function (InstaMedia $media) {
|
||||
$path = \explode('/', \rtrim(\parse_url(
|
||||
$media->permalink,
|
||||
\PHP_URL_PATH
|
||||
), '/'));
|
||||
|
||||
$media->pictures = $this->fetchPicture(\collect($path)->last());
|
||||
return $media;
|
||||
});
|
||||
|
||||
return \view('front.opinsta.index', \compact('instaMediaList', 'has_started'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Assert config is valid
|
||||
*
|
||||
* @return void
|
||||
* @throws \ErrorException If config is invalid.
|
||||
*/
|
||||
private function assertConfigIsValid(): void
|
||||
{
|
||||
try {
|
||||
$start = config('opinsta.start');
|
||||
$end = config('opinsta.end');
|
||||
|
||||
Validator::validate([
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
], [
|
||||
'start' => 'date_format:d-m-Y|before:end',
|
||||
'end' => 'date_format:d-m-Y|after:start',
|
||||
]);
|
||||
} catch (ValidationException $e) {
|
||||
$message = \collect($e->errors())->map(function ($el) {
|
||||
return \collect($el)->implode(', ');
|
||||
})->implode(', ');
|
||||
throw new \ErrorException("Op install config is invalid, {$message}");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Le jeu a démaré ?
|
||||
*
|
||||
* Démarre à la date de départ (0h00) et s'arrête à la date de fin (23h59)
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function hasStarted(): bool
|
||||
{
|
||||
$start = Carbon::createFromFormat('d-m-Y', config('opinsta.start'), 'Europe/Paris')->setTime(0, 0);
|
||||
$end = Carbon::createFromFormat('d-m-Y', config('opinsta.end'), 'Europe/Paris')->setTime(0, 0);
|
||||
$now = Carbon::now('Europe/Paris')->setTime(0, 0);
|
||||
return $now->isBetween($start, $end);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch Media Picture Object
|
||||
*
|
||||
* @param string $ig_media_hash
|
||||
* @return array<integer,string[]>
|
||||
*/
|
||||
private function fetchPicture(string $ig_media_hash): array
|
||||
{
|
||||
return Cache::remember(
|
||||
"media_picture_ajax_fetch{$ig_media_hash}",
|
||||
// * 3H cache
|
||||
3 * 60 * 60,
|
||||
function () use ($ig_media_hash) {
|
||||
return InstaMedia::fetchInstagramMediaPictures($ig_media_hash);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -70,7 +70,10 @@ class SecureHeaders
|
|||
'Content-Security-Policy',
|
||||
implode(' ', $cspPolicies) . $reportUri
|
||||
);
|
||||
$response->headers->set('Feature-Policy', 'fullscreen \'self\';');
|
||||
$response->headers->set('Feature-Policy', \implode(',', [
|
||||
'fullscreen', 'accelerometer', 'encrypted-media',
|
||||
'gyroscope', 'picture-in-picture', '\'self\''
|
||||
]) . ';');
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
|
|
|||
91
app/Lib/Instagram/ApiFetcher.php
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
namespace App\Lib\Instagram;
|
||||
|
||||
use App\Exceptions\InstaApiLimitReachedException as InstaApiException;
|
||||
use Illuminate\Http\Client\HttpClientException;
|
||||
use Illuminate\Http\Client\Response;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
/**
|
||||
* Fetch Instagram Top Media List
|
||||
*
|
||||
* @package App\Lib
|
||||
*/
|
||||
class ApiFetcher
|
||||
{
|
||||
/**
|
||||
* Try to fetch media pictures from a permalink using og data.
|
||||
*
|
||||
* @param string $url
|
||||
* @return array
|
||||
* @throws \RuntimeException If a call error or a response parsing error occurs.
|
||||
*/
|
||||
public function fetchMediaPicturesFromPostPermalink(string $url): array
|
||||
{
|
||||
try {
|
||||
$response = $this->httpCall('GET', $url);
|
||||
$html = $response->body();
|
||||
$dom = new \DOMDocument();
|
||||
$dom->loadHTML($html);
|
||||
|
||||
$scripts = $dom->getElementsByTagName('script');
|
||||
return collect($scripts)->filter()->map(function (\DOMElement $script) {
|
||||
if ($script->getAttribute('type') != 'application/ld+json') {
|
||||
return null;
|
||||
}
|
||||
$entity = json_decode($script->nodeValue, true);
|
||||
if ($entity['@type'] !== 'SocialMediaPosting') {
|
||||
return null;
|
||||
}
|
||||
return \collect($entity['image'])->map(function (array $picture) {
|
||||
return $picture['url'];
|
||||
})->all();
|
||||
})->filter(function ($el) {
|
||||
return !empty($el);
|
||||
})->first() ?? [];
|
||||
} catch (\Exception $e) {
|
||||
throw new \RuntimeException($e->getMessage(), $e->getCode(), $e);
|
||||
} //end try
|
||||
}
|
||||
|
||||
/**
|
||||
* Call url and fetch result in array.
|
||||
*
|
||||
* @param string $method The HTTP VERB to use (GET, POST).
|
||||
* @param string|\Psr\Http\Message\UriInterface $uri The uri to call.
|
||||
* @param array $parameters The call parameters to pass on.
|
||||
* @return \Illuminate\Http\Client\Response
|
||||
* @throws \Error If the request method is not supported.
|
||||
* @throws \RuntimeException If something goes wrong.
|
||||
* @throws \App\Exceptions\InstaApiException If the api denies access for some reason.
|
||||
*/
|
||||
private function httpCall(
|
||||
string $method,
|
||||
$uri = '',
|
||||
array $parameters = []
|
||||
): Response {
|
||||
try {
|
||||
if (!\in_array(\strtoupper($method), ['GET', 'POST'])) {
|
||||
throw new \Error("Unsupported method {$method}");
|
||||
}
|
||||
/** @var \Illuminate\Http\Client\Response */
|
||||
$response = Http::timeout(\config('app.debug') ? 3 : 30)
|
||||
->retry(2, 100)
|
||||
->{strtolower($method)}($uri, $parameters);
|
||||
// * Throw an exception if an error occured.
|
||||
$response->throw();
|
||||
|
||||
return $response;
|
||||
} catch (HttpClientException $e) {
|
||||
/** @var \Illuminate\Http\Client\Response $response */
|
||||
if ($e instanceof \Illuminate\Http\Client\RequestException and $e->getCode() === 403) {
|
||||
$response = $e->response;
|
||||
$message = $response->json('error.message');
|
||||
$code = $response->json('error.code');
|
||||
throw new InstaApiException($message, $code, $e);
|
||||
}
|
||||
throw new \RuntimeException($e);
|
||||
} //end try
|
||||
}
|
||||
}
|
||||
50
app/Lib/Instagram/Objects/TopMedia.php
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace App\Lib\Instagram\Objects;
|
||||
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
/**
|
||||
* Top Media object
|
||||
*
|
||||
* @property integer $insta_id A unique instagram id that can be used for api calls.
|
||||
* @property string $type The instagram object type, commonly IMAGE or CAROUSEL_ALBUM.
|
||||
* @property string $username The instagram user name, scrapped using OG description.
|
||||
* @property string $caption The object text content.
|
||||
* @property string $permalink The uri where is stored the Instagram object.
|
||||
* @property \Carbon\Carbon $timestamp UTC timestamp from instagram api.
|
||||
* @property integer $comments_count The number of comments.
|
||||
* @property null|integer $like_count The number of likes.
|
||||
*
|
||||
* @package App\Lib\Instagram\Objects
|
||||
*/
|
||||
class TopMedia extends \stdClass
|
||||
{
|
||||
/**
|
||||
* Set this object data from Ig api data
|
||||
*
|
||||
* @param object $ig_media
|
||||
* @return void
|
||||
*/
|
||||
public function setData(object $ig_media): void
|
||||
{
|
||||
$this->insta_id = \intval($ig_media->id);
|
||||
$this->type = $ig_media->media_type;
|
||||
$this->permalink = $ig_media->permalink;
|
||||
$this->timestamp = Carbon::parse($ig_media->timestamp);
|
||||
$this->comments_count = \intval($ig_media->comments_count);
|
||||
$this->like_count = \optional($ig_media)->like_count ? \intval($ig_media->like_count) : null;
|
||||
$this->caption = $ig_media->caption;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set this object username
|
||||
*
|
||||
* @param string $username
|
||||
* @return void
|
||||
*/
|
||||
public function setUserName(string $username): void
|
||||
{
|
||||
$this->username = $username;
|
||||
}
|
||||
}
|
||||
91
app/Models/OpInsta/InstaMedia.php
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models\OpInsta;
|
||||
|
||||
use Illuminate\Database\Eloquent\Casts\AsStringable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* @mixin \App\Lib\Instagram\Objects\TopMedia
|
||||
*
|
||||
* @package App\Models\OpInsta
|
||||
*/
|
||||
class InstaMedia extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The connection name for the model.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
protected $connection = 'opinsta';
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $casts = [
|
||||
'caption' => AsStringable::class,
|
||||
'permalink' => AsStringable::class,
|
||||
'timestamp' => 'immutable_datetime'
|
||||
];
|
||||
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Fetch Media picture using ig media hash
|
||||
*
|
||||
* @param string $ig_media_hash
|
||||
* @return array
|
||||
* @throws \RuntimeException If a call error or a response parsing error occurs.
|
||||
*/
|
||||
public static function fetchInstagramMediaPictures(string $ig_media_hash): array
|
||||
{
|
||||
/** @var \App\Lib\Instagram\ApiFetcher */
|
||||
$igFetcherClient = \app('Instagram');
|
||||
return $igFetcherClient->fetchMediaPicturesFromPostPermalink("https://www.instagram.com/p/{$ig_media_hash}/");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch and check config elements
|
||||
*
|
||||
* @return array 'hashtag_id', 'user_id', 'media_count', 'fields'
|
||||
* @throws \RuntimeException If config is not valid.
|
||||
*/
|
||||
private static function fetchConfigParameters(): array
|
||||
{
|
||||
$hashtag_id = config('services.facebook.enpoints.ig_top_media.hashtag_id');
|
||||
$user_id = config('services.facebook.enpoints.ig_top_media.user_id');
|
||||
$media_count = config('services.facebook.enpoints.ig_top_media.media_count');
|
||||
|
||||
if (empty($hashtag_id)) {
|
||||
throw new \RuntimeException(
|
||||
'Missing services.facebook.enpoints.ig_top_media.hashtag_id,
|
||||
FACEBOOK_GRAPH_ENDPOINT_IG_TOPMEDIA_HASHTAGID'
|
||||
);
|
||||
}
|
||||
if (empty($user_id)) {
|
||||
throw new \RuntimeException(
|
||||
'Missing services.facebook.enpoints.ig_top_media.user_id,
|
||||
FACEBOOK_GRAPH_ENDPOINT_IG_TOPMEDIA_USERID'
|
||||
);
|
||||
}
|
||||
if (empty($media_count)) {
|
||||
throw new \RuntimeException(
|
||||
'Missing services.facebook.enpoints.ig_top_media.media_count,
|
||||
FACEBOOK_GRAPH_ENDPOINT_IG_TOPMEDIA_NBMEDIA'
|
||||
);
|
||||
}
|
||||
$hashtag_id = \intval($hashtag_id);
|
||||
$user_id = \intval($user_id);
|
||||
$media_count = \intval($media_count);
|
||||
return \compact(
|
||||
'hashtag_id',
|
||||
'user_id',
|
||||
'media_count'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Lib\Instagram\ApiFetcher;
|
||||
use App\Models\Actu;
|
||||
use App\Models\Articles;
|
||||
use App\Models\GeneralConfig;
|
||||
|
|
@ -82,6 +83,11 @@ class AppServiceProvider extends ServiceProvider
|
|||
Log::critical($e->getMessage());
|
||||
View::share('GeneralConfigGlobal', []);
|
||||
}
|
||||
|
||||
// * Instagram Singleton
|
||||
App::singleton('Instagram', function () {
|
||||
return new ApiFetcher();
|
||||
});
|
||||
}//end if
|
||||
|
||||
Blade::directive('svg', function ($arguments) {
|
||||
|
|
|
|||
|
|
@ -82,6 +82,26 @@ return [
|
|||
]) : [],
|
||||
],
|
||||
|
||||
'opinsta' => [
|
||||
'driver' => 'mysql',
|
||||
'url' => env('DATABASE_URL_OPINSTA'),
|
||||
'host' => env('DB_HOST_OPINSTA', '127.0.0.1'),
|
||||
'port' => env('DB_PORT_OPINSTA', '3306'),
|
||||
'database' => env('DB_DATABASE_OPINSTA', 'forge'),
|
||||
'username' => env('DB_USERNAME_OPINSTA', 'forge'),
|
||||
'password' => env('DB_PASSWORD_OPINSTA', ''),
|
||||
'unix_socket' => env('DB_SOCKET_OPINSTA', ''),
|
||||
'charset' => 'utf8mb4',
|
||||
'collation' => 'utf8mb4_unicode_ci',
|
||||
'prefix' => '',
|
||||
'prefix_indexes' => true,
|
||||
'strict' => true,
|
||||
'engine' => null,
|
||||
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
||||
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA_2016'),
|
||||
]) : [],
|
||||
],
|
||||
|
||||
'pgsql' => [
|
||||
'driver' => 'pgsql',
|
||||
'url' => env('DATABASE_URL'),
|
||||
|
|
|
|||
6
config/opinsta.php
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'start' => env('OPINSTA_START'),
|
||||
'end' => env('OPINSTA_END')
|
||||
];
|
||||
|
|
@ -38,7 +38,8 @@ return [
|
|||
'publishedProduct' => [Products::class, 'slug']
|
||||
],
|
||||
'products.range' => [
|
||||
'slugRange' => [Range::class, 'slug']
|
||||
'slugRange' => [Range::class, 'slug'],
|
||||
'slugSubRange' => [Range::class, 'slug'],
|
||||
],
|
||||
'products.consumption-times' => [
|
||||
'slugConsumptionTime' => [ConsumptionTimes::class, 'slug']
|
||||
|
|
@ -85,7 +86,7 @@ return [
|
|||
*/
|
||||
'queryConditions' => [
|
||||
'status' => true,
|
||||
'ocbStatus' => EleveurOcbStatus::yes()->value,
|
||||
'ocbStatus' => strval(EleveurOcbStatus::yes()->value),
|
||||
'star_moment' => true
|
||||
],
|
||||
|
||||
|
|
|
|||
1752
package-lock.json
generated
BIN
resources/assets/fonts/bourton/bourtonbase-webfont.woff
Normal file
BIN
resources/assets/fonts/bourton/bourtonbase-webfont.woff2
Normal file
10
resources/assets/images/entete-opinsta.svg
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="188 730.2 800 63.9" style="enable-background:new 188 730.2 800 63.9;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFF;}
|
||||
</style>
|
||||
<title>Sans titre - 1</title>
|
||||
<path class="st0" d="M188,730.2v63.9h800v-63.9C988,765.7,188,765.7,188,730.2z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 533 B |
BIN
resources/assets/images/opinsta/1.png
Normal file
|
After Width: | Height: | Size: 319 KiB |
BIN
resources/assets/images/opinsta/2.png
Normal file
|
After Width: | Height: | Size: 346 KiB |
BIN
resources/assets/images/opinsta/3.png
Normal file
|
After Width: | Height: | Size: 319 KiB |
BIN
resources/assets/images/opinsta/4.png
Normal file
|
After Width: | Height: | Size: 319 KiB |
BIN
resources/assets/images/opinsta/5.png
Normal file
|
After Width: | Height: | Size: 330 KiB |
BIN
resources/assets/images/opinsta/6.png
Normal file
|
After Width: | Height: | Size: 360 KiB |
BIN
resources/assets/images/opinsta/7.png
Normal file
|
After Width: | Height: | Size: 357 KiB |
BIN
resources/assets/images/opinsta/FOND-GAGANTS-1-5-mobile.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
resources/assets/images/opinsta/FOND-GAGANTS-1-5.png
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
resources/assets/images/opinsta/FOND-GAGANTS-6-10-mobile.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
resources/assets/images/opinsta/FOND-HEADER-mobile.png
Normal file
|
After Width: | Height: | Size: 8.7 KiB |
BIN
resources/assets/images/opinsta/assiette.png
Normal file
|
After Width: | Height: | Size: 326 KiB |
3
resources/assets/images/opinsta/lauriers.svg
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
resources/assets/images/opinsta/no_picture.jpg
Normal file
|
After Width: | Height: | Size: 17 KiB |
7
resources/sass/_variables.scss
vendored
|
|
@ -64,6 +64,13 @@ $vegetalBodyBG: #8dd175;
|
|||
$vegetalTitle: #64ab4b;
|
||||
$pmuColor: #003b22;
|
||||
|
||||
// OP Insta
|
||||
$opinsta-yellow: #ffb504;
|
||||
$opinsta-red: #d02e27;
|
||||
$opinsta-font-color: #4B3236;
|
||||
$opinsta-bg-brown: #4B3236;
|
||||
$opinsta-bg-beige: #f3ebe4;
|
||||
|
||||
// on s'engage
|
||||
$engagementDarkerGreen: #082014;
|
||||
$engagementDarkGreen: #006633;
|
||||
|
|
|
|||
6
resources/sass/front/_body.scss
vendored
|
|
@ -18,12 +18,16 @@ html {
|
|||
@media print {
|
||||
justify-content: normal;
|
||||
}
|
||||
}
|
||||
|
||||
&.white-bg {
|
||||
background-color: $white;
|
||||
}
|
||||
|
||||
&.real-white-bg {
|
||||
background-color: #FFF;
|
||||
}
|
||||
}
|
||||
|
||||
.quote {
|
||||
font-family: 'CreamyScriptRegular';
|
||||
color: $color5;
|
||||
|
|
|
|||
72
resources/sass/front/_sub_header.scss
vendored
|
|
@ -839,6 +839,78 @@
|
|||
}
|
||||
}
|
||||
|
||||
.sub_header_opinsta {
|
||||
width: 100%;
|
||||
height: 36em;
|
||||
background-image: url("~@/images/opinsta/FOND-HEADER-mobile.png");
|
||||
background-color: #FFF;
|
||||
|
||||
.title {
|
||||
font-size: 1rem;
|
||||
margin-top: 7rem;
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
|
||||
h1 {
|
||||
color: #FFF;
|
||||
text-align: center;
|
||||
font-family: "bourton";
|
||||
// 33px
|
||||
font-size: 2.2rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #FFF;
|
||||
text-align: center;
|
||||
font-family: "bakerie";
|
||||
// 30px
|
||||
font-size: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
@include min-width($tablet) {
|
||||
height: 37em;
|
||||
margin-top: 3rem;
|
||||
background-color: $opinsta-yellow;
|
||||
background-image: inherit;
|
||||
|
||||
&::after {
|
||||
background-image: url("~@/images/entete-opinsta.svg");
|
||||
}
|
||||
|
||||
.title {
|
||||
position: absolute;
|
||||
right: 14%;
|
||||
transform: translateX(14%);
|
||||
width: 50%;
|
||||
h1 {
|
||||
// 45px
|
||||
font-size: 3rem;
|
||||
}
|
||||
h2 {
|
||||
// 35px
|
||||
font-size: 2.333rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include min-width($desktop) {
|
||||
height: 50em;
|
||||
|
||||
.title {
|
||||
top: 1rem;
|
||||
h1 {
|
||||
// 60px
|
||||
font-size: 4rem;
|
||||
}
|
||||
h2 {
|
||||
// 50px
|
||||
font-size: 3.333rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sub_header_mention {
|
||||
background-image: url("~@/images/faq/faq_background.jpg");
|
||||
width: 100%;
|
||||
|
|
|
|||
17
resources/sass/front/pages/opinsta/_fonts.scss
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
$font-path: '~@/fonts';
|
||||
|
||||
@font-face {
|
||||
font-family: 'bourton';
|
||||
src: url('#{$font-path}/bourton/bourtonbase-webfont.woff2') format('woff2'),
|
||||
url('#{$font-path}/bourton/bourtonbase-webfont.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'bakerie';
|
||||
src: url('#{$font-path}/bakerie/adam_ladd_-_bakerie_smooth_bold-webfont.woff2') format('woff2'),
|
||||
url('#{$font-path}/bakerie/adam_ladd_-_bakerie_smooth_bold-webfont.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
629
resources/sass/front/pages/opinsta/_index.scss
vendored
Normal file
|
|
@ -0,0 +1,629 @@
|
|||
|
||||
@use "sass:list";
|
||||
@use "sass:math";
|
||||
@use "sass:color";
|
||||
@import "./fonts";
|
||||
|
||||
.content.opinsta {
|
||||
background-color: #FFF;
|
||||
color: $opinsta-font-color;
|
||||
max-width: inherit !important;
|
||||
|
||||
a {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
p,span,a {
|
||||
color: $opinsta-font-color;
|
||||
}
|
||||
}
|
||||
|
||||
.content.opinsta.index {
|
||||
overflow: hidden;
|
||||
@include min-width(1200px) {
|
||||
overflow: inherit;
|
||||
}
|
||||
|
||||
@keyframes defilement {
|
||||
0% { margin-left: 0; }
|
||||
100% { margin-left: -100%; }
|
||||
}
|
||||
|
||||
@keyframes defilement2 {
|
||||
0% { margin-left: 100%; }
|
||||
100% { margin-left: 0%; }
|
||||
}
|
||||
|
||||
.messagedefilant {
|
||||
display: block;
|
||||
margin: 2.666rem 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
max-width: 64.666rem;
|
||||
height: 3rem;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
@include min-width ($mobile) {
|
||||
height: 4rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
position: absolute;
|
||||
min-width: 100%;
|
||||
|
||||
// @include min-width ($mobile) {
|
||||
// text-align: center;
|
||||
// }
|
||||
|
||||
span,
|
||||
&:after {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
font-size: 2.666rem;
|
||||
white-space: nowrap;
|
||||
top:0;
|
||||
@include min-width ($mobile) {
|
||||
font-size: 4rem;
|
||||
}
|
||||
}
|
||||
span {
|
||||
animation: defilement 10s infinite linear;
|
||||
// @include min-width ($mobile) {
|
||||
// animation: none;
|
||||
// }
|
||||
}
|
||||
&::after {
|
||||
position: absolute;
|
||||
top:0; left:0;
|
||||
content:attr(data-text);
|
||||
animation: defilement2 10s infinite linear;
|
||||
// @include min-width ($mobile) {
|
||||
// animation: none;
|
||||
// display: none;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
%opinsta-btn {
|
||||
padding: 0.6rem 1rem;
|
||||
color: #fff;
|
||||
background-color: $opinsta-bg-brown;
|
||||
font-size: 1.2rem;
|
||||
line-height: 1.614rem;
|
||||
font-family: 'bourton';
|
||||
text-transform: uppercase;
|
||||
|
||||
@include min-width ($tablet) {
|
||||
font-size: 2rem;
|
||||
line-height: 2.69rem;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 0.2rem solid $primary-color;
|
||||
}
|
||||
&:hover, &.active {
|
||||
color: $opinsta-bg-brown;
|
||||
background-color: #FFF;
|
||||
&:focus {
|
||||
outline: 0.2rem solid $primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
%opinsta-position {
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
border-radius: 3rem;
|
||||
background-color: #d02e27;
|
||||
color: #FFF;
|
||||
top: -2rem;
|
||||
left: -2rem;
|
||||
font-size: 1rem;
|
||||
font-weight: bold;
|
||||
font-family: 'bourton';
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
$opinsta-positions: (
|
||||
1: "er",
|
||||
2: "e",
|
||||
3: "e",
|
||||
4: "e",
|
||||
5: "e",
|
||||
6: "e",
|
||||
7: "e",
|
||||
8: "e",
|
||||
9: "e",
|
||||
10: "e",
|
||||
);
|
||||
$opinsta-positions-sizes: (
|
||||
2.8,
|
||||
2.2,
|
||||
1.9,
|
||||
1.9,
|
||||
1.9,
|
||||
1.9,
|
||||
1.9,
|
||||
1.9,
|
||||
1.9,
|
||||
1.9,
|
||||
1.9
|
||||
);
|
||||
$opinsta-positions-colors: (
|
||||
#d02e27,
|
||||
#1482e0,
|
||||
#ffb504,
|
||||
#4b3236,
|
||||
#155993,
|
||||
#8eb8e9,
|
||||
#76b658,
|
||||
#9cc9ab,
|
||||
#ee7c28,
|
||||
#ac283d,
|
||||
);
|
||||
|
||||
.winner-card {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
|
||||
a {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
width: 20.666rem;
|
||||
height: 20.666rem + 2rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.position {
|
||||
@extend %opinsta-position;
|
||||
}
|
||||
.picture {
|
||||
object-fit: cover;
|
||||
}
|
||||
@each $idx, $ext in $opinsta-positions {
|
||||
$position-size: list.nth($opinsta-positions-sizes, $idx);
|
||||
.picture-#{$idx} {
|
||||
max-width: (20.666rem * $position-size / 2);
|
||||
width: 100%;
|
||||
max-height: (20.666rem * $position-size / 2);
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
.username {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
font-family: "bourton";
|
||||
font-size: 2rem;
|
||||
line-height: 2.333rem;
|
||||
word-break: break-all;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
@each $idx, $ext in $opinsta-positions {
|
||||
$position-color: list.nth($opinsta-positions-colors, $idx);
|
||||
$position-size: list.nth($opinsta-positions-sizes, $idx);
|
||||
|
||||
&-#{$idx} {
|
||||
width: 20.666rem * $position-size / 2;
|
||||
height: (20.666rem + 2rem) * $position-size / 2;
|
||||
margin-top: 1.4rem * $idx !important;
|
||||
}
|
||||
|
||||
.position-#{$idx} {
|
||||
background-color: $position-color;
|
||||
font-size: (1.6rem * $position-size / 1.2);
|
||||
width: (4rem * $position-size / 1.8);
|
||||
height: (4rem * $position-size / 1.8);
|
||||
border-radius: (3rem * $position-size / 2);
|
||||
padding-top: (0.6rem * $position-size / 2);
|
||||
padding-right: (0.8rem * $position-size / 2);
|
||||
&::after {
|
||||
content: '#{$ext}';
|
||||
top: 0.6rem;
|
||||
position: absolute;
|
||||
font-size: (0.8rem * $position-size / 1.8);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
.username-#{$idx} {
|
||||
color: $position-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#opinsta-ytbe {
|
||||
/** ratio 315px x 560px */
|
||||
position: relative;
|
||||
width: 83vw;
|
||||
height: 149vw;
|
||||
max-width: 21.4rem;
|
||||
max-height: 38.2rem;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
@include min-width($tablet) {
|
||||
position: absolute;
|
||||
top: 9rem;
|
||||
left: 8%;
|
||||
transform: translateX(-8%);
|
||||
z-index: 50;
|
||||
// 261px
|
||||
width: 17.4rem;
|
||||
// 465px
|
||||
height: 31rem;
|
||||
}
|
||||
@include min-width($desktop) {
|
||||
// 315px
|
||||
width: 21rem;
|
||||
// 560px
|
||||
height: 37.333rem;
|
||||
}
|
||||
}
|
||||
|
||||
.opinsta-btn {
|
||||
@extend %opinsta-btn;
|
||||
}
|
||||
.opinsta-btn-yellow {
|
||||
@extend %opinsta-btn;
|
||||
background-color: $opinsta-yellow;
|
||||
&:hover, &.active {
|
||||
color: $opinsta-yellow;
|
||||
background-color: #FFF;
|
||||
}
|
||||
}
|
||||
|
||||
.text-yellow {
|
||||
color: $opinsta-yellow;
|
||||
}
|
||||
|
||||
.section-white {
|
||||
background-color: #FFF;
|
||||
color: $opinsta-font-color;
|
||||
margin-top: 1rem;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
|
||||
.title-container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.title {
|
||||
position: relative;
|
||||
font-size: 1rem;
|
||||
margin-top: 5rem;
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
|
||||
.big-year {
|
||||
position: absolute;
|
||||
top: -3rem;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) rotateZ(-12deg);
|
||||
background-color: $opinsta-red;
|
||||
padding: 0.4rem 0.6rem;
|
||||
font-family: "bourton";
|
||||
font-size: 1.36rem;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
h2 {
|
||||
text-align: center;
|
||||
font-family: "bourton";
|
||||
// 26px
|
||||
font-size: 1.73333rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
@include min-width($desktop) {
|
||||
h2 {
|
||||
// 33.5px
|
||||
font-size: 2.23333rem;
|
||||
}
|
||||
}
|
||||
|
||||
@include min-width($tablet) {
|
||||
position: relative;
|
||||
right: 14%;
|
||||
transform: translateX(14%);
|
||||
width: 50vw;
|
||||
h2 {
|
||||
// 45px
|
||||
font-size: 3rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.participate {
|
||||
margin: 4rem;
|
||||
|
||||
ul, p, span {
|
||||
font-family: "Catamaran-Regular";
|
||||
font-size: 1rem;
|
||||
line-height: 1.3rem;
|
||||
|
||||
@include min-width ($tablet) {
|
||||
font-size: 2rem;
|
||||
line-height: 2.6rem;
|
||||
}
|
||||
}
|
||||
h2 {
|
||||
text-align: center;
|
||||
color: $opinsta-yellow;
|
||||
// 25px
|
||||
font-size: 1.666rem;
|
||||
font-family: 'bourton';
|
||||
margin-bottom: 2rem;
|
||||
|
||||
@include min-width ($tablet) {
|
||||
font-size: 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ul li {
|
||||
list-style-type: none;
|
||||
|
||||
&::before {
|
||||
content: "\2022";
|
||||
color: $opinsta-yellow;
|
||||
font-weight: bold;
|
||||
display: inline-block;
|
||||
width: 0.8rem;
|
||||
margin-left: -0.8rem;
|
||||
font-size: 1.4rem;
|
||||
|
||||
@include min-width ($tablet) {
|
||||
width: 1.2rem;
|
||||
margin-left: -1.2rem;
|
||||
font-size: 2.4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.opinsta-btn {
|
||||
display: inline-block;
|
||||
margin-top: 4rem;
|
||||
margin-bottom: 3rem;
|
||||
left: 50%;
|
||||
position: relative;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.section-beige {
|
||||
background-color: $opinsta-bg-beige;
|
||||
padding-top: 1rem;
|
||||
|
||||
&.top {
|
||||
background-image: url("~@/images/opinsta/FOND-GAGANTS-1-5-mobile.png");
|
||||
background-position-y: top;
|
||||
background-position-x: center;
|
||||
background-size: 100% auto;
|
||||
background-repeat: no-repeat;
|
||||
background-color: inherit;
|
||||
min-height: 3rem;
|
||||
|
||||
@include min-width($tablet) {
|
||||
min-height: 8rem;
|
||||
}
|
||||
}
|
||||
|
||||
.couscous-plate {
|
||||
float: right;
|
||||
width: 17rem;
|
||||
object-fit: contain;
|
||||
margin-top: -12rem;
|
||||
margin-right: -7rem;
|
||||
|
||||
@include min-width($tablet) {
|
||||
margin-right: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.closed-event {
|
||||
height: 11rem;
|
||||
padding-top: 3rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 6rem;
|
||||
padding-bottom: 3rem;
|
||||
line-height: 5rem;
|
||||
span {
|
||||
font-family: bourton;
|
||||
font-size: 3rem;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.messagedefilant {
|
||||
top: 7rem;
|
||||
max-width: 60rem;
|
||||
|
||||
h2 {
|
||||
height: 2.666rem;
|
||||
span {
|
||||
font-size: 2.666rem;
|
||||
}
|
||||
@include min-width ($tablet) {
|
||||
height: 4rem;
|
||||
span {
|
||||
font-size: 4rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
margin-top: 14rem;
|
||||
padding-bottom: 6rem;
|
||||
|
||||
.winner-part-1 {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
|
||||
.winner-card {
|
||||
margin: 3rem;
|
||||
// FORCE USERNAME TO BE WHITE
|
||||
.username {
|
||||
color: $opinsta-font-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.section-brown {
|
||||
position: relative;
|
||||
background-color: $opinsta-bg-brown;
|
||||
|
||||
&.bottom {
|
||||
background-image: url("~@/images/opinsta/FOND-GAGANTS-6-10-mobile.png");
|
||||
background-position-y: bottom;
|
||||
background-position-x: center;
|
||||
background-size: 100% auto;
|
||||
background-repeat: no-repeat;
|
||||
background-color: inherit;
|
||||
min-height: 3rem;
|
||||
|
||||
@include min-width($tablet) {
|
||||
min-height: 8rem;
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
padding-top: 3rem;
|
||||
|
||||
.winner-part-2 {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
|
||||
.winner-card {
|
||||
margin: 2rem;
|
||||
margin-top: 2rem !important;
|
||||
margin-bottom: 6rem !important;
|
||||
}
|
||||
}
|
||||
|
||||
div {
|
||||
text-align: center;
|
||||
margin-top: 4rem;
|
||||
padding-bottom: 4rem;
|
||||
}
|
||||
|
||||
.bravo span {
|
||||
color: #FFF;
|
||||
font-family: "bourton";
|
||||
font-size: 4rem;
|
||||
& span {
|
||||
font-family: "bakerie";
|
||||
font-size: 2.666rem;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
.section-closed {
|
||||
padding-bottom: 6rem;
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
padding-top: 3rem;
|
||||
padding-left: 1.5rem;
|
||||
padding-right: 1.5rem;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@include min-width($tablet) {
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-family: "bourton";
|
||||
font-size: 4rem;
|
||||
line-height: 4.4rem;
|
||||
@include min-width($tablet) {
|
||||
font-size: 2,666rem;
|
||||
line-height: 3.253rem;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
font-family: "bourton";
|
||||
font-size: 1.666rem;
|
||||
line-height: 1.953rem;
|
||||
@include min-width($tablet) {
|
||||
font-size: 1.066rem;
|
||||
line-height: 1.25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@function randomNum($min, $max) {
|
||||
$rand: math.random();
|
||||
$randomNum: $min + math.floor($rand * (($max - $min) + 1));
|
||||
@return $randomNum;
|
||||
}
|
||||
|
||||
.picture-list-scroll {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding: 5rem 3rem;
|
||||
flex-direction: row;
|
||||
overflow-x: auto;
|
||||
|
||||
img {
|
||||
object-fit: contain;
|
||||
margin: 1rem auto;
|
||||
width: 80%;
|
||||
height: auto;
|
||||
max-height: 19.8rem;
|
||||
min-width: 13rem;
|
||||
|
||||
@include min-width($tablet) {
|
||||
width: 20vw;
|
||||
min-width: 19.8rem;
|
||||
max-width: 27.866rem;
|
||||
margin: 1rem;
|
||||
}
|
||||
|
||||
@for $i from 1 through 50 {
|
||||
&:nth-child(#{$i}) {
|
||||
transform: rotateZ(randomNum(-40deg, 0deg) + randomNum(0deg, 40deg) + randomNum(-25deg, 25deg) * math.random());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
resources/sass/main.scss
vendored
|
|
@ -95,3 +95,4 @@
|
|||
@import "front/pages/onsengage/bloc5";
|
||||
|
||||
@import "front/pages/opbrcharcut/all";
|
||||
@import "front/pages/opinsta/index";
|
||||
|
|
|
|||
156
resources/views/front/opinsta/index.blade.php
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
@extends('layouts.app')
|
||||
@section('title', __('Grand jeu concours #legauloisettoi'))
|
||||
@section('description', __('Grand jeu concours #legauloisettoi'))
|
||||
|
||||
@section('sub_header')
|
||||
<div class="sub_header sub_header_opinsta">
|
||||
<div class="title">
|
||||
<h1>{{ __('Grand jeu concours #legauloisettoi') }}</h1>
|
||||
<h2>{{ __('Résultat concours') }}</h2>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('bg-color', 'real-white-bg')
|
||||
|
||||
@section('content')
|
||||
<div class="content opinsta index">
|
||||
{{-- SECTION BLANCHE --}}
|
||||
<section class="section-white">
|
||||
<div class="title-container">
|
||||
<div class="title">
|
||||
@mobile()
|
||||
<h2>
|
||||
<span class="big-year">{{ __('1 an') }}</span>
|
||||
{{ __(" de produits Le Gaulois d'une valeur de 200€ à gagner !") }}
|
||||
</h2>
|
||||
@else
|
||||
<h2>
|
||||
{{ __('Participez à notre challenge') }}
|
||||
<span class="text-yellow">#legauloisettoi</span>
|
||||
{{ __("et tentez de remporter un an de produits Le Gaulois !") }}
|
||||
</h2>
|
||||
<span class="big-year">{{ __('1 an') }}</span>
|
||||
@endmobile()
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<iframe id="opinsta-ytbe" class="video youtube" src="{{ route('front.frame', ['type' => 'youtube']) }}" data-src=" https://www.youtube.com/embed/vQz8xzUfhsg" data-authorize="0" frameBorder="0" allow="fullscreen; accelerometer; encrypted-media; gyroscope; picture-in-picture" width="315px" height="560px">
|
||||
</iframe>
|
||||
|
||||
{{-- https://youtube.com/shorts/vQz8xzUfhsg?feature=share --}}
|
||||
|
||||
<div class="participate">
|
||||
<h2>{{ __('Pour participer :') }}</h2>
|
||||
<ul>
|
||||
<li>{{
|
||||
__('Réalisez votre recette préférée à l’aide d’un produit Charcuterie Le Gaulois.')
|
||||
}}</li>
|
||||
<li>{{
|
||||
__('Postez la photo sur votre compte Instagram en utilisant le #LeGauloisEtToi.')
|
||||
}}</li>
|
||||
<li>{{
|
||||
__('Cinq gagnants seront sélectionnés et remporteront l’équivalent de 200€
|
||||
de produits Le Gaulois sous forme de bons de réductions allant de 1,50€
|
||||
à 3€ et valables sur tous les produits de la marque !')
|
||||
}}</li>
|
||||
</ul>
|
||||
<p>{{
|
||||
__('Afin de permettre votre participation à ce jeu concours, assurez-vous que votre
|
||||
compte Instagram soit en public pour que votre post gourmand soit visible par
|
||||
tout le monde ! Les 5 posts les plus populaires gagneront ce grand jeu concours ! Alors, prêt à
|
||||
relever le défi en élaborant votre plus belle création gourmande avec les
|
||||
produits de la gamme Charcuterie Le Gaulois ?')
|
||||
}}</p>
|
||||
<a href="{{ route('le-gaulois-et-toi.rules') }}" class="opinsta-btn">
|
||||
@mobile()
|
||||
{{ __('Plus d’informations') }}
|
||||
@else
|
||||
{{ __('Plus d’informations dans le règlement du jeu concours.') }}
|
||||
@endmobile()
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{-- SECTION BEIGE --}}
|
||||
<section class="section-beige top"> </section>
|
||||
<section class="section-beige">
|
||||
|
||||
<img class="couscous-plate" src="{{ asset('assets/images/opinsta/assiette.png') }}" alt="{{ __('Une assiette de couscous.') }}">
|
||||
|
||||
@if(!$has_started)
|
||||
<div class="closed-event">
|
||||
<span>{{ __('Revenez bientôt pour suivre le classement de notre Concours') }}</span>
|
||||
</div>
|
||||
|
||||
@else
|
||||
|
||||
{{-- BANDEROLLE --}}
|
||||
<div class="messagedefilant">
|
||||
<h2 data-text="{{ __('Résultats du concours #legauloisettoi') }}"><span>{{ __('Résultats du concours #legauloisettoi') }} <img src="{{ asset('assets/images/opinsta/lauriers.svg') }}" alt="{{ __('Courone de lauriers') }}"> </span></h2>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
|
||||
@if($instaMediaList->count())
|
||||
{{-- GAGNANTS --}}
|
||||
<div class="winner-part-1">
|
||||
@foreach ($instaMediaList->take(5) as $index => $instaMedia)
|
||||
@include('front.opinsta.winner-card', compact('index', 'instaMedia'))
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@endif
|
||||
</section>
|
||||
|
||||
@if($has_started and $instaMediaList->count())
|
||||
|
||||
{{-- SECTION BRUNE --}}
|
||||
<section class="section-brown">
|
||||
|
||||
<div class="container">
|
||||
|
||||
@if($instaMediaList->count() > 5)
|
||||
|
||||
{{-- GAGNANTS PART 2 --}}
|
||||
<div class="winner-part-2">
|
||||
@foreach ($instaMediaList->take(- ($instaMediaList->count() - 5)) as $index => $instaMedia)
|
||||
@include('front.opinsta.winner-card', compact('index', 'instaMedia'))
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
@endif
|
||||
|
||||
<div>
|
||||
<a class="opinsta-btn opinsta-btn-yellow" href="https://www.instagram.com/explore/tags/legauloisettoi/" target="_blank">{{ __('Voir toutes les participations') }}</a>
|
||||
</div>
|
||||
|
||||
<div class="bravo">
|
||||
<span>{{ __('Bravo à tous') }}<br><span>{{ __('les participants !') }}</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="section-brown bottom"> </section>
|
||||
|
||||
@endif
|
||||
|
||||
{{-- SECTION SUIVEZ NOUS --}}
|
||||
<section class="section-closed">
|
||||
|
||||
<div class="container">
|
||||
<h2>{{ __('Suivez-nous') }}</h2>
|
||||
<a href="{{ __('https://www.instagram.com/legaulois_officiel/?hl=fr') }}">@legaulois_officiel</a>
|
||||
</div>
|
||||
|
||||
<div class="picture-list-scroll">
|
||||
@for ($i = 1; $i
|
||||
<= 7; $i++) <img src="{{ asset('assets/images/opinsta/'. $i .'.png') }}" alt="{{ __('OP Insta') }}" />
|
||||
@endfor
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
@endsection
|
||||
166
resources/views/front/opinsta/rules.blade.php
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
@extends('layouts.app')
|
||||
@section('title', __('Règlement du jeu CHALLENGE #LEGAULOISETTOI'))
|
||||
@section('description', __('Règlement du jeu CHALLENGE #LEGAULOISETTOI'))
|
||||
|
||||
@section('sub_header')
|
||||
<div class="sub_header sub_header_mention">
|
||||
<div class="title">
|
||||
<h1>{{ __('Règlement du jeu CHALLENGE #LEGAULOISETTOI') }}</h1>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="content legals">
|
||||
<section>
|
||||
<h3>Article 1 – Organisateur du Jeu</h3>
|
||||
<p>
|
||||
La société LDC SABLE, dont le siège social est situé Zone Industrielle Saint-Laurent, SABLE-SUR-SARTHE (72300), immatriculée au RCS du MANS sous le numéro 444 502 025, (ci-après la « <b>Société Organisatrice</b> ») organise un jeu avec obligation d’achat intitulé « #LeGauloisEtToi » du 1er mai 2023 au 25 juin 2023 minuit (ci-après le « <b>Jeu</b> »).
|
||||
<br><br>
|
||||
Il est précisé, conformément aux conditions générales d’utilisation du réseau social Instagram, plateforme sur laquelle est organisée le Jeu, qu’Instagram n’est pas responsable de l’opération, et que celui-ci n’est ni géré, ni sponsorisé par ce dernier.
|
||||
</p>
|
||||
<h3>Article 2 – Annonce du Jeu</h3>
|
||||
<p>
|
||||
Le Jeu est annoncé sur les produits Charcuterie de la marque Le Gaulois porteurs de l’opération (ci-après le/les « <b>Produit(s)</b> ») et sur le site internet de la marque www.legaulois.fr/le-gaulois-et-toi (ci-après le « <b>Site Internet</b> »).
|
||||
</p>
|
||||
<h3>Article 3 – Acceptation du Règlement</h3>
|
||||
<p>
|
||||
Le fait de participer à ce Jeu implique l’acceptation sans réserve du présent règlement (ci-après le « <b>Règlement</b> ») et donc des modalités de déroulement du Jeu.
|
||||
<br><br>
|
||||
La participation au Jeu implique également l’autorisation du Participant à l’égard de la Société Organisatrice d’utiliser et de reproduire le contenu ainsi réalisé dans le cadre du Jeu et publié sur le compte personnel Instagram du Participant pour toute la durée du Jeu et jusqu’à 6 mois après la fin du Jeu.
|
||||
</p>
|
||||
<h3>Article 4 – Dépôt & obtention du Règlement</h3>
|
||||
<p>
|
||||
Le Règlement est déposé et peut être obtenu à la SARL HERBETTE – BOUQUET, huissier de justice, 3 rue Legagneux – BP 70123 – 85501 Les Herbiers Cedex (ci-après l’« <b>Huissier</b> »). Il est également accessible sur le Site Internet.
|
||||
</p>
|
||||
<h3>Article 5 – Conditions de participation <br>Chaque participant doit respecter l’esprit du Jeu et son règlement.</h3>
|
||||
<p>
|
||||
Le Jeu, est ouvert à toute personne physique résidant en France métropolitaine, Corse comprise (ci-après désigné le « <b>Participant</b> » ou les « <b>Participants</b> »).
|
||||
<br><br>
|
||||
Sont exclus de toute participation :
|
||||
</p>
|
||||
<ul>
|
||||
<li>- les salariés de la Société Organisatrice ;</li>
|
||||
<li>- les membres de l’étude d’Huissier auprès de laquelle le Règlement est déposé ;</li>
|
||||
<li>- de façon générale, toutes les personnes ayant participé directement ou indirectement à l’élaboration du Jeu (notamment gestionnaires de contrôle et sous-traitants) ; et</li>
|
||||
<li>- pour chacune des catégories de personnes susvisées, les membres de leur famille en ligne directe, ainsi que les personnes vivant sous le même toit.</li>
|
||||
</ul>
|
||||
<p>
|
||||
<br><br>
|
||||
Pour participer au Jeu, <b>il est nécessaire d’avoir acheté un Produit Charcuterie de la marque Le Gaulois</b> disponible au rayon Charcuterie Libre-Service de votre magasin. Le Participant devra également disposer d’un accès Internet, d’une adresse email, d’un numéro de téléphone, d’une adresse postale valide et d’un compte public sur le réseau social Instagram.
|
||||
<br><br>
|
||||
La participation est strictement nominative : le Participant ne peut en aucun cas jouer sous plusieurs pseudonymes, avec plusieurs adresses emails et comptes Instagram et ce, quel que soit le nombre d’adresses électroniques et de comptes Instagram dont il dispose ou pour le compte d’autres Participants ou personnes. Aucun autre moyen de participation, notamment par courrier, par Facebook ou tout autre réseau social, ne sera pris en compte.
|
||||
</p>
|
||||
<h3>Article 6 – Modalités de participation</h3>
|
||||
<p>
|
||||
Pour participer au Jeu, il suffit de :
|
||||
</p>
|
||||
<ul>
|
||||
<li>- Acheter en magasin un Produit Charcuterie de la marque Le Gaulois entre 1er mai 2023 et le 25 juin 2023 </li>
|
||||
<li>- Réaliser une recette à l’aide du Produit Charcuterie de la marque Le Gaulois</li>
|
||||
<li>- Prendre une photo de ladite recette et la publier sur son compte personnel Instagram en mentionnant le hashtag #LeGauloisEtToi entre le 1er mai 2023 et le 25 juin 2023 (ci-après « la Publication »). Toute participation doit être finalisée et validée avant le 25 juin 2023 à 23h59, heure de Paris.</li>
|
||||
<li>- Les cinq Participants dont la publication aura obtenu été les plus populaires remporteront l’équivalent de 200 euros de produits Le Gaulois sous forme de bons de réductions à utiliser avant le 01/06/2024 allant de 1,50 euros à 3 euros et valables sur tous les produits de la marque.</li>
|
||||
</ul>
|
||||
<p>
|
||||
<br>
|
||||
Le classement présent sur le site internet legaulois.fr/le-gaulois-et-toi est réalisé tous les jours sur la base de l’algorithme dont seul Instagram connait les caractéristiques (la récupération des posts fait appel à l’API Graph Instagram où La popularité est déterminée par un mélange de vues et d’interaction parmi les utilisateurs à l’aide de la même méthodologie que celle qui détermine les meilleures publications lors de la recherche de hashtag sur www.instagram.com).
|
||||
<br><br>
|
||||
Afin que sa participation soit prise en compte, le compte Instagram du Participant devra être public durant la durée du Jeu.<br>
|
||||
En publiant sur son compte personnel Instagram une photo de la recette avec le hashtag #LeGauloisEtToi, le Participant autorise la Société Organisatrice à reproduire et diffuser la Publication sur le site internet du Jeu www.legaulois.fr/le-gaulois-et-toi pour toute la durée du Jeu et jusqu’à 6 mois après la fin du Jeu.
|
||||
<br><br>
|
||||
Le caractère public du compte personnel Instagram du Participant ainsi que l’autorisation d’utiliser et reproduire la Publication sur le site internet du Jeu par la Société Organisatrice sont obligatoires pour que la Société Organisatrice puisse considérer la participation du Participant et l’informer de son gain d’une dotation dans le cadre du Jeu. Dans l’hypothèse où le Participant n’a pas rendu son compte Instagram public ou s’oppose à toute utilisation de la Publication sur le site du Jeu, la Société Organisatrice ne sera pas tenue d’attribuer la dotation et pourra donc remettre en jeu la dotation dans le cadre du Jeu.
|
||||
<br><br>
|
||||
Les frais de participation et de connexion restent à la charge du Participant.
|
||||
<br><br>
|
||||
De manière générale, tout comportement abusif ayant pour conséquence une dénaturation du principe même du Jeu (méthodes, combines, manœuvres permettant de supprimer l’effet de hasard, méthode permettant de booster les interactions sur la Publication par exemple…), toute tentative de fraude ou de tricherie de la part d’un Participant entraînera la nullité de toutes ses participations tel que décrit à l’article « Cas de fraude ou suspicion de fraude ».
|
||||
<br><br>
|
||||
En participant au Jeu, les Participants s’engagent à respecter les conditions générales d’utilisation du réseau social Instagram, et notamment de ne pas tenir de propos illicites (notamment à caractère violent, raciste, diffamatoire, injurieux, mensongers, érotiques, pornographiques, homophobe, transphobe et politiques), auquel cas la Société Organisatrice se réserve le droit d’exclure le Participant du Jeu.
|
||||
<br><br>
|
||||
Pour respecter l’esprit du Jeu et donner à tous les Participants la possibilité de gagner, chaque Participant ne pourra gagner au maximum qu’une seule dotation.
|
||||
</p>
|
||||
<h3>Article 7 – Mode de désignation des Gagnants</h3>
|
||||
<p>
|
||||
Les gagnants du Jeu seront désignés en fonction de la popularité de la Publication du Participant sur le réseau social Instagram, se basant sur un mélange de vues et d’interactions parmi les utilisateurs.
|
||||
<br><br>
|
||||
<b>En cas de fraude ou de suspicion de fraude décrit à l’article « Cas de fraude ou suspicion de fraude », la Société Organisatrice se réserve le droit d’attribuer la dotation au Participant suivant : selon le classement des publications été les plus populaires.</b>
|
||||
</p>
|
||||
<h3>Article 8 – Description des dotations</h3>
|
||||
<p>
|
||||
Sont mis en jeu :
|
||||
<br><br>
|
||||
200 euros de produits de la marque Le Gaulois sous forme de plusieurs bons de réduction d’une valeur comprise entre 1,50€ à 3,00€ (valeur correspondant au prix moyen TTC des produits selon les éléments et données consommateurs relevés par Kantar ces 3 dernières années).
|
||||
<br><br>
|
||||
La valeur indiquée correspond au prix public TTC couramment pratiqué ou estimé à la date de rédaction du présent règlement. Elle est donnée à titre indicatif et peut subir des variations.<br>
|
||||
Les visuels présents sur les différents supports de communication sont non contractuels et peuvent donc présenter des différences avec la réalité.
|
||||
</p>
|
||||
<h3>Article 9 – Remise et acceptation des dotations</h3>
|
||||
<p>
|
||||
Les Gagnants seront contactés sur la messagerie d’Instagram ou par email à la fin du Jeu pour que leurs soient indiquées les modalités d’obtention de leurs dotations. Les Gagnants seront annoncés sur le site internet du Jeu www.legaulois.fr/le-gaulois-et-toi le 26/06/2023 et toute interaction intervenue sur une Publication après la fin du Jeu ne seront pas prises en compte.<br>
|
||||
La Société Organisatrice n’est pas responsable en cas de fourniture de données incomplètes ou en cas de suppression ou de perte d’email ou de messages, ou en cas de dysfonctionnement des réseaux sociaux concernés.
|
||||
<br><br>
|
||||
En cas de renoncement au lot gagné, il n’y a pas de possibilité d’avoir un autre lot.
|
||||
<br><br>
|
||||
La Société Organisatrice se réserve le droit de modifier la nature du gain gagné et de le remplacer par un gain d’une valeur équivalente notamment si des circonstances indépendantes de sa volonté l’exigent.
|
||||
<br><br>
|
||||
Dans l’hypothèse où pour une raison indépendante de la volonté de la Société Organisatrice, le Gagnant ne pouvait se voir remettre sa dotation, cette dernière sera définitivement perdue et pourra être réattribuée à la discrétion de la Société Organisatrice à un autre Participant. Dans cette hypothèse, aucune indemnité de quelque nature que ce soit ne sera due au Gagnant.
|
||||
<br><br>
|
||||
En cas d’impossibilité de contacter le Gagnant, la Société Organisatrice se réserve le droit d’attribuer la dotation correspondante à un autre Participant.
|
||||
<br><br>
|
||||
Les dotations ne pourront donner lieu à aucune contestation, ni à la remise de leur contre-valeur en numéraire totale ou partielle, ni à leur échange ou remplacement.
|
||||
<br><br>
|
||||
Le cas échéant, les frais de déplacement, d’assurance, de transport, etc., inhérents à la jouissance du lot mais non expressément prévus dans les dotations resteront à la charge du Gagnant.
|
||||
</p>
|
||||
<h3>Article 10 – Responsabilité</h3>
|
||||
<p>
|
||||
S’agissant des dotations, la Société Organisatrice ne pourra en aucun cas être tenue responsable des retards, pertes, avaries, manque de lisibilité des cachets, du fait des services postaux, intervenues lors de la livraison des dotations.<br>
|
||||
Également, la responsabilité de la Société Organisatrice est strictement limitée à la délivrance des dotations effectivement et valablement gagnées. La Société Organisatrice n’endosse aucune responsabilité contractuelle relative au bon fonctionnement, à l’emploi, à la sécurité ou à la conformité aux normes auxquelles les dotations sont éventuellement soumises.
|
||||
<br><br>
|
||||
Il est précisé que la Société Organisatrice ne fournira aucune prestation et ni garantie, les gains consistant uniquement en la remise des dotations prévues ci-dessus.<br>
|
||||
La Société Organisatrice se dégage de toute responsabilité relative à une éventuelle insatisfaction des Gagnants concernant leur dotation.
|
||||
</p>
|
||||
<h3>Article 11 – Annulation & Modification du Jeu</h3>
|
||||
<p>
|
||||
La Société Organisatrice ne saurait être tenue responsable si, en cas de force majeure ou d’événements indépendants de sa volonté, elle était amenée à annuler le Jeu, à le réduire, à le prolonger, à le différer ou à le modifier. Les informations relatives à la suppression ou à la modification du Jeu seront dans l’affirmative indiquées directement sur le Site Internet et feront l’objet d’un avenant au présent règlement.
|
||||
</p>
|
||||
<h3>Article 12 – Vérification d’identité</h3>
|
||||
<p>
|
||||
<b>Les Participants autorisent toutes vérifications concernant leur identité et leur domicile.</b> Toute indication d’identité et/ou de coordonnées (adresse postale, e-mail, numéro de téléphone, etc.) erronées entraînent l’annulation de la participation ainsi que la perte immédiate des gains le cas échéant. A ce titre, la Société Organisatrice se réserve le droit de demander une copie de la pièce d’identité des Participants à tout moment, dans la mesure où il est rappelé, conformément à l’article 5 du présent Règlement, qu’aucune personne mineure ni aucun salarié de la Société Organisatrice ne pourra participer ou prétendre aux dotations mises en jeu dans le cadre des présentes. La Société Organisatrice se réserve le droit de procéder à toute vérification utile pour assurer le respect de cette règle. Toute personne ne remplissant pas ces conditions ou refusant de les justifier sera exclue du Jeu et ne pourra, en cas de gain, bénéficier de son lot.
|
||||
</p>
|
||||
<h3>Article 13 – Protection des données personnelles</h3>
|
||||
<p>
|
||||
La participation à ce Jeu donne lieu à l’établissement d’un fichier automatisé. Les données personnelles du Participant sont recueillies par et pour le compte de la Société Organisatrice, responsable de traitement, dans le but de gérer la participation au Jeu, permettre la mise en œuvre du tirage par instant gagnant et assurer la communication promotionnelle du Jeu, des activités de la marque et de ses nouveaux produits. Ces informations sont destinées au service marketing de la Société Organisatrice. Les données seront conservées pendant une durée de trois ans à compter de la fin du Jeu.
|
||||
<br><br>
|
||||
Conformément à la réglementation applicable, chaque Participant dispose d’un droit d’accès ; d’un droit de rectification ; d’un droit de limitation du traitement de ses données ; d’un droit d’effacement de ses données ; d’un droit d’opposition au traitement de ses données, à la prospection ou pour motif légitime ; d’un droit à la portabilité de ses données ; d’un droit de définir des directives relatives à la conservation, l’effacement ou la communication de ses données, applicables après son décès ; d’un droit de retirer son consentement. Le Participant peut exercer les droits listés ci-dessus sur simple demande à l’adresse postale indiquée à l’article « Organisateur du jeu » ou à l’adresse url suivante : <a href="https://www.ldc.fr/rgpd/consommateurs/" target="_blank">https://www.ldc.fr/rgpd/consommateurs/</a> . Le Participant est en droit d’introduire une réclamation auprès de la CNIL.
|
||||
<br><br>
|
||||
La collecte des données personnelles des Participants est obligatoire pour participer au Jeu. Par conséquent, les personnes qui exerceront leur droit de suppression des données les concernant avant la fin du Jeu seront réputées renoncer à leur participation dans la mesure où l’acheminement des gains sera rendu impossible.
|
||||
</p>
|
||||
<h3>Article 14 – Réseau Internet</h3>
|
||||
<p>
|
||||
La participation au Jeu implique la connaissance et l’acceptation des caractéristiques et limites du réseau internet. En ce sens, la Société Organisatrice ne pourra être tenue responsable, notamment, des dysfonctionnements pouvant affecter le réseau internet, pour tout problème de configuration ou lié à un navigateur donné.<br>
|
||||
La connexion de toute personne au Site Internet et la participation au Jeu se font sous l’entière et exclusive responsabilité des Participants.<br>
|
||||
La Société Organisatrice rappelle aux Participants les caractéristiques et les limites du réseau internet et décline toute responsabilité liée aux conséquences de la connexion des Participants à ce réseau via le Site Internet.<br>
|
||||
Plus particulièrement, la Société Organisatrice ne saurait être tenue responsable de tout dommage, matériel ou immatériel causé aux Participants, à leurs équipements informatiques et aux données qui y sont stockées et aux conséquences pouvant en découler sur leur activité personnelle, professionnelle ou commerciale qui résulterait de quelque manière que ce soit d’une connexion au Site Internet.<br>
|
||||
La Société Organisatrice ne saurait davantage être tenue responsable au cas où un ou plusieurs Participants ne pourraient parvenir à se connecter sur le Site Internet du fait de tout défaut technique ou de problème lié notamment à l’encombrement du réseau.
|
||||
</p>
|
||||
<h3>Article 15 – Cas de fraude ou suspicion de fraude</h3>
|
||||
<p>
|
||||
Il appartient aux Participants de s’assurer que les coordonnées transmises à la Société Organisatrice lors de la prise de contact en cas de gain sont correctes. Il ne sera admis aucune réclamation si le Participant a indiqué des coordonnées incomplètes, incorrectes, fausses. <br>
|
||||
Il est entendu que tout autre mode de participation que celui visé à l’article « Modalités de participation » est exclu. <br>
|
||||
<b>Toute participation incomplète et/ou non conforme aux conditions énoncées dans le Règlement ne sera pas prise en compte et sera par conséquent considérée comme nulle.</b>
|
||||
<br><br>
|
||||
Les adresses IP de connexion et d'utilisation sont enregistrées et vérifiées. Tout compte ouvert avec une adresse email jetable sera bloqué et supprimé sans préavis.<br>
|
||||
La Société Organisatrice pourra suspendre et annuler la participation d’un ou plusieurs Participants(s) en cas de constatation d'un comportement suspect qui peut être, sans que cela soit exhaustif : la mise en place d’un système de réponses automatisé, la mise en place d’une méthode permettant de multiplier les interactions sur la Publication, un rythme de gains inhabituel, une tentative de forcer les serveurs des organisateurs, une multiplication de comptes, l’utilisation de comptes personnels Instagram multiples, etc.<br>
|
||||
<b>Il est rappelé que la Société Organisatrice se réserve le droit de procéder à toute vérification d’identité du Participant (conformément aux dispositions de l’article « Vérification d’identité »).</b>
|
||||
<br><br>
|
||||
La Société Organisatrice est l’unique décisionnaire de l’exclusion ou de la réintégration des Participants concernés au regard des informations en sa possession. En cas de sanction ou de réclamation, il convient aux Participants d’apporter la preuve qu'ils ont adopté un comportement conforme au présent règlement. La responsabilité de la Société Organisatrice ne pourra être engagée à ce titre.<br>
|
||||
Afin de sauvegarder les mêmes chances à tous les Participants du Jeu, la Société Organisatrice se réserve le droit de ne pas attribuer la dotation au fraudeur. Dans ce cas, la Société Organisatrice se réserve le droit d’attribuer cette dotation au Participant suivant dans le classement suivant les publications ayant été les plus populaires.
|
||||
<br><br>
|
||||
La Société Organisatrice pourra annuler tout ou partie du Jeu s'il apparaît que des fraudes sont intervenues sous quelque forme que ce soit, notamment de manière informatique.
|
||||
</p>
|
||||
<h3>Article 16 – Loi applicable</h3>
|
||||
<p>
|
||||
Le Jeu ainsi que le Règlement sont soumis à la loi française. La Société Organisatrice sera seule souveraine pour trancher toute question d’application du Règlement ou en cas de lacune de celui-ci. A défaut de parvenir à un accord amiable en cas de contestation relative aux conditions d’interprétation et/ou d’application du présent règlement, les litiges qui en découleraient seraient soumis à l’appréciation des tribunaux compétents dans les conditions de droit commun.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
@endsection
|
||||
7
resources/views/front/opinsta/winner-card.blade.php
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<div class="winner-card winner-card-{{ $index + 1 }}">
|
||||
<a href="{{ $instaMedia->permalink }}" target="_blank" title="{{ __('Voir le post instagram de :author', ['author' => $instaMedia->username]) }}">
|
||||
<span class="position position-{{ $index + 1 }}">{{ $index + 1 }}</span>
|
||||
<img class="picture picture-{{ $index + 1 }}" src="{{ collect($instaMedia->pictures)->first() }}" alt="{{ __('Image instagram') }}">
|
||||
<span class="username username-{{ $index + 1 }}">{{ "@{$instaMedia->username}" }}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -14,6 +14,7 @@ use App\Http\Controllers\DansLesPresController;
|
|||
use App\Http\Controllers\EngagementsController;
|
||||
use App\Http\Controllers\OpBrCharcut\EnterCodeController;
|
||||
use App\Http\Controllers\FaqController;
|
||||
use App\Http\Controllers\Fo\OpInstaController;
|
||||
use App\Http\Controllers\HomeController;
|
||||
use App\Http\Controllers\KitchenSideController;
|
||||
use App\Http\Controllers\MapController;
|
||||
|
|
@ -333,3 +334,9 @@ Route::prefix('/mon-compte')
|
|||
|
||||
Route::get('/boncharcuterie', [EnterCodeController::class, 'index'])->name('opbrcharcut.saisir-code');
|
||||
Route::post('/boncharcuterie', [EnterCodeController::class, 'participate'])->name('opbrcharcut.participate');
|
||||
|
||||
|
||||
Route::prefix('/le-gaulois-et-toi')->name('le-gaulois-et-toi.')->group(function () {
|
||||
Route::get('/', [OpInstaController::class, 'index'])->name('index');
|
||||
Route::view('/reglement', 'front.opinsta.rules')->name('rules');
|
||||
});
|
||||
|
|
|
|||
5
webpack.mix.js
vendored
|
|
@ -19,6 +19,11 @@ mix.webpackConfig({
|
|||
]
|
||||
})
|
||||
],
|
||||
// Pour debug compilation errors
|
||||
// stats: {
|
||||
// children: true,
|
||||
// warningsFilter: [/\-\-underline\-color/],
|
||||
// },
|
||||
});
|
||||
|
||||
let assetDir = 'assets';
|
||||
|
|
|
|||