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.
 
 
 
 
 
 

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