.
This commit is contained in:
parent
6099d538c0
commit
745b9247c9
46 changed files with 543 additions and 181 deletions
66
.vscode/vscode-kanban.json
vendored
66
.vscode/vscode-kanban.json
vendored
|
@ -31,6 +31,18 @@
|
|||
"title": "export page",
|
||||
"type": "bug"
|
||||
},
|
||||
{
|
||||
"assignedTo": {
|
||||
"name": "lesion"
|
||||
},
|
||||
"category": "feature",
|
||||
"creation_time": "2019-04-23T19:55:59.993Z",
|
||||
"id": "10",
|
||||
"prio": 1,
|
||||
"references": [],
|
||||
"title": "gestione errori form aggiungi evento",
|
||||
"type": "bug"
|
||||
},
|
||||
{
|
||||
"assignedTo": {
|
||||
"name": "lesion"
|
||||
|
@ -73,6 +85,15 @@
|
|||
}
|
||||
],
|
||||
"in-progress": [
|
||||
{
|
||||
"assignedTo": {
|
||||
"name": "lesion"
|
||||
},
|
||||
"creation_time": "2019-04-30T22:00:29.237Z",
|
||||
"id": "17",
|
||||
"references": [],
|
||||
"title": "porcoddio la config arriva anche al client ovviamente, devo separare!"
|
||||
},
|
||||
{
|
||||
"assignedTo": {
|
||||
"name": "lesion"
|
||||
|
@ -85,18 +106,6 @@
|
|||
],
|
||||
"testing": [],
|
||||
"todo": [
|
||||
{
|
||||
"assignedTo": {
|
||||
"name": "lesion"
|
||||
},
|
||||
"category": "feature",
|
||||
"creation_time": "2019-04-23T19:55:59.993Z",
|
||||
"id": "10",
|
||||
"prio": 1,
|
||||
"references": [],
|
||||
"title": "gestione errori form aggiungi evento",
|
||||
"type": "bug"
|
||||
},
|
||||
{
|
||||
"assignedTo": {
|
||||
"name": "lesion"
|
||||
|
@ -168,6 +177,24 @@
|
|||
"references": [],
|
||||
"title": "colori te prego!"
|
||||
},
|
||||
{
|
||||
"assignedTo": {
|
||||
"name": "lesion"
|
||||
},
|
||||
"creation_time": "2019-05-27T20:42:22.581Z",
|
||||
"id": "24",
|
||||
"references": [],
|
||||
"title": "copy to clipboard"
|
||||
},
|
||||
{
|
||||
"assignedTo": {
|
||||
"name": "lesion"
|
||||
},
|
||||
"creation_time": "2019-05-29T13:08:20.887Z",
|
||||
"id": "25",
|
||||
"references": [],
|
||||
"title": "creazione script di backup"
|
||||
},
|
||||
{
|
||||
"assignedTo": {
|
||||
"name": "lesion"
|
||||
|
@ -214,15 +241,6 @@
|
|||
"references": [],
|
||||
"title": "popup sul calendario"
|
||||
},
|
||||
{
|
||||
"assignedTo": {
|
||||
"name": "lesion"
|
||||
},
|
||||
"creation_time": "2019-04-30T22:00:29.237Z",
|
||||
"id": "17",
|
||||
"references": [],
|
||||
"title": "porcoddio la config arriva anche al client ovviamente, devo separare!"
|
||||
},
|
||||
{
|
||||
"assignedTo": {
|
||||
"name": "lesion"
|
||||
|
@ -259,10 +277,10 @@
|
|||
"assignedTo": {
|
||||
"name": "lesion"
|
||||
},
|
||||
"creation_time": "2019-05-27T20:42:22.581Z",
|
||||
"id": "24",
|
||||
"creation_time": "2019-05-29T13:10:04.463Z",
|
||||
"id": "26",
|
||||
"references": [],
|
||||
"title": "copy to clipboard"
|
||||
"title": "v-calendar colori e eventi multidays..."
|
||||
}
|
||||
]
|
||||
}
|
|
@ -7,7 +7,6 @@
|
|||
:attributes='attributes'
|
||||
:from-page.sync='page'
|
||||
is-expanded
|
||||
show-clear-margin
|
||||
is-inline
|
||||
@dayclick='click')
|
||||
|
||||
|
@ -15,7 +14,7 @@
|
|||
<script>
|
||||
import { mapState, mapActions, mapGetters } from 'vuex'
|
||||
import moment from 'dayjs'
|
||||
import { intersection } from 'lodash'
|
||||
import { intersection, sample, get } from 'lodash'
|
||||
|
||||
export default {
|
||||
name: 'Calendar',
|
||||
|
@ -45,18 +44,19 @@ export default {
|
|||
order: event.start_datetime,
|
||||
}
|
||||
const day = moment(event.start_datetime).date()
|
||||
let color = event.tags && event.tags.length && event.tags[0].color ? event.tags[0].color : 'rgba(170,170,250,0.7)'
|
||||
if (event.past) color = 'rgba(200,200,200,0.5)'
|
||||
let color = event.past ? 'rgba(200,200,200,0.5)' : get(event, 'tags[0].color') || 'rgba(170,170,250,0.7)'
|
||||
|
||||
console.error(color)
|
||||
if (event.multidate) {
|
||||
e.dates = {
|
||||
start: event.start_datetime, end: event.end_datetime
|
||||
}
|
||||
e.highlight = { backgroundColor: color,
|
||||
// borderColor: 'transparent',
|
||||
borderWidth: '4px' }
|
||||
e.highlight = {
|
||||
color: 'red' // : sample(['purple', 'red', 'green', 'blue']),
|
||||
}
|
||||
} else {
|
||||
e.dates = event.start_datetime
|
||||
e.dot = { backgroundColor: color, borderColor: color, borderWidth: '3px' }
|
||||
e.dot = { color: 'rgba(102,10,20)' }
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
@ -84,4 +84,11 @@ export default {
|
|||
align-self: center;
|
||||
}
|
||||
|
||||
.vc-highlight {
|
||||
/* color: red; */
|
||||
height: 22px !important;
|
||||
opacity: 0.4;
|
||||
border-radius: 15px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
<template lang="pug">
|
||||
section
|
||||
|
||||
a(href='#totop')
|
||||
el-button.top.d-block.d-sm-none(icon='el-icon-top' circle type='primary' plain)
|
||||
a.totop(name='totop')
|
||||
.row.m-0
|
||||
|
||||
no-ssr
|
||||
Calendar.col-sm-12.col-lg-8.col-xl-6
|
||||
|
||||
.p-0.col-sm-6.col-lg-4.col-xl-3(v-for='event in filteredEvents')
|
||||
a(:id='event.newDay' v-if='event.newDay')
|
||||
.d-block.d-sm-none
|
||||
|
@ -20,14 +25,13 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import Event from '@/components/Event'
|
||||
import Calendar from '@/components/Calendar'
|
||||
import Search from '@/components/Search'
|
||||
|
||||
export default {
|
||||
name: 'Home',
|
||||
data () {
|
||||
return { }
|
||||
},
|
||||
components: { Calendar, Event, Search },
|
||||
components: { Calendar, Event },
|
||||
computed: mapGetters(['filteredEvents']),
|
||||
}
|
||||
</script>
|
||||
|
@ -36,5 +40,19 @@ section {
|
|||
width: 100%;
|
||||
max-width: 1500px;
|
||||
margin: 0 auto;
|
||||
|
||||
.top {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
z-index: 1;
|
||||
opacity: 0.7;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.totop {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
<script>
|
||||
import {mapState, mapActions} from 'vuex'
|
||||
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
|
@ -35,10 +34,11 @@ export default {
|
|||
methods: mapActions(['setSearchPlaces', 'setSearchTags', 'showPastEvents']),
|
||||
computed: {
|
||||
...mapState(['tags', 'places', 'filters', 'show_past_events']),
|
||||
// TOFIX: optimize
|
||||
keywords () {
|
||||
const tags = this.tags.map( t => ({ value: 't' + t.tag, label: t.tag, count: +t.eventsCount }))
|
||||
const places = this.places.map( p => ({ value: 'p' + p.id, label: p.name, count: +p.eventsCount }))
|
||||
return tags.concat(places)
|
||||
const tags = this.tags.map( t => ({ value: 't' + t.tag, label: t.tag, weigth: t.weigth }))
|
||||
const places = this.places.map( p => ({ value: 'p' + p.id, label: p.name, weigth: p.weigth }))
|
||||
return tags.concat(places).sort((a, b) => b.weigth-a.weigth)
|
||||
},
|
||||
showPast : {
|
||||
set (value) {
|
||||
|
@ -59,24 +59,6 @@ export default {
|
|||
return this.filters.tags.map(t => 't' + t).concat(this.filters.places.map(p => 'p' + p))
|
||||
}
|
||||
},
|
||||
filters_tags: {
|
||||
set (value) {
|
||||
this.setSearchTags(value)
|
||||
},
|
||||
get () {
|
||||
return this.filters.tags
|
||||
}
|
||||
},
|
||||
filters_places: {
|
||||
set (value) {
|
||||
this.setSearchPlaces(value)
|
||||
},
|
||||
get () {
|
||||
return this.filters.places
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
</style>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<template lang="pug">
|
||||
nuxt
|
||||
<template>
|
||||
<nuxt/>
|
||||
</template>
|
||||
|
|
3
locales/en.js
Normal file
3
locales/en.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"registration_email": "registration_email"
|
||||
}
|
3
locales/es.js
Normal file
3
locales/es.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"registration_email": "registration_email"
|
||||
}
|
125
locales/it.js
Normal file
125
locales/it.js
Normal file
|
@ -0,0 +1,125 @@
|
|||
const it = {
|
||||
common: {
|
||||
add_event: 'Nuovo evento',
|
||||
next: 'Continua',
|
||||
export: 'Esporta',
|
||||
send: 'Invia',
|
||||
where: 'Dove',
|
||||
address: 'Indirizzo',
|
||||
when: 'Quando',
|
||||
what: 'Cosa',
|
||||
media: 'Media',
|
||||
login: 'Entra',
|
||||
email: 'Email',
|
||||
password: 'Password',
|
||||
register: 'Registrati',
|
||||
description: 'Descrizione',
|
||||
remove: 'Elimina',
|
||||
hide: 'Nascondi',
|
||||
search: 'Cerca',
|
||||
edit: 'Modifica',
|
||||
info: 'Info',
|
||||
confirm: 'Conferma',
|
||||
admin: 'Amministra',
|
||||
users: 'Utenti',
|
||||
events: 'Eventi',
|
||||
places: 'Luoghi',
|
||||
settings: 'Opzioni',
|
||||
actions: 'Azioni',
|
||||
deactivate: 'Disattiva',
|
||||
remove_admin: 'Rimuovi Admin',
|
||||
activate: 'Attiva',
|
||||
save: 'Salva',
|
||||
preview: 'Anteprima',
|
||||
logout: 'Esci',
|
||||
share: 'Esporta',
|
||||
name: 'Nome',
|
||||
associate: 'Associa',
|
||||
edit_event: 'Modifica evento',
|
||||
related: 'Memoria storica',
|
||||
add: 'Aggiungi',
|
||||
logout_ok: 'Uscita correttamente',
|
||||
copy: 'Copia'
|
||||
},
|
||||
|
||||
login: {
|
||||
description: `Entrando puoi pubblicare nuovi eventi.`,
|
||||
check_email: 'Controlla la tua posta (anche lo spam)',
|
||||
not_registered: 'Non sei registrata?',
|
||||
forgot_password: 'Dimenticato la password?',
|
||||
error: 'Errore: ',
|
||||
insert_email: 'Inserisci la mail',
|
||||
ok: 'Tutto rego'
|
||||
},
|
||||
|
||||
export: {
|
||||
intro: `Contrariamente alle piattaforme del capitalismo, che fanno di tutto per tenere
|
||||
i dati e gli utenti al loro interno, crediamo che le informazioni, come le persone,
|
||||
debbano essere libere. Per questo puoi rimanere aggiornata sugli eventi che vuoi, come meglio credi, senza necessariamente passare da questo sito.`,
|
||||
email_description: `Puoi ricevere via mail gli eventi che ti interessano.`,
|
||||
insert_your_address: 'Indirizzo email',
|
||||
feed_description: `Per seguire gli aggiornamenti da computer o smartphone senza la necessità di aprire periodicamente il sito, il metodo consigliato è quello dei Feed RSS.</p>
|
||||
|
||||
<p>Con i feed rss utilizzi un'apposita applicazione per ricevere aggiornamenti dai siti che più ti interessano. È un buon metodo per seguire anche molti siti in modo molto rapido, senza necessità di creare un account o altre complicazioni.</p>
|
||||
|
||||
<li>Se hai Android, ti consigliamo <a href="https://play.google.com/store/apps/details?id=net.frju.flym">Flym</a> o Feeder</li>
|
||||
<li>Per iPhone/iPad puoi usare <a href="https://itunes.apple.com/ua/app/feeds4u/id1038456442?mt=8">Feed4U</a></li>
|
||||
<li>Per il computer fisso/portatile consigliamo Feedbro, da installare all'interno <a href="https://addons.mozilla.org/en-GB/firefox/addon/feedbroreader/">di Firefox </a>o <a href="https://chrome.google.com/webstore/detail/feedbro/mefgmmbdailogpfhfblcnnjfmnpnmdfa">di Chrome</a> e compatibile con tutti i principali sistemi operativi.</li>
|
||||
<br/>
|
||||
Aggiungendo questo link al tuo lettore di feed, rimarrai aggiornata.`,
|
||||
ical_description: `I computer e gli smartphone sono comunemente attrezzati con un'applicazione per gestire un calendario. A questi programmi solitamente è possibile far importare un calendario remoto.`,
|
||||
list_description: `Se hai un sito web e vuoi mostrare una lista di eventi, puoi usare il seguente codice`
|
||||
},
|
||||
|
||||
register: {
|
||||
description: `I movimenti hanno bisogno di organizzarsi e autofinanziarsi. <br/>Questo è un dono per voi, usatelo solo per eventi non commerciali e ovviamente antifascisti, antisessisti, antirazzisti.
|
||||
<br/>Prima di poter pubblicare <strong>dobbiamo approvare l'account</strong>, considera che <strong>dietro questo sito ci sono delle persone</strong> di
|
||||
carne e sangue, scrivici quindi due righe per farci capire che eventi vorresti pubblicare.`,
|
||||
error: 'Errore: '
|
||||
},
|
||||
|
||||
event: {
|
||||
anon: 'Anonimo',
|
||||
anon_description: `Puoi inserire un evento senza rigistrarti o fare il login,
|
||||
ma in questo caso dovrai aspettare che qualcuno lo legga confermando che si
|
||||
tratta di un evento adatto a questo spazio, delegando questa scelta.<br/><br/>
|
||||
Puoi fare il <a href='/login'>login</a> o <a href='/registrarti'>registrarti</a>,
|
||||
altrimenti vai avanti e riceverai una risposta il prima possibile.`,
|
||||
multidate_description: 'tanti giorni',
|
||||
date_description: `Quand'è il gancio?`,
|
||||
dates_description: 'Che giorni?',
|
||||
same_day: 'stesso giorno',
|
||||
what_description: 'Nome evento',
|
||||
description_description: 'Descrizione, dajene di copia/incolla',
|
||||
tag_description: 'Tag...',
|
||||
media_description: 'Puoi aggiungere un volantino',
|
||||
time_start_description: 'Comincia alle',
|
||||
time_end_description: 'Se vuoi puoi specificare un orario di fine.',
|
||||
added: 'Evento aggiunto',
|
||||
added_anon: 'Evento aggiunto, verrà confermato quanto prima.',
|
||||
where_description: `Dov'è il gancio?<br/>Se il posto non è presente, scrivilo e premi invio. `,
|
||||
confirmed: 'Evento confermato'
|
||||
},
|
||||
|
||||
admin: {
|
||||
mastodon_instance: 'Istanza',
|
||||
mastodon_description: 'Puoi associare un account mastodon a questa istanza di gancio, ogni evento verrà pubblicato lì.',
|
||||
place_description: `Nel caso in cui un luogo sia errato o cambi indirizzo, puoi modificarlo. <br/>Considera che tutti gli eventi associati a questo luogo cambieranno indirizzo (anche quelli passati!)`,
|
||||
event_confirm_description: 'Puoi confermare qui gli eventi inseriti da utenti anonimi'
|
||||
},
|
||||
|
||||
auth: {
|
||||
not_confirmed: 'Non abbiamo ancora confermato questa mail...',
|
||||
fail: 'Autenticazione fallita. Sicura la password è giusta? E la mail?'
|
||||
},
|
||||
|
||||
settings: {
|
||||
change_password: 'Cambia password'
|
||||
},
|
||||
|
||||
err: {
|
||||
register_error: 'Errore nella registrazione'
|
||||
}
|
||||
}
|
||||
|
||||
export default it
|
30
migrations/20190521100417-act_ids_comment_data.js
Normal file
30
migrations/20190521100417-act_ids_comment_data.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
up: (queryInterface, Sequelize) => {
|
||||
/*
|
||||
Add altering commands here.
|
||||
Return a promise to correctly handle asynchronicity.
|
||||
|
||||
Example:
|
||||
return queryInterface.createTable('users', { id: Sequelize.INTEGER });
|
||||
*/
|
||||
const a = queryInterface.addColumn('events', 'activitypub_ids', Sequelize.ARRAY(Sequelize.DOUBLE), { index: true })
|
||||
const b = queryInterface.addColumn('comments', 'data', Sequelize.JSON)
|
||||
return Promise.all([a, b])
|
||||
|
||||
},
|
||||
|
||||
down: (queryInterface, Sequelize) => {
|
||||
/*
|
||||
Add reverting commands here.
|
||||
Return a promise to correctly handle asynchronicity.
|
||||
|
||||
Example:
|
||||
return queryInterface.dropTable('users');
|
||||
*/
|
||||
const b = queryInterface.removeColumn('comments', 'data')
|
||||
const a = queryInterface.removeColumn('events', 'activitypub_ids')
|
||||
return Promise.all([a, b])
|
||||
}
|
||||
};
|
27
migrations/20190522104158-bigint.js
Normal file
27
migrations/20190522104158-bigint.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
up: (queryInterface, Sequelize) => {
|
||||
/*
|
||||
Add altering commands here.
|
||||
Return a promise to correctly handle asynchronicity.
|
||||
|
||||
Example:
|
||||
return queryInterface.createTable('users', { id: Sequelize.INTEGER });
|
||||
*/
|
||||
const a = queryInterface.changeColumn('events', 'activitypub_id', { type: Sequelize.BIGINT, index: true })
|
||||
const b = queryInterface.changeColumn('events', 'activitypub_ids', { type: Sequelize.ARRAY(Sequelize.BIGINT), index: true, defaultValue: [] })
|
||||
const c = queryInterface.changeColumn('comments', 'activitypub_id', { type: Sequelize.BIGINT, index: true})
|
||||
return Promise.all([a, b, c])
|
||||
},
|
||||
|
||||
down: (queryInterface, Sequelize) => {
|
||||
/*
|
||||
Add reverting commands here.
|
||||
Return a promise to correctly handle asynchronicity.
|
||||
|
||||
Example:
|
||||
return queryInterface.dropTable('users');
|
||||
*/
|
||||
}
|
||||
};
|
29
migrations/20190527205032-tag_id_weight.js
Normal file
29
migrations/20190527205032-tag_id_weight.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
up: async (queryInterface, Sequelize) => {
|
||||
/*
|
||||
Add altering commands here.
|
||||
Return a promise to correctly handle asynchronicity.
|
||||
|
||||
Example:
|
||||
return queryInterface.createTable('users', { id: Sequelize.INTEGER });
|
||||
*/
|
||||
await queryInterface.addColumn('tags', 'weigth', Sequelize.INTEGER)
|
||||
await queryInterface.sequelize.query('update "tags" SET weigth=subquery.c from (SELECT COUNT(*) as c, "tagTag" from "tagEvent" group by "tagTag") as subquery where "subquery"."tagTag"="tags"."tag";')
|
||||
await queryInterface.addColumn('places', 'weigth', Sequelize.INTEGER)
|
||||
await queryInterface.sequelize.query('update "places" SET weigth=subquery.c from (SELECT COUNT(*) as c, "placeId" from "events" group by "placeId") as subquery where "subquery"."placeId"="places"."id";')
|
||||
},
|
||||
|
||||
down: async (queryInterface, Sequelize) => {
|
||||
/*
|
||||
Add reverting commands here.
|
||||
Return a promise to correctly handle asynchronicity.
|
||||
|
||||
Example:
|
||||
return queryInterface.dropTable('users');
|
||||
*/
|
||||
await queryInterface.removeColumn('tags', 'weigth', Sequelize.INTEGER)
|
||||
await queryInterface.removeColumn('places', 'weigth', Sequelize.INTEGER)
|
||||
}
|
||||
};
|
37
models/index.js
Normal file
37
models/index.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const Sequelize = require('sequelize');
|
||||
const basename = path.basename(__filename);
|
||||
const env = process.env.NODE_ENV || 'development';
|
||||
const config = require(__dirname + '/../config/config.json')[env];
|
||||
const db = {};
|
||||
|
||||
let sequelize;
|
||||
if (config.use_env_variable) {
|
||||
sequelize = new Sequelize(process.env[config.use_env_variable], config);
|
||||
} else {
|
||||
sequelize = new Sequelize(config.database, config.username, config.password, config);
|
||||
}
|
||||
|
||||
fs
|
||||
.readdirSync(__dirname)
|
||||
.filter(file => {
|
||||
return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
|
||||
})
|
||||
.forEach(file => {
|
||||
const model = sequelize['import'](path.join(__dirname, file));
|
||||
db[model.name] = model;
|
||||
});
|
||||
|
||||
Object.keys(db).forEach(modelName => {
|
||||
if (db[modelName].associate) {
|
||||
db[modelName].associate(db);
|
||||
}
|
||||
});
|
||||
|
||||
db.sequelize = sequelize;
|
||||
db.Sequelize = Sequelize;
|
||||
|
||||
module.exports = db;
|
|
@ -41,7 +41,7 @@
|
|||
"sequelize-cli": "^5.4.0",
|
||||
"sharp": "^0.22.0",
|
||||
"sqlite3": "^4.0.6",
|
||||
"v-calendar": "^1.0.0-beta.10",
|
||||
"v-calendar": "^1.0.0-beta.13",
|
||||
"vue-awesome": "^3.5.1",
|
||||
"vue-custom-element": "^3.2.6",
|
||||
"vue-i18n": "^8.10.0",
|
||||
|
|
|
@ -26,10 +26,9 @@
|
|||
filterable allow-create
|
||||
default-first-option
|
||||
)
|
||||
el-option(v-for='place in places_name' :label='place' :value='place' :key='place.id')
|
||||
br
|
||||
br
|
||||
div {{$t("common.address")}} {{event.place.name}}
|
||||
el-option(v-for='place in places' :label='place.name' :value='place.name' :key='place.id')
|
||||
span {{place.name}} - {{place.weigth}}
|
||||
div {{$t("common.address")}}
|
||||
el-input.mb-3(ref='address' v-model='event.place.address'
|
||||
:disabled='places_name.indexOf(event.place.name)>-1'
|
||||
@keydown.native.enter='next')
|
||||
|
@ -89,9 +88,9 @@
|
|||
:on-change='uploadedFile'
|
||||
:multiple='false'
|
||||
:file-list="fileList"
|
||||
)
|
||||
i.el-icon-upload
|
||||
div.el-upload__text {{$t('event.media_description')}}
|
||||
)
|
||||
i.el-icon-upload
|
||||
div.el-upload__text {{$t('event.media_description')}}
|
||||
el-button.float-right(@click='done' :disabled='!couldProceed') {{edit?$t('common.edit'):$t('common.send')}}
|
||||
|
||||
</template>
|
||||
|
@ -153,7 +152,7 @@ export default {
|
|||
computed: {
|
||||
...mapState({
|
||||
tags: state => state.tags.map(t => t.tag ),
|
||||
places_name: state => state.places.map(p => p.name ),
|
||||
places_name: state => state.places.map(p => p.name ).sort((a, b) => b.weigth-a.weigth),
|
||||
places: state => state.places,
|
||||
user: state => state.user,
|
||||
events: state => state.events
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
template(slot='label')
|
||||
v-icon(name='map-marker-alt')
|
||||
span.ml-1 {{$t('common.places')}}
|
||||
p {{$t('admin.place_description')}}
|
||||
p(v-html="$t('admin.place_description')")
|
||||
el-form.mb-2(:inline='true' label-width='120px')
|
||||
el-form-item(:label="$t('common.name')")
|
||||
el-input.mr-1(:placeholder='$t("common.name")' v-model='place.name')
|
||||
|
@ -201,7 +201,7 @@ export default {
|
|||
await this.$axios.$get(`/event/confirm/${id}`)
|
||||
this.loading = false
|
||||
Message({
|
||||
message: this.$t('common.event_confirmed'),
|
||||
message: this.$t('event.confirmed'),
|
||||
type: 'success'
|
||||
})
|
||||
this.events = this.events.filter(e => e.id !== id)
|
||||
|
|
|
@ -12,15 +12,18 @@ export default {
|
|||
components: { List },
|
||||
async asyncData ({ $axios, req, res }) {
|
||||
const title = req.query.title || SHARED_CONF.title
|
||||
const show_tags = req.query.showtags
|
||||
const tags = req.query.tags
|
||||
const places = req.query.places
|
||||
const now = new Date()
|
||||
|
||||
// TODO: filter future events based on tags/places/userid
|
||||
const events = await $axios.$get(`/event/${now.getMonth()}/${now.getFullYear()}`)
|
||||
let params = []
|
||||
if (places) params.push(`places=${places}`)
|
||||
if (tags) params.push(`tags=${tags}`)
|
||||
|
||||
return { show_tags, events, title }
|
||||
params = params.length ? `?${params.join('&')}` : ''
|
||||
const events = await $axios.$get(`/export/json${params}`)
|
||||
|
||||
return { events, title }
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
h5.text-center {{event.title}}
|
||||
div.nextprev
|
||||
nuxt-link(v-if='prev' :to='`/event/${prev.id}`')
|
||||
el-button(icon='el-icon-arrow-left' round size='small' type='success' plain)
|
||||
el-button(icon='el-icon-arrow-left' round type='success')
|
||||
nuxt-link.float-right(v-if='next' :to='`/event/${next.id}`')
|
||||
el-button(icon='el-icon-arrow-right' round size='small' plain type='success')
|
||||
el-button(icon='el-icon-arrow-right' round type='success')
|
||||
|
||||
//- image
|
||||
img(:src='imgPath' v-if='event.image_path')
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<template lang="pug">
|
||||
el-dialog(:title='$t("common.export")' visible :before-close='close')
|
||||
p {{$t('export.intro')}}
|
||||
|
||||
li(v-if='filters.tags.length') {{$t('common.tags')}}:
|
||||
el-tag.ml-1(size='mini' v-for='tag in filters.tags' :key='tag.tag') {{tag}}
|
||||
li(v-if='filters.places.length') {{$t('common.places')}}:
|
||||
el-tag.ml-1(size='mini' v-for='place in filters.places' :key='place.id') {{place}}
|
||||
Search
|
||||
//- li(v-if='filters.tags.length') {{$t('common.tags')}}:
|
||||
//- el-tag.ml-1(size='mini' v-for='tag in filters.tags' :key='tag.tag') {{tag}}
|
||||
//- li(v-if='filters.places.length') {{$t('common.places')}}:
|
||||
//- el-tag.ml-1(size='mini' v-for='place in filters.places' :key='place.id') {{place}}
|
||||
el-tabs.mt-2(v-model='type')
|
||||
|
||||
el-tab-pane.pt-1(label='email' name='email')
|
||||
|
@ -55,13 +55,15 @@ import { mapState, mapGetters } from 'vuex'
|
|||
import path from 'path'
|
||||
import Calendar from '@/components/Calendar'
|
||||
import List from '@/components/List'
|
||||
import Search from '@/components/Search'
|
||||
|
||||
import {intersection} from 'lodash'
|
||||
import { Message } from 'element-ui'
|
||||
const { SHARED_CONF } = require('@/config')
|
||||
|
||||
export default {
|
||||
name: 'Export',
|
||||
components: { List },
|
||||
components: { List, Search },
|
||||
data () {
|
||||
return {
|
||||
type: 'email',
|
||||
|
@ -96,6 +98,11 @@ export default {
|
|||
if (this.list.title) {
|
||||
params.push(`title=${this.list.title}`)
|
||||
}
|
||||
|
||||
if (this.filters.places) {
|
||||
params.push(`places=${this.filters.places}`)
|
||||
}
|
||||
|
||||
return `<iframe src="${SHARED_CONF.baseurl}/embed/list?${params.join('&')}"></iframe>`
|
||||
},
|
||||
link () {
|
||||
|
|
52
pages/recover/_code.vue
Normal file
52
pages/recover/_code.vue
Normal file
|
@ -0,0 +1,52 @@
|
|||
<template lang="pug">
|
||||
el-dialog(visible)
|
||||
template(slot='title')
|
||||
h5 <img src='/favicon.ico'/> {{$t('common.recover_password')}}
|
||||
div(v-if='valid')
|
||||
el-form
|
||||
el-form-item {{$t('common.new_password')}}
|
||||
el-input(type='password', v-model='new_password')
|
||||
el-button(plain type="success" icon='el-icon-send', @click='change_password') {{$t('common.send')}}
|
||||
|
||||
div(v-else) {{$t('recover.not_valid_code')}}
|
||||
|
||||
|
||||
</template>
|
||||
<script>
|
||||
import { Message } from 'element-ui'
|
||||
|
||||
export default {
|
||||
name: 'Recover',
|
||||
data () {
|
||||
return { new_password: '' }
|
||||
},
|
||||
async asyncData({ params, $axios }) {
|
||||
const code = params.code
|
||||
try {
|
||||
const valid = await $axios.$post('/user/check_recover_code', { recover_code: code })
|
||||
return { valid, code }
|
||||
}
|
||||
catch (e) {
|
||||
return { valid: false }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async change_password () {
|
||||
try {
|
||||
const res = await this.$axios.$post('/user/recover_password', { recover_code: this.code, password: this.new_password })
|
||||
Message({
|
||||
type: 'success',
|
||||
message: this.$t('Password changed!')
|
||||
})
|
||||
} catch(e) {
|
||||
Message({
|
||||
type: 'warning',
|
||||
message: e
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
@ -41,12 +41,9 @@ export default {
|
|||
})
|
||||
this.$router.replace("/")
|
||||
} catch (e) {
|
||||
console.log('DENTRO CATCH!!!', e)
|
||||
const error = e && e.response && e.response.data && e.response.data.errors[0].message || e
|
||||
console.error(error)
|
||||
console.error(e)
|
||||
Message({
|
||||
message: this.$t('register.error') + error,
|
||||
message: this.$t('register.error') + this.$t(error),
|
||||
type: 'error'
|
||||
})
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import 'dayjs/locale/it'
|
|||
moment.locale('it')
|
||||
|
||||
export default (a) => {
|
||||
|
||||
Vue.filter('linkify', value => value.replace(/(https?:\/\/[^\s]+)/g, '<a href="$1">$1</a>'))
|
||||
Vue.filter('datetime', value => moment(value).format('ddd, D MMMM HH:mm'))
|
||||
Vue.filter('short_datetime', value => moment(value).format('D/MM HH:mm'))
|
||||
Vue.filter('hour', value => moment(value).format('HH:mm'))
|
||||
|
@ -12,7 +12,7 @@ export default (a) => {
|
|||
Vue.filter('month', value => moment(value).format('MMM'))
|
||||
Vue.filter('event_when', event => {
|
||||
if (event.multidate) {
|
||||
return moment(event.start_datetime).format('dddd, D MMMM HH:mm') + ' - ' + moment(event.end_datetime).format('ddd, D MMMM')
|
||||
return moment(event.start_datetime).format('ddd, D MMMM HH:mm') + ' - ' + moment(event.end_datetime).format('ddd, D MMMM')
|
||||
} else {
|
||||
if (event.end_datetime && event.end_datetime !== event.start_datetime)
|
||||
return moment(event.start_datetime).format('dddd, D MMMM HH:mm') + '-' + moment(event.end_datetime).format('HH:mm')
|
||||
|
|
9
plugins/initialize.js
Normal file
9
plugins/initialize.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
// TOFIX: not needed in any case (eg. embed)
|
||||
export default async ({ store, $axios }) => {
|
||||
const now = new Date()
|
||||
const events = await $axios.$get(`/event/${now.getMonth()}/${now.getFullYear()}`)
|
||||
store.commit('setEvents', events)
|
||||
const { tags, places } = await $axios.$get('/event/meta')
|
||||
store.commit('update', { tags, places })
|
||||
}
|
|
@ -11,6 +11,7 @@ const Auth = {
|
|||
next()
|
||||
},
|
||||
async isAuth(req, res, next) {
|
||||
console.error('ma sono dentro auth ?!?!', req.user)
|
||||
if (!req.user) {
|
||||
return res
|
||||
.status(403)
|
||||
|
|
|
@ -12,6 +12,7 @@ moment.locale('it')
|
|||
const botController = {
|
||||
bot: null,
|
||||
async initialize () {
|
||||
console.error('dentro bot inizialiteds')
|
||||
const settings = await settingsController.settings()
|
||||
if (!settings.mastodon_auth || !settings.mastodon_auth.access_token) return
|
||||
const mastodon_auth = settings.mastodon_auth
|
||||
|
|
|
@ -21,24 +21,22 @@ const eventController = {
|
|||
|
||||
async getMeta(req, res) {
|
||||
const places = await Place.findAll({
|
||||
group: ['place.id'],
|
||||
order: [[Sequelize.fn("COUNT", Sequelize.col('events.id')), 'DESC']],
|
||||
order: [[Sequelize.literal('weigth'), 'DESC']],
|
||||
attributes: {
|
||||
include: [[Sequelize.fn("COUNT", Sequelize.col('events.id')), 'eventsCount']],
|
||||
exclude: ['createdAt', 'updatedAt']
|
||||
include: [[Sequelize.fn('count', Sequelize.col('events.placeId')) ,'weigth']], // <---- Here you will get the total count of user
|
||||
exclude: ['weigth', 'createdAt', 'updatedAt']
|
||||
},
|
||||
include: { model: Event, attributes: [] }
|
||||
include: [{ model: Event, attributes: [] }],
|
||||
group: ['place.id']
|
||||
})
|
||||
|
||||
const tags = await Tag.findAll({
|
||||
group: ['tag'],
|
||||
order: [[Sequelize.fn("COUNT", Sequelize.col('events.id')), 'DESC']],
|
||||
includeIgnoreAttributes:false,
|
||||
order: [['weigth' , 'DESC']],
|
||||
includeIgnoreAttributes: false,
|
||||
attributes: {
|
||||
include: [[Sequelize.fn("COUNT", Sequelize.col('events.id')), 'eventsCount']],
|
||||
exclude: ['createdAt', 'updatedAt']
|
||||
},
|
||||
include: { model: Event, attributes: [] }})
|
||||
}
|
||||
})
|
||||
|
||||
res.json({ tags, places })
|
||||
},
|
||||
|
@ -92,7 +90,7 @@ const eventController = {
|
|||
Comment,
|
||||
{ model: Place, attributes: ['name', 'address'] }
|
||||
] ,
|
||||
order: [ [Comment, 'id', 'DESC'] ]
|
||||
order: [ [Comment, 'id', 'DESC'], [Tag, 'weigth', 'DESC'] ]
|
||||
})
|
||||
res.json(event)
|
||||
},
|
||||
|
@ -177,15 +175,17 @@ const eventController = {
|
|||
{ start_datetime: { [Op.lte]: end } }
|
||||
]
|
||||
},
|
||||
order: [['start_datetime', 'ASC']],
|
||||
order: [
|
||||
['start_datetime', 'ASC'],
|
||||
[Tag, 'weigth', 'DESC']
|
||||
],
|
||||
include: [
|
||||
{ model: User, required: false },
|
||||
Comment,
|
||||
Tag,
|
||||
{ model: Place, required: false }
|
||||
// { model: User, required: false },
|
||||
// { type: Comment, required: false, attributes: ['']
|
||||
{ model: Tag, required: false, attributes: ['tag', 'weigth','color'] },
|
||||
{ model: Place, required: false, attributes: ['id', 'name', 'address'] }
|
||||
]
|
||||
})
|
||||
// console.log(events)
|
||||
res.json(events)
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ const exportController = {
|
|||
|
||||
async export (req, res) {
|
||||
console.log('type ', req.params.type)
|
||||
console.error(req)
|
||||
const type = req.params.type
|
||||
const tags = req.query.tags
|
||||
const places = req.query.places
|
||||
|
@ -18,14 +19,20 @@ const exportController = {
|
|||
whereTag.tag = tags.split(',')
|
||||
}
|
||||
if (places) {
|
||||
wherePlace.name = places.split(',')
|
||||
wherePlace.id = places.split(',')
|
||||
}
|
||||
console.error(places)
|
||||
const events = await Event.findAll({
|
||||
where: { is_visible: true, start_datetime: { [Op.gte]: yesterday } },
|
||||
include: [Comment, {
|
||||
model: Tag,
|
||||
where: whereTag
|
||||
}, { model: Place, where: wherePlace } ]
|
||||
order: ['start_datetime'],
|
||||
where: {
|
||||
is_visible: true,
|
||||
start_datetime: { [Op.gte]: yesterday },
|
||||
placeId: places.split(',')
|
||||
},
|
||||
attributes: {
|
||||
exclude: ['createdAt', 'updatedAt']
|
||||
},
|
||||
include: [{model: Place, attributes: ['name', 'id', 'address', 'weigth']}]
|
||||
})
|
||||
switch (type) {
|
||||
case 'feed':
|
||||
|
|
|
@ -74,17 +74,14 @@ const userController = {
|
|||
async addEvent(req, res) {
|
||||
const body = req.body
|
||||
|
||||
// remove description tag and create anchor tags
|
||||
const description = body.description
|
||||
.replace(/(<([^>]+)>)/ig, '')
|
||||
.replace(/(https?:\/\/[^\s]+)/g, '<a href="$1">$1</a>')
|
||||
|
||||
const eventDetails = {
|
||||
title: body.title,
|
||||
description,
|
||||
description: body.description.replace(/(<([^>]+)>)/ig, ''),
|
||||
multidate: body.multidate,
|
||||
start_datetime: body.start_datetime,
|
||||
end_datetime: body.end_datetime,
|
||||
|
||||
// publish this event if authenticated
|
||||
is_visible: !!req.user
|
||||
}
|
||||
|
||||
|
@ -94,7 +91,7 @@ const userController = {
|
|||
|
||||
let event = await Event.create(eventDetails)
|
||||
|
||||
// create place
|
||||
// create place if needs to
|
||||
let place
|
||||
try {
|
||||
place = await Place.findOrCreate({ where: { name: body.place_name },
|
||||
|
@ -140,7 +137,7 @@ const userController = {
|
|||
|
||||
body.description = body.description
|
||||
.replace(/(<([^>]+)>)/ig, '') // remove all tags from description
|
||||
.replace(/(https?:\/\/[^\s]+)/g, '<a href="$1">$1</a>') // add links
|
||||
// .replace(/(https?:\/\/[^\s]+)/g, '<a href="$1">$1</a>') // add links
|
||||
|
||||
await event.update(body)
|
||||
let place
|
||||
|
|
|
@ -19,7 +19,8 @@ const Event = db.define('event', {
|
|||
})
|
||||
|
||||
const Tag = db.define('tag', {
|
||||
tag: { type: Sequelize.STRING, index: true, unique: true, },
|
||||
tag: { type: Sequelize.STRING, index: true, unique: true, primaryKey: true },
|
||||
weigth: { type: Sequelize.INTEGER, defaultValue: 0 },
|
||||
color: { type: Sequelize.STRING }
|
||||
})
|
||||
|
||||
|
@ -43,6 +44,7 @@ const Notification = db.define('notification', {
|
|||
|
||||
const Place = db.define('place', {
|
||||
name: { type: Sequelize.STRING, unique: true, index: true },
|
||||
weigth: { type: Sequelize.INTEGER, defaultValue: 0 },
|
||||
address: { type: Sequelize.STRING }
|
||||
})
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ const db = require('../db')
|
|||
const User = db.define('user', {
|
||||
email: {
|
||||
type: Sequelize.STRING,
|
||||
unique: { msg: 'Email already exists' },
|
||||
unique: { msg: 'err.register_error' },
|
||||
index: true,
|
||||
allowNull: false
|
||||
},
|
||||
|
|
4
server/emails/confirm/html.pug
Normal file
4
server/emails/confirm/html.pug
Normal file
|
@ -0,0 +1,4 @@
|
|||
p= t('confirm_email')
|
||||
|
||||
hr
|
||||
small #{config.baseurl}
|
18
server/emails/event/html.pug
Normal file
18
server/emails/event/html.pug
Normal file
|
@ -0,0 +1,18 @@
|
|||
h3 #{event.title}
|
||||
p Dove: #{event.place.name} - #{event.place.address}
|
||||
p Quando: #{datetime(event.start_datetime)}
|
||||
br
|
||||
if event.image_path
|
||||
<img style="width: 100%" src="#{config.apiurl}/uploads/#{event.image_path}" />
|
||||
p #{event.description}
|
||||
|
||||
each tag in event.tags
|
||||
span ##{tag.tag}
|
||||
br
|
||||
<a href="#{config.baseurl}/event/#{event.id}">#{config.baseurl}/event/#{event.id}</a>
|
||||
hr
|
||||
if to_confirm
|
||||
p Puoi confermare questo evento <a href="#{config.baseurl}/admin/confirm/#{event.id}">qui</a>
|
||||
else
|
||||
p Puoi eliminare queste notifiche <a href="#{config.baseurl}/del_notification/#{notification.remove_code}">qui</a>
|
||||
<a href="#{config.baseurl}">#{config.title} - #{config.description}</a>
|
1
server/emails/event/subject.pug
Normal file
1
server/emails/event/subject.pug
Normal file
|
@ -0,0 +1 @@
|
|||
= `[${config.title}] ${event.title} @${event.place.name} ${datetime(event.start_datetime)}`
|
8
server/emails/mail.css
Normal file
8
server/emails/mail.css
Normal file
|
@ -0,0 +1,8 @@
|
|||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table, th, td {
|
||||
border: 1px solid #555;
|
||||
}
|
3
server/emails/recover/html.pug
Normal file
3
server/emails/recover/html.pug
Normal file
|
@ -0,0 +1,3 @@
|
|||
p= t('recover_email')
|
||||
|
||||
<a href="#{config.baseurl}/recover/#{user.recover_code}">#{t('press here')}</a>
|
1
server/emails/recover/subject.pug
Normal file
1
server/emails/recover/subject.pug
Normal file
|
@ -0,0 +1 @@
|
|||
= `[Gancio] Richiesta password recovery`
|
6
server/emails/register/html.pug
Normal file
6
server/emails/register/html.pug
Normal file
|
@ -0,0 +1,6 @@
|
|||
p= t('registration_email')
|
||||
|
||||
hr
|
||||
small #{config.title} / #{config.description}
|
||||
br
|
||||
small #{config.baseurl}
|
1
server/emails/register/subject.pug
Normal file
1
server/emails/register/subject.pug
Normal file
|
@ -0,0 +1 @@
|
|||
= `[Gancio] Richiesta registrazione`
|
|
@ -7,11 +7,14 @@ const path = require('path')
|
|||
const { Nuxt, Builder } = require('nuxt')
|
||||
const app = express()
|
||||
const cors = require('cors')
|
||||
const notifier = require('./notifier')
|
||||
|
||||
const corsConfig = {
|
||||
allowedHeaders: ['Authorization'],
|
||||
exposeHeaders: ['Authorization']
|
||||
}
|
||||
|
||||
|
||||
// Import and Set Nuxt.js options
|
||||
const config = require('../nuxt.config.js')
|
||||
config.dev = !(process.env.NODE_ENV === 'production')
|
||||
|
@ -47,3 +50,4 @@ async function start() {
|
|||
})
|
||||
}
|
||||
start()
|
||||
notifier.startLoop(20)
|
||||
|
|
|
@ -21,6 +21,7 @@ async function sendNotification (notification, event, eventNotification) {
|
|||
if (settings.mastodon_auth.instance && settings.mastodon_auth.access_token) {
|
||||
const b = bot.post(settings.mastodon_auth, event).then(b => {
|
||||
event.activitypub_id = b.data.id
|
||||
// event.activitypub_ids.push(b.data.id)
|
||||
return event.save()
|
||||
})
|
||||
promises.push(b)
|
||||
|
@ -29,7 +30,8 @@ async function sendNotification (notification, event, eventNotification) {
|
|||
return Promise.all(promises)
|
||||
}
|
||||
|
||||
async function loop () {
|
||||
async function notify() {
|
||||
console.error('dentro il loop di notify')
|
||||
settings = await settingsController.settings()
|
||||
// get all event notification in queue
|
||||
const eventNotifications = await EventNotification.findAll({ where: { status: 'new' } })
|
||||
|
@ -51,5 +53,14 @@ async function loop () {
|
|||
return Promise.all(promises)
|
||||
}
|
||||
|
||||
setInterval(loop, 260000)
|
||||
loop()
|
||||
let interval
|
||||
function startLoop(seconds) {
|
||||
console.error('starting notifier loop')
|
||||
interval = setInterval(notify, seconds*1000)
|
||||
}
|
||||
|
||||
function stopLoop() {
|
||||
stopInterval(interval)
|
||||
}
|
||||
|
||||
module.exports = { startLoop, stopLoop }
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 4.2 KiB |
BIN
static/gancio.png
Normal file
BIN
static/gancio.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
|
@ -20,9 +20,9 @@ export const state = () => ({
|
|||
|
||||
export const getters = {
|
||||
token: state => state.token,
|
||||
|
||||
// filter current + future events only
|
||||
// plus, filter matches search tag/place
|
||||
|
||||
filteredEvents: (state) => {
|
||||
|
||||
let events = state.events
|
||||
|
@ -50,7 +50,6 @@ export const getters = {
|
|||
let lastDay = null
|
||||
events = map(events, e => {
|
||||
const currentDay = moment(e.start_datetime).date()
|
||||
console.log(currentDay)
|
||||
e.newDay = (!lastDay || lastDay!==currentDay) && currentDay
|
||||
lastDay = currentDay
|
||||
return e
|
||||
|
@ -88,22 +87,9 @@ export const mutations = {
|
|||
state.tags = tags
|
||||
state.places = places
|
||||
},
|
||||
// search
|
||||
addSearchTag(state, tag) {
|
||||
if (!state.filters.tags.find(t => t === tag.tag)) {
|
||||
state.filters.tags.push(tag.tag)
|
||||
} else {
|
||||
state.filters.tags = state.filters.tags.filter(t => t !== tag.tag)
|
||||
}
|
||||
},
|
||||
setSearchTags(state, tags) {
|
||||
state.filters.tags = tags
|
||||
},
|
||||
addSearchPlace(state, place) {
|
||||
if (state.filters.places.find(p => p.name === place.name)) {
|
||||
state.filters.places.push(place)
|
||||
}
|
||||
},
|
||||
setSearchPlaces(state, places) {
|
||||
state.filters.places = places
|
||||
},
|
||||
|
@ -122,26 +108,23 @@ export const actions = {
|
|||
commit('update', { tags, places })
|
||||
},
|
||||
async addEvent({ commit }, formData) {
|
||||
const event = await this.$axios.$post('/user/event', formData) // .addEvent(formData)
|
||||
commit('addEvent', event)
|
||||
const event = await this.$axios.$post('/user/event', formData)
|
||||
if (event.user) {
|
||||
commit('addEvent', event)
|
||||
}
|
||||
},
|
||||
async updateEvent({ commit }, formData) {
|
||||
const event = await this.$axios.$put('/user/event', formData)
|
||||
commit('updateEvent', event)
|
||||
if (event.user) {
|
||||
commit('updateEvent', event)
|
||||
}
|
||||
},
|
||||
delEvent({ commit }, eventId) {
|
||||
commit('delEvent', eventId)
|
||||
},
|
||||
// search
|
||||
addSearchTag({ commit }, tag) {
|
||||
commit('addSearchTag', tag)
|
||||
},
|
||||
setSearchTags({ commit }, tags) {
|
||||
commit('setSearchTags', tags)
|
||||
},
|
||||
addSearchPlace({ commit }, place) {
|
||||
commit('addSearchPlace', place)
|
||||
},
|
||||
setSearchPlaces({ commit }, places) {
|
||||
commit('setSearchPlaces', places)
|
||||
},
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Gancio Widget Example</title>
|
||||
<script src="https://unpkg.com/vue"></script>
|
||||
<script src='dist/gancio-widget.min.js'></script>
|
||||
<link rel="stylesheet" href="../list/style.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<gancio-widget minimal></gancio-widget>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,12 +0,0 @@
|
|||
import Vue from 'vue'
|
||||
import vueCustomElement from 'vue-custom-element'
|
||||
import App from '../../components/List'
|
||||
// import router from './router'
|
||||
// import store from '../../store'
|
||||
|
||||
Vue.use(vueCustomElement)
|
||||
|
||||
// App.store = store
|
||||
// App.router = router
|
||||
Vue.customElement('gancio-widget', App)
|
||||
export default App
|
|
@ -1,3 +0,0 @@
|
|||
#gancio-widget {
|
||||
border: 1px solid black;
|
||||
}
|
Loading…
Reference in a new issue