diff --git a/assets/main.css b/assets/main.css index 021e600..3946fdb 100644 --- a/assets/main.css +++ b/assets/main.css @@ -404,3 +404,7 @@ section.estimates .details { flex-flow: column; gap: 10px; } + +canvas.displayer { + margin: auto; +} diff --git a/components/app.vue b/components/app.vue index 9b8e70d..a09e491 100644 --- a/components/app.vue +++ b/components/app.vue @@ -112,6 +112,13 @@ function getUser() { } this.user.avatar = b + return getLetterhead(token) + }).then (result => { + if (!result || !result.length) return // Exit if token is invalid + this.user = result[0] + if (this.user.letterhead) return + + return getAvatar(token) }) } @@ -126,11 +133,26 @@ function getAvatar(t) { }).then(r => r.blob()) } +function getLetterhead(t) { + return fetch("/api/user/letterhead", + {method: 'GET', + headers: { + "Accept": "application/json", + "Authorization": `Bearer ${t || this.token}`, + } + }).then(r => r.blob()) +} + function updateAvatar() { const token = getCookie("skouter") getAvatar(token).then(b => this.user.avatar = b) } +function updateLetterhead() { + const token = getCookie("skouter") + getAvatar(token).then(b => this.user.letterhead = b) +} + function getFees() { const token = getCookie("skouter") diff --git a/components/settings.vue b/components/settings.vue index b296cdd..e344773 100644 --- a/components/settings.vue +++ b/components/settings.vue @@ -4,7 +4,7 @@

Avatar

- + diff --git a/skouter.go b/skouter.go index 5e6f3e8..441c21a 100644 --- a/skouter.go +++ b/skouter.go @@ -993,6 +993,40 @@ func insertAvatar(db *sql.DB, user int, img []byte) error { return nil } +func fetchLetterhead(db *sql.DB, user int) ( []byte, error ) { + var img []byte + var query string + var err error + + query = `SELECT + letterhead + FROM user WHERE user.id = ? + ` + row := db.QueryRow(query, user) + err = row.Scan(&img) + + if err != nil { + return img, err + } + + return img, nil +} + + +func insertLetterhead(db *sql.DB, user int, img []byte) error { + query := `UPDATE user + SET letterhead = ? + WHERE id = ? + ` + _, err := db.Exec(query, img, user) + if err != nil { + return err + } + + return nil +} + + func setAvatar(w http.ResponseWriter, db *sql.DB, r *http.Request) { var validTypes []string = []string{"image/png", "image/jpeg"} var isValidType bool @@ -1020,6 +1054,33 @@ func getAvatar(w http.ResponseWriter, db *sql.DB, r *http.Request) { w.Write(img) } +func setLetterhead(w http.ResponseWriter, db *sql.DB, r *http.Request) { + var validTypes []string = []string{"image/png", "image/jpeg"} + var isValidType bool + + claims, err := getClaims(r) + if err != nil { http.Error(w, "Invalid token.", 422); return } + img, err := io.ReadAll(r.Body) + if err != nil { http.Error(w, "Invalid file.", 422); return } + for _, v := range validTypes { + if v == http.DetectContentType(img) { isValidType = true } + } + if !isValidType { http.Error(w, "Invalid file type.", 422); return } + + err = insertAvatar(db, claims.Id, img) + if err != nil { http.Error(w, "Could not insert.", 500); return } +} + +func getLetterhead(w http.ResponseWriter, db *sql.DB, r *http.Request) { + claims, err := getClaims(r) + if err != nil { http.Error(w, "Invalid token.", 422); return } + img, err := fetchLetterhead(db, claims.Id) + if err != nil { http.Error(w, "Could not retrieve.", 500); return } + + w.Header().Set("Content-Type", http.DetectContentType(img)) + w.Write(img) +} + func queryBorrower(db *sql.DB, id int) ( Borrower, error ) { var borrower Borrower var query string @@ -1671,6 +1732,14 @@ func api(w http.ResponseWriter, r *http.Request) { r.Method == http.MethodPost && guard(r, 1): setAvatar(w, db, r) + case match(p, "/api/user/letterhead", &args) && + r.Method == http.MethodGet && + guard(r, 1): + getLetterhead(w, db, r) + case match(p, "/api/user/letterhead", &args) && + r.Method == http.MethodPost && + guard(r, 1): + setLetterhead(w, db, r) case match(p, "/api/fees", &args) && r.Method == http.MethodGet && guard(r, 1):