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();
+});