help@rskworld.in +91 93305 39277
RSK World
  • Home
  • Development
    • Web Development
    • Mobile Apps
    • Software
    • Games
    • Project
  • Technologies
    • Data Science
    • AI Development
    • Cloud Development
    • Blockchain
    • Cyber Security
    • Dev Tools
    • Testing Tools
  • Blog
  • About
  • Contact

Theme Settings

Color Scheme
Display Options
Font Size
100%
Back to Project
RSK World
news-summary-bot
/
templates
/
admin
RSK World
news-summary-bot
News Summary Bot - Python + Flask + OpenAI + NewsAPI + AI Summarization + Real-time News + News Aggregation
admin
  • analytics.html14.5 KB
  • content.html15.6 KB
  • dashboard.html18.7 KB
  • login.html5.5 KB
  • settings.html18.6 KB
  • users.html12.1 KB
dashboard.html
templates/admin/dashboard.html
Raw Download
Find: Go to:
<!DOCTYPE html>
<html lang="en">
<!--
    Admin Dashboard - News Summary Bot
    Developer: Molla Samser
    Design & Testing: Rima Khatun
    Company: RSK World
    Year: 2026
    Website: https://rskworld.in
-->
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Admin Dashboard - News Summary Bot</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
        :root {
            --primary: #dc3545;
            --secondary: #0d6efd;
            --success: #28a745;
            --warning: #ffc107;
            --info: #17a2b8;
            --dark: #1a1a1a;
            --glass: rgba(255, 255, 255, 0.1);
            --glass-border: rgba(255, 255, 255, 0.2);
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Outfit', sans-serif;
            background: #0f0f0f;
            color: white;
            line-height: 1.6;
        }

        .admin-container {
            display: flex;
            min-height: 100vh;
        }

        .sidebar {
            width: 250px;
            background: var(--glass);
            backdrop-filter: blur(10px);
            border-right: 1px solid var(--glass-border);
            padding: 2rem 1rem;
        }

        .sidebar-header {
            display: flex;
            align-items: center;
            margin-bottom: 2rem;
        }

        .sidebar-header i {
            font-size: 2rem;
            color: var(--primary);
            margin-right: 1rem;
        }

        .sidebar-header h2 {
            font-size: 1.2rem;
            font-weight: 600;
        }

        .nav-menu {
            list-style: none;
        }

        .nav-item {
            margin-bottom: 0.5rem;
        }

        .nav-link {
            display: flex;
            align-items: center;
            padding: 0.75rem 1rem;
            color: white;
            text-decoration: none;
            border-radius: 10px;
            transition: all 0.3s ease;
        }

        .nav-link:hover, .nav-link.active {
            background: var(--glass);
            border: 1px solid var(--glass-border);
        }

        .nav-link i {
            margin-right: 0.75rem;
            width: 20px;
        }

        .main-content {
            flex: 1;
            padding: 2rem;
            overflow-y: auto;
        }

        .header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 2rem;
        }

        .header h1 {
            font-size: 2rem;
            font-weight: 600;
        }

        .header-actions {
            display: flex;
            gap: 1rem;
        }

        .btn {
            padding: 0.5rem 1rem;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            text-decoration: none;
            display: inline-flex;
            align-items: center;
            gap: 0.5rem;
            transition: all 0.3s ease;
        }

        .btn-primary {
            background: var(--primary);
            color: white;
        }

        .btn-secondary {
            background: var(--glass);
            color: white;
            border: 1px solid var(--glass-border);
        }

        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: 1.5rem;
            margin-bottom: 2rem;
        }

        .stat-card {
            background: var(--glass);
            backdrop-filter: blur(10px);
            border: 1px solid var(--glass-border);
            border-radius: 15px;
            padding: 1.5rem;
            transition: all 0.3s ease;
        }

        .stat-card:hover {
            transform: translateY(-5px);
        }

        .stat-icon {
            width: 50px;
            height: 50px;
            border-radius: 10px;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-bottom: 1rem;
            font-size: 1.5rem;
        }

        .stat-icon.primary {
            background: rgba(220, 53, 69, 0.2);
            color: var(--primary);
        }

        .stat-icon.success {
            background: rgba(40, 167, 69, 0.2);
            color: var(--success);
        }

        .stat-icon.info {
            background: rgba(23, 162, 184, 0.2);
            color: var(--info);
        }

        .stat-icon.warning {
            background: rgba(255, 193, 7, 0.2);
            color: var(--warning);
        }

        .stat-value {
            font-size: 2rem;
            font-weight: 700;
            margin-bottom: 0.5rem;
        }

        .stat-label {
            color: rgba(255, 255, 255, 0.7);
            font-size: 0.9rem;
        }

        .charts-grid {
            display: grid;
            grid-template-columns: 2fr 1fr;
            gap: 1.5rem;
            margin-bottom: 2rem;
        }

        .chart-card {
            background: var(--glass);
            backdrop-filter: blur(10px);
            border: 1px solid var(--glass-border);
            border-radius: 15px;
            padding: 1.5rem;
        }

        .chart-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 1.5rem;
        }

        .chart-title {
            font-size: 1.2rem;
            font-weight: 600;
        }

        .trending-topics {
            background: var(--glass);
            backdrop-filter: blur(10px);
            border: 1px solid var(--glass-border);
            border-radius: 15px;
            padding: 1.5rem;
        }

        .trending-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 0.75rem 0;
            border-bottom: 1px solid var(--glass-border);
        }

        .trending-item:last-child {
            border-bottom: none;
        }

        .trending-keywords {
            display: flex;
            gap: 0.5rem;
            flex-wrap: wrap;
        }

        .keyword-tag {
            background: rgba(220, 53, 69, 0.2);
            color: var(--primary);
            padding: 0.25rem 0.5rem;
            border-radius: 5px;
            font-size: 0.8rem;
        }

        .trending-meta {
            display: flex;
            align-items: center;
            gap: 1rem;
            color: rgba(255, 255, 255, 0.7);
            font-size: 0.9rem;
        }

        .footer {
            text-align: center;
            padding: 2rem;
            color: rgba(255, 255, 255, 0.5);
            font-size: 0.9rem;
        }

        .footer a {
            color: var(--primary);
            text-decoration: none;
        }

        @media (max-width: 768px) {
            .admin-container {
                flex-direction: column;
            }

            .sidebar {
                width: 100%;
                border-right: none;
                border-bottom: 1px solid var(--glass-border);
            }

            .charts-grid {
                grid-template-columns: 1fr;
            }
        }
    </style>
