From 172c5037b426ffa61ea4eed64801f8a8aaa7e25d Mon Sep 17 00:00:00 2001 From: Ruidy Date: Sat, 10 Feb 2024 21:10:33 +0100 Subject: [PATCH] reports page --- constants/months.go | 16 +++++ constants/routes.go | 1 + internal/server/handlers.go | 54 +++++++++++++++ internal/server/routes.go | 2 + internal/views/base.templ | 1 + internal/views/report_section.templ | 38 +++++++++++ internal/views/report_section_templ.go | 35 ++++++++++ internal/views/reports.templ | 43 ++++++++++++ internal/views/reports_templ.go | 93 ++++++++++++++++++++++++++ 9 files changed, 283 insertions(+) create mode 100644 constants/months.go create mode 100644 internal/views/report_section.templ create mode 100644 internal/views/report_section_templ.go create mode 100644 internal/views/reports.templ create mode 100644 internal/views/reports_templ.go diff --git a/constants/months.go b/constants/months.go new file mode 100644 index 0000000..5939932 --- /dev/null +++ b/constants/months.go @@ -0,0 +1,16 @@ +package constants + +var Months = []string{ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", +} diff --git a/constants/routes.go b/constants/routes.go index 2f1b344..461c787 100644 --- a/constants/routes.go +++ b/constants/routes.go @@ -3,4 +3,5 @@ package constants const ( RouteBooking = "/bookings" RouteNewBooking = "/bookings/new" + RouteReports = "/reports" ) diff --git a/internal/server/handlers.go b/internal/server/handlers.go index 1a9956e..cfb653d 100644 --- a/internal/server/handlers.go +++ b/internal/server/handlers.go @@ -142,6 +142,60 @@ func (s Server) handleCreateItem() echo.HandlerFunc { } } +func (s Server) handleReportsPage() echo.HandlerFunc { + return func(c echo.Context) error { + period := c.QueryParam("period") + if !u.Contains([]string{"month", "year"}, period) { + period = "month" + } + + monthStr := c.QueryParam("month") + month, err := strconv.Atoi(monthStr) + if err != nil || month < 1 || month > 12 { + month = int(time.Now().Month()) + } + + yearStr := c.QueryParam("year") + _, err = strconv.Atoi(yearStr) + if err != nil { + yearStr = time.Now().Format("2006") + } + return s.renderTempl(c, http.StatusOK, views.Reports(constants.Months, yearStr)) + } +} + +func (s Server) handleComputeReport() echo.HandlerFunc { + return func(c echo.Context) error { + period := c.QueryParam("period") + if !u.Contains([]string{"month", "year"}, period) { + return &echo.HTTPError{ + Code: http.StatusBadRequest, + Message: fmt.Sprintf("%q is not a valid period", period), + } + } + + monthStr := c.QueryParam("month") + month, err := strconv.Atoi(monthStr) + if err != nil || month < 1 || month > 12 { + return &echo.HTTPError{ + Code: http.StatusBadRequest, + Message: fmt.Sprintf("%q is not a valid month", month), + } + } + + yearStr := c.QueryParam("year") + year, err := strconv.Atoi(yearStr) + if err != nil { + return &echo.HTTPError{ + Code: http.StatusBadRequest, + Message: fmt.Sprintf("%q is not a valid year", year), + } + } + // TODO: compute report view model + return s.renderTempl(c, http.StatusOK, views.ReportSection()) + } +} + func (s Server) handleCreateInvoicePdf() echo.HandlerFunc { return func(c echo.Context) error { data := struct { diff --git a/internal/server/routes.go b/internal/server/routes.go index b6c6c54..53635e6 100644 --- a/internal/server/routes.go +++ b/internal/server/routes.go @@ -30,5 +30,7 @@ func (s Server) MountHandlers() { s.Router.POST(constants.RouteNewBooking, s.handleCreateBooking()) s.Router.GET(fmt.Sprintf("%s/:id", constants.RouteBooking), s.handleBookingPage()) s.Router.POST(fmt.Sprintf("%s/:id/items", constants.RouteBooking), s.handleCreateItem()) + s.Router.GET(constants.RouteReports, s.handleReportsPage()) + s.Router.GET(fmt.Sprintf("%s/do", constants.RouteReports), s.handleComputeReport()) s.Router.GET("/pdf", s.handleCreateInvoicePdf()) } diff --git a/internal/views/base.templ b/internal/views/base.templ index 7661537..b29fbd5 100644 --- a/internal/views/base.templ +++ b/internal/views/base.templ @@ -20,6 +20,7 @@ templ BaseLayout() { diff --git a/internal/views/report_section.templ b/internal/views/report_section.templ new file mode 100644 index 0000000..ccc6269 --- /dev/null +++ b/internal/views/report_section.templ @@ -0,0 +1,38 @@ +package views + +templ ReportSection() { +
+

Your report

+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + +
IDNameTotal (€)FromToPlatform
+ + 12 + + joefgsdkjfjjxlkvjjjxlkvj
+
+} diff --git a/internal/views/report_section_templ.go b/internal/views/report_section_templ.go new file mode 100644 index 0000000..24c6ff8 --- /dev/null +++ b/internal/views/report_section_templ.go @@ -0,0 +1,35 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.543 +package views + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import "context" +import "io" +import "bytes" + +func ReportSection() templ.Component { + return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) + if !templ_7745c5c3_IsBuffer { + templ_7745c5c3_Buffer = templ.GetBuffer() + defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Your report

IDNameTotal (€)FromToPlatform
12joefgsdkjfjjxlkvjjjxlkvj
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) + } + return templ_7745c5c3_Err + }) +} diff --git a/internal/views/reports.templ b/internal/views/reports.templ new file mode 100644 index 0000000..1db3dfb --- /dev/null +++ b/internal/views/reports.templ @@ -0,0 +1,43 @@ +package views + +import ( + "strconv" +) + +templ Reports(months []string, year string) { + @BaseLayout() { +
+

Reports

+

Generate monthly and yearly statements

+
+
+
+ Period + + +
+ + + +
+
+ } +} diff --git a/internal/views/reports_templ.go b/internal/views/reports_templ.go new file mode 100644 index 0000000..78044a2 --- /dev/null +++ b/internal/views/reports_templ.go @@ -0,0 +1,93 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.543 +package views + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import "context" +import "io" +import "bytes" + +import ( + "strconv" +) + +func Reports(months []string, year string) templ.Component { + return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) + if !templ_7745c5c3_IsBuffer { + templ_7745c5c3_Buffer = templ.GetBuffer() + defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var2 := templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) + if !templ_7745c5c3_IsBuffer { + templ_7745c5c3_Buffer = templ.GetBuffer() + defer templ.ReleaseBuffer(templ_7745c5c3_Buffer) + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Reports

Generate monthly and yearly statements

Period
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = io.Copy(templ_7745c5c3_W, templ_7745c5c3_Buffer) + } + return templ_7745c5c3_Err + }) + templ_7745c5c3_Err = BaseLayout().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) + } + return templ_7745c5c3_Err + }) +}