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.
 
 
 
 
 
 

127 lines
2.8 KiB

  1. <template>
  2. <form>
  3. <div>
  4. <label>Given name</label>
  5. <input required type="text" name="gname" v-model="user.firstName"/>
  6. </div>
  7. <div>
  8. <label>Surname</label>
  9. <input required type="text" name="sname" v-model="user.lastName"/>
  10. </div>
  11. <div>
  12. <label>Email</label>
  13. <input type="email" name="email" v-model="user.email"/>
  14. </div>
  15. <div>
  16. <label>Password</label>
  17. <input requried type="password" name="pass" v-model="user.pass"/>
  18. </div>
  19. <div>
  20. <label>Country</label>
  21. <select name="country" v-model="user.country">
  22. <option value="USA">USA</option>
  23. <option value="Canada">Canada</option>
  24. </select>
  25. </div>
  26. <div class="address-entry">
  27. <label for="">Address</label>
  28. <input
  29. type="text" @input="searchLocation" v-model="address.full">
  30. <dropdown v-if="addresses && addresses.length"
  31. :entries="addresses.map(a => ({text: a.full_address, value: a}))"
  32. @select="setAddress"
  33. >
  34. </dropdown>
  35. </div>
  36. <div><label>NMLS ID</label><input type="text" name="nmls"/></div>
  37. <div><span class="error">{{error}}</span></div>
  38. <div>
  39. <button class="btn" @click="submit" type="button">Continue</button>
  40. </div>
  41. </form>
  42. </template>
  43. <script setup>
  44. import { ref } from "vue"
  45. import Dropdown from "./dropdown.vue"
  46. const addresses = ref([])
  47. const user = ref({})
  48. const address = ref({})
  49. const locationsId = ref(null)
  50. const props = defineProps(['error'])
  51. const emit = defineEmits(['submit'])
  52. function searchLocation(e) {
  53. address.value.full = e.target.value
  54. clearTimeout(locationsId.value)
  55. locationsId.value = setTimeout(getLocations, 1000, e)
  56. }
  57. function getLocations(e) {
  58. let prefix = "https://api.mapbox.com/search/searchbox/v1/suggest?"
  59. let search = e.target.value
  60. let key = encodeURIComponent(process.env.MAPBOX_API_KEY)
  61. if (!search) return
  62. fetch(`${prefix}q=${search}&proximity=ip&access_token=${key}&session_token=1`
  63. ).then(resp => resp.json()).then(entries => {
  64. if (!entries?.suggestions) {
  65. addresses.value = null
  66. return
  67. }
  68. addresses.value = entries.suggestions.filter(e => e.full_address)
  69. })
  70. }
  71. function setAddress(a) {
  72. address.value = {
  73. id: address.value.id,
  74. full: a.full_address,
  75. street: a.address,
  76. city: a.context?.place.name ?? '',
  77. region: a.context?.region?.name ?? '',
  78. country: a.context?.country?.name ?? '',
  79. zip: a.context?.postcode?.name ?? '',
  80. }
  81. addresses.value = null
  82. }
  83. function submit() {
  84. user.value.address = address.value
  85. emit('submit', user.value)
  86. }
  87. </script>
  88. <style scoped>
  89. form > div {
  90. display: flex;
  91. justify-content: space-between;
  92. margin: 10px;
  93. position: relative;
  94. }
  95. button {
  96. margin: auto;
  97. min-width: 90px;
  98. display: block;
  99. }
  100. span.error {
  101. margin: 10px auto;
  102. color: darkred;
  103. }
  104. </style>