diff --git a/pkg/handlers/auth.go b/pkg/handlers/auth.go index 517ed73..7109e32 100644 --- a/pkg/handlers/auth.go +++ b/pkg/handlers/auth.go @@ -5,6 +5,7 @@ import ( "fmt" "strings" + "github.com/a-h/templ" "github.com/go-playground/validator/v10" "github.com/labstack/echo/v4" @@ -17,6 +18,8 @@ import ( "git.grosinger.net/tgrosinger/saasitone/pkg/page" "git.grosinger.net/tgrosinger/saasitone/pkg/redirect" "git.grosinger.net/tgrosinger/saasitone/pkg/services" + "git.grosinger.net/tgrosinger/saasitone/templ/layouts" + "git.grosinger.net/tgrosinger/saasitone/templ/pages" "git.grosinger.net/tgrosinger/saasitone/templates" ) @@ -40,31 +43,6 @@ type ( db *services.DBClient *services.TemplateRenderer } - - forgotPasswordForm struct { - Email string `form:"email" validate:"required,email"` - form.Submission - } - - loginForm struct { - Email string `form:"email" validate:"required,email"` - Password string `form:"password" validate:"required"` - form.Submission - } - - registerForm struct { - Name string `form:"name" validate:"required"` - Email string `form:"email" validate:"required,email"` - Password string `form:"password" validate:"required"` - ConfirmPassword string `form:"password-confirm" validate:"required,eqfield=Password"` - form.Submission - } - - resetPasswordForm struct { - Password string `form:"password" validate:"required"` - ConfirmPassword string `form:"password-confirm" validate:"required,eqfield=Password"` - form.Submission - } ) func init() { @@ -101,16 +79,22 @@ func (h *Auth) Routes(g *echo.Group) { func (h *Auth) ForgotPasswordPage(ctx echo.Context) error { p := page.New(ctx) - p.Layout = templates.LayoutAuth p.Name = templates.PageForgotPassword p.Title = "Forgot password" - p.Form = form.Get[forgotPasswordForm](ctx) - return h.RenderPage(ctx, p) + f := form.Get[pages.ForgotPasswordForm](ctx) + component := pages.ForgotPassword(p, f) + + // TODO: This can be reused + p.LayoutComponent = func(content templ.Component) templ.Component { + return layouts.Auth(p, content) + } + + return h.RenderPageTempl(ctx, p, component) } func (h *Auth) ForgotPasswordSubmit(ctx echo.Context) error { - var input forgotPasswordForm + var input pages.ForgotPasswordForm succeed := func() error { form.Clear(ctx) @@ -163,16 +147,22 @@ func (h *Auth) ForgotPasswordSubmit(ctx echo.Context) error { func (h *Auth) LoginPage(ctx echo.Context) error { p := page.New(ctx) - p.Layout = templates.LayoutAuth p.Name = templates.PageLogin p.Title = "Log in" - p.Form = form.Get[loginForm](ctx) - return h.RenderPage(ctx, p) + f := form.Get[pages.LoginForm](ctx) + component := pages.Login(p, f) + + // TODO: This can be reused + p.LayoutComponent = func(content templ.Component) templ.Component { + return layouts.Auth(p, content) + } + + return h.RenderPageTempl(ctx, p, component) } func (h *Auth) LoginSubmit(ctx echo.Context) error { - var input loginForm + var input pages.LoginForm authFailed := func() error { input.SetFieldError("Email", "") @@ -231,16 +221,22 @@ func (h *Auth) Logout(ctx echo.Context) error { func (h *Auth) RegisterPage(ctx echo.Context) error { p := page.New(ctx) - p.Layout = templates.LayoutAuth p.Name = templates.PageRegister p.Title = "Register" - p.Form = form.Get[registerForm](ctx) - return h.RenderPage(ctx, p) + f := form.Get[pages.RegisterForm](ctx) + component := pages.Register(p, f) + + // TODO: This can be reused + p.LayoutComponent = func(content templ.Component) templ.Component { + return layouts.Auth(p, content) + } + + return h.RenderPageTempl(ctx, p, component) } func (h *Auth) RegisterSubmit(ctx echo.Context) error { - var input registerForm + var input pages.RegisterForm err := form.Submit(ctx, &input) @@ -335,16 +331,22 @@ func (h *Auth) sendVerificationEmail(ctx echo.Context, usr sqlc.User) { func (h *Auth) ResetPasswordPage(ctx echo.Context) error { p := page.New(ctx) - p.Layout = templates.LayoutAuth p.Name = templates.PageResetPassword p.Title = "Reset password" - p.Form = form.Get[resetPasswordForm](ctx) - return h.RenderPage(ctx, p) + f := form.Get[pages.ResetPasswordForm](ctx) + component := pages.ResetPassword(p, f) + + // TODO: This can be reused + p.LayoutComponent = func(content templ.Component) templ.Component { + return layouts.Auth(p, content) + } + + return h.RenderPageTempl(ctx, p, component) } func (h *Auth) ResetPasswordSubmit(ctx echo.Context) error { - var input resetPasswordForm + var input pages.ResetPasswordForm err := form.Submit(ctx, &input) diff --git a/pkg/handlers/pages.go b/pkg/handlers/pages.go index ebe00c5..bfade70 100644 --- a/pkg/handlers/pages.go +++ b/pkg/handlers/pages.go @@ -3,10 +3,12 @@ package handlers import ( "html/template" + "github.com/a-h/templ" "github.com/labstack/echo/v4" "git.grosinger.net/tgrosinger/saasitone/pkg/page" "git.grosinger.net/tgrosinger/saasitone/pkg/services" + "git.grosinger.net/tgrosinger/saasitone/templ/layouts" "git.grosinger.net/tgrosinger/saasitone/templ/pages" "git.grosinger.net/tgrosinger/saasitone/templates" ) @@ -51,7 +53,6 @@ func (h *Pages) Routes(g *echo.Group) { func (h *Pages) Home(ctx echo.Context) error { p := page.New(ctx) - p.Layout = templates.LayoutMain p.Name = templates.PageHome p.Metatags.Description = "Welcome to the homepage." p.Metatags.Keywords = []string{"Go", "MVC", "Web", "Software"} @@ -60,6 +61,11 @@ func (h *Pages) Home(ctx echo.Context) error { data := h.Post.FetchAll(&p.Pager) component := pages.Home(p, data) + // TODO: This can be reused + p.LayoutComponent = func(content templ.Component) templ.Component { + return layouts.Main(p, content) + } + return h.RenderPageTempl(ctx, p, component) } diff --git a/pkg/page/page.go b/pkg/page/page.go index 9826c24..4f0c755 100644 --- a/pkg/page/page.go +++ b/pkg/page/page.go @@ -4,6 +4,7 @@ import ( "net/http" "time" + "github.com/a-h/templ" "github.com/labstack/echo/v4" echomw "github.com/labstack/echo/v4/middleware" @@ -56,6 +57,8 @@ type Page struct { // The template extension should not be included in this value. Layout templates.Layout + LayoutComponent func(content templ.Component) templ.Component + // Name stores the name of the page as well as the name of the template file which will be used to render // the content portion of the layout template. // This should match a template file located within the pages directory inside the templates directory. diff --git a/pkg/services/template_renderer.go b/pkg/services/template_renderer.go index 796cab3..b5e518a 100644 --- a/pkg/services/template_renderer.go +++ b/pkg/services/template_renderer.go @@ -16,7 +16,6 @@ import ( "git.grosinger.net/tgrosinger/saasitone/pkg/context" "git.grosinger.net/tgrosinger/saasitone/pkg/log" "git.grosinger.net/tgrosinger/saasitone/pkg/page" - "git.grosinger.net/tgrosinger/saasitone/templ/layouts" "git.grosinger.net/tgrosinger/saasitone/templates" ) @@ -116,7 +115,7 @@ func (t *TemplateRenderer) RenderPageTempl(ctx echo.Context, page page.Page, con // Only partial content should be rendered. err = content.Render(ctx.Request().Context(), &buf) } else { - err = layouts.Main(page, content).Render(ctx.Request().Context(), &buf) + err = page.LayoutComponent(content).Render(ctx.Request().Context(), &buf) } if err != nil { return echo.NewHTTPError( diff --git a/templ/components/forms.templ b/templ/components/forms.templ new file mode 100644 index 0000000..9ca7e24 --- /dev/null +++ b/templ/components/forms.templ @@ -0,0 +1,11 @@ +package components + +templ CSRF(csrf string) { + +} + +templ FieldErrors(errors []string) { + for _, err := range errors { +

{ err }

+ } +} diff --git a/templ/components/forms_templ.go b/templ/components/forms_templ.go new file mode 100644 index 0000000..cb2e0c5 --- /dev/null +++ b/templ/components/forms_templ.go @@ -0,0 +1,87 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.707 +package components + +//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 CSRF(csrf 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_Err = templ_7745c5c3_Buffer.WriteString("") + 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 + }) +} + +func FieldErrors(errors []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_Var3 := templ.GetChildren(ctx) + if templ_7745c5c3_Var3 == nil { + templ_7745c5c3_Var3 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + for _, err := range errors { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(err) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templ/components/forms.templ`, Line: 9, Col: 33} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + 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 + } + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) + } + return templ_7745c5c3_Err + }) +} diff --git a/templ/layouts/auth.templ b/templ/layouts/auth.templ new file mode 100644 index 0000000..a6f93fa --- /dev/null +++ b/templ/layouts/auth.templ @@ -0,0 +1,42 @@ +package layouts + +import ( + "git.grosinger.net/tgrosinger/saasitone/pkg/page" + "git.grosinger.net/tgrosinger/saasitone/templ/components" +) + +templ Auth(p page.Page, content templ.Component) { + + + + @metatags(p) + @css() + @js() + + +
+
+
+
+
+ if p.Title != "" { +

{ p.Title }

+ } +
+ @components.Messages(p) + @content + +
+
+
+
+
+
+ @footer(p) + + +} diff --git a/templ/layouts/auth_templ.go b/templ/layouts/auth_templ.go new file mode 100644 index 0000000..897172f --- /dev/null +++ b/templ/layouts/auth_templ.go @@ -0,0 +1,126 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.707 +package layouts + +//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 ( + "git.grosinger.net/tgrosinger/saasitone/pkg/page" + "git.grosinger.net/tgrosinger/saasitone/templ/components" +) + +func Auth(p page.Page, content templ.Component) 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("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = metatags(p).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = css().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = js().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 + } + if p.Title != "" { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(p.Title) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templ/layouts/auth.templ`, Line: 23, Col: 36} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + 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 + } + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = components.Messages(p).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = content.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 + } + templ_7745c5c3_Err = footer(p).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 + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) + } + return templ_7745c5c3_Err + }) +} diff --git a/templ/pages/forgot-password.templ b/templ/pages/forgot-password.templ new file mode 100644 index 0000000..d17d091 --- /dev/null +++ b/templ/pages/forgot-password.templ @@ -0,0 +1,36 @@ +package pages + +import ( + "git.grosinger.net/tgrosinger/saasitone/templ/components" + "git.grosinger.net/tgrosinger/saasitone/pkg/form" + "git.grosinger.net/tgrosinger/saasitone/pkg/page" +) + +type ForgotPasswordForm struct { + Email string `form:"email" validate:"required,email"` + form.Submission +} + +templ ForgotPassword(p page.Page, f *ForgotPasswordForm) { +
+
+

