vue-html2pdf appears unmaintained and hacky so it's being avoided.master
@@ -2,7 +2,10 @@ | |||||
<div class="panel"> | <div class="panel"> | ||||
<template v-if="user"> | <template v-if="user"> | ||||
<side-bar v-if="user" :role="user && user.status" :active="active"> | <side-bar v-if="user" | ||||
:role="user && user.status" | |||||
:avatar="user.avatar" | |||||
:active="active"> | |||||
</side-bar> | </side-bar> | ||||
<div v-if="loading" class="page loading"> | <div v-if="loading" class="page loading"> | ||||
@@ -24,6 +27,7 @@ v-else-if="active == 3" | |||||
:token="token" | :token="token" | ||||
@addFeeTemp="(f) => fees.push(f)" | @addFeeTemp="(f) => fees.push(f)" | ||||
@removeFeeTemp="(fee) => fees = fees.filter(f => f.id != fee.id)" | @removeFeeTemp="(fee) => fees = fees.filter(f => f.id != fee.id)" | ||||
@preview="previewEstimate" | |||||
/> | /> | ||||
<settings | <settings | ||||
@@ -32,13 +36,21 @@ v-else-if="active == 3" | |||||
@updateAvatar="updateAvatar" | @updateAvatar="updateAvatar" | ||||
@updateLetterhead="updateLetterhead" | @updateLetterhead="updateLetterhead" | ||||
v-else-if="active == 4" /> | v-else-if="active == 4" /> | ||||
<sign-out :user="user" v-else-if="active == 5" /> | <sign-out :user="user" v-else-if="active == 5" /> | ||||
</template> | </template> | ||||
<template v-if="!user && active == 6"> | <template v-if="!user && active == 6"> | ||||
<login @login="start" /> | <login @login="start" /> | ||||
</template> | </template> | ||||
<estimate-test | |||||
v-else-if="active == 7" | |||||
:token="token" | |||||
:estimate="preview" | |||||
/> | |||||
</div> | </div> | ||||
</template> | </template> | ||||
@@ -48,6 +60,7 @@ import Spinner from "./spinner.vue" | |||||
import Home from "./home.vue" | import Home from "./home.vue" | ||||
import NewEstimate from "./new/new.vue" | import NewEstimate from "./new/new.vue" | ||||
import Estimates from "./estimates.vue" | import Estimates from "./estimates.vue" | ||||
import EstimateTest from "./estimate-test.vue" | |||||
import Settings from "./settings.vue" | import Settings from "./settings.vue" | ||||
import SignOut from "./sign-out.vue" | import SignOut from "./sign-out.vue" | ||||
import Login from "./login.vue" | import Login from "./login.vue" | ||||
@@ -191,6 +204,8 @@ function active() { | |||||
return 5 | return 5 | ||||
} else if (/^#login\/?/.exec(this.hash)) { | } else if (/^#login\/?/.exec(this.hash)) { | ||||
return 6 | return 6 | ||||
} else if (/^#estimate\/?/.exec(this.hash)) { | |||||
return 7 | |||||
} else { | } else { | ||||
return 0 | return 0 | ||||
} | } | ||||
@@ -218,12 +233,18 @@ function start() { | |||||
} | } | ||||
function previewEstimate(estimate) { | |||||
this.preview = estimate | |||||
window.location.hash = 'estimate' | |||||
} | |||||
export default { | export default { | ||||
components: { | components: { | ||||
SideBar, | SideBar, | ||||
Spinner, | Spinner, | ||||
Home, | Home, | ||||
NewEstimate, | NewEstimate, | ||||
EstimateTest, | |||||
Estimates, | Estimates, | ||||
Settings, | Settings, | ||||
SignOut, | SignOut, | ||||
@@ -240,6 +261,7 @@ export default { | |||||
getAvatar, | getAvatar, | ||||
updateLetterhead, | updateLetterhead, | ||||
getLetterhead, | getLetterhead, | ||||
previewEstimate, | |||||
}, | }, | ||||
data() { | data() { | ||||
return { | return { | ||||
@@ -249,6 +271,7 @@ export default { | |||||
fees: [], | fees: [], | ||||
loadingError: "", | loadingError: "", | ||||
token: '', | token: '', | ||||
preview: null, | |||||
} | } | ||||
}, | }, | ||||
created() { | created() { | ||||
@@ -0,0 +1,21 @@ | |||||
<template> | |||||
<div ref="doc" v-if="estimate">{{estimate}} | |||||
<button @click="makePDF">Generate</button> | |||||
</div> | |||||
</template> | |||||
<script setup> | |||||
import { ref } from "vue" | |||||
import html2pdf from "html2pdf.js"; | |||||
const doc = ref(null) | |||||
const props = defineProps(['token', 'estimate']) | |||||
function makePDF() { | |||||
html2pdf(doc.value) | |||||
} | |||||
</script> | |||||
<style> | |||||
</style> |
@@ -27,8 +27,6 @@ | |||||
@save="newFee" | @save="newFee" | ||||
/> | /> | ||||
<section class="inputs estimates"> | <section class="inputs estimates"> | ||||
<h3>Saved Estimates</h3> | <h3>Saved Estimates</h3> | ||||
@@ -56,7 +54,7 @@ ${{(estimate.price / 100).toLocaleString()}} | |||||
<label>Total monthly: ${{format(estimate.results[i].totalMonthly)}}</label> | <label>Total monthly: ${{format(estimate.results[i].totalMonthly)}}</label> | ||||
<label>Cash to close: ${{format(estimate.results[i].cashToClose)}}</label> | <label>Cash to close: ${{format(estimate.results[i].cashToClose)}}</label> | ||||
</div> | </div> | ||||
<button @click="() => $emit('preview', estimate)">Preview</button> | |||||
<button @click="() => estimate = null">Cancel</button> | <button @click="() => estimate = null">Cancel</button> | ||||
</div> | </div> | ||||
@@ -71,7 +69,7 @@ import FeeDialog from "./fee-dialog.vue" | |||||
import { format } from "../helpers.js" | import { format } from "../helpers.js" | ||||
const props = defineProps(['user', 'fees', 'token']) | const props = defineProps(['user', 'fees', 'token']) | ||||
const emit = defineEmits(['addFeeTemp', 'removeFeeTemp']) | const emit = defineEmits(['addFeeTemp', 'removeFeeTemp', 'preview']) | ||||
let edit = ref(null) | let edit = ref(null) | ||||
let estimates = ref([]) | let estimates = ref([]) | ||||
let estimate = ref() | let estimate = ref() | ||||
@@ -20,8 +20,8 @@ fill-rule="evenodd" d="M2 12.5a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 | |||||
0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 | 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5zm0-3a.5.5 0 0 1 .5-.5h11a.5.5 0 | ||||
0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/> </svg> | 0 1 0 1h-11a.5.5 0 0 1-.5-.5z"/> </svg> | ||||
<img | <img v-if="avatar" | ||||
src="/assets/image/mintberry.jpg"> | :src="avatarUrl"> | ||||
<a href="#" :class="active == 1 ? 'active' : ''"> | <a href="#" :class="active == 1 ? 'active' : ''"> | ||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" | <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" | ||||
@@ -96,11 +96,15 @@ fill="currentColor" class="bi bi-door-closed" viewBox="0 0 16 16"> <path d="M3 | |||||
</template> | </template> | ||||
<script setup> | <script setup> | ||||
import { ref, onMounted } from "vue" | import { ref, onMounted, computed } from "vue" | ||||
const props = defineProps(['role', 'active']) | const props = defineProps(['role', 'active', 'avatar']) | ||||
const mobile = ref(false) | const mobile = ref(false) | ||||
const toggled = ref(false) | const toggled = ref(false) | ||||
let avatarUrl = computed(() => { | |||||
return URL.createObjectURL(props.avatar) | |||||
}) | |||||
function checkMobile() { | function checkMobile() { | ||||
if (window.innerWidth < 720) { | if (window.innerWidth < 720) { | ||||
mobile.value = true | mobile.value = true | ||||
@@ -3,8 +3,8 @@ | |||||
"watch": "webpack --mode development --watch" | "watch": "webpack --mode development --watch" | ||||
}, | }, | ||||
"dependencies": { | "dependencies": { | ||||
"vue": "^3.2.41", | "html2pdf": "^0.0.11", | ||||
"vue-html2pdf": "^1.8.0" | "vue": "^3.2.41" | ||||
}, | }, | ||||
"devDependencies": { | "devDependencies": { | ||||
"css-loader": "^6.7.1", | "css-loader": "^6.7.1", | ||||