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
+
+
+
+ |
+ Account |
+ Date |
+ |
+ Amount |
+
+
+
+
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 @@