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.

:construction: add session, user and route types

+147 -2
+58 -2
client/src/client.gleam
··· 1 - import gleam/io 1 + import client/page 2 + import lustre 3 + import lustre/effect.{type Effect} 4 + import modem 5 + import rsvp 6 + import shared/route 7 + import shared/session 8 + 9 + pub type Model { 10 + Model( 11 + /// Current user 12 + session: session.Session, 13 + /// Current route 14 + route: route.Route, 15 + /// Current Page model 16 + page: page.Page, 17 + ) 18 + } 2 19 3 20 pub fn main() -> Nil { 4 - io.println("Hello from client!") 21 + let app = lustre.application(init:, update: todo, view: todo) 22 + let assert Ok(_runtime) = lustre.start(app, "#app", Nil) 23 + 24 + Nil 25 + } 26 + 27 + pub type Msg { 28 + UserNavigatedTo(route.Route) 29 + UserRestoredSession(Result(session.Session, rsvp.Error)) 30 + } 31 + 32 + pub fn init(_props: Nil) -> #(Model, Effect(Msg)) { 33 + let assert Ok(uri) = modem.initial_uri() 34 + let route = route.parse(uri) 35 + let page = page.init(route) 36 + let is_protected = route.is_protected(route) 37 + let session = init_session(route, is_protected) 38 + 39 + let router_effect = 40 + modem.init(fn(uri) { route.parse(uri) |> UserNavigatedTo }) 41 + 42 + let session_effect = 43 + UserRestoredSession 44 + |> rsvp.expect_json(session.decoder(), _) 45 + |> rsvp.get("/api/whoami", _) 46 + 47 + let effect = effect.batch([session_effect, router_effect]) 48 + #(Model(session:, route:, page:), effect) 49 + } 50 + 51 + fn init_session(route: route.Route, is_protected: Bool) -> session.Session { 52 + case route { 53 + route.Login | route.Home -> 54 + session.Pending(on_success: route.Home, on_error: route) 55 + 56 + route if is_protected -> 57 + session.Pending(on_success: route, on_error: route.Login) 58 + 59 + _ -> session.None 60 + } 5 61 }
+17
client/src/client/page.gleam
··· 1 + import client/page/login 2 + import shared/route 3 + 4 + pub type Page { 5 + Home 6 + Login(login.Model) 7 + 8 + NotFound 9 + } 10 + 11 + pub fn init(route: route.Route) { 12 + case route { 13 + route.Home -> Home 14 + route.Login -> Login(login.empty) 15 + route.NotFound -> NotFound 16 + } 17 + }
+5
client/src/client/page/login.gleam
··· 1 + pub type Model { 2 + Model(email: String, password: String) 3 + } 4 + 5 + pub const empty = Model(email: "", password: "")
+11
shared/manifest.toml
··· 1 + # This file was generated by Gleam 2 + # You typically do not need to edit this file 3 + 4 + packages = [ 5 + { name = "gleam_stdlib", version = "1.0.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "960090C2FB391784BB34267B099DC9315CC1B1F6013E7415BC763CEF1905D7D3" }, 6 + { name = "gleeunit", version = "1.10.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "254B697FE72EEAD7BF82E941723918E421317813AC49923EE76A18C788C61E72" }, 7 + ] 8 + 9 + [requirements] 10 + gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" } 11 + gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
+24
shared/src/shared/route.gleam
··· 1 + import gleam/uri 2 + 3 + pub type Route { 4 + Home 5 + Login 6 + 7 + NotFound 8 + } 9 + 10 + pub fn is_protected(route: Route) -> Bool { 11 + case route { 12 + Login | NotFound -> False 13 + _ -> True 14 + } 15 + } 16 + 17 + pub fn parse(uri: uri.Uri) -> Route { 18 + case uri.path_segments(uri.path) { 19 + [] | [""] -> Home 20 + ["login"] -> Login 21 + 22 + ["not-found"] | _ -> NotFound 23 + } 24 + }
+29
shared/src/shared/session.gleam
··· 1 + import gleam/dynamic/decode 2 + import shared/route 3 + import shared/user 4 + 5 + pub type Session { 6 + Authenticated(user: user.User) 7 + Pending(on_success: route.Route, on_error: route.Route) 8 + 9 + None 10 + } 11 + 12 + pub fn decoder() -> decode.Decoder(Session) { 13 + use variant <- decode.field("type", decode.string) 14 + case variant { 15 + "authenticated" -> { 16 + use user <- decode.field("user", todo) 17 + decode.success(Authenticated(user:)) 18 + } 19 + 20 + "pending" -> { 21 + use on_success <- decode.field("on_success", todo) 22 + use on_error <- decode.field("on_error", todo) 23 + decode.success(Pending(on_success:, on_error:)) 24 + } 25 + 26 + "none" -> decode.success(None) 27 + _ -> decode.failure(None, "Session") 28 + } 29 + }
+3
shared/src/shared/user.gleam
··· 1 + pub type User { 2 + User 3 + }