Skip to content

Commit

Permalink
fix: detección geo, mensajes y errores (#111)
Browse files Browse the repository at this point in the history
* chore: agrega servicio sentry

* fix: mejora logica y validaciones servicio user

* chore: mueve servicios a carpeta

* fix: mejoras menores helper

* fix: mejora validacion inicial app

* fix: mejora action para obtener geo

* chore: actualiza deps

* chore: remueve validacion inicial route

* fix: mejoras validaciones y mensajes de error

* chore: agrega param save-exact

* fix: mejoras en el retorno de codigos de errores

* chore: modifica orden de carga de action userGeoData
  • Loading branch information
raulghm authored Oct 28, 2019
1 parent d51a4b3 commit 6356a28
Show file tree
Hide file tree
Showing 15 changed files with 366 additions and 169 deletions.
3 changes: 2 additions & 1 deletion .env-example
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
NODE_ENV=development
VUE_APP_TITLE=GrowlerApp
VUE_APP_GRAPHQL_API=https://api-growlerapp.herokuapp.com/graphql
VUE_APP_GOOGLE_MAPS_KEY=
VUE_APP_GOOGLE_MAPS_KEY=
VUE_APP_SENTRY_SLUG=''
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
package-lock=false
save-exact=true
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"generate-icons": "icon-font-generator icons/svg/*.svg -o public/icons --prefix ico --csstp icons/css.hbs --htmltp icons/html.hbs --fontspath ./"
},
"dependencies": {
"@sentry/browser": "^5.7.1",
"@sentry/integrations": "^5.7.1",
"apollo-cache-inmemory": "1.6.3",
"apollo-client": "2.6.4",
"apollo-link-http": "1.5.16",
Expand Down
13 changes: 11 additions & 2 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

<script>
import vHeader from '@/components/v-Header'
import { checkUserGeoData } from '@/services/user'
export default {
name: 'App',
Expand All @@ -21,8 +22,16 @@ export default {
vHeader
},
created () {
this.$store.dispatch('userGeoData', { force: false })
mounted () {
/**
* Busca si existe geo data almacenada localmente
* de lo contrario devuelve a vista splash
*/
if (checkUserGeoData()) {
this.$store.dispatch('userGeoData', { force: false })
} else {
this.$router.push('/')
}
}
}
</script>
Expand Down
7 changes: 4 additions & 3 deletions src/helpers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ const isJSON = json => {
if (json && typeof json === 'object' && json !== null) {
return true
}
} catch (err) {}
return false
} catch (error) {
return error
}
}

export default {
export {
isJSON
}
3 changes: 2 additions & 1 deletion src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import App from './App.vue'
import router from './router'
import store from './store'
import './registerServiceWorker'
import { apolloProvider } from './apollo'
import './services/sentry'
import { apolloProvider } from './services/apollo'

Vue.config.productionTip = false

Expand Down
14 changes: 1 addition & 13 deletions src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,9 @@ import Home from '@/views/Home'
import Splash from '@/views/Splash'
import About from '@/views/About'
import Store from '@/views/Store'
import user from '@/user'

Vue.use(Router)

const requireUser = (to, from, next) => {
if (!user.checkUserGeoData()) {
next({
path: '/'
})
} else {
next()
}
}

export default new Router({
scrollBehavior () {
return new Promise(resolve => {
Expand All @@ -41,8 +30,7 @@ export default new Router({
{
path: '/home',
name: 'home',
component: Home,
beforeEnter: requireUser
component: Home
},
{
path: '/store/:id',
Expand Down
File renamed without changes.
10 changes: 10 additions & 0 deletions src/services/sentry.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Vue from 'vue'
import * as Sentry from '@sentry/browser'
import * as Integrations from '@sentry/integrations'

if (process.env.NODE_ENV === 'production') {
Sentry.init({
dsn: process.env.VUE_APP_SENTRY_SLUG,
integrations: [new Integrations.Vue({ Vue, attachProps: true })]
})
}
130 changes: 130 additions & 0 deletions src/services/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import { isJSON } from '@/helpers'

/**
* Parse any errors from PositionError callback
* @param {object} error
* @return {object}
*/
const parsePositionError = error => {
switch (error.code) {
case error.PERMISSION_DENIED:
return {
code: 1,
message: 'User denied the request for geolocation.'
}
case error.POSITION_UNAVAILABLE:
return {
code: 2,
message: 'Location information is unavailable.'
}
case error.TIMEOUT:
return {
code: 3,
message: 'The request to get user location timed out.'
}
}
}

/**
* Get user geo from device
* @return {Promise<Object>}
* https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API
*/
const getUserGeoDataFromDevice = () => {
return new Promise((resolve, reject) => {
if ('geolocation' in navigator) {
navigator.geolocation.getCurrentPosition(({ coords }) =>
resolve(coords), error => reject(parsePositionError(error))
)
}
})
}

/**
* Fetch user geo data
* @return {object} user geo data
*/
const fetchUserGeoData = () => {
return new Promise(async (resolve, reject) => {
try {
let data = await getUserGeoDataFromDevice()
data = {
lat: data.latitude,
long: data.longitude
}
setUserGeoDataToStorage(data)
resolve(data)
} catch (error) {
// eslint-disable-next-line prefer-promise-reject-errors
reject(error)
}
})
}

/**
* Set flag if user has joined to app
*/
const setUserHasJoined = () => {
localStorage.setItem('userHasJoined', JSON.stringify(true))
}

/**
* Check if user has joined to app
*/
const checkHasJoined = () => {
return !!localStorage.getItem('userHasJoined')
}

/**
* Set user geo data
* @param {object} data
*/
const setUserGeoDataToStorage = data => {
localStorage.setItem('userGeoData', JSON.stringify(data))
}

/**
* Get user geo data from localstorage
*/
const getUserGeoDataFromStorage = () => {
try {
return JSON.parse(localStorage.getItem('userGeoData'))
} catch (err) {
return null
}
}

/**
* Check if user has geo data
*/
const checkUserGeoData = () => {
const data = getUserGeoDataFromStorage()
return isJSON(data) && data.lat && data.long
}

/**
* Get user data from storage or user device
* @param {boolean} force
* @return {Promise<object>} user geo data
*/
const getUserData = (force = false) => {
try {
if (force) {
return fetchUserGeoData()
} else {
return checkUserGeoData()
? getUserGeoDataFromStorage()
: fetchUserGeoData()
}
} catch (error) {
return error
}
}

export {
getUserData,
checkUserGeoData,
checkHasJoined,
setUserHasJoined,
fetchUserGeoData
}
18 changes: 12 additions & 6 deletions src/store.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Vue from 'vue'
import Vuex from 'vuex'
import user from '@/user'
import { getUserData } from '@/services/user'

Vue.use(Vuex)

Expand All @@ -16,9 +16,8 @@ export default new Vuex.Store({
setLoading (state, value) {
state.loading = value
},
async setUserGeoData (state, { force }) {
const data = await user.getUserData(force)
state.userData = data
setUserGeoData (state, value) {
state.userData = value
},
setMenu (state, value) {
state.isMenuActive = value
Expand All @@ -29,8 +28,15 @@ export default new Vuex.Store({
},

actions: {
userGeoData ({ commit }, payload) {
commit('setUserGeoData', payload)
userGeoData ({ commit }, { force }) {
return new Promise(async (resolve, reject) => {
try {
commit('setUserGeoData', await getUserData(force))
resolve(true)
} catch (error) {
reject(error)
}
})
}
}
})
96 changes: 0 additions & 96 deletions src/user.js

This file was deleted.

Loading

0 comments on commit 6356a28

Please sign in to comment.