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
fitness-coach-bot
/
static
/
js
RSK World
fitness-coach-bot
Fitness Coach Bot - Python + Flask + SQLAlchemy + Workout Plans + Exercise Guidance + Health Tracking + AI Fitness Coach
js
  • analytics_dashboard.js11.7 KB
  • app.js11.7 KB
  • pose_detection.js21.3 KB
  • voice_recognition.js8 KB
analytics_dashboard.jsapp.js
static/js/analytics_dashboard.js
Raw Download
Find: Go to:
/**
 * Advanced Analytics Dashboard with Visualizations
 * Author: RSK World (https://rskworld.in)
 * Founded by: Molla Samser
 * Designer & Tester: Rima Khatun
 * Contact: help@rskworld.in, +91 93305 39277
 * Year: 2026
 */

class AnalyticsDashboard {
    constructor() {
        this.charts = {};
        this.data = {};
        this.init();
    }

    async init() {
        await this.loadChartsLibrary();
        this.loadAnalyticsData();
        this.setupEventListeners();
    }

    async loadChartsLibrary() {
        // Load Chart.js
        if (typeof Chart === 'undefined') {
            const script = document.createElement('script');
            script.src = 'https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js';
            document.head.appendChild(script);
            await new Promise(resolve => script.onload = resolve);
        }
    }

    async loadAnalyticsData() {
        try {
            const response = await fetch('/api/analytics?timeframe=30');
            const data = await response.json();
            
            if (data.success) {
                this.data = data.analytics;
                this.renderAllCharts();
            }
        } catch (error) {
            console.error('Error loading analytics:', error);
        }
    }

    renderAllCharts() {
        this.renderWorkoutFrequencyChart();
        this.renderProgressChart();
        this.renderStrengthChart();
        this.renderNutritionChart();
        this.renderRecoveryChart();
        this.renderRadarChart();
    }

    renderWorkoutFrequencyChart() {
        const ctx = document.getElementById('workoutFrequencyChart');
        if (!ctx) return;

        const categories = this.data.categories || {};
        const workout = categories.workout || {};

        this.charts.workoutFrequency = new Chart(ctx, {
            type: 'line',
            data: {
                labels: this.generateDateLabels(30),
                datasets: [{
                    label: 'Workouts per Week',
                    data: this.generateWorkoutData(),
                    borderColor: 'rgb(75, 192, 192)',
                    backgroundColor: 'rgba(75, 192, 192, 0.2)',
                    tension: 0.4,
                    fill: true
                }]
            },
            options: {
                responsive: true,
                plugins: {
                    title: {
                        display: true,
                        text: 'Workout Frequency Trend'
                    },
                    legend: {
                        display: true
                    }
                },
                scales: {
                    y: {
                        beginAtZero: true,
                        ticks: {
                            stepSize: 1
                        }
                    }
                }
            }
        });
    }

