feat: extract dashboard
All checks were successful
Build and Push Docker Image / Build-And-Push-Docker-Image (push) Successful in 1m19s

This commit is contained in:
2025-12-26 07:11:39 +01:00
parent 5e563f2c59
commit c927d917ec
9 changed files with 55 additions and 55 deletions

View File

@@ -1,12 +1,12 @@
package handler
package dashboard
import (
"fmt"
"log/slog"
"net/http"
"spend-sparrow/internal/core"
"spend-sparrow/internal/dashboard/template"
"spend-sparrow/internal/service"
"spend-sparrow/internal/template/dashboard"
"spend-sparrow/internal/utils"
"strings"
"time"
@@ -14,32 +14,32 @@ import (
"github.com/google/uuid"
)
type Dashboard interface {
type Handler interface {
Handle(router *http.ServeMux)
}
type DashboardImpl struct {
type HandlerImpl struct {
r *core.Render
d *service.Dashboard
s *Service
treasureChest service.TreasureChest
}
func NewDashboard(r *core.Render, d *service.Dashboard, treasureChest service.TreasureChest) Dashboard {
return DashboardImpl{
func NewHandler(r *core.Render, s *Service, treasureChest service.TreasureChest) Handler {
return HandlerImpl{
r: r,
d: d,
s: s,
treasureChest: treasureChest,
}
}
func (handler DashboardImpl) Handle(router *http.ServeMux) {
router.Handle("GET /dashboard", handler.handleDashboard())
router.Handle("GET /dashboard/main-chart", handler.handleDashboardMainChart())
router.Handle("GET /dashboard/treasure-chests", handler.handleDashboardTreasureChests())
router.Handle("GET /dashboard/treasure-chest", handler.handleDashboardTreasureChest())
func (handler HandlerImpl) Handle(router *http.ServeMux) {
router.Handle("GET /dashboard", handler.handleHandler())
router.Handle("GET /dashboard/main-chart", handler.handleHandlerMainChart())
router.Handle("GET /dashboard/treasure-chests", handler.handleHandlerTreasureChests())
router.Handle("GET /dashboard/treasure-chest", handler.handleHandlerTreasureChest())
}
func (handler DashboardImpl) handleDashboard() http.HandlerFunc {
func (handler HandlerImpl) handleHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
core.UpdateSpan(r)
@@ -55,18 +55,18 @@ func (handler DashboardImpl) handleDashboard() http.HandlerFunc {
return
}
comp := dashboard.Dashboard(treasureChests)
comp := template.Dashboard(treasureChests)
handler.r.RenderLayoutWithStatus(r, w, comp, user, http.StatusOK)
}
}
func (handler DashboardImpl) handleDashboardMainChart() http.HandlerFunc {
func (handler HandlerImpl) handleHandlerMainChart() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
core.UpdateSpan(r)
user := core.GetUser(r)
series, err := handler.d.MainChart(r.Context(), user)
series, err := handler.s.MainChart(r.Context(), user)
if err != nil {
core.HandleError(w, r, err)
return
@@ -126,13 +126,13 @@ func (handler DashboardImpl) handleDashboardMainChart() http.HandlerFunc {
}
}
func (handler DashboardImpl) handleDashboardTreasureChests() http.HandlerFunc {
func (handler HandlerImpl) handleHandlerTreasureChests() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
core.UpdateSpan(r)
user := core.GetUser(r)
treeList, err := handler.d.TreasureChests(r.Context(), user)
treeList, err := handler.s.TreasureChests(r.Context(), user)
if err != nil {
core.HandleError(w, r, err)
return
@@ -181,7 +181,7 @@ func (handler DashboardImpl) handleDashboardTreasureChests() http.HandlerFunc {
}
}
func (handler DashboardImpl) handleDashboardTreasureChest() http.HandlerFunc {
func (handler HandlerImpl) handleHandlerTreasureChest() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
core.UpdateSpan(r)
@@ -200,7 +200,7 @@ func (handler DashboardImpl) handleDashboardTreasureChest() http.HandlerFunc {
treasureChestId = &id
}
series, err := handler.d.TreasureChest(r.Context(), user, treasureChestId)
series, err := handler.s.TreasureChest(r.Context(), user, treasureChestId)
if err != nil {
core.HandleError(w, r, err)
return

View File

@@ -1,9 +1,10 @@
package service
package dashboard
import (
"context"
"spend-sparrow/internal/auth_types"
"spend-sparrow/internal/core"
"spend-sparrow/internal/service"
"spend-sparrow/internal/types"
"time"
@@ -11,20 +12,20 @@ import (
"github.com/jmoiron/sqlx"
)
type Dashboard struct {
type Service struct {
db *sqlx.DB
}
func NewDashboard(db *sqlx.DB) *Dashboard {
return &Dashboard{
func NewService(db *sqlx.DB) *Service {
return &Service{
db: db,
}
}
func (s Dashboard) MainChart(
func (s Service) MainChart(
ctx context.Context,
user *auth_types.User,
) ([]types.DashboardMainChartEntry, error) {
) ([]DashboardMainChartEntry, error) {
if user == nil {
return nil, core.ErrUnauthorized
}
@@ -40,9 +41,9 @@ func (s Dashboard) MainChart(
return nil, err
}
timeEntries := make([]types.DashboardMainChartEntry, 0)
timeEntries := make([]DashboardMainChartEntry, 0)
var lastEntry *types.DashboardMainChartEntry
var lastEntry *DashboardMainChartEntry
for _, t := range transactions {
if t.Error != nil {
@@ -51,14 +52,14 @@ func (s Dashboard) MainChart(
newDay := t.Timestamp.Truncate(24 * time.Hour)
if lastEntry == nil {
lastEntry = &types.DashboardMainChartEntry{
lastEntry = &DashboardMainChartEntry{
Day: newDay,
Value: 0,
Savings: 0,
}
} else if lastEntry.Day != newDay {
timeEntries = append(timeEntries, *lastEntry)
lastEntry = &types.DashboardMainChartEntry{
lastEntry = &DashboardMainChartEntry{
Day: newDay,
Value: lastEntry.Value,
Savings: lastEntry.Savings,
@@ -81,10 +82,10 @@ func (s Dashboard) MainChart(
return timeEntries, nil
}
func (s Dashboard) TreasureChests(
func (s Service) TreasureChests(
ctx context.Context,
user *auth_types.User,
) ([]*types.DashboardTreasureChest, error) {
) ([]*DashboardTreasureChest, error) {
if user == nil {
return nil, core.ErrUnauthorized
}
@@ -96,22 +97,22 @@ func (s Dashboard) TreasureChests(
return nil, err
}
treasureChests = sortTreasureChests(treasureChests)
treasureChests = service.SortTreasureChests(treasureChests)
result := make([]*types.DashboardTreasureChest, 0)
result := make([]*DashboardTreasureChest, 0)
for _, t := range treasureChests {
if t.ParentId == nil {
result = append(result, &types.DashboardTreasureChest{
result = append(result, &DashboardTreasureChest{
Name: t.Name,
Value: t.CurrentBalance,
Children: make([]types.DashboardTreasureChest, 0),
Children: make([]DashboardTreasureChest, 0),
})
} else {
result[len(result)-1].Children = append(result[len(result)-1].Children, types.DashboardTreasureChest{
result[len(result)-1].Children = append(result[len(result)-1].Children, DashboardTreasureChest{
Name: t.Name,
Value: t.CurrentBalance,
Children: make([]types.DashboardTreasureChest, 0),
Children: make([]DashboardTreasureChest, 0),
})
}
}
@@ -119,11 +120,11 @@ func (s Dashboard) TreasureChests(
return result, nil
}
func (s Dashboard) TreasureChest(
func (s Service) TreasureChest(
ctx context.Context,
user *auth_types.User,
treausureChestId *uuid.UUID,
) ([]types.DashboardMainChartEntry, error) {
) ([]DashboardMainChartEntry, error) {
if user == nil {
return nil, core.ErrUnauthorized
}
@@ -140,9 +141,9 @@ func (s Dashboard) TreasureChest(
return nil, err
}
timeEntries := make([]types.DashboardMainChartEntry, 0)
timeEntries := make([]DashboardMainChartEntry, 0)
var lastEntry *types.DashboardMainChartEntry
var lastEntry *DashboardMainChartEntry
for _, t := range transactions {
if t.Error != nil {
@@ -151,13 +152,13 @@ func (s Dashboard) TreasureChest(
newDay := t.Timestamp.Truncate(24 * time.Hour)
if lastEntry == nil {
lastEntry = &types.DashboardMainChartEntry{
lastEntry = &DashboardMainChartEntry{
Day: newDay,
Value: 0,
}
} else if lastEntry.Day != newDay {
timeEntries = append(timeEntries, *lastEntry)
lastEntry = &types.DashboardMainChartEntry{
lastEntry = &DashboardMainChartEntry{
Day: newDay,
Value: lastEntry.Value,
}

View File

@@ -1,4 +1,4 @@
package dashboard
package template
import "spend-sparrow/internal/types"

View File

@@ -0,0 +1 @@
package template

View File

@@ -1,4 +1,4 @@
package types
package dashboard
import "time"

View File

@@ -10,6 +10,7 @@ import (
"spend-sparrow/internal/account"
"spend-sparrow/internal/authentication"
"spend-sparrow/internal/core"
"spend-sparrow/internal/dashboard"
"spend-sparrow/internal/handler"
"spend-sparrow/internal/handler/middleware"
"spend-sparrow/internal/log"
@@ -118,11 +119,11 @@ func createHandlerWithServices(ctx context.Context, d *sqlx.DB, serverSettings *
treasureChestService := service.NewTreasureChest(d, randomService, clockService)
transactionService := service.NewTransaction(d, randomService, clockService)
transactionRecurringService := service.NewTransactionRecurring(d, randomService, clockService, transactionService)
dashboardService := service.NewDashboard(d)
dashboardService := dashboard.NewService(d)
render := core.NewRender()
indexHandler := handler.NewIndex(render, clockService)
dashboardHandler := handler.NewDashboard(render, dashboardService, treasureChestService)
dashboardHandler := dashboard.NewHandler(render, dashboardService, treasureChestService)
authHandler := authentication.NewHandler(authService, render)
accountHandler := account.NewHandler(accountService, render)
treasureChestHandler := handler.NewTreasureChest(treasureChestService, transactionRecurringService, render)

View File

@@ -206,7 +206,7 @@ func (s TreasureChestImpl) GetAll(ctx context.Context, user *auth_types.User) ([
return nil, err
}
return sortTreasureChests(treasureChests), nil
return SortTreasureChests(treasureChests), nil
}
func (s TreasureChestImpl) Delete(ctx context.Context, user *auth_types.User, idStr string) error {
@@ -278,7 +278,7 @@ func (s TreasureChestImpl) Delete(ctx context.Context, user *auth_types.User, id
return nil
}
func sortTreasureChests(nodes []*types.TreasureChest) []*types.TreasureChest {
func SortTreasureChests(nodes []*types.TreasureChest) []*types.TreasureChest {
var (
roots []*types.TreasureChest
)

View File

@@ -1,2 +0,0 @@
package dashboard

View File

@@ -5,7 +5,6 @@ import (
"spend-sparrow/internal/auth_types"
"spend-sparrow/internal/authentication"
"spend-sparrow/internal/core"
"spend-sparrow/internal/db"
"testing"
"time"
@@ -29,7 +28,7 @@ func setupDb(t *testing.T) *sqlx.DB {
}
})
err = db.RunMigrations(context.Background(), d, "../")
err = core.RunMigrations(context.Background(), d, "../")
if err != nil {
t.Fatalf("Error running migrations: %v", err)
}