this repo has no description
lustre frontent oat-ui gleam
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

💄 disable submit button when fields are empty

+47 -40
+7 -7
src/client.gleam
··· 123 123 pub fn view(model: Model) -> element.Element(Msg) { 124 124 case model { 125 125 // HOME PAGE --------------------------------------------------------------- 126 - Model(session:, route: route.Home, page: page.Home, ..) -> 127 - layout(model, home.view(session), HomeMsg) 126 + Model(route: route.Home, page: page.Home, ..) -> 127 + layout(model, home.view(model.session), HomeMsg) 128 128 129 129 // LOGIN PAGE -------------------------------------------------------------- 130 - Model(session:, route: route.Login, page: page.Login(page), lang:) -> 131 - layout(model, login.view(session, page, lang), LoginMsg) 130 + Model(route: route.Login, page: page.Login(page), ..) -> 131 + layout(model, login.view(page, model.lang), LoginMsg) 132 132 133 133 // DASHBOARD PAGE ---------------------------------------------------------- 134 - Model(session:, route: route.Dashboard, page: page.Dashboard(page), ..) -> 135 - layout(model, dashboard.view(session, page), DashboardMsg) 134 + Model(route: route.Dashboard, page: page.Dashboard(page), ..) -> 135 + layout(model, dashboard.view(model.session, page), DashboardMsg) 136 136 137 137 _ -> layout(model, not_found.view(), NotFoundMsg) 138 138 } ··· 234 234 235 235 login.ServerAuthenticatedUser(session) -> #( 236 236 Model(..model, session:), 237 - route.Home 237 + route.Dashboard 238 238 |> route.to_path 239 239 |> modem.push(option.None, option.None), 240 240 )
+35 -28
src/client/page/login.gleam
··· 81 81 } 82 82 } 83 83 84 - pub fn view( 85 - _session: session.Session, 86 - model: Model, 87 - lang: language.Language, 88 - ) -> element.Element(Msg) { 84 + pub fn view(model: Model, lang: language.Language) -> element.Element(Msg) { 89 85 // Wrapper 90 86 let wrapper_attr = [ 91 87 class("mx-auto max-w-lg h-full"), ··· 94 90 95 91 html.div(wrapper_attr, [ 96 92 //  LOGO AND TITLE ------------------------------------------------------- 97 - html.section( 98 - [ 99 - class("p-4 w-full"), 100 - class("flex gap-2 justify-center items-center sm:gap-4"), 101 - ], 102 - [ 103 - brand.logo([class("size-8 drop-shadow-md sm:size-12")]), 104 - html.div([], [ 105 - brand.title([class("my-0 text-xl text-center")]), 106 - html.small([class("hidden sm:inline text-subtext")], [ 107 - html.text(case lang { 108 - language.BrazillianPortuguese | language.PortugalPortuguese -> 109 - "Soluções Climáticas Inteligentes" 110 - _ -> "Smart climate solutions" 111 - }), 112 - ]), 93 + html.section([class("my-2 hstack")], [ 94 + brand.logo([class("size-8 drop-shadow-md sm:size-12")]), 95 + html.div([], [ 96 + brand.title([class("my-0 text-xl text-center")]), 97 + html.small([class("hidden sm:inline text-subtext")], [ 98 + html.text(case lang { 99 + language.BrazillianPortuguese | language.PortugalPortuguese -> 100 + "Soluções Climáticas Inteligentes" 101 + _ -> "Smart climate solutions" 102 + }), 113 103 ]), 114 - ], 115 - ), 104 + ]), 105 + ]), 116 106 117 107 // 󱐁 FORM ----------------------------------------------------------------- 118 108 html.article([class("w-full card @container")], [ ··· 141 131 html.label([attr.data("field", ""), class("mt-4")], [ 142 132 html.text("Email"), 143 133 html.input([ 134 + event.on_input(UserTypedEmail), 144 135 attr.type_("email"), 145 136 attr.value(model.email), 146 137 attr.placeholder(case lang { ··· 164 155 165 156 html.input([ 166 157 attr.type_("password"), 158 + event.on_input(UserTypedPassword), 167 159 attr.value(model.password), 168 160 attr.placeholder("********"), 169 161 class("py-1 px-2 bg-gray-100 rounded-md text-subtext"), ··· 173 165 ]), 174 166 ]), 175 167 176 - // Login Button 177 168 html.footer([], [ 178 - html.button([event.on_click(UserClickedSubmit), class("w-full")], [ 179 - html.text("Login"), 180 - ]), 169 + // Login Button 170 + html.button( 171 + [ 172 + event.on_click(UserClickedSubmit), 173 + attr.aria_busy(model.loading), 174 + class("w-full"), 175 + 176 + // Disabled if any of the input fields are empty. 177 + attr.disabled( 178 + model.email == "" || model.password == "" || model.loading, 179 + ), 180 + ], 181 + [html.text("Login")], 182 + ), 181 183 184 + // Divider 182 185 html.hr([class("my-4")]), 183 186 187 + // Other links 184 188 html.div( 185 189 [ 186 190 class("text-sm text-center"), 187 - class("grid grid-cols-1 @xs:gap-2 @xs:grid-cols-2"), 191 + class("grid grid-cols-1 gap-2 @xs:grid-cols-2"), 188 192 ], 189 193 [ 194 + // Forgot my password 190 195 html.a([], [ 191 196 html.text(case lang { 192 197 language.BrazillianPortuguese | language.PortugalPortuguese -> ··· 194 199 _ -> "Forgot my password" 195 200 }), 196 201 ]), 202 + 203 + // Forgot my password 197 204 html.a([], [ 198 205 html.text(case lang { 199 206 language.BrazillianPortuguese | language.PortugalPortuguese ->
+1 -1
src/client/page/navbar.gleam
··· 43 43 44 44 fn view_middle_section() -> element.Element(Msg) { 45 45 let a_style = class("hover:cursor-pointer") 46 - html.section([class("hidden space-x-4 md:inline text-subtext")], [ 46 + html.section([class("hidden space-x-4 lg:inline text-subtext")], [ 47 47 html.a([a_style], [html.text("Soluções")]), 48 48 html.a([a_style], [html.text("Como Funciona")]), 49 49 html.a([a_style], [html.text("Benefícios")]),
+4 -4
test/page/login_test.gleam
··· 32 32 pub fn auth_success_test() -> Nil { 33 33 let want = dummy.token() 34 34 35 - let model = 35 + let login_step = 36 36 Ok(session.Authenticated(want)) 37 37 |> login.ApiReturnedSession 38 38 |> login.update(login.empty, _) 39 39 40 - let assert login.ServerAuthenticatedUser(session) = model 40 + let assert login.ServerAuthenticatedUser(session) = login_step 41 41 let assert session.Authenticated(got) = session 42 42 assert got == want as "correct token" 43 43 ··· 45 45 } 46 46 47 47 pub fn auth_failure_test() -> Nil { 48 - let model = 48 + let login_step = 49 49 Error(rsvp.NetworkError) 50 50 |> login.ApiReturnedSession 51 51 |> login.update(login.empty, _) 52 52 53 - let assert login.ServerFailedToAuthenticate(_) = model 53 + let assert login.ServerFailedToAuthenticate(_) = login_step 54 54 55 55 Nil 56 56 }