Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions components/outputs/ui/app-variation-login-core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
from shiny import App, ui, render, reactive

USERS = {"admin": "password123", "user": "mypass"}


def login_ui():
return ui.page_fluid(
ui.h2("Login"),
ui.input_text("username", "Username", placeholder="Enter username"),
ui.input_password("password", "Password", placeholder="Enter password"),
ui.input_action_button("login_btn", "Login"),
ui.output_text("login_status"),
ui.br(),
ui.card(
ui.h2("Demo credentials:"),
ui.div("admin / password123"),
ui.div("user / mypass"),
),
)


def dashboard_ui():
return ui.page_fluid(
ui.h1("Dashboard"),
ui.output_text("current_user_display"),
ui.input_action_button("logout_btn", "Logout"),
)


def server(input, output, session):
authenticated = reactive.Value(False)
current_user = reactive.Value("")

@reactive.Effect
@reactive.event(input.login_btn)
def handle_login():
username = input.username()
password = input.password()

if USERS.get(username) == password:
authenticated.set(True)
current_user.set(username)
else:
authenticated.set(False)
current_user.set("")

@reactive.Effect
@reactive.event(input.logout_btn)
def handle_logout():
authenticated.set(False)
current_user.set("")

@render.ui
def dynamic_ui():
if authenticated():
return dashboard_ui()
else:
return login_ui()

@render.text
def login_status():
if not authenticated() and input.login_btn() > 0:
return "Invalid credentials. Please try again."
return ""

@render.text
def current_user_display():
if user := current_user():
return f"You are logged in as: {user}"
return ""


app_ui = ui.page_fluid(ui.output_ui("dynamic_ui"))

app = App(app_ui, server)
11 changes: 11 additions & 0 deletions components/outputs/ui/index.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,17 @@ listing:
- title: Core
file: app-variation-update-an-input-core.py
shinylive: https://shinylive.io/py/editor/#code=NobwRAdghgtgpmAXAAjFADugdOgnmAGlQGMB7CAFzkqVQDMAnUmZAZwAsBLCXZTmdKQYVkAQUxEG1ACZwGRAK6cAOhFUZ0AfSXIAvMiU4oAczia6AGyXSAFKuQODnLBai5SCiprJWYEVnYQjsFOWNzonpoMUNKcpJoARp4U5AH2IRnKYDCksllEWQAinKzorrw5eYTIwFkAKlAJFnD5yFkAChakFFkAukSscM3EVNK69Y3NWekZAJQEMyGGHhQRXkp22blmZJRMFqxZ84uzqqdqF7J0bHIAbnI24Z5EK2sDcKyscRCziIsAAlIILIGFglIsrshKjtyBR9gFfotgpxrk8KFhoTZZnp9BMmi0kEiMsgmAB3Vh6PgQNZYMkIvjXLJ0rJUqlrZBDQbIACMAAYiRkfBT9GisEKsQy2mAhSzuGzPByDnBkAAWAUhKQUBQMIKGBrGAAyJQogWJZtCaM0rAsnBBm2Z1SyACVSOS-tVblArHBdHSiDBuLpuf6oAAPIO845Bc0ZQyW622h5ZGWOsAAYVIvn87qInu9uiF-sDwahYYjUZjDnOZs5cD+0Zj7DgnGM7BEIupniwTZbbYlKKlPdbPTArLRiq5AFZefyG+bSbaKOxKaKF9Il-3GWA10vZUFx7XkNPZ5WSXAtTrQvqjawTeqzXHO14E3askO260sgAJZvDnPIPMFB9d8KCLCAI15ENwz5GcK1PRxHzWK0bVfbdF3YT8wAAdXQ-9AJ9Hd2DAiCoIgyMFjnM1zlUdRMEpcR0BsDRtE4d4GHuBhzmqMAKFwdAEBQHi4FDCgwAAX16IA
- title: Login/logout application
description: 'Dynamic UI can be used to create completely different interfaces based on application state. This login example demonstrates switching between a login form and a dashboard interface using `@render.ui`.

The app maintains authentication state using reactive values and renders different UIs based on whether the user is logged in or not.'
apps:
- title: Preview
file: app-variation-login-core.py
height: 350
- title: Core
file: app-variation-login-core.py
shinylive: https://shinylive.io/py/editor/#h=0&code=NobwRAdghgtgpmAXGKAHVA6VBPMAaMAYwHsIAXOcpMAMwCdiYACAZwAsBLCbJjmVYnTJMAgujxMArhwl1KAEzh1ZcKITIcAbnAA6EPQFUAygFEASkaYBeJiB0p5MLvcRN7qKCxYB3QfICMAEwAzPYS9pIsSi5uYDDYHl72AL56aRCKNEwANsQA5lwA+tIAFACUiHpM1UxyZJJ0EFIcWFB5cIU02dLyJVU1A9IYbIF9YAAy+c5gZXj9A9VDXKiSZIUUAB5kY5FK0PBhsQZRjbC6+Eyo2WpwbMTZinRW9ibkSlIn++ez8wtLECs1okfH4xsDfHR5Id7AAFTwgyGHK43O4PJTPMCvCh0S7wiFQmZzJoLRYtZarQpqDSkQoAI1WZFIY1yBQgdLI+gu9kmrPsP2JJKGxFWgPWcC2zKmbJYZCg9RYfKJJNJGFpdHKSuVQ0IUEhfQFypVIzGABE4DBiExCHJFOQOFBsixKoTfoahvItGMoI4uEwAPS4rz4oKhF0Gt0tD2aHYnf1MeLAxWumr8gZldJ6TJMeSeNi04i6+TFDjlSoGuoNJpDDztTrdDi9ZNG-ym3P5wtJ8M1IUiimbbb2QgNOTkYonQoeljI7CdiMYclrKkcGn0siMiCSvLCta0jnQib5bezlMZjJwLInbTqhcSbeAiRRLzLiAVX5QVZsSgaHUUeTWWqqOoWhwBgABqDqSHAJQAGIOlE6YGkOdAjmsuw4jYchLtoYEQVB9h8ukAwAAKYUB2EmDQNBwOovwkYBGjYXA2jkCUC4YCyRS7i+vxZmwUAZNkHQcRur5dosnxnP+bFoV85RNoGCJ-jYbHgqCCHyRwWTGOYRgYO02wyWcZTWDYqmQmWhoDO+ZCfnaP5wPIGBRNsAAqdCQQhlk1EhKFjkoTlwAZEnwJ5ypwI6cAWV5TDWbZ35yg5AXbLBEWhV5Plfn5dBJWMBH6AadFYSBFFUTRBWkQxIFMV+rEAqs7GHhSXFpdm55MHxAlCY12yiYasVfhw9mOc5MFwXALUDBlo5oTl+EzIRNR0We2XSDxbXyNg+yDcWpYaVk-V2QlvS9dFFaNNmbYFpCO0TTU4VRFFXlnU0wk3Qt1RLY8GD9mtWSvTKcqRLtYm8FkEDEMIB3xb+5QxRkvB1WQDWsuyIlMAAfEwAAMj2Wc9sQAJIQJoDoNlaNoDXBGBMDCgmeHATBkHQPBtFAXAYPhIP43N71MJ9-k-QaWZTah46TtOwOGppHzvIgNgi1lkunYFlZMDQ9gAJrCjFcg5Pk7R-r6niuCAaGpGA8ncxbFv5XoaCoMW-7Vm0HRdD0JQ9mQoqlPYG1bYQxZ8up0DoP+YioCU9vFg+ShXghYDJAAukAA
---

:::{#example}
Expand Down
Loading