AI Image and Audio Generation Improvements.
AI Video Generation Pre-Flight Checklist. Cost Estimate Improvements.
This commit is contained in:
@@ -1,729 +0,0 @@
|
||||
"""
|
||||
Enhanced Twitter Dashboard with modern UI components and improved user experience.
|
||||
"""
|
||||
|
||||
import streamlit as st
|
||||
from typing import Dict, List, Optional, Any
|
||||
import json
|
||||
from datetime import datetime, timedelta
|
||||
import plotly.express as px
|
||||
import plotly.graph_objects as go
|
||||
from plotly.subplots import make_subplots
|
||||
import pandas as pd
|
||||
import numpy as np
|
||||
|
||||
from .tweet_generator import smart_tweet_generator
|
||||
from .twitter_streamlit_ui import (
|
||||
TwitterDashboard,
|
||||
FeatureCard,
|
||||
TweetCard,
|
||||
TweetForm,
|
||||
SettingsForm,
|
||||
Sidebar,
|
||||
Header,
|
||||
Tabs,
|
||||
Breadcrumbs,
|
||||
Theme,
|
||||
save_to_session,
|
||||
get_from_session,
|
||||
clear_session,
|
||||
show_success_message,
|
||||
show_error_message,
|
||||
show_info_message,
|
||||
show_warning_message
|
||||
)
|
||||
|
||||
def apply_modern_styling():
|
||||
"""Apply modern CSS styling to the dashboard."""
|
||||
st.markdown("""
|
||||
<style>
|
||||
/* Import Google Fonts */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
|
||||
|
||||
/* Global Styles */
|
||||
.stApp {
|
||||
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* Main Container */
|
||||
.main-container {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(20px);
|
||||
border-radius: 20px;
|
||||
padding: 2rem;
|
||||
margin: 1rem;
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Header Styles */
|
||||
.dashboard-header {
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
padding: 2rem 0;
|
||||
background: linear-gradient(135deg, #1DA1F2, #0C85D0);
|
||||
border-radius: 16px;
|
||||
color: white;
|
||||
box-shadow: 0 10px 30px rgba(29, 161, 242, 0.3);
|
||||
}
|
||||
|
||||
.dashboard-title {
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.dashboard-subtitle {
|
||||
font-size: 1.1rem;
|
||||
opacity: 0.9;
|
||||
margin-top: 0.5rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
/* Feature Cards */
|
||||
.feature-card {
|
||||
background: white;
|
||||
border-radius: 16px;
|
||||
padding: 1.5rem;
|
||||
margin-bottom: 1rem;
|
||||
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.08);
|
||||
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.feature-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 1rem;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.feature-title {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
color: #2D3748;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.feature-description {
|
||||
color: #718096;
|
||||
font-size: 0.95rem;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.feature-status {
|
||||
display: inline-block;
|
||||
padding: 0.25rem 0.75rem;
|
||||
border-radius: 20px;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 500;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
|
||||
.status-active {
|
||||
background: linear-gradient(135deg, #48BB78, #38A169);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.status-coming-soon {
|
||||
background: linear-gradient(135deg, #ED8936, #DD6B20);
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* Metrics Cards */
|
||||
.metric-card {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem;
|
||||
text-align: center;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08);
|
||||
border-left: 4px solid #1DA1F2;
|
||||
}
|
||||
|
||||
.metric-value {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
color: #2D3748;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.metric-label {
|
||||
color: #718096;
|
||||
font-size: 0.9rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
.stButton > button {
|
||||
background: linear-gradient(135deg, #1DA1F2, #0C85D0);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.95rem;
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: 0 4px 15px rgba(29, 161, 242, 0.3);
|
||||
}
|
||||
|
||||
.stButton > button:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(29, 161, 242, 0.4);
|
||||
}
|
||||
|
||||
/* Tabs */
|
||||
.stTabs [data-baseweb="tab-list"] {
|
||||
gap: 0.5rem;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
padding: 0.5rem;
|
||||
border-radius: 12px;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.stTabs [data-baseweb="tab"] {
|
||||
background: transparent;
|
||||
border-radius: 8px;
|
||||
color: #4A5568;
|
||||
font-weight: 500;
|
||||
padding: 0.75rem 1.5rem;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.stTabs [aria-selected="true"] {
|
||||
background: white;
|
||||
color: #1DA1F2;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
/* Connection Status */
|
||||
.connection-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 1rem;
|
||||
border-radius: 12px;
|
||||
margin-bottom: 1.5rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.status-connected {
|
||||
background: linear-gradient(135deg, #C6F6D5, #9AE6B4);
|
||||
color: #22543D;
|
||||
border: 1px solid #9AE6B4;
|
||||
}
|
||||
|
||||
.status-disconnected {
|
||||
background: linear-gradient(135deg, #FED7D7, #FEB2B2);
|
||||
color: #742A2A;
|
||||
border: 1px solid #FEB2B2;
|
||||
}
|
||||
|
||||
/* Quick Actions */
|
||||
.quick-actions {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 1rem;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
.quick-action-btn {
|
||||
background: white;
|
||||
border: 2px solid #E2E8F0;
|
||||
border-radius: 12px;
|
||||
padding: 1.5rem;
|
||||
text-align: center;
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.quick-action-btn:hover {
|
||||
border-color: #1DA1F2;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(29, 161, 242, 0.15);
|
||||
}
|
||||
|
||||
.quick-action-icon {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 0.5rem;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.quick-action-title {
|
||||
font-weight: 600;
|
||||
color: #2D3748;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
|
||||
.quick-action-desc {
|
||||
font-size: 0.85rem;
|
||||
color: #718096;
|
||||
}
|
||||
|
||||
/* Analytics Charts */
|
||||
.chart-container {
|
||||
background: white;
|
||||
border-radius: 16px;
|
||||
padding: 1.5rem;
|
||||
margin: 1rem 0;
|
||||
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media (max-width: 768px) {
|
||||
.main-container {
|
||||
margin: 0.5rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.dashboard-title {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.quick-actions {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
def render_connection_status():
|
||||
"""Render Twitter connection status with modern styling."""
|
||||
# Simulate connection status (replace with real authentication check)
|
||||
is_connected = get_from_session("twitter_connected", False)
|
||||
|
||||
if is_connected:
|
||||
user_info = get_from_session("twitter_user", {"name": "Demo User", "handle": "@demo_user"})
|
||||
st.markdown(f"""
|
||||
<div class="connection-status status-connected">
|
||||
<span style="font-size: 1.2rem;">✅</span>
|
||||
<div>
|
||||
<strong>Connected as {user_info['name']}</strong>
|
||||
<div style="font-size: 0.9rem; opacity: 0.8;">{user_info['handle']}</div>
|
||||
</div>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
else:
|
||||
st.markdown("""
|
||||
<div class="connection-status status-disconnected">
|
||||
<span style="font-size: 1.2rem;">⚠️</span>
|
||||
<div>
|
||||
<strong>Twitter Not Connected</strong>
|
||||
<div style="font-size: 0.9rem; opacity: 0.8;">Connect your account to access all features</div>
|
||||
</div>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
if st.button("🔗 Connect Twitter Account", key="connect_twitter"):
|
||||
# Simulate connection (replace with real OAuth flow)
|
||||
save_to_session("twitter_connected", True)
|
||||
save_to_session("twitter_user", {"name": "Demo User", "handle": "@demo_user"})
|
||||
st.rerun()
|
||||
|
||||
def render_dashboard_header():
|
||||
"""Render the modern dashboard header."""
|
||||
st.markdown("""
|
||||
<div class="dashboard-header">
|
||||
<h1 class="dashboard-title">🐦 Twitter AI Dashboard</h1>
|
||||
<p class="dashboard-subtitle">Create, analyze, and optimize your Twitter content with AI-powered tools</p>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
def render_quick_actions():
|
||||
"""Render quick action buttons."""
|
||||
st.markdown("### 🚀 Quick Actions")
|
||||
|
||||
col1, col2, col3, col4 = st.columns(4)
|
||||
|
||||
with col1:
|
||||
if st.button("✍️ Create Tweet", use_container_width=True, key="quick_tweet"):
|
||||
st.session_state.current_page = "tweet_generator"
|
||||
st.rerun()
|
||||
|
||||
with col2:
|
||||
if st.button("📊 View Analytics", use_container_width=True, key="quick_analytics"):
|
||||
st.session_state.current_page = "analytics"
|
||||
st.rerun()
|
||||
|
||||
with col3:
|
||||
if st.button("📅 Content Calendar", use_container_width=True, key="quick_calendar"):
|
||||
show_info_message("Content Calendar feature coming soon!")
|
||||
|
||||
with col4:
|
||||
if st.button("⚙️ Settings", use_container_width=True, key="quick_settings"):
|
||||
st.session_state.current_page = "settings"
|
||||
st.rerun()
|
||||
|
||||
def render_metrics_overview():
|
||||
"""Render key metrics overview."""
|
||||
st.markdown("### 📈 Performance Overview")
|
||||
|
||||
# Generate sample metrics (replace with real data)
|
||||
col1, col2, col3, col4 = st.columns(4)
|
||||
|
||||
with col1:
|
||||
st.markdown("""
|
||||
<div class="metric-card">
|
||||
<div class="metric-value">1,234</div>
|
||||
<div class="metric-label">Total Tweets</div>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
with col2:
|
||||
st.markdown("""
|
||||
<div class="metric-card">
|
||||
<div class="metric-value">45.2K</div>
|
||||
<div class="metric-label">Total Engagement</div>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
with col3:
|
||||
st.markdown("""
|
||||
<div class="metric-card">
|
||||
<div class="metric-value">3.8%</div>
|
||||
<div class="metric-label">Engagement Rate</div>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
with col4:
|
||||
st.markdown("""
|
||||
<div class="metric-card">
|
||||
<div class="metric-value">12.5K</div>
|
||||
<div class="metric-label">Followers</div>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
def render_engagement_chart():
|
||||
"""Render engagement trends chart."""
|
||||
st.markdown("### 📊 Engagement Trends")
|
||||
|
||||
# Generate sample data (replace with real Twitter data)
|
||||
dates = pd.date_range(start=datetime.now() - timedelta(days=30), periods=30)
|
||||
engagement = np.random.normal(100, 20, 30)
|
||||
engagement = np.maximum(engagement, 0) # Ensure positive values
|
||||
|
||||
df = pd.DataFrame({
|
||||
'Date': dates,
|
||||
'Engagement': engagement,
|
||||
'Likes': engagement * 0.6,
|
||||
'Retweets': engagement * 0.3,
|
||||
'Replies': engagement * 0.1
|
||||
})
|
||||
|
||||
# Create interactive chart
|
||||
fig = make_subplots(
|
||||
rows=2, cols=1,
|
||||
subplot_titles=('Total Engagement', 'Engagement Breakdown'),
|
||||
vertical_spacing=0.1,
|
||||
row_heights=[0.7, 0.3]
|
||||
)
|
||||
|
||||
# Main engagement line
|
||||
fig.add_trace(
|
||||
go.Scatter(
|
||||
x=df['Date'],
|
||||
y=df['Engagement'],
|
||||
mode='lines+markers',
|
||||
name='Total Engagement',
|
||||
line=dict(color='#1DA1F2', width=3),
|
||||
marker=dict(size=6)
|
||||
),
|
||||
row=1, col=1
|
||||
)
|
||||
|
||||
# Stacked area chart for breakdown
|
||||
fig.add_trace(
|
||||
go.Scatter(
|
||||
x=df['Date'],
|
||||
y=df['Likes'],
|
||||
mode='lines',
|
||||
name='Likes',
|
||||
fill='tonexty',
|
||||
line=dict(color='#E53E3E')
|
||||
),
|
||||
row=2, col=1
|
||||
)
|
||||
|
||||
fig.add_trace(
|
||||
go.Scatter(
|
||||
x=df['Date'],
|
||||
y=df['Retweets'],
|
||||
mode='lines',
|
||||
name='Retweets',
|
||||
fill='tonexty',
|
||||
line=dict(color='#38A169')
|
||||
),
|
||||
row=2, col=1
|
||||
)
|
||||
|
||||
fig.add_trace(
|
||||
go.Scatter(
|
||||
x=df['Date'],
|
||||
y=df['Replies'],
|
||||
mode='lines',
|
||||
name='Replies',
|
||||
fill='tonexty',
|
||||
line=dict(color='#D69E2E')
|
||||
),
|
||||
row=2, col=1
|
||||
)
|
||||
|
||||
fig.update_layout(
|
||||
height=500,
|
||||
showlegend=True,
|
||||
hovermode='x unified',
|
||||
plot_bgcolor='rgba(0,0,0,0)',
|
||||
paper_bgcolor='rgba(0,0,0,0)'
|
||||
)
|
||||
|
||||
fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='rgba(0,0,0,0.1)')
|
||||
fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='rgba(0,0,0,0.1)')
|
||||
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
|
||||
def render_feature_grid():
|
||||
"""Render the feature grid with modern cards."""
|
||||
st.markdown("### 🛠️ Available Tools")
|
||||
|
||||
features = [
|
||||
{
|
||||
"title": "Smart Tweet Generator",
|
||||
"description": "Create engaging tweets with AI assistance, hashtag suggestions, and emoji optimization",
|
||||
"icon": "✨",
|
||||
"status": "active",
|
||||
"action": "tweet_generator"
|
||||
},
|
||||
{
|
||||
"title": "Performance Predictor",
|
||||
"description": "Predict tweet engagement and find optimal posting times",
|
||||
"icon": "🔮",
|
||||
"status": "coming_soon",
|
||||
"action": None
|
||||
},
|
||||
{
|
||||
"title": "Content Calendar",
|
||||
"description": "Plan and schedule your Twitter content strategy",
|
||||
"icon": "📅",
|
||||
"status": "coming_soon",
|
||||
"action": None
|
||||
},
|
||||
{
|
||||
"title": "Hashtag Research",
|
||||
"description": "Discover trending hashtags and analyze their performance",
|
||||
"icon": "#️⃣",
|
||||
"status": "coming_soon",
|
||||
"action": None
|
||||
},
|
||||
{
|
||||
"title": "Visual Content",
|
||||
"description": "Create quote cards, infographics, and visual tweets",
|
||||
"icon": "🎨",
|
||||
"status": "coming_soon",
|
||||
"action": None
|
||||
},
|
||||
{
|
||||
"title": "Analytics Dashboard",
|
||||
"description": "Deep dive into your Twitter performance metrics",
|
||||
"icon": "📊",
|
||||
"status": "coming_soon",
|
||||
"action": None
|
||||
}
|
||||
]
|
||||
|
||||
# Create grid layout
|
||||
cols = st.columns(3)
|
||||
|
||||
for i, feature in enumerate(features):
|
||||
with cols[i % 3]:
|
||||
status_class = "status-active" if feature["status"] == "active" else "status-coming-soon"
|
||||
|
||||
card_html = f"""
|
||||
<div class="feature-card" onclick="handleFeatureClick('{feature['action']}')">
|
||||
<span class="feature-icon">{feature['icon']}</span>
|
||||
<h3 class="feature-title">{feature['title']}</h3>
|
||||
<p class="feature-description">{feature['description']}</p>
|
||||
<span class="feature-status {status_class}">{feature['status'].replace('_', ' ')}</span>
|
||||
</div>
|
||||
"""
|
||||
|
||||
st.markdown(card_html, unsafe_allow_html=True)
|
||||
|
||||
# Add button for active features
|
||||
if feature["status"] == "active" and feature["action"]:
|
||||
if st.button(f"Launch {feature['title']}", key=f"launch_{i}", use_container_width=True):
|
||||
st.session_state.current_page = feature["action"]
|
||||
st.rerun()
|
||||
|
||||
def render_recent_activity():
|
||||
"""Render recent activity feed."""
|
||||
st.markdown("### 📱 Recent Activity")
|
||||
|
||||
# Sample activity data (replace with real data)
|
||||
activities = [
|
||||
{"time": "2 hours ago", "action": "Generated tweet", "details": "AI-powered content about social media trends"},
|
||||
{"time": "5 hours ago", "action": "Analyzed performance", "details": "Tweet received 45 likes and 12 retweets"},
|
||||
{"time": "1 day ago", "action": "Scheduled tweet", "details": "Content scheduled for optimal posting time"},
|
||||
{"time": "2 days ago", "action": "Updated hashtags", "details": "Added trending hashtags to improve reach"}
|
||||
]
|
||||
|
||||
for activity in activities:
|
||||
st.markdown(f"""
|
||||
<div style="
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
margin-bottom: 0.5rem;
|
||||
border-left: 3px solid #1DA1F2;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
|
||||
">
|
||||
<div style="font-weight: 600; color: #2D3748; margin-bottom: 0.25rem;">
|
||||
{activity['action']}
|
||||
</div>
|
||||
<div style="color: #718096; font-size: 0.9rem; margin-bottom: 0.25rem;">
|
||||
{activity['details']}
|
||||
</div>
|
||||
<div style="color: #A0AEC0; font-size: 0.8rem;">
|
||||
{activity['time']}
|
||||
</div>
|
||||
</div>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
def run_dashboard():
|
||||
"""Main function to run the enhanced Twitter dashboard."""
|
||||
# Apply modern styling
|
||||
apply_modern_styling()
|
||||
|
||||
# Initialize session state
|
||||
if "current_page" not in st.session_state:
|
||||
st.session_state.current_page = "dashboard"
|
||||
|
||||
# Handle page navigation
|
||||
if st.session_state.current_page == "tweet_generator":
|
||||
if st.button("← Back to Dashboard", key="back_to_dashboard"):
|
||||
st.session_state.current_page = "dashboard"
|
||||
st.rerun()
|
||||
smart_tweet_generator()
|
||||
return
|
||||
|
||||
# Main dashboard container
|
||||
st.markdown('<div class="main-container">', unsafe_allow_html=True)
|
||||
|
||||
# Render dashboard header
|
||||
render_dashboard_header()
|
||||
|
||||
# Render connection status
|
||||
render_connection_status()
|
||||
|
||||
# Create main layout
|
||||
tab1, tab2, tab3 = st.tabs(["🏠 Overview", "📊 Analytics", "⚙️ Settings"])
|
||||
|
||||
with tab1:
|
||||
# Quick actions
|
||||
render_quick_actions()
|
||||
|
||||
# Metrics overview
|
||||
render_metrics_overview()
|
||||
|
||||
# Feature grid
|
||||
render_feature_grid()
|
||||
|
||||
# Recent activity
|
||||
col1, col2 = st.columns([2, 1])
|
||||
with col1:
|
||||
render_engagement_chart()
|
||||
with col2:
|
||||
render_recent_activity()
|
||||
|
||||
with tab2:
|
||||
st.markdown("### 📈 Advanced Analytics")
|
||||
|
||||
# Time range selector
|
||||
col1, col2 = st.columns([1, 3])
|
||||
with col1:
|
||||
time_range = st.selectbox(
|
||||
"Time Range",
|
||||
["Last 7 days", "Last 30 days", "Last 90 days", "Last year"],
|
||||
index=1
|
||||
)
|
||||
|
||||
# Detailed analytics
|
||||
render_engagement_chart()
|
||||
|
||||
# Performance insights
|
||||
st.markdown("### 💡 Performance Insights")
|
||||
|
||||
insights = [
|
||||
"Your tweets perform 23% better when posted between 2-4 PM",
|
||||
"Tweets with 2-3 hashtags get 15% more engagement",
|
||||
"Visual content increases engagement by 35%",
|
||||
"Questions in tweets boost replies by 28%"
|
||||
]
|
||||
|
||||
for insight in insights:
|
||||
st.info(f"💡 {insight}")
|
||||
|
||||
with tab3:
|
||||
st.markdown("### ⚙️ Dashboard Settings")
|
||||
|
||||
# Twitter API settings
|
||||
with st.expander("🔑 Twitter API Configuration", expanded=False):
|
||||
st.markdown("Configure your Twitter API credentials to enable full functionality.")
|
||||
|
||||
api_key = st.text_input("API Key", type="password", help="Your Twitter API key")
|
||||
api_secret = st.text_input("API Secret", type="password", help="Your Twitter API secret")
|
||||
access_token = st.text_input("Access Token", type="password", help="Your Twitter access token")
|
||||
access_token_secret = st.text_input("Access Token Secret", type="password", help="Your Twitter access token secret")
|
||||
|
||||
if st.button("Save API Configuration"):
|
||||
# Save configuration (implement secure storage)
|
||||
show_success_message("API configuration saved successfully!")
|
||||
|
||||
# Dashboard preferences
|
||||
with st.expander("🎨 Dashboard Preferences", expanded=True):
|
||||
theme = st.selectbox("Theme", ["Light", "Dark", "Auto"], index=0)
|
||||
default_tone = st.selectbox("Default Tweet Tone", ["Professional", "Casual", "Humorous", "Inspirational"], index=1)
|
||||
auto_hashtags = st.checkbox("Auto-suggest hashtags", value=True)
|
||||
|
||||
if st.button("Save Preferences"):
|
||||
show_success_message("Preferences saved successfully!")
|
||||
|
||||
# Account management
|
||||
with st.expander("👤 Account Management", expanded=False):
|
||||
st.markdown("Manage your connected Twitter accounts and permissions.")
|
||||
|
||||
if get_from_session("twitter_connected", False):
|
||||
st.success("✅ Twitter account connected")
|
||||
if st.button("Disconnect Account"):
|
||||
save_to_session("twitter_connected", False)
|
||||
st.rerun()
|
||||
else:
|
||||
st.warning("⚠️ No Twitter account connected")
|
||||
if st.button("Connect Account"):
|
||||
save_to_session("twitter_connected", True)
|
||||
st.rerun()
|
||||
|
||||
st.markdown('</div>', unsafe_allow_html=True)
|
||||
|
||||
# JavaScript for handling feature clicks
|
||||
st.markdown("""
|
||||
<script>
|
||||
function handleFeatureClick(action) {
|
||||
if (action && action !== 'null') {
|
||||
// This would trigger a Streamlit rerun with the selected action
|
||||
console.log('Feature clicked:', action);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_dashboard()
|
||||
Reference in New Issue
Block a user