Enter your email address and we'll email you a link that allows you to reset your password.

+
+
+ +
+ + @components.FieldErrors(f.Submission.GetFieldErrors("Email")) +
+
+
+

+ +

+

+ Cancel +

+
+ @components.CSRF(p.CSRF) +
+} diff --git a/templ/pages/forgot-password_templ.go b/templ/pages/forgot-password_templ.go new file mode 100644 index 0000000..128cbd1 --- /dev/null +++ b/templ/pages/forgot-password_templ.go @@ -0,0 +1,115 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.707 +package pages + +//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 ( + "git.grosinger.net/tgrosinger/saasitone/pkg/form" + "git.grosinger.net/tgrosinger/saasitone/pkg/page" + "git.grosinger.net/tgrosinger/saasitone/templ/components" +) + +type ForgotPasswordForm struct { + Email string `form:"email" validate:"required,email"` + form.Submission +} + +func ForgotPassword(p page.Page, f *ForgotPasswordForm) 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("

Enter your email address and we'll email you a link that allows you to reset your password.

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 = []any{"input", f.Submission.GetFieldStatusClass("Email")} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var3...) + 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 + } + templ_7745c5c3_Err = components.FieldErrors(f.Submission.GetFieldErrors("Email")).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Cancel

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = components.CSRF(p.CSRF).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 + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) + } + return templ_7745c5c3_Err + }) +} diff --git a/templ/pages/home_templ.go b/templ/pages/home_templ.go index e1519d1..6e95148 100644 --- a/templ/pages/home_templ.go +++ b/templ/pages/home_templ.go @@ -133,7 +133,7 @@ func Home(p page.Page, posts []services.Post) templ.Component { return templ_7745c5c3_Err } if p.HTMX.Request.Target != "posts" { - templ_7745c5c3_Err = fileMsg(p).Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = fileMsg().Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -208,7 +208,7 @@ func topContent(p page.Page) templ.Component { }) } -func fileMsg(p page.Page) templ.Component { +func fileMsg() 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 { diff --git a/templ/pages/login.templ b/templ/pages/login.templ new file mode 100644 index 0000000..2cf31b2 --- /dev/null +++ b/templ/pages/login.templ @@ -0,0 +1,42 @@ +package pages + +import ( + "git.grosinger.net/tgrosinger/saasitone/templ/components" + "git.grosinger.net/tgrosinger/saasitone/pkg/form" + "git.grosinger.net/tgrosinger/saasitone/pkg/page" +) + +type LoginForm struct { + Email string `form:"email" validate:"required,email"` + Password string `form:"password" validate:"required"` + form.Submission +} + +templ Login(p page.Page, f *LoginForm) { +
+ @components.Messages(p) +
+ +
+ + @components.FieldErrors(f.Submission.GetFieldErrors("Email")) +
+
+
+ +
+ + @components.FieldErrors(f.Submission.GetFieldErrors("Password")) +
+
+
+

+ +

+

+ Cancel +

+
+ @components.CSRF(p.CSRF) +
+} diff --git a/templ/pages/login_templ.go b/templ/pages/login_templ.go new file mode 100644 index 0000000..7d0de53 --- /dev/null +++ b/templ/pages/login_templ.go @@ -0,0 +1,154 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.707 +package pages + +//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 ( + "git.grosinger.net/tgrosinger/saasitone/pkg/form" + "git.grosinger.net/tgrosinger/saasitone/pkg/page" + "git.grosinger.net/tgrosinger/saasitone/templ/components" +) + +type LoginForm struct { + Email string `form:"email" validate:"required,email"` + Password string `form:"password" validate:"required"` + form.Submission +} + +func Login(p page.Page, f *LoginForm) 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("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = components.Messages(p).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 + } + var templ_7745c5c3_Var3 = []any{"input", f.Submission.GetFieldStatusClass("Email")} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var3...) + 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 + } + templ_7745c5c3_Err = components.FieldErrors(f.Submission.GetFieldErrors("Email")).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 + } + var templ_7745c5c3_Var6 = []any{"input", f.Submission.GetFieldStatusClass("Password")} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...) + 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 + } + templ_7745c5c3_Err = components.FieldErrors(f.Submission.GetFieldErrors("Password")).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Cancel

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = components.CSRF(p.CSRF).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 + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) + } + return templ_7745c5c3_Err + }) +} diff --git a/templ/pages/register.templ b/templ/pages/register.templ new file mode 100644 index 0000000..9ab8c8b --- /dev/null +++ b/templ/pages/register.templ @@ -0,0 +1,57 @@ +package pages + +import ( + "git.grosinger.net/tgrosinger/saasitone/templ/components" + "git.grosinger.net/tgrosinger/saasitone/pkg/form" + "git.grosinger.net/tgrosinger/saasitone/pkg/page" +) + +type RegisterForm struct { + Name string `form:"name" validate:"required"` + Email string `form:"email" validate:"required,email"` + Password string `form:"password" validate:"required"` + ConfirmPassword string `form:"password-confirm" validate:"required,eqfield=Password"` + form.Submission +} + +templ Register(p page.Page, f *RegisterForm) { +
+
+ +
+ + @components.FieldErrors(f.Submission.GetFieldErrors("Name")) +
+
+
+ +
+ + @components.FieldErrors(f.Submission.GetFieldErrors("Email")) +
+
+
+ +
+ + @components.FieldErrors(f.Submission.GetFieldErrors("Password")) +
+
+
+ +
+ + @components.FieldErrors(f.Submission.GetFieldErrors("ConfigmPassword")) +
+
+
+

+ +

+

+ Cancel +

+
+ @components.CSRF(p.CSRF) +
+} diff --git a/templ/pages/register_templ.go b/templ/pages/register_templ.go new file mode 100644 index 0000000..ae09605 --- /dev/null +++ b/templ/pages/register_templ.go @@ -0,0 +1,221 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.707 +package pages + +//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 ( + "git.grosinger.net/tgrosinger/saasitone/pkg/form" + "git.grosinger.net/tgrosinger/saasitone/pkg/page" + "git.grosinger.net/tgrosinger/saasitone/templ/components" +) + +type RegisterForm struct { + Name string `form:"name" validate:"required"` + Email string `form:"email" validate:"required,email"` + Password string `form:"password" validate:"required"` + ConfirmPassword string `form:"password-confirm" validate:"required,eqfield=Password"` + form.Submission +} + +func Register(p page.Page, f *RegisterForm) 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("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 = []any{"input", f.Submission.GetFieldStatusClass("Name")} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var3...) + 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 + } + templ_7745c5c3_Err = components.FieldErrors(f.Submission.GetFieldErrors("Name")).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 + } + var templ_7745c5c3_Var6 = []any{"input", f.Submission.GetFieldStatusClass("Email")} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...) + 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 + } + templ_7745c5c3_Err = components.FieldErrors(f.Submission.GetFieldErrors("Email")).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 + } + var templ_7745c5c3_Var9 = []any{"input", f.Submission.GetFieldStatusClass("Password")} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...) + 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 + } + templ_7745c5c3_Err = components.FieldErrors(f.Submission.GetFieldErrors("Password")).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 + } + var templ_7745c5c3_Var11 = []any{"input", f.Submission.GetFieldStatusClass("ConfigmPassword")} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var11...) + 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 + } + templ_7745c5c3_Err = components.FieldErrors(f.Submission.GetFieldErrors("ConfigmPassword")).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Cancel

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = components.CSRF(p.CSRF).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 + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) + } + return templ_7745c5c3_Err + }) +} diff --git a/templ/pages/reset-password.templ b/templ/pages/reset-password.templ new file mode 100644 index 0000000..62407c6 --- /dev/null +++ b/templ/pages/reset-password.templ @@ -0,0 +1,38 @@ +package pages + +import ( + "git.grosinger.net/tgrosinger/saasitone/templ/components" + "git.grosinger.net/tgrosinger/saasitone/pkg/form" + "git.grosinger.net/tgrosinger/saasitone/pkg/page" +) + +type ResetPasswordForm struct { + Password string `form:"password" validate:"required"` + ConfirmPassword string `form:"password-confirm" validate:"required,eqfield=Password"` + form.Submission +} + +templ ResetPassword(p page.Page, f *ResetPasswordForm) { +
+
+ +
+ + @components.FieldErrors(f.Submission.GetFieldErrors("Password")) +
+
+
+ +
+ + @components.FieldErrors(f.Submission.GetFieldErrors("ConfigmPassword")) +
+
+
+

+ +

+
+ @components.CSRF(p.CSRF) +
+} diff --git a/templ/pages/reset-password_templ.go b/templ/pages/reset-password_templ.go new file mode 100644 index 0000000..8f81b39 --- /dev/null +++ b/templ/pages/reset-password_templ.go @@ -0,0 +1,124 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.707 +package pages + +//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 ( + "git.grosinger.net/tgrosinger/saasitone/pkg/form" + "git.grosinger.net/tgrosinger/saasitone/pkg/page" + "git.grosinger.net/tgrosinger/saasitone/templ/components" +) + +type ResetPasswordForm struct { + Password string `form:"password" validate:"required"` + ConfirmPassword string `form:"password-confirm" validate:"required,eqfield=Password"` + form.Submission +} + +func ResetPassword(p page.Page, f *ResetPasswordForm) 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("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 = []any{"input", f.Submission.GetFieldStatusClass("Password")} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var3...) + 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 + } + templ_7745c5c3_Err = components.FieldErrors(f.Submission.GetFieldErrors("Password")).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 + } + var templ_7745c5c3_Var5 = []any{"input", f.Submission.GetFieldStatusClass("ConfirmPassword")} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var5...) + 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 + } + templ_7745c5c3_Err = components.FieldErrors(f.Submission.GetFieldErrors("ConfigmPassword")).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 + } + templ_7745c5c3_Err = components.CSRF(p.CSRF).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 + } + if !templ_7745c5c3_IsBuffer { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) + } + return templ_7745c5c3_Err + }) +} diff --git a/templates/pages/forgot-password.gohtml b/templates/pages/forgot-password.gohtml deleted file mode 100644 index b058962..0000000 --- a/templates/pages/forgot-password.gohtml +++ /dev/null @@ -1,23 +0,0 @@ -{{define "content"}} -
-
-

