Skouter mortgage estimates. Web application with view written in PHP and Vue, but controller and models in Go.
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
2 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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 @click="create"
  13. xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
  14. class="bi bi-plus" viewBox="0 0 16 16"> <path d="M8 4a.5.5 0 0 1 .5.5v3h3a.5.5 0
  15. 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 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="estimate.borrowers"
  36. @input="(e) => estimate.borrowers = strip(e)">
  37. <label>Credit Score</label>
  38. <input :value="estimate.creditScore"
  39. @input="(e) => estimate.creditScore = strip(e)">
  40. <label>Monthly Income ($)</label>
  41. <input :value="estimate.mIncome"
  42. @input="(e) => estimate.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 => estimate.transaction = 0"
  48. selected="estimate.transaction == 0">
  49. <label>Purchase</label>
  50. <input type="radio" name="transaction_type" value="refinance"
  51. @input="e => estimate.transaction = 1"
  52. selected="estimate.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="estimate.price" @input="setPrice">
  59. <label>Type</label>
  60. <select id="" name="" v-model="estimate.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 = strip(e)">
  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. <label>Interest Rate (%)</label>
  98. <input :value="loans[sel].interest" @input="setInterest">
  99. <label>Days of Interest</label>
  100. <input :value="loans[sel].interestDays" @input="setInterestDays">
  101. <label>Hazard Insurance Escrowed?</label>
  102. <input type="checkbox" :value="loans[sel].hazardEscrowed" @input="">
  103. <label>Months to Escrow Hazard Insurance</label>
  104. <input :value="loans[sel].hazardMonths" @input="">
  105. <label>Hazard Insurance ($/monthly)</label>
  106. <input :value="loans[sel].hazard" @input="setHazard">
  107. <label>Taxes Escrowed?</label>
  108. <input type="checkbox" :value="loans[sel].taxEscrowed" @input="">
  109. <label>Months to Escrow Real Estate Tax</label>
  110. <input :value="loans[sel].taxEscrow" @input="">
  111. <label>Real Estate Tax ($/monthly)</label>
  112. <input :value="loans[sel].tax" @input="setTax">
  113. </section>
  114. <section class="form inputs">
  115. <h3>Interest Rates</h3>
  116. <label>Loan Term (years)</label>
  117. <input :value="loans[sel].term"
  118. @input="(e) => loans[sel].term = strip(e)">
  119. <label>Loan Program</label>
  120. <select id="" name="" v-model="loans[sel].program">
  121. <option value="none">None</option>
  122. </select>
  123. <label>Loan to Value (%)</label>
  124. <input :value="loans[sel].ltv" @input="setLtv">
  125. <label>Loan Amount ($)</label>
  126. <input :value="loans[sel].amount"
  127. @input="setAmount">
  128. <label>Housing Expense DTI (%) - Optional</label>
  129. <input :value="loans[sel].housingDti" @input="setHousingDti">
  130. <label>Total DTI (%) - Optional</label>
  131. <input :value="loans[sel].dti" @input="setDti">
  132. </section>
  133. </div>
  134. </template>
  135. <script>
  136. const example = {
  137. title: "Example",
  138. type: "",
  139. term: 0,
  140. ltv: 0, // Loan to home value ratio
  141. dti: 0,
  142. housingDti: 0,
  143. amount: 0,
  144. interest: 0,
  145. interestDays: 0,
  146. hazard: 0, // Hazard insurance monthly payment
  147. hazardMonths: 0, // Hazard insurance months
  148. hazardEscrowed: true, // If hazard insurance is escrowed
  149. tax: 0, // Real Estate taxes monthly payment
  150. taxEscrow: 0, // Months to escrow
  151. taxEscrowed: true, // If tax is escrowed
  152. program: "",
  153. pud: true, // Property under development
  154. zip: ''
  155. }
  156. const loans = [
  157. Object.assign({}, example),
  158. Object.assign(Object.assign({}, example), {title: "Another One"})
  159. ]
  160. const estimate = {
  161. property: "",
  162. transaction: 0,
  163. price: 0,
  164. borrowers: 0,
  165. creditScore: 0,
  166. mIncome: 0,
  167. loans: loans
  168. }
  169. // Clone loan from initial example as a new loan
  170. function create() {
  171. this.estimate.loans.push(Object.assign({}, loans[0]))
  172. }
  173. // Strips non-digits from an input box event and returns it's rounded integer
  174. function strip(e) {
  175. let value = parseInt(e.target.value.replace(/\D/g, '') || 0)
  176. e.target.value = value
  177. return value
  178. }
  179. function stripLetters(e) {
  180. let value = (e.target.value.replace(/[^\w\s]/g, '').slice(0, 20) || '')
  181. e.target.value = value
  182. return value
  183. }
  184. function del() {
  185. if (this.loans.length > 1) {
  186. let x = this.sel
  187. this.sel = 0
  188. this.loans.splice(x, 1)
  189. }
  190. }
  191. // Changes loan.ltv's <input> and data() values, then syncs with data.amount
  192. function setLtv(e) {
  193. let ltv = strip(e)
  194. let loan = this.loans[this.sel]
  195. if (!this.estimate.price) return
  196. if (ltv > 100) ltv = 100
  197. if (ltv < 0) ltv = 0
  198. loan.ltv = ltv
  199. e.target.value = ltv
  200. loan.amount = Math.round(ltv / 100 * this.estimate.price)
  201. }
  202. // Changes loan.amount's <input> and data() values, then syncs with data.ltv
  203. function setAmount(e) {
  204. let amount = strip(e)
  205. let loan = this.loans[this.sel]
  206. if (!this.estimate.price) return
  207. if (amount > loan.price) amount = loan.price
  208. if (amount < 0) amount = 0
  209. loan.amount = amount
  210. e.target.value = amount
  211. loan.ltv = Math.round(amount / this.estimate.price * 100)
  212. }
  213. // Updates the property price for all loans
  214. function setPrice(e) {
  215. let value = strip(e)
  216. this.estimate.price = value
  217. e.target.value = value
  218. }
  219. function setDti(e) {
  220. let dti = strip(e)
  221. let loan = this.loans[this.sel]
  222. if (!loan.price) return
  223. if (dti > 100) dti = 100
  224. if (dti < 0) dti = 0
  225. e.target.value = dti
  226. loan.dti = dti
  227. }
  228. function setHousingDti(e) {
  229. let housingDti = strip(e)
  230. let loan = this.loans[this.sel]
  231. if (!loan.price) return
  232. if (housingDti > 100) housingDti = 100
  233. if (housingDti < 0) housingDti = 0
  234. e.target.value = housingDti
  235. loan.housingDti = housingDti
  236. }
  237. export default {
  238. methods: {
  239. setPrice, setLtv, setAmount, setDti, setHousingDti,
  240. strip, stripLetters, del, create
  241. },
  242. props: ['user'],
  243. data() {
  244. return {
  245. estimate: estimate,
  246. loans: estimate.loans,
  247. sel: 0,
  248. }
  249. }
  250. }
  251. </script>