From d4a5e4cc4dc7df03fb914294eb30156e88bb8fb1 Mon Sep 17 00:00:00 2001
From: Immanuel Onyeka <immanuel@onyeka.ca>
Date: Thu, 7 Sep 2023 13:40:15 -0400
Subject: [PATCH] Remove vue component for PDF generation

Also structure CLI functions to allow for `skouter dev seed` command.
---
 README.md                    |   3 +
 components/app.vue           |   8 --
 components/estimate-test.vue | 137 -----------------------------------
 go.mod                       |   1 +
 go.sum                       |   2 +
 skouter.go                   |  64 ++++++++++++----
 6 files changed, 56 insertions(+), 159 deletions(-)
 delete mode 100644 components/estimate-test.vue

diff --git a/README.md b/README.md
index 5b86e99..16dc3f8 100644
--- a/README.md
+++ b/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'.
diff --git a/components/app.vue b/components/app.vue
index ab3a89d..0213069 100644
--- a/components/app.vue
+++ b/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"
diff --git a/components/estimate-test.vue b/components/estimate-test.vue
deleted file mode 100644
index 0cfe639..0000000
--- a/components/estimate-test.vue
+++ /dev/null
@@ -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>
diff --git a/go.mod b/go.mod
index 352bca1..b110535 100644
--- a/go.mod
+++ b/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
diff --git a/go.sum b/go.sum
index 0cb2a39..bf3e3fe 100644
--- a/go.sum
+++ b/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=
diff --git a/skouter.go b/skouter.go
index 1bf9247..3bcc780 100644
--- a/skouter.go
+++ b/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
+    }
 }