update
This commit is contained in:
parent
e3fbebe1b8
commit
4791bd8037
30 changed files with 15738 additions and 278 deletions
|
|
@ -1,13 +1,515 @@
|
|||
<template>
|
||||
<div>
|
||||
OrganizationList
|
||||
</div>
|
||||
<v-row no-gutters class="d-flex justify-center">
|
||||
<v-col cols="12" xl="8" md="10" sm="12">
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
:items="organizations"
|
||||
sort-by="calories"
|
||||
class="elevation-1"
|
||||
>
|
||||
<template v-slot:top>
|
||||
<v-toolbar flat color="white">
|
||||
<v-toolbar-title>Gestion des associations</v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn
|
||||
outlined
|
||||
color="primary"
|
||||
dark
|
||||
@click="fetchData()"
|
||||
class="mb-2 mr-2"
|
||||
>
|
||||
<v-icon>refresh</v-icon>
|
||||
</v-btn>
|
||||
<v-dialog v-model="dialog" max-width="500px">
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn
|
||||
color="primary"
|
||||
dark
|
||||
class="mb-2"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
>
|
||||
Nouvelle association
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
<span class="headline">{{ formTitle }}</span>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
v-model="editedItem.adminName"
|
||||
required
|
||||
label="Nom (interne) de l'associatiton">
|
||||
</v-text-field>
|
||||
<v-text-field
|
||||
v-model="editedItem.email"
|
||||
label="E-mail utilisé pour recevoir le lien/la clé d'identification">
|
||||
</v-text-field>
|
||||
<v-select
|
||||
:items="validationState"
|
||||
v-model="editedItem.validationState"
|
||||
label="DEBUG: status de la validation"
|
||||
></v-select>
|
||||
<div v-if="editedIndex === -1">
|
||||
<p>
|
||||
Remarque : Lorsque vous allez créer cette association un email contenant le lien de connexion va être automatiquement envoyé sur l'adresse renseignée.
|
||||
</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p>
|
||||
Remarque : Si l'email change lors d'une modification, rien ne sera fait en plus.
|
||||
Si vous voulez envoyer un email contenant le lient de connexion, vous devez utiliser le bouton dédié pour ça.
|
||||
</p>
|
||||
</div>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="grey darken-3" text @click="close">Annuler</v-btn>
|
||||
<v-btn color="blue darken-1" text @click="save">Valider</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-toolbar>
|
||||
</template>
|
||||
<!-- <template v-slot:item.icon="{ item }">
|
||||
</template> -->
|
||||
<!-- <template v-slot:item.description="{ item }">
|
||||
{{ item.description|less }}
|
||||
</template> -->
|
||||
<template v-slot:item.actions="{ item }">
|
||||
<v-tooltip top>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn icon small color="success">
|
||||
<v-icon
|
||||
small
|
||||
@click="openApproveModal(item)"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
>
|
||||
done
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<span>Valider les changements</span>
|
||||
</v-tooltip>
|
||||
<v-tooltip top>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn icon small color="info">
|
||||
<v-icon
|
||||
small
|
||||
@click="editItem(item)"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
>
|
||||
mdi-pencil
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<span>Modifier</span>
|
||||
</v-tooltip>
|
||||
<v-tooltip top>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn icon small color="error">
|
||||
<v-icon
|
||||
small
|
||||
@click="openDeleteModal(item)"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
>
|
||||
mdi-delete
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<span>Supprimer</span>
|
||||
</v-tooltip>
|
||||
<v-tooltip top>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn icon small color="primary">
|
||||
<v-icon
|
||||
small
|
||||
@click="openDetailsModal(item)"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
>
|
||||
visibility
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<span>Voir plus</span>
|
||||
</v-tooltip>
|
||||
<v-tooltip top>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn icon small color="success">
|
||||
<v-icon
|
||||
small
|
||||
@click="openExternal(item)"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
>
|
||||
launch
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<span>Ouvrir la page publique</span>
|
||||
</v-tooltip>
|
||||
</template>
|
||||
<template v-slot:no-data>
|
||||
<span>Aucune associations n'ont été crées jusqu'a présent</span>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-col>
|
||||
<v-dialog v-model="deleteModal" max-width="600">
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
Voulez vous vraiment supprimer cette association ?
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<b>Attention, cette action est irréversible !</b>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn color="blue darken-1" text @click="deleteModal = false">Annuler</v-btn>
|
||||
<v-btn color="red darken-1" text @click="deleteItem">Supprimer</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
<v-dialog v-model="detailsModal" max-width="600">
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
Détails et actions sur l'association {{ toSeeItem.adminName }}
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<!-- show dates, status, current and published version page link, token -->
|
||||
<!-- action: reset token, send email -->
|
||||
<v-list two-line>
|
||||
|
||||
<v-divider />
|
||||
<v-list-item>
|
||||
<v-list-item-icon>
|
||||
<v-icon>vpn_key</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ toSeeItem.token }}</v-list-item-title>
|
||||
<v-list-item-subtitle>Token/clée</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
<v-divider />
|
||||
<v-list-item>
|
||||
<v-list-item-icon>
|
||||
<v-icon>update</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ toSeeItem.createdAt }}</v-list-item-title>
|
||||
<v-list-item-subtitle>Date de création</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
<div v-if="toSeeItem.updatedAt !== undefined">
|
||||
<v-list-item>
|
||||
<v-list-item-action />
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ toSeeItem.updatedAt }}</v-list-item-title>
|
||||
<v-list-item-subtitle>Date de dernière mise à jour</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</div>
|
||||
|
||||
<div v-if="toSeeItem.publishedAt !== undefined">
|
||||
<v-divider />
|
||||
<v-list-item>
|
||||
<v-list-item-action />
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>{{ toSeeItem.publishedAt }}</v-list-item-title>
|
||||
<v-list-item-subtitle>Date de dernière publication</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</div>
|
||||
|
||||
<v-divider />
|
||||
<v-list-item three-line>
|
||||
<v-list-item-icon>
|
||||
<v-icon>refresh</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>Générer une nouvelle clé</v-list-item-title>
|
||||
<v-list-item-subtitle>Cette action va remplacer les clés existantes par une nouvelle clé généré aléatoirement</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<v-btn color="info" outlined @click="generateToken(toSeeItem)" small>Générer</v-btn>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
|
||||
<v-divider />
|
||||
<v-list-item>
|
||||
<v-list-item-icon>
|
||||
<v-icon>email</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title>Envoyer un email contenant la clé</v-list-item-title>
|
||||
<v-list-item-subtitle>Un message sera envoyé contenant le token existant</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
<v-list-item-action>
|
||||
<v-btn color="teal" outlined @click="sendEmailToken(toSeeItem)" small>Envoyer</v-btn>
|
||||
</v-list-item-action>
|
||||
</v-list-item>
|
||||
<v-divider />
|
||||
</v-list>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn color="blue darken-1" text @click="detailsModal = false">Fermer</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
<v-dialog v-model="approveModal" max-width="700">
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
Vérification et publication des changements de l'association {{ toSeeItem.adminName }}
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-switch label="Les modifications sont acceptées" v-model="approved" />
|
||||
<v-textarea
|
||||
:disabled="approved"
|
||||
label="Raisons du rejet"
|
||||
v-model="rejectionDescription">
|
||||
</v-textarea>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn color="grey darken-3" text @click="approveModal = false">Fermer</v-btn>
|
||||
<v-btn
|
||||
color="primary"
|
||||
text
|
||||
@click="approveOrReject()"
|
||||
:disabled="approved && rejectionDescription.length === 0"
|
||||
>Valider</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
mounted () {
|
||||
console.log('dzqsd')
|
||||
|
||||
data: () => {
|
||||
const item = {
|
||||
adminName: '',
|
||||
email: '',
|
||||
validationState: 'none'
|
||||
}
|
||||
return {
|
||||
dialog: false,
|
||||
headers: [
|
||||
{
|
||||
text: 'Nom interne',
|
||||
value: 'adminName'
|
||||
},
|
||||
{
|
||||
text: 'E-mail',
|
||||
value: 'email'
|
||||
},
|
||||
{
|
||||
text: 'Actions',
|
||||
value: 'actions'
|
||||
}
|
||||
],
|
||||
organizations: [],
|
||||
editedIndex: -1,
|
||||
editedItem: item,
|
||||
defaultItem: item,
|
||||
deleteModal: false,
|
||||
validationState: ['none', 'pending', 'rejected', 'published'],
|
||||
detailsModal: false,
|
||||
toSeeItem: item,
|
||||
approveModal: false,
|
||||
toApproveItem: item,
|
||||
rejectionDescription: '',
|
||||
approved: false
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
formTitle () {
|
||||
return this.editedIndex === -1 ? 'Nouvelle association' : "Modification de l'association"
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
dialog (val) {
|
||||
val || this.close()
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.$store.commit('SET_TITLE', 'Gestion des associations')
|
||||
this.fetchData()
|
||||
},
|
||||
|
||||
methods: {
|
||||
fetchData () {
|
||||
this.$apitator.get('/admin/organizations', { withAuth: true }).then(res => {
|
||||
this.organizations = res.data.data
|
||||
})
|
||||
},
|
||||
|
||||
editItem (item) {
|
||||
this.editedIndex = this.organizations.indexOf(item)
|
||||
this.editedItem = Object.assign({}, item)
|
||||
this.dialog = true
|
||||
},
|
||||
|
||||
openDeleteModal (item) {
|
||||
this.toDeleteItem = item
|
||||
this.deleteModal = true
|
||||
},
|
||||
|
||||
deleteItem () {
|
||||
const index = this.organizations.indexOf(this.toDeleteItem)
|
||||
if (confirm('Êtes vous sûr de vouloir supprimer cette association ?')) {
|
||||
this.organizations.splice(index, 1)
|
||||
this.$apitator.delete('/admin/organizations/' + this.toDeleteItem._id, { withAuth: true }).then(() => {
|
||||
this.deleteModal = false
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'success',
|
||||
text: "Cette association vient d'être supprimé"
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
openDetailsModal (item) {
|
||||
this.toSeeItem = item
|
||||
this.detailsModal = true
|
||||
},
|
||||
|
||||
close () {
|
||||
this.dialog = false
|
||||
this.$nextTick(() => {
|
||||
this.editedItem = Object.assign({}, this.defaultItem)
|
||||
this.editedIndex = -1
|
||||
})
|
||||
},
|
||||
|
||||
save () {
|
||||
if (this.editedIndex > -1) {
|
||||
// call the api to update the organization
|
||||
this.$apitator.put('/admin/organizations/' + this.editedItem._id, {
|
||||
adminName: this.editedItem.adminName,
|
||||
email: this.editedItem.email,
|
||||
validationState: this.editedItem.validationState
|
||||
}, { withAuth: true }).then(res => {
|
||||
console.log(res.data)
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'success',
|
||||
text: 'Association mise à jour'
|
||||
})
|
||||
this.fetchData()
|
||||
this.close()
|
||||
}).catch(() => {
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'error',
|
||||
text: 'Impossible de modifier cette association'
|
||||
})
|
||||
})
|
||||
} else {
|
||||
// call the api to store the organization
|
||||
this.$apitator.post('/admin/organizations', {
|
||||
adminName: this.editedItem.adminName,
|
||||
email: this.editedItem.email,
|
||||
validationState: this.editedItem.validationState
|
||||
}, { withAuth: true }).then(() => {
|
||||
this.fetchData()
|
||||
this.close()
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'success',
|
||||
text: 'Association ajoutée'
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'error',
|
||||
text: "Impossible d'ajouter cette association"
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
generateToken (item) {
|
||||
if (!confirm('Êtes vous sur de reinitialiser la clée de cette association ? Les liens de connexions existants seront inutilisables.')) {
|
||||
return
|
||||
}
|
||||
this.$apitator.post('/admin/organizations/' + item._id + '/reset-token', {}, { withAuth: true }).then(() => {
|
||||
this.detailsModal = false
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'success',
|
||||
text: 'La clée de cette association a été reinitialisé'
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'error',
|
||||
text: 'Impossible de reinitialiser la clée de cette association'
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
sendEmailToken (item) {
|
||||
this.$apitator.post('/admin/organizations/' + item._id + '/send-email-token', {}, { withAuth: true }).then(() => {
|
||||
this.detailsModal = false
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'success',
|
||||
text: 'Un email va être envoyé à cette association contenant la clée'
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'error',
|
||||
text: "Impossible d'envoyer un email à cette association"
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
openExternal (item) {
|
||||
window.open('https://forum.espacecondorcet.org/association/slug' + item.slug, '_blank').focus()
|
||||
},
|
||||
|
||||
openApproveModal (item) {
|
||||
this.approveModal = true
|
||||
this.toApproveItem = item
|
||||
this.approved = false
|
||||
},
|
||||
|
||||
approveOrReject (item) {
|
||||
if (this.approved) {
|
||||
this.$apitator.post('/admin/organizations/' + item._id + '/approve', {}, { withAuth: true }).then(() => {
|
||||
this.approveModal = false
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'success',
|
||||
text: 'La publication est cours de réalisation et un email va être envoyé à cette association afin de notifier de cette publication'
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'error',
|
||||
text: "Impossible d'approuver les changements"
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.$apitator.post('/admin/organizations/' + item._id + '/reject', {
|
||||
rejectionDescription: this.rejectionDescription
|
||||
}, { 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'
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,110 +1,114 @@
|
|||
<template>
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
:items="tags"
|
||||
sort-by="calories"
|
||||
class="elevation-1"
|
||||
>
|
||||
<template v-slot:top>
|
||||
<v-toolbar flat color="white">
|
||||
<v-toolbar-title>Gestion des catégories</v-toolbar-title>
|
||||
<!-- <v-divider
|
||||
class="mx-4"
|
||||
inset
|
||||
vertical
|
||||
></v-divider> -->
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn
|
||||
outlined
|
||||
color="primary"
|
||||
dark
|
||||
@click="fetchData()"
|
||||
class="mb-2 mr-2"
|
||||
>
|
||||
<v-icon>refresh</v-icon>
|
||||
</v-btn>
|
||||
<v-dialog v-model="dialog" max-width="500px">
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-row no-gutters class="d-flex justify-center">
|
||||
<v-col cols="12" xl="8" md="10" sm="12">
|
||||
<v-data-table
|
||||
:headers="headers"
|
||||
:items="tags"
|
||||
sort-by="name"
|
||||
class="elevation-1"
|
||||
>
|
||||
<template v-slot:top>
|
||||
<v-toolbar flat color="white">
|
||||
<v-toolbar-title>Gestion des catégories</v-toolbar-title>
|
||||
<!-- <v-divider
|
||||
class="mx-4"
|
||||
inset
|
||||
vertical
|
||||
></v-divider> -->
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn
|
||||
outlined
|
||||
color="primary"
|
||||
dark
|
||||
class="mb-2"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
@click="fetchData()"
|
||||
class="mb-2 mr-2"
|
||||
>
|
||||
Nouvelle catégorie
|
||||
<v-icon>refresh</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
<span class="headline">{{ formTitle }}</span>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
v-model="editedItem.name"
|
||||
required
|
||||
label="Nom de la catégorie">
|
||||
</v-text-field>
|
||||
<v-text-field
|
||||
v-model="editedItem.icon"
|
||||
label="Icône de la catégorie">
|
||||
</v-text-field>
|
||||
<v-text-field
|
||||
v-model="editedItem.description"
|
||||
label="Description de la catégorie">
|
||||
</v-text-field>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="blue darken-1" text @click="close">Annuler</v-btn>
|
||||
<v-btn color="blue darken-1" text @click="save">Valider</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-toolbar>
|
||||
</template>
|
||||
<template v-slot:item.icon="{ item }">
|
||||
<div style="display:flex">
|
||||
<svg
|
||||
style="width: 1em; margin-right: .75em"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="camera"
|
||||
class="svg-inline--fa fa-camera fa-w-16"
|
||||
role="img"
|
||||
:viewBox="'0 0 ' + item.icon.width + ' ' + item.icon.height"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor" :d="item.icon.path"></path>
|
||||
</svg>
|
||||
<span>{{ item.icon.id }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.description="{ item }">
|
||||
{{ item.description|less }}
|
||||
</template>
|
||||
<template v-slot:item.actions="{ item }">
|
||||
<v-btn icon small color="info">
|
||||
<v-icon
|
||||
small
|
||||
@click="editItem(item)"
|
||||
>
|
||||
mdi-pencil
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon small color="error">
|
||||
<v-icon
|
||||
small
|
||||
@click="deleteItem(item)"
|
||||
>
|
||||
mdi-delete
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<template v-slot:no-data>
|
||||
<span>Aucune catégories n'ont été crées jusqu'a présent</span>
|
||||
</template>
|
||||
</v-data-table>
|
||||
<v-dialog v-model="dialog" max-width="500px">
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<v-btn
|
||||
color="primary"
|
||||
dark
|
||||
class="mb-2"
|
||||
v-bind="attrs"
|
||||
v-on="on"
|
||||
>
|
||||
Nouvelle catégorie
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
<span class="headline">{{ formTitle }}</span>
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
v-model="editedItem.name"
|
||||
required
|
||||
label="Nom de la catégorie">
|
||||
</v-text-field>
|
||||
<v-text-field
|
||||
v-model="editedItem.icon"
|
||||
label="Icône de la catégorie">
|
||||
</v-text-field>
|
||||
<v-text-field
|
||||
v-model="editedItem.description"
|
||||
label="Description de la catégorie">
|
||||
</v-text-field>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn color="grey darken-3" text @click="close">Annuler</v-btn>
|
||||
<v-btn color="blue darken-1" text @click="save">Valider</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-toolbar>
|
||||
</template>
|
||||
<template v-slot:item.icon="{ item }">
|
||||
<div style="display:flex">
|
||||
<svg
|
||||
style="width: 1em; margin-right: .75em"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="camera"
|
||||
class="svg-inline--fa fa-camera fa-w-16"
|
||||
role="img"
|
||||
:viewBox="'0 0 ' + item.icon.width + ' ' + item.icon.height"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="currentColor" :d="item.icon.path"></path>
|
||||
</svg>
|
||||
<span>{{ item.icon.id }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:item.description="{ item }">
|
||||
{{ item.description|less }}
|
||||
</template>
|
||||
<template v-slot:item.actions="{ item }">
|
||||
<v-btn icon small color="info">
|
||||
<v-icon
|
||||
small
|
||||
@click="editItem(item)"
|
||||
>
|
||||
mdi-pencil
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon small color="error">
|
||||
<v-icon
|
||||
small
|
||||
@click="deleteItem(item)"
|
||||
>
|
||||
mdi-delete
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<template v-slot:no-data>
|
||||
<span>Aucune catégories n'ont été crées jusqu'a présent</span>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -119,7 +123,7 @@ export default {
|
|||
width: 200
|
||||
},
|
||||
{
|
||||
text: 'Icone',
|
||||
text: 'Icône',
|
||||
value: 'icon',
|
||||
width: 250
|
||||
},
|
||||
|
|
@ -160,6 +164,7 @@ export default {
|
|||
},
|
||||
|
||||
created () {
|
||||
this.$store.commit('SET_TITLE', 'Gestion des tags')
|
||||
this.fetchData()
|
||||
},
|
||||
|
||||
|
|
|
|||
51
src/views/Delegate/Contact.vue
Normal file
51
src/views/Delegate/Contact.vue
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="mb-2">
|
||||
<p class="text-body">
|
||||
Ici vous pouvez préciser quelques manières de contacter votre association, aucun des champs indiqués n'est obligatoire.
|
||||
</p>
|
||||
</div>
|
||||
<v-text-field
|
||||
prepend-icon="person"
|
||||
label="Personne responsable"
|
||||
outlined
|
||||
v-model="$store.state.data.contacts.person" />
|
||||
<v-text-field
|
||||
prepend-icon="call"
|
||||
label="Numéro de téléphone"
|
||||
outlined
|
||||
v-model="$store.state.data.contacts.phone" />
|
||||
<v-text-field
|
||||
prepend-icon="public"
|
||||
label="Site web"
|
||||
outlined
|
||||
v-model="$store.state.data.contacts.website" />
|
||||
<v-textarea
|
||||
prepend-icon="room"
|
||||
label="Adresse"
|
||||
outlined
|
||||
v-model="$store.state.data.contacts.address" />
|
||||
<v-text-field
|
||||
prepend-icon="$vuetify.icons.facebook"
|
||||
label="Compte facebook"
|
||||
outlined
|
||||
v-model="$store.state.data.contacts.facebook" />
|
||||
<v-text-field
|
||||
prepend-icon="$vuetify.icons.twitter"
|
||||
label="Compte twitter"
|
||||
outlined
|
||||
v-model="$store.state.data.contacts.twitter" />
|
||||
<v-text-field
|
||||
prepend-icon="$vuetify.icons.instagram"
|
||||
label="Compte instagram"
|
||||
outlined
|
||||
v-model="$store.state.data.contacts.instagram" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: () => ({}),
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
5
src/views/Delegate/Gallery.vue
Normal file
5
src/views/Delegate/Gallery.vue
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
Gallery
|
||||
</div>
|
||||
</template>
|
||||
77
src/views/Delegate/Main.vue
Normal file
77
src/views/Delegate/Main.vue
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
<template>
|
||||
<div>
|
||||
<v-row class="mb-5">
|
||||
<v-col cols="12" sm="12" md="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-btn @click="$refs.avatarEditor.toggle()" color="primary">Changer le logo</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row style="align-items: center;">
|
||||
<v-col cols="12" sm="12" md="12">
|
||||
<v-text-field
|
||||
label="Nom de l'association"
|
||||
outlined
|
||||
prepend-icon="label"
|
||||
v-model="$store.state.data.name" />
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-textarea
|
||||
outlined
|
||||
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" />
|
||||
|
||||
<AvatarEditor
|
||||
ref="avatarEditor"
|
||||
:loading="logoLoading"
|
||||
@submitted="handleAvatarEditorSubmitted"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AvatarEditor from '../../components/AvatarEditor'
|
||||
|
||||
export default {
|
||||
components: { AvatarEditor },
|
||||
|
||||
data: () => ({
|
||||
logoLoading: false,
|
||||
rules: {
|
||||
descriptionShort: [v => v.length <= 100 || 'Au maximum 100 caractères'],
|
||||
logo: [v => !v || v.size < 2000000 || 'La taille du logo doit être inférieur à 2 Mega Octets!']
|
||||
}
|
||||
}),
|
||||
|
||||
methods: {
|
||||
handleAvatarEditorSubmitted: function (blob) {
|
||||
const form = new FormData()
|
||||
form.append('file', blob, blob.filename)
|
||||
this.logoLoading = true
|
||||
this.$apitator.post('/delegate/thumbnail', form, { withAuth: true }).then(res => {
|
||||
this.logoLoading = false
|
||||
this.$store.commit('SET_DATA', { thumbnail: res.data.thumbnail })
|
||||
this.$refs.avatarEditor.finish()
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'success',
|
||||
text: 'Logo mis à jour !'
|
||||
})
|
||||
}).catch(() => {
|
||||
this.logoLoading = false
|
||||
this.$store.commit('ADD_ALERT', {
|
||||
color: 'error',
|
||||
text: 'Impossible de mettre à jour le logo'
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
56
src/views/Delegate/Presentation.vue
Normal file
56
src/views/Delegate/Presentation.vue
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<template>
|
||||
<div>
|
||||
<tiptap-vuetify
|
||||
v-model="$store.state.data.descriptionLong"
|
||||
:extensions="tiptapExtensions"
|
||||
placeholder="Décrivez ici votre association plus en détail (section présentation)"
|
||||
min-height="15em"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import 'tiptap-vuetify/dist/main.css'
|
||||
import {
|
||||
TiptapVuetify,
|
||||
Heading,
|
||||
Bold,
|
||||
Italic,
|
||||
Underline,
|
||||
Paragraph,
|
||||
BulletList,
|
||||
OrderedList,
|
||||
ListItem,
|
||||
Link,
|
||||
Blockquote,
|
||||
HardBreak,
|
||||
HorizontalRule,
|
||||
History
|
||||
} from 'tiptap-vuetify'
|
||||
|
||||
export default {
|
||||
components: { TiptapVuetify },
|
||||
|
||||
data: () => ({
|
||||
tiptapExtensions: [
|
||||
History,
|
||||
Blockquote,
|
||||
Link,
|
||||
Underline,
|
||||
Italic,
|
||||
ListItem,
|
||||
BulletList,
|
||||
OrderedList,
|
||||
[Heading, {
|
||||
options: {
|
||||
levels: [1, 2, 3]
|
||||
}
|
||||
}],
|
||||
Bold,
|
||||
HorizontalRule,
|
||||
Paragraph,
|
||||
HardBreak
|
||||
]
|
||||
})
|
||||
}
|
||||
</script>
|
||||
167
src/views/Delegate/Pricing.vue
Normal file
167
src/views/Delegate/Pricing.vue
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="d-flex justify-end">
|
||||
<v-btn @click="openAddModal()" color="teal" outlined>
|
||||
<v-icon left>add</v-icon>
|
||||
Ajouter un tarif
|
||||
</v-btn>
|
||||
</div>
|
||||
<div
|
||||
v-if="$store.state.data.pricing.length === 0"
|
||||
class="mb-2 mt-2 d-flex justify-center">
|
||||
<span class="text-gray">
|
||||
Pas de tarifs ajoutés
|
||||
</span>
|
||||
</div>
|
||||
<v-row v-else>
|
||||
<v-col
|
||||
v-for="pricing in $store.state.data.pricing"
|
||||
:key="pricing._id"
|
||||
cols="12"
|
||||
sm="12"
|
||||
md="6"
|
||||
lg="6"
|
||||
>
|
||||
<v-card
|
||||
class="mx-auto"
|
||||
max-width="344"
|
||||
>
|
||||
<v-card-text>
|
||||
<div v-text="pricing.name" />
|
||||
<div
|
||||
v-text="pricing.priceLabel"
|
||||
class="mb-2 mt-2 display-1 text--primary" />
|
||||
<div
|
||||
v-text="pricing.description"
|
||||
class="text--primary" />
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
@click="openDeleteModal(pricing)"
|
||||
icon
|
||||
color="error"
|
||||
>
|
||||
<v-icon>delete</v-icon>
|
||||
</v-btn>
|
||||
<v-btn
|
||||
@click="openEditModal(pricing)"
|
||||
icon
|
||||
color="info"
|
||||
>
|
||||
<v-icon>edit</v-icon>
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-dialog
|
||||
max-width="500"
|
||||
v-model="itemModal">
|
||||
<v-card>
|
||||
<v-card-title v-text="itemModalTitle + ' un tarif'" />
|
||||
<v-card-text>
|
||||
<v-text-field
|
||||
v-model="item.priceLabel"
|
||||
label="Tarif"
|
||||
hint="Requis"
|
||||
/>
|
||||
<v-text-field
|
||||
v-model="item.name"
|
||||
label="Nom/Titre du tarif"
|
||||
hint="Requis"
|
||||
/>
|
||||
<v-text-field
|
||||
v-model="item.description"
|
||||
label="Description/Sous Titre du tarif"
|
||||
hint="Optionel"
|
||||
/>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn @click="itemModal = false" text color="primary">
|
||||
Fermer
|
||||
</v-btn>
|
||||
<v-spacer />
|
||||
<v-btn @click="save()" text color="success">
|
||||
Valider
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
<v-dialog
|
||||
max-width="500"
|
||||
v-model="deleteModal">
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
Voulez vous vraiment supprimer ce tarif ?
|
||||
</v-card-title>
|
||||
<v-card-actions>
|
||||
<v-btn @click="deleteModal = false" text color="primary">
|
||||
Fermer
|
||||
</v-btn>
|
||||
<v-spacer />
|
||||
<v-btn @click="destroy()" text color="error">
|
||||
Supprimer
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: () => ({
|
||||
itemModal: false,
|
||||
mode: '',
|
||||
item: {
|
||||
priceLabel: '',
|
||||
name: '',
|
||||
description: ''
|
||||
},
|
||||
toDelete: {},
|
||||
deleteModal: false,
|
||||
oldEdit: {}
|
||||
}),
|
||||
created () {
|
||||
this.item = JSON.parse('{"priceLabel":"3.14159 €","name":"Hippie","description":"Vomissures que ce juillets haleurs haleurs dont, roulant"}')
|
||||
},
|
||||
computed: {
|
||||
itemModalTitle () { return this.mode === 'add' ? 'Ajouter' : 'Editer' }
|
||||
},
|
||||
methods: {
|
||||
openAddModal () {
|
||||
this.mode = 'add'
|
||||
this.itemModal = true
|
||||
},
|
||||
save () {
|
||||
let pricing = this.$store.state.data.pricing
|
||||
if (this.mode === 'add') {
|
||||
this.item._id = Date.now().toString()
|
||||
pricing.push(this.item)
|
||||
} else {
|
||||
pricing = pricing.map(i => i === this.oldEdit ? this.item : i)
|
||||
}
|
||||
|
||||
this.$store.commit('SET_DATA', { pricing })
|
||||
this.itemModal = false
|
||||
},
|
||||
openEditModal (item) {
|
||||
this.item = item
|
||||
this.oldEdit = item
|
||||
this.mode = 'edit'
|
||||
this.itemModal = true
|
||||
},
|
||||
openDeleteModal (item) {
|
||||
this.deleteModal = true
|
||||
this.toDelete = item
|
||||
},
|
||||
destroy () {
|
||||
let pricing = this.$store.state.data.pricing
|
||||
pricing = pricing.filter(item => item !== this.toDelete)
|
||||
this.$store.commit('SET_DATA', { pricing })
|
||||
this.deleteModal = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
115
src/views/Delegate/Schedule.vue
Normal file
115
src/views/Delegate/Schedule.vue
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="d-flex">
|
||||
<div
|
||||
class="schedule-item"
|
||||
v-for="item in scheduleData"
|
||||
:key="item.name"
|
||||
>
|
||||
<!--
|
||||
cols="12"
|
||||
sm="12"
|
||||
md="6"
|
||||
lg="6"
|
||||
-->
|
||||
<v-card>
|
||||
<v-card-title>
|
||||
<div class="subheading font-weight-bold">{{ item.name }}</div>
|
||||
<div class="text-subtitle-2">{{ item.description }}</div>
|
||||
</v-card-title>
|
||||
|
||||
<v-divider></v-divider>
|
||||
|
||||
<v-list dense>
|
||||
<v-list-item
|
||||
v-for="when in item.when"
|
||||
:key="when.day">
|
||||
<v-list-item-content>{{ when.day }}</v-list-item-content>
|
||||
<v-list-item-content class="align-end">
|
||||
{{ when.from }} - {{ when.to }}
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: () => ({
|
||||
scheduleData: [
|
||||
{
|
||||
name: 'Création de robot super cool',
|
||||
description: 'Clita duo sanctus sed rebum elitr dolores et lorem stet',
|
||||
when: [
|
||||
{
|
||||
day: 'Lundi',
|
||||
from: '13:45',
|
||||
to: '14:25'
|
||||
},
|
||||
{
|
||||
day: 'Mardi',
|
||||
from: '10:30',
|
||||
to: '11:00'
|
||||
},
|
||||
{
|
||||
day: 'Mecredi',
|
||||
from: '09:00',
|
||||
to: '10:00'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Introduction à la programmation',
|
||||
description: 'Clita duo sanctus sed rebum elitr dolores et lorem stetEt ipsum sit et invidunt invidunt tempor lorem consetetur amet, takimata elitr sanctus nonumy at amet ut ut. Justo et stet sanctus no at at, sit ut sit vero rebum ipsum aliquyam vero. Ea at diam vero vero magna kasd ipsum. Diam ipsum amet consetetur sadipscing amet, sed lorem dolor.',
|
||||
when: [
|
||||
{
|
||||
day: 'Lundi',
|
||||
from: '13:45',
|
||||
to: '14:25'
|
||||
},
|
||||
{
|
||||
day: 'Mardi',
|
||||
from: '10:30',
|
||||
to: '11:00'
|
||||
},
|
||||
{
|
||||
day: 'Mecredi',
|
||||
from: '09:00',
|
||||
to: '10:00'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Ldsldsllds',
|
||||
description: 'Clita duo sanctus sed rebum elitr dolores et lorem stetEt ipsum sit et invidunt invidunt tempor lorem consetetur amet, takimata elitr sanctus nonumy at amet ut ut. Justo et stet sanctus no at at, sit ut sit vero rebum ipsum aliquyam vero. Ea at diam vero vero magna kasd ipsum. Diam ipsum amet consetetur sadipscing amet, sed lorem dolor.',
|
||||
when: [
|
||||
{
|
||||
day: 'Lundi',
|
||||
from: '13:45',
|
||||
to: '14:25'
|
||||
},
|
||||
{
|
||||
day: 'Mardi',
|
||||
from: '10:30',
|
||||
to: '11:00'
|
||||
},
|
||||
{
|
||||
day: 'Mecredi',
|
||||
from: '09:00',
|
||||
to: '10:00'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.schedule-item {
|
||||
width: 25em;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,10 +1,14 @@
|
|||
<template>
|
||||
<div class="home">
|
||||
<h2>Vous êtes :</h2>
|
||||
<ul>
|
||||
<li><a href="">Une association</a></li>
|
||||
<li><a href="">Administrateur de l'Espace Condorcet Centre Social</a></li>
|
||||
</ul>
|
||||
<v-main>
|
||||
<v-container>
|
||||
<h2>Vous êtes :</h2>
|
||||
<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-container>
|
||||
</v-main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue