Skip to content

Commit 7819fea

Browse files
Initial POC of gomponents.
1 parent 5cad4cb commit 7819fea

File tree

14 files changed

+684
-48
lines changed

14 files changed

+684
-48
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ require (
1919
github.com/spf13/viper v1.19.0
2020
github.com/stretchr/testify v1.10.0
2121
golang.org/x/crypto v0.33.0
22+
maragu.dev/gomponents v1.0.0
2223
)
2324

2425
require (

go.sum

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,6 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
8888
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
8989
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
9090
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
91-
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
92-
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
9391
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
9492
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
9593
github.com/maypok86/otter v1.2.4 h1:HhW1Pq6VdJkmWwcZZq19BlEQkHtI8xgsQzBVXJU0nfc=
@@ -104,8 +102,6 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
104102
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
105103
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
106104
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
107-
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
108-
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
109105
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
110106
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
111107
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -123,8 +119,6 @@ github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs=
123119
github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4=
124120
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
125121
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
126-
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
127-
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
128122
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
129123
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
130124
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
@@ -245,3 +239,5 @@ gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
245239
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
246240
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
247241
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
242+
maragu.dev/gomponents v1.0.0 h1:eeLScjq4PqP1l+r5z/GC+xXZhLHXa6RWUWGW7gSfLh4=
243+
maragu.dev/gomponents v1.0.0/go.mod h1:oEDahza2gZoXDoDHhw8jBNgH+3UR5ni7Ur648HORydM=

pkg/handlers/auth.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/mikestefanello/pagoda/pkg/msg"
1616
"github.com/mikestefanello/pagoda/pkg/page"
1717
"github.com/mikestefanello/pagoda/pkg/redirect"
18+
"github.com/mikestefanello/pagoda/pkg/routenames"
1819
"github.com/mikestefanello/pagoda/pkg/services"
1920
"github.com/mikestefanello/pagoda/templates"
2021
)
@@ -226,7 +227,7 @@ func (h *Auth) LoginSubmit(ctx echo.Context) error {
226227
msg.Success(ctx, fmt.Sprintf("Welcome back, <strong>%s</strong>. You are now logged in.", u.Name))
227228

228229
return redirect.New(ctx).
229-
Route(routeNameHome).
230+
Route(routenames.Home).
230231
Go()
231232
}
232233

@@ -237,7 +238,7 @@ func (h *Auth) Logout(ctx echo.Context) error {
237238
msg.Danger(ctx, "An error occurred. Please try again.")
238239
}
239240
return redirect.New(ctx).
240-
Route(routeNameHome).
241+
Route(routenames.Home).
241242
Go()
242243
}
243244

@@ -312,7 +313,7 @@ func (h *Auth) RegisterSubmit(ctx echo.Context) error {
312313
h.sendVerificationEmail(ctx, u)
313314

314315
return redirect.New(ctx).
315-
Route(routeNameHome).
316+
Route(routenames.Home).
316317
Go()
317318
}
318319

