feat(layout): remove unnecessary divs #60

Merged
tim merged 2 commits from 49-accounts into prod 2025-05-08 11:29:13 +00:00
9 changed files with 62 additions and 67 deletions
+21 -21
View File
@@ -8,13 +8,13 @@ import (
"github.com/jmoiron/sqlx"
)
// While it may be duplicated to check for groupIds in the database access, it serves as a security layer
// While it may be duplicated to check for userId in the database access, it serves as a security layer
type Account interface {
Insert(groupId uuid.UUID, account *types.Account) error
Update(groupId uuid.UUID, account *types.Account) error
GetAll(groupId uuid.UUID) ([]*types.Account, error)
Get(groupId uuid.UUID, id uuid.UUID) (*types.Account, error)
Delete(groupId uuid.UUID, id uuid.UUID) error
Insert(userId uuid.UUID, account *types.Account) error
Update(userId uuid.UUID, account *types.Account) error
GetAll(userId uuid.UUID) ([]*types.Account, error)
Get(userId uuid.UUID, id uuid.UUID) (*types.Account, error)
Delete(userId uuid.UUID, id uuid.UUID) error
}
type AccountSqlite struct {
@@ -25,11 +25,11 @@ func NewAccountSqlite(db *sqlx.DB) *AccountSqlite {
return &AccountSqlite{db: db}
}
func (db AccountSqlite) Insert(groupId uuid.UUID, account *types.Account) error {
func (db AccountSqlite) Insert(userId uuid.UUID, account *types.Account) error {
_, err := db.db.Exec(`
INSERT INTO account (id, group_id, name, current_balance, oink_balance, created_at, created_by)
VALUES (?,?,?,?,?,?,?)`, account.Id, groupId, account.Name, 0, 0, account.CreatedAt, account.CreatedBy)
INSERT INTO account (id, user_id, name, current_balance, oink_balance, created_at, created_by)
VALUES (?,?,?,?,?,?,?)`, account.Id, userId, account.Name, 0, 0, account.CreatedAt, account.CreatedBy)
if err != nil {
log.Error("Error inserting account: %v", err)
return types.ErrInternal
@@ -38,7 +38,7 @@ func (db AccountSqlite) Insert(groupId uuid.UUID, account *types.Account) error
return nil
}
func (db AccountSqlite) Update(groupId uuid.UUID, account *types.Account) error {
func (db AccountSqlite) Update(userId uuid.UUID, account *types.Account) error {
log.Info("Updating account: %v", account)
r, err := db.db.Exec(`
@@ -51,7 +51,7 @@ func (db AccountSqlite) Update(groupId uuid.UUID, account *types.Account) error
updated_at = ?,
updated_by = ?
WHERE id = ?
AND group_id = ?`, account.Name, account.CurrentBalance, account.LastTransaction, account.OinkBalance, account.UpdatedAt, account.UpdatedBy, account.Id, groupId)
AND user_id = ?`, account.Name, account.CurrentBalance, account.LastTransaction, account.OinkBalance, account.UpdatedAt, account.UpdatedBy, account.Id, userId)
if err != nil {
log.Error("Error updating account: %v", err)
return types.ErrInternal
@@ -70,17 +70,17 @@ func (db AccountSqlite) Update(groupId uuid.UUID, account *types.Account) error
return nil
}
func (db AccountSqlite) GetAll(groupId uuid.UUID) ([]*types.Account, error) {
func (db AccountSqlite) GetAll(userId uuid.UUID) ([]*types.Account, error) {
accounts := make([]*types.Account, 0)
err := db.db.Select(&accounts, `
SELECT
id, group_id, name,
id, user_id, name,
current_balance, last_transaction, oink_balance,
created_at, created_by, updated_at, updated_by
FROM account
WHERE group_id = ?
ORDER BY name`, groupId)
WHERE user_id = ?
ORDER BY name`, userId)
if err != nil {
log.Error("Could not getAll accounts: %v", err)
return nil, types.ErrInternal
@@ -89,17 +89,17 @@ func (db AccountSqlite) GetAll(groupId uuid.UUID) ([]*types.Account, error) {
return accounts, nil
}
func (db AccountSqlite) Get(groupId uuid.UUID, id uuid.UUID) (*types.Account, error) {
func (db AccountSqlite) Get(userId uuid.UUID, id uuid.UUID) (*types.Account, error) {
account := &types.Account{}
err := db.db.Get(account, `
SELECT
id, group_id, name,
id, user_id, name,
current_balance, last_transaction, oink_balance,
created_at, created_by, updated_at, updated_by
FROM account
WHERE group_id = ?
AND id = ?`, groupId, id)
WHERE user_id = ?
AND id = ?`, userId, id)
if err != nil {
log.Error("Could not get accounts: %v", err)
return nil, types.ErrInternal
@@ -108,9 +108,9 @@ func (db AccountSqlite) Get(groupId uuid.UUID, id uuid.UUID) (*types.Account, er
return account, nil
}
func (db AccountSqlite) Delete(groupId uuid.UUID, id uuid.UUID) error {
func (db AccountSqlite) Delete(userId uuid.UUID, id uuid.UUID) error {
res, err := db.db.Exec("DELETE FROM account WHERE id = ? and group_id = ?", id, groupId)
res, err := db.db.Exec("DELETE FROM account WHERE id = ? and user_id = ?", id, userId)
if err != nil {
log.Error("Error deleting account: %v", err)
return types.ErrInternal
+1 -1
View File
@@ -135,7 +135,7 @@ func (db AuthSqlite) DeleteUser(userId uuid.UUID) error {
return types.ErrInternal
}
_, err = tx.Exec("DELETE FROM account WHERE group_id = ?", userId)
_, err = tx.Exec("DELETE FROM account WHERE user_id = ?", userId)
if err != nil {
_ = tx.Rollback()
log.Error("Could not delete accounts: %v", err)
+2 -2
View File
@@ -334,7 +334,7 @@ func TestIntegrationAuth(t *testing.T) {
resp, err = httpClient.Do(req)
timeEnd := time.Now()
assert.Nil(t, err)
if timeEnd.Sub(timeStart) > 260*time.Millisecond || timeEnd.Sub(timeStart) <= 250*time.Millisecond {
if timeEnd.Sub(timeStart) > 260*time.Millisecond || timeEnd.Sub(timeStart) < 250*time.Millisecond {
t.Fail()
t.Logf("Time did not match: %v", timeEnd.Sub(timeStart))
}
@@ -929,7 +929,7 @@ func TestIntegrationAuth(t *testing.T) {
err = db.QueryRow("SELECT COUNT(*) FROM user WHERE user_id = ?", userId).Scan(&rows)
assert.Nil(t, err)
assert.Equal(t, 0, rows)
err = db.QueryRow("SELECT COUNT(*) FROM account WHERE group_id = ?", userId).Scan(&rows)
err = db.QueryRow("SELECT COUNT(*) FROM account WHERE user_id = ?", userId).Scan(&rows)
assert.Nil(t, err)
assert.Equal(t, 0, rows)
})
+1 -1
View File
@@ -1,7 +1,7 @@
CREATE TABLE account (
id TEXT NOT NULL UNIQUE PRIMARY KEY,
group_id TEXT NOT NULL,
user_id TEXT NOT NULL,
name TEXT NOT NULL,
+3 -3
View File
@@ -55,8 +55,8 @@ func (service AccountImpl) Add(user *types.User, name string) (*types.Account, e
}
account := &types.Account{
Id: newId,
GroupId: user.Id,
Id: newId,
UserId: user.Id,
Name: name,
@@ -150,7 +150,7 @@ func (service AccountImpl) Delete(user *types.User, id uuid.UUID) error {
return err
}
if account.GroupId != user.Id {
if account.UserId != user.Id {
return types.ErrUnauthorized
}
+6 -6
View File
@@ -14,11 +14,11 @@ func TestMoneyCalculation(t *testing.T) {
// // GIVEN
// timestamp := time.Date(2020, 01, 01, 0, 0, 0, 0, time.UTC)
//
// groupId := uuid.New()
// userId := uuid.New()
//
// account := types.Account{
// Id: uuid.New(),
// GroupId: groupId,
// UserId: userId,
//
// Type: "Bank",
// Name: "Bank",
@@ -31,7 +31,7 @@ func TestMoneyCalculation(t *testing.T) {
// // The PiggyBank is a fictional account. The money it "holds" is actually in the Account
// piggyBank := types.PiggyBank{
// Id: uuid.New(),
// GroupId: groupId,
// UserId: userId,
//
// AccountId: account.Id,
// Name: "Car",
@@ -41,7 +41,7 @@ func TestMoneyCalculation(t *testing.T) {
//
// savingsPlan := types.SavingsPlan{
// Id: uuid.New(),
// GroupId: groupId,
// UserId: userId,
// PiggyBankId: piggyBank.Id,
//
// MonthlySaving: 10,
@@ -51,7 +51,7 @@ func TestMoneyCalculation(t *testing.T) {
//
// transaction1 := types.Transaction{
// Id: uuid.New(),
// GroupId: groupId,
// UserId: userId,
//
// AccountId: account.Id,
//
@@ -61,7 +61,7 @@ func TestMoneyCalculation(t *testing.T) {
//
// transaction2 := types.Transaction{
// Id: uuid.New(),
// GroupId: groupId,
// UserId: userId,
//
// AccountId: account.Id,
// PiggyBankId: &piggyBank.Id,
+20 -24
View File
@@ -29,31 +29,27 @@ templ Layout(slot templ.Component, user templ.Component, loggedIn bool, path str
</head>
<body class="h-screen flex flex-col" hx-headers='{"csrf-token": "CSRF_TOKEN"}'>
// Header
<div class="">
<nav class="flex bg-white items-center gap-2 py-1 px-2 h-12 md:gap-10 md:px-10 md:py-2">
<a href="/" class="flex gap-2 mr-20">
<img class="w-6" src="/static/favicon.svg" alt="SpendSparrow logo"/>
<span class="text-4xl font-bold font-pirata">SpendSparrow</span>
</a>
if loggedIn {
<a class={ layoutLinkClass(path == "/") } href="/">Dashboard</a>
<a class={ layoutLinkClass(path == "/transaction") } href="/transaction">Transaction</a>
<a class={ layoutLinkClass(path == "/account") } href="/account">Account</a>
}
<div class="ml-auto">
@user
</div>
</nav>
<div class="h-12 fixed top-12 mr-4 inset-0 bg-linear-0 from-transparent to-white"></div>
</div>
<nav class="flex bg-white items-center gap-2 py-1 px-2 h-12 md:gap-10 md:px-10 md:py-2">
<a href="/" class="flex gap-2 mr-20">
<img class="w-6" src="/static/favicon.svg" alt="SpendSparrow logo"/>
<span class="text-4xl font-bold font-pirata">SpendSparrow</span>
</a>
if loggedIn {
<a class={ layoutLinkClass(path == "/") } href="/">Dashboard</a>
<a class={ layoutLinkClass(path == "/transaction") } href="/transaction">Transaction</a>
<a class={ layoutLinkClass(path == "/account") } href="/account">Account</a>
}
<div class="ml-auto">
@user
</div>
</nav>
<div class="h-12 fixed top-12 mr-4 inset-0 bg-linear-0 from-transparent to-white"></div>
// Content
<div class="flex-1 overflow-auto">
<main class="h-full">
if slot != nil {
@slot
}
</main>
</div>
<main class="flex-1 overflow-auto">
if slot != nil {
@slot
}
</main>
// Footer
<!-- </div> -->
<div id="toasts" class="fixed bottom-4 right-4 ml-4 max-w-96 flex flex-col gap-2 z-50">
-1
View File
@@ -8,7 +8,6 @@ import (
type User struct {
Id uuid.UUID
GroupId uuid.UUID
Email string
EmailVerified bool
EmailVerifiedAt *time.Time
+8 -8
View File
@@ -12,8 +12,8 @@ import (
//
// If it becomes necessary to precalculate snapshots for performance reasons, this can be done in the future. But the transaction should always be the source of truth.
type Transaction struct {
Id uuid.UUID
GroupId uuid.UUID
Id uuid.UUID
UserId uuid.UUID
AccountId uuid.UUID
// nil indicates that the transaction is not yet associated with a piggy bank
@@ -37,8 +37,8 @@ type Transaction struct {
// The Account holds money
type Account struct {
Id uuid.UUID
GroupId uuid.UUID `db:"group_id"`
Id uuid.UUID
UserId uuid.UUID `db:"user_id"`
// Custom Name of the account, e.g. "Bank", "Cash", "Credit Card"
Name string
@@ -57,8 +57,8 @@ type Account struct {
// The PiggyBank is a fictional account. The money it "holds" is actually in the Account
type PiggyBank struct {
Id uuid.UUID
GroupId uuid.UUID
Id uuid.UUID
UserId uuid.UUID
AccountId uuid.UUID
Name string
@@ -73,8 +73,8 @@ type PiggyBank struct {
// The SavingsPlan is applied every interval to the PiggyBank/Account as a transaction
type SavingsPlan struct {
Id uuid.UUID
GroupId uuid.UUID
Id uuid.UUID
UserId uuid.UUID
PiggyBankId uuid.UUID