</head>
<body>
    <div class="admin-container">
        <aside class="sidebar">
            <div class="sidebar-header">
                <i class="fas fa-newspaper"></i>
                <h2>Admin Panel</h2>
            </div>
            
            <ul class="nav-menu">
                <li class="nav-item">
                    <a href="{{ url_for('admin.dashboard') }}" class="nav-link active">
                        <i class="fas fa-tachometer-alt"></i>
                        Dashboard
                    </a>
                </li>
                <li class="nav-item">
                    <a href="{{ url_for('admin.analytics_page') }}" class="nav-link">
                        <i class="fas fa-chart-line"></i>
                        Analytics
                    </a>
                </li>
                <li class="nav-item">
                    <a href="{{ url_for('admin.users') }}" class="nav-link">
                        <i class="fas fa-users"></i>
                        Users
                    </a>
                </li>
                <li class="nav-item">
                    <a href="{{ url_for('admin.content') }}" class="nav-link">
                        <i class="fas fa-newspaper"></i>
                        Content
                    </a>
                </li>
                <li class="nav-item">
                    <a href="{{ url_for('admin.settings') }}" class="nav-link">
                        <i class="fas fa-cog"></i>
                        Settings
                    </a>
                </li>
                <li class="nav-item">
                    <a href="{{ url_for('admin.logout') }}" class="nav-link">
                        <i class="fas fa-sign-out-alt"></i>
                        Logout
                    </a>
                </li>
            </ul>
        </aside>

        <main class="main-content">
            <header class="header">
                <h1>Dashboard Overview</h1>
                <div class="header-actions">
                    <button class="btn btn-secondary" onclick="refreshData()">
                        <i class="fas fa-sync-alt"></i> Refresh
                    </button>
                    <a href="/" class="btn btn-primary">
                        <i class="fas fa-external-link-alt"></i> View Site
                    </a>
                </div>
            </header>

            <div class="stats-grid">
                <div class="stat-card">
                    <div class="stat-icon primary">
                        <i class="fas fa-newspaper"></i>
                    </div>
                    <div class="stat-value">{{ total_articles }}</div>
                    <div class="stat-label">Total Articles</div>
                </div>

                <div class="stat-card">
                    <div class="stat-icon success">
                        <i class="fas fa-users"></i>
                    </div>
                    <div class="stat-value">{{ total_users }}</div>
                    <div class="stat-label">Active Users</div>
                </div>

                <div class="stat-card">
                    <div class="stat-icon info">
                        <i class="fas fa-chart-line"></i>
                    </div>
                    <div class="stat-value">{{ "%.1f"|format(avg_reliability) }}%</div>
                    <div class="stat-label">Avg Reliability</div>
                </div>

                <div class="stat-card">
                    <div class="stat-icon warning">
                        <i class="fas fa-fire"></i>
                    </div>
                    <div class="stat-value">{{ trending_topics|length }}</div>
                    <div class="stat-label">Trending Topics</div>
                </div>
            </div>

            <div class="charts-grid">
                <div class="chart-card">
                    <div class="chart-header">
                        <h3 class="chart-title">Sentiment Trends</h3>
                        <select id="sentimentPeriod" onchange="updateSentimentChart()">
                            <option value="7">7 Days</option>
                            <option value="30" selected>30 Days</option>
                            <option value="90">90 Days</option>
                        </select>
                    </div>
                    <canvas id="sentimentChart" width="400" height="200"></canvas>
                </div>

                <div class="chart-card">
                    <div class="chart-header">
                        <h3 class="chart-title">Category Distribution</h3>
                    </div>
                    <canvas id="categoryChart" width="200" height="200"></canvas>
                </div>
            </div>

            <div class="trending-topics">
                <div class="chart-header">
                    <h3 class="chart-title">Trending Topics</h3>
                    <a href="{{ url_for('admin.analytics_page') }}" class="btn btn-secondary">View All</a>
                </div>
                
                {% for topic in trending_topics %}
                <div class="trending-item">
                    <div class="trending-keywords">
                        {% for keyword in topic.keywords %}
                        <span class="keyword-tag">{{ keyword }}</span>
                        {% endfor %}
                    </div>
                    <div class="trending-meta">
                        <span><i class="fas fa-folder"></i> {{ topic.category }}</span>
                        <span><i class="fas fa-fire"></i> {{ topic.frequency }}</span>
                    </div>
                </div>
                {% endfor %}
            </div>
        </main>
    </div>

    <footer class="footer">
        <p>&copy; 2026 <a href="https://rskworld.in">RSK World</a>. All rights reserved.</p>
        <p>Developed by Molla Samser | Design & Testing by Rima Khatun</p>
    </footer>

    <script>
        // Sentiment Trends Chart
        const sentimentCtx = document.getElementById('sentimentChart').getContext('2d');
        
        // Parse Flask template data safely
        const sentimentData = {{ sentiment_trends | tojson }};
        const categoryData = {{ category_stats | tojson }};
        
        const sentimentLabels = Object.keys(sentimentData);
        const sentimentDataPositive = sentimentLabels.map(date => sentimentData[date].Positive || 0);
        const sentimentDataNegative = sentimentLabels.map(date => sentimentData[date].Negative || 0);
        const sentimentDataNeutral = sentimentLabels.map(date => sentimentData[date].Neutral || 0);
        
        const sentimentChart = new Chart(sentimentCtx, {
            type: 'line',
            data: {
                labels: sentimentLabels,
                datasets: [
                    {
                        label: 'Positive',
                        data: sentimentDataPositive,
                        borderColor: '#28a745',
                        backgroundColor: 'rgba(40, 167, 69, 0.1)',
                        tension: 0.4
                    },
                    {
                        label: 'Negative',
                        data: sentimentDataNegative,
                        borderColor: '#dc3545',
                        backgroundColor: 'rgba(220, 53, 69, 0.1)',
                        tension: 0.4
                    },
                    {
                        label: 'Neutral',
                        data: sentimentDataNeutral,
                        borderColor: '#ffc107',
                        backgroundColor: 'rgba(255, 193, 7, 0.1)',
                        tension: 0.4
                    }
                ]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    legend: {
                        labels: {
                            color: 'white'
                        }
                    }
                },
                scales: {
                    x: {
                        ticks: {
                            color: 'white'
                        },
                        grid: {
                            color: 'rgba(255, 255, 255, 0.1)'
                        }
                    },
                    y: {
                        ticks: {
                            color: 'white'
                        },
                        grid: {
                            color: 'rgba(255, 255, 255, 0.1)'
                        }
                    }
                }
            }
        });

        // Category Distribution Chart
        const categoryCtx = document.getElementById('categoryChart').getContext('2d');
        const categoryLabels = Object.keys(categoryData);
        const categoryValues = categoryLabels.map(cat => categoryData[cat].total_articles || 0);
        
        const categoryChart = new Chart(categoryCtx, {
            type: 'doughnut',
            data: {
                labels: categoryLabels,
                datasets: [{
                    data: categoryValues,
                    backgroundColor: [
                        '#dc3545',
                        '#0d6efd',
                        '#28a745',
                        '#ffc107',
                        '#17a2b8',
                        '#6f42c1',
                        '#fd7e14'
                    ]
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                plugins: {
                    legend: {
                        position: 'bottom',
                        labels: {
                            color: 'white'
                        }
                    }
                }
            }
        });

        function refreshData() {
            location.reload();
        }

        function updateSentimentChart() {
            const period = document.getElementById('sentimentPeriod').value;
            // Fetch new data based on period
            fetch(`/admin/api/analytics/data?type=sentiment&days=${period}`)
                .then(response => response.json())
                .then(data => {
                    // Update chart with new data
                    const newLabels = Object.keys(data);
                    const newPositive = newLabels.map(date => data[date].Positive || 0);
                    const newNegative = newLabels.map(date => data[date].Negative || 0);
                    const newNeutral = newLabels.map(date => data[date].Neutral || 0);
                    
                    sentimentChart.data.labels = newLabels;
                    sentimentChart.data.datasets[0].data = newPositive;
                    sentimentChart.data.datasets[1].data = newNegative;
                    sentimentChart.data.datasets[2].data = newNeutral;
                    sentimentChart.update();
                });
        }
    </script>
</body>
</html>
585 lines•18.7 KB
markup
🚀 Support RSK World

Subscribe to our YouTube channel for latest tutorials & updates!



Click subscribe & support our work ❤️

About RSK World

Founded by Molla Samser, with Designer & Tester Rima Khatun, RSK World is your one-stop destination for free programming resources, source code, and development tools.

Founder: Molla Samser
Designer & Tester: Rima Khatun

Development

  • Game Development
  • Web Development
  • Mobile Development
  • AI Development
  • Development Tools

Legal

  • Terms & Conditions
  • Privacy Policy
  • Disclaimer

Contact Info

Nutanhat, Mongolkote
Purba Burdwan, West Bengal
India, 713147

+91 93305 39277

hello@rskworld.in
support@rskworld.in

© 2026 RSK World. All rights reserved.

Content used for educational purposes only. View Disclaimer