Skouter mortgage estimates. Web application with view written in PHP and Vue, but controller and models in Go.
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

settings.vue 3.7 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <template>
  2. <div class="page settings">
  3. <h2>Settings</h2>
  4. <section class="form inputs">
  5. <h3>Avatar</h3>
  6. <canvas class="displayer" width="200" height="200" ref="avatar"></canvas>
  7. <input type="file"
  8. @change="e => changeAvatar(e.target.files[0])"
  9. />
  10. <button @click="uploadAvatar">Upload</button>
  11. <label class="error">{{avatarError}}</label>
  12. </section>
  13. <section class="form inputs letterhead">
  14. <h3>Letterhead</h3>
  15. <canvas class="displayer" height="200" ref="letterhead"></canvas>
  16. <input type="file"
  17. @change="e => changeLetterhead(e.target.files[0])"
  18. />
  19. <button @click="uploadLetterhead">Upload</button>
  20. <label class="error">{{avatarError}}</label>
  21. </section>
  22. <section class="form inputs special">
  23. <h3>Profile</h3>
  24. <label for="">First Name</label>
  25. <input type="text">
  26. <label for="">Last Name</label>
  27. <input type="text">
  28. <label for="">NMLS ID</label>
  29. <input type="text">
  30. <label for="">Branch ID</label>
  31. <input type="text">
  32. <select id="" name="" >
  33. <option value="usa">USA</option>
  34. <option value="canada">Canada</option>
  35. </select>
  36. <button @click="check">Save</button>
  37. </section>
  38. <section class="form inputs special">
  39. <h3>Login</h3>
  40. <label for="">Email</label>
  41. <input type="text">
  42. <label for="">New Password</label>
  43. <input type="text">
  44. <button @click="check">Save</button>
  45. </section>
  46. <Dialog v-if="ready" @close="() => ready = false">
  47. <h3>Confirm your current password to save changes.</h3>
  48. <input type="text">
  49. <button>Confirm</button>
  50. </Dialog>
  51. </div>
  52. </template>
  53. <script setup>
  54. import { ref, watch, onMounted } from "vue"
  55. import Dialog from "./dialog.vue"
  56. let avatar = ref(null) // the canvas element
  57. let letterhead = ref(null) // the canvas element
  58. let ready = ref(false)
  59. let avatarChanged = ref(false)
  60. let avatarError = ref('')
  61. let letterheadError = ref('')
  62. const props = defineProps(['user', 'token'])
  63. const emit = defineEmits(['updateAvatar', 'updateLetterhead'])
  64. function save() {
  65. }
  66. function check() {
  67. ready.value = true
  68. }
  69. function uploadAvatar() {
  70. avatar.value.toBlob(b => {
  71. fetch(`/api/user/avatar`,
  72. {method: 'POST',
  73. body: b,
  74. headers: {
  75. "Accept": "application/json",
  76. "Authorization": `Bearer ${props.token}`,
  77. },
  78. }).then(resp => {
  79. if (resp.ok) {emit('updateAvatar')}
  80. })
  81. })
  82. }
  83. function uploadLetterhead() {
  84. letterhead.value.toBlob(b => {
  85. fetch(`/api/user/letterhead`,
  86. {method: 'POST',
  87. body: b,
  88. headers: {
  89. "Accept": "application/json",
  90. "Authorization": `Bearer ${props.token}`,
  91. },
  92. }).then(resp => {
  93. if (resp.ok) {emit('updateLetterhead')}
  94. })
  95. })
  96. }
  97. function changeAvatar(blob) {
  98. const validTypes = ['image/jpeg', 'image/png']
  99. if (!validTypes.includes(blob.type)) {
  100. avatarError.value = 'Image must be JPEG of PNG format'
  101. return
  102. }
  103. avatarError.value = ''
  104. createImageBitmap(blob,
  105. {resizeWidth: 200, resizeHeight: 200, resizeQuality: 'medium'}).
  106. then((img) => {
  107. avatar.value.getContext("2d").drawImage(img, 0, 0, 200, 200)
  108. })
  109. }
  110. function changeLetterhead(blob) {
  111. const validTypes = ['image/jpeg', 'image/png']
  112. if (!validTypes.includes(blob.type)) {
  113. letterheadError.value = 'Image must be JPEG of PNG format'
  114. return
  115. }
  116. letterheadError.value = ''
  117. return createImageBitmap(blob,
  118. {resizeWidth: 400, resizeHeight: 200, resizeQuality: 'medium'}).
  119. then((img) => {
  120. letterhead.value.getContext("2d").drawImage(img, 0, 0, 400, 200)
  121. })
  122. }
  123. watch(props.user, (u) => {
  124. if (props.user.avatar) {
  125. changeAvatar(props.user.avatar)
  126. }
  127. if (props.user.letterhead) {
  128. changeLetterhead(props.user.letterhead)
  129. }
  130. }, {immediate: true})
  131. </script>