Преглед на файлове

Remove vue component for PDF generation

Also structure CLI functions to allow for `skouter dev seed` command.
master
Immanuel Onyeka преди 1 година
родител
ревизия
d4a5e4cc4d
променени са 6 файла, в които са добавени 56 реда и са изтрити 159 реда
  1. +3
    -0
      README.md
  2. +0
    -8
      components/app.vue
  3. +0
    -137
      components/estimate-test.vue
  4. +1
    -0
      go.mod
  5. +2
    -0
      go.sum
  6. +50
    -14
      skouter.go

+ 3
- 0
README.md Целия файл

@@ -8,3 +8,6 @@ DBPass
Uses ESbuild and the Vue node package.
`sudo apt install esbuild; npm install vue;`
``

### Starting Server
It reads database info from environment variables, unless called as `skouter dev`. Dev mode uses default datbase credentials for user 'tester'.

+ 0
- 8
components/app.vue Целия файл

@@ -45,13 +45,6 @@ v-else-if="active == 4" />
<login @login="start" />
</template>

<estimate-test
v-else-if="active == 7"
:token="token"
:estimate="preview"
:user="user"
/>

</div>
</template>

@@ -61,7 +54,6 @@ import Spinner from "./spinner.vue"
import Home from "./home.vue"
import NewEstimate from "./new/new.vue"
import Estimates from "./estimates.vue"
import EstimateTest from "./estimate-test.vue"
import Settings from "./settings.vue"
import SignOut from "./sign-out.vue"
import Login from "./login.vue"


+ 0
- 137
components/estimate-test.vue Целия файл

@@ -1,137 +0,0 @@
<template>
<div id="pdf-doc" ref="doc" v-if="estimate">
<div class="disclaimer"><p>Actual costs may vary from estimates after approval. Get an official quote before choosing a loan.</p></div>

<header class="heading">

<img :src="letterhead" />

<div>

<div class="user-info">
<h4>{{user.firstName + " " + user.lastName}}</h4>
<span>{{user.email}}</span>
<span>{{user.phone}}</span>
<small>{{user.address.street}}</small>
<small>
{{`${user.address.city}, ${user.address.region} ${user.address.zip}`}}
</small>
</div>
<img :src="avatar"/>
</div>

</header>

<button @click="getPdf">Generate</button>
<a :href="pdfLink" v-if="pdfLink" download="estimate.pdf">download </a>
</div>
</template>

<script setup>
import { ref, computed, onMounted } from "vue"
import html2pdf from "html2pdf.js";

const doc = ref(null)
const props = defineProps(['token', 'estimate', 'user'])
const estimate = ref(null)
const estimates = ref(null)
const pdfLink = ref('')

const letterhead = computed(() => {
if (!props.user.letterhead) return null
return URL.createObjectURL(props.user.letterhead)
})

const avatar = computed(() => {
if (!props.user.letterhead) return null
console.log(props.user)
return URL.createObjectURL(props.user.avatar)
})

function makePDF() {
var opt = {
image: { type: 'png', quality: 1 },
}

html2pdf(doc.value, opt)
}


function getEstimates() {
return 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
// console.log(result)
})
}

function getPdf() {
fetch(`/api/pdf`,
{method: 'POST',
body: JSON.stringify(estimate.value),
headers: {
"Accept": "application/json",
"Authorization": `Bearer ${props.token}`,
},
}).then(response => {
if (response.ok) { return response.blob() }
else {
return null
}
}).then (result => {
if (!result) return
pdfLink.value = URL.createObjectURL(result)
})
}

onMounted(() => {
getEstimates().then(() => estimate.value = estimates.value[0])
})
</script>

<style scoped>
#pdf-doc {
margin: 4px 30px;
}

.disclaimer {
font-weight: bold;
border-bottom: 1px solid lightgrey;
margin-bottom: 20px;
color: var(--text);
}

.disclaimer p {
margin: 5px 0;
}

h4 {
margin: 4px 0;
}

header.heading {
display: flex;
justify-content: space-between;
}

.user-info {
display: flex;
flex-flow: column;
}

#pdf-doc header.heading > div {
display: flex;
gap: 8px;
text-align: right;
}
</style>

+ 1
- 0
go.mod Целия файл

@@ -4,6 +4,7 @@ go 1.19