    renderProgressChart() {
        const ctx = document.getElementById('progressChart');
        if (!ctx) return;

        const body = this.data.categories?.body || {};
        const metrics = body.body_metrics || {};

        this.charts.progress = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: ['Weight', 'Body Fat %', 'Muscle Mass'],
                datasets: [{
                    label: 'Current',
                    data: [
                        metrics.weight?.current || 0,
                        metrics.body_fat?.current || 0,
                        metrics.muscle_mass?.current || 0
                    ],
                    backgroundColor: [
                        'rgba(54, 162, 235, 0.8)',
                        'rgba(255, 99, 132, 0.8)',
                        'rgba(75, 192, 192, 0.8)'
                    ]
                }, {
                    label: 'Start',
                    data: [
                        metrics.weight?.start || 0,
                        metrics.body_fat?.start || 0,
                        metrics.muscle_mass?.start || 0
                    ],
                    backgroundColor: [
                        'rgba(54, 162, 235, 0.4)',
                        'rgba(255, 99, 132, 0.4)',
                        'rgba(75, 192, 192, 0.4)'
                    ]
                }]
            },
            options: {
                responsive: true,
                plugins: {
                    title: {
                        display: true,
                        text: 'Body Composition Progress'
                    }
                },
                scales: {
                    y: {
                        beginAtZero: true
                    }
                }
            }
        });
    }

    renderStrengthChart() {
        const ctx = document.getElementById('strengthChart');
        if (!ctx) return;

        const strength = this.data.categories?.strength || {};
        const exercises = strength.strength_exercises || {};

        const exerciseNames = Object.keys(exercises);
        const improvements = exerciseNames.map(name => exercises[name].improvement || 0);

        this.charts.strength = new Chart(ctx, {
            type: 'line',
            data: {
                labels: exerciseNames.map(name => name.replace('_', ' ').toUpperCase()),
                datasets: [{
                    label: 'Strength Improvement %',
                    data: improvements,
                    borderColor: 'rgb(255, 99, 132)',
                    backgroundColor: 'rgba(255, 99, 132, 0.2)',
                    tension: 0.4,
                    fill: true
                }]
            },
            options: {
                responsive: true,
                plugins: {
                    title: {
                        display: true,
                        text: 'Strength Progress by Exercise'
                    }
                },
                scales: {
                    y: {
                        beginAtZero: true,
                        ticks: {
                            callback: function(value) {
                                return value + '%';
                            }
                        }
                    }
                }
            }
        });
    }

    renderNutritionChart() {
        const ctx = document.getElementById('nutritionChart');
        if (!ctx) return;

        const nutrition = this.data.categories?.nutrition || {};
        const macros = nutrition.macro_distribution || {};

        this.charts.nutrition = new Chart(ctx, {
            type: 'doughnut',
            data: {
                labels: ['Protein', 'Carbs', 'Fats'],
                datasets: [{
                    data: [
                        macros.protein || 0,
                        macros.carbs || 0,
                        macros.fat || 0
                    ],
                    backgroundColor: [
                        'rgba(255, 99, 132, 0.8)',
                        'rgba(54, 162, 235, 0.8)',
                        'rgba(255, 206, 86, 0.8)'
                    ]
                }]
            },
            options: {
                responsive: true,
                plugins: {
                    title: {
                        display: true,
                        text: 'Macronutrient Distribution'
                    },
                    legend: {
                        position: 'bottom'
                    }
                }
            }
        });
    }

    renderRecoveryChart() {
        const ctx = document.getElementById('recoveryChart');
        if (!ctx) return;

        const recovery = this.data.categories?.recovery || {};
        const sleep = recovery.sleep_data || {};

        this.charts.recovery = new Chart(ctx, {
            type: 'radar',
            data: {
                labels: ['Sleep Duration', 'Sleep Quality', 'Consistency', 'Recovery Score'],
                datasets: [{
                    label: 'Recovery Metrics',
                    data: [
                        (sleep.avg_duration || 0) * 10, // Scale to 0-100
                        sleep.avg_quality || 0,
                        sleep.consistency || 0,
                        recovery.recovery_score || 0
                    ],
                    backgroundColor: 'rgba(75, 192, 192, 0.2)',
                    borderColor: 'rgb(75, 192, 192)',
                    pointBackgroundColor: 'rgb(75, 192, 192)'
                }]
            },
            options: {
                responsive: true,
                plugins: {
                    title: {
                        display: true,
                        text: 'Recovery Overview'
                    }
                },
                scales: {
                    r: {
                        beginAtZero: true,
                        max: 100
                    }
                }
            }
        });
    }

    renderRadarChart() {
        const ctx = document.getElementById('overallRadarChart');
        if (!ctx) return;

        const categories = this.data.categories || {};

        this.charts.overall = new Chart(ctx, {
            type: 'radar',
            data: {
                labels: ['Workout', 'Strength', 'Cardio', 'Nutrition', 'Recovery', 'Body'],
                datasets: [{
                    label: 'Overall Fitness Score',
                    data: [
                        categories.workout?.score || 0,
                        categories.strength?.score || 0,
                        categories.cardio?.score || 0,
                        categories.nutrition?.score || 0,
                        categories.recovery?.score || 0,
                        categories.body?.score || 0
                    ],
                    backgroundColor: 'rgba(153, 102, 255, 0.2)',
                    borderColor: 'rgb(153, 102, 255)',
                    pointBackgroundColor: 'rgb(153, 102, 255)'
                }]
            },
            options: {
                responsive: true,
                plugins: {
                    title: {
                        display: true,
                        text: 'Overall Fitness Profile'
                    }
                },
                scales: {
                    r: {
                        beginAtZero: true,
                        max: 100
                    }
                }
            }
        });
    }

    generateDateLabels(days) {
        const labels = [];
        const today = new Date();
        for (let i = days - 1; i >= 0; i--) {
            const date = new Date(today);
            date.setDate(date.getDate() - i);
            labels.push(date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }));
        }
        return labels;
    }

    generateWorkoutData() {
        // Generate sample data - in real app, would come from backend
        const data = [];
        for (let i = 0; i < 30; i++) {
            data.push(Math.floor(Math.random() * 7) + 1);
        }
        return data;
    }

    setupEventListeners() {
        const timeframeSelect = document.getElementById('timeframeSelect');
        if (timeframeSelect) {
            timeframeSelect.addEventListener('change', (e) => {
                this.loadAnalyticsData(e.target.value);
            });
        }
    }

    exportReport() {
        // Export analytics report as PDF/image
        window.print();
    }
}

