From 9610ddf7319a56e2651324aca82f440048eb1033 Mon Sep 17 00:00:00 2001 From: Nickiel12 Date: Tue, 27 Feb 2024 18:38:00 -0800 Subject: [PATCH] ran gofmt --- api.go | 2 +- db/db.go | 103 +++++++------- recount-server.go | 4 +- tests/testdb.go | 23 ++-- types/types.go | 24 ++-- web/rendering.go | 85 ++++++------ web/router.go | 165 +++++++++++------------ web/static/index.js | 2 + web/static/new_transactions.js | 45 ++++++- web/templates/new_transaction_pane.templ | 6 +- 10 files changed, 246 insertions(+), 213 deletions(-) diff --git a/api.go b/api.go index 2b97769..c51b370 100644 --- a/api.go +++ b/api.go @@ -41,7 +41,7 @@ func getTransactions(w http.ResponseWriter, req *http.Request) { transactions := []types.Transaction{} - err := db.GetTransactions(&transactions, input.ResultCount, input.PageNum); + err := db.GetTransactions(&transactions, input.ResultCount, input.PageNum) if err != nil { diff --git a/db/db.go b/db/db.go index d9de3b9..dfd22c6 100644 --- a/db/db.go +++ b/db/db.go @@ -1,8 +1,8 @@ package db import ( + "database/sql" "fmt" - "database/sql" "github.com/jmoiron/sqlx" _ "github.com/lib/pq" @@ -11,14 +11,14 @@ import ( "nickiel.net/recount_server/types" ) -var DB_TYPE string; -var DB_SCHEMA string; -var DB_CONNECTION_STRING string; +var DB_TYPE string +var DB_SCHEMA string +var DB_CONNECTION_STRING string func SetConstants(db_type string, db_schema string, db_conn_string string) { - DB_TYPE = db_type; - DB_SCHEMA = db_schema; - DB_CONNECTION_STRING = db_conn_string; + DB_TYPE = db_type + DB_SCHEMA = db_schema + DB_CONNECTION_STRING = db_conn_string } func GetTransactions(transactions *[]types.Transaction, resultCount int, pageNum int) error { @@ -69,62 +69,61 @@ func NewTransaction(transaction types.Transaction) error { } func GetUserAccounts(userID int) ([]types.Account, error) { - user_accounts := make([]types.Account, 4); + user_accounts := make([]types.Account, 4) - user_accounts[0] = types.Account { - Id: 1, - DisplayName: sql.NullString { - String: "Savings", - Valid: true, - } , - Description: sql.NullString { - String: "BECU Saving Account", - Valid: true, - }, - }; - user_accounts[1] = types.Account { - Id: 2, - DisplayName: sql.NullString { - String: "BECU Credit Card", - Valid: true, - } , - Description: sql.NullString { - String: "BECU Saving Account", - Valid: true, - }, - }; + user_accounts[0] = types.Account{ + Id: 1, + DisplayName: sql.NullString{ + String: "Savings", + Valid: true, + }, + Description: sql.NullString{ + String: "BECU Saving Account", + Valid: true, + }, + } + user_accounts[1] = types.Account{ + Id: 2, + DisplayName: sql.NullString{ + String: "BECU Credit Card", + Valid: true, + }, + Description: sql.NullString{ + String: "BECU Saving Account", + Valid: true, + }, + } - return user_accounts, nil; + return user_accounts, nil } func GetUserBuckets(userID int) ([]types.Bucket, error) { - bucket1 := types.Bucket{ - Id: 1, - DisplayCode: sql.NullString{String: "SVNG", Valid: true}, - DisplayName: sql.NullString{String: "Savings", Valid: true}, - Description: sql.NullString{String: "The Savings Bucket", Valid: true}, - } + bucket1 := types.Bucket{ + Id: 1, + DisplayCode: sql.NullString{String: "SVNG", Valid: true}, + DisplayName: sql.NullString{String: "Savings", Valid: true}, + Description: sql.NullString{String: "The Savings Bucket", Valid: true}, + } - bucket2 := types.Bucket{ - Id: 2, - DisplayCode: sql.NullString{String: "SPND", Valid: true}, - DisplayName: sql.NullString{String: "Spending", Valid: true}, - Description: sql.NullString{String: "The Spending Bucket", Valid: true}, - } + bucket2 := types.Bucket{ + Id: 2, + DisplayCode: sql.NullString{String: "SPND", Valid: true}, + DisplayName: sql.NullString{String: "Spending", Valid: true}, + Description: sql.NullString{String: "The Spending Bucket", Valid: true}, + } - // Creating a slice of length two and populating it with the two structs - buckets := []types.Bucket{bucket1, bucket2} + // Creating a slice of length two and populating it with the two structs + buckets := []types.Bucket{bucket1, bucket2} - return buckets, nil; + return buckets, nil } func GetTransPaneEntries(userID int) ([]types.QuickTransactionType, error) { - transaction_types := make([]types.QuickTransactionType, 1); + transaction_types := make([]types.QuickTransactionType, 1) - transaction_types[0] = types.QuickTransactionType { - DisplayName: "Manual", - }; + transaction_types[0] = types.QuickTransactionType{ + DisplayName: "Manual", + } - return transaction_types, nil; + return transaction_types, nil } - diff --git a/recount-server.go b/recount-server.go index 64e9155..3ab76a3 100644 --- a/recount-server.go +++ b/recount-server.go @@ -1,8 +1,8 @@ package main import ( + "nickiel.net/recount_server/db" "nickiel.net/recount_server/tests" - "nickiel.net/recount_server/db" "nickiel.net/recount_server/web" "net/http" @@ -60,7 +60,7 @@ func main() { debug_mode.Init_testdb(DB_TYPE, DB_CONNECTION_STRING) } - db.SetConstants(DB_TYPE, DB_SCHEMA, DB_CONNECTION_STRING); + db.SetConstants(DB_TYPE, DB_SCHEMA, DB_CONNECTION_STRING) debug_mode.SetLogLevel(zerolog.GlobalLevel()) diff --git a/tests/testdb.go b/tests/testdb.go index 883a4d4..60eadab 100644 --- a/tests/testdb.go +++ b/tests/testdb.go @@ -1,8 +1,8 @@ package debug_mode import ( - "nickiel.net/recount_server/types" "encoding/json" + "nickiel.net/recount_server/types" "os" "github.com/jmoiron/sqlx" @@ -11,32 +11,31 @@ import ( "github.com/rs/zerolog/log" ) - func SetLogLevel(level zerolog.Level) { zerolog.SetGlobalLevel(level) } func Init_testdb(DB_TYPE string, DB_CONNECTION_STRING string) { - cwd, err := os.Getwd(); + cwd, err := os.Getwd() if err != nil { log.Fatal().Err(err).Msg("Could not get current working directory") } else { - cwd = cwd + "/"; + cwd = cwd + "/" log.Trace().Msgf("Currect working directory is: %s", cwd) } - _, err = os.Stat(cwd + DB_CONNECTION_STRING) + _, err = os.Stat(cwd + DB_CONNECTION_STRING) if err != nil { log.Debug().Msg("No existing test.db file found") } else { - log.Debug().Msg("Found existing test.db file. Attempting to delete") - err = os.Remove(cwd + DB_CONNECTION_STRING) - if err != nil { - log.Warn().Err(err).Msg("Failed to delete testing db. Continueing anyways") - } else { - log.Debug().Msg("Deleted test.db file successfully") - } + log.Debug().Msg("Found existing test.db file. Attempting to delete") + err = os.Remove(cwd + DB_CONNECTION_STRING) + if err != nil { + log.Warn().Err(err).Msg("Failed to delete testing db. Continueing anyways") + } else { + log.Debug().Msg("Deleted test.db file successfully") + } } db, err := sqlx.Connect(DB_TYPE, DB_CONNECTION_STRING) diff --git a/types/types.go b/types/types.go index 51584e9..0455c69 100644 --- a/types/types.go +++ b/types/types.go @@ -3,7 +3,7 @@ package types import ( "database/sql" - "time" + "time" ) type Transaction struct { @@ -22,33 +22,33 @@ type Account struct { } type Bucket struct { - Id int `db:"bkt_id" json:"id"` - DisplayCode sql.NullString `db:"bkt_display_code" json:"DisplayCode"` - DisplayName sql.NullString `db:"bkt_display_name" json:"DisplayName"` - Description sql.NullString `db:"bkt_description" json:"Description"` + Id int `db:"bkt_id" json:"id"` + DisplayCode sql.NullString `db:"bkt_display_code" json:"DisplayCode"` + DisplayName sql.NullString `db:"bkt_display_name" json:"DisplayName"` + Description sql.NullString `db:"bkt_description" json:"Description"` } type HumanLegibleTransaction struct { Id int `db:"trns_id" json:"Id"` Amount string `db:"trns_amount" json:"Amount"` Description sql.NullString `db:"trns_description" json:"Description"` - AccountName sql.NullString `db:"account_name" json:"AccountName"` + AccountName sql.NullString `db:"account_name" json:"AccountName"` Account int `db:"trns_account" json:"Account"` Bucket sql.NullInt64 `db:"trns_bucket" json:"Bucket"` - BucketName sql.NullString `db:"bucket_name" json:"BucketName"` + BucketName sql.NullString `db:"bucket_name" json:"BucketName"` Date time.Time `db:"trns_date" json:"TransactionDate"` } type QuickTransactionType struct { - DisplayName string + DisplayName string } type ChartjsData struct { - Labels []string `json:"labels"` - Data []int `json:"data"` + Labels []string `json:"labels"` + Data []int `json:"data"` } type TwoIntsItem struct { - Item1 int - Item2 int + Item1 int + Item2 int } diff --git a/web/rendering.go b/web/rendering.go index c9ae6dd..9d7bcc4 100644 --- a/web/rendering.go +++ b/web/rendering.go @@ -1,7 +1,7 @@ package web import ( - "nickiel.net/recount_server/web/templates" + "nickiel.net/recount_server/web/templates" "context" "database/sql" @@ -15,11 +15,10 @@ import ( "nickiel.net/recount_server/types" ) - -const DEFAULT_RESULT_COUNT = 20; +const DEFAULT_RESULT_COUNT = 20 func GetTransactionsRows(w http.ResponseWriter, req *http.Request) { - transactions := make([]types.HumanLegibleTransaction, 10) + transactions := make([]types.HumanLegibleTransaction, 10) // Populate the slice with dummy data (you can replace this with your actual data) for i := 10; i > 0; i-- { @@ -34,15 +33,15 @@ func GetTransactionsRows(w http.ResponseWriter, req *http.Request) { Date: time.Now(), } - transactions[10 - i] = transaction + transactions[10-i] = transaction } - component := templates.TransactionRows(&transactions); - component.Render(context.Background(), w); + component := templates.TransactionRows(&transactions) + component.Render(context.Background(), w) } func GetTransactionQuickAccessEntries(w http.ResponseWriter, req *http.Request) { - transactions := make([]types.HumanLegibleTransaction, 20) + transactions := make([]types.HumanLegibleTransaction, 20) // Populate the slice with dummy data (you can replace this with your actual data) for i := 0; i < 20; i++ { @@ -59,50 +58,50 @@ func GetTransactionQuickAccessEntries(w http.ResponseWriter, req *http.Request) transactions[i] = transaction } - component := templates.TransactionQuickAccessEntries(&transactions); - component.Render(context.Background(), w); + component := templates.TransactionQuickAccessEntries(&transactions) + component.Render(context.Background(), w) } func GetExpenditureChart(w http.ResponseWriter, req *http.Request) { - data_package := struct{ - Labels []string `json:"labels"` - IncomeDataset []int `json:"income_data"` - ExpensesDataset []int `json:"expenses_data"` - } { - Labels: []string{"Income", "Expenses"}, - IncomeDataset: []int {300, 250}, - ExpensesDataset: []int {200, 100}, - }; + data_package := struct { + Labels []string `json:"labels"` + IncomeDataset []int `json:"income_data"` + ExpensesDataset []int `json:"expenses_data"` + }{ + Labels: []string{"Income", "Expenses"}, + IncomeDataset: []int{300, 250}, + ExpensesDataset: []int{200, 100}, + } - json_data, err := json.Marshal(data_package); - if err != nil { - log.Fatal().Err(err).Msg("Could not jsonify data_package"); - } - - w.Write(json_data); + json_data, err := json.Marshal(data_package) + if err != nil { + log.Fatal().Err(err).Msg("Could not jsonify data_package") + } + + w.Write(json_data) } func GetAccountSummaries(w http.ResponseWriter, req *http.Request) { - accounts := make([]types.TwoIntsItem, 20) - for i := 0; i < 20; i++ { - accounts[i] = types.TwoIntsItem {Item1: i*100, Item2: i+5} - } - component := templates.AccountSummaryRows(&accounts) - component.Render(context.Background(), w) + accounts := make([]types.TwoIntsItem, 20) + for i := 0; i < 20; i++ { + accounts[i] = types.TwoIntsItem{Item1: i * 100, Item2: i + 5} + } + component := templates.AccountSummaryRows(&accounts) + component.Render(context.Background(), w) } func GetAccountSummaryChart(w http.ResponseWriter, req *http.Request) { - accountID := chi.URLParam(req, "accountID") - - data_package := types.ChartjsData { - Labels: []string {accountID, "1/10", "1/17", "1/24"}, - Data: []int {100, 0, -50, 25}, - } + accountID := chi.URLParam(req, "accountID") - json_data, err := json.Marshal(data_package); - if err != nil { - log.Fatal().Err(err).Msg("Could not jsonify data_package"); - } - - w.Write(json_data); + data_package := types.ChartjsData{ + Labels: []string{accountID, "1/10", "1/17", "1/24"}, + Data: []int{100, 0, -50, 25}, + } + + json_data, err := json.Marshal(data_package) + if err != nil { + log.Fatal().Err(err).Msg("Could not jsonify data_package") + } + + w.Write(json_data) } diff --git a/web/router.go b/web/router.go index a0a8605..b5e4462 100644 --- a/web/router.go +++ b/web/router.go @@ -18,10 +18,10 @@ import ( ) type IndexTemplateModel struct { - InnerHtml template.HTML - ActivePage string - NewTransactionPane template.HTML - QuickAccessPane template.HTML + InnerHtml template.HTML + ActivePage string + NewTransactionPane template.HTML + QuickAccessPane template.HTML } const TemplateDir = "./web/templates/" @@ -33,111 +33,110 @@ func SetLogLevel(level zerolog.Level) { func WebRouter() http.Handler { r := chi.NewRouter() r.Get("/", getDashboard) - r.Get("/transactions", getTransactionsPage) + r.Get("/transactions", getTransactionsPage) - r.Get("/components/account_summaries", GetAccountSummaries) + r.Get("/components/account_summaries", GetAccountSummaries) - r.Get("/components/data/transaction_table_rows", GetTransactionsRows) - r.Get("/components/data/expenditure_chart", GetExpenditureChart) - r.Get("/components/data/account_summary/{accountID}", GetAccountSummaryChart) - r.Get("/components/data/transaction_quick_access", GetTransactionQuickAccessEntries) + r.Get("/components/data/transaction_table_rows", GetTransactionsRows) + r.Get("/components/data/expenditure_chart", GetExpenditureChart) + r.Get("/components/data/account_summary/{accountID}", GetAccountSummaryChart) + r.Get("/components/data/transaction_quick_access", GetTransactionQuickAccessEntries) - r.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(http.Dir("web/static/")))) + r.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(http.Dir("web/static/")))) return r } //for name, values := range req.Header { - // Loop over all values for the name. +// Loop over all values for the name. // for _, value := range values { // log.Debug().Msg(name + " " + value); // } // } func renderFullPage(w http.ResponseWriter, c templ.Component, pageName string) { - var main_component bytes.Buffer + var main_component bytes.Buffer - // Render the provided templ component - err := c.Render(context.Background(), &main_component) - if err != nil { - log.Fatal().Err(err).Msg("Fatal error reading hello template"); - } + // Render the provided templ component + err := c.Render(context.Background(), &main_component) + if err != nil { + log.Fatal().Err(err).Msg("Fatal error reading hello template") + } - // get the index template - index, err := template.ParseFiles(TemplateDir + "index.html") - if err != nil { - log.Fatal(). - Err(err). - Msg("Fatal error reading index template") - } + // get the index template + index, err := template.ParseFiles(TemplateDir + "index.html") + if err != nil { + log.Fatal(). + Err(err). + Msg("Fatal error reading index template") + } + var new_tp bytes.Buffer - var new_tp bytes.Buffer; + quick_trans_types, err := db.GetTransPaneEntries(0) + if err != nil { + log.Fatal().Err(err).Msg("Could not get transaction pane entries for user") + } + user_acnts, err := db.GetUserAccounts(0) + if err != nil { + log.Fatal().Err(err).Msg("Could not get accounts for user") + } + user_bkts, err := db.GetUserBuckets(0) + if err != nil { + log.Fatal().Err(err).Msg("Could not get buckets for user") + } - quick_trans_types, err := db.GetTransPaneEntries(0); - if err != nil { - log.Fatal().Err(err).Msg("Could not get transaction pane entries for user"); - } - user_acnts, err := db.GetUserAccounts(0); - if err != nil { - log.Fatal().Err(err).Msg("Could not get accounts for user"); - } - user_bkts, err := db.GetUserBuckets(0); - if err != nil { - log.Fatal().Err(err).Msg("Could not get buckets for user"); - } + err = templates.NewTransactionPane(&quick_trans_types, &user_acnts, &user_bkts).Render(context.Background(), &new_tp) + if err != nil { + log.Fatal().Err(err).Msg("Could not render new transaction pane for index") + } - err = templates.NewTransactionPane(&quick_trans_types, &user_acnts, &user_bkts).Render(context.Background(), &new_tp); - if err != nil { - log.Fatal().Err(err).Msg("Could not render new transaction pane for index"); - } + var quick_ap bytes.Buffer + err = templates.QuickAccessPane().Render(context.Background(), &quick_ap) + if err != nil { + log.Fatal().Err(err).Msg("Could not render quick access pane for index") + } - var quick_ap bytes.Buffer; - err = templates.QuickAccessPane().Render(context.Background(), &quick_ap); - if err != nil { - log.Fatal().Err(err).Msg("Could not render quick access pane for index"); - } - - // Inject the templ component html into the index template - err = index.Execute(w, - IndexTemplateModel{ - InnerHtml: template.HTML(main_component.String()), - ActivePage: pageName, - NewTransactionPane: template.HTML(new_tp.String()), - QuickAccessPane: template.HTML(quick_ap.String()), - }); - if err != nil { - log.Fatal().Err(err).Msg("Fatal error reading hello template"); - } + // Inject the templ component html into the index template + err = index.Execute(w, + IndexTemplateModel{ + InnerHtml: template.HTML(main_component.String()), + ActivePage: pageName, + NewTransactionPane: template.HTML(new_tp.String()), + QuickAccessPane: template.HTML(quick_ap.String()), + }) + if err != nil { + log.Fatal().Err(err).Msg("Fatal error reading hello template") + } } func getDashboard(w http.ResponseWriter, req *http.Request) { - component := templates.Dashboard(); + component := templates.Dashboard() - _, ok := req.Header["Hx-Request"] - if ok { - err := component.Render(context.Background(), w); - if err != nil { - log.Fatal().Err(err).Msg("Couldn't render dashboard templ template"); - } - } else { - renderFullPage(w, component, "Dashboard"); - } + _, ok := req.Header["Hx-Request"] + if ok { + err := component.Render(context.Background(), w) + if err != nil { + log.Fatal().Err(err).Msg("Couldn't render dashboard templ template") + } + } else { + renderFullPage(w, component, "Dashboard") + } } func getTransactionsPage(w http.ResponseWriter, req *http.Request) { - accounts := make([]string, 10); - for i := 0; i < 10; i++ { - accounts[i] = strconv.Itoa(i) + " Account"; - } + accounts := make([]string, 10) + for i := 0; i < 10; i++ { + accounts[i] = strconv.Itoa(i) + " Account" + } - component := templates.TransactionsPage(1, &accounts); - _, ok := req.Header["Hx-Request"] - if ok { - err := component.Render(context.Background(), w); - if err != nil { - log.Fatal().Err(err).Msg("Couldn't render transactions templ template"); - } - } else { - renderFullPage(w, component, "Transactions") - } + component := templates.TransactionsPage(1, &accounts) + _, ok := req.Header["Hx-Request"] + if ok { + err := component.Render(context.Background(), w) + if err != nil { + log.Fatal().Err(err).Msg("Couldn't render transactions templ template") + } + } else { + renderFullPage(w, component, "Transactions") + } } diff --git a/web/static/index.js b/web/static/index.js index c358456..34aa320 100644 --- a/web/static/index.js +++ b/web/static/index.js @@ -4,6 +4,7 @@ import { open_new_transaction_pane , close_new_transaction_pane , add_new_breakdown + , register_breakdown_handlers } from "./new_transactions.js"; @@ -60,6 +61,7 @@ function register_handlers() { a_el.addEventListener("click", switch_nav); }); register_dropdowns(); + register_breakdown_handlers(); document.querySelector("#open-draft").addEventListener("click", open_drafts); document.querySelector("#close-transaction-pane").addEventListener("click", close_drafts); document.querySelector(".input-sizer > input").addEventListener("input", (event) => { diff --git a/web/static/new_transactions.js b/web/static/new_transactions.js index 271052f..dbcfdb6 100644 --- a/web/static/new_transactions.js +++ b/web/static/new_transactions.js @@ -48,15 +48,48 @@ function close_new_transaction_pane() { } +/** + * @param {Event} event +*/ +function on_input(event) { + if (event.target.id === "bottom-most-breakdown-input" + || document.querySelectorAll("#breakdown-tbody input[type='number']").length === 0 + ) { + add_new_breakdown(); + } + + let breakdown_inputs = Array.from(document + .querySelectorAll("#breakdown-tbody input[type='number']:not(#bottom-most-breakdown-input)" + )); + let breakdown_sum = breakdown_inputs.reduce(function(total, el) { + return total + parseFloat(el.value || 0); + }, 0); + + let total_input = document.getElementById("amount-entry"); + if (total_input.value) { + let value_total = parseFloat(total_input.value); + + document.getElementById("bottom-most-breakdown-input").value = (value_total - breakdown_sum).toFixed(2); + } else { + total_input.placeholder = breakdown_sum; + } +} + function add_new_breakdown() { - let source = document.querySelector("#breakdown-template-row tr").cloneNode(true); - source.style.removeProperty("display"); - console.log(source.querySelector("input[type='number']")); + let input_latest_old = document.getElementById("bottom-most-breakdown-input"); + if (input_latest_old) { + input_latest_old.id = ""; + } + + let source = document.importNode(document.getElementById("breakdown-template-row").content, true); + let input_latest = source.querySelector("input[type='number']"); + input_latest.addEventListener("input", on_input); + input_latest.id = "bottom-most-breakdown-input"; document.getElementById("breakdown-tbody").appendChild(source); } -function update_breakdown_amount() { - +function register_breakdown_handlers() { + document.getElementById("amount-entry").addEventListener("input", on_input); } -export {open_new_transaction_pane, close_new_transaction_pane, add_new_breakdown} +export {open_new_transaction_pane, close_new_transaction_pane, add_new_breakdown, register_breakdown_handlers} diff --git a/web/templates/new_transaction_pane.templ b/web/templates/new_transaction_pane.templ index 5385ede..5594af8 100644 --- a/web/templates/new_transaction_pane.templ +++ b/web/templates/new_transaction_pane.templ @@ -5,7 +5,8 @@ import "strconv" templ NewTransactionPane(entry_types *[]types.QuickTransactionType, acnts *[]types.Account, buckets *[]types.Bucket) { -