|
- <template>
- <div class="app-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)"
- @download="downloadEstimate"
- />
-
- <settings
- :user="user"
- :token="token"
- @updateAvatar="updateAvatar"
- @updateLetterhead="updateLetterhead"
- v-else-if="active == 4" />
-
- <biller v-if="invalidSub" :user="user"/>
-
- <sign-out :user="user" v-if="active == 5" />
-
- </template>
-
- <template v-if="!user && active == 6">
- <login @login="start" />
- </template>
-
- </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 Settings from "./settings.vue"
- import SignOut from "./sign-out.vue"
- import Login from "./login.vue"
- import Biller from "./update-billing/update-billing.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 fetchUser() {
- return fetch(`/api/user`,
- {method: 'GET',
- headers: {
- "Accept": "application/json",
- "Authorization": `Bearer ${getCookie("skouter")}`,
- },
- }).then(response => {
- if (response.ok) {
- return response.json()
- }
- })
- }
-
- 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) return // Exit if token is invalid
- this.user = result
- if (this.user.avatar) return
-
- return getAvatar(token)
- }).then(b => {
- const validTypes = ['image/jpeg', 'image/png']
-
- if (!b || !validTypes.includes(b.type) || b.size <= 1) {
- fetch("/assets/image/default-avatar.jpg").
- then(r => r.blob()).then( a => this.user.avatar = a )
- } else {
- this.user.avatar = b
- }
-
- return getLetterhead(token)
- }).then(b => {
- const validTypes = ['image/jpeg', 'image/png']
-
- if (!b || !validTypes.includes(b.type) || b.size <= 1) {
- fetch("/assets/image/default-avatar.jpg").
- then(r => r.blob()).then( a => this.user.letterhead = a )
- } else {
- 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
- const validStatuses = ["incomplete", "trialing", "active"]
-
- let loaders = []
- loaders.push(this.getUser())
- loaders.push(this.getFees())
- Promise.all(loaders).then((a, b) => {
- this.loading = false
- if (!b) { // !b means there is no rejection error for any promise
- // Time untill token expiration may have elapsed before the page
- // reloaded
- this.refreshToken()
- fetchUser().then( u => {
- if (u.sub.customerId &&
- validStatuses.includes(u.sub.paymentStatus) &&
- this.user.status != "Unsubscribed") {
- return
- }
- // Payment must be updated
- this.invalidSub = true
- })
- }
- window.location.hash = ''
- }).catch(error => {
- console.log("An error occured %O", error)
- this.loadingError = "Could not initialize app."
- window.location.hash = 'login'
- })
-
- }
-
- function downloadEstimate(estimate) {
- fetch(`/api/pdf`,
- {method: 'POST',
- body: JSON.stringify(estimate),
- headers: {
- "Accept": "application/json",
- "Authorization": `Bearer ${this.token}`,
- },
- }).then(response => {
- if (response.ok) { return response.blob() }
- }).then (result => {
- console.log(result)
- if (!result) return // Exit if token is invalid or blank file returned
- })
- }
-
- export default {
- components: {
- SideBar,
- Spinner,
- Home,
- NewEstimate,
- Estimates,
- Settings,
- Biller,
- SignOut,
- Login
- },
- computed: { active },
- methods: {
- getCookie,
- start,
- getUser,
- getFees,
- refreshToken,
- updateAvatar,
- getAvatar,
- updateLetterhead,
- getLetterhead,
- downloadEstimate,
- },
- data() {
- return {
- loading: true,
- user: null,
- hash: window.location.hash,
- fees: [],
- loadingError: "",
- token: '',
- invalidSub: false,
- }
- },
- 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>
|