Skip to content

Commit 0d547b2

Browse files
authored
Update layout.py
1 parent 7a1a267 commit 0d547b2

1 file changed

Lines changed: 88 additions & 9 deletions

File tree

ui/layout.py

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
"""
22
Streamlit 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-
75
import streamlit as st
8-
96
from .components import (
107
display_header,
118
display_features,
@@ -21,6 +18,23 @@
2118
)
2219
from .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

2539
def 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+
40116
def 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

81159
def 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

86165
def main_layout():

0 commit comments

Comments
 (0)