Skouter mortgage estimates. Web application with view written in PHP and Vue, but controller and models in Go.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 
 

203 lines
4.7 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 :user="user" :fees="fees" 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.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. }
  47. })
  48. // Recursive refresh
  49. setTimeout(this.refreshToken, 1000*60*25)
  50. }
  51. function getUser() {
  52. const token = getCookie("skouter")
  53. return fetch(`/api/user`,
  54. {method: 'GET',
  55. headers: {
  56. "Accept": "application/json",
  57. "Authorization": `Bearer ${token}`,
  58. },
  59. }).then(response => {
  60. if (response.ok) {
  61. return response.json()
  62. } else {
  63. // Redirect to login if starting token is invalid
  64. window.location.hash = '#login'
  65. }
  66. }).then (result => {
  67. if (!result || !result.length) return // Exit if token is invalid
  68. this.user = result[0]
  69. })
  70. }
  71. function getFees() {
  72. const token = getCookie("skouter")
  73. return fetch(`/api/fees`,
  74. {method: 'GET',
  75. headers: {
  76. "Accept": "application/json",
  77. "Authorization": `Bearer ${token}`,
  78. },
  79. }).then(response => {
  80. if (response.ok) { return response.json() }
  81. }).then (result => {
  82. if (!result || !result.length) return // Exit if token is invalid or no fees are saved
  83. this.fees = result
  84. console.log("the result %O", result)
  85. })
  86. }
  87. // The default fees of a new loan. Percentage values take precedent over amounts
  88. const fees = [
  89. { name: 'Processing fee', type: 'Lender Fees', amount: 500, perc: 0 },
  90. { name: 'Underwriting fee', type: 'Lender Fees', amount: 500, perc: 0 },
  91. { name: 'Credit Report', type: 'Services Required by Lender',
  92. amount: 52.50 },
  93. { name: 'Appraisal', type: 'Services Required by Lender', amount: 52.50 },
  94. { name: 'Title Services', type: 'Title Company', amount: 1000 },
  95. { name: 'Lender\'s Title Insurance', type: 'Title Company', amount: 1599 },
  96. { name: 'Owner\'s Title Insurance', type: 'Title Company', amount: 451.00 },
  97. { name: 'Recording Charges', type: 'Government', amount: 99.00 },
  98. { name: 'State Tax', type: 'Government', amount: 2411.00 },
  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. }
  165. },
  166. created() {
  167. window.onhashchange = () => this.hash = window.location.hash
  168. this.token = this.getCookie("skouter")
  169. if (!this.token) {
  170. window.location.hash = 'login'
  171. this.loading = false
  172. return
  173. }
  174. this.start()
  175. }
  176. }
  177. </script>