keep going with api porting in nuxt

This commit is contained in:
lesion 2019-04-23 13:45:52 +00:00
parent 35fa25c060
commit eed3896396
17 changed files with 191 additions and 136 deletions

24
.eslintrc.js Normal file
View file

@ -0,0 +1,24 @@
module.exports = {
root: true,
env: {
browser: true,
node: true
},
parserOptions: {
parser: 'babel-eslint'
},
extends: [
'@nuxtjs',
// 'plugin:nuxt/recommended',
// 'plugin:prettier/recommended',
// 'prettier',
// 'prettier/vue'
],
plugins: [
'prettier'
],
// add your custom rules here
rules: {
'nuxt/no-cjs-in-config': 'off'
}
}

View file

@ -1,12 +1,11 @@
<template lang="pug">
v-calendar#calendar.card(
show-caps
:popover-expanded='true'
:attributes='attributes'
:from-page.sync='page'
is-expanded is-inline)
div(slot='popover', slot-scope='{ customData }')
router-link(:to="`/event/${customData.id}`") {{customData.start_datetime|hour}} - {{customData.title}} @{{customData.place.name}}
//- div(slot='popover', slot-scope='{ customData }')
//- router-link(:to="`/event/${customData.id}`") {{customData.start_datetime|hour}} - {{customData.title}} @{{customData.place.name}}
</template>
<script>
import { mapState, mapActions } from 'vuex'
@ -40,10 +39,10 @@ export default {
key: event.id,
customData: event,
order: event.start_datetime,
popover: {
slot: 'popover',
visibility: 'hover'
}
// popover: {
// slot: 'popover',
// visibility: 'hover'
// }
}
let color = event.tags && event.tags.length && event.tags[0].color ? event.tags[0].color : 'rgba(170,170,250,0.7)'
@ -73,7 +72,7 @@ export default {
highlight: {
backgroundColor: '#aaffaa'
},
popover: {label: this.$t('Today')}
// popover: {label: this.$t('Today')}
},
...this.filteredEvents.map(this.eventToAttribute)
]

View file

@ -1,13 +1,14 @@
<template lang="pug">
b-card(bg-variant='dark' text-variant='white' :class="{ withImg: event.image_path ? true : false }"
@click='$router.push("/event/" + event.id)'
:img-src='imgPath')
strong {{event.title}}
div <v-icon name='clock'/> {{event.start_datetime|datetime}}
//- span <v-icon name='map-marker-alt'/> {{event.place.name}}
br
el-tag.mr-1(:color='tag.color || "grey"' v-for='tag in event.tags' :key='tag.tag'
size='small' @click.stop='addSearchTag(tag)') {{tag.tag}}
nuxt-link(:to='`/event/${event.id}`')
//- @click='$router.push("/event/" + event.id)'
b-card(bg-variant='dark' text-variant='white' :class="{ withImg: event.image_path ? true : false }"
:img-src='imgPath')
strong {{event.title}}
div <v-icon name='clock'/> {{event.start_datetime|datetime}}
//- span <v-icon name='map-marker-alt'/> {{event.place.name}}
br
el-tag.mr-1(:color='tag.color || "grey"' v-for='tag in event.tags' :key='tag.tag'
size='small' @click.stop='addSearchTag(tag)') {{tag.tag}}
</template>
<script>
import { mapState, mapActions } from 'vuex'

View file

@ -40,7 +40,7 @@ export default {
},
watch: {
filteredEvents() {
// this.$nextTick(this.$refs.magicgrid.positionItems) TOFIX
this.$nextTick(this.$refs.magicgrid.positionItems)
}
}
}

View file

