Skouter mortgage estimates. Web application with view written in PHP and Vue, but controller and models in Go.
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 
 
 
 

138 satır
2.8 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: 'POST',
  66. body: JSON.stringify(estimate.value),
  67. headers: {
  68. "Accept": "application/json",
  69. "Authorization": `Bearer ${props.token}`,
  70. },
  71. }).then(response => {
  72. if (response.ok) { return response.blob() }
  73. else {
  74. return null
  75. }
  76. }).then (result => {
  77. if (!result) return
  78. pdfLink.value = URL.createObjectURL(result)
  79. })
  80. }
  81. onMounted(() => {
  82. getEstimates().then(() => estimate.value = estimates.value[0])
  83. })
  84. </script>
  85. <style scoped>
  86. #pdf-doc {
  87. margin: 4px 30px;
  88. }
  89. .disclaimer {
  90. font-weight: bold;
  91. border-bottom: 1px solid lightgrey;
  92. margin-bottom: 20px;
  93. color: var(--text);
  94. }
  95. .disclaimer p {
  96. margin: 5px 0;
  97. }
  98. h4 {
  99. margin: 4px 0;
  100. }
  101. header.heading {
  102. display: flex;
  103. justify-content: space-between;
  104. }
  105. .user-info {
  106. display: flex;
  107. flex-flow: column;
  108. }
  109. #pdf-doc header.heading > div {
  110. display: flex;
  111. gap: 8px;
  112. text-align: right;
  113. }
  114. </style>