Skouter mortgage estimates. Web application with view written in PHP and Vue, but controller and models in Go.
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

250 wiersze
5.6 KiB

  1. <template>
  2. <div id="new" class="page">
  3. <h2>New Loan</h2>
  4. <section class="loans-list">
  5. <h3 v-for="(l, indx) in loans"
  6. :class="sel == indx ? 'sel' : ''"
  7. @click="() => sel = indx"
  8. >
  9. {{l.title}}
  10. </h3>
  11. <div class="add">
  12. <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
  13. fill="currentColor" class="bi bi-plus" viewBox="0 0 16 16"> <path d="M8 4a.5.5 0
  14. 0 1 .5.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3A.5.5 0
  15. 0 1 8 4z"/> </svg>
  16. </div>
  17. </section>
  18. <section class="form inputs">
  19. <h3>Loan</h3>
  20. <label>Name</label>
  21. <input :value="loans[sel].title"
  22. @input="(e) => loans[sel].title = stripLetters(e)">
  23. <button @click="del">Delete</button>
  24. </section>
  25. <section class="form inputs">
  26. <div class="hint">
  27. <img class="icon" src="/assets/image/icon/question-circle.svg" alt="">
  28. <div class="tooltip">
  29. <p>Assumes borrower is not self employed, not bankrupt in the past 7
  30. years, a citizen, and intends to occupy the property.</p>
  31. </div>
  32. </div>
  33. <h3>Borrower</h3>
  34. <label>Number of Borrowers</label>
  35. <input :value="loans[sel].borrowers"
  36. @input="(e) => loans.forEach(l => l.borrowers = strip(e))">
  37. <label>Credit Score</label>
  38. <input :value="loans[sel].creditScore"
  39. @input="(e) => loans.forEach(l => l.creditScore = strip(e))">
  40. <label>Monthly Income ($)</label>
  41. <input :value="loans[sel].mIncome"
  42. @input="(e) => loans.forEach(l => l.mIncome = strip(e))">
  43. </section>
  44. <section class="radios form">
  45. <h3>Transaction Type</h3>
  46. <input type="radio" name="transaction_type" value="transaction"
  47. @input="e => loans[sel].transaction = 0"
  48. selected="loans[sel].transaction == 0">
  49. <label>Purchase</label>
  50. <input type="radio" name="transaction_type" value="refinance"
  51. @input="e => loans[sel].transaction = 1"
  52. selected="loans[sel].transaction == 1">
  53. <label>Refinance</label>
  54. </section>
  55. <section class="form inputs">
  56. <h3>Property Details</h3>
  57. <label>Price ($)</label>
  58. <input :value="loans[sel].price" @input="setPrice">
  59. <label>Type</label>
  60. <select id="" name="" v-model="loans[sel].property">
  61. <option value="attched">Single Family Attached</option>
  62. <option value="detached">Single Family Detached</option>
  63. <option value="lorise">Lo-rise (4 stories or less)</option>
  64. <option value="hirise">Hi-rise (over 4 stories)</option>
  65. </select>
  66. </section>
  67. <section class="radios form">
  68. <h3>Loan Type</h3>
  69. <input type="radio" name="loan_type" value="conv" v-model="loans[sel].type"
  70. >
  71. <label>Conventional</label>
  72. <input type="radio" name="loan_type" value="fha" v-model="loans[sel].type">
  73. <label>FHA</label>
  74. <input type="radio" name="loan_type" value="va" v-model="loans[sel].type">
  75. <label>VA</label>
  76. <input type="radio" name="loan_type" value="usda" v-model="loans[sel].type">
  77. <label>USDA</label>
  78. </section>
  79. <section class="form inputs">
  80. <h3>Loan Details</h3>
  81. <label>Loan Term (years)</label>
  82. <input :value="loans[sel].term"
  83. @input="(e) => loans[sel].term = parseInt(e.target.value.replace(/[^0-9]/g, ''))">
  84. <label>Loan Program</label>
  85. <select id="" name="" v-model="loans[sel].program">
  86. <option value="none">None</option>
  87. </select>
  88. <label>Loan to Value (%)</label>
  89. <input :value="loans[sel].ltv" @input="setLtv">
  90. <label>Loan Amount ($)</label>
  91. <input :value="loans[sel].amount"
  92. @input="setAmount">
  93. <label>Housing Expense DTI (%) - Optional</label>
  94. <input :value="loans[sel].housingDti" @input="setHousingDti">
  95. <label>Total DTI (%) - Optional</label>
  96. <input :value="loans[sel].dti" @input="setDti">
  97. </section>
  98. </div>
  99. </template>
  100. <script>
  101. // Strips non-digits from an input box event and returns it's rounded integer
  102. function strip(e) {
  103. return parseInt(e.target.value.replace(/\D/g, '') || 0)
  104. }
  105. function stripLetters(e) {
  106. let value = (e.target.value.replace(/[^\w\s]/g, '').slice(0, 20) || '')
  107. e.target.value = value
  108. return value
  109. }
  110. function del() {
  111. if (this.loans.length > 1) {
  112. let x = this.sel
  113. this.sel = 0
  114. this.loans.splice(x, 1)
  115. }
  116. }
  117. function setLtv(e) {
  118. let ltv = strip(e)
  119. let loan = this.loans[this.sel]
  120. if (!loan.price) return
  121. if (ltv > 100) ltv = 100
  122. if (ltv < 0) ltv = 0
  123. loan.ltv = ltv
  124. e.target.value = ltv
  125. loan.amount = Math.round(ltv / 100 * loan.price)
  126. }
  127. function setAmount(e) {
  128. let amount = strip(e)
  129. let loan = this.loans[this.sel]
  130. if (!loan.price) return
  131. if (amount > loan.price) amount = loan.price
  132. if (amount < 0) amount = 0
  133. loan.amount = amount
  134. e.target.value = amount
  135. loan.ltv = Math.round(amount / loan.price * 100)
  136. }
  137. // Updates the property price for all loans
  138. function setPrice(e) {
  139. let value = strip(e)
  140. this.loans.forEach(l => {
  141. l.price = value
  142. l.amount = Math.round(l.ltv / 100 * value)
  143. })
  144. e.target.value = value
  145. }
  146. function setDti(e) {
  147. let dti = strip(e)
  148. let loan = this.loans[this.sel]
  149. if (!loan.price) return
  150. if (dti > 100) dti = 100
  151. if (dti < 0) dti = 0
  152. e.target.value = dti
  153. loan.dti = dti
  154. }
  155. function setHousingDti(e) {
  156. let housingDti = strip(e)
  157. let loan = this.loans[this.sel]
  158. if (!loan.price) return
  159. if (housingDti > 100) housingDti = 100
  160. if (housingDti < 0) housingDti = 0
  161. e.target.value = housingDti
  162. loan.housingDti = housingDti
  163. }
  164. const loans = [
  165. {
  166. title: "Loan Example",
  167. property: "",
  168. transaction: 0,
  169. type: "",
  170. price: 0,
  171. term: 0,
  172. ltv: 0,
  173. borrowers: 0,
  174. creditScore: 0,
  175. mIncome: 0,
  176. dti: 0,
  177. housingDti: 0,
  178. amount: 0,
  179. program: "",
  180. pud: false,
  181. zip: ''
  182. },
  183. {
  184. title: "Another One",
  185. property: "",
  186. transaction: 0,
  187. type: "",
  188. price: 0,
  189. term: 0,
  190. ltv: 0,
  191. borrowers: 0,
  192. creditScore: 0,
  193. mIncome: 0,
  194. dti: 0,
  195. housingDti: 0,
  196. program: "",
  197. pud: true,
  198. zip: ''
  199. }
  200. ]
  201. export default {
  202. methods: {
  203. setPrice, setLtv, setAmount, setDti, setHousingDti,
  204. strip, stripLetters, del
  205. },
  206. props: ['user'],
  207. data() {
  208. return {
  209. loans: loans, sel: 0, loan: loans[0],
  210. }
  211. }
  212. }
  213. </script>