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.
 
 
 
 
 
 

200 lines
4.0 KiB

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