Skip to main content
The login module provides two authentication UI components for the CS Library Kiosk: a student ID scanner interface and an email/password login interface.

login.create()

Creates a student ID-based login interface with barcode scanning support.

Signature

def create(on_login_success: Callable) -> tuple[ui.element, ui.input]

Parameters

on_login_success
Callable
required
Callback function triggered when the user submits their student ID (via Enter key or Sign In button).The function should validate the ID and handle successful authentication.

Returns

container
ui.element
The root container element with class login-outer scsu-bg. Contains the entire login UI with left branding panel and right input panel.
id_input
ui.input
The student ID input field. Has autofocus enabled and is bound to the on_login_success callback on Enter key press.Access the value with id_input.value.

UI Structure

The component creates a split-screen layout: Left Panel (42% width)
  • SCSU logo (inverted/white)
  • Blue accent divider with glow effect
  • “Department of Computer Science” label
  • “CS Library Sign-in Portal” heading
  • Descriptive text
  • Copyright footer
  • Diagonal stripe texture overlay
Right Panel (58% width)
  • “Welcome Back” heading (3rem, bold)
  • Blue accent bar with shadow
  • Instructions: “Scan your ID to enter CS Library Kiosk”
  • Student ID input field with badge icon
  • “Sign In” button with blue glow on hover
  • Live clock display (updates every second)

Styling Features

  • Dark theme with #0a1f44 blue background on left panel
  • Starfield background via scsu-bg class
  • Input field uses NiceGUI’s dark standout props
  • Blue (#3b82f6) accent color with glow effects
  • Responsive with Space Grotesk font family

Usage Example

from app import login
import database as db
from nicegui import ui

@ui.page('/')
async def main_page():
    async def try_login():
        user = await db.get_user_by_id(id_input.value.strip())
        id_input.value = ''  # Clear input
        
        if user and user['active']:
            # Store user session
            current_user.update(user)
            ui.notify(f"Welcome, {user['name']}!", type='positive')
            
            # Hide login, show dashboard
            login_cont.visible = False
            dashboard_cont.visible = True
        else:
            ui.notify('Invalid Student ID.', type='negative')
    
    # Create login UI
    login_cont, id_input = login.create(try_login)

login_email.create()

Creates an email/password authentication interface with registration link.

Signature

def create(on_login_success: Callable) -> tuple[ui.element, ui.input]

Parameters

on_login_success
Callable
required
Callback function triggered when the user submits credentials (via Enter key on password field or Sign In button).The function should validate email/password and handle successful authentication.

Returns

container
ui.element
The root container element with class login-outer scsu-bg. Contains the entire login UI.
email_input
ui.input
The email input field. Has autofocus enabled and includes a special password_input attribute for accessing the password field.Special Property:
  • email_input.password_input: Reference to the password input field
This allows you to access both fields from the returned object:
email = email_input.value
password = email_input.password_input.value

UI Structure

Similar split-screen layout to login.create() with key differences: Left Panel
  • Same branding as student ID login
Right Panel
  • “Welcome Back” heading
  • Blue accent bar
  • Instructions: “Sign in with your email and password”
  • Email input field with email icon
  • Password input field with lock icon
  • “Sign In” button
  • Registration link: “Don’t have an account? Create one”
  • Live clock display

Interactive Features

  • Enter key on email: Focuses password field
  • Enter key on password: Triggers on_login_success
  • Registration link: Navigates to /register route
  • Password field has type=password for masked input

Usage Example

from app import login_email
import database as db
from nicegui import ui

@ui.page('/')
async def main_page():
    current_user = {}
    
    async def try_login():
        # Access both fields via the returned email_input object
        email = id_input.value.strip()
        password = id_input.password_input.value
        
        user = await db.authenticate_user(email, password)
        
        if user and user['active']:
            current_user.update(user)
            ui.notify(f"Welcome, {user['name']}", type='positive')
            
            # Clear sensitive data
            id_input.value = ""
            id_input.password_input.value = ""
            
            # Show dashboard
            login_cont.visible = False
            app_header.visible = True
            dash_cont.visible = True
        else:
            ui.notify('Invalid email or password.', type='negative')
            # Clear only password on failed login
            id_input.password_input.value = ""
    
    # Create email login UI
    login_cont, id_input = login_email.create(try_login)

Common Patterns

Switching Between Kiosk and Web Modes

# In main.py (kiosk mode with student ID scanner)
from app import login
login_cont, id_input = login.create(handle_id_login)

# In mainwebsite.py (web mode with email/password)
from app import login_email  
login_cont, id_input = login_email.create(handle_email_login)

Styling Customization

Both components inject custom CSS via ui.add_head_html() with these classes:
  • .login-outer: Full viewport flex container
  • .left-panel: 42% width branding panel with #0a1f44 background
  • .right-panel: Flexible right panel for inputs
  • .stripe-texture: Diagonal stripe overlay pattern
  • .scsu-bg: Starfield background (defined globally)

Time Display Pattern

Both components include a live clock using NiceGUI timers:
time_label = ui.label().classes('text-xs font-bold tracking-[0.2em] uppercase text-slate-400')

def update_time():
    time_label.text = datetime.now().strftime('%a, %b %d | %I:%M %p')

ui.timer(1.0, update_time)  # Updates every second
update_time()  # Initial update

See Also

Build docs developers (and LLMs) love