diff --git a/client/package.json b/client/package.json
index 07d1d1be..31e18429 100644
--- a/client/package.json
+++ b/client/package.json
@@ -9,8 +9,8 @@
},
"dependencies": {
"axios": "^0.18.0",
- "bootstrap-vue": "^2.0.0-rc.11",
- "element-ui": "^2.5.4",
+ "bootstrap-vue": "^2.0.0-rc.13",
+ "element-ui": "^2.6.0",
"mastodon-api": "^1.3.0",
"moment": "^2.23.0",
"node-sass": "^4.11.0",
diff --git a/client/src/api.js b/client/src/api.js
index 5236a925..2b8bf563 100644
--- a/client/src/api.js
+++ b/client/src/api.js
@@ -23,7 +23,6 @@ function put (path, data) {
}
function del (path) {
- console.log(store.state.token)
return api.delete(path, { headers: { 'x-access-token': store.state.token } }).then(ret => ret.data)
}
diff --git a/client/src/components/Admin.vue b/client/src/components/Admin.vue
index 8237fc36..6db50099 100644
--- a/client/src/components/Admin.vue
+++ b/client/src/components/Admin.vue
@@ -1,17 +1,20 @@
b-modal(hide-footer hide-header
- @hide='$router.go(-1)' size='lg' :visible='true')
+ @hide='$router.replace("/")' size='lg' :visible='true')
h4.text-center Admin
b-tabs(pills)
- b-tab
+
+ b-tab.pt-1
template(slot='title')
v-icon(name='users')
span {{$t('Users')}}
- b-table(:items='users' :fields='userFields' striped hover)
+ b-table(:items='users' :fields='userFields' striped small hover
+ :per-page='5' :current-page='userPage')
template(slot='action' slot-scope='data')
b-button.mr-1(:variant='data.item.is_active?"warning":"success"' @click='toggle(data.item)') {{data.item.is_active?$t('Deactivate'):$t('Activate')}}
b-button(:variant='data.item.is_admin?"danger":"warning"' @click='toggleAdmin(data.item)') {{data.item.is_admin?$t('Remove Admin'):$t('Admin')}}
- b-tab
+ b-pagination(:per-page='5' v-model='userPage' :total-rows='users.length')
+ b-tab.pt-1
template(slot='title')
v-icon(name='map-marker-alt')
span {{$t('Places')}}
@@ -29,12 +32,15 @@
template(slot='title')
v-icon(name='tag')
span {{$t('Tags')}}
- b-table(:items='tags' :fields='tagFields' striped hover)
+ p You can choose colors of your tags
+ b-table(:items='tags' :fields='tagFields'
+ striped small hover :per-page='10' :current-page='tagPage')
template(slot='tag' slot-scope='data')
b-badge(:style='{backgroundColor: data.item.color}') {{data.item.tag}}
template(slot='color' slot-scope='data')
el-color-picker(v-model='data.item.color' @change='updateColor(data.item)')
- b-tab
+ b-pagination(:per-page='10' v-model='tagPage' :total-rows='tags.length')
+ b-tab.pt-1
template(slot='title')
v-icon(name='tools')
span {{$t('Settings')}}
@@ -51,8 +57,12 @@ export default {
users: [],
userFields: ['email', 'action'],
placeFields: ['name', 'address'],
+ placePage: 1,
+ userPage: 1,
+ tagPage: 1,
tagFields: ['tag', 'color'],
description: '',
+ place: {name: '', address: '' }
}
},
async mounted () {
@@ -83,4 +93,4 @@ export default {
}
}
}
-
+
\ No newline at end of file
diff --git a/client/src/components/Calendar.vue b/client/src/components/Calendar.vue
index 3d11bd8f..2a33e6ea 100644
--- a/client/src/components/Calendar.vue
+++ b/client/src/components/Calendar.vue
@@ -43,7 +43,8 @@ export default {
}
}
- const color = event.tags.length && event.tags[0].color ? event.tags[0].color : 'rgba(200,200,200,0.5)'
+ let color = event.tags.length && event.tags[0].color ? event.tags[0].color : 'rgba(200,200,200,0.5)'
+ if (event.past) color = 'rgba(200,200,200,0.5)'
if (event.multidate) {
e.dates = {
start: event.start_datetime, end: event.end_datetime
@@ -60,18 +61,19 @@ export default {
},
computed: {
filteredEvents () {
- if (!this.filters.tags.length && !this.filters.places.length) return this.events
- return this.events.filter(e => {
- if (this.filters.tags.length) {
- const m = intersection(e.tags.map(t => t.tag), this.filters.tags)
- if (m.length>0) return true
- }
- if (this.filters.places.length) {
- if (this.filters.places.find(p => p === e.place.name))
- return true
- }
- return 0
- })
+ return this.$store.getters.filteredEvents
+ // if (!this.filters.tags.length && !this.filters.places.length) return this.events
+ // return this.events.filter(e => {
+ // if (this.filters.tags.length) {
+ // const m = intersection(e.tags.map(t => t.tag), this.filters.tags)
+ // if (m.length>0) return true
+ // }
+ // if (this.filters.places.length) {
+ // if (this.filters.places.find(p => p === e.place.name))
+ // return true
+ // }
+ // return 0
+ // })
},
...mapState(['events', 'tags', 'filters']),
attributes () {
diff --git a/client/src/components/Event.vue b/client/src/components/Event.vue
index bf7d55d4..0ca74601 100644
--- a/client/src/components/Event.vue
+++ b/client/src/components/Event.vue
@@ -2,9 +2,9 @@
b-card(bg-variant='dark' text-variant='white'
@click='$router.push("/event/" + event.id)'
:img-src='imgPath')
- h5 {{event.title}}
+ strong {{event.title}}
div {{event.start_datetime|datetime}}
- span(v-b-popover.hover="event.place && event.place.address || ''") {{event.place.name}}
+ span {{event.place.name}}
br
b-badge(:style='{backgroundColor: tag.color}' v-for='tag in event.tags' href='#'
@click.stop='addSearchTag(tag)') {{tag.tag}}
diff --git a/client/src/components/EventDetail.vue b/client/src/components/EventDetail.vue
index 87182766..a001dae9 100644
--- a/client/src/components/EventDetail.vue
+++ b/client/src/components/EventDetail.vue
@@ -1,6 +1,6 @@
b-modal#eventDetail(hide-footer hide-header
- @hide='$router.go(-1)' size='lg' :visible='true')
+ @hide='$router.replace("/")' size='lg' :visible='true')
b-card(bg-variant='dark' href='#' text-variant='white'
no-body, :img-src='imgPath')
diff --git a/client/src/components/Home.vue b/client/src/components/Home.vue
index 2376b6f3..2a6a4a8e 100644
--- a/client/src/components/Home.vue
+++ b/client/src/components/Home.vue
@@ -13,24 +13,15 @@ import filters from '@/filters.js'
import Event from '@/components/Event'
import Calendar from '@/components/Calendar'
import {intersection} from 'lodash'
+import moment from 'moment'
+
export default {
name: 'Home',
components: { Event, Calendar },
computed: {
...mapState(['events', 'filters']),
filteredEvents () {
- if (!this.filters.tags.length && !this.filters.places.length) return this.events
- return this.events.filter(e => {
- if (this.filters.tags.length) {
- const m = intersection(e.tags.map(t => t.tag), this.filters.tags)
- if (m.length>0) return true
- }
- if (this.filters.places.length) {
- if (this.filters.places.find(p => p === e.place.name))
- return true
- }
- return 0
- })
+ return this.$store.getters.filteredEvents.filter(e => !e.past)
}
}
}
diff --git a/client/src/components/Login.vue b/client/src/components/Login.vue
index c49c60d1..1b71cece 100644
--- a/client/src/components/Login.vue
+++ b/client/src/components/Login.vue
@@ -1,6 +1,6 @@
b-modal(hide-header hide-footer @shown="$refs.email.focus()"
- @hide='$router.go(-1)' :visible='true')
+ @hide='$router.replace("/")' :visible='true')
h4.text-center.center {{$t('Login')}}
b-form
//- p.text-muted Sign In to your account
diff --git a/client/src/components/Register.vue b/client/src/components/Register.vue
index 700274e5..e70b9662 100644
--- a/client/src/components/Register.vue
+++ b/client/src/components/Register.vue
@@ -1,6 +1,6 @@
b-modal(hide-header hide-footer
- @hide='$router.go(-1)' :visible='true' @shown='$refs.email.focus()')
+ @hide='$router.replace("/")' :visible='true' @shown='$refs.email.focus()')
h4.text-center.center {{$t('Register')}}
b-form
p.text-muted(v-html="$t('register_explanation')")
@@ -42,8 +42,6 @@ export default {
async register () {
try {
const user = await api.register(this.user)
- // this.login(user)
- // this.user = { name: '' }
this.$router.go(-1)
this.$message({
message: this.$t('registration_complete'),
diff --git a/client/src/components/newEvent.vue b/client/src/components/newEvent.vue
index b398602e..dd593bcd 100644
--- a/client/src/components/newEvent.vue
+++ b/client/src/components/newEvent.vue
@@ -1,6 +1,6 @@
b-modal(hide-header hide-footer no-close-on-backdrop
- @hide='$router.go(-1)' no-close-on-esc size='lg' :visible='true')
+ @hide='$router.replace("/")' no-close-on-esc size='lg' :visible='true')
h4.text-center.center {{edit?$t('Edit event'):$t('New event')}}
b-tabs#tabss(pills v-model='activeTab')
b-form
diff --git a/client/src/locale/it.js b/client/src/locale/it.js
index 14db4025..43f08222 100644
--- a/client/src/locale/it.js
+++ b/client/src/locale/it.js
@@ -18,16 +18,20 @@ const it = {
tag_explanation: 'Puoi inserire un tag (es. concerto, corteo)',
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.`,
+ debbano essere libere. Per questo puoi rimanere aggiornata sugli eventi che vuoi, come meglio credi, senza necessariamente passare da qui.`,
export_feed_explanation: `Per seguire gli aggiornamenti da computer o smartphone senza la necessità di aprire periodicamente il sito, il metodo consigliato è quello dei Feed RSS.
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.
- Se hai Android, ti consigliamo Flym o Feeder
- Per iPhone/iPad puoi usare Feed4U
- Per il computer fisso/portatile consigliamo Feedbro, da installare all'interno di Firefox o di Chrome e compatibile con tutti i principali sistemi operativi.
-
- Aggiungendo il link sopra, rimarrai aggiornata sui seguenti eventi:`,
+ Se hai Android, ti consigliamo Flym o Feeder
+ Per iPhone/iPad puoi usare Feed4U
+ Per il computer fisso/portatile consigliamo Feedbro, da installare all'interno di Firefox o di Chrome e compatibile con tutti i principali sistemi operativi.
+
+ Aggiungendo questo link al tuo lettore di feed, rimarrai aggiornata.`,
+ export_email_explanation: `Puoi ricevere via mail gli eventi che ti interessano [WIP]`,
+ export_list_explanation: `Se hai un sito web e vuoi mostrare una lista di eventi, puoi usare il seguente codice [WIP]`,
+ export_calendar_explanation: `Se hai un sito web e vuoi mostrare un calendario di eventi, puoi usare il seguente codice [WIP]`,
+ export_ical_explanation: `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.`,
Poster: 'Locandina',
Settings: 'Impostazioni',
Search: 'Cerca',
@@ -47,12 +51,19 @@ const it = {
Users: 'Utenti',
Places: 'Luoghi',
Tags: 'Etichette',
+ Name: 'Nome',
+ Save: 'Salva',
+ Address: 'Indirizzo',
Remove: 'Elimina',
Edit: 'Modifica',
Admin: 'Amministra',
Today: 'Oggi',
+ Export: 'Esporta',
+ send_reminder: 'Ricordamelo il giorno prima',
+ notify_on_insert: `Notifica all'inserimento`,
'Edit event': 'Modifica evento',
'New event': 'Nuovo evento',
+ 'Insert your address': 'Inserisci il tuo indirizzo',
registration_complete: 'Controlla la tua posta (anche la cartella spam)',
registration_email: `Ciao, la tua registrazione sarà confermata nei prossimi giorni. Riceverai una conferma non temere.`,
register_explanation: `I movimenti hanno bisogno di organizzarsi e autofinanziarsi.
Questo è un dono per voi, non possiamo più vedervi usare le piattaforme del capitalismo. Solo eventi non commerciali e ovviamente antifascisti, antisessisti, antirazzisti.
diff --git a/client/src/router.js b/client/src/router.js
index f03e1dec..63b2e1b4 100644
--- a/client/src/router.js
+++ b/client/src/router.js
@@ -44,7 +44,7 @@ export default new Router({
props: { edit: true }
},
{
- path: '/export/:type',
+ path: '/export',
components: { modal: Export }
}
]
diff --git a/client/src/store.js b/client/src/store.js
index 461ad1ec..feaef55a 100644
--- a/client/src/store.js
+++ b/client/src/store.js
@@ -1,7 +1,9 @@
import Vue from 'vue'
import Vuex from 'vuex'
import VuexPersistence from 'vuex-persist'
+import { intersection } from 'lodash'
import api from './api'
+import moment from 'moment'
Vue.use(Vuex)
const vuexLocal = new VuexPersistence({
@@ -12,7 +14,29 @@ const vuexLocal = new VuexPersistence({
export default new Vuex.Store({
plugins: [vuexLocal.plugin],
getters: {
- token: state => state.token
+ token: state => state.token,
+ filteredEvents: state => {
+ const events = state.events.map(e => {
+ const past = (moment().diff(e.start_datetime, 'minutes') > 0)
+ e.past = past
+ return e
+ })
+ if (!state.filters.tags.length && !state.filters.places.length) {
+ return events
+ }
+ return events.filter(e => {
+ if (state.filters.tags.length) {
+ const m = intersection(e.tags.map(t => t.tag), state.filters.tags)
+ if (m.length > 0) return true
+ }
+ if (state.filters.places.length) {
+ if (state.filters.places.find(p => p === e.place.name)) {
+ return true
+ }
+ }
+ return 0
+ })
+ }
},
state: {
logged: false,
diff --git a/config/config.production.json b/config/config.production.json
index 03f052eb..c47cc3a4 100644
--- a/config/config.production.json
+++ b/config/config.production.json
@@ -9,6 +9,11 @@
"apiurl": "https://example.com/api",
"db": {
+ "dialect": "postgres",
+ "host": "localhost",
+ "database": "gancio",
+ "user": "user",
+ "password": "password"
},
"admin": "admin@example.com",
diff --git a/views/feed/rss.pug b/views/feed/rss.pug
index 8ef6b32b..a2d335bd 100644
--- a/views/feed/rss.pug
+++ b/views/feed/rss.pug
@@ -11,7 +11,7 @@ rss(version='2.0', xmlns:atom='#{config.baseurl}/event/#{event.id}
+ link #{config.baseurl}/event/#{event.id}
description
| #{event.title}