This commit is contained in:
Matthieu Bessat 2020-07-16 17:42:49 +02:00
parent b931d5c40b
commit b8d7b53308
7 changed files with 316 additions and 87 deletions

View file

@ -0,0 +1,89 @@
<template>
<v-dialog
v-model="enabled"
fullscreen
hide-overlay
transition="dialog-bottom-transition"
scrollable
>
<v-card tile>
<v-toolbar
:prominent="false"
flat
dark
color="primary"
>
<v-btn
icon
dark
@click="$emit('close')"
>
<v-icon>mdi-close</v-icon>
</v-btn>
<v-toolbar-title v-text="dialogTitle" />
<v-spacer />
<v-toolbar-items>
<slot />
</v-toolbar-items>
</v-toolbar>
<v-card-text class="frame-container">
<iframe
class="frame"
:src="frameUrl">
</iframe>
</v-card-text>
</v-card>
</v-dialog>
</template>
<script>
export default {
props: {
slug: {
type: String,
required: true
},
enabled: {
type: Boolean,
required: true
},
dialogTitle: {
type: String,
required: true
},
version: {
type: String,
default: 'proposed'
}
},
computed: {
frameUrl () {
return process.env.VUE_APP_BASE_URL + '/association/' + this.slug + '?version=' + this.version
}
}
}
</script>
<style scoped>
.frame-container {
height: 100%;
display: flex;
}
.frame {
border: 1px solid gray;
width: 100%;
border-radius: 4px;
margin-top: 1.1em;
}
@media (max-width: 500px) {
.frame {
border-radius: 0;
border: 0;
margin-top: 0;
}
.frame-container {
padding: 0 !important;
}
}
</style>

View file

@ -51,13 +51,16 @@
</v-card-title> </v-card-title>
<v-card-text> <v-card-text>
<p> <p>
Vous n'êtes pas encore connecté à l'interface d'administration veuillez copier-coller le token dans la boîte ci-dessous. Vous n'êtes pas encore connecté à l'interface d'administration veuillez copier-coller la clée administrateur dans la boîte ci-dessous.
</p> </p>
<v-text-field <v-text-field
v-on:keydown.enter="submitForm()"
autofocus autofocus
label="Token" label="Clée"
v-model="token" /> 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-text>
<v-card-actions> <v-card-actions>
<v-spacer /> <v-spacer />
@ -80,7 +83,8 @@ export default {
left: false, left: false,
enabled: false, enabled: false,
loading: true, loading: true,
token: '' token: '',
showPassword: false
}), }),
created () { created () {
this.init() this.init()
@ -107,12 +111,16 @@ export default {
window.localStorage.setItem('adminToken', adminToken) window.localStorage.setItem('adminToken', adminToken)
this.loading = false this.loading = false
this.enabled = true this.enabled = true
// this.$store.commit('ADD_ALERT', {
// color: 'success',
// text: 'Vous voilà connecté !'
// })
}).catch(() => { }).catch(() => {
this.loading = false this.loading = false
if (this.token !== '') { if (this.token !== '') {
this.$store.commit('ADD_ALERT', { this.$store.commit('ADD_ALERT', {
color: 'error', color: 'error',
text: 'Token invalide !' text: 'Clée administrateur invalide !'
}) })
} }
}) })

View file

