| <!DOCTYPE html>
|
| <html lang="en">
|
| <head>
|
| <meta charset="UTF-8">
|
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| <title>GradePredict AI | Student Performance Analytics</title>
|
| <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
| <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;800&display=swap" rel="stylesheet">
|
| </head>
|
| <body>
|
| <div class="background-blobs">
|
| <div class="blob blob-1"></div>
|
| <div class="blob blob-2"></div>
|
| <div class="blob blob-3"></div>
|
| </div>
|
|
|
| <main class="container">
|
| <header class="glass-card animate-fade-in">
|
| <h1>GradePredict <span class="accent">AI</span></h1>
|
| <p>Advanced RNN-based Student Performance Forecasting</p>
|
| </header>
|
|
|
| <section class="prediction-grid">
|
| <div class="glass-card input-section animate-slide-up">
|
| <h2>Predict Your Score</h2>
|
| <form id="predictionForm">
|
| <div class="input-group">
|
| <label for="num_courses">Number of Courses</label>
|
| <input type="number" id="num_courses" name="num_courses" placeholder="e.g. 5" min="1" max="100" required>
|
| </div>
|
| <div class="input-group">
|
| <label for="time_study">Daily Study Hours</label>
|
| <input type="number" id="time_study" name="time_study" placeholder="e.g. 4.5" step="0.1" min="0" max="24" required>
|
| </div>
|
| <button type="submit" id="predictBtn">
|
| <span class="btn-text">Calculate Score</span>
|
| <div class="loader-dots" id="loader">
|
| <span></span><span></span><span></span>
|
| </div>
|
| </button>
|
| </form>
|
| </div>
|
|
|
| <div class="glass-card result-section animate-slide-up-delayed">
|
| <div id="resultPlaceholder" class="placeholder">
|
| <div class="icon-pulse">🎓</div>
|
| <p>Enter your details to generate prediction</p>
|
| </div>
|
| <div id="resultOutput" class="output hidden">
|
| <div class="score-circle">
|
| <span id="scoreValue">0.00</span>
|
| <p>Marks</p>
|
| </div>
|
| <h3>Predicted Efficiency</h3>
|
| <p id="analysisText">Based on your input, here is your forecasted performance.</p>
|
| </div>
|
| </div>
|
| </section>
|
|
|
| <footer class="animate-fade-in">
|
| <p>© 2026 GradePredict AI | Powered by LSTM Recurrent Neural Networks</p>
|
| </footer>
|
| </main>
|
|
|
| <script>
|
| document.getElementById('predictionForm').addEventListener('submit', async (e) => {
|
| e.preventDefault();
|
|
|
| const btn = document.getElementById('predictBtn');
|
| const loader = document.getElementById('loader');
|
| const btnText = btn.querySelector('.btn-text');
|
| const placeholder = document.getElementById('resultPlaceholder');
|
| const output = document.getElementById('resultOutput');
|
| const scoreValue = document.getElementById('scoreValue');
|
|
|
|
|
| btn.disabled = true;
|
| btnText.style.opacity = '0';
|
| loader.style.display = 'flex';
|
|
|
| const formData = {
|
| num_courses: document.getElementById('num_courses').value,
|
| time_study: document.getElementById('time_study').value
|
| };
|
|
|
| try {
|
| const response = await fetch('/predict', {
|
| method: 'POST',
|
| headers: { 'Content-Type': 'application/json' },
|
| body: JSON.stringify(formData)
|
| });
|
|
|
| const data = await response.json();
|
|
|
| if (data.marks !== undefined) {
|
| placeholder.classList.add('hidden');
|
| output.classList.remove('hidden');
|
|
|
|
|
| animateValue(scoreValue, 0, data.marks, 1000);
|
| } else {
|
| alert('Error: ' + data.error);
|
| }
|
| } catch (err) {
|
| alert('Connection Error: ' + err.message);
|
| } finally {
|
| btn.disabled = false;
|
| btnText.style.opacity = '1';
|
| loader.style.display = 'none';
|
| }
|
| });
|
|
|
| function animateValue(obj, start, end, duration) {
|
| let startTimestamp = null;
|
| const step = (timestamp) => {
|
| if (!startTimestamp) startTimestamp = timestamp;
|
| const progress = Math.min((timestamp - startTimestamp) / duration, 1);
|
| obj.innerHTML = (progress * (end - start) + start).toFixed(2);
|
| if (progress < 1) {
|
| window.requestAnimationFrame(step);
|
| }
|
| };
|
| window.requestAnimationFrame(step);
|
| }
|
| </script>
|
| </body>
|
| </html>
|
|
|