Skouter mortgage estimates. Web application with view written in PHP and Vue, but controller and models in Go.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

app.vue 4.0 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <template>
  2. <div class="panel">
  3. <template v-if="user">
  4. <side-bar v-if="user" :role="user && user.status" :active="active">
  5. </side-bar>
  6. <div v-if="loading" class="page loading">
  7. <span class="error" >{{loadingError}}</span>
  8. <spinner></spinner>
  9. </div>
  10. <home :user="user" v-else-if="active == 1" />
  11. <new-estimate :user="user" :fees="fees" :token="token" v-else-if="active == 2" />
  12. <estimates :user="user" :fees="fees" v-else-if="active == 3" />
  13. <settings :user="user" v-else-if="active == 4" />
  14. <sign-out :user="user" v-else-if="active == 5" />
  15. </template>
  16. <template v-if="!user && active == 6">
  17. <login @login="start" />
  18. </template>
  19. </div>
  20. </template>
  21. <script>
  22. import SideBar from "./sidebar.vue"
  23. import Spinner from "./spinner.vue"
  24. import Home from "./home.vue"
  25. import NewEstimate from "./new/new.vue"
  26. import Estimates from "./estimates.vue"
  27. import Settings from "./settings.vue"
  28. import SignOut from "./sign-out.vue"
  29. import Login from "./login.vue"
  30. function getCookie(name) {
  31. var re = new RegExp(name + "=([^;]+)")
  32. var value = re.exec(document.cookie)
  33. return (value != null) ? unescape(value[1]) : null
  34. }
  35. function refreshToken() {
  36. const token = getCookie("skouter")
  37. fetch(`/api/token`,
  38. {method: 'GET',
  39. headers: {
  40. "Accept": "application/json",
  41. "Authorization": `Bearer ${token}`,
  42. },
  43. }).then(response => {
  44. if (!response.ok) {
  45. console.log("Error refreshing token.")
  46. } else {
  47. this.token = getCookie("skouter")
  48. }
  49. })
  50. // Recursive refresh
  51. setTimeout(this.refreshToken, 1000*60*25)
  52. }
  53. function getUser() {
  54. const token = getCookie("skouter")
  55. this.token = token
  56. return fetch(`/api/user`,
  57. {method: 'GET',
  58. headers: {
  59. "Accept": "application/json",
  60. "Authorization": `Bearer ${token}`,
  61. },
  62. }).then(response => {
  63. if (response.ok) {
  64. return response.json()
  65. } else {
  66. // Redirect to login if starting token is invalid
  67. window.location.hash = '#login'
  68. }
  69. }).then (result => {
  70. if (!result || !result.length) return // Exit if token is invalid
  71. this.user = result[0]
  72. })
  73. }
  74. function getFees() {
  75. const token = getCookie("skouter")
  76. return fetch(`/api/fees`,
  77. {method: 'GET',
  78. headers: {
  79. "Accept": "application/json",
  80. "Authorization": `Bearer ${token}`,
  81. },
  82. }).then(response => {
  83. if (response.ok) { return response.json() }
  84. }).then (result => {
  85. if (!result || !result.length) return // Exit if token is invalid or no fees are saved
  86. this.fees = result
  87. })
  88. }
  89. // Used to check the current section of the app generally without a regex match
  90. // each time.
  91. function active() {
  92. if (this.hash == '' || this.hash == '#') {
  93. return 1
  94. } else if (/^#new\/?/.exec(this.hash)) {
  95. return 2
  96. } else if (/^#estimates\/?/.exec(this.hash)) {
  97. return 3
  98. } else if (/^#settings\/?/.exec(this.hash)) {
  99. return 4
  100. } else if (/^#sign-out\/?/.exec(this.hash)) {
  101. return 5
  102. } else if (/^#login\/?/.exec(this.hash)) {
  103. return 6
  104. } else {
  105. return 0
  106. }
  107. }
  108. // Fetch data before showing UI. If requests fail, assume token is expired.
  109. function start() {
  110. this.loading = true
  111. let loaders = []
  112. loaders.push(this.getUser())
  113. loaders.push(this.getFees())
  114. Promise.all(loaders).then((a, b) => {
  115. this.loading = false
  116. if (!b) {
  117. // Time untill token expiration may have elapsed before the page
  118. // reloaded
  119. this.refreshToken()
  120. }
  121. }).catch(error => {
  122. console.log("An error occured %O", error)
  123. this.loadingError = "Could not initialize app."
  124. window.location.hash = 'login'
  125. })
  126. }
  127. export default {
  128. components: {
  129. SideBar,
  130. Spinner,
  131. Home,
  132. NewEstimate,
  133. Estimates,
  134. Settings,
  135. SignOut,
  136. Login
  137. },
  138. computed: { active },
  139. methods: {
  140. getCookie,
  141. start,
  142. getUser,
  143. getFees,
  144. refreshToken,
  145. },
  146. data() {
  147. return {
  148. loading: true,
  149. user: null,
  150. hash: window.location.hash,
  151. fees: [],
  152. loadingError: "",
  153. token: '',
  154. }
  155. },
  156. created() {
  157. window.onhashchange = () => this.hash = window.location.hash
  158. this.token = this.getCookie("skouter")
  159. if (!this.token) {
  160. window.location.hash = 'login'
  161. this.loading = false
  162. return
  163. }
  164. this.start()
  165. }
  166. }
  167. </script>