diff --git a/components/Announcement.vue b/components/Announcement.vue
new file mode 100644
index 00000000..b6dcb276
--- /dev/null
+++ b/components/Announcement.vue
@@ -0,0 +1,32 @@
+
+ .card.announcement.event.mt-1.text-white(body-style='padding: 0px;')
+ nuxt-link(:to='`/announcement/${announcement.id}`')
+ .title {{announcement.title}}
+
+ .card-body
+ .description(v-html='description')
+
+
+
+
diff --git a/components/Home.vue b/components/Home.vue
index a0180193..fe1c4f69 100644
--- a/components/Home.vue
+++ b/components/Home.vue
@@ -9,6 +9,7 @@
Search(past-filter recurrent-filter)
#events
+ Announcement(v-for='announcement in announcements' :key='announcement.id' :announcement='announcement')
Event(v-for='event in events' :key='event.id' :event='event')
@@ -16,18 +17,19 @@
diff --git a/layouts/default.vue b/layouts/default.vue
index 79393643..ca1d2e6b 100644
--- a/layouts/default.vue
+++ b/layouts/default.vue
@@ -1,5 +1,5 @@
- el-container#main(:class='{dark: $route.name==="index"}')
+ el-container#main(:class='{dark: $route.name==="index" || $route.name==="announcement-id"}')
el-dialog(:visible.sync='showFollowMe')
h4(slot='title') {{$t('common.follow_me_title')}}
FollowMe
diff --git a/locales/it.json b/locales/it.json
index 6f5c764a..4727f7df 100644
--- a/locales/it.json
+++ b/locales/it.json
@@ -76,7 +76,9 @@
"pause": "Pausa",
"start": "Avvia",
"fediverse": "Fediverso",
- "skip": "Salta"
+ "skip": "Salta",
+ "delete": "Elimina",
+ "announcements": "Annunci"
},
"login": {
"description": "Entrando puoi pubblicare nuovi eventi.",
@@ -176,7 +178,10 @@
"filter_users": "Filtra utenti",
"instance_name": "Nome istanza",
"favicon": "Logo",
- "user_block_confirm": "Sicura di voler bloccare l'utente?"
+ "user_block_confirm": "Sicura di voler bloccare l'utente?",
+ "delete_announcement_confirm": "Sicura di voler eliminare l'annuncio?",
+ "announcement_remove_ok": "Annuncio rimosso",
+ "announcement_description": "In questa sezione puoi inserire annunci che rimarranno in homepage"
},
"auth": {
"not_confirmed": "Non abbiamo ancora confermato questa mail...",
diff --git a/pages/Admin.vue b/pages/Admin.vue
index 721960c7..332125e4 100644
--- a/pages/Admin.vue
+++ b/pages/Admin.vue
@@ -58,6 +58,13 @@
span.ml-1 {{$t('common.moderation')}}
Moderation
+ //- ANNOUNCEMENTS
+ el-tab-pane.pt-1
+ template(slot='label')
+ v-icon(name='bullhorn')
+ span.ml-1 {{$t('common.announcements')}}
+ Announcement
+
+
diff --git a/plugins/vue-awesome.js b/plugins/vue-awesome.js
index 13876aca..1eca8476 100644
--- a/plugins/vue-awesome.js
+++ b/plugins/vue-awesome.js
@@ -47,6 +47,7 @@ import 'vue-awesome/icons/link'
import 'vue-awesome/icons/hands-helping'
import 'vue-awesome/icons/question'
import 'vue-awesome/icons/vector-square'
+import 'vue-awesome/icons/bullhorn'
import Icon from 'vue-awesome/components/Icon'
diff --git a/server/api/controller/announce.js b/server/api/controller/announce.js
new file mode 100644
index 00000000..4e3dea9f
--- /dev/null
+++ b/server/api/controller/announce.js
@@ -0,0 +1,57 @@
+const { announcement: Announcement } = require('../models')
+const debug = require('debug')('announcement:controller')
+
+const announceController = {
+ async getAll (req, res) {
+ const announces = await Announcement.findAll({ raw: true })
+ return res.json(announces)
+ },
+
+ _getVisible () {
+ return Announcement.findAll({ where: { visible: true }, raw: true })
+ },
+
+ async add (req, res) {
+ const announcementDetail = {
+ title: req.body.title,
+ announcement: req.body.announcement,
+ visible: true
+ }
+ debug('Create announcement ', req.body.title)
+ const announce = await Announcement.create(announcementDetail)
+ res.json(announce)
+ },
+
+ async update (req, res) {
+ const announceDetails = {
+ title: req.body.title,
+ announcement: req.body.announcement,
+ visible: req.body.visible
+ }
+ const announce_id = req.params.announce_id
+ try {
+ let announce = await Announcement.findByPk(announce_id)
+ announce = await announce.update(announceDetails)
+ res.json(announce)
+ } catch (e) {
+ debug('Toggle announcement failed ', e)
+ res.sendStatus(404)
+ }
+ },
+
+ async remove (req, res) {
+ debug('Remove announcement ', req.params.announce_id)
+ const announce_id = req.params.announce_id
+ try {
+ const announce = await Announcement.findByPk(announce_id)
+ await announce.destroy()
+ res.sendStatus(200)
+ } catch (e) {
+ debug('Remove announcement failed ', e)
+ res.sendStatus(404)
+ }
+ }
+
+}
+
+module.exports = announceController
diff --git a/server/api/index.js b/server/api/index.js
index 095a16c1..bb062490 100644
--- a/server/api/index.js
+++ b/server/api/index.js
@@ -11,6 +11,7 @@ const instanceController = require('./controller/instance')
const apUserController = require('./controller/ap_user')
const resourceController = require('./controller/resource')
const oauthController = require('./controller/oauth')
+const announceController = require('./controller/announce')
const storage = require('./storage')
const upload = multer({ storage })
@@ -126,6 +127,12 @@ api.put('/resources/:resource_id', isAdmin, resourceController.hide)
api.delete('/resources/:resource_id', isAdmin, resourceController.remove)
api.get('/resources', isAdmin, resourceController.getAll)
+// - ADMIN ANNOUNCEMENTS
+api.get('/announcements', isAdmin, announceController.getAll)
+api.post('/announcements', isAdmin, announceController.add)
+api.put('/announcements/:announce_id', isAdmin, announceController.update)
+api.delete('/announcements/:announce_id', isAdmin, announceController.remove)
+
api.get('/clients', hasPerm('oauth:read'), oauthController.getClients)
api.get('/client/:client_id', hasPerm('oauth:read'), oauthController.getClient)
api.post('/client', oauthController.createClient)
diff --git a/server/api/models/announcement.js b/server/api/models/announcement.js
index 18d39380..332bbf13 100644
--- a/server/api/models/announcement.js
+++ b/server/api/models/announcement.js
@@ -1,7 +1,7 @@
module.exports = (sequelize, DataTypes) => {
const announcement = sequelize.define('announcement', {
- announce: DataTypes.STRING,
- until: DataTypes.DATE,
+ title: DataTypes.STRING,
+ announcement: DataTypes.STRING,
visible: DataTypes.BOOLEAN
}, {})
diff --git a/server/firstrun.js b/server/firstrun.js
index 31bfa59b..59f8df8b 100644
--- a/server/firstrun.js
+++ b/server/firstrun.js
@@ -54,6 +54,12 @@ module.exports = {
// add default notification
consola.info('Add default notification')
+ // await db.announcement.create({
+ // visible: true,
+ // title: 'Welcome to Gancio',
+ // announcement: 'TODO: HTML First presentation post'
+ // })
+
// send confirmed event to mastodon
await db.notification.create({ action: 'Create', type: 'ap', filters: { is_visible: true } })
await db.notification.create({ action: 'Update', type: 'ap', filters: { is_visible: true } })
diff --git a/server/migrations/20200215153310-create-announcement.js b/server/migrations/20200215153310-create-announcement.js
index d770b0f5..a065f900 100644
--- a/server/migrations/20200215153310-create-announcement.js
+++ b/server/migrations/20200215153310-create-announcement.js
@@ -7,12 +7,10 @@ module.exports = {
primaryKey: true,
type: Sequelize.INTEGER
},
- announce: {
+ title: Sequelize.STRING,
+ announcement: {
type: Sequelize.STRING
},
- until: {
- type: Sequelize.DATE
- },
visible: Sequelize.BOOLEAN,
createdAt: {
allowNull: false,
diff --git a/server/routes.js b/server/routes.js
index eba3fd5d..30dab567 100644
--- a/server/routes.js
+++ b/server/routes.js
@@ -12,6 +12,7 @@ const { spamFilter } = require('./federation/helpers')
const debug = require('debug')('routes')
const exportController = require('./api/controller/export')
const eventController = require('./api/controller/event')
+const announceController = require('./api/controller/announce')
const helpers = require('./helpers')
const { startOfMonth, startOfWeek, getUnixTime } = require('date-fns')
@@ -59,11 +60,12 @@ app.use((error, req, res, next) => {
// remaining request goes to nuxt
// first nuxt component is ./pages/index.vue (with ./layouts/default.vue)
-// prefill current events, tags, places (used in every path)
+// prefill current events, tags, places and announcements (used in every path)
app.use(async (req, res, next) => {
const start_datetime = getUnixTime(startOfWeek(startOfMonth(new Date())))
req.events = await eventController._select(start_datetime, 100)
req.meta = await eventController._getMeta()
+ req.announcements = await announceController._getVisible()
next()
})
diff --git a/store/index.js b/store/index.js
index cdb7636f..55faa0c5 100644
--- a/store/index.js
+++ b/store/index.js
@@ -1,6 +1,5 @@
import moment from 'moment-timezone'
import intersection from 'lodash/intersection'
-import find from 'lodash/find'
export const state = () => ({
locale: '',
@@ -26,7 +25,8 @@ export const state = () => ({
show_past_events: false,
show_recurrent_events: false,
show_pinned_event: false
- }
+ },
+ announcements: []
})
export const getters = {
@@ -136,6 +136,9 @@ export const mutations = {
},
setPast (state, in_past) {
state.in_past = in_past
+ },
+ setAnnouncements (state, announcements) {
+ state.announcements = announcements
}
}
@@ -146,6 +149,7 @@ export const actions = {
commit('setSettings', req.settings)
commit('setEvents', req.events)
+ commit('setAnnouncements', req.announcements)
commit('update', req.meta)
// apply settings
@@ -161,6 +165,10 @@ export const actions = {
commit('setEvents', events)
commit('showPastEvents', in_past)
},
+ async updateAnnouncements ({ commit }) {
+ const announcements = await this.$axios.$get('/announcements')
+ commit('setAnnouncements', announcements)
+ },
async updateMeta ({ commit }) {
const { tags, places } = await this.$axios.$get('/event/meta')
commit('update', { tags, places })
@@ -177,6 +185,9 @@ export const actions = {
commit('updateEvent', event)
}
},
+ setAnnouncements ({ commit }, announcements) {
+ commit('setAnnouncements', announcements)
+ },
delEvent ({ commit }, eventId) {
commit('delEvent', eventId)
},