Content Calendar, Content Gap Analysis, and Content Optimization

This commit is contained in:
ajaysi
2025-05-27 09:15:08 +05:30
parent 4049d19787
commit 889021c078
100 changed files with 18504 additions and 1251 deletions

View File

@@ -1,3 +1,8 @@
"""
UI setup module for ALwrity application.
Provides consistent navigation and layout structure.
"""
import os
import streamlit as st
from lib.utils.file_processor import load_image
@@ -15,6 +20,99 @@ from lib.ai_writers.insta_ai_writer import insta_writer
from lib.ai_writers.youtube_writers.youtube_ai_writer import youtube_main_menu
from lib.ai_writers.ai_writer_dashboard import get_ai_writers, list_ai_writers
def render_social_tools_dashboard():
"""Render a modern dashboard for social media tools."""
st.markdown("""
<style>
.social-card {
background: white;
border-radius: 10px;
padding: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease;
height: 100%;
}
.social-card:hover {
transform: translateY(-5px);
}
.social-icon {
font-size: 2.5rem;
margin-bottom: 15px;
}
.social-title {
font-size: 1.2rem;
font-weight: 600;
margin-bottom: 10px;
}
.social-description {
color: #666;
font-size: 0.9rem;
margin-bottom: 15px;
}
.social-button {
width: 100%;
padding: 8px 16px;
border-radius: 5px;
border: none;
font-weight: 500;
cursor: pointer;
transition: all 0.3s ease;
}
</style>
""", unsafe_allow_html=True)
# Define social tools with their details and paths
social_tools = {
"Facebook": {
"icon": "📘",
"description": "Create engaging Facebook posts and manage your content strategy",
"color": "#4267B2",
"path": "facebook"
},
"LinkedIn": {
"icon": "💼",
"description": "Generate professional LinkedIn content and optimize your profile",
"color": "#0077B5",
"path": "linkedin"
},
"Twitter": {
"icon": "🐦",
"description": "Craft viral tweets and manage your Twitter presence",
"color": "#1DA1F2",
"path": "twitter"
},
"Instagram": {
"icon": "📸",
"description": "Create Instagram captions and plan your visual content",
"color": "#E1306C",
"path": "instagram"
},
"YouTube": {
"icon": "🎥",
"description": "Generate video scripts and optimize your YouTube content",
"color": "#FF0000",
"path": "youtube"
}
}
# Create a grid of cards
cols = st.columns(3)
for idx, (platform, details) in enumerate(social_tools.items()):
with cols[idx % 3]:
st.markdown(f"""
<div class="social-card">
<div class="social-icon">{details['icon']}</div>
<div class="social-title">{platform}</div>
<div class="social-description">{details['description']}</div>
</div>
""", unsafe_allow_html=True)
if st.button(f"Open {platform}", key=f"btn_{platform}",
help=f"Launch {platform} tools",
use_container_width=True):
# Set query parameters to redirect to the specific tool
st.query_params["tool"] = details["path"]
st.rerun()
def setup_ui():
"""Set up the UI with custom styling."""
@@ -314,29 +412,18 @@ def setup_alwrity_ui():
"AI Writers": ("📝", get_ai_writers),
"Content Planning": ("📅", content_planning_tools),
"AI SEO Tools": ("🔍", ai_seo_tools),
"AI Social Tools": ("📱", None), # Set to None as we'll handle this separately
"AI Social Tools": ("📱", render_social_tools_dashboard),
"ALwrity Settings": ("⚙️", render_settings_page),
"Agents Teams(TBD)": ("🤝", lambda: st.subheader("Agents Teams - Coming Soon!")),
"Ask Alwrity(TBD)": ("💬", lambda: (
st.subheader("Chat with your Data, Chat with any Data.. COMING SOON !"),
st.markdown("Create a collection by uploading files (PDF, MD, CSV, etc), or crawl a data source (Websites, more sources coming soon."),
st.markdown("One can ask/chat, summarize and do semantic search over the uploaded data")
)),
"ALwrity Settings": ("⚙️", render_settings_page)
))
}
logger.info(f"Defined {len(nav_items)} navigation items")
# Define sub-menu items for AI Social Tools
social_tools_submenu = {
"Facebook": ("📘", lambda: facebook_main_menu()),
"LinkedIn": ("💼", lambda: linkedin_main_menu()),
"Twitter": ("🐦", lambda: run_dashboard()),
"Instagram": ("📸", lambda: insta_writer()),
"YouTube": ("🎥", lambda: youtube_main_menu())
}
logger.info(f"Defined {len(social_tools_submenu)} social tools submenu items")
# Create sidebar navigation
st.sidebar.markdown("### ALwrity Options")
st.sidebar.markdown('<div class="sidebar-nav">', unsafe_allow_html=True)
@@ -345,53 +432,12 @@ def setup_alwrity_ui():
for name, (icon, func) in nav_items.items():
button_class = "nav-button active" if st.session_state.active_tab == name else "nav-button"
if name == "AI Social Tools":
# For AI Social Tools, we'll create a button that toggles the sub-menu
if st.sidebar.button(f"{icon} {name}", key=f"nav_{name}",
help=f"Navigate to {name}", use_container_width=True):
st.session_state.active_tab = name
# Reset sub-tab when main tab changes
st.session_state.active_sub_tab = None
logger.info(f"Selected main tab: {name}")
# If AI Social Tools is active, show the sub-menu
if st.session_state.active_tab == "AI Social Tools":
st.sidebar.markdown('<div class="sub-menu">', unsafe_allow_html=True)
# Create sub-menu buttons
for sub_name, (sub_icon, sub_func) in social_tools_submenu.items():
# Create the button with a custom key that includes the platform name
button_key = f"sub_{sub_name}"
# Determine if this button is active
is_active = st.session_state.active_sub_tab == sub_name
# Create a container with the platform-specific class
platform_class = f"{sub_name.lower()}-button"
if is_active:
platform_class += " active"
# Add the platform-specific class to the button container
st.sidebar.markdown(f'<div class="{platform_class}">', unsafe_allow_html=True)
# Create the button
if st.sidebar.button(f"{sub_icon} {sub_name}", key=button_key,
help=f"Navigate to {sub_name}", use_container_width=True):
st.session_state.active_sub_tab = sub_name
logger.info(f"Selected social tool: {sub_name}")
# Close the div
st.sidebar.markdown('</div>', unsafe_allow_html=True)
st.sidebar.markdown('</div>', unsafe_allow_html=True)
else:
# For other navigation items, create regular buttons
if st.sidebar.button(f"{icon} {name}", key=f"nav_{name}",
help=f"Navigate to {name}", use_container_width=True):
st.session_state.active_tab = name
# Reset sub-tab when main tab changes
st.session_state.active_sub_tab = None
logger.info(f"Selected main tab: {name}")
if st.sidebar.button(f"{icon} {name}", key=f"nav_{name}",
help=f"Navigate to {name}", use_container_width=True):
st.session_state.active_tab = name
# Reset sub-tab when main tab changes
st.session_state.active_sub_tab = None
logger.info(f"Selected main tab: {name}")
st.sidebar.markdown('</div>', unsafe_allow_html=True)
@@ -402,10 +448,36 @@ def setup_alwrity_ui():
st.sidebar.image(icon_path, use_container_width=False)
st.sidebar.markdown('</div>', unsafe_allow_html=True)
# Display content based on active tab
# Display content based on active tab and tool selection
if st.session_state.active_tab == "AI Social Tools":
if not st.session_state.active_sub_tab:
# Only show title and info when no sub-tab is selected
# Check if a specific tool is selected
selected_tool = st.query_params.get("tool")
if selected_tool:
# Add a back button at the top
if st.button("← Back to Social Tools Dashboard", key=f"back_to_dashboard_{selected_tool}"):
# Clear the tool query parameter
st.query_params.clear()
st.rerun()
# Map tool paths to their respective functions
tool_functions = {
"facebook": facebook_main_menu,
"linkedin": linkedin_main_menu,
"twitter": run_dashboard,
"instagram": insta_writer,
"youtube": youtube_main_menu
}
if selected_tool in tool_functions:
# Clear any existing content
st.empty()
# Execute the selected tool's function
tool_functions[selected_tool]()
else:
st.error(f"Invalid tool selected: {selected_tool}")
render_social_tools_dashboard()
else:
# Show the dashboard if no tool is selected
st.markdown("""
<style>
.main .block-container {
@@ -414,40 +486,14 @@ def setup_alwrity_ui():
</style>
""", unsafe_allow_html=True)
st.title(f"{nav_items[st.session_state.active_tab][0]} {st.session_state.active_tab}")
st.info("Please select a social media platform from the sidebar.")
else:
# When a platform is selected, show no title and minimize spacing
st.markdown("""
<style>
.main .block-container {
padding-top: 0 !important;
padding-bottom: 0;
}
/* Remove all margins and padding from content area */
.element-container {
margin: 0 !important;
padding: 0 !important;
}
/* Hide any automatic headers */
.main .block-container > div:first-child {
margin-top: 0 !important;
padding-top: 0 !important;
}
</style>
""", unsafe_allow_html=True)
# Call the function directly without any title
social_tools_submenu[st.session_state.active_sub_tab][1]()
render_social_tools_dashboard()
else:
# Check if we're in the AI Writers section and handle writer selection
# Handle other tabs as before
if st.session_state.active_tab == "AI Writers":
# Get the writer parameter from the URL using st.query_params
writer = st.query_params.get("writer")
logger.info(f"Current writer from query params: {writer}")
if writer:
# Get the list of writers without rendering the dashboard
writers = list_ai_writers()
logger.info(f"Found {len(writers)} writers")
@@ -457,9 +503,7 @@ def setup_alwrity_ui():
if w["path"] == writer:
writer_found = True
logger.info(f"Found matching writer: {w['name']}, executing function")
# Clear any existing content
st.empty()
# Execute the writer function
w["function"]()
break
@@ -467,11 +511,9 @@ def setup_alwrity_ui():
logger.error(f"No writer found with path: {writer}")
st.error(f"No writer found with path: {writer}")
else:
# If no writer selected, show the dashboard
logger.info("No writer selected, showing dashboard")
get_ai_writers()
else:
# For all other tabs, show the title
st.markdown("""
<style>
.main .block-container {