using Statum; using Invercargill; using Invercargill.DataStructures; namespace Example { /** * `POST /_statum/action/{guid}` — logs in: reads the submitted name, builds a * session `auth` slot from typed models (public + private), embedding a * `logout` action reference, and redirects home. */ public class LoginAction : StatumAction { public override async DirectiveBuilder handle() throws GLib.Error { var name = "guest"; if (request.form != null) { var submitted = request.form.get_field("name"); if (submitted != null && ((!)submitted).length > 0) { name = (!)submitted; } } var is_admin = name == "admin"; var pub = new AuthPublic(); pub.name = name; pub.role = is_admin ? "admin" : "member"; pub.logout = action_registry.author(); pub.update_announcement = action_registry.author(); var priv = new AuthPrivate(); priv.is_admin = is_admin; return directives() .set_private_typed("auth", Scope.SESSION, pub, priv) .navigate("/"); } } /** * `POST /_statum/action/{guid}` — logs out: clears the held `auth` slot and * redirects home. */ public class LogoutAction : StatumAction { public override async DirectiveBuilder handle() throws GLib.Error { HeldSlot auth; if (request.held.try_get("auth", out auth)) { yield state_service.clear_slot(auth.key); return directives().clear(auth.key).navigate("/"); } return directives().navigate("/"); } } /** * `POST /_statum/action/{guid}` — bumps the counter by the typed private * `delta`, using the typed {@link DirectiveBuilder.update_held} so the * `bump` action reference is preserved automatically across the update. */ public class BumpCounterAction : TypedStatumAction { public override async DirectiveBuilder handle() throws GLib.Error { var delta = request_private != null ? ((!)request_private).delta : 1; return directives().update_held("counter", c => c.value += delta); } } /** * `POST /_statum/action/{guid}` — updates the global announcement from the * dashboard. Reads the `text` form field, updates the global slot (which * pushes to all subscribed clients via SSE), and returns to the dashboard. */ public class UpdateAnnouncementAction : StatumAction { public override async DirectiveBuilder handle() throws GLib.Error { var text = "Updated"; if (request.form != null) { var submitted = request.form.get_field("text"); if (submitted != null && ((!)submitted).length > 0) { text = (!)submitted; } } yield state_service.update_global_typed("announcement", a => { a.text = text; }); return directives().notify("info", "Announcement updated").navigate("/dashboard"); } } }