11"""
22Streamlit Page Layout Module
3-
4- Contains main page layout and flow control
3+ Contains main page layout and flow control with CRM-aware header/sidebar
54"""
6-
75import streamlit as st
8-
96from .components import (
107 display_header ,
118 display_features ,
2118)
2219from .styles import get_main_styles
2320
21+ # New: CRM imports for permissions & business switching (lazy optional)
22+ try :
23+ from crm .crm_auth import current_business_context , switch_business_context , Role
24+ except Exception :
25+ current_business_context = lambda s : s .get ("active_business_id" )
26+ def switch_business_context (session , user , biz_id ):
27+ session ["active_business_id" ] = biz_id
28+ return True
29+ class Role : # fallback enum-like
30+ OWNER = type ("T" , (), {"value" : "owner" })
31+
32+ ASSETS_LOGO_PATH_CANDIDATES = [
33+ "assets/Deepcode.png" ,
34+ "assets/Main Logo S&M Transparent.png" ,
35+ "assets/genericlogo.png" ,
36+ "assets/logo.png" ,
37+ ]
2438
2539def setup_page_config ():
2640 """Setup page configuration"""
@@ -37,9 +51,75 @@ def apply_custom_styles():
3751 st .markdown (get_main_styles (), unsafe_allow_html = True )
3852
3953
54+ def _resolve_logo_path () -> str | None :
55+ for p in ASSETS_LOGO_PATH_CANDIDATES :
56+ try :
57+ # Streamlit can show local relative path if exists in repo
58+ return p
59+ except Exception :
60+ continue
61+ return None
62+
63+
64+ def _crm_header (user = None ):
65+ """Render dynamic header with logo, business switch, and permission-aware nav."""
66+ cols = st .columns ([0.1 , 0.5 , 0.4 ])
67+ with cols [0 ]:
68+ logo = _resolve_logo_path ()
69+ if logo :
70+ st .image (logo , use_container_width = True )
71+ with cols [1 ]:
72+ st .subheader ("Trinity CRM Suite" )
73+ active_biz = current_business_context (st .session_state )
74+ st .caption (f"Business: { active_biz or 'No business selected' } " )
75+ with cols [2 ]:
76+ if user and getattr (user , "memberships" , None ):
77+ options = [m .business_id for m in user .memberships ]
78+ default = options .index (active_biz ) if active_biz in options else 0
79+ selected = st .selectbox ("Switch business" , options , index = default )
80+ if st .button ("Apply" , key = "apply_biz_switch" ):
81+ switch_business_context (st .session_state , user , selected )
82+ else :
83+ st .info ("Connect or create a business in Onboarding" )
84+
85+ st .markdown ("---" )
86+
87+
88+ def _crm_sidebar (user = None ):
89+ """Sidebar with permissions-based visibility and SaaS placeholders."""
90+ with st .sidebar :
91+ st .markdown ("### Navigation" )
92+ active_biz = current_business_context (st .session_state )
93+ can_view_contacts = bool (user and active_biz and user .has_permission (active_biz , "contacts:read" )) if user else True
94+ can_view_leads = bool (user and active_biz and user .has_permission (active_biz , "leads:read" )) if user else True
95+ can_manage_pipeline = bool (user and active_biz and user .has_permission (active_biz , "pipeline:read" )) if user else True
96+ can_admin = bool (user and active_biz and user .has_permission (active_biz , "settings:read" )) if user else True
97+
98+ if can_view_contacts :
99+ st .page_link ("/contacts" , label = "Contacts" , icon = "👤" )
100+ if can_view_leads :
101+ st .page_link ("/leads" , label = "Leads" , icon = "📈" )
102+ if can_manage_pipeline :
103+ st .page_link ("/pipeline" , label = "Pipeline" , icon = "🪜" )
104+
105+ st .markdown ("---" )
106+ st .markdown ("### Admin & Onboarding" )
107+ # SaaS onboarding admin placeholder
108+ if can_admin :
109+ st .page_link ("/admin/onboarding" , label = "Onboarding Admin" , icon = "🧭" )
110+ st .page_link ("/admin/business-wizard" , label = "Business Wizard" , icon = "🧩" )
111+
112+ st .markdown ("---" )
113+ return sidebar_control_panel ()
114+
115+
40116def render_main_content ():
41117 """Render main content area"""
42- # Display header and features
118+ # Dynamic CRM header
119+ user = st .session_state .get ("__user__" ) # integration point for auth layer
120+ _crm_header (user )
121+
122+ # Display original header and features
43123 display_header ()
44124 display_features ()
45125 st .markdown ("---" )
@@ -69,18 +149,17 @@ def render_input_interface():
69149 if input_source and not st .session_state .processing :
70150 if st .button ("🚀 Start Processing" , type = "primary" , use_container_width = True ):
71151 handle_start_processing_button (input_source , input_type )
72-
73152 elif st .session_state .processing :
74153 st .info ("🔄 Processing in progress... Please wait." )
75154 st .warning ("⚠️ Do not refresh the page or close the browser during processing." )
76-
77155 elif not input_source :
78156 st .info ("👆 Please upload a file or enter a URL to start processing." )
79157
80158
81159def render_sidebar ():
82- """Render sidebar"""
83- return sidebar_control_panel ()
160+ """Render sidebar with CRM navigation"""
161+ user = st .session_state .get ("__user__" )
162+ return _crm_sidebar (user )
84163
85164
86165def main_layout ():
0 commit comments