@ -128,10 +128,13 @@
Vous n'êtes pas encore connecté à l'interface de modification de votre association, veuillez copier-coller la clée qui vous a été envoyé par e-mail dans la boîte ci-dessous. Vous n'êtes pas encore connecté à l'interface de modification de votre association, veuillez copier-coller la clée qui vous a été envoyé par e-mail dans la boîte ci-dessous.
</p> </p>
<v-text-field <v-text-field
v-on:keydown.enter="submitForm()"
autofocus
label="Clée" label="Clée"
v-model="token" /> 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-text>
<v-card-actions> <v-card-actions>
<v-spacer /> <v-spacer />
@ -170,9 +173,16 @@
</v-alert> </v-alert>
</v-card-text> </v-card-text>
<v-card-actions> <v-card-actions>
<v-btn color="primary" text @click="publishModal = false">Fermer</v-btn> <v-btn text @click="publishModal = false">Fermer</v-btn>
<v-spacer /> <v-spacer />
<v-btn :disabled="!canPublish" text @click="askApproval()">Demander une vérification</v-btn> <v-btn
color="primary"
text
:disabled="!canPublish"
:loading="askingApprovalLoading"
@click="askApproval()">
Demander une vérification
</v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</v-dialog> </v-dialog>
@ -211,7 +221,8 @@ export default {
canPublish: false, canPublish: false,
publishModal: false, publishModal: false,
askingApprovalLoading: false, askingApprovalLoading: false,
rejectionDetailsModal: false rejectionDetailsModal: false,
showPassword: false
}), }),
created () { created () {
this.init() this.init()
@ -375,8 +386,7 @@ export default {
}, },
askApproval () { askApproval () {
this.askingApprovalLoading = true this.askingApprovalLoading = true
this.$apitator.post('/delegate/submit', {}, { withAuth: true }).then(res => { this.$apitator.post('/delegate/submit', {}, { withAuth: true }).then(() => {
console.log(res.data.data)
this.publishModal = false this.publishModal = false
this.askingApprovalLoading = false this.askingApprovalLoading = false
this.$store.commit('SET_DELEGATE', { validationState: 'pending' }) this.$store.commit('SET_DELEGATE', { validationState: 'pending' })
@ -386,7 +396,7 @@ export default {
}) })
}).catch(err => { }).catch(err => {
console.log(err.data) console.log(err.data)
this.isSaving = false this.askingApprovalLoading = false
this.$store.commit('ADD_ALERT', { this.$store.commit('ADD_ALERT', {
color: 'error', color: 'error',
text: "Impossible de soumettre l'association" text: "Impossible de soumettre l'association"

View file

@ -34,7 +34,7 @@ export default new Vuex.Store({
} }
}, },
delegate: { delegate: {
validationState: 'none', validationState: 'unaware',
admiName: '', admiName: '',
email: '', email: '',
publicUrl: '' publicUrl: ''

View file

@ -4,12 +4,14 @@
<v-data-table <v-data-table
:headers="headers" :headers="headers"
:items="organizations" :items="organizations"
sort-by="calories" sort-by="validationState"
class="elevation-1" class="elevation-1"
> >
<template v-slot:top> <template v-slot:top>
<v-toolbar flat color="white"> <v-toolbar flat color="white">
<v-toolbar-title>Gestion des associations</v-toolbar-title> <v-toolbar-title v-if="!$vuetify.breakpoint.mobile">
Gestion des associations
</v-toolbar-title>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn <v-btn
outlined outlined
@ -29,7 +31,7 @@
v-bind="attrs" v-bind="attrs"
v-on="on" v-on="on"
> >
Nouvelle association <v-icon left>add</v-icon> Association
</v-btn> </v-btn>
</template> </template>
<v-card> <v-card>
@ -84,21 +86,28 @@
<!-- <template v-slot:item.description="{ item }"> <!-- <template v-slot:item.description="{ item }">
{{ item.description|less }} {{ item.description|less }}
</template> --> </template> -->
<template v-slot:item.validationState="{ item }">
<v-chip
:color="getValidationColor(item.validationState)"
dark>
{{ getValidationText(item.validationState) }}
</v-chip>
</template>
<template v-slot:item.actions="{ item }"> <template v-slot:item.actions="{ item }">
<v-tooltip top> <v-tooltip top>
<template v-slot:activator="{ on, attrs }"> <template v-slot:activator="{ on, attrs }">
<v-btn icon small color="success"> <v-btn icon small color="success">
<v-icon <v-icon
small small
@click="openApproveModal(item)" @click="openExternal(item)"
v-bind="attrs" v-bind="attrs"
v-on="on" v-on="on"
> >
done launch
</v-icon> </v-icon>
</v-btn> </v-btn>
</template> </template>
<span>Valider les changements</span> <span>Ouvrir la page publique (version non publié)</span>
</v-tooltip> </v-tooltip>
<v-tooltip top> <v-tooltip top>
<template v-slot:activator="{ on, attrs }"> <template v-slot:activator="{ on, attrs }">
@ -145,20 +154,20 @@
</template> </template>
<span>Voir plus</span> <span>Voir plus</span>
</v-tooltip> </v-tooltip>
<v-tooltip top> <v-tooltip top v-if="item.validationState === 'pending'">
<template v-slot:activator="{ on, attrs }"> <template v-slot:activator="{ on, attrs }">
<v-btn icon small color="success"> <v-btn small icon color="success">
<v-icon <v-icon
small small
@click="openExternal(item)" @click="openApproveModal(item)"
v-bind="attrs" v-bind="attrs"
v-on="on" v-on="on"
> >
launch done
</v-icon> </v-icon>
</v-btn> </v-btn>
</template> </template>
<span>Ouvrir la page publique</span> <span>Valider les changements</span>
</v-tooltip> </v-tooltip>
</template> </template>
<template v-slot:no-data> <template v-slot:no-data>
@ -266,32 +275,38 @@
</v-card-text> </v-card-text>
<v-card-actions> <v-card-actions>
<v-spacer /> <v-spacer />
<v-btn color="blue darken-1" text @click="detailsModal = false">Fermer</v-btn> <v-btn color="primary" text @click="detailsModal = false">Fermer</v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</v-dialog> </v-dialog>
<v-dialog v-model="approveModal" max-width="700"> <Preview
:enabled="approveModal"
:slug="toApproveItem.slug"
:dialogTitle="approveModalTitle"
@close="approveModal = false"
>
<v-btn outlined dark text @click="rejectionModal = true">
<v-icon>clear</v-icon>
</v-btn>
<v-btn outlined dark text @click="approve()">
<v-icon>done</v-icon>
</v-btn>
</Preview>
<v-dialog max-width="500px" v-model="rejectionModal">
<v-card> <v-card>
<v-card-title> <v-card-title>Indiquez la raison de ce refus</v-card-title>
Vérification et publication des changements de l'association {{ toSeeItem.adminName }}
</v-card-title>
<v-card-text> <v-card-text>
<v-switch label="Les modifications sont acceptées" v-model="approved" />
<v-textarea <v-textarea
:disabled="approved" :disabled="approved"
label="Raisons du rejet" label="Description"
v-model="rejectionDescription"> v-model="rejectionDescription" />
</v-textarea>
</v-card-text> </v-card-text>
<v-card-actions> <v-card-actions>
<v-btn text @click="rejectionModal = false">Fermer</v-btn>
<v-spacer /> <v-spacer />
<v-btn color="grey darken-3" text @click="approveModal = false">Fermer</v-btn> <v-btn color="primary" text @click="reject()" :disabled="rejectionDescription.length === 0">
<v-btn Valider
color="primary" </v-btn>
text
@click="approveOrReject()"
:disabled="approved && rejectionDescription.length === 0"
>Valider</v-btn>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</v-dialog> </v-dialog>
@ -299,14 +314,20 @@
</template> </template>
<script> <script>
import Preview from '../../components/Preview'
export default { export default {
components: {
Preview
},
data: () => { data: () => {
const item = { const item = {
adminName: '', adminName: '',
email: '', email: '',
validationState: 'none', validationState: 'none',
rejectionDescription: '' rejectionDescription: '',
slug: ''
} }
return { return {
dialog: false, dialog: false,
@ -315,6 +336,10 @@ export default {
text: 'Nom interne', text: 'Nom interne',
value: 'adminName' value: 'adminName'
}, },
{
text: 'État',
value: 'validationState'
},
{ {
text: 'E-mail', text: 'E-mail',
value: 'email' value: 'email'
@ -329,19 +354,23 @@ export default {
editedItem: item, editedItem: item,
defaultItem: item, defaultItem: item,
deleteModal: false, deleteModal: false,
validationState: ['none', 'pending', 'rejected', 'published'], validationState: ['unaware', 'pending', 'rejected', 'published'],
detailsModal: false, detailsModal: false,
toSeeItem: item, toSeeItem: item,
approveModal: false, approveModal: false,
toApproveItem: item, toApproveItem: item,
rejectionDescription: '', rejectionDescription: '',
approved: false approved: false,
rejectionModal: false
} }
}, },
computed: { computed: {
formTitle () { formTitle () {
return this.editedIndex === -1 ? 'Nouvelle association' : "Modification de l'association" return this.editedIndex === -1 ? 'Nouvelle association' : "Modification de l'association"
},
approveModalTitle () {
return 'Vérification des changements apporté par "' + this.toApproveItem.adminName + '"'
} }
}, },
@ -360,6 +389,14 @@ export default {
fetchData () { fetchData () {
this.$apitator.get('/admin/organizations', { withAuth: true }).then(res => { this.$apitator.get('/admin/organizations', { withAuth: true }).then(res => {
this.organizations = res.data.data this.organizations = res.data.data
if (this.$route.query.approval !== undefined) {
const organizations = this.organizations.filter(o => o._id === this.$route.query.approval)
if (organizations.length > 0) {
this.$router.push({ query: {} })
this.openApproveModal(organizations[0])
}
}
}) })
}, },
@ -479,7 +516,7 @@ export default {
}, },
openExternal (item) { openExternal (item) {
window.open('https://forum.espacecondorcet.org/association/slug' + item.slug, '_blank').focus() window.open(process.env.VUE_APP_BASE_URL + '/association/' + item.slug + '?version=proposed', '_blank').focus()
}, },
openApproveModal (item) { openApproveModal (item) {
@ -488,35 +525,74 @@ export default {
this.approved = false this.approved = false
}, },
approveOrReject (item) { approve () {
if (this.approved) { this.$apitator.post('/admin/organizations/' + this.toApproveItem._id + '/approve', {}, { withAuth: true }).then(() => {
this.$apitator.post('/admin/organizations/' + item._id + '/approve', {}, { withAuth: true }).then(() => { this.approveModal = false
this.approveModal = false this.organizations = this.organizations.map(o => {
this.$store.commit('ADD_ALERT', { if (o._id === this.toApproveItem._id) {
color: 'success', o.validationState = 'published'
text: 'La publication est cours de réalisation et un email va être envoyé à cette association afin de notifier de cette publication' }
}) return o
}).catch(() => {
this.$store.commit('ADD_ALERT', {
color: 'error',
text: "Impossible d'approuver les changements"
})
}) })
} else { this.$store.commit('ADD_ALERT', {
this.$apitator.post('/admin/organizations/' + item._id + '/reject', { color: 'success',
rejectionDescription: this.rejectionDescription text: 'La publication est cours de réalisation et un email va être envoyé à cette association afin de notifier de cette publication'
}, { withAuth: true }).then(() => {
this.approveModal = false
this.$store.commit('ADD_ALERT', {
color: 'success',
text: "Un email va être envoyé à cette association afin d'informer du problème"
})
}).catch(() => {
this.$store.commit('ADD_ALERT', {
color: 'error',
text: 'Impossible de rejeter les changements'
})
}) })
}).catch(() => {
this.$store.commit('ADD_ALERT', {
color: 'error',
text: "Impossible d'approuver les changements"
})
})
},
reject () {
this.$apitator.post('/admin/organizations/' + this.toApproveItem._id + '/reject', {
rejectionDescription: this.rejectionDescription
}, { withAuth: true }).then(() => {
this.rejectionModal = false
this.approveModal = false
this.organizations = this.organizations.map(o => {
if (o._id === this.toApproveItem._id) {
o.validationState = 'rejected'
}
return o
})
this.$store.commit('ADD_ALERT', {
color: 'success',
text: "Un email va être envoyé à cette association afin d'informer du problème"
})
}).catch(() => {
this.$store.commit('ADD_ALERT', {
color: 'error',
text: 'Impossible de rejeter les changements'
})
})
},
getValidationColor (state) {
switch (state) {
case 'unaware':
return 'accent'
case 'published':
return 'success'
case 'rejected':
return 'error'
case 'pending':
return 'secondary'
}
},
getValidationText (state) {
switch (state) {
case 'unaware':
return 'Début'
case 'published':
return 'Publié'
case 'rejected':
return 'Refusé'
case 'pending':
return 'En attente'
} }
} }
} }

View file

@ -9,12 +9,9 @@
> >
<template v-slot:top> <template v-slot:top>
<v-toolbar flat color="white"> <v-toolbar flat color="white">
<v-toolbar-title>Gestion des catégories</v-toolbar-title> <v-toolbar-title v-if="!$vuetify.breakpoint.mobile">
<!-- <v-divider Gestion des catégories
class="mx-4" </v-toolbar-title>
inset
vertical
></v-divider> -->
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn <v-btn
outlined outlined
@ -34,7 +31,7 @@
v-bind="attrs" v-bind="attrs"
v-on="on" v-on="on"
> >
Nouvelle catégorie <v-icon left>add</v-icon> Catégorie
</v-btn> </v-btn>
</template> </template>
<v-card> <v-card>

View file

@ -2,11 +2,54 @@
<div class="home"> <div class="home">
<v-main> <v-main>
<v-container> <v-container>
<h2>Vous êtes :</h2> <h2 class="text-center">Vous êtes :</h2>
<ul>
<li><router-link :to="{name: 'DelegateMain'}">Une association</router-link></li> <v-row class="justify-center">
<li><router-link :to="{name: 'OrganizationList'}">Administrateur de l'Espace Condorcet Centre Social</router-link></li> <v-col
</ul> cols="12"
sm="12"
md="6"
lg="4"
>
<v-list>
<v-divider />
<div
v-for="nav in navItems"
:key="nav.target">
<v-list-item
:to="{ name: nav.target }"
ripple
class="d-flex justify-center"
>
<v-list-item-avatar>
<v-icon color="primary">{{ nav.icon }}</v-icon>
</v-list-item-avatar>
<v-list-item-content style="flex: initial;">
<v-list-item-title>
{{ nav.name }}
</v-list-item-title>
</v-list-item-content>
</v-list-item>
<v-divider />
</div>
<!-- <v-divider />
<v-list-item :to="{name: 'OrganizationList'}" ripple>
<v-list-item-avatar>
<v-icon color="error">build</v-icon>
</v-list-item-avatar>
<v-list-item-content style="flex: initial;">
<v-list-item-title>
Un administrateur
</v-list-item-title>
</v-list-item-content>
</v-list-item> -->
</v-list>
</v-col>
<!-- <ul>
<li><router-link :to="{name: 'DelegateMain'}">Une association</router-link></li>
<li><router-link :to="{name: 'OrganizationList'}">Administrateur de l'Espace Condorcet Centre Social</router-link></li>
</ul> -->
</v-row>
</v-container> </v-container>
</v-main> </v-main>
</div> </div>
@ -14,6 +57,12 @@
<script> <script>
export default { export default {
name: 'Home' name: 'Home',
data: () => ({
navItems: [
{ name: 'Une association', target: 'DelegateMain', icon: 'group' },
{ name: 'Un administrateur', target: 'OrganizationList', icon: 'build' }
]
})
} }
</script> </script>