Enter your email address and we'll email you a link that allows you to reset your password.

-
-
- -
- - {{template "field-errors" (.Form.Submission.GetFieldErrors "Email")}} -
-
-
-

- -

-

- Cancel -

-
- {{template "csrf" .}} -
-{{end}} \ No newline at end of file diff --git a/templates/pages/login.gohtml b/templates/pages/login.gohtml deleted file mode 100644 index a2613bc..0000000 --- a/templates/pages/login.gohtml +++ /dev/null @@ -1,28 +0,0 @@ -{{define "content"}} -
- {{template "messages" .}} -
- -
- - {{template "field-errors" (.Form.Submission.GetFieldErrors "Email")}} -
-
-
- -
- - {{template "field-errors" (.Form.Submission.GetFieldErrors "Password")}} -
-
-
-

- -

-

- Cancel -

-
- {{template "csrf" .}} -
-{{end}} \ No newline at end of file diff --git a/templates/pages/register.gohtml b/templates/pages/register.gohtml deleted file mode 100644 index e55781f..0000000 --- a/templates/pages/register.gohtml +++ /dev/null @@ -1,41 +0,0 @@ -{{define "content"}} -
-
- -
- - {{template "field-errors" (.Form.GetFieldErrors "Name")}} -
-
-
- -
- - {{template "field-errors" (.Form.GetFieldErrors "Email")}} -
-
-
- -
- - {{template "field-errors" (.Form.GetFieldErrors "Password")}} -
-
-
- -
- - {{template "field-errors" (.Form.GetFieldErrors "ConfirmPassword")}} -
-
-
-

- -

-

- Cancel -

-
- {{template "csrf" .}} -
-{{end}} \ No newline at end of file diff --git a/templates/pages/reset-password.gohtml b/templates/pages/reset-password.gohtml deleted file mode 100644 index 5444514..0000000 --- a/templates/pages/reset-password.gohtml +++ /dev/null @@ -1,24 +0,0 @@ -{{define "content"}} -
-
- -
- - {{template "field-errors" (.Form.GetFieldErrors "Password")}} -
-
-
- -
- - {{template "field-errors" (.Form.GetFieldErrors "ConfirmPassword")}} -
-
-
-

- -

-
- {{template "csrf" .}} -
-{{end}} \ No newline at end of file diff --git a/templates/templates.go b/templates/templates.go index 1986422..239d489 100644 --- a/templates/templates.go +++ b/templates/templates.go @@ -16,7 +16,6 @@ type ( const ( LayoutMain Layout = "main" - LayoutAuth Layout = "auth" LayoutHTMX Layout = "htmx" )