From c20830a3347e8cc786960169dfcf61f7c748f1bd Mon Sep 17 00:00:00 2001 From: Nickiel12 Date: Mon, 15 Jan 2024 19:26:51 -0800 Subject: [PATCH] added fading in tables --- tests/testdb.go | 13 ++------- types/types.go | 27 +++++++++++++++++ web/dashboard.templ | 47 +++++++++++++++++++++++++----- web/dataendpoints.templ | 28 ++++++++++++++++++ web/router.go | 30 +++++++++++++++++++ web/sass/nav.scss | 1 + web/sass/site.scss | 19 +++++++++--- web/sass/utility-classes.scss | 55 +++++++++++++++++++++++++++++++++++ web/sass/variables.scss | 6 ++++ web/static/index.js | 49 ++++++++++++++++++++++++------- web/templates/index.html | 10 +++++-- 11 files changed, 250 insertions(+), 35 deletions(-) create mode 100644 types/types.go create mode 100644 web/dataendpoints.templ diff --git a/tests/testdb.go b/tests/testdb.go index 237c6d5..922ac13 100644 --- a/tests/testdb.go +++ b/tests/testdb.go @@ -1,10 +1,9 @@ package debug_mode import ( - "database/sql" + "nickiel.net/recount_server/types" "encoding/json" "os" - "time" "github.com/jmoiron/sqlx" _ "github.com/mattn/go-sqlite3" @@ -12,14 +11,6 @@ import ( "github.com/rs/zerolog/log" ) -type Transaction struct { - Id int `db:"trns_id" json:"Id"` - Amount string `db:"trns_amount" json:"Amount"` - Description sql.NullString `db:"trns_description" json:"Description"` - Account int `db:"trns_account" json:"Account"` - Bucket sql.NullInt64 `db:"trns_bucket" json:"Bucket"` - Date time.Time `db:"trns_date" json:"TransactionDate"` -} func SetLogLevel(level zerolog.Level) { zerolog.SetGlobalLevel(level) @@ -142,7 +133,7 @@ INSERT INTO transactions (trns_amount, trns_description, trns_account, trns_buck "TransactionDate": "2023-11-11T00:00:00Z" }` - var trns Transaction = Transaction{} + var trns types.Transaction = types.Transaction{} err = json.Unmarshal([]byte(jsonExample), &trns) if err != nil { diff --git a/types/types.go b/types/types.go new file mode 100644 index 0000000..339ae08 --- /dev/null +++ b/types/types.go @@ -0,0 +1,27 @@ +package types + +import ( + "database/sql" + + "time" +) + +type Transaction struct { + Id int `db:"trns_id" json:"Id"` + Amount string `db:"trns_amount" json:"Amount"` + Description sql.NullString `db:"trns_description" json:"Description"` + Account int `db:"trns_account" json:"Account"` + Bucket sql.NullInt64 `db:"trns_bucket" json:"Bucket"` + Date time.Time `db:"trns_date" json:"TransactionDate"` +} + +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"` + Account int `db:"trns_account" json:"Account"` + Bucket sql.NullInt64 `db:"trns_bucket" json:"Bucket"` + BucketName sql.NullString `db:"bucket_name" json:"BucketName"` + Date time.Time `db:"trns_date" json:"TransactionDate"` +} diff --git a/web/dashboard.templ b/web/dashboard.templ index 6f2305d..df67906 100644 --- a/web/dashboard.templ +++ b/web/dashboard.templ @@ -3,24 +3,55 @@ package web templ dashboard() { Dashboard
-
+
- - + +
- - + +
-
- - +
+
+ + + + + + + + + + + + + + + + + + + +
+ +
+ + ID + + +
+
AccountDateAmount
diff --git a/web/dataendpoints.templ b/web/dataendpoints.templ new file mode 100644 index 0000000..0052334 --- /dev/null +++ b/web/dataendpoints.templ @@ -0,0 +1,28 @@ +package web + +import ( + "nickiel.net/recount_server/types" + + "strconv" +) + +templ transaction_rows(transactions *[]types.HumanLegibleTransaction) { + for i, value := range *transactions { + + +
{strconv.Itoa(value.Id)}
+ if value.AccountName.Valid { +
{value.AccountName.String}
+ } else { +
{strconv.Itoa(value.Account)}
+ } +
{value.Date.Format("01/02/2006")}
+
$
+ if (len(value.Amount) > 0 && value.Amount[0] == '-') { +
{value.Amount}
+ } else { +
+{value.Amount}
+ } + + } +} diff --git a/web/router.go b/web/router.go index d6b0141..9b6485c 100644 --- a/web/router.go +++ b/web/router.go @@ -1,16 +1,20 @@ package web import ( + "database/sql" "html/template" "net/http" "bytes" "context" + "fmt" + "time" "github.com/a-h/templ" "github.com/go-chi/chi/v5" "github.com/rs/zerolog" "github.com/rs/zerolog/log" + "nickiel.net/recount_server/types" ) type TemplateState struct { @@ -27,6 +31,7 @@ func SetLogLevel(level zerolog.Level) { func WebRouter() http.Handler { r := chi.NewRouter() r.Get("/", getIndex) + r.Get("/web/transaction_table_rows", getTransactions) r.Get("/hello", getHello) r.Handle("/static/*", http.StripPrefix("/static/", http.FileServer(http.Dir("web/static/")))) return r @@ -93,3 +98,28 @@ func getHello(w http.ResponseWriter, req *http.Request) { renderFullPage(w, component, "hello"); } } + +const DEFAULT_RESULT_COUNT = 20; + +func getTransactions(w http.ResponseWriter, req *http.Request) { + 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-- { + transaction := types.HumanLegibleTransaction{ + Id: i, + Amount: fmt.Sprintf("%d.00", (i+1)*100), + Description: sql.NullString{String: fmt.Sprintf("Transaction %d", i+1), Valid: true}, + AccountName: sql.NullString{String: "Savings", Valid: true}, + Account: 123, + Bucket: sql.NullInt64{Int64: int64(i + 100), Valid: true}, + BucketName: sql.NullString{String: fmt.Sprintf("Bucket %d", i+1), Valid: true}, + Date: time.Now(), + } + + transactions[10 - i] = transaction + } + + component := transaction_rows(&transactions); + component.Render(context.Background(), w); +} diff --git a/web/sass/nav.scss b/web/sass/nav.scss index 4ffd6b0..8c613b5 100644 --- a/web/sass/nav.scss +++ b/web/sass/nav.scss @@ -4,6 +4,7 @@ header { width: 100%; margin-top: 10px; margin-bottom: 10px; + border-radius: $border-radius; } nav { display: flex; diff --git a/web/sass/site.scss b/web/sass/site.scss index 1876b1a..8e5f7ab 100644 --- a/web/sass/site.scss +++ b/web/sass/site.scss @@ -13,6 +13,7 @@ $border-radius: 8px; body { background-color: var(--#{$prefix}-bg); + height: 97vh; } @@ -38,26 +39,35 @@ body { @media (min-width: 1362px) { .card-table { box-sizing: border-box; - width: clamp(300px, 80%, 450px); + width: 100%; + margin-left: 0%; + margin-right: 0%; } } @media (max-width: 1362px) { .card-table { + margin-left: auto; + margin-right: auto; box-sizing: border-box; - margin-left: 10%; - margin-right: 10%; + width: clamp(300px, 80%, 450px); } } +div#below-header { + height: 93vh; +} + div#left-col { width: 15vw; padding: 10px; background-color: var(--#{$prefix}-nav-bg); + border-radius: $border-radius; } div#main-body-content { width: 70vw; - padding: 10px; + height: 100%; + overflow-y: scroll; opacity: 1; transition: opacity 0.2s ease-out; } @@ -73,4 +83,5 @@ div#right-col { width: 15vw; padding: 10px; background-color: var(--#{$prefix}-nav-bg); + border-radius: $border-radius; } diff --git a/web/sass/utility-classes.scss b/web/sass/utility-classes.scss index 21a595b..23def63 100644 --- a/web/sass/utility-classes.scss +++ b/web/sass/utility-classes.scss @@ -77,3 +77,58 @@ $directions: ( .cr-bottom { border-radius: 0px 0px $border-radius $border-radius; } + +.t-s { + text-align: start; +} +.t-e { + text-align: end; +} + +table.table { + color: var(--#{$prefix}-text); + td { + padding-right: 10px; + } +} + +table.table-striped { + border-collapse: collapse; + overflow: hidden; + thead { + background-color: var(--#{$prefix}-surface0); + } + tbody { + tr { + &.row_awaiting_processing { + background-color: var(--#{$prefix}-bg) !important; + max-width: 0px; + div { + opacity: 0; + max-height: 0px; + } + } + div { + display: block; + overflow: hidden; + max-height: 50px; + transition: max-height 0.6s cubic-bezier(0.02, 0.15, 0.84, 0.98), + opacity 0.5s ease-in; + } + max-width: 100%; + transition: all 0.5s ease-in; + &:nth-child(odd) { + background-color: var(--#{$prefix}-crust); + } + &:nth-child(even) { + background-color: var(--#{$prefix}-mantle); + } + } + } + .positive { + color: var(--#{$prefix}-green); + } + .negative { + color: var(--#{$prefix}-red); + } +} diff --git a/web/sass/variables.scss b/web/sass/variables.scss index 17dc3c6..dd7eed5 100644 --- a/web/sass/variables.scss +++ b/web/sass/variables.scss @@ -7,7 +7,13 @@ --#{$prefix}-mantle: #{map-get($color, 'mantle')}; --#{$prefix}-surface0: #{map-get($color, 'surface0')}; --#{$prefix}-surface1: #{map-get($color, 'surface1')}; + --#{$prefix}-surface2: #{map-get($color, 'surface2')}; + --#{$prefix}-overlay0: #{map-get($color, 'overlay0')}; + --#{$prefix}-overlay1: #{map-get($color, 'overlay1')}; + --#{$prefix}-overlay2: #{map-get($color, 'overlay2')}; --#{$prefix}-text: #{map-get($color, 'text')}; + --#{$prefix}-green: #{map-get($color, 'green')}; + --#{$prefix}-red: #{map-get($color, 'red')}; --#{$prefix}-nav-bg: #{map-get($color, 'crust')}; --#{$prefix}-nav-color: #{map-get($color, 'text')}; diff --git a/web/static/index.js b/web/static/index.js index 0998160..7384b62 100644 --- a/web/static/index.js +++ b/web/static/index.js @@ -1,22 +1,51 @@ -function say_hello() { - console.log("Hello World"); +function debounce(func, delay) { + let timeoutId; + + return function (...args) { + clearTimeout(timeoutId); + + timeoutId = setTimeout(() => { + func.apply(this, args); + }, delay); + }; } function register_nav_links() { var navAnchors = document.querySelectorAll("nav a"); navAnchors.forEach(function (a_el) { - a_el.addEventListener("click", nav_a_click); + a_el.addEventListener("click", function(event) { + var active_anchor = document.querySelector("nav a.active"); + active_anchor.classList.remove("active"); + + var clicked = event.target; + clicked.classList.add("active"); + }); }); } -function nav_a_click(event) { - var active_anchor = document.querySelector("nav a.active"); - active_anchor.classList.remove("active"); - - var clicked = event.target; - clicked.classList.add("active"); +function register_handlers() { + register_nav_links(); } -export {say_hello, register_nav_links}; + +function load_in_table() { + var rows = Array.from(document.querySelectorAll(".row_awaiting_processing")); + rows.sort((a, b) => b.dataset.rcntTransactionRowPos - a.dataset.rcntTransactionRowPos); + + const processElement = (element, index) => { + element.classList.remove('row_awaiting_processing'); + setTimeout(() => { + if (index < rows.length - 1) { + processElement(rows[index + 1], index + 1); + } + }, 25); // 1000 milliseconds (1 second) delay, adjust as needed +}; + + processElement(rows[0], 0); +} + +const trigger_table_animation = debounce(load_in_table, 100); + +export {register_handlers, trigger_table_animation}; diff --git a/web/templates/index.html b/web/templates/index.html index afb1046..07d1042 100644 --- a/web/templates/index.html +++ b/web/templates/index.html @@ -60,9 +60,15 @@