@@ -410,7 +411,7 @@ func (h *Auth) VerifyEmail(ctx echo.Context) error {
410411
if err != nil {
411412
msg.Warning(ctx, "The link is either invalid or has expired.")
412413
return redirect.New(ctx).
413-
Route(routeNameHome).
414+
Route(routenames.Home).
414415
Go()
415416
}
416417

@@ -449,6 +450,6 @@ func (h *Auth) VerifyEmail(ctx echo.Context) error {
449450

450451
msg.Success(ctx, "Your email has been successfully verified.")
451452
return redirect.New(ctx).
452-
Route(routeNameHome).
453+
Route(routenames.Home).
453454
Go()
454455
}

pkg/handlers/contact.go

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,18 @@ package handlers
22

33
import (
44
"fmt"
5+
56
"github.com/go-playground/validator/v10"
67
"github.com/labstack/echo/v4"
78
"github.com/mikestefanello/pagoda/pkg/form"
8-
"github.com/mikestefanello/pagoda/pkg/page"
9+
"github.com/mikestefanello/pagoda/pkg/routenames"
910
"github.com/mikestefanello/pagoda/pkg/services"
10-
"github.com/mikestefanello/pagoda/templates"
11-
)
12-
13-
const (
14-
routeNameContact = "contact"
15-
routeNameContactSubmit = "contact.submit"
11+
"github.com/mikestefanello/pagoda/pkg/ui"
1612
)
1713

1814
type (
1915
Contact struct {
2016
mail *services.MailClient
21-
*services.TemplateRenderer
22-
}
23-
24-
contactForm struct {
25-
Email string `form:"email" validate:"required,email"`
26-
Department string `form:"department" validate:"required,oneof=sales marketing hr"`
27-
Message string `form:"message" validate:"required"`
28-
form.Submission
2917
}
3018
)
3119

@@ -34,28 +22,21 @@ func init() {
3422
}
3523

3624
func (h *Contact) Init(c *services.Container) error {
37-
h.TemplateRenderer = c.TemplateRenderer
3825
h.mail = c.Mail
3926
return nil
4027
}
4128

4229
func (h *Contact) Routes(g *echo.Group) {
43-
g.GET("/contact", h.Page).Name = routeNameContact
44-
g.POST("/contact", h.Submit).Name = routeNameContactSubmit
30+
g.GET("/contact", h.Page).Name = routenames.Contact
31+
g.POST("/contact", h.Submit).Name = routenames.ContactSubmit
4532
}
4633

4734
func (h *Contact) Page(ctx echo.Context) error {
48-
p := page.New(ctx)
49-
p.Layout = templates.LayoutMain
50-
p.Name = templates.PageContact
51-
p.Title = "Contact us"
52-
p.Form = form.Get[contactForm](ctx)
53-
54-
return h.RenderPage(ctx, p)
35+
return ui.ContactUs(ctx, form.Get[ui.ContactForm](ctx))
5536
}
5637

5738
func (h *Contact) Submit(ctx echo.Context) error {
58-
var input contactForm
39+
var input ui.ContactForm
5940

6041
err := form.Submit(ctx, &input)
6142

pkg/handlers/pages.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,21 @@ import (
66

77
"github.com/labstack/echo/v4"
88
"github.com/mikestefanello/pagoda/pkg/page"
9+
"github.com/mikestefanello/pagoda/pkg/routenames"
910
"github.com/mikestefanello/pagoda/pkg/services"
11+
"github.com/mikestefanello/pagoda/pkg/ui"
1012
"github.com/mikestefanello/pagoda/templates"
1113
)
1214

1315
const (
1416
routeNameAbout = "about"
15-
routeNameHome = "home"
1617
)
1718

1819
type (
1920
Pages struct {
2021
*services.TemplateRenderer
2122
}
2223

23-
post struct {
24-
Title string
25-
Body string
26-
}
27-
2824
aboutData struct {
2925
ShowCacheWarning bool
3026
FrontendTabs []aboutTab
@@ -47,11 +43,12 @@ func (h *Pages) Init(c *services.Container) error {
4743
}
4844

4945
func (h *Pages) Routes(g *echo.Group) {
50-
g.GET("/", h.Home).Name = routeNameHome
46+
g.GET("/", h.Home).Name = routenames.Home
47+
g.GET("/oldhome", h.HomeOld).Name = "oldhome"
5148
g.GET("/about", h.About).Name = routeNameAbout
5249
}
5350

54-
func (h *Pages) Home(ctx echo.Context) error {
51+
func (h *Pages) HomeOld(ctx echo.Context) error {
5552
p := page.New(ctx)
5653
p.Layout = templates.LayoutMain
5754
p.Name = templates.PageHome
@@ -63,13 +60,23 @@ func (h *Pages) Home(ctx echo.Context) error {
6360
return h.RenderPage(ctx, p)
6461
}
6562

63+
func (h *Pages) Home(ctx echo.Context) error {
64+
pgr := page.NewPager(ctx, 4)
65+
p := h.fetchPosts(&pgr)
66+
67+
return ui.Home(ctx, ui.Posts{
68+
Posts: p,
69+
Pager: pgr,
70+
})
71+
}
72+
6673
// fetchPosts is an mock example of fetching posts to illustrate how paging works
67-
func (h *Pages) fetchPosts(pager *page.Pager) []post {
74+
func (h *Pages) fetchPosts(pager *page.Pager) []ui.Post {
6875
pager.SetItems(20)
69-
posts := make([]post, 20)
76+
posts := make([]ui.Post, 20)
7077

7178
for k := range posts {
72-
posts[k] = post{
79+
posts[k] = ui.Post{
7380
Title: fmt.Sprintf("Post example #%d", k+1),
7481
Body: fmt.Sprintf("Lorem ipsum example #%d ddolor sit amet, consectetur adipiscing elit. Nam elementum vulputate tristique.", k+1),
7582
}

pkg/ui/cache.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package ui

0 commit comments

Comments
 (0)