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.
 
 
 
 
 
 

137 lines
2.7 KiB

  1. <template>
  2. <div id="pdf-doc" ref="doc" v-if="estimate">
  3. <div class="disclaimer"><p>Actual costs may vary from estimates after approval. Get an official quote before choosing a loan.</p></div>
  4. <header class="heading">
  5. <img :src="letterhead" />
  6. <div>
  7. <div class="user-info">
  8. <h4>{{user.firstName + " " + user.lastName}}</h4>
  9. <span>{{user.email}}</span>
  10. <span>{{user.phone}}</span>
  11. <small>{{user.address.street}}</small>
  12. <small>
  13. {{`${user.address.city}, ${user.address.region} ${user.address.zip}`}}
  14. </small>
  15. </div>
  16. <img :src="avatar"/>
  17. </div>
  18. </header>
  19. <button @click="getPdf">Generate</button>
  20. <a :href="pdfLink" v-if="pdfLink" download="estimate.pdf">download </a>
  21. </div>
  22. </template>
  23. <script setup>
  24. import { ref, computed, onMounted } from "vue"
  25. import html2pdf from "html2pdf.js";
  26. const doc = ref(null)
  27. const props = defineProps(['token', 'estimate', 'user'])
  28. const estimate = ref(null)
  29. const estimates = ref(null)
  30. const pdfLink = ref('')
  31. const letterhead = computed(() => {
  32. if (!props.user.letterhead) return null
  33. return URL.createObjectURL(props.user.letterhead)
  34. })
  35. const avatar = computed(() => {
  36. if (!props.user.letterhead) return null
  37. console.log(props.user)
  38. return URL.createObjectURL(props.user.avatar)
  39. })
  40. function makePDF() {
  41. var opt = {
  42. image: { type: 'png', quality: 1 },
  43. }
  44. html2pdf(doc.value, opt)
  45. }
  46. function getEstimates() {
  47. return fetch(`/api/estimates`,
  48. {method: 'GET',
  49. headers: {
  50. "Accept": "application/json",
  51. "Authorization": `Bearer ${props.token}`,
  52. },
  53. }).then(response => {
  54. if (response.ok) { return response.json() } else {
  55. response.text().then(t => console.log(t))
  56. }
  57. }).then (result => {
  58. if (!result || !result.length) return // Exit if token is invalid or no fees are saved
  59. estimates.value = result
  60. // console.log(result)
  61. })
  62. }
  63. function getPdf() {
  64. fetch(`/api/pdf`,
  65. {method: 'GET',
  66. headers: {
  67. "Accept": "application/json",
  68. "Authorization": `Bearer ${props.token}`,
  69. },
  70. }).then(response => {
  71. if (response.ok) { return response.blob() }
  72. else {
  73. return null
  74. }
  75. }).then (result => {
  76. if (!result) return
  77. pdfLink.value = URL.createObjectURL(result)
  78. })
  79. }
  80. onMounted(() => {
  81. getEstimates().then(() => estimate.value = estimates.value[0])
  82. })
  83. </script>
  84. <style scoped>
  85. #pdf-doc {
  86. margin: 4px 30px;
  87. }
  88. .disclaimer {
  89. font-weight: bold;
  90. border-bottom: 1px solid lightgrey;
  91. margin-bottom: 20px;
  92. color: var(--text);
  93. }
  94. .disclaimer p {
  95. margin: 5px 0;
  96. }
  97. h4 {
  98. margin: 4px 0;
  99. }
  100. header.heading {
  101. display: flex;
  102. justify-content: space-between;
  103. }
  104. .user-info {
  105. display: flex;
  106. flex-flow: column;
  107. }
  108. #pdf-doc header.heading > div {
  109. display: flex;
  110. gap: 8px;
  111. text-align: right;
  112. }
  113. </style>