update
This commit is contained in:
parent
4a94799602
commit
de2e56baae
13 changed files with 314 additions and 171 deletions
|
@ -12,7 +12,7 @@
|
|||
"register-service-worker": "^1.7.1",
|
||||
"tiptap-vuetify": "^2.23.0",
|
||||
"vue": "^2.6.11",
|
||||
"vue-apitator": "^0.0.16",
|
||||
"vue-apitator": "0.0.17",
|
||||
"vue-class-component": "^7.2.3",
|
||||
"vue-croppa": "^1.3.8",
|
||||
"vue-input-facade": "^1.3.1",
|
||||
|
|
|
@ -20,6 +20,9 @@ export default Vue.extend({
|
|||
|
||||
created () {
|
||||
console.log('Using ' + process.env.VUE_APP_BASE_URL)
|
||||
if (window.localStorage.getItem('associations_condorcet_debug') === 'YES') {
|
||||
this.$store.commit('SET_DEBUG', true)
|
||||
}
|
||||
},
|
||||
|
||||
data: () => ({})
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
:vertical="$vuetify.breakpoint.mobile"
|
||||
:multi-line="$vuetify.breakpoint.mobile"
|
||||
v-model="$store.state.alert.enabled"
|
||||
:timeout="500000"
|
||||
:timeout="2500"
|
||||
>
|
||||
{{ $store.state.alert.text }}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
<v-tab @click="navigate('DelegateGallery')">
|
||||
Images/vidéos
|
||||
</v-tab>
|
||||
<v-tab @click="navigate('DelegatePresentation')">
|
||||
<v-tab @click="navigate('DelegateDescription')">
|
||||
Description
|
||||
</v-tab>
|
||||
<v-tab @click="navigate('DelegateSchedule')">
|
||||
|
@ -254,7 +254,7 @@ export default {
|
|||
selectRoute (route) {
|
||||
const path = route.path.split('/')
|
||||
const name = path[path.length - 1]
|
||||
const routes = ['', 'gallery', 'presentation', 'schedule', 'pricing', 'contact']
|
||||
const routes = ['', 'gallery', 'description', 'schedule', 'pricing', 'contact']
|
||||
this.tab = routes.indexOf(name)
|
||||
},
|
||||
init () {
|
||||
|
@ -374,15 +374,22 @@ export default {
|
|||
}
|
||||
},
|
||||
goToPage () {
|
||||
window.open(this.publicUrl, '_blank').focus()
|
||||
window.open(this.$store.state.delegate.publicUrl, '_blank').focus()
|
||||
},
|
||||
openPublishModal () {
|
||||
// compute if the user can ask approval
|
||||
this.$store.commit('VALIDATE_MAIN', isValid => {
|
||||
if (isValid) {
|
||||
this.publishModal = true
|
||||
const data = this.$store.state.data
|
||||
this.canPublish =
|
||||
data.name.length > 0 &&
|
||||
data.descriptionShort.length > 10
|
||||
} else {
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'error',
|
||||
text: 'Vous devez remplir tout les champs requis afin de publier'
|
||||
})
|
||||
this.publishModal = false
|
||||
}
|
||||
this.canPublish = isValid
|
||||
})
|
||||
},
|
||||
askApproval () {
|
||||
this.askingApprovalLoading = true
|
||||
|
|
|
@ -46,14 +46,14 @@ const routes: Array<RouteConfig> = [
|
|||
component: () => import(/* webpackChunkName: "delegateMain" */ '../views/Delegate/Main.vue')
|
||||
},
|
||||
{
|
||||
path: 'contact',
|
||||
name: 'DelegateContact',
|
||||
component: () => import(/* webpackChunkName: "delegateContact" */ '../views/Delegate/Contact.vue')
|
||||
path: 'gallery',
|
||||
name: 'DelegateGallery',
|
||||
component: () => import(/* webpackChunkName: "delegateGallery" */ '../views/Delegate/Gallery.vue')
|
||||
},
|
||||
{
|
||||
path: 'pricing',
|
||||
name: 'DelegatePricing',
|
||||
component: () => import(/* webpackChunkName: "delegatePricing" */ '../views/Delegate/Pricing.vue')
|
||||
path: 'description',
|
||||
name: 'DelegateDescription',
|
||||
component: () => import(/* webpackChunkName: "delegateDescription" */ '../views/Delegate/Description.vue')
|
||||
},
|
||||
{
|
||||
path: 'schedule',
|
||||
|
@ -61,16 +61,21 @@ const routes: Array<RouteConfig> = [
|
|||
component: () => import(/* webpackChunkName: "delegateSchedule" */ '../views/Delegate/Schedule.vue')
|
||||
},
|
||||
{
|
||||
path: 'gallery',
|
||||
name: 'DelegateGallery',
|
||||
component: () => import(/* webpackChunkName: "delegateGallery" */ '../views/Delegate/Gallery.vue')
|
||||
path: 'pricing',
|
||||
name: 'DelegatePricing',
|
||||
component: () => import(/* webpackChunkName: "delegatePricing" */ '../views/Delegate/Pricing.vue')
|
||||
},
|
||||
{
|
||||
path: 'presentation',
|
||||
name: 'DelegatePresentation',
|
||||
component: () => import(/* webpackChunkName: "delegatePresentation" */ '../views/Delegate/Presentation.vue')
|
||||
path: 'contact',
|
||||
name: 'DelegateContact',
|
||||
component: () => import(/* webpackChunkName: "delegateContact" */ '../views/Delegate/Contact.vue')
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '*',
|
||||
name: 'NotFound',
|
||||
component: () => import(/* webpackChunkName: "notFound" */ '../views/NotFound.vue')
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -38,11 +38,18 @@ export default new Vuex.Store({
|
|||
admiName: '',
|
||||
email: '',
|
||||
publicUrl: ''
|
||||
}
|
||||
},
|
||||
debug: false,
|
||||
validateMain: false,
|
||||
validateMainCallback: () => false
|
||||
},
|
||||
mutations: {
|
||||
SET_DEBUG (state, payload) {
|
||||
state.debug = payload
|
||||
},
|
||||
SET_TITLE (state, payload) {
|
||||
state.title = payload
|
||||
window.document.title = state.title + ' | Panel forum des associations'
|
||||
},
|
||||
ADD_ALERT (state, payload) {
|
||||
state.alert = {
|
||||
|
@ -64,6 +71,13 @@ export default new Vuex.Store({
|
|||
},
|
||||
SET_DELEGATE (state, payload) {
|
||||
state.delegate = { ...state.delegate, ...payload }
|
||||
},
|
||||
VALIDATE_MAIN (state, callback) {
|
||||
state.validateMain = true
|
||||
state.validateMainCallback = () => {
|
||||
state.validateMain = false
|
||||
return callback()
|
||||
}
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
|
|
|
@ -1,26 +1,13 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="mb-3 pb-1">
|
||||
<div class="mb-1 pb-1">
|
||||
<v-alert
|
||||
border="left"
|
||||
colored-border
|
||||
dense
|
||||
type="info"
|
||||
elevation="1"
|
||||
>
|
||||
Ici vous pouvez préciser quelques manières de contacter votre association, aucun des champs indiqués n'est obligatoire.
|
||||
</v-alert>
|
||||
</div>
|
||||
<v-text-field
|
||||
prepend-icon="person"
|
||||
label="Personne responsable"
|
||||
outlined
|
||||
v-model="$store.state.data.contacts.person" />
|
||||
<v-text-field
|
||||
prepend-icon="alternate_email"
|
||||
label="Email"
|
||||
:rules="rules.email"
|
||||
outlined
|
||||
v-model="$store.state.data.contacts.email" />
|
||||
<v-text-field
|
||||
prepend-icon="call"
|
||||
label="Numéro de téléphone"
|
||||
|
@ -65,9 +52,6 @@ export default {
|
|||
website: [
|
||||
v => v === '' || /.+@.+\..+/.test(v) || "L'email doit être valide"
|
||||
],
|
||||
email: [
|
||||
v => v === '' || /.+@.+\..+/.test(v) || "L'email doit être valide"
|
||||
],
|
||||
address: [
|
||||
v => v.length < 200 || 'Maximum 200 caractères'
|
||||
],
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<template>
|
||||
<div>
|
||||
<!-- COVER START -->
|
||||
<div v-if="false" class="mb-3">
|
||||
<div
|
||||
class="cover-common cover-container"
|
||||
:style="coverStyle">
|
||||
|
@ -30,7 +31,7 @@
|
|||
</v-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<AvatarEditor
|
||||
ref="avatarEditor"
|
||||
:loading="coverLoading"
|
||||
|
@ -41,10 +42,10 @@
|
|||
@submitted="handleAvatarEditorSubmitted"
|
||||
/>
|
||||
<!-- COVER END -->
|
||||
<div class="d-flex justify-end mt-3 mb-3">
|
||||
<div class="d-flex justify-end mb-3">
|
||||
<v-btn color="primary" outlined @click="addMediaModal = true">
|
||||
<v-icon left>add</v-icon>
|
||||
Ajouter une image
|
||||
Ajouter un média
|
||||
</v-btn>
|
||||
</div>
|
||||
<div
|
||||
|
@ -56,10 +57,10 @@
|
|||
outlined
|
||||
type="info"
|
||||
>
|
||||
Aucun medias n'ont été ajoutés pour l'instant
|
||||
Aucun médias n'ont été ajoutés pour l'instant
|
||||
</v-alert>
|
||||
</div>
|
||||
<v-row v-else>
|
||||
<v-row v-else class="justify-center">
|
||||
<v-col
|
||||
v-for="(media, index) in $store.state.data.gallery"
|
||||
:key="media._id"
|
||||
|
@ -109,6 +110,22 @@
|
|||
<span>Décaler vers la droite</span>
|
||||
</v-tooltip>
|
||||
<v-spacer />
|
||||
|
||||
<v-tooltip bottom>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn
|
||||
icon
|
||||
color="teal"
|
||||
small
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
@click="shiftRightMedia(media)"
|
||||
>
|
||||
<v-icon small>stars</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<span>Choisir comme couverture</span>
|
||||
</v-tooltip>
|
||||
<v-btn icon color="error" small @click="openDeleteMediaModal(media)">
|
||||
<v-icon small>delete</v-icon>
|
||||
</v-btn>
|
||||
|
@ -124,14 +141,27 @@
|
|||
<v-card-text>
|
||||
<div class="mt-2">
|
||||
<v-file-input
|
||||
prepend-icon="perm_media"
|
||||
v-model="files"
|
||||
chips
|
||||
multiple
|
||||
show-size
|
||||
counter
|
||||
accept="image/png,image/jpeg,video/mp4"
|
||||
label="Sélectionnez les images ou vidéos à importer">
|
||||
</v-file-input>
|
||||
</div>
|
||||
<div v-if="uploadLoading" class="mt-3">
|
||||
<v-progress-linear
|
||||
color="purple"
|
||||
height="2em"
|
||||
v-model="uploadProgress"
|
||||
>
|
||||
<template v-slot="{ value }">
|
||||
<strong>{{ Math.ceil(value) }}%</strong>
|
||||
</template>
|
||||
</v-progress-linear>
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn text color="primary" @click="addMediaModal = false">
|
||||
|
@ -172,7 +202,8 @@ export default {
|
|||
uploadLoading: false,
|
||||
files: [],
|
||||
deleteMediaModal: false,
|
||||
mediaToDelete: {}
|
||||
mediaToDelete: {},
|
||||
uploadProgress: 50
|
||||
}),
|
||||
|
||||
computed: {
|
||||
|
@ -225,7 +256,17 @@ export default {
|
|||
const formData = new FormData()
|
||||
results.forEach(r => formData.append(r[0], new Blob([new Uint8Array(r[1])]), r[2]))
|
||||
|
||||
this.$apitator.post('/delegate/medias', formData, { withAuth: true }).then(res => {
|
||||
this.$apitator.post('/delegate/medias', formData, {
|
||||
withAuth: true,
|
||||
onUploadProgress: (progressEvent) => {
|
||||
console.log(progressEvent)
|
||||
const totalLength = progressEvent.lengthComputable ? progressEvent.total : progressEvent.target.getResponseHeader('content-length') || progressEvent.target.getResponseHeader('x-decompressed-content-length')
|
||||
console.log('onUploadProgress', totalLength)
|
||||
if (totalLength !== null) {
|
||||
this.uploadProgress = Math.round((progressEvent.loaded * 100) / totalLength)
|
||||
}
|
||||
}
|
||||
}).then(res => {
|
||||
this.$store.commit('SET_DATA', { gallery: res.data.data.gallery })
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'success',
|
||||
|
|
|
@ -1,12 +1,25 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="">
|
||||
<v-alert
|
||||
outlined
|
||||
dense
|
||||
type="info"
|
||||
>
|
||||
Tout les champs indiqués ici sont obligatoire afin de publier votre page
|
||||
</v-alert>
|
||||
</div>
|
||||
<v-form
|
||||
ref="form"
|
||||
v-model="$store.state.mainFormIsValid"
|
||||
lazy-validation>
|
||||
<v-row class="mb-6 pb-2">
|
||||
<v-col cols="12" sm="12" md="6" style="align-items: center; justify-content: center; display: flex;">
|
||||
<v-col cols="12" sm="6" style="align-items: center; justify-content: center; display: flex;">
|
||||
<v-avatar size="200" style="border: 2px solid #95a5a6">
|
||||
<img :src="$store.state.data.thumbnail.location" />
|
||||
</v-avatar>
|
||||
</v-col>
|
||||
<v-col cols="12" sm="12" md="6" style="align-items: center; justify-content: center; display: flex;">
|
||||
<v-col cols="12" sm="6" style="align-items: center; justify-content: center; display: flex;">
|
||||
<v-btn @click="$refs.avatarEditor.toggle()" color="primary" outlined>
|
||||
<v-icon left>
|
||||
edit
|
||||
|
@ -20,10 +33,11 @@
|
|||
label="Nom de l'association"
|
||||
prepend-icon="tag"
|
||||
outlined
|
||||
v-model="$store.state.data.name" />
|
||||
v-model="$store.state.data.name"
|
||||
:rules="rules.name" />
|
||||
|
||||
<v-select
|
||||
label="Catégorie de l'association"
|
||||
label="Catégorie(s) de l'association"
|
||||
outlined
|
||||
prepend-icon="category"
|
||||
item-text="name"
|
||||
|
@ -32,15 +46,34 @@
|
|||
:items="$store.state.tags">
|
||||
</v-select>
|
||||
|
||||
<v-row>
|
||||
<v-col cols="12" sm="6" class="py-0">
|
||||
<v-text-field
|
||||
prepend-icon="person"
|
||||
label="Personne responsable"
|
||||
outlined
|
||||
v-model="$store.state.data.contacts.person"
|
||||
:rules="rules.person" />
|
||||
</v-col>
|
||||
<v-col cols="12" sm="6" class="py-0">
|
||||
<v-text-field
|
||||
prepend-icon="alternate_email"
|
||||
label="Email"
|
||||
outlined
|
||||
v-model="$store.state.data.contacts.email"
|
||||
:rules="rules.email" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- placeholder="Courte description qui apparaitra sur la page d'accueil" -->
|
||||
<v-textarea
|
||||
outlined
|
||||
prepend-icon="description"
|
||||
label="Description ou résumé rapide"
|
||||
placeholder="Courte description qui apparaitra sur la page d'accueil"
|
||||
:rules="rules.descriptionShort"
|
||||
counter
|
||||
v-model="$store.state.data.descriptionShort" />
|
||||
|
||||
</v-form>
|
||||
<AvatarEditor
|
||||
ref="avatarEditor"
|
||||
:loading="logoLoading"
|
||||
|
@ -56,10 +89,19 @@ export default {
|
|||
components: { AvatarEditor },
|
||||
|
||||
data: () => ({
|
||||
formValid: true,
|
||||
logoLoading: false,
|
||||
rules: {
|
||||
descriptionShort: [v => v.length <= 200 || 'Au maximum 200 caractères'],
|
||||
logo: [v => !v || v.size < 2000000 || 'La taille du logo doit être inférieur à 2 Mega Octets!']
|
||||
name: [
|
||||
v => v.length >= 3 || 'Au minimum 3 caractères',
|
||||
v => v.length <= 50 || 'Au maximum 50 caractères'
|
||||
],
|
||||
descriptionShort: [
|
||||
v => v.length >= 20 || 'Au minimum 20 caractères',
|
||||
v => v.length <= 200 || 'Au maximum 200 caractères'
|
||||
],
|
||||
email: [v => /.+@.+\..+/.test(v) || "L'email est requis et dois être valide"],
|
||||
person: [v => v.length >= 4 || 'Au minimum 4 caractères']
|
||||
}
|
||||
}),
|
||||
|
||||
|
@ -70,6 +112,14 @@ export default {
|
|||
// })
|
||||
// },
|
||||
|
||||
watch: {
|
||||
'$store.state.validateMain' (val) {
|
||||
if (val) {
|
||||
this.$store.state.validateMainCallback(this.$refs.form.validate())
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleAvatarEditorSubmitted: function (blob) {
|
||||
const form = new FormData()
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
<template>
|
||||
<div class="home">
|
||||
<v-main>
|
||||
<v-container>
|
||||
<h2 class="text-center">Vous êtes :</h2>
|
||||
|
||||
|
@ -51,8 +49,6 @@
|
|||
</ul> -->
|
||||
</v-row>
|
||||
</v-container>
|
||||
</v-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
43
src/views/NotFound.vue
Normal file
43
src/views/NotFound.vue
Normal file
|
@ -0,0 +1,43 @@
|
|||
<template>
|
||||
<v-container fluid class="gradient">
|
||||
<v-layout class="d-flex justify-center mt-3">
|
||||
<v-card class="text-center pt-10 pb-1 px-5 mt-5" max-width="500px">
|
||||
<v-card-text class="black--text">
|
||||
<div style="font-size: 5em">🤷♂️🤷</div>
|
||||
<div class="text-h4 mb-3 mt-10">Page non trouvée !</div>
|
||||
<v-divider />
|
||||
<div class="text-subtitle-1 mt-2">
|
||||
Avez-vous essayé de l'éteindre et de le rallumer?
|
||||
<span style="font-size: 1.5em">🔌</span>
|
||||
</div>
|
||||
<div class="text-subtitle-1 mt-3 mb-1 text-left">
|
||||
Liens magiques :
|
||||
<ul>
|
||||
<li><a href="https://www.youtube.com/watch?v=2B1ub5g5L0k">Pour les gens friant de video (très émetteur)</a></li>
|
||||
<li><a href="https://www.youtube.com/watch?v=StfLy3pzno0">Pour les gens qui veulent pas trop consommer de flux vidéo et donc émettre moins de CO2</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<blockquote class="grey--text text-left">
|
||||
Si vous voyez des carrés blancs à la place d'emojis alors vous devez mettre à jour votre navigateur ou pire, changer d'OS
|
||||
</blockquote>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
mounted () {
|
||||
this.$store.commit('SET_TITLE', 'Page non trouvé !')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.gradient {
|
||||
height: 100vh;
|
||||
background: rgb(52,152,219);
|
||||
background: linear-gradient(45deg, rgba(52,152,219,1) 0%, rgba(39,174,96,1) 100%);
|
||||
}
|
||||
</style>
|
|
@ -9074,10 +9074,10 @@ vm-browserify@^1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
||||
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
|
||||
|
||||
vue-apitator@^0.0.16:
|
||||
version "0.0.16"
|
||||
resolved "https://registry.yarnpkg.com/vue-apitator/-/vue-apitator-0.0.16.tgz#4c59f617aa692e7f0d3fd059424c3938a9666bea"
|
||||
integrity sha512-k0hQS8jR10avPTd28vPHjTV+H7aW2pfSz4O3gJ4D1z5J/ne4l+ygNAqQofOzgGL9bKaiojc9Guxr2f34fnUvYg==
|
||||
vue-apitator@0.0.17:
|
||||
version "0.0.17"
|
||||
resolved "https://registry.yarnpkg.com/vue-apitator/-/vue-apitator-0.0.17.tgz#3fcd925effa833956f07c63c57eaf72523c2dc0f"
|
||||
integrity sha512-xa3ChL3v2pq77x0KYQnSkrt5jSyYhvCGIKRsCQLAyvOqQqA1TPBYazBjQeEvP2FSFficIu9lJHlqp0gflkGy/A==
|
||||
dependencies:
|
||||
axios "^0.19.0"
|
||||
vue "^2.5.17"
|
||||
|
|
Loading…
Reference in a new issue