From 7c9e032f76ac59ffd407285e22682580223fef97 Mon Sep 17 00:00:00 2001 From: "kacaii.dev" Date: Wed, 17 Jun 2026 10:22:11 -0300 Subject: [PATCH] page/signup: add signup page --- src/client.gleam | 32 ++++++++++++---- src/client/page.gleam | 3 ++ src/client/page/login.gleam | 19 ++++++---- src/client/page/signup.gleam | 72 ++++++++++++++++++++++++++++++++++++ src/client/route.gleam | 6 ++- 5 files changed, 116 insertions(+), 16 deletions(-) create mode 100644 src/client/page/signup.gleam diff --git a/src/client.gleam b/src/client.gleam index 52c797c..8e890c3 100644 --- a/src/client.gleam +++ b/src/client.gleam @@ -6,6 +6,7 @@ import client/page/login import client/page/navbar import client/page/not_found import client/page/sidebar +import client/page/signup import client/route import client/session import gleam/bool @@ -62,14 +63,15 @@ pub type Message { ) // PAGES --- - LoginMessage(msg: login.Message) - HomeMessage(msg: home.Message) - DashboardMessage(msg: dashboard.Message) + LoginMessage(message: login.Message) + HomeMessage(message: home.Message) + DashboardMessage(message: dashboard.Message) // UI Elements - SidebarMessage(msg: sidebar.Message) - NavbarMessage(msg: navbar.Message) - NotFoundMessage(msg: not_found.Message) + SidebarMessage(message: sidebar.Message) + NavbarMessage(message: navbar.Message) + NotFoundMessage(message: not_found.Message) + SignupMessage(message: signup.Message) } // INIT ------------------------------------------------------------------------ @@ -157,6 +159,9 @@ pub fn view(model: Model) -> Element(Message) { Model(route: route.Dashboard, page: page.Dashboard(page), ..) -> layout(model, dashboard.view(model.session, page), DashboardMessage) + Model(route: route.Signup, page: page.Signup(page), ..) -> + layout(model, signup.view(page, model.lang), SignupMessage) + _ -> layout(model, not_found.view(), NotFoundMessage) } } @@ -170,7 +175,7 @@ pub fn update(model: Model, message: Message) -> #(Model, Effect(Message)) { model, UserNavigatedTo(route:) -> handle_navigation(model, route) //  LANGUAGE SELECTION - model, NavbarMessage(msg: navbar.UserSelectedLanguage(lang:)) -> #( + model, NavbarMessage(message: navbar.UserSelectedLanguage(lang:)) -> #( Model(..model, lang:), effect.none(), ) @@ -215,12 +220,25 @@ pub fn update(model: Model, message: Message) -> #(Model, Effect(Message)) { LoginMessage(page_message) -> handle_login_step(model, page, page_message) + Model(route: route.Signup, page: page.Signup(page), ..), + SignupMessage(page_message) + -> handle_signup_message(model, page, page_message) + // FALLBACK // _, _ -> #(model, effect.none()) } } +fn handle_signup_message( + model: Model, + _page: signup.Model, + _page_message: signup.Message, +) -> #(Model, Effect(Message)) { + // TODO: handle message + #(model, effect.none()) +} + fn handle_navigation( model: Model, route: route.Route, diff --git a/src/client/page.gleam b/src/client/page.gleam index 9014c19..a68a40e 100644 --- a/src/client/page.gleam +++ b/src/client/page.gleam @@ -2,6 +2,7 @@ import client/page/dashboard import client/page/home import client/page/login import client/page/not_found +import client/page/signup import client/route import lustre/effect.{type Effect} @@ -10,6 +11,7 @@ pub type Page { Home(model: home.Model) Login(model: login.Model) NotFound(model: not_found.Model) + Signup(model: signup.Model) } /// Initialize the current page Model @@ -28,6 +30,7 @@ pub fn init(route: route.Route) -> #(Page, Effect(_)) { route.Login -> do_init(login.init, Login) route.Dashboard -> do_init(dashboard.init, Dashboard) route.NotFound -> do_init(not_found.init, NotFound) + route.Signup -> do_init(signup.init, Signup) } } diff --git a/src/client/page/login.gleam b/src/client/page/login.gleam index 9415741..89e8506 100644 --- a/src/client/page/login.gleam +++ b/src/client/page/login.gleam @@ -185,14 +185,17 @@ pub fn view(model: Model, lang: lang.Language) -> Element(Message) { lang.Spanish -> "¿Eres nuevo aquí?" }), ]), - html.a([attr.href("#"), class("font-bold text-emerald-500")], [ - html.text(case lang { - lang.BrazillianPortuguese | lang.Portuguese -> "Crie sua conta" - lang.English -> "Signup" - lang.German -> "Erstellen Sie Ihr Konto" - lang.Spanish -> "Crea tu cuenta" - }), - ]), + html.a( + [route.href(route.Signup), class("font-bold text-emerald-500")], + [ + html.text(case lang { + lang.BrazillianPortuguese | lang.Portuguese -> "Crie sua conta" + lang.English -> "Signup" + lang.German -> "Erstellen Sie Ihr Konto" + lang.Spanish -> "Crea tu cuenta" + }), + ], + ), ]), ]), diff --git a/src/client/page/signup.gleam b/src/client/page/signup.gleam new file mode 100644 index 0000000..cc32252 --- /dev/null +++ b/src/client/page/signup.gleam @@ -0,0 +1,72 @@ +import client/language as lang +import client/route +import lustre/attribute.{class} as attr +import lustre/effect.{type Effect} +import lustre/element.{type Element} +import lustre/element/html + +pub type Model { + Model +} + +pub type Message + +pub fn init() -> #(Model, Effect(_)) { + #(Model, effect.none()) +} + +pub fn update(_model: Model, _msg: Message) { + todo +} + +pub fn view(_model: Model, lang: lang.Language) -> Element(Message) { + let wrapper_attributes = [ + class("p-4 mx-auto max-w-lg h-full"), + class("flex flex-col gap-4 justify-center items-center"), + ] + + html.div(wrapper_attributes, [ + html.article([class("w-full rounded-xl card @container")], [ + html.header([class("hidden mb-4 md:block")], [ + html.h2([class("my-2 text-2xl font-bold")], [ + html.text(case lang { + lang.BrazillianPortuguese | lang.Portuguese -> "Criar conta" + // TODO: + lang.German -> "todo" + lang.English -> "Create account" + // TODO: + lang.Spanish -> "todo" + }), + ]), + + html.div([class("gap-2 hstack")], [ + html.p([class("text-subtext")], [ + html.text(case lang { + lang.BrazillianPortuguese | lang.Portuguese -> "Ja tem conta?" + lang.English -> "Already have an account?" + // TODO: + lang.German -> "todo" + // TODO: + lang.Spanish -> "todo" + }), + ]), + html.a( + [route.href(route.Login), class("font-bold text-emerald-500")], + [ + html.text(case lang { + lang.BrazillianPortuguese | lang.Portuguese -> "Entrar" + lang.English -> "Login" + // TODO: + lang.German -> "todo" + // TODO: + lang.Spanish -> "todo" + }), + ], + ), + ]), + + html.div([], []), + ]), + ]), + ]) +} diff --git a/src/client/route.gleam b/src/client/route.gleam index 396d4d4..b7402a3 100644 --- a/src/client/route.gleam +++ b/src/client/route.gleam @@ -5,6 +5,7 @@ import lustre/attribute as attr pub type Route { Home Login + Signup Dashboard NotFound @@ -17,6 +18,7 @@ pub fn decoder() -> decode.Decoder(Route) { "login" -> decode.success(Login) "dashboard" -> decode.success(Dashboard) "not_found" -> decode.success(NotFound) + "signup" -> decode.success(Signup) _ -> decode.failure(NotFound, "Route") } @@ -25,7 +27,7 @@ pub fn decoder() -> decode.Decoder(Route) { ///  Some routes might require authentication in order to be accessed pub fn is_protected(self: Route) -> Bool { case self { - Login | NotFound | Home -> False + Login | NotFound | Home | Signup -> False _ -> True } } @@ -35,6 +37,7 @@ pub fn parse(uri: uri.Uri) -> Route { [] -> Home ["login"] -> Login ["dashboard"] -> Dashboard + ["signup"] -> Signup ["not-found"] | _ -> NotFound } @@ -46,6 +49,7 @@ pub fn path(self: Route) -> String { Login -> "/login" Dashboard -> "/dashboard" NotFound -> "/not-found" + Signup -> "/signup" } } -- 2.51.2