|
- <template>
- <div class="page">
- <h2>Estimates</h2>
-
- <section class="form inputs">
- <h3>Default Fees</h3>
-
- <div
- v-for="(fee, indx) in fees"
- :key="fee.name + indx" class="fee"
- >
- <label @click="() => edit = fee">
- ${{fee.amount/100}}{{ fee.perc ? ` ${fee.perc}%` : ''}} - {{fee.name}}<br>
- {{fee.type}}
- </label>
- <img width="21" height="21" src="/assets/image/icon/x-red.svg"
- @click="() => remove(fee)">
- </div>
- <button @click="() => edit = {}">New Fee</button>
- </section>
-
- <fee-dialog v-if="edit"
- :heading="'Fee'"
- :initial="edit"
- :price="0"
- @close="() => edit = null"
- @save="newFee"
- />
-
- <section class="inputs estimates">
- <h3>Templates</h3>
-
- <div class="entry" v-for="t in templates" v-if="!template"
- @click="() => template = t" key="t.id">
- <span>
- {{t.estimate.id}} - {{t.estimate.property}} - ${{(t.estimate.price/100).toLocaleString()}}
- </span>
- </div>
-
- <div class="details" v-if="template">
- <label>
- #{{template.estimate.id}} -
-
-
- {{template.estimate.transaction}} -
- {{template.estimate.property}} -
- ${{(template.estimate.price / 100).toLocaleString()}}
- </label>
- <label>Borrowers: {{template.estimate.borrower.num}}</label>
- <label>Credit: {{template.estimate.borrower.credit}}</label>
- <label>Income: {{(template.estimate.borrower.income/100).toLocaleString()}}</label>
-
- <div v-for="l in template.estimate.loans" class="details">
- <h4>{{l.title}}</h4>
- <label>{{l.type.name}}</label>
- <label>Total monthly: ${{format(l.result.totalMonthly)}}</label>
- <label>Cash to close: ${{format(l.result.cashToClose)}}</label>
- </div>
- <button @click="() => download(template.estimate)">Generate PDF</button>
- <button @click="() => deletingt = true">Remove</button>
- <button @click="() => template = null">Cancel</button>
- </div>
- </section>
-
- <section class="inputs estimates">
- <h3>Saved Estimates</h3>
-
- <div class="entry" v-for="e in estimates" v-if="!estimate"
- @click="() => estimate = e" key="e.id">
- <span>
- {{e.id}} - {{e.property}} - ${{(e.price/100).toLocaleString()}}
- </span>
- </div>
-
- <div class="details" v-if="estimate">
- <label>
- #{{estimate.id}} -
- {{estimate.transaction}} -
- {{estimate.property}} -
- ${{(estimate.price / 100).toLocaleString()}}
- </label>
- <label>Borrowers: {{estimate.borrower.num}}</label>
- <label>Credit: {{estimate.borrower.credit}}</label>
- <label>Income: {{(estimate.borrower.income/100).toLocaleString()}}</label>
-
- <div v-for="l in estimate.loans" class="details">
- <h4>{{l.title}}</h4>
- <label>{{l.type.name}}</label>
- <label>Total monthly: ${{format(l.result.totalMonthly)}}</label>
- <label>Cash to close: ${{format(l.result.cashToClose)}}</label>
- </div>
- <button @click="() => download(estimate)">Generate PDF</button>
- <button @click="() => saveTemplate(estimate)">Save As Template</button>
- <button @click="() => deleting = true" :disabled="isTemplate()">Delete</button>
- <button @click="() => estimate = null">Cancel</button>
- </div>
-
- </section>
-
- <DDialog v-if="dlink" @close="() => dlink = ''"
- :fileName="`estimate-${estimate.id}.pdf`" :url="dlink">
- </DDialog>
-
- <Dialog v-if="deleting" @close="() => deleting = false">
- <h3>Are you sure you want to delete this estimate?</h3>
- <button @click="() => del(estimate)">Confirm</button>
- </Dialog>
-
- <Dialog v-if="deletingt" @close="() => deletingt = false">
- <h3>Are you sure you want to delete this template?</h3>
- <button @click="() => delt(template)">Confirm</button>
- </Dialog>
-
-
- </div>
- </template>
-
- <script setup>
- import { ref, computed, onMounted } from 'vue'
- import FeeDialog from "./fee-dialog.vue"
- import DDialog from "./download-dialog.vue"
- import Dialog from "./dialog.vue"
- import { format } from "../helpers.js"
-
- const props = defineProps(['user', 'fees', 'token'])
- const emit = defineEmits(['addFeeTemp', 'removeFeeTemp', 'preview'])
- let edit = ref(null)
- let estimates = ref([])
- let templates = ref([])
- let estimate = ref()
- let template = ref()
- let dlink = ref("")
- let deleting = ref(false)
- let deletingt = ref(false)
-
- function newFee(fee, isDebit) {
- if (!isDebit) {
- fee.amount = -1 * fee.amount || 0
- fee.perc = -1 * fee.perc || 0
- }
-
- fetch(`/api/fee`,
- {method: 'POST',
- body: JSON.stringify(fee),
- headers: {
- "Accept": "application/json",
- "Authorization": `Bearer ${props.token}`,
- },
- }).then(resp => {
- if (resp.ok && resp.status == 200) {
- resp.json().then(r => emit('addFeeTemp', r))
- } else {
- // resp.text().then(t => this.errors = [t])
- // window.location.hash = 'new'
- resp.text().then(t => console.log(t))
- }
- })
- edit.value = null
- }
-
- function newType() {
-
- }
-
- function remove(fee) {
- fetch(`/api/fee`,
- {method: 'DELETE',
- headers: {
- "Accept": "application/json",
- "Authorization": `Bearer ${props.token}`,
- },
- body: JSON.stringify(fee)
- }).then(response => {
- if (response.ok) { emit('removeFeeTemp', fee) } else {
- response.text().then(t => console.log(t))
- }
- })
- }
-
- function getEstimates() {
- fetch(`/api/estimates`,
- {method: 'GET',
- headers: {
- "Accept": "application/json",
- "Authorization": `Bearer ${props.token}`,
- },
- }).then(response => {
- if (response.ok) { return response.json() } else {
- response.text().then(t => console.log(t))
- }
- }).then (result => {
- if (!result || !result.length) return // Exit if token is invalid or no fees are saved
- estimates.value = result
- })
- }
-
- function getTemplates() {
- fetch(`/api/templates`,
- {method: 'GET',
- headers: {
- "Accept": "application/json",
- "Authorization": `Bearer ${props.token}`,
- },
- }).then(response => {
- if (response.ok) { return response.json() } else {
- response.text().then(t => console.log(t))
- }
- }).then (result => {
- if (!result || !result.length) return // Exit if token is invalid or no fees are saved
- templates.value = result
- })
- }
-
- function saveTemplate(e) {
- fetch(`/api/templates`,
- {method: 'POST',
- body: JSON.stringify(e),
- headers: {
- "Accept": "application/json",
- "Authorization": `Bearer ${props.token}`,
- },
- }).then(response => {
- if (response.ok) { getTemplates() }
- })
- }
-
- function del(e) {
- fetch(`/api/estimate`,
- {method: 'DELETE',
- body: JSON.stringify(e),
- headers: {
- "Accept": "application/json",
- "Authorization": `Bearer ${props.token}`,
- },
- }).then(response => {
- if (response.ok) {
- estimates.value = estimates.value.filter(e => e.id != estimate.value.id)
- estimate.value = null
- deleting.value = false
- }
- })
- }
-
- function delt(t) {
- fetch(`/api/templates`,
- {method: 'DELETE',
- body: JSON.stringify(t),
- headers: {
- "Accept": "application/json",
- "Authorization": `Bearer ${props.token}`,
- },
- }).then(response => {
- if (response.ok) {
- templates.value = templates.value.filter(t => t.id != template.value.id)
- template.value = null
- deletingt.value = false
- }
- })
- }
-
- function download(estimate) {
- fetch(`/api/pdf`,
- {method: 'POST',
- body: JSON.stringify(estimate),
- headers: {
- "Accept": "application/json",
- "Authorization": `Bearer ${props.token}`,
- },
- }).then(response => {
- if (response.ok) { return response.blob() }
- }).then (result => {
- if (!result) return // Exit if token is invalid or blank file returned
- dlink.value = URL.createObjectURL(result)
- })
- }
-
- function isTemplate() {
- return templates.value.some( t => t.estimate.id == estimate.value.id )
- }
-
- onMounted(() => {
- getEstimates()
- getTemplates()
- })
- </script>
-
- <style scoped>
- .modal a.button {
- margin: auto;
- margin-top: 30px;
- }
- </style>
|