<template> <div class="panel"> <template v-if="user"> <side-bar v-if="user" :role="user && user.status" :avatar="user.avatar" :active="active"> </side-bar> <div v-if="loading" class="page loading"> <span class="error" >{{loadingError}}</span> <spinner></spinner> </div> <home :user="user" v-else-if="active == 1" /> <new-estimate :user="user" :fees="fees" :token="token" v-else-if="active == 2" /> <estimates :user="user" :fees="fees" v-else-if="active == 3" :token="token" @addFeeTemp="(f) => fees.push(f)" @removeFeeTemp="(fee) => fees = fees.filter(f => f.id != fee.id)" @preview="previewEstimate" /> <settings :user="user" :token="token" @updateAvatar="updateAvatar" @updateLetterhead="updateLetterhead" v-else-if="active == 4" /> <sign-out :user="user" v-else-if="active == 5" /> </template> <template v-if="!user && active == 6"> <login @login="start" /> </template> <estimate-test v-else-if="active == 7" :token="token" :estimate="preview" /> </div> </template> <script> import SideBar from "./sidebar.vue" import Spinner from "./spinner.vue" import Home from "./home.vue" import NewEstimate from "./new/new.vue" import Estimates from "./estimates.vue" import EstimateTest from "./estimate-test.vue" import Settings from "./settings.vue" import SignOut from "./sign-out.vue" import Login from "./login.vue" function getCookie(name) { var re = new RegExp(name + "=([^;]+)") var value = re.exec(document.cookie) return (value != null) ? unescape(value[1]) : null } function refreshToken() { const token = getCookie("skouter") const timeout = setTimeout(this.refreshToken, 1000*60*25) fetch(`/api/token`, {method: 'GET', headers: { "Accept": "application/json", "Authorization": `Bearer ${token}`, }, }).then(response => { if (!response.ok) { console.log("Error refreshing token.") clearTimeout(timeout) window.location.hash = '#login' } else { this.token = getCookie("skouter") } }) } function getUser() { const token = getCookie("skouter") this.token = token return fetch(`/api/user`, {method: 'GET', headers: { "Accept": "application/json", "Authorization": `Bearer ${token}`, }, }).then(response => { if (response.ok) { return response.json() } else { // Redirect to login if starting token is invalid window.location.hash = '#login' } }).then (result => { if (!result || !result.length) return // Exit if token is invalid this.user = result[0] if (this.user.avatar) return return getAvatar(token) }).then(b => { const validTypes = ['image/jpeg', 'image/png'] if (!validTypes.includes(b.type) || b.size <= 1) { fetch("/assets/image/empty-avatar.jpg"). then(r => r.blob()).then( a => this.user.avatar = a ) return } this.user.avatar = b return getLetterhead(token) }).then(b => { const validTypes = ['image/jpeg', 'image/png'] if (!validTypes.includes(b.type) || b.size <= 1) { fetch("/assets/image/empty-letterhead.jpg"). then(r => r.blob()).then( a => this.user.letterhead = a ) return } this.user.letterhead = b }) } function getAvatar(t) { return fetch("/api/user/avatar", {method: 'GET', headers: { "Accept": "application/json", "Authorization": `Bearer ${t || this.token}`, } }).then(r => r.blob()) } function getLetterhead(t) { return fetch("/api/user/letterhead", {method: 'GET', headers: { "Accept": "application/json", "Authorization": `Bearer ${t || this.token}`, } }).then(r => r.blob()) } function updateAvatar() { const token = getCookie("skouter") getAvatar(token).then(b => this.user.avatar = b) } function updateLetterhead() { const token = getCookie("skouter") getLetterhead(token).then(b => this.user.letterhead = b) } function getFees() { const token = getCookie("skouter") return fetch(`/api/fees`, {method: 'GET', headers: { "Accept": "application/json", "Authorization": `Bearer ${token}`, }, }).then(response => { if (response.ok) { return response.json() } }).then (result => { if (!result || !result.length) return // Exit if token is invalid or no fees are saved this.fees = result }) } // Used to check the current section of the app generally without a regex match // each time. function active() { if (this.hash == '' || this.hash == '#') { return 1 } else if (/^#new\/?/.exec(this.hash)) { return 2 } else if (/^#estimates\/?/.exec(this.hash)) { return 3 } else if (/^#settings\/?/.exec(this.hash)) { return 4 } else if (/^#sign-out\/?/.exec(this.hash)) { return 5 } else if (/^#login\/?/.exec(this.hash)) { return 6 } else if (/^#estimate\/?/.exec(this.hash)) { return 7 } else { return 0 } } // Fetch data before showing UI. If requests fail, assume token is expired. function start() { this.loading = true let loaders = [] loaders.push(this.getUser()) loaders.push(this.getFees()) Promise.all(loaders).then((a, b) => { this.loading = false if (!b) { // Time untill token expiration may have elapsed before the page // reloaded this.refreshToken() } }).catch(error => { console.log("An error occured %O", error) this.loadingError = "Could not initialize app." window.location.hash = 'login' }) } function previewEstimate(estimate) { this.preview = estimate window.location.hash = 'estimate' } export default { components: { SideBar, Spinner, Home, NewEstimate, EstimateTest, Estimates, Settings, SignOut, Login }, computed: { active }, methods: { getCookie, start, getUser, getFees, refreshToken, updateAvatar, getAvatar, updateLetterhead, getLetterhead, previewEstimate, }, data() { return { loading: true, user: null, hash: window.location.hash, fees: [], loadingError: "", token: '', preview: null, } }, created() { window.onhashchange = () => this.hash = window.location.hash this.token = this.getCookie("skouter") if (!this.token) { window.location.hash = 'login' this.loading = false return } this.start() } } </script>