531 lines
18 KiB
Vue
531 lines
18 KiB
Vue
<template>
|
|
<div>
|
|
<div v-if="enabled">
|
|
<v-toolbar
|
|
color="orange darken-3"
|
|
dark
|
|
flat
|
|
>
|
|
<v-toolbar-title>{{ $store.state.data.name }}</v-toolbar-title>
|
|
<v-spacer></v-spacer>
|
|
<v-btn
|
|
outlined
|
|
class="mr-3"
|
|
:disabled="$store.state.delegate.validationState === 'pending'"
|
|
@click="openPublishModal()"
|
|
>
|
|
Publier
|
|
</v-btn>
|
|
<v-menu bottom close-on-content-click>
|
|
<template v-slot:activator="{ on, attrs }">
|
|
<v-btn
|
|
class="mr-2"
|
|
icon
|
|
v-bind="attrs"
|
|
v-on="on"
|
|
>
|
|
<v-icon>more_vert</v-icon>
|
|
</v-btn>
|
|
</template>
|
|
|
|
<v-list>
|
|
<v-list-item @click="openPreviewModal()">
|
|
<v-list-item-title>Prévisualiser votre page</v-list-item-title>
|
|
</v-list-item>
|
|
<v-list-item @click="goToPage()">
|
|
<v-list-item-title>Ouvrir la page publique</v-list-item-title>
|
|
</v-list-item>
|
|
<v-list-item @click="openDestroyModal()">
|
|
<v-list-item-title>Supprimer votre association</v-list-item-title>
|
|
</v-list-item>
|
|
<v-list-item @click="logout()">
|
|
<v-list-item-title>Se déconnecter</v-list-item-title>
|
|
</v-list-item>
|
|
</v-list>
|
|
</v-menu>
|
|
<!--
|
|
<v-btn icon @click="goToPage()">
|
|
<v-icon>open_in_new</v-icon>
|
|
</v-btn>
|
|
<v-btn icon @click="logout()">
|
|
<v-icon>exit_to_app</v-icon>
|
|
</v-btn> -->
|
|
<template v-slot:extension>
|
|
<v-tabs
|
|
v-model="tab"
|
|
centered
|
|
show-arrows
|
|
slider-color="accent"
|
|
ref="tabs"
|
|
>
|
|
<v-tab @click="navigate('DelegateMain')">
|
|
Présentation
|
|
</v-tab>
|
|
<v-tab @click="navigate('DelegateGallery')">
|
|
Images/vidéos
|
|
</v-tab>
|
|
<v-tab @click="navigate('DelegateDescription')">
|
|
Description
|
|
</v-tab>
|
|
<v-tab @click="navigate('DelegateSchedule')">
|
|
Horaires
|
|
</v-tab>
|
|
<v-tab @click="navigate('DelegatePricing')">
|
|
Tarifs
|
|
</v-tab>
|
|
<v-tab @click="navigate('DelegateContact')">
|
|
Contact
|
|
</v-tab>
|
|
</v-tabs>
|
|
</template>
|
|
</v-toolbar>
|
|
<v-container fluid>
|
|
<v-row class="justify-center">
|
|
<v-col cols="12" sm="12" md="8" lg="7" xl="5">
|
|
<v-alert
|
|
v-if="$store.state.delegate.validationState === 'rejected'"
|
|
prominent
|
|
dense
|
|
type="info"
|
|
border="left"
|
|
color="error">
|
|
<v-row align="center">
|
|
<v-col class="grow">
|
|
Les changements apportés ont été refusés, vous devez donc les modifier
|
|
</v-col>
|
|
<v-col class="shrink">
|
|
<v-btn outlined @click="rejectionDetailsModal = true">Pourquoi ?</v-btn>
|
|
</v-col>
|
|
</v-row>
|
|
</v-alert>
|
|
<v-alert
|
|
v-if="$store.state.delegate.validationState === 'pending'"
|
|
dense
|
|
type="error"
|
|
color="error">
|
|
Votre association est verrouillée car elle est en attente d'une vérification, même si vous pouvez faire des changements il sera impossible de les sauvegarder.
|
|
</v-alert>
|
|
<router-view></router-view>
|
|
<div class="mt-3 d-flex justify-end">
|
|
<v-btn
|
|
color="success"
|
|
:loading="isSaving"
|
|
@click="save()"
|
|
:disabled="$store.state.delegate.validationState === 'pending'"
|
|
>
|
|
<v-icon left>
|
|
check_circle
|
|
</v-icon>
|
|
Sauvegarder
|
|
</v-btn>
|
|
</div>
|
|
</v-col>
|
|
</v-row>
|
|
</v-container>
|
|
</div>
|
|
<div v-if="!enabled && loading" class="d-flex align-center justify-center mt-10 pt-10">
|
|
<v-progress-circular indeterminate color="primary" />
|
|
</div>
|
|
<div v-if="!enabled && !loading" class="d-flex align-center justify-center mt-5">
|
|
<v-card max-width="600">
|
|
<v-card-title>
|
|
Connexion au panel de modification
|
|
</v-card-title>
|
|
<v-card-text>
|
|
<p>
|
|
Vous n'êtes pas encore connecté à l'interface de modification de votre association, veuillez copier-coller la clé qui vous a été envoyé par e-mail dans la boîte ci-dessous.
|
|
</p>
|
|
<v-text-field
|
|
label="Clé"
|
|
autofocus
|
|
v-model="token"
|
|
:type="showPassword ? 'text' : 'password'"
|
|
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
|
|
v-on:keydown.enter="submitForm()"
|
|
@click:append="showPassword = !showPassword" />
|
|
</v-card-text>
|
|
<v-card-actions>
|
|
<v-spacer />
|
|
<v-btn
|
|
color="primary"
|
|
@click="submitForm()"
|
|
:disabled="token === ''">
|
|
Se connecter
|
|
</v-btn>
|
|
</v-card-actions>
|
|
</v-card>
|
|
</div>
|
|
<v-dialog v-model="publishModal" max-width="700px">
|
|
<v-card>
|
|
<v-card-title>
|
|
Demander une vérification humaine
|
|
</v-card-title>
|
|
<v-card-text>
|
|
<div v-if="canPublish">
|
|
<p>
|
|
Avant que vos changements ne soient publiés et accessibles à l'adresse <a :href="$store.state.delegate.publicUrl">{{ $store.state.delegatePublicUrl }}</a>, ils doivent être vérifiés par la personne en charge de la publication.
|
|
</p>
|
|
<p>
|
|
Veillez à ne pas demander de vérification manuelle trop souvent : veuillez limiter vos demandes.
|
|
Nous vous demandons de bien relire vos différentes modifications apportés afin de corriger d'éventuelles erreurs
|
|
</p>
|
|
<p>
|
|
La vérification étant manuelle et prenant du temps humain nous vous demandons de bien vouloir être patient, le résultat de cette vérification sera notifé à l'adresse {{ this.$store.state.delegate.email }}.
|
|
</p>
|
|
<v-alert type="warning" class="mb-0">
|
|
Attention, l'action de demander une vérification entraîne le verouillage de l'association, il ne sera plus possible de faire des modifications sur cette interface jusqu'a ce que vos changements soient validés ou rejetés.
|
|
</v-alert>
|
|
</div>
|
|
<v-alert v-else type="error" class="mt-2 mb-0">
|
|
Vous ne pouvez pas être publié car vous n'avez pas remplis les champs requis
|
|
</v-alert>
|
|
</v-card-text>
|
|
<v-card-actions>
|
|
<v-btn text @click="publishModal = false">Fermer</v-btn>
|
|
<v-spacer />
|
|
<v-btn
|
|
color="primary"
|
|
text
|
|
:disabled="!canPublish"
|
|
:loading="askingApprovalLoading"
|
|
@click="askApproval()">
|
|
Demander une vérification
|
|
</v-btn>
|
|
</v-card-actions>
|
|
</v-card>
|
|
</v-dialog>
|
|
<v-dialog v-model="rejectionDetailsModal" max-width="700px">
|
|
<v-card>
|
|
<v-card-title>
|
|
Détails sur le refus de publication
|
|
</v-card-title>
|
|
<v-card-text>
|
|
<p>
|
|
Vos changements ont été refusés, veuillez prendre connaissance de la raison :
|
|
</p>
|
|
<blockquote>
|
|
{{ $store.state.delegate.rejectionDescription }}
|
|
</blockquote>
|
|
</v-card-text>
|
|
<v-card-actions>
|
|
<v-spacer />
|
|
<v-btn color="primary" text @click="rejectionDetailsModal = false">Fermer</v-btn>
|
|
</v-card-actions>
|
|
</v-card>
|
|
</v-dialog>
|
|
<v-dialog v-model="destroyModal" max-width="600px">
|
|
<v-card>
|
|
<v-card-title>
|
|
Êtes vous sur de vouloir supprimer votre association ?
|
|
</v-card-title>
|
|
<v-card-text>
|
|
<p>
|
|
<b>Attention, ceci est une action pottentiellement dangereuse !</b>
|
|
</p>
|
|
<p>
|
|
La suppression de votre association entraine une supression <b>DEFINITIVE</b> de manière <b>IMMEDIATE</b> de toute les données associés à votre association (textes, images, vidéos...).
|
|
</p>
|
|
<p>
|
|
Cette action est <b>IRREVERSIBLE</b>.
|
|
</p>
|
|
</v-card-text>
|
|
<v-card-actions>
|
|
<div style="display:flex; justify-content:space-between; flex-wrap: wrap; width: 100%">
|
|
<v-btn color="primary" text @click="destroyModal = false">Fermer</v-btn>
|
|
<v-btn
|
|
:loading="destroyLoading"
|
|
color="error" text
|
|
@click="destroy">
|
|
je comprends, supprimer
|
|
</v-btn>
|
|
</div>
|
|
</v-card-actions>
|
|
</v-card>
|
|
</v-dialog>
|
|
<Preview
|
|
ref="preview"
|
|
:enabled="previewModal"
|
|
:id="$store.state.delegate._id"
|
|
:slug="$store.state.delegate.slug"
|
|
:dialogTitle="'Prévisualisation'"
|
|
@close="previewModal = false"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import Preview from '../components/Preview'
|
|
|
|
export default {
|
|
components: {
|
|
Preview
|
|
},
|
|
data: () => ({
|
|
enabled: false,
|
|
loading: true,
|
|
token: '',
|
|
loadingHandle: null,
|
|
isSaving: false,
|
|
tab: 0,
|
|
slug: '',
|
|
canPublish: false,
|
|
publishModal: false,
|
|
askingApprovalLoading: false,
|
|
rejectionDetailsModal: false,
|
|
showPassword: false,
|
|
previewModal: false,
|
|
destroyModal: false,
|
|
destroyLoading: false
|
|
}),
|
|
created () {
|
|
this.init()
|
|
},
|
|
watch: {
|
|
$route (to) {
|
|
this.selectRoute(to)
|
|
}
|
|
},
|
|
mounted () {
|
|
this.$store.commit('SET_TITLE', "Modification de l'association")
|
|
this.selectRoute(this.$route)
|
|
/**
|
|
* this is very ugly I kown
|
|
*/
|
|
// setTimeout(() => {
|
|
// window.dispatchEvent(new Event('resize'))
|
|
// }, 100)
|
|
// const i = setInterval(() => {
|
|
// window.dispatchEvent(new Event('resize'))
|
|
// }, 500)
|
|
// setTimeout(() => {
|
|
// window.dispatchEvent(new Event('resize'))
|
|
// }, 1000)
|
|
// setTimeout(() => {
|
|
// clearInterval(i)
|
|
// }, 3000)
|
|
},
|
|
methods: {
|
|
openPreviewModal () {
|
|
this.save(false).then(() => {
|
|
this.$refs.preview.reload()
|
|
this.previewModal = true
|
|
}).catch((err) => {
|
|
console.log(err)
|
|
})
|
|
},
|
|
selectRoute (route) {
|
|
const path = route.path.split('/')
|
|
const name = path[path.length - 1]
|
|
const routes = ['', 'gallery', 'description', 'schedule', 'pricing', 'contact']
|
|
this.tab = routes.indexOf(name)
|
|
},
|
|
init () {
|
|
this.enabled = false
|
|
|
|
this.loadingHandle = setTimeout(() => {
|
|
this.loading = true
|
|
}, 300)
|
|
|
|
let inUrl = false
|
|
let delegateToken = (new URL(window.location)).searchParams.get('delegateToken')
|
|
if (this.token !== '') {
|
|
delegateToken = this.token
|
|
}
|
|
if (delegateToken === null) {
|
|
delegateToken = window.localStorage.getItem('delegateToken')
|
|
if (delegateToken === null || delegateToken === 'null') {
|
|
clearTimeout(this.loadingHandle)
|
|
this.loading = false
|
|
return
|
|
}
|
|
} else {
|
|
inUrl = true
|
|
}
|
|
// get the size
|
|
// this.$apitator.get('/delegate/size', { withAuth: true }).then(res => {
|
|
// console.log(res.data.data)
|
|
// })
|
|
this.$apitator.setAuthorizationToken(delegateToken)
|
|
// verify the token
|
|
this.$apitator.get('/delegate', { withAuth: true }).then(res => {
|
|
window.localStorage.setItem('delegateToken', delegateToken)
|
|
if (this.token !== '') {
|
|
this.$router.push({ query: { delegateToken: this.token } })
|
|
}
|
|
clearTimeout(this.loadingHandle)
|
|
this.loading = false
|
|
this.enabled = true
|
|
const organization = res.data.data.organization
|
|
const proposedVersion = res.data.data.organization.proposedVersion
|
|
const tags = res.data.data.tags
|
|
this.$store.commit('SET_DELEGATE', {
|
|
_id: organization._id,
|
|
adminName: organization.adminName,
|
|
email: organization.email,
|
|
slug: organization.slugs[organization.slugs.length - 1],
|
|
publicUrl: process.env.VUE_APP_BASE_URL + '/association/' + organization.slugs[organization.slugs.length - 1],
|
|
validationState: organization.validationState,
|
|
rejectionDescription: organization.rejectionDescription
|
|
})
|
|
this.$store.commit('SET_DATA', proposedVersion)
|
|
this.$store.commit('SET_TAGS', tags)
|
|
this.$nextTick(() => {
|
|
setTimeout(this.$refs.tabs.callSlider, 200)
|
|
setTimeout(this.$refs.tabs.callSlider, 400)
|
|
setTimeout(this.$refs.tabs.callSlider, 500)
|
|
setTimeout(this.$refs.tabs.callSlider, 1000)
|
|
setTimeout(this.$refs.tabs.callSlider, 1500)
|
|
})
|
|
}).catch(err => {
|
|
console.log(err)
|
|
clearTimeout(this.loadingHandle)
|
|
this.loading = false
|
|
if (this.token !== '' || inUrl) {
|
|
this.$store.commit('ADD_ALERT', {
|
|
color: 'error',
|
|
text: 'Clé invalide !'
|
|
})
|
|
}
|
|
})
|
|
},
|
|
logout () {
|
|
window.localStorage.removeItem('delegateToken')
|
|
this.$router.push('/')
|
|
},
|
|
save (showSuccessAlert = true) {
|
|
return new Promise((resolve, reject) => {
|
|
this.isSaving = true
|
|
const data = this.$store.state.data
|
|
this.$apitator.put('/delegate', data, { withAuth: true }).then(() => {
|
|
this.isSaving = false
|
|
if (showSuccessAlert) {
|
|
this.$store.commit('ADD_ALERT', {
|
|
color: 'success',
|
|
text: 'Vos changements ont été sauvegardés !'
|
|
})
|
|
}
|
|
resolve()
|
|
}).catch(err => {
|
|
console.log(err.response)
|
|
if (err.response != null) {
|
|
console.log(err.response.data)
|
|
console.log(err.response.code)
|
|
}
|
|
this.isSaving = false
|
|
if (err.response != null && err.response.status === 413) {
|
|
this.$store.commit('ADD_ALERT', {
|
|
color: 'error',
|
|
text: 'Le contenu renseigné est trop grand, vous devez le réduire'
|
|
})
|
|
} else {
|
|
this.$store.commit('ADD_ALERT', {
|
|
color: 'error',
|
|
text: 'Impossible de sauvegarder vos changements'
|
|
})
|
|
}
|
|
reject(err)
|
|
})
|
|
})
|
|
},
|
|
navigate (routeName) {
|
|
if (routeName !== this.$route.name) {
|
|
this.$router.push({ name: routeName })
|
|
}
|
|
},
|
|
submitForm () {
|
|
if (this.token !== '') {
|
|
this.init()
|
|
}
|
|
},
|
|
goToPage () {
|
|
window.open(this.$store.state.delegate.publicUrl, '_blank').focus()
|
|
},
|
|
openPublishModal () {
|
|
const open = () => {
|
|
// compute if the user can ask approval
|
|
// check against rules in the store
|
|
const validation = []
|
|
const keys = Object.keys(this.$store.state.mainRules)
|
|
keys.forEach(key => {
|
|
let value = ''
|
|
if (key.indexOf('contacts.') !== -1) {
|
|
value = this.$store.state.data.contacts[key.replace('contacts.', '')]
|
|
} else {
|
|
value = this.$store.state.data[key]
|
|
}
|
|
const rules = this.$store.state.mainRules[key]
|
|
validation.push(rules.map(r => r(value)).filter(r => r === true).length === rules.length)
|
|
})
|
|
validation.push(this.$store.state.data.thumbnail.location.length > 1)
|
|
const isValid = validation.filter(v => v).length === validation.length
|
|
if (isValid) {
|
|
this.publishModal = true
|
|
this.save(false).catch((err) => {
|
|
console.log(err)
|
|
})
|
|
} else {
|
|
this.$store.commit('ADD_ALERT', {
|
|
color: 'error',
|
|
text: 'Vous devez remplir tout les champs requis afin de publier'
|
|
})
|
|
if (this.$route.name !== 'DelegateMain') {
|
|
this.$store.commit('ON_MAIN_READY', () => {
|
|
return true
|
|
})
|
|
this.$router.push({ name: 'DelegateMain' }, () => {
|
|
this.$store.commit('VALIDATE_MAIN')
|
|
})
|
|
} else {
|
|
this.$store.commit('VALIDATE_MAIN')
|
|
}
|
|
this.publishModal = false
|
|
}
|
|
this.canPublish = isValid
|
|
}
|
|
this.$store.state.validateMain = false
|
|
open()
|
|
},
|
|
askApproval () {
|
|
this.askingApprovalLoading = true
|
|
this.$apitator.post('/delegate/submit', {}, { withAuth: true }).then(() => {
|
|
this.publishModal = false
|
|
this.askingApprovalLoading = false
|
|
this.$store.commit('SET_DELEGATE', { validationState: 'pending' })
|
|
this.$store.commit('ADD_ALERT', {
|
|
color: 'success',
|
|
text: 'Les changements vont êtres soumis à une vérification manuelle'
|
|
})
|
|
}).catch(err => {
|
|
console.log(err.data)
|
|
this.askingApprovalLoading = false
|
|
this.$store.commit('ADD_ALERT', {
|
|
color: 'error',
|
|
text: "Impossible de soumettre l'association"
|
|
})
|
|
})
|
|
},
|
|
openDestroyModal () {
|
|
this.destroyModal = true
|
|
},
|
|
destroy () {
|
|
this.destroyLoading = true
|
|
this.$apitator.delete('/delegate/', { withAuth: true }).then(() => {
|
|
this.destroyModal = false
|
|
this.destroyLoading = false
|
|
this.$store.commit('ADD_ALERT', {
|
|
color: 'success',
|
|
text: "Votre association vient d'être supprimé, bonne continuation!"
|
|
})
|
|
this.logout()
|
|
}).catch(err => {
|
|
console.error(err)
|
|
this.destroyLoading = false
|
|
this.$store.commit('ADD_ALERT', {
|
|
color: 'error',
|
|
text: "Impossible de supprimer l'association"
|
|
})
|
|
})
|
|
}
|
|
}
|
|
}
|
|
</script>
|