Improve Bourse And responsive

This commit is contained in:
Jérémy Munsch 2021-03-21 14:14:41 +01:00
parent 638bb8671e
commit c8f63e65af
20 changed files with 648 additions and 91 deletions

View file

@ -16,6 +16,7 @@ class BourseController extends Controller
{
public function bourse()
{
ClubController::getNotifications();
/** @var \App\Models\Customers */
$customer = Auth::guard('customer')->user();
/** @var \Illuminate\Database\Eloquent\Collection */
@ -30,17 +31,18 @@ class BourseController extends Controller
{
/** @var \App\Models\Customers */
$user = Auth::guard('customer')->user();
$departaimants = $user->departaimantsCollections()
/** @var \App\Models\DepartaimantsCollection $departaimant */
$departaimant = $user->departaimantsCollections()
->where('type', $type->value)->firstOrFail();
$depStatus = DepartaimantStatus::make((int)$request->state);
$departaimants->set(
$departaimant->set(
forward_static_call([$request->maps[$type->value], 'make'], $request->id),
$depStatus
);
$departaimants->saveOrFail();
$departaimant->saveOrFail();
return response()->json([
'status' => 'OK',
@ -100,7 +102,9 @@ class BourseController extends Controller
$dep->status->equals($status)
// Filter results with Departaimant
and (strlen($departaimant) ? strpos(
strtolower(Utils::replaceSpecChar(str_replace(['-', ' ', '\''], '', $dep->departaimant->label))),
strtolower(Utils::replaceSpecChar(
str_replace(['-', ' ', '\''], '', $dep->departaimant->label)
)),
$departaimant
) !== false : true)
// Filter results with customer Departaimants

View file

@ -29,6 +29,7 @@ class BoutiqueController extends Controller
{
public function index()
{
ClubController::getNotifications();
$sellItems = SellItem::all();
return view('front.club.boutique.boutique', compact('sellItems'));
}

View file

@ -24,7 +24,7 @@ class ClubController extends Controller
{
public function index(ArticlesCategories $category)
{
$this->getNotifications();
self::getNotifications();
$reductions = Reductions::where([
['end_date_broadcast', '>', now()],
['status', 1]
@ -56,7 +56,7 @@ class ClubController extends Controller
public function infos()
{
$this->getNotifications();
self::getNotifications();
$customer = Auth::guard('customer')->user();
if (!$customer) {
abort(404);
@ -115,7 +115,7 @@ class ClubController extends Controller
/** @var \App\Models\Customers */
$customer = Auth::guard('customer')->user();
$customer->readNotifications()->sync($notificationsIds);
$this->getNotifications();
self::getNotifications();
return view('front.club.notifications');
}
@ -124,7 +124,7 @@ class ClubController extends Controller
*/
public function cart()
{
$this->getNotifications();
self::getNotifications();
$products = Auth::guard('customer')->user()->products;
return view('front.club.cart', compact('products'));
}
@ -134,7 +134,7 @@ class ClubController extends Controller
*/
public function favoritesRecipes()
{
$this->getNotifications();
self::getNotifications();
$recipes = Auth::guard('customer')->user()->recipes;
return view('front.club.favorites-recipes', compact('recipes'));
}
@ -144,7 +144,7 @@ class ClubController extends Controller
*/
public function reductions()
{
$this->getNotifications();
self::getNotifications();
// TODO: get url from MesBr class
/** @var \App\Lib\MesBR */
$mesBR = app('mesBr');
@ -160,7 +160,7 @@ class ClubController extends Controller
*/
public function article(Articles $publishedArticle)
{
$this->getNotifications();
self::getNotifications();
// Check si le customer connecté a déjà répondu
$alreadyAnswered = false;
if (Auth::guard('customer')->check()) {
@ -213,7 +213,7 @@ class ClubController extends Controller
public function messages()
{
$this->getNotifications();
self::getNotifications();
/** @var \App\Models\Customers */
$customer = Auth::guard('customer')->user();
$conversations = $customer->conversations();
@ -299,7 +299,7 @@ class ClubController extends Controller
return response()->json($blockCustomer);
}
private function getNotifications()
public static function getNotifications()
{
if (!Auth::guard('customer')->check()) {
return;

View file

@ -307,7 +307,7 @@ class DepartaimantsCollection extends Model
*/
public static function depField(DepartaimantCollectionType $depColtype, Departaimant $dep): int
{
$fieldCols = floor(8 * 8 / self::$departementWidth); // bigInt = 8 * 8 octets
$fieldCols = self::getTableColumnWith();
$totalFieldCols = self::$tableFields * $fieldCols;
$depsPerField = floor($totalFieldCols / self::$tableFields);
return (int)floor((array_search(

View file

@ -17,6 +17,7 @@
"cross-env": "^7.0",
"del-cli": "^3.0.1",
"fslightbox": "^3.2.3",
"fslightbox-vue": "^1.2.0",
"jquery": "^3.5.1",
"laravel-mix": "^5.0.9",
"laravel-mix-polyfill": "^2.0.0",
@ -47,6 +48,7 @@
"smoothscroll-polyfill": "^0.4.4",
"tiny-slider": "^2.9.3",
"toastify-js": "^1.9.3",
"vue-multiselect": "^2.1.6",
"vue-router": "^3.5.1",
"vue-select-image": "^1.9.0",
"vue-svg-map": "^1.2.0",

Binary file not shown.

View file

@ -3,7 +3,7 @@
<div class="bourse-sub_container">
<div class="tabs-bloc">
<!-- tabs link -->
<nav class="tabs-link">
<nav id="tableHeader" class="tabs-link">
<ul>
<li class="echange-item">
<div>
@ -23,7 +23,7 @@
<table :class="'table-bourseEchanges ' + curentStateClass">
<thead>
<tr class="searchInputs" v-show="curentStateClass != 'has'">
<th>
<th colspan="3">
<a @click="departaimant = ''"><i class="far fa-times-circle" ></i></a>
<input
:disabled="curentStateClass == 'has'"
@ -32,8 +32,6 @@
type="text"
:placeholder="__('Départaimant')"
>
</th>
<th colspan="2">
<a @click="pseudo = ''"><i class="far fa-times-circle" ></i></a>
<input
:disabled="curentStateClass == 'has'"
@ -52,37 +50,39 @@
</thead>
<tbody>
<tr v-for="(result, index) in searchResult" :key="index">
<td class="departaimant-col" :data-hash="result.hashcode">{{ result.departaimant }}</td>
<td class="pseudo-col">
<a href="#">
<span>{{ result.username }}</span>
<td :data-label="__('Départ\'Aimant')" class="departaimant-col" :data-hash="result.hashcode">{{ result.departaimant }}</td>
<td :data-label="__('Pseudo')" class="pseudo-col">
<a :href="'#' + result.username + '/' + result.departaimant" @click="sendMessage(result)">
<i class="icon-messages"></i>
<span>{{ result.username | str_limit(12) }}</span>
</a>
</td>
<td class="date-col"> {{ result.date }} </td>
<td :data-label="__('Date')" class="date-col"> {{ result.date }} </td>
</tr>
<tr v-if="pendingSearch">
<td colspan="3"><i class="fas fa-circle-notch fa-spin pendingSearch"></i></td>
<td colspan="3" class="pendingSearch"><i class="fas fa-circle-notch fa-spin"></i></td>
</tr>
<tr v-if="!pendingSearch && searchResult.length === 0 && curentStateClass !== 'has'">
<tr v-if="!pendingSearch && searchResult.length === 0 && curentStateClass !== 'has'" class="message">
<td colspan="3">{{ __('Aucun résultat(s)') }}</td>
</tr>
<tr v-if="curentStateClass === 'has'">
<td colspan="3" v-html="__('Pour afficher des résultat cliquez sur je :bold cherche :endbold ou :bold j\'échange :endbold à droite', {
'bold':'<b>', 'endbold': '</b>'
<tr v-if="curentStateClass === 'has'" class="message">
<td colspan="3" v-html="__('Pour afficher des résultat cliquez sur je :wantsLink cherche :endlink ou :givesLink j\'échange :endlink, puis sélectionnez les départaimants voulus.', {
'wantsLink':'<a href=\'#wantsLink\'>',
'givesLink':'<a href=\'#givesLink\'>',
'endlink': '</a>'
})"></td>
</tr>
</tbody>
<tfoot>
<tr v-show="curentStateClass != 'has'">
<th colspan="3">
<th colspan="3" class="navButtons">
<button
:disabled="pendingSearch || curentStateClass == 'has' || page <= 1"
@click="page = page <= 1 ? 1 : page-1"
@click="previousPage"
>{{ __('Précédent') }}</button>
<button
:disabled="pendingSearch || curentStateClass == 'has' || !searchResult.length"
@click="page += 1"
@click="nextPage"
>{{ __('Suivant') }}</button>
</th>
</tr>
@ -108,6 +108,7 @@
<button
v-if="status.value != oDepartaimantStatus.none.value"
:key="name"
:id="name+'Link'"
:class="name + (status.value === currentState ? ' active' : '')"
@click="changeState(status.value)"
>
@ -118,16 +119,62 @@
</div>
</div>
<p class="departaimant-name">{{ currentDep }}</p>
<div id="depSelect">
<div class="custom-select">
<multiselect
:disabled="pendingSearch"
:placeholder="__('Sélectionnez un départaimant pour en modifier son état')"
label="name"
track-by="name"
:tabindex="0"
:options="mapAttributes"
:searchable="false"
:allow-empty="false"
:show-labels="false"
:hide-selected="false"
@input="selectLocation">
<template slot="singleLabel" slot-scope="props">
<span v-if="props.option.checked"><i class="fas fa-check-square"></i></span>
<span v-if="!props.option.checked"><i class="far fa-square"></i></span>
<span>{{ props.option.name }}</span>
</template>
<template slot="option" slot-scope="props">
<span v-if="props.option.checked"><i class="fas fa-check-square"></i></span>
<span v-if="!props.option.checked"><i class="far fa-square"></i></span>
<span>{{ props.option.name }}</span>
</template>
</multiselect>
</div>
</div>
<div :class="'svg-container ' + curentStateClass">
<checkbox-svg-map v-model="selectedLocations" :map="currentMap" @click="clickLocation" @mouseover="hoverLocation"/>
<checkbox-svg-map
v-model="selectedLocations"
:map="currentMap"
@click="clickLocation"
@keydown="clickLocation"
@mouseover="hoverLocation"/>
</div>
</div>
</div>
<FsLightbox
:toggler="showMessagePopup"
:sources="[{
component: SendMessage,
props: {
messageDest: messageDest,
customerName: customerName
}
}]"
:exitFullscreenOnClose="true"
/>
</div>
</template>
<script>
import { CheckboxSvgMap } from "vue-svg-map";
import { Multiselect } from "vue-multiselect";
import FsLightbox from "fslightbox-vue";
import SendMessage from "./SendMessageComponent.vue";
const Maps = {
0: require('./OldMagnetMap').default,
@ -136,21 +183,35 @@
export default {
components: {
CheckboxSvgMap
CheckboxSvgMap,
Multiselect,
FsLightbox,
SendMessage
},
created() {
this.$vueEventBus.$on('messageSent', this.messageSent)
this.$vueEventBus.$on('closeMessageBox', this.closeMessageBox)
},
beforeDestroy() {
this.$vueEventBus.$off('messageSent')
this.$vueEventBus.$off('closeMessageBox')
},
mounted() {
this.userCollections = JSON.parse(this.maps);
this.oCollectionsType = JSON.parse(this.enumCollectionsType);
this.oDepartaimantStatus = JSON.parse(this.enumDepartaimantStatus);
this.currentState = this.oDepartaimantStatus.has.value;
this.customerName = this.guardCustomerName;
},
props: [
'guardCustomerName',
'maps',
'enumCollectionsType',
'enumDepartaimantStatus'
],
data() {
return {
customerName: '',
selectedLocations: [],
currentMap: Maps[0],
currentMapId: 0,
@ -164,8 +225,12 @@
oDepartaimantAction: {},
userCollections: [],
searchResult: [],
mapAttributes: [],
pendingSearch: false,
totalMagnetsIncCollection: 0
totalMagnetsIncCollection: 0,
showMessagePopup: false,
SendMessage: SendMessage,
messageDest: null
}
},
computed: {
@ -182,18 +247,36 @@
return 'has';
}
},
updated() {
this.$nextTick(function () {
let wantsLink = document.querySelector('a[href="#wantsLink"]');
let givesLink = document.querySelector('a[href="#givesLink"]');
if(wantsLink && givesLink) {
document.querySelector('a[href="#wantsLink"]').addEventListener('click', (e) => {
e.preventDefault();
__Gaul.scrollToContent('wantsLink', 80)
})
document.querySelector('a[href="#givesLink"]').addEventListener('click', (e) => {
e.preventDefault();
__Gaul.scrollToContent('givesLink', 80)
})
}
})
},
methods: {
switchCollection(id){
switchCollection(id) {
this.currentMap = Maps[id];
this.currentMapId = id;
this.currentDep = "Les Départ'aimants";
this.currentDep = this.__("Les Départ'aimants");
this.pseudo = '';
this.mapAttributes = []; // force select refresh
this.loadMap();
this.searchResults();
},
changeState(state){
changeState(state) {
this.currentState = state;
this.pseudo = '';
this.mapAttributes = []; // force select refresh
this.loadMap();
this.searchResults();
},
@ -202,13 +285,23 @@
let name = evt.target.getAttribute('name');
this.currentDep = id + " - " + name;
},
clickLocation(evt){
selectLocation(location) {
let state = !location.checked ? this.currentState : this.oDepartaimantStatus.none.value
document.getElementById(location.id).setAttribute('aria-checked', location.checked);
this.mapAttributes = []; // force select refresh
this.queryResults(location.id, location.name, state)
},
clickLocation(evt) {
let id = evt.target.getAttribute('id');
let name = evt.target.getAttribute('name');
let checked = evt.target.getAttribute('aria-checked');
let state = checked === null ? this.currentState : this.oDepartaimantStatus.none.value
this.mapAttributes = []; // force select refresh
this.queryResults(id, name, state)
},
queryResults(id, name, state) {
this.currentDep = id + " - " + name;
this.pendingSearch = true;
axios.post(this.route('club.bourse.saveState') + '/' + this.currentMapId, {
id: id,
state: state,
@ -218,7 +311,9 @@
})
.catch(error => {
console.log(error);
this.pendingSearch = false;
}).then(() => {
this.pendingSearch = false;
this.searchResults();
});
},
@ -237,6 +332,17 @@
}
}
this.totalMagnetsIncCollection = this.userCollections[this.currentMapId].length;
this.$nextTick(function () {
let mapAttributes = [];
for(let path of document.querySelectorAll('svg.svg-map path')) {
mapAttributes.push({
id: path.id,
name: path.getAttribute('name'),
checked: path.getAttribute('aria-checked') ? true : false
});
}
this.$set(this, 'mapAttributes', mapAttributes)
})
},
searchResults() {
this.searchResult = [];
@ -256,7 +362,7 @@
page: this.page
})
.then(response => {
if (response.data.status === 'OK'){
if (response.data.status === 'OK') {
this.searchResult = response.data.data;
}else{
alert('Une erreur est survenue.');
@ -267,11 +373,43 @@
}).then(() => {
setTimeout(() => {
this.pendingSearch = false;
// rerun request if inputs have changed
if(pseudoQuery !== this.pseudo || departaimantQuery !== this.departaimant) {
this.searchResults();
}
}, 100)
}, 300)
});
},
nextPage() {
__Gaul.scrollToContent('tableHeader', 80);
setTimeout(() => { this.page += 1; }, 500)
},
previousPage() {
__Gaul.scrollToContent('tableHeader', 80);
setTimeout(() => { this.page = this.page <= 1 ? 1 : this.page-1 }, 500)
},
sendMessage(result) {
this.messageDest = result
this.showMessagePopup = !this.showMessagePopup
},
messageSent() {
let toast = {
duration: 6000,
newWindow: false,
close: true,
className: "notifications",
gravity: "top",
offset: {
x: "2em",
y: "3em"
},
stopOnFocus: true // Prevents dismissing of toast on hover
};
toast.text = this.__('Votre message à bien été envoyé');
Toastify(toast).showToast();
},
closeMessageBox() {
this.showMessagePopup = !this.showMessagePopup
}
},
watch: {
@ -342,11 +480,27 @@
width: 90%;
display: flex;
.fslightbox-toolbar {
display: none;
}
@include max-width($large_screen) {
}
@include max-width($big_screen) {
flex-direction: column-reverse;
width: 100%;
}
//accessibility link focus
a:focus {
outline: 2px solid $tableHeaderText;
}
// Reset button Style to nice one
button {
display: inline;
border: none;
padding: 1rem 2rem;
padding: 0.6rem 3rem;
margin: 0;
text-decoration: none;
background: $buttonBgColor;
@ -361,6 +515,11 @@
-moz-appearance: none;
}
button:disabled,
button[disabled] {
color: #AAA;
}
button:hover,
button:focus {
background: darken($buttonBgColor, 10%);
@ -379,10 +538,21 @@
flex: 1;
& .tabs-bloc {
@include max-width($big_screen) {
padding: 0 4em;
}
@include max-width($mobile) {
padding: 0.3em;
}
& .tabs-link {
font-size: 0;
& ul {
display: flex;
}
& li {
display: inline-block;
display: flex;
font-size: 10px;
width: 50%;
}
@ -433,14 +603,35 @@
border-style: solid;
border-radius: 0 0 3px 3px;
width: 100%;
border-width: 7px 0 4px;
margin-bottom: 35px;
padding: 0 30px;
border-width: 0.8em 0 0.3em;
margin-bottom: 5em;
padding: 0 1em;
tbody {
display:block;
height: 52em;
overflow:auto;
& > tr {
margin-top: 1em;
margin-bottom: 1em;
& > td {
& a {
color: $color4;
font-weight: 700;
text-decoration: underline;
&:visited {
color: $departaimantColor;
}
&:hover {
color: $tableLinksHover;
}
& span {
text-decoration: underline;
}
}
}
}
}
thead, tbody tr {
display:table;
@ -451,9 +642,85 @@
width: calc( 100% - 1em )
}
tfoot {
text-align: center;
}
@include max-width($mobile) {
padding: 0;
thead {
tr:first-child th {
padding: 15px 0;
}
tr:last-child {
display: none;
}
}
tbody {
padding: 1.2em;
overflow: inherit;
height: inherit;
}
tr {
display: block;
margin-bottom: 40px;
}
td {
display: block;
text-align: right;
&.pendingSearch {
text-align: center;
}
}
td:before {
content: attr(data-label);
float: left;
font-weight: bold;
}
tfoot tr th {
display: flex;
flex-direction: column;
button {
margin-bottom :1em;
width: 100%;
}
}
}
& .message td {
text-align: center;
padding: 1em;
}
& .searchInputs {
position: relative;
& th {
font-size: 3em;
@include max-width($mobile) {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
&:last-child {
text-align: center;
& input {
width: 90% !important;
margin-bottom: 1em;
}
& > a:nth-child(3) > svg {
top: 3.9em !important;
}
& > a > svg {
top: 1em;
left: 1.2em;
}
}
}
& svg {
cursor: pointer;
color: $textInputColor;
@ -468,9 +735,9 @@
width: 100%;
}
&:last-child {
text-align: right;
text-align: center;
& input {
width: 80%;
width: 45%;
}
}
}
@ -486,34 +753,24 @@
border-color: $gives;
}
& td {
font-size: 1.8em;
margin-bottom: 0.3em;
}
& th {
border-bottom: 1px solid $tableLineSplit;
color: $tableHeaderText;
font-family: "alphafridgemagnets";
font-size: 30px;
width: 40%;
text-align: center;
font-size: 2em;
padding: 15px;
}
& td {
background-color: #fff;
font-family: "catamaran-regular";
font-size: 17px;
color: #000;
padding: 5px;
text-align: center;
vertical-align: middle;
text-align: center;
&.departaimant-col {
font-family: 'alphafridgemagnets';
text-transform: uppercase;
color: $departaimantColor;
}
&.pseudo-col {
font-family: 'catamaran-bold';
& a {
color: $tableLinks;
& span {
@ -532,15 +789,16 @@
}
& .pendingSearch {
font-size: 2.5em;
color: $departaimantColor;
margin: 2em 0;
text-align: center;
& svg {
font-size: 2.5em;
color: $departaimantColor;
}
}
}
}
& .carte-svg-bloc {
& .departaimant-name {
font-family: 'alphafridgemagnets';
font-size: 26px;
@ -550,10 +808,28 @@
color: $departaimantColor;
}
#depSelect {
padding: 2em;
display: none;
@include max-width($tablet) {
display: block;
}
}
@include max-width($tablet) {
.svg-map {
pointer-events: none;
}
}
& .menu {
display: flex;
align-items: center;
justify-content: space-evenly;
@include max-width($mobile) {
flex-direction: column;
}
& .states {
display: flex;
cursor: pointer;
@ -580,12 +856,18 @@
&.has {
color: $has;
&:focus {
outline: 1px solid $has;
}
& i {
color: inherit;
}
&:hover, &.active {
background-color: $has;
color: white;
&:focus {
outline: 1px solid white;
}
& i {
color: inherit;
}
@ -594,12 +876,18 @@
&.gives {
color: $gives;
&:focus {
outline: 1px solid $gives;
}
& i {
color: inherit;
}
&:hover, &.active {
color: white;
background-color: $gives;
&:focus {
outline: 1px solid white;
}
& i {
color: inherit;
}
@ -608,12 +896,18 @@
&.wants {
color: $wants;
&:focus {
outline: 1px solid $wants;
}
& i {
color: inherit;
}
&:hover, &.active {
color: white;
background-color: $wants;
&:focus {
outline: 1px solid white;
}
& i {
color: inherit;
}
@ -659,6 +953,12 @@
& .svg-container {
width: 70%;
margin: 0 auto;
@include max-width($desktop) {
width: 80%;
}
@include max-width($tablet) {
width: 90%;
}
}
}

View file

@ -0,0 +1,151 @@
<template>
<div class="pop-contactMembre">
<div>
<h2>{{__('Contacter un membre') }}</h2>
<div class="form-bloc">
<button class="btn closeButton" @click="close">
<i class="fas fa-times"></i>
</button>
<p ref="error" class="blocFormError display-none">
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
<span>{{ __('Une erreur est survenue impossible d\'envoyer votre message') }}</span>
</p>
<p ref="errorLessThan" class="blocFormError display-none">
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
<span>{{ __('Votre message doit avoir au moins 20 caratères') }}</span>
</p>
<p ref="errorMoreThan" class="blocFormError display-none">
<i class="fa fa-exclamation-triangle" aria-hidden="true"></i>
<span>{{ __('Votre message ne peut avoir plus de 250 caratères') }}</span>
</p>
<div class="input-group textarea-item" >
<label for="">{{ __('Message') }}<em>*</em></label>
<textarea ref="message" @click="focus" name="Message" cols="20" rows="10" v-model="defaultMessage"></textarea>
</div>
<div class="wrap-btn">
<button @click="sendMessage" class="btn btn-yellow text-uppercase">
<span v-if="!sending"><i class="icon-repondre"></i></span>
<span v-if="sending"><i class="fas fa-circle-notch fa-spin"></i></span>
<span>{{ __('Envoyer') }}</span>
</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
customerName: null,
messageDest: null
},
computed: {
defaultMessage() {
return this.__(' Bonjour :pseudo,\n\nVous avez déposé une demande d’échange concernant le Départ’aimant :departaimant et j’aimerai en discuter avec vous.\n\nMerci pour votre réponse.\n\n :author', {
'pseudo': this.messageDest.username,
'departaimant': this.messageDest.departaimant,
'author': this.customerName
})
}
},
data() {
return {
sending: false
}
},
methods: {
focus(e) {
e.target.focus()
},
sendMessage() {
let message = this.$refs.message.value.trim()
this.$refs.error.classList.add('display-none')
this.$refs.errorMoreThan.classList.add('display-none')
this.$refs.errorLessThan.classList.add('display-none')
if(message.length > 250) {
this.$refs.errorMoreThan.classList.remove('display-none')
return;
}
if(message.length < 20) {
this.$refs.errorLessThan.classList.remove('display-none')
return;
}
this.sending = true;
axios.post(this.route('account.sendMessage'), {
to: this.messageDest.username,
message: message,
})
.then(response => {
this.$vueEventBus.$emit('closeMessageBox')
this.$vueEventBus.$emit('messageSent')
})
.catch(error => {
console.log(error);
this.$refs.error.classList.remove('display-none')
}).then(() => {
this.sending = false;
});
},
close() {
this.$vueEventBus.$emit('closeMessageBox')
}
}
}
</script>
<style lang="scss">
@import '../../../../../sass/_variables.scss';
.pop-contactMembre {
background-color: #974c99;
width: $tablet;
padding: 5em;
height: inherit !important;
.display-none {
display: none !important;
}
h2 {
color: #fff;
font-family: 'alphafridgemagnets';
font-size: 3em;
margin-bottom: 15px;
text-align: left;
text-decoration: none;
}
label {
color: #fff;
display: block;
font-family: 'catamaran-bold';
font-size: 1.2em;
padding-bottom: 5px;
text-align: left;
}
textarea {
border: none;
border-radius: 3px;
color: #999595;
font-family: 'catamaran-regular';
font-size: 1.8em;
height: 12rem;
padding: 15px 20px;
width: 100%;
}
.closeButton {
position: absolute;
top: 1rem;
right: 1rem;
font-size: 2em;
padding: 0.6em;
border-radius: 3px;
& svg {
top: -5px;
position: relative;
}
}
}
</style>

View file

@ -23,6 +23,16 @@ window.__Gaul = {
fn(...params);
});
}
},
scrollToContent: (idContent, headerOffset) => {
let element = document.getElementById(idContent);
let elementPosition = element.getBoundingClientRect().top;
let offsetPosition = window.pageYOffset + elementPosition - headerOffset;
scrollTo({
top: offsetPosition,
behavior: "smooth"
});
}
}

26
resources/js/main.js vendored
View file

@ -28,6 +28,8 @@ let vueOptions = {
el: "#app"
};
Vue.prototype.$vueEventBus = new Vue()
// register modules
const modules = require.context("./modules", true, /\.js$/i);
modules.keys().map(key => Vue.mixin(modules(key).default));
@ -62,18 +64,14 @@ if (document.getElementById("vue-use-router")) {
const app = new Vue(vueOptions);
// TODO remove inline js call to this function from moment.blade and product.blade
/** Méthode de scroll vers un élément de la page via son id html et la taille du header */
window.scrollToContent = function (idContent, headerOffset) {
var element = document.getElementById(idContent);
var elementPosition = element.getBoundingClientRect().top;
var offsetPosition = window.pageYOffset + elementPosition - headerOffset;
window.scrollTo({
top: offsetPosition,
behavior: "smooth"
});
};
Vue.filter('str_limit', function (value, size) {
if (!value) return '';
value = value.toString();
if (value.length <= size) {
return value;
}
return value.substr(0, size) + '...';
});
// ProgressBar de l'inscription
require("./front/functions.js");
@ -88,3 +86,7 @@ pages.keys().map(key => {
}
require(`./pages/${key}`);
});
// Alias for Vuejs
Vue.prototype.__Gaul = window.__Gaul;
Vue.prototype.scrollTo = window.scrollTo;

View file

@ -64,15 +64,15 @@ $body-bg: $color1;
// Bourse
$gives: #e43b4e;
$wants: $orange;
$gives: #CF1D40;
$wants: darken(adjust-hue($orange, -5), 10%);
$has: #6cc18a;
$baseMapColor: #4b84c1;
$baseMapOutline: #fff;
$departaimantColor: #9c549e;
$collectionBtnColor: #fff;
$vintageColor: #e77b32;
$vintageColor: darken(#e77b32, 10%);
$actualColor: #974c99;
$bgInputColor: #fff;

View file

@ -5,6 +5,9 @@ html {
position: absolute;
width: 17rem;
transition-duration: 0.3s;
@include max-width($tablet) {
width: 13rem !important;
}
}
}
}

View file

@ -215,6 +215,8 @@
background-repeat: repeat;
background-size: auto;
position: relative;
margin-top: $menuBaseHeight;
& .content {
height: 100%;
& .logos {
@ -326,8 +328,12 @@
}
}
.sub_header_club_index {
margin-top: $menuBaseHeight;
}
.sub_header_club {
height: 444px;
margin-top: $menuBaseHeight;
& .title-club-account {
position: absolute;

View file

@ -1,9 +1,22 @@
.club-bourse {
& h1 {
color: #1e5ba1;
color: $color4;
font-family: 'alphafridgemagnets';
text-align: center;
font-size: 40px;
margin-bottom: 46px;
}
& .chapo {
width: 70%;
margin: 4em auto;
a {
color: $color4;
font-weight: 700;
text-decoration: underline;
&:visited {
color: $departaimantColor;
}
}
}
}

View file

@ -118,6 +118,7 @@
position: absolute;
top: 40%;
right: 21%;
width: 4em;
@media screen and (max-width: $tablet - 60) {
right: 24%;
@ -297,6 +298,7 @@
padding: 0 23px;
text-align: center;
text-transform: uppercase;
margin: 0.2em;
&:hover {
background-color: $orange;

View file

@ -3,6 +3,7 @@
@import "~animate.css/animate.css";
@import "~tiny-slider/dist/tiny-slider.css";
@import "~toastify-js/src/toastify.css";
@import "~vue-multiselect/dist/vue-multiselect.min.css";
@import "variables";
@import "front/reset";
@import "front/fonts";

View file

@ -5,9 +5,10 @@
@section('sub_header')
<div class="sub_header club-bourse">
<div class="content">
@include('front.club.modules.customerToolbar')
<div class="logos">
<img src="{{ asset('images/le_club-logo-t.png') }}" alt="{{ __('Le Club Des Gaulois - Le Gaulois') }}" class="club-img">
<img src="{{ asset('images/club/logo-departaimant.png') }}" alt="{{ __('Les Départ\'aimants - Le Gaulois') }}">
<img src="{{ asset('assets/images/le_club-logo-t.png') }}" alt="{{ __('Le Club Des Gaulois - Le Gaulois') }}" class="club-img">
<img src="{{ asset('assets/images/club/logo-departaimant.png') }}" alt="{{ __('Les Départ\'aimants - Le Gaulois') }}">
</div>
</div>
</div>
@ -16,7 +17,14 @@
@section('content')
<div class="club-bourse">
<h1>{{ __('La Bourse aux échanges') }}</h1>
<div class="chapo">
<p>{{ __('Le Gaulois vous aide à gérer votre collection et vous met en relation avec d’autres collectionneurs pour échanger vos doubles et/ou trouver les Départ’Aimants qu’il vous manquent. Pour entrer en contact avec l’un d’eux, il vous suffit de cliquer sur son pseudo afin de pouvoir effectuer la transaction.') }}<br>
<a target="_blank" href="{{ asset('assets/documents/CGU_Club-LE-GAULOIS.pdf') }}">{{ __('Voir les conditions d\'utilisation du Club des Gaulois') }}</a>
</p>
<p>{{ __('Pour trouver rapidement vos Départ’Aimants, vous pouvez rechercher par département et/ou par pseudo en utilisant les menus ci-dessous') }}&nbsp;:&nbsp;</p>
</div>
<bourse
guard-customer-name="{{ Auth::guard('customer')->user()->username }}"
maps="{{ $departaimants }}"
enum-collections-type='@json(DepartaimantsCollectionType::toArray())'
enum-departaimant-status='@json(DepartaimantStatus::toArray())'>
@ -35,7 +43,8 @@
window._asset = '{{ asset('') }}';
window._routes = {
"club.bourse.saveState": "{{ route('club.bourse.saveState', ['type' => '/']) }}",
"club.bourse.search": "{{ route('club.bourse.search', ['type' => '/']) }}"
"club.bourse.search": "{{ route('club.bourse.search', ['type' => '/']) }}",
"account.sendMessage": "{{ route('account.sendMessage') }}"
};
</script>
@endpush

View file

@ -3,7 +3,7 @@
@section('description', "Entrez dans le Club des Gaulois pour bénéficier des avantages réservés aux membres : bons de réduction, avant-premières, Départ'aimants et bourse aux échanges")
@section('sub_header')
<div class="sub_header">
<div class="sub_header sub_header_club_index">
<div class="content">
@include('front.club.modules.customerToolbar')
<div class="title-club">
@ -47,6 +47,7 @@
</ul>
</div>
<a class="btn brdr-jaune" href="{{ route('club.bourse.index') }}" title="{{ __('Complétez votre collec') }}">{{__('Complétez votre collec\'') }}</a>
<a class="btn brdr-jaune" href="{{ route('club.boutique.index') }}" title="{{ __('Accédez à la boutique') }}">{{__('Accédez à la boutique') }}</a>
</div>
</div>
</div>

View file

@ -24,7 +24,8 @@
<section class="strates">
@foreach ($moment->strates as $strate)
<div class="strate-item">
<button class="scroll-button" onclick="scrollToContent('{{ 'strate-text-' . $loop->iteration }}', 70)"></button>
{{-- TODO: Remove this inline js call --}}
<button class="scroll-button" onclick="__Gaul.scrollToContent('{{ 'strate-text-' . $loop->iteration }}', 70)"></button>
@if ($strate->picture)
<figure>
<span><img src="{{ asset($strate->picture) }}" alt="{{ $strate->title }} - Le Gaulois"></span>
@ -42,7 +43,8 @@
@if ($moment->featured_status === 1)
<section class="ascent">
<div class="ascent-content">
<button class="scroll-button" onclick="scrollToContent('title-ascent', 70)"></button>
{{-- TODO: Remove this inline js call --}}
<button class="scroll-button" onclick="__Gaul.scrollToContent('title-ascent', 70)"></button>
<h1 id="title-ascent">{{ $moment->featured_title }}</h1>
{!! $moment->featured_text !!}
@if ($moment->featured_type === "produits")
@ -87,7 +89,8 @@
@endif
@if ($moment->voucher_status === 1)
<section class="voucher">
<button class="scroll-button" onclick="scrollToContent('voucher-content', 70)"></button>
{{-- TODO: Remove this inline js call --}}
<button class="scroll-button" onclick="__Gaul.scrollToContent('voucher-content', 70)"></button>
<div class="voucher-content">
<figure class="voucher-picture" id="voucher-content">
<img src="{{ asset('assets/images/moments/lebonplan-moment.png') }}" alt="Bon plan - Le Gaulois">

View file

@ -6,6 +6,8 @@ use App\Models\Moments;
use App\Models\Recipes;
use Diglactic\Breadcrumbs\Breadcrumbs;
// TODO add missing routes as for club and others
// Root
Breadcrumbs::for('home', function ($trail) {
$trail->push(__('Accueil'), route('home'));
@ -164,3 +166,50 @@ Breadcrumbs::for('moment', function ($trail, Moments $moment) {
$trail->parent('home');
$trail->push(sprintf("%s", $moment->title), route('moment', compact('moment')));
});
// Club
Breadcrumbs::for('club.index', function ($trail) {
$trail->parent('home');
$trail->push(__('Le Club des Gaulois'), route('club.index'));
});
// TODO:
// Breadcrumbs::for('club.infos.child', function ($trail) {
// $trail->parent('ocb.index');
// $trail->push(__('Volaille'), route('ocb.infos.child'));
// });
Breadcrumbs::for('club.reductions', function ($trail) {
$trail->parent('club.index');
$trail->push(__('Les promos'), route('club.reductions'));
});
Breadcrumbs::for('club.bourse.index', function ($trail) {
$trail->parent('club.index');
$trail->push(__('La Bourse au échanges'), route('club.bourse.index'));
});
Breadcrumbs::for('club.boutique.index', function ($trail) {
$trail->parent('club.index');
$trail->push(__('La Boutique'), route('club.boutique.index'));
});
Breadcrumbs::for('account.infos', function ($trail) {
$trail->parent('club.index');
$trail->push(__('Mon compte'), route('account.infos'));
});
Breadcrumbs::for('account.cart', function ($trail) {
$trail->parent('account.infos');
$trail->push(__('Ma liste de courses'), route('account.cart'));
});
Breadcrumbs::for('account.messages', function ($trail) {
$trail->parent('account.infos');
$trail->push(__('Mes messages'), route('account.messages'));
});
Breadcrumbs::for('account.reportCustomer', function ($trail) {
$trail->parent('account.infos');
$trail->push(__('Signaler un abus'), route('account.reportCustomer'));
});
Breadcrumbs::for('account.notifications', function ($trail) {
$trail->parent('account.infos');
$trail->push(__('Notifications'), route('account.notifications'));
});
Breadcrumbs::for('account.favs-recipes', function ($trail) {
$trail->parent('account.infos');
$trail->push(__('Mes recettes favorites'), route('account.favs-recipes'));
});