// Initialize dashboard when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
    if (document.getElementById('analyticsDashboard')) {
        window.analyticsDashboard = new AnalyticsDashboard();
    }
});
363 lines•11.7 KB
javascript
static/js/app.js
Raw Download
Find: Go to:
/**
 * Fitness Coach Bot - Frontend JavaScript
 * Author: RSK World (https://rskworld.in)
 * Founded by: Molla Samser
 * Designer & Tester: Rima Khatun
 * Contact: help@rskworld.in, +91 93305 39277
 * Year: 2026
 */

class FitnessCoachBot {
    constructor() {
        this.init();
        this.loadUserProfile();
        this.loadHealthTips();
        this.updateStats();
    }

    init() {
        // Get DOM elements
        this.chatMessages = document.getElementById('chatMessages');
        this.messageInput = document.getElementById('messageInput');
        this.sendButton = document.getElementById('sendButton');
        this.profileForm = document.getElementById('profileForm');
        this.refreshTipsBtn = document.getElementById('refreshTips');
        
        // Event listeners
        this.sendButton.addEventListener('click', () => this.sendMessage());
        this.messageInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                this.sendMessage();
            }
        });
        
        this.profileForm.addEventListener('submit', (e) => {
            e.preventDefault();
            this.saveUserProfile();
        });
        
        this.refreshTipsBtn.addEventListener('click', () => this.loadHealthTips());
        
        // Quick suggestion buttons
        document.querySelectorAll('.quick-suggestion').forEach(button => {
            button.addEventListener('click', () => {
                this.messageInput.value = button.textContent;
                this.sendMessage();
            });
        });
        
        // Feature cards
        document.querySelectorAll('.feature-card').forEach(card => {
            card.addEventListener('click', () => {
                const feature = card.querySelector('h6').textContent;
                this.handleFeatureClick(feature);
            });
        });
    }

    async sendMessage() {
        const message = this.messageInput.value.trim();
        if (!message) return;

        // Add user message to chat
        this.addMessage(message, 'user');
        this.messageInput.value = '';
        
        // Show typing indicator
        this.showTypingIndicator();
        
        try {
            // Send message to backend
            const response = await fetch('/api/chat', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ message: message })
            });
            
            const data = await response.json();
            
            // Hide typing indicator
            this.hideTypingIndicator();
            
            if (data.success) {
                // Add bot response to chat
                this.addMessage(data.response, 'bot');
            } else {
                this.addMessage('Sorry, I encountered an error. Please try again.', 'bot');
            }
        } catch (error) {
            this.hideTypingIndicator();
            this.addMessage('Sorry, I\'m having trouble connecting. Please check your internet connection.', 'bot');
            console.error('Error sending message:', error);
        }
    }

    addMessage(content, sender) {
        const messageDiv = document.createElement('div');
        messageDiv.className = `message ${sender}-message mb-3 fade-in`;
        
        const avatarClass = sender === 'bot' ? 'bot-avatar' : 'user-avatar';
        const iconClass = sender === 'bot' ? 'fas fa-robot text-primary' : 'fas fa-user text-success';
        
        messageDiv.innerHTML = `
            <div class="d-flex">
                <div class="${avatarClass} me-2">
                    <i class="${iconClass}"></i>
                </div>
                <div class="message-content ${sender === 'user' ? 'bg-primary text-white' : 'bg-light'} rounded p-3">
                    <p class="mb-0">${content}</p>
                    <small class="${sender === 'user' ? 'text-white-50' : 'text-muted'}">${new Date().toLocaleTimeString()}</small>
                </div>
            </div>
        `;
        
        this.chatMessages.appendChild(messageDiv);
        this.scrollToBottom();
    }

    showTypingIndicator() {
        const typingDiv = document.createElement('div');
        typingDiv.className = 'typing-indicator active mb-3';
        typingDiv.id = 'typingIndicator';
        typingDiv.innerHTML = `
            <div class="d-flex">
                <div class="bot-avatar me-2">
                    <i class="fas fa-robot text-primary"></i>
                </div>
                <div class="message-content bg-light rounded p-3">
                    <div class="typing-dots">
                        <span></span>
                        <span></span>
                        <span></span>
                    </div>
                </div>
            </div>
        `;
        
        this.chatMessages.appendChild(typingDiv);
        this.scrollToBottom();
    }

    hideTypingIndicator() {
        const typingIndicator = document.getElementById('typingIndicator');
        if (typingIndicator) {
            typingIndicator.remove();
        }
    }

    scrollToBottom() {
        this.chatMessages.scrollTop = this.chatMessages.scrollHeight;
    }

    async saveUserProfile() {
        const profileData = {
            name: document.getElementById('userName').value,
            age: document.getElementById('userAge').value,
            weight: document.getElementById('userWeight').value,
            fitness_goal: document.getElementById('userGoal').value
        };

        try {
            const response = await fetch('/api/user/profile', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(profileData)
            });
            
            const data = await response.json();
            
            if (data.success) {
                this.showNotification('Profile saved successfully!', 'success');
                this.updateStats();
            } else {
                this.showNotification('Error saving profile. Please try again.', 'error');
            }
        } catch (error) {
            this.showNotification('Error saving profile. Please check your connection.', 'error');
            console.error('Error saving profile:', error);
        }
    }

    async loadUserProfile() {
        try {
            const response = await fetch('/api/user/profile');
            const data = await response.json();
            
            if (data.success && data.user) {
                const user = data.user;
                document.getElementById('userName').value = user.name || '';
                document.getElementById('userAge').value = user.age || '';
                document.getElementById('userWeight').value = user.weight || '';
                document.getElementById('userGoal').value = user.fitness_goal || '';
            }
        } catch (error) {
            console.error('Error loading profile:', error);
        }
    }

    async loadHealthTips() {
        try {
            const response = await fetch('/api/health-tips');
            const data = await response.json();
            
            if (data.success && data.tips) {
                const tipsContainer = document.getElementById('healthTips');
                tipsContainer.innerHTML = '';
                
                data.tips.forEach(tip => {
                    const tipDiv = document.createElement('div');
                    tipDiv.className = 'tip-item mb-2 fade-in';
                    tipDiv.innerHTML = `<small class="text-muted">💡 ${tip.title}</small>`;
                    tipsContainer.appendChild(tipDiv);
                });
            }
        } catch (error) {
            console.error('Error loading health tips:', error);
            // Fallback tips
            this.showFallbackTips();
        }
    }

    showFallbackTips() {
        const fallbackTips = [
            '💡 Drink at least 8 glasses of water daily',
            '🥗 Include protein in every meal',
            '😴 Get 7-9 hours of quality sleep',
            '🏃 Take regular movement breaks',
            '🧘 Practice stress management daily'
        ];
        
        const tipsContainer = document.getElementById('healthTips');
        tipsContainer.innerHTML = '';
        
        fallbackTips.forEach(tip => {
            const tipDiv = document.createElement('div');
            tipDiv.className = 'tip-item mb-2 fade-in';
            tipDiv.innerHTML = `<small class="text-muted">${tip}</small>`;
            tipsContainer.appendChild(tipDiv);
        });
    }

    async updateStats() {
        // Simulated stats - in real app, these would come from backend
        const stats = {
            workouts: Math.floor(Math.random() * 50) + 10,
            streak: Math.floor(Math.random() * 30) + 1,
            calories: Math.floor(Math.random() * 5000) + 1000,
            goals: Math.floor(Math.random() * 20) + 5
        };
        
        // Animate counter updates
        this.animateCounter('workoutCount', stats.workouts);
        this.animateCounter('streakCount', stats.streak);
        this.animateCounter('caloriesCount', stats.calories);
        this.animateCounter('goalsCount', stats.goals);
    }

    animateCounter(elementId, targetValue) {
        const element = document.getElementById(elementId);
        const duration = 1000;
        const step = targetValue / (duration / 16);
        let currentValue = 0;
        
        const timer = setInterval(() => {
            currentValue += step;
            if (currentValue >= targetValue) {
                currentValue = targetValue;
                clearInterval(timer);
            }
            element.textContent = Math.floor(currentValue);
        }, 16);
    }

    handleFeatureClick(feature) {
        const messages = {
            'Workout Plans': 'Can you create a personalized workout plan for me?',
            'Exercise Guidance': 'Show me proper form for basic exercises',
            'Progress Tracking': 'How can I track my fitness progress effectively?',
            'Health Tips': 'Give me some nutrition and health advice'
        };
        
        this.messageInput.value = messages[feature] || `Tell me about ${feature}`;
        this.sendMessage();
    }

    showNotification(message, type) {
        const notification = document.createElement('div');
        notification.className = `${type}-message position-fixed top-0 start-50 translate-middle-x mt-3`;
        notification.style.zIndex = '9999';
        notification.innerHTML = `
            <div class="d-flex align-items-center">
                <i class="fas ${type === 'success' ? 'fa-check-circle' : 'fa-exclamation-circle'} me-2"></i>
                ${message}
            </div>
        `;
        
        document.body.appendChild(notification);
        
        setTimeout(() => {
            notification.remove();
        }, 3000);
    }
}

// Initialize the app when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
    new FitnessCoachBot();
});

// Service Worker for PWA capabilities (optional)
if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
        navigator.serviceWorker.register('/sw.js')
            .then((registration) => {
                console.log('SW registered: ', registration);
            })
            .catch((registrationError) => {
                console.log('SW registration failed: ', registrationError);
            });
    });
}
325 lines•11.7 KB
javascript

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