Restructure app layout for sidebar and theme integration #31

Closed
opened 2026-01-15 06:51:44 +00:00 by lmiranda · 0 comments
Owner

Description

Modify the main app.py to integrate the sidebar component, theme infrastructure, and active page detection. This is the central integration point for the navigation and theme system.

Files to Modify

  • portfolio_app/app.py
  • portfolio_app/components/__init__.py

Changes Required

1. app.py Modifications

Remove forceColorScheme

# Before
forceColorScheme="light"

# After
defaultColorScheme="dark"

Add MantineProvider ID

dmc.MantineProvider(
    ...,
    id="mantine-provider",
)

Add Required Components to Layout

from dash import dcc, html
from .components import create_sidebar
from .callbacks.theme import register_theme_callbacks

app.layout = dmc.MantineProvider(
    html.Div([
        # Theme persistence store
        dcc.Store(id="theme-store", storage_type="local", data={"colorScheme": "dark"}),
        
        # Location for active page detection
        dcc.Location(id="url", refresh=False),
        
        # Sidebar
        create_sidebar(),
        
        # Page content with offset
        html.Div(
            dash.page_container,
            className="page-content-wrapper",
        ),
    ]),
    theme={
        "primaryColor": "blue",
        "fontFamily": "'Inter', sans-serif",
    },
    defaultColorScheme="dark",
    id="mantine-provider",
)

Register Callbacks

def create_app() -> dash.Dash:
    app = dash.Dash(...)
    # ... layout setup ...
    
    # Register theme callbacks
    register_theme_callbacks(app)
    
    return app

2. components/init.py Updates

Add sidebar to exports:

from .sidebar import create_sidebar

__all__ = [
    ...,
    "create_sidebar",
]

3. Active Page Detection Callback

Add callback to update sidebar active state based on URL:

@app.callback(
    Output("nav-home", "className"),
    Output("nav-toronto", "className"),
    Input("url", "pathname"),
)
def update_active_nav(pathname):
    home_class = "nav-icon-active" if pathname == "/" else ""
    toronto_class = "nav-icon-active" if pathname == "/toronto" else ""
    return home_class, toronto_class

Integration Checklist

  • Remove forceColorScheme="light"
  • Add defaultColorScheme="dark"
  • Add id="mantine-provider"
  • Add dcc.Store for theme state
  • Add dcc.Location for URL tracking
  • Import and render create_sidebar()
  • Wrap page_container with page-content-wrapper class
  • Register theme callbacks
  • Export sidebar from components

Acceptance Criteria

  • App starts without errors
  • Sidebar visible on all pages
  • Theme defaults to dark
  • Page content has proper left margin
  • Active page indicator updates on navigation
  • Theme toggle functional

Part of Sprint 7 (#27)

Depends On

  • #28 (sidebar component)
  • #29 (sidebar CSS)
  • #30 (theme callbacks)
## Description Modify the main app.py to integrate the sidebar component, theme infrastructure, and active page detection. This is the central integration point for the navigation and theme system. ## Files to Modify - `portfolio_app/app.py` - `portfolio_app/components/__init__.py` ## Changes Required ### 1. app.py Modifications #### Remove forceColorScheme ```python # Before forceColorScheme="light" # After defaultColorScheme="dark" ``` #### Add MantineProvider ID ```python dmc.MantineProvider( ..., id="mantine-provider", ) ``` #### Add Required Components to Layout ```python from dash import dcc, html from .components import create_sidebar from .callbacks.theme import register_theme_callbacks app.layout = dmc.MantineProvider( html.Div([ # Theme persistence store dcc.Store(id="theme-store", storage_type="local", data={"colorScheme": "dark"}), # Location for active page detection dcc.Location(id="url", refresh=False), # Sidebar create_sidebar(), # Page content with offset html.Div( dash.page_container, className="page-content-wrapper", ), ]), theme={ "primaryColor": "blue", "fontFamily": "'Inter', sans-serif", }, defaultColorScheme="dark", id="mantine-provider", ) ``` #### Register Callbacks ```python def create_app() -> dash.Dash: app = dash.Dash(...) # ... layout setup ... # Register theme callbacks register_theme_callbacks(app) return app ``` ### 2. components/__init__.py Updates Add sidebar to exports: ```python from .sidebar import create_sidebar __all__ = [ ..., "create_sidebar", ] ``` ### 3. Active Page Detection Callback Add callback to update sidebar active state based on URL: ```python @app.callback( Output("nav-home", "className"), Output("nav-toronto", "className"), Input("url", "pathname"), ) def update_active_nav(pathname): home_class = "nav-icon-active" if pathname == "/" else "" toronto_class = "nav-icon-active" if pathname == "/toronto" else "" return home_class, toronto_class ``` ## Integration Checklist - [ ] Remove `forceColorScheme="light"` - [ ] Add `defaultColorScheme="dark"` - [ ] Add `id="mantine-provider"` - [ ] Add `dcc.Store` for theme state - [ ] Add `dcc.Location` for URL tracking - [ ] Import and render `create_sidebar()` - [ ] Wrap `page_container` with `page-content-wrapper` class - [ ] Register theme callbacks - [ ] Export sidebar from components ## Acceptance Criteria - [ ] App starts without errors - [ ] Sidebar visible on all pages - [ ] Theme defaults to dark - [ ] Page content has proper left margin - [ ] Active page indicator updates on navigation - [ ] Theme toggle functional ## Part of Sprint 7 (#27) ## Depends On - #28 (sidebar component) - #29 (sidebar CSS) - #30 (theme callbacks)
lmiranda added this to the Launch: Host, Bio and Toronto House Market Analysis project 2026-01-16 14:51:54 +00:00
lmiranda self-assigned this 2026-01-16 14:51:59 +00:00
lmiranda moved this to Done in Launch: Host, Bio and Toronto House Market Analysis on 2026-01-16 14:52:15 +00:00
Sign in to join this conversation.