require (
github.com/SebastiaanKlippert/go-wkhtmltopdf v1.9.0
github.com/brianvoe/gofakeit/v6 v6.23.2
github.com/disintegration/gift v1.2.1
github.com/go-sql-driver/mysql v1.6.0
github.com/golang-jwt/jwt/v4 v4.5.0


+ 2
- 0
go.sum Целия файл

@@ -1,5 +1,7 @@
github.com/SebastiaanKlippert/go-wkhtmltopdf v1.9.0 h1:DNrExYwvyyI404SxdUCCANAj9TwnGjRfa3cYFMNY1AU=
github.com/SebastiaanKlippert/go-wkhtmltopdf v1.9.0/go.mod h1:SQq4xfIdvf6WYKSDxAJc+xOJdolt+/bc1jnQKMtPMvQ=
github.com/brianvoe/gofakeit/v6 v6.23.2 h1:lVde18uhad5wII/f5RMVFLtdQNE0HaGFuBUXmYKk8i8=
github.com/brianvoe/gofakeit/v6 v6.23.2/go.mod h1:Ow6qC71xtwm79anlwKRlWZW6zVq9D2XHE4QSSMP/rU8=
github.com/disintegration/gift v1.2.1 h1:Y005a1X4Z7Uc+0gLpSAsKhWi4qLtsdEcMIbbdvdZ6pc=
github.com/disintegration/gift v1.2.1/go.mod h1:Jh2i7f7Q2BM7Ezno3PhfezbR1xpUg9dUg3/RlKGr4HI=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=


+ 50
- 14
skouter.go Целия файл

@@ -24,6 +24,7 @@ import (
// pdf "github.com/SebastiaanKlippert/go-wkhtmltopdf"
"github.com/golang-jwt/jwt/v4"
"github.com/disintegration/gift"
"github.com/brianvoe/gofakeit/v6"
"image"
"image/png"
_ "image/jpeg"
@@ -195,7 +196,7 @@ var paths = map[string]string {
var pages = map[string]Page {
"home": cache("home", "Home"),
"terms": cache("terms", "Terms and Conditions"),
"test": cachePdf("comparison"),
"report": cachePdf("comparison"),
"app": cache("app", "App"),
}

@@ -1846,10 +1847,7 @@ func validateEstimate(w http.ResponseWriter, db *sql.DB, r *http.Request) {
if err != nil { http.Error(w, err.Error(), 406); return }
}

func showPDF(w http.ResponseWriter, r *http.Request) {
// var args []string

// p := r.URL.Path
func checkPdf(w http.ResponseWriter, r *http.Request) {
db, err := sql.Open("mysql",
fmt.Sprintf("%s:%s@tcp(127.0.0.1:3306)/skouter_dev",
os.Getenv("DBUser"),
@@ -1863,8 +1861,6 @@ func showPDF(w http.ResponseWriter, r *http.Request) {
// maybe os.Exit(1) instead
}
page := cachePdf("comparison")
estimates, err := getEstimates(db, 1, 0)
if err != nil { w.WriteHeader(500); return }
@@ -1894,7 +1890,7 @@ func showPDF(w http.ResponseWriter, r *http.Request) {
}
}
err = page.tpl.ExecuteTemplate(w, "master.tpl", info)
err = pages["report"].tpl.ExecuteTemplate(w, "master.tpl", info)
if err != nil {fmt.Println(err)}

}
@@ -1944,7 +1940,7 @@ func getPdf(w http.ResponseWriter, db *sql.DB, r *http.Request) {
base64.StdEncoding.EncodeToString(letterhead)
err = pages["test"].tpl.ExecuteTemplate(stdin, "master.tpl", info)
err = pages["report"].tpl.ExecuteTemplate(stdin, "master.tpl", info)
if err != nil {
w.WriteHeader(500);
log.Println(err)
@@ -1961,7 +1957,6 @@ func getPdf(w http.ResponseWriter, db *sql.DB, r *http.Request) {
}
if err := cmd.Wait(); err != nil {
// w.WriteHeader(500)
log.Println(err)
return
}
@@ -2117,7 +2112,7 @@ func route(w http.ResponseWriter, r *http.Request) {
case match(p, "/app", &args):
page = pages[ "app" ]
case match(p, "/test", &args):
showPDF(w, r)
checkPdf(w, r)
return
default:
http.NotFound(w, r)
@@ -2136,21 +2131,62 @@ func serve() {
log.Fatal(http.ListenAndServe(address, nil))
}

func dbSeed() {
db, err := sql.Open("mysql",
fmt.Sprintf("%s:%s@tcp(127.0.0.1:3306)/%s",
os.Getenv("DBUser"),
os.Getenv("DBPass"),
os.Getenv("DBName"),
))

err = db.Ping()
if err != nil {
fmt.Println("Bad database configuration: %v\n", err)
panic(err)
// maybe os.Exit(1) instead
}
}

func dev(args []string) {
if len(args) == 0 {
os.Setenv("DBName", "skouter_dev")
os.Setenv("DBUser", "tester")
os.Setenv("DBPass", "test123")
serve()
return
}
switch args[0] {
case "seed":
dbSeed()
default:
return
}
}

func check(args []string) {
os.Setenv("DBName", "skouter_dev")
os.Setenv("DBUser", "tester")
os.Setenv("DBPass", "test123")
files := http.FileServer(http.Dir(""))

http.Handle("/assets/", files)
http.HandleFunc("/", checkPdf)
log.Fatal(http.ListenAndServe(address, nil))
}

func main() {
if len(os.Args) <= 1 {
serve()
return
}
if os.Args[1] == "dev" {

switch os.Args[1] {
case "dev":
dev(os.Args[2:])
}
case "check":
check(os.Args[2:])
default:
return
}
}

Loading…
Отказ
Запис