@ -16,7 +16,9 @@ module.exports = {
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }]
},
serverMiddleware: [{ path: '/api', handler: '@/server/api/index.js' }],
serverMiddleware: [
{ path: '/api', handler: '@/server/api/index.js' }
],
/*
** Customize the progress-bar color
@ -39,7 +41,8 @@ module.exports = {
plugins: ['@/plugins/element-ui', '@/plugins/filters',
'@/plugins/i18n', '@/plugins/bootstrap-vue',
'@/plugins/vue-awesome',
{ src: '@/plugins/v-calendar', ssr: false },
'@/plugins/v-calendar',
{ src: '@/plugins/vuex-persist', ssr: false },
'@/plugins/magic-grid'],
/*
@ -53,6 +56,8 @@ module.exports = {
** Axios module configuration
*/
axios: {
prefix: '/api',
credentials: true
// See https://github.com/nuxt-community/axios-module#options
},
@ -60,7 +65,7 @@ module.exports = {
** Build configuration
*/
build: {
transpile: [/^element-ui/, /^vue-awesome/, /^vue-magic-grid/],
transpile: [/^element-ui/, /^vue-awesome/, /^vue-magic-grid/, /^vuex-persist/],
/*
** You can extend webpack config here

View file

@ -13,7 +13,7 @@
"precommit": "npm run lint"
},
"dependencies": {
"@nuxtjs/axios": "^5.3.6",
"@nuxtjs/axios": "^5.4.1",
"axios": "^0.18.0",
"bcrypt": "^3.0.5",
"body-parser": "^1.18.3",
@ -27,15 +27,18 @@
"ics": "^2.13.2",
"jsonwebtoken": "^8.5.1",
"mastodon-api": "^1.3.0",
"morgan": "^1.9.1",
"multer": "^1.4.1",
"nuxt": "^2.4.0",
"pg": "^7.10.0",
"sequelize": "^5.2.1",
"sharp": "^0.22.0",
"sqlite3": "^4.0.6",
"v-calendar": "^0.9.7",
"vue-awesome": "^3.5.1",
"vue-i18n": "^8.10.0",
"vue-magic-grid": "^0.0.4"
"vue-magic-grid": "^0.0.4",
"vuex-persist": "^2.0.0"
},
"devDependencies": {
"@nuxtjs/eslint-config": "^0.0.1",

View file

@ -16,7 +16,7 @@
<script>
import { mapActions } from 'vuex'
import { Message } from 'element-ui'
import api from '@/plugins/api'
// import api from '@/plugins/api'
export default {
name: 'Login',
@ -36,7 +36,7 @@ export default {
return
}
this.loading = true
await api.forgotPassword(this.email)
// await api.forgotPassword(this.email)
this.loading = false
Message({ message: this.$t('Check your email!'), type: 'success' })
},
@ -44,7 +44,7 @@ export default {
e.preventDefault()
try {
this.loading = true
const user = await api.login(this.email, this.password)
const user = await this.$axios.$post('/login', { email: this.email, password: this.password })
this.loading = false
if (!user) {
Message({ message: this.$t('Login error'), type: 'error' })

View file

@ -127,6 +127,10 @@ export default {
// this.settings = await api.getAdminSettings()
this.mastodon_instance = this.settings.mastodon_auth && this.settings.mastodon_auth.instance
},
async asyncData ({ $axios, params }) {
const users = await $axios.$get('/users')
return { users }
},
computed: {
...mapState(['tags', 'places']),
paginatedEvents () {

View file

@ -1,8 +1,9 @@
<template lang="pug">
b-modal#eventDetail(ref='eventDetail' hide-body hide-header hide-footer @hidden='$router.replace("/")' size='lg' :visible='true')
b-card(no-body, :img-src='imgPath' v-loading='loading')
el-button.close_button(circle icon='el-icon-close' type='success'
@click='$refs.eventDetail.hide()')
nuxt-link(to='/')
el-button.close_button(circle icon='el-icon-close' type='success'
@click='$refs.eventDetail.hide()')
b-card-header
h3 {{event.title}}
v-icon(name='clock')
@ -40,7 +41,7 @@
</template>
<script>
import { mapState, mapActions } from 'vuex';
import api from '@/plugins/api'
// import api from '@/plugins/api'
//import filters from '@/filters'
export default {
@ -61,17 +62,25 @@ export default {
loading: true,
}
},
mounted () {
this.id = this.$route.params.id
this.load()
// mounted () {
// this.id = this.$route.params.id
// this.load()
// },
async asyncData ( { $axios, params }) {
console.error('daje dentro asyncData!')
console.error('async data porcod')
const event = await $axios.$get(`/event/${params.id}`)
// this.event = event
// this.loading = false
return { event, id: params.id, loading: false }
},
methods: {
...mapActions(['delEvent']),
async load () {
const event = await api.getEvent(this.id)
this.event = event
this.loading = false
},
// async load () {
// const event = await this.api.getEvent(this.id)
// this.event = event
// this.loading = false
// },
async remove () {
await api.delEvent(this.event.id)
this.delEvent(this.event.id)
@ -80,11 +89,12 @@ export default {
async toggle () {
try {
if (this.event.is_visible) {
await api.unconfirmEvent(this.id)
await this.$axios.$get(`/event/unconfirm/${this.id}`)
// await api.unconfirmEvent(this.id)
this.event.is_visible = false
} else {
await api.confirmEvent(this.id)
await this.$axios.$get(`/event/confirm/${this.id}`)
// await api.confirmEvent(this.id)
this.event.is_visible = true
}
} catch (e) {
@ -95,6 +105,12 @@ export default {
}
</script>
<style>
/* #eventDetail {
display: block !important;
opacity: 1;
} */
#eventDetail .modal-body {
padding: 0px;
width: 100%;

View file

@ -62,7 +62,7 @@
</template>
<script>
import api from '@/plugins/api'
// import api from '@/plugins/api'
import { mapActions, mapState } from 'vuex'
import moment from 'dayjs'
import Calendar from '@/components/Calendar'
@ -110,7 +110,6 @@ export default {
if (event.tags) {
this.event.tags = event.tags.map(t => t.tag)
}
}
this.updateMeta()
},

View file

@ -6,14 +6,13 @@
el-input.mb-2(ref='email' v-model='user.email' type='email'
:placeholder='$t("Email")' autocomplete='email')
span(slot='prepend') @
el-input.mb-2(v-model='user.password' type="password" placeholder="Password")
v-icon(name='lock' slot='prepend')
el-input.mb-2(v-model='user.description' type="textarea" rows='3' :placeholder="$t('Description')")
v-icon(name='envelope-open-text')
el-button.float-right(plain type="success" icon='el-icon-arrow-right' @click='register') {{$t('Send')}}
</template>
@ -34,7 +33,8 @@ export default {
...mapActions(['login']),
async register () {
try {
const user = await api.register(this.user)
const user = await this.$axios.$post('/user', this.user) //api.register(this.user)
console.log(user)
if (!user.is_admin) {
this.$refs.modal.hide()
Message({

View file

@ -1,82 +1,80 @@
import axios from 'axios'
import { getters } from '@/store'
const api = axios.create({
baseURL: process.env.NODE_ENV === 'development' ? 'http://localhost:3000/api' : '/api',
withCredentials: true,
responseType: 'json',
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Credentials': 'true',
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
// import axios from 'axios'
// import { getters } from '@/store'
// const api = axios.create({
// baseURL: process.env.NODE_ENV === 'development' ? 'http://localhost:3000/api' : '/api',
// withCredentials: true,
// responseType: 'json',
// headers: {
// // 'Access-Control-Allow-Origin': '*',
// // 'Access-Control-Allow-Credentials': 'true',
// // 'Accept': 'application/json',
// 'Content-Type': 'application/json'
// }
// })
function get(path) {
return api.get(path) //, { headers: { 'Authorization': getters.token } })
.then(res => res.data)
// .catch((e) => {
// if (e.response.status === 403) {
// // store.commit('logout') // TOFIX
// return false
// }
// throw e.response && e.response.data &&
// e.response.data.errors && e.response.data.errors[0].message
// })
}
// export default function ({ $axios }) {
// function get(path) {
// return $axios.$get(path, { headers: { 'Authorization': 'Bearer ' + getters.token } })
// }
function post(path, data) {
return api.post(path, data, { headers: { 'Authorization': getters.token } })
.then(res => res.data)
// .catch((e) => {
// if (e.response.status === 403) {
// // store.commit('logout') // TOFIX
// return false
// }
// throw e.response && e.response.data &&
// e.response.data.errors && e.response.data.errors[0].message
// })
}
function put(path, data) {
return api.put(path, data, { headers: { 'Authorization': getters.token } })
.then(ret => ret.data)
}
// function post(path, data) {
// return $axios.$post(path, data)
// }
function del(path) {
return api.delete(path, { headers: { 'Authorization': getters.token } }).then(ret => ret.data)
}
// function post(path, data) {
// return api.post(path, data) // , { headers: { 'Authorization': getters.token } })
// .then(res => res.data)
// .catch((e) => {
// console.error(e)
// if (e.response.status === 403) {
// // store.commit('logout') // TOFIX
// return false
// }
// throw e.response && e.response.data &&
// e.response.data.errors && e.response.data.errors[0].message
// })
// }
// function put(path, data) {
// return api.put(path, data, { headers: { 'Authorization': getters.token } })
// .then(ret => ret.data)
// }
export default {
login: (email, password) => post('/login', { email, password }),
register: user => post('/user', user),
// function del(path) {
// return api.delete(path, { headers: { 'Authorization': getters.token } }).then(ret => ret.data)
// }
// password recovery
forgotPassword: email => post('/user/recover', { email }),
checkRecoverCode: recover_code => post('/user/check_recover_code', { recover_code }),
recoverPassword: (recover_code, password) => post('/user/recover_password', { recover_code, password }),
// return {
// login: (email, password) => post('/login', { email, password }),
// register: user => post('/user', user)
getAllEvents: (month, year) => get(`/event/${year}/${month}`),
getUnconfirmedEvents: () => get('/event/unconfirmed'),
// // password recovery
// forgotPassword: email => post('/user/recover', { email }),
// checkRecoverCode: recover_code => post('/user/check_recover_code', { recover_code }),
// recoverPassword: (recover_code, password) => post('/user/recover_password', { recover_code, password }),
confirmEvent: id => get(`/event/confirm/${id}`),
unconfirmEvent: id => get(`/event/unconfirm/${id}`),
// getAllEvents: (month, year) => get(`/event/${year}/${month}`),
// getUnconfirmedEvents: () => get('/event/unconfirmed'),
addNotification: notification => post('/event/notification', notification),
delNotification: code => del(`/event/notification/${code}`),
// confirmEvent: id => get(`/event/confirm/${id}`),
// unconfirmEvent: id => get(`/event/unconfirm/${id}`),
addEvent: event => post('/user/event', event),
updateEvent: event => put('/user/event', event),
// addNotification: notification => post('/event/notification', notification),
// delNotification: code => del(`/event/notification/${code}`),
updatePlace: place => put('/place', place),
delEvent: eventId => del(`/user/event/${eventId}`),
getEvent: eventId => get(`/event/${eventId}`),
getMeta: () => get('/event/meta'),
getUser: () => get('/user'),
getUsers: () => get('/users'),
updateTag: tag => put('/tag', tag),
updateUser: user => put('/user', user),
getAuthURL: mastodonInstance => post('/user/getauthurl', mastodonInstance),
setCode: code => post('/user/code', code),
getAdminSettings: () => get('/settings')
// setAdminSetting: (key, value) => post('/settings', { key, value })
}
// addEvent: event => post('/user/event', event),
// updateEvent: event => put('/user/event', event),
// updatePlace: place => put('/place', place),
// delEvent: eventId => del(`/user/event/${eventId}`),
// getEvent: eventId => get(`/event/${eventId}`),
// getMeta: () => get('/event/meta'),
// getUser: () => get('/user'),
// getUsers: () => get('/users'),
// updateTag: tag => put('/tag', tag),
// updateUser: user => put('/user', user),
// getAuthURL: mastodonInstance => post('/user/getauthurl', mastodonInstance),
// setCode: code => post('/user/code', code),
// getAdminSettings: () => get('/settings')
// // setAdminSetting: (key, value) => post('/settings', { key, value })
// }
// }

View file

@ -2,7 +2,10 @@ import Vue from 'vue'
import { Button, Select, Tag, Option, Table, FormItem, Card,
Form, Tabs, TabPane, Switch, Input, Loading, TimeSelect,
TableColumn, ColorPicker, Pagination, Popover } from 'element-ui'
// import locale from 'element-ui/lib/locale/lang/en'
import localeEn from 'element-ui/lib/locale/lang/en'
import localeIt from 'element-ui/lib/locale/lang/it'
import locale from 'element-ui/lib/locale'
locale.use(localeIt)
export default () => {
Vue.use(Button)

8
plugins/vuex-persist.js Normal file
View file

@ -0,0 +1,8 @@
// ~/plugins/vuex-persist.js
import VuexPersistence from 'vuex-persist'
export default ({ store }) => {
return new VuexPersistence({
reducer: state => ({ logged: state.logged, user: state.user, token: state.token })
}).plugin(store)
}

View file

@ -6,7 +6,7 @@ const User = require('./models/user')
const Auth = {
fillUser(req, res, next) {
const token =
req.body.token || req.params.token || req.headers['x-access-token']
req.body.token || req.params.token || req.headers.authorization
if (!token) return next()
jwt.verify(token, config.secret, async (err, decoded) => {
if (err) return next()
@ -20,7 +20,8 @@ const Auth = {
const token =
(req.body && req.body.token) ||
req.params.token ||
req.headers['x-access-token']
req.headers.authorization
console.error('sono dentro isAuth ', token, req.headers)
if (!token) return res.status(403).send({ message: 'Token not found' })
jwt.verify(token, config.secret, async (err, decoded) => {
if (err) {

View file

@ -1,5 +1,6 @@
const express = require('express')
const consola = require('consola')
const morgan = require('morgan')
const bodyParser = require('body-parser')
const { Nuxt, Builder } = require('nuxt')
const app = express()
@ -29,7 +30,7 @@ async function start() {
// Give nuxt middleware to express
app.use(cors(corsConfig))
// app.use(morgan('dev'))
app.use(morgan('dev'))
// app.set('views', path.join)
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

View file

@ -51,7 +51,6 @@ export const getters = {
return 0
})
}
}
export const mutations = {
@ -112,40 +111,34 @@ export const actions = {
// set user if logged! TODO
const now = new Date()
const events = await api.getAllEvents(now.getMonth() - 1, now.getFullYear())
// const events = await api.getAllEvents(now.getMonth() - 1, now.getFullYear())
const events = await this.$axios.$get(`/event/${now.getMonth() - 1}/${now.getFullYear()}`)
commit('setEvents', events)
},
async updateEvents({ commit }, date) {
console.log('dentro updateEvents ', date.month, api)
try {
const events = await api.getAllEvents(date.month - 1, date.year)
console.log('dopo getAll events', events)
commit('setEvents', events)
} catch (e) {
console.log(e)
}
},
async updateMeta({ commit }) {
const { tags, places } = await api.getMeta()
const { tags, places } = await this.$axios.$get('/event/meta')
commit('update', { tags, places })
},
async addEvent({ commit }, formData) {
const event = await api.addEvent(formData)
console.log('ciao addEvent')
const event = await this.$axios.$post('/user/event', formData) // .addEvent(formData)
if (this.state.logged) {
commit('addEvent', event)
}
},
async updateEvent({ commit }, formData) {
const event = await api.updateEvent(formData)
const event = await this.$axios.$put('/user/event', formData)
commit('updateEvent', event)
},
delEvent({ commit }, eventId) {
commit('delEvent', eventId)
},
login({ commit }, user) {
this.$axios.setToken(user.token)
commit('login', user)
},
logout({ commit }) {
this.$axios.setToken(false)
commit('logout')
},
// search