diff --git a/Makefile b/Makefile index f4ee109..3ef5878 100644 --- a/Makefile +++ b/Makefile @@ -75,6 +75,8 @@ tailwind: -o ./internal/handler/views/assets/css/main.min.css \ -c ./tailwind.config.js \ --minify + bun build ./internal/handler/views/src/js/main.js --minify \ + --outfile ./internal/handler/views/assets/js/main.min.js .PHONY: clean clean: diff --git a/internal/handler/response.go b/internal/handler/response.go index 5799285..cfa506f 100644 --- a/internal/handler/response.go +++ b/internal/handler/response.go @@ -30,6 +30,42 @@ func (s *fiberServer) homeHandler(c *fiber.Ctx) error { return handler(c) } +// Render Remote Nodes Page +func (s *fiberServer) remoteNodesHandler(c *fiber.Ctx) error { + p := views.Meta{ + Title: "Public Monero Remote Nodes List", + Description: "Although it's possible to use these existing public Monero nodes, you're MUST RUN AND USE YOUR OWN NODE!", + Keywords: "monero remote nodes,public monero nodes,monero public nodes,monero wallet,tor monero node,monero cors rpc", + Robots: "INDEX,FOLLOW", + Permalink: "https://xmr.ditatompel.com/remote-nodes", + Identifier: "/remote-nodes", + } + + c.Set("Link", fmt.Sprintf(`<%s>; rel="canonical"`, p.Permalink)) + home := views.BaseLayout(p, views.RemoteNodes()) + handler := adaptor.HTTPHandler(templ.Handler(home)) + + return handler(c) +} + +// Render Add Node Page +func (s *fiberServer) addNodeHandler(c *fiber.Ctx) error { + p := views.Meta{ + Title: "Add Monero Node", + Description: "You can use this page to add known remote node to the system so my bots can monitor it.", + Keywords: "monero,monero node,monero public node,monero wallet,list monero node,monero node monitoring", + Robots: "INDEX,FOLLOW", + Permalink: "https://xmr.ditatompel.com/add-node", + Identifier: "/add-node", + } + + c.Set("Link", fmt.Sprintf(`<%s>; rel="canonical"`, p.Permalink)) + home := views.BaseLayout(p, views.AddNode()) + handler := adaptor.HTTPHandler(templ.Handler(home)) + + return handler(c) +} + // Returns a single node information based on `id` query param func Node(c *fiber.Ctx) error { nodeId, err := c.ParamsInt("id", 0) diff --git a/internal/handler/routes.go b/internal/handler/routes.go index eb61fe2..fc66792 100644 --- a/internal/handler/routes.go +++ b/internal/handler/routes.go @@ -2,6 +2,8 @@ package handler func (s *fiberServer) Routes() { s.App.Get("/", s.homeHandler) + s.App.Get("/remote-nodes", s.remoteNodesHandler) + s.App.Get("/add-node", s.addNodeHandler) // V1 API routes v1 := s.App.Group("/api/v1") diff --git a/internal/handler/views/add_node.templ b/internal/handler/views/add_node.templ new file mode 100644 index 0000000..9bdb828 --- /dev/null +++ b/internal/handler/views/add_node.templ @@ -0,0 +1,5 @@ +package views + +templ AddNode() { +

Add Node

