From de0d448b88a6899dc0d1eb265e2af4cb03a6789d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Eduardo=20Jer=C3=A9z=20Gir=C3=B3n?= Date: Mon, 22 Jul 2024 20:47:14 -0600 Subject: [PATCH] Add first user creation process --- internal/view/web/auth/create_first_user.go | 129 +++++++++++++------- internal/view/web/auth/router.go | 4 +- 2 files changed, 91 insertions(+), 42 deletions(-) diff --git a/internal/view/web/auth/create_first_user.go b/internal/view/web/auth/create_first_user.go index d3833f3..622af90 100644 --- a/internal/view/web/auth/create_first_user.go +++ b/internal/view/web/auth/create_first_user.go @@ -4,8 +4,11 @@ import ( "net/http" lucide "github.com/eduardolat/gomponents-lucide" + "github.com/eduardolat/pgbackweb/internal/database/dbgen" "github.com/eduardolat/pgbackweb/internal/util/echoutil" + "github.com/eduardolat/pgbackweb/internal/validate" "github.com/eduardolat/pgbackweb/internal/view/web/component" + "github.com/eduardolat/pgbackweb/internal/view/web/htmx" "github.com/eduardolat/pgbackweb/internal/view/web/layout" "github.com/labstack/echo/v4" "github.com/maragudk/gomponents" @@ -21,50 +24,64 @@ func createFirstUserPage() gomponents.Node { component.H1Text("Create first user"), html.Form( + htmx.HxPost("/auth/create-first-user"), + htmx.HxDisabledELT("find button"), html.Class("mt-4 space-y-2"), - component.InputControl(component.InputControlParams{ - Name: "name", - Label: "Full name", - Placeholder: "John Doe", - Required: true, - Type: component.InputTypeText, - AutoComplete: "name", - }), - - component.InputControl(component.InputControlParams{ - Name: "email", - Label: "Email", - Placeholder: "john@example.com", - Required: true, - Type: component.InputTypeEmail, - AutoComplete: "email", - }), - - component.InputControl(component.InputControlParams{ - Name: "password", - Label: "Password", - Placeholder: "******", - Required: true, - Type: component.InputTypePassword, - AutoComplete: "new-password", - }), - - component.InputControl(component.InputControlParams{ - Name: "password_confirmation", - Label: "Confirm password", - Placeholder: "******", - Required: true, - Type: component.InputTypePassword, - }), - html.Div( - html.Class("pt-2 grid place-items-end"), - html.Button( - html.Class("btn btn-primary"), - html.Type("submit"), - component.SpanText("Create user and continue"), - lucide.UserPlus(), + component.InputControl(component.InputControlParams{ + Name: "name", + Label: "Full name", + Placeholder: "John Doe", + Required: true, + Type: component.InputTypeText, + AutoComplete: "name", + }), + + component.InputControl(component.InputControlParams{ + Name: "email", + Label: "Email", + Placeholder: "john@example.com", + Required: true, + Type: component.InputTypeEmail, + AutoComplete: "email", + }), + + component.InputControl(component.InputControlParams{ + Name: "password", + Label: "Password", + Placeholder: "******", + Required: true, + Type: component.InputTypePassword, + AutoComplete: "new-password", + Children: []gomponents.Node{ + html.MinLength("6"), + html.MaxLength("50"), + }, + }), + + component.InputControl(component.InputControlParams{ + Name: "password_confirmation", + Label: "Confirm password", + Placeholder: "******", + Required: true, + Type: component.InputTypePassword, + Children: []gomponents.Node{ + html.MinLength("6"), + html.MaxLength("50"), + }, + }), + + html.Div( + html.Class("pt-2 flex justify-end items-center space-x-2"), + component.HxLoadingMd(), + html.Button( + html.ID("create-first-user-button"), + html.Class("btn btn-primary"), + html.Type("submit"), + component.SpanText("Create user and continue"), + lucide.UserPlus(), + ), ), ), ), @@ -75,3 +92,33 @@ func createFirstUserPage() gomponents.Node { Body: content, }) } + +func (h *handlers) createFirstUserHandler(c echo.Context) error { + ctx := c.Request().Context() + + var formData struct { + Name string `form:"name" validate:"required"` + Email string `form:"email" validate:"required,email"` + Password string `form:"password" validate:"required,min=6,max=50"` + PasswordConfirmation string `form:"password_confirmation" validate:"required,eqfield=Password"` + } + if err := c.Bind(&formData); err != nil { + return htmx.RespondToastError(c, err.Error()) + } + if err := validate.Struct(&formData); err != nil { + return htmx.RespondToastError(c, err.Error()) + } + + _, err := h.servs.UsersService.CreateUser(ctx, dbgen.UsersServiceCreateUserParams{ + Name: formData.Name, + Email: formData.Email, + Password: formData.Password, + }) + if err != nil { + return htmx.RespondToastError(c, err.Error()) + } + + return htmx.RespondAlertWithRedirect( + c, "User created successfully", "/auth/login", + ) +} diff --git a/internal/view/web/auth/router.go b/internal/view/web/auth/router.go index aae8ae3..8bd0680 100644 --- a/internal/view/web/auth/router.go +++ b/internal/view/web/auth/router.go @@ -12,6 +12,8 @@ type handlers struct { func MountRouter(parent *echo.Group, servs *service.Service) { h := handlers{servs: servs} - parent.GET("/login", h.loginPageHandler) parent.GET("/create-first-user", h.createFirstUserPageHandler) + parent.POST("/create-first-user", h.createFirstUserHandler) + + parent.GET("/login", h.loginPageHandler) }