+} diff --git a/internal/handler/views/add_node_templ.go b/internal/handler/views/add_node_templ.go new file mode 100644 index 0000000..b2cce0e --- /dev/null +++ b/internal/handler/views/add_node_templ.go @@ -0,0 +1,40 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.778 +package views + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +func AddNode() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + 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("

Add Node

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/handler/views/home.templ b/internal/handler/views/home.templ index 6e7a6f7..28c1709 100644 --- a/internal/handler/views/home.templ +++ b/internal/handler/views/home.templ @@ -1,4 +1,5 @@ package views templ Home() { +

Home

} diff --git a/internal/handler/views/home_templ.go b/internal/handler/views/home_templ.go index 44d399d..826ae1b 100644 --- a/internal/handler/views/home_templ.go +++ b/internal/handler/views/home_templ.go @@ -29,6 +29,10 @@ func Home() templ.Component { templ_7745c5c3_Var1 = templ.NopComponent } ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Home

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } return templ_7745c5c3_Err }) } diff --git a/internal/handler/views/layout.templ b/internal/handler/views/layout.templ index c78cb3f..0441799 100644 --- a/internal/handler/views/layout.templ +++ b/internal/handler/views/layout.templ @@ -39,8 +39,10 @@ templ base(m Meta) { + + @navbar()
{ children... }
diff --git a/internal/handler/views/layout_templ.go b/internal/handler/views/layout_templ.go index 5dec309..fcd4ec4 100644 --- a/internal/handler/views/layout_templ.go +++ b/internal/handler/views/layout_templ.go @@ -176,7 +176,28 @@ func base(m Meta) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">
") + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\">") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = navbar().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -188,12 +209,12 @@ func base(m Meta) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var12 string - templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(config.Version) + var templ_7745c5c3_Var13 string + templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(config.Version) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/handler/views/layout.templ`, Line: 49, Col: 64} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/handler/views/layout.templ`, Line: 51, Col: 64} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -221,12 +242,12 @@ func BaseLayout(m Meta, cmp templ.Component) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var13 := templ.GetChildren(ctx) - if templ_7745c5c3_Var13 == nil { - templ_7745c5c3_Var13 = templ.NopComponent + templ_7745c5c3_Var14 := templ.GetChildren(ctx) + if templ_7745c5c3_Var14 == nil { + templ_7745c5c3_Var14 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Var14 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_Var15 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) if !templ_7745c5c3_IsBuffer { @@ -244,7 +265,7 @@ func BaseLayout(m Meta, cmp templ.Component) templ.Component { } return templ_7745c5c3_Err }) - templ_7745c5c3_Err = base(m).Render(templ.WithChildren(ctx, templ_7745c5c3_Var14), templ_7745c5c3_Buffer) + templ_7745c5c3_Err = base(m).Render(templ.WithChildren(ctx, templ_7745c5c3_Var15), templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -268,9 +289,9 @@ func BlankLayout(cmp templ.Component) templ.Component { }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var15 := templ.GetChildren(ctx) - if templ_7745c5c3_Var15 == nil { - templ_7745c5c3_Var15 = templ.NopComponent + templ_7745c5c3_Var16 := templ.GetChildren(ctx) + if templ_7745c5c3_Var16 == nil { + templ_7745c5c3_Var16 = templ.NopComponent } ctx = templ.ClearChildren(ctx) templ_7745c5c3_Err = cmp.Render(ctx, templ_7745c5c3_Buffer) diff --git a/internal/handler/views/partial_navbar.templ b/internal/handler/views/partial_navbar.templ new file mode 100644 index 0000000..dd277b0 --- /dev/null +++ b/internal/handler/views/partial_navbar.templ @@ -0,0 +1,26 @@ +package views + +templ navbar() { +
+ +
+} diff --git a/internal/handler/views/partial_navbar_templ.go b/internal/handler/views/partial_navbar_templ.go new file mode 100644 index 0000000..3f043da --- /dev/null +++ b/internal/handler/views/partial_navbar_templ.go @@ -0,0 +1,40 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.778 +package views + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +func navbar() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + 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("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/handler/views/remote_nodes.templ b/internal/handler/views/remote_nodes.templ new file mode 100644 index 0000000..f01b97a --- /dev/null +++ b/internal/handler/views/remote_nodes.templ @@ -0,0 +1,5 @@ +package views + +templ RemoteNodes() { +

Remote Nodes

+} diff --git a/internal/handler/views/remote_nodes_templ.go b/internal/handler/views/remote_nodes_templ.go new file mode 100644 index 0000000..1c5bf71 --- /dev/null +++ b/internal/handler/views/remote_nodes_templ.go @@ -0,0 +1,40 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.778 +package views + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +func RemoteNodes() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + 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("

Remote Nodes

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/handler/views/src/js/main.js b/internal/handler/views/src/js/main.js new file mode 100644 index 0000000..ae822d6 --- /dev/null +++ b/internal/handler/views/src/js/main.js @@ -0,0 +1,7 @@ +import "@preline/collapse"; + +htmx.onLoad(function () { + // Auto init preline JS, see https://preline.co/docs/preline-javascript.html + // This need to be inside `htmx.onLoad` to be work together with hx-boost. + HSCollapse.autoInit(); +});