Download index.html from OUAREDAEK/SRL: direct link, hf CLI and curl.
- Browser
- Download file 145 kB
-
https://huggingface.co/spaces/OUAREDAEK/SRL/resolve/main/index.html
- Command line
-
hf download hf://spaces/OUAREDAEK/SRL/index.html
-
curl -L -o index.html https://huggingface.co/spaces/OUAREDAEK/SRL/resolve/main/index.html
145 kB
| <html lang="fr"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Compagnon Pédagogique - Apprentissage Autorégulé Personnalisé</title> | |
| <!-- Chart.js pour les visualisations --> | |
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> | |
| <!-- Font Awesome pour les icônes --> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| :root { | |
| --primary-color: #3b82f6; | |
| --secondary-color: #10b981; | |
| --accent-color: #8b5cf6; | |
| --warning-color: #f59e0b; | |
| --danger-color: #ef4444; | |
| --dark-color: #1e293b; | |
| --light-color: #f8fafc; | |
| --gray-color: #64748b; | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%); | |
| color: var(--dark-color); | |
| line-height: 1.6; | |
| min-height: 100vh; | |
| } | |
| .container { | |
| max-width: 1400px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| } | |
| /* Header */ | |
| .header { | |
| background: linear-gradient(135deg, var(--dark-color) 0%, #0f172a 100%); | |
| color: white; | |
| padding: 2rem; | |
| border-radius: 15px; | |
| margin-bottom: 2rem; | |
| box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .header::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| height: 4px; | |
| background: linear-gradient(90deg, var(--primary-color), var(--secondary-color), var(--accent-color)); | |
| } | |
| .header h1 { | |
| font-size: 2.5rem; | |
| margin-bottom: 0.5rem; | |
| display: flex; | |
| align-items: center; | |
| gap: 15px; | |
| } | |
| .header p { | |
| font-size: 1.1rem; | |
| opacity: 0.9; | |
| max-width: 800px; | |
| } | |
| .badge { | |
| background: var(--primary-color); | |
| color: white; | |
| padding: 5px 15px; | |
| border-radius: 20px; | |
| font-size: 0.9rem; | |
| display: inline-block; | |
| margin-top: 10px; | |
| } | |
| /* Navigation */ | |
| .nav-tabs { | |
| display: flex; | |
| background: white; | |
| border-radius: 12px; | |
| overflow: hidden; | |
| box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05); | |
| margin-bottom: 2rem; | |
| flex-wrap: wrap; | |
| } | |
| .nav-tab { | |
| flex: 1; | |
| min-width: 180px; | |
| padding: 1.2rem; | |
| border: none; | |
| background: transparent; | |
| color: var(--gray-color); | |
| font-size: 1rem; | |
| font-weight: 600; | |
| cursor: pointer; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 10px; | |
| transition: all 0.3s ease; | |
| } | |
| .nav-tab:hover { | |
| background: #f8fafc; | |
| color: var(--primary-color); | |
| } | |
| .nav-tab.active { | |
| background: var(--primary-color); | |
| color: white; | |
| box-shadow: 0 5px 15px rgba(59, 130, 246, 0.3); | |
| } | |
| /* Sections */ | |
| .tab-content { | |
| display: none; | |
| animation: fadeIn 0.5s ease; | |
| } | |
| .tab-content.active { | |
| display: block; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| .card { | |
| background: white; | |
| border-radius: 15px; | |
| padding: 2rem; | |
| margin-bottom: 2rem; | |
| box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05); | |
| border-left: 5px solid var(--primary-color); | |
| } | |
| .card-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 1.5rem; | |
| padding-bottom: 1rem; | |
| border-bottom: 2px solid #f1f5f9; | |
| } | |
| .card-header h3 { | |
| font-size: 1.5rem; | |
| color: var(--dark-color); | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| /* Questionnaire Styles */ | |
| .questionnaire-section { | |
| margin-bottom: 2.5rem; | |
| padding: 1.5rem; | |
| background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%); | |
| border-radius: 12px; | |
| } | |
| .questionnaire-header { | |
| display: flex; | |
| align-items: center; | |
| gap: 15px; | |
| margin-bottom: 1.5rem; | |
| padding-bottom: 1rem; | |
| border-bottom: 2px solid #e2e8f0; | |
| } | |
| .questionnaire-icon { | |
| width: 50px; | |
| height: 50px; | |
| border-radius: 10px; | |
| background: linear-gradient(135deg, var(--primary-color), var(--accent-color)); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 1.5rem; | |
| color: white; | |
| } | |
| .questionnaire-title { | |
| font-size: 1.4rem; | |
| color: var(--dark-color); | |
| font-weight: 600; | |
| } | |
| .questionnaire-description { | |
| color: var(--gray-color); | |
| font-size: 0.95rem; | |
| margin-top: 5px; | |
| } | |
| .question-item { | |
| background: white; | |
| padding: 1.5rem; | |
| border-radius: 10px; | |
| margin-bottom: 1.5rem; | |
| box-shadow: 0 3px 10px rgba(0, 0, 0, 0.05); | |
| border-left: 4px solid #e2e8f0; | |
| transition: all 0.3s; | |
| } | |
| .question-item:hover { | |
| border-left-color: var(--primary-color); | |
| transform: translateY(-2px); | |
| box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); | |
| } | |
| .question-text { | |
| font-size: 1.1rem; | |
| font-weight: 500; | |
| color: var(--dark-color); | |
| margin-bottom: 1rem; | |
| line-height: 1.5; | |
| } | |
| .scale-options { | |
| display: flex; | |
| justify-content: space-between; | |
| gap: 10px; | |
| margin-top: 1rem; | |
| } | |
| .scale-option { | |
| flex: 1; | |
| text-align: center; | |
| padding: 10px; | |
| border: 2px solid #e2e8f0; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| transition: all 0.3s; | |
| background: white; | |
| } | |
| .scale-option:hover { | |
| border-color: var(--primary-color); | |
| background: rgba(59, 130, 246, 0.05); | |
| } | |
| .scale-option.selected { | |
| border-color: var(--primary-color); | |
| background: rgba(59, 130, 246, 0.1); | |
| font-weight: 600; | |
| color: var(--primary-color); | |
| } | |
| .scale-label { | |
| display: block; | |
| font-size: 0.9rem; | |
| color: var(--gray-color); | |
| margin-top: 5px; | |
| } | |
| .progress-section { | |
| margin-top: 2rem; | |
| padding: 1.5rem; | |
| background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%); | |
| border-radius: 12px; | |
| border-left: 5px solid var(--primary-color); | |
| } | |
| .progress-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 1rem; | |
| } | |
| .progress-title { | |
| font-size: 1.2rem; | |
| color: var(--dark-color); | |
| font-weight: 600; | |
| } | |
| .progress-percentage { | |
| font-size: 1.3rem; | |
| font-weight: bold; | |
| color: var(--primary-color); | |
| } | |
| .progress-bar-container { | |
| height: 12px; | |
| background: #e2e8f0; | |
| border-radius: 6px; | |
| overflow: hidden; | |
| margin: 15px 0; | |
| } | |
| .progress-bar-fill { | |
| height: 100%; | |
| background: linear-gradient(90deg, var(--primary-color), var(--accent-color)); | |
| border-radius: 6px; | |
| transition: width 0.5s ease; | |
| width: 0%; | |
| } | |
| .questionnaire-progress { | |
| display: flex; | |
| justify-content: space-between; | |
| font-size: 0.9rem; | |
| color: var(--gray-color); | |
| } | |
| .profile-summary { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); | |
| gap: 20px; | |
| margin-top: 2rem; | |
| } | |
| .profile-card { | |
| background: white; | |
| padding: 1.5rem; | |
| border-radius: 12px; | |
| box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05); | |
| } | |
| .profile-card-header { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| margin-bottom: 1rem; | |
| padding-bottom: 0.8rem; | |
| border-bottom: 2px solid #f1f5f9; | |
| } | |
| .profile-card-icon { | |
| width: 40px; | |
| height: 40px; | |
| border-radius: 8px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 1.2rem; | |
| color: white; | |
| } | |
| .profile-card-title { | |
| font-size: 1.2rem; | |
| font-weight: 600; | |
| color: var(--dark-color); | |
| } | |
| .trait-list { | |
| display: flex; | |
| flex-direction: column; | |
| gap: 10px; | |
| } | |
| .trait-item { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| padding: 10px; | |
| background: #f8fafc; | |
| border-radius: 8px; | |
| } | |
| .trait-name { | |
| font-weight: 500; | |
| color: var(--dark-color); | |
| } | |
| .trait-value { | |
| font-weight: 600; | |
| color: var(--primary-color); | |
| } | |
| .recommendations-section { | |
| background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); | |
| border-radius: 12px; | |
| padding: 1.5rem; | |
| margin-top: 2rem; | |
| border-left: 5px solid var(--warning-color); | |
| } | |
| .recommendation-item { | |
| display: flex; | |
| align-items: flex-start; | |
| gap: 15px; | |
| margin-bottom: 1rem; | |
| padding: 1rem; | |
| background: rgba(255, 255, 255, 0.7); | |
| border-radius: 8px; | |
| } | |
| .recommendation-icon { | |
| font-size: 1.5rem; | |
| color: var(--warning-color); | |
| } | |
| .motivation-chart { | |
| height: 300px; | |
| margin-top: 1.5rem; | |
| } | |
| .section-completion { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| margin-top: 1rem; | |
| padding: 10px; | |
| background: rgba(16, 185, 129, 0.1); | |
| border-radius: 8px; | |
| } | |
| .section-complete { | |
| background: rgba(16, 185, 129, 0.1); | |
| border-left: 4px solid var(--secondary-color); | |
| } | |
| .section-incomplete { | |
| background: rgba(239, 68, 68, 0.1); | |
| border-left: 4px solid var(--danger-color); | |
| } | |
| /* Objectif Section */ | |
| .productivity-grid { | |
| display: grid; | |
| grid-template-columns: 1fr 1fr; | |
| gap: 20px; | |
| margin-top: 10px; | |
| } | |
| .option-section { | |
| background: white; | |
| border-radius: 10px; | |
| padding: 1rem; | |
| border: 1px solid #e2e8f0; | |
| } | |
| .option-section h4 { | |
| font-size: 1rem; | |
| color: #333; | |
| margin-bottom: 10px; | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .option-section h4 i { | |
| color: #333; | |
| } | |
| .option-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); | |
| gap: 10px; | |
| } | |
| .option-item { | |
| padding: 12px; | |
| border: 1px solid #e2e8f0; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| transition: all 0.3s; | |
| text-align: center; | |
| background: white; | |
| } | |
| .option-item:hover { | |
| border-color: #666; | |
| background: #f8f9fa; | |
| } | |
| .option-item.selected { | |
| border-color: #333; | |
| background: #f0f0f0; | |
| font-weight: 600; | |
| } | |
| .option-icon { | |
| font-size: 1.2rem; | |
| margin-bottom: 5px; | |
| display: block; | |
| color: #333; | |
| } | |
| .option-title { | |
| font-weight: 500; | |
| color: #333; | |
| font-size: 0.9rem; | |
| margin-bottom: 3px; | |
| } | |
| .option-description { | |
| font-size: 0.8rem; | |
| color: #666; | |
| line-height: 1.2; | |
| } | |
| /* Energy Pattern */ | |
| .energy-patterns { | |
| display: flex; | |
| gap: 15px; | |
| margin-top: 10px; | |
| } | |
| .energy-pattern { | |
| flex: 1; | |
| padding: 15px; | |
| border: 2px solid #e2e8f0; | |
| border-radius: 10px; | |
| text-align: center; | |
| cursor: pointer; | |
| transition: all 0.3s; | |
| } | |
| .energy-pattern:hover { | |
| border-color: var(--secondary-color); | |
| background: rgba(16, 185, 129, 0.05); | |
| } | |
| .energy-pattern.selected { | |
| border-color: var(--secondary-color); | |
| background: rgba(16, 185, 129, 0.1); | |
| box-shadow: 0 5px 15px rgba(16, 185, 129, 0.1); | |
| } | |
| /* Time Slots */ | |
| .time-slots { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 10px; | |
| margin-top: 10px; | |
| } | |
| .time-slot { | |
| padding: 10px 20px; | |
| border: 2px solid #e2e8f0; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| transition: all 0.3s; | |
| text-align: center; | |
| min-width: 80px; | |
| } | |
| .time-slot:hover { | |
| border-color: var(--accent-color); | |
| background: rgba(139, 92, 246, 0.05); | |
| } | |
| .time-slot.selected { | |
| border-color: var(--accent-color); | |
| background: rgba(139, 92, 246, 0.1); | |
| box-shadow: 0 3px 10px rgba(139, 92, 246, 0.1); | |
| } | |
| /* Quality Indicators */ | |
| .quality-indicator { | |
| display: flex; | |
| gap: 10px; | |
| margin: 15px 0; | |
| } | |
| .quality-dot { | |
| width: 25px; | |
| height: 25px; | |
| border-radius: 50%; | |
| cursor: pointer; | |
| transition: all 0.3s; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| color: white; | |
| font-weight: bold; | |
| font-size: 0.8rem; | |
| } | |
| .quality-dot:hover { | |
| transform: scale(1.2); | |
| } | |
| .quality-0 { background: linear-gradient(135deg, #ef4444, #dc2626); } | |
| .quality-1 { background: linear-gradient(135deg, #f59e0b, #d97706); } | |
| .quality-2 { background: linear-gradient(135deg, #10b981, #059669); } | |
| .quality-3 { background: linear-gradient(135deg, #3b82f6, #1d4ed8); } | |
| .quality-dot.active { | |
| box-shadow: 0 0 0 3px white, 0 0 0 6px currentColor; | |
| } | |
| /* Form Elements */ | |
| .form-group { | |
| margin-bottom: 1.5rem; | |
| } | |
| .form-label { | |
| display: block; | |
| margin-bottom: 0.5rem; | |
| font-weight: 600; | |
| color: var(--dark-color); | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .form-control { | |
| width: 100%; | |
| padding: 12px 15px; | |
| border: 2px solid #e2e8f0; | |
| border-radius: 10px; | |
| font-size: 1rem; | |
| transition: all 0.3s; | |
| background: #f8fafc; | |
| } | |
| .form-control:focus { | |
| outline: none; | |
| border-color: var(--primary-color); | |
| background: white; | |
| box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); | |
| } | |
| .form-row { | |
| display: flex; | |
| gap: 20px; | |
| margin-bottom: 1.5rem; | |
| } | |
| .form-col { | |
| flex: 1; | |
| } | |
| /* Buttons */ | |
| .btn { | |
| padding: 12px 25px; | |
| border: none; | |
| border-radius: 10px; | |
| font-size: 1rem; | |
| font-weight: 600; | |
| cursor: pointer; | |
| transition: all 0.3s; | |
| display: inline-flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 10px; | |
| } | |
| .btn-primary { | |
| background: linear-gradient(135deg, var(--primary-color) 0%, #2563eb 100%); | |
| color: white; | |
| } | |
| .btn-primary:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 20px rgba(59, 130, 246, 0.3); | |
| } | |
| .btn-secondary { | |
| background: var(--secondary-color); | |
| color: white; | |
| } | |
| .btn-large { | |
| padding: 15px 30px; | |
| font-size: 1.1rem; | |
| } | |
| /* Planner Cards */ | |
| .planning-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(350px, 1fr)); | |
| gap: 20px; | |
| margin-top: 2rem; | |
| } | |
| .session-card { | |
| background: white; | |
| border-radius: 12px; | |
| padding: 1.5rem; | |
| box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05); | |
| border-top: 4px solid var(--primary-color); | |
| transition: transform 0.3s; | |
| } | |
| .session-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1); | |
| } | |
| .session-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: flex-start; | |
| margin-bottom: 1rem; | |
| } | |
| .session-date { | |
| font-size: 1.2rem; | |
| font-weight: bold; | |
| color: var(--dark-color); | |
| } | |
| .session-repetition { | |
| background: var(--primary-color); | |
| color: white; | |
| padding: 5px 15px; | |
| border-radius: 20px; | |
| font-size: 0.9rem; | |
| } | |
| .session-details { | |
| margin-top: 1rem; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 8px; | |
| } | |
| .detail-item { | |
| display: flex; | |
| justify-content: space-between; | |
| padding: 5px 0; | |
| border-bottom: 1px dashed #e2e8f0; | |
| } | |
| /* Visualizations */ | |
| .visualization-container { | |
| background: white; | |
| border-radius: 15px; | |
| padding: 2rem; | |
| margin-top: 2rem; | |
| box-shadow: 0 5px 20px rgba(0, 0, 0, 0.05); | |
| } | |
| .chart-container { | |
| position: relative; | |
| height: 400px; | |
| width: 100%; | |
| } | |
| /* Stats Cards */ | |
| .stats-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); | |
| gap: 20px; | |
| margin-top: 2rem; | |
| } | |
| .stat-card { | |
| background: white; | |
| border-radius: 12px; | |
| padding: 1.5rem; | |
| text-align: center; | |
| box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05); | |
| } | |
| .stat-value { | |
| font-size: 2.5rem; | |
| font-weight: bold; | |
| color: var(--primary-color); | |
| margin: 10px 0; | |
| } | |
| .stat-label { | |
| color: var(--gray-color); | |
| font-size: 0.9rem; | |
| } | |
| /* Heatmap d'activité */ | |
| .heatmap-container { | |
| margin-top: 2rem; | |
| } | |
| .heatmap-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 1.5rem; | |
| } | |
| .heatmap-title { | |
| font-size: 1.3rem; | |
| color: var(--dark-color); | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .heatmap-controls { | |
| display: flex; | |
| gap: 10px; | |
| } | |
| .heatmap-period { | |
| padding: 8px 15px; | |
| border: 2px solid #e2e8f0; | |
| border-radius: 8px; | |
| background: #f8fafc; | |
| cursor: pointer; | |
| transition: all 0.3s; | |
| } | |
| .heatmap-period:hover { | |
| border-color: var(--primary-color); | |
| } | |
| .heatmap-period.active { | |
| background: var(--primary-color); | |
| color: white; | |
| border-color: var(--primary-color); | |
| } | |
| .heatmap-grid { | |
| display: grid; | |
| grid-template-columns: auto repeat(7, 1fr); | |
| gap: 8px; | |
| margin-top: 1rem; | |
| } | |
| .heatmap-day-label { | |
| text-align: right; | |
| padding: 10px; | |
| font-weight: 600; | |
| color: var(--dark-color); | |
| } | |
| .heatmap-cell { | |
| aspect-ratio: 1; | |
| border-radius: 4px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 0.8rem; | |
| font-weight: bold; | |
| cursor: pointer; | |
| transition: transform 0.2s; | |
| } | |
| .heatmap-cell:hover { | |
| transform: scale(1.1); | |
| z-index: 10; | |
| } | |
| .heatmap-intensity-0 { background: #f1f5f9; color: var(--gray-color); } | |
| .heatmap-intensity-1 { background: #dbeafe; color: var(--dark-color); } | |
| .heatmap-intensity-2 { background: #93c5fd; color: white; } | |
| .heatmap-intensity-3 { background: #3b82f6; color: white; } | |
| .heatmap-intensity-4 { background: #1d4ed8; color: white; } | |
| .heatmap-week-label { | |
| text-align: center; | |
| padding: 5px; | |
| font-size: 0.9rem; | |
| color: var(--gray-color); | |
| } | |
| .heatmap-legend { | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| gap: 15px; | |
| margin-top: 1.5rem; | |
| padding-top: 1.5rem; | |
| border-top: 2px solid #f1f5f9; | |
| } | |
| .legend-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 5px; | |
| } | |
| .legend-color { | |
| width: 20px; | |
| height: 20px; | |
| border-radius: 4px; | |
| } | |
| /* Notifications */ | |
| .notification-card { | |
| background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); | |
| border-left: 5px solid var(--warning-color); | |
| padding: 1.5rem; | |
| border-radius: 12px; | |
| margin-bottom: 1rem; | |
| animation: fadeIn 0.5s ease; | |
| } | |
| /* ============================================ */ | |
| /* STYLES POUR LES FLASHCARDS */ | |
| /* ============================================ */ | |
| .flashcards-controls { | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| gap: 20px; | |
| margin: 2rem 0; | |
| padding: 1rem; | |
| background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%); | |
| border-radius: 12px; | |
| } | |
| .flashcard-container { | |
| min-height: 400px; | |
| perspective: 1000px; | |
| margin: 2rem 0; | |
| } | |
| .flashcard { | |
| width: 100%; | |
| height: 400px; | |
| position: relative; | |
| transform-style: preserve-3d; | |
| transition: transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275); | |
| cursor: pointer; | |
| } | |
| .flashcard.flipped { | |
| transform: rotateY(180deg); | |
| } | |
| .flashcard-face { | |
| position: absolute; | |
| width: 100%; | |
| height: 100%; | |
| backface-visibility: hidden; | |
| border-radius: 15px; | |
| padding: 2rem; | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); | |
| overflow: hidden; | |
| } | |
| .flashcard-front { | |
| background: linear-gradient(135deg, #ffffff 0%, #f1f5f9 100%); | |
| border: 2px solid var(--primary-color); | |
| } | |
| .flashcard-back { | |
| background: linear-gradient(135deg, var(--primary-color) 0%, #1d4ed8 100%); | |
| color: white; | |
| transform: rotateY(180deg); | |
| text-align: center; | |
| } | |
| .flashcard-category { | |
| position: absolute; | |
| top: 15px; | |
| left: 15px; | |
| padding: 5px 15px; | |
| border-radius: 20px; | |
| font-size: 0.8rem; | |
| font-weight: 600; | |
| background: rgba(255, 255, 255, 0.2); | |
| backdrop-filter: blur(10px); | |
| } | |
| .flashcard-content { | |
| max-width: 600px; | |
| text-align: center; | |
| padding: 2rem; | |
| } | |
| .flashcard-title { | |
| font-size: 1.8rem; | |
| font-weight: bold; | |
| margin-bottom: 1.5rem; | |
| color: var(--dark-color); | |
| } | |
| .flashcard-question { | |
| font-size: 1.3rem; | |
| line-height: 1.6; | |
| margin-bottom: 2rem; | |
| color: var(--dark-color); | |
| } | |
| .flashcard-back .flashcard-title { | |
| color: white; | |
| } | |
| .flashcard-back .flashcard-question { | |
| color: rgba(255, 255, 255, 0.9); | |
| } | |
| .flashcard-action { | |
| background: white; | |
| color: var(--primary-color); | |
| border: none; | |
| padding: 12px 30px; | |
| border-radius: 25px; | |
| font-weight: 600; | |
| cursor: pointer; | |
| margin-top: 1.5rem; | |
| transition: all 0.3s; | |
| box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); | |
| } | |
| .flashcard-action:hover { | |
| transform: translateY(-3px); | |
| box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15); | |
| } | |
| .flashcard-instruction { | |
| position: absolute; | |
| bottom: 15px; | |
| left: 0; | |
| right: 0; | |
| text-align: center; | |
| font-size: 0.9rem; | |
| color: var(--gray-color); | |
| opacity: 0.8; | |
| } | |
| .flashcard-evaluation { | |
| margin-top: 2rem; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 1rem; | |
| width: 100%; | |
| max-width: 400px; | |
| } | |
| .evaluation-slider { | |
| width: 100%; | |
| -webkit-appearance: none; | |
| height: 8px; | |
| border-radius: 4px; | |
| background: rgba(255, 255, 255, 0.3); | |
| outline: none; | |
| } | |
| .evaluation-slider::-webkit-slider-thumb { | |
| -webkit-appearance: none; | |
| width: 24px; | |
| height: 24px; | |
| border-radius: 50%; | |
| background: white; | |
| cursor: pointer; | |
| box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); | |
| } | |
| .evaluation-label { | |
| display: flex; | |
| justify-content: space-between; | |
| font-size: 0.9rem; | |
| color: rgba(255, 255, 255, 0.9); | |
| } | |
| .category-filters { | |
| display: flex; | |
| flex-wrap: wrap; | |
| gap: 10px; | |
| margin: 1.5rem 0; | |
| justify-content: center; | |
| } | |
| .category-filter { | |
| padding: 8px 20px; | |
| border: 2px solid #e2e8f0; | |
| border-radius: 20px; | |
| background: white; | |
| cursor: pointer; | |
| transition: all 0.3s; | |
| font-weight: 500; | |
| color: var(--dark-color); | |
| } | |
| .category-filter:hover { | |
| border-color: var(--primary-color); | |
| color: var(--primary-color); | |
| } | |
| .category-filter.active { | |
| background: var(--primary-color); | |
| color: white; | |
| border-color: var(--primary-color); | |
| } | |
| .flashcard-progress { | |
| width: 100%; | |
| height: 6px; | |
| background: #e2e8f0; | |
| border-radius: 3px; | |
| margin: 1rem 0; | |
| overflow: hidden; | |
| } | |
| .flashcard-progress-bar { | |
| height: 100%; | |
| background: linear-gradient(90deg, var(--primary-color), var(--accent-color)); | |
| border-radius: 3px; | |
| transition: width 0.3s ease; | |
| } | |
| .dashboardEM-container { | |
| background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%); | |
| border-radius: 15px; | |
| padding: 2rem; | |
| margin-top: 2rem; | |
| } | |
| .dashboardEM-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); | |
| gap: 20px; | |
| margin-top: 1.5rem; | |
| } | |
| .dashboardEM-card { | |
| background: white; | |
| border-radius: 12px; | |
| padding: 1.5rem; | |
| box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05); | |
| } | |
| .dashboardEM-header { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| margin-bottom: 1rem; | |
| padding-bottom: 1rem; | |
| border-bottom: 2px solid #f1f5f9; | |
| } | |
| .dashboardEM-icon { | |
| width: 40px; | |
| height: 40px; | |
| border-radius: 10px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 1.2rem; | |
| color: white; | |
| } | |
| .dashboardEM-metric { | |
| display: flex; | |
| align-items: baseline; | |
| gap: 10px; | |
| margin: 1rem 0; | |
| } | |
| .dashboardEM-value { | |
| font-size: 2.5rem; | |
| font-weight: bold; | |
| color: var(--primary-color); | |
| } | |
| .dashboardEM-change { | |
| font-size: 0.9rem; | |
| padding: 3px 8px; | |
| border-radius: 12px; | |
| background: rgba(16, 185, 129, 0.1); | |
| color: var(--secondary-color); | |
| } | |
| .dashboardEM-change.negative { | |
| background: rgba(239, 68, 68, 0.1); | |
| color: var(--danger-color); | |
| } | |
| .dashboardEM-trend { | |
| display: flex; | |
| align-items: center; | |
| gap: 5px; | |
| font-size: 0.9rem; | |
| color: var(--gray-color); | |
| } | |
| /* Indicateurs de gestion du temps */ | |
| .time-management-stats { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); | |
| gap: 20px; | |
| margin-top: 2rem; | |
| } | |
| .time-stat-card { | |
| background: white; | |
| border-radius: 12px; | |
| padding: 1.5rem; | |
| box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05); | |
| border-top: 4px solid var(--secondary-color); | |
| } | |
| .time-stat-header { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| margin-bottom: 1rem; | |
| } | |
| .time-stat-icon { | |
| width: 40px; | |
| height: 40px; | |
| border-radius: 10px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 1.2rem; | |
| color: white; | |
| background: linear-gradient(135deg, #10b981, #059669); | |
| } | |
| .time-stat-value { | |
| font-size: 2.5rem; | |
| font-weight: bold; | |
| color: var(--secondary-color); | |
| margin: 10px 0; | |
| } | |
| .time-stat-description { | |
| color: var(--gray-color); | |
| font-size: 0.9rem; | |
| margin-top: 5px; | |
| } | |
| .progress-circle { | |
| width: 100px; | |
| height: 100px; | |
| position: relative; | |
| margin: 0 auto; | |
| } | |
| .progress-circle svg { | |
| width: 100%; | |
| height: 100%; | |
| } | |
| .progress-text { | |
| position: absolute; | |
| top: 50%; | |
| left: 50%; | |
| transform: translate(-50%, -50%); | |
| font-size: 1.5rem; | |
| font-weight: bold; | |
| color: var(--secondary-color); | |
| } | |
| /* Modal pour la saisie */ | |
| .modal { | |
| display: none; | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: rgba(0, 0, 0, 0.5); | |
| z-index: 1000; | |
| align-items: center; | |
| justify-content: center; | |
| } | |
| .modal-content { | |
| background: white; | |
| border-radius: 15px; | |
| padding: 2rem; | |
| width: 90%; | |
| max-width: 600px; | |
| max-height: 80vh; | |
| overflow-y: auto; | |
| animation: slideIn 0.3s ease; | |
| } | |
| @keyframes slideIn { | |
| from { transform: translateY(-20px); opacity: 0; } | |
| to { transform: translateY(0); opacity: 1; } | |
| } | |
| .modal-header { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| margin-bottom: 1.5rem; | |
| padding-bottom: 1rem; | |
| border-bottom: 2px solid #f1f5f9; | |
| } | |
| .modal-title { | |
| font-size: 1.5rem; | |
| color: var(--dark-color); | |
| } | |
| .modal-close { | |
| background: none; | |
| border: none; | |
| font-size: 1.5rem; | |
| color: var(--gray-color); | |
| cursor: pointer; | |
| } | |
| /* Effort Pattern */ | |
| .effort-pattern { | |
| background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%); | |
| border-radius: 12px; | |
| padding: 1.5rem; | |
| margin-top: 2rem; | |
| } | |
| .pattern-badge { | |
| display: inline-block; | |
| padding: 8px 15px; | |
| background: linear-gradient(135deg, #f59e0b, #d97706); | |
| color: white; | |
| border-radius: 20px; | |
| font-weight: bold; | |
| margin-bottom: 1rem; | |
| } | |
| .pattern-details { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); | |
| gap: 15px; | |
| margin-top: 1rem; | |
| } | |
| .pattern-item { | |
| background: white; | |
| padding: 1rem; | |
| border-radius: 8px; | |
| box-shadow: 0 3px 10px rgba(0, 0, 0, 0.05); | |
| } | |
| .pattern-label { | |
| font-size: 0.9rem; | |
| color: var(--gray-color); | |
| margin-bottom: 5px; | |
| } | |
| .pattern-value { | |
| font-size: 1.1rem; | |
| font-weight: bold; | |
| color: var(--dark-color); | |
| } | |
| /* Persistance */ | |
| .persistence-section { | |
| background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%); | |
| border-radius: 12px; | |
| padding: 1.5rem; | |
| margin-top: 2rem; | |
| border-left: 5px solid #f59e0b; | |
| } | |
| .persistence-header { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| margin-bottom: 1rem; | |
| } | |
| .persistence-level { | |
| font-size: 1.5rem; | |
| font-weight: bold; | |
| color: #d97706; | |
| } | |
| .persistence-details { | |
| margin-top: 1rem; | |
| } | |
| .persistence-item { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| margin-bottom: 10px; | |
| padding: 8px; | |
| background: rgba(255, 255, 255, 0.5); | |
| border-radius: 8px; | |
| } | |
| /* Responsive */ | |
| @media (max-width: 768px) { | |
| .form-row { | |
| flex-direction: column; | |
| gap: 0; | |
| } | |
| .nav-tabs { | |
| flex-direction: column; | |
| } | |
| .planning-grid { | |
| grid-template-columns: 1fr; | |
| } | |
| .header h1 { | |
| font-size: 2rem; | |
| } | |
| .productivity-grid { | |
| grid-template-columns: 1fr; | |
| } | |
| .energy-patterns { | |
| flex-direction: column; | |
| } | |
| .time-slots { | |
| justify-content: center; | |
| } | |
| .heatmap-grid { | |
| gap: 4px; | |
| } | |
| .heatmap-cell { | |
| font-size: 0.7rem; | |
| } | |
| .time-management-stats { | |
| grid-template-columns: 1fr; | |
| } | |
| .scale-options { | |
| flex-direction: column; | |
| } | |
| .profile-summary { | |
| grid-template-columns: 1fr; | |
| } | |
| .flashcard { | |
| height: 350px; | |
| } | |
| .flashcard-title { | |
| font-size: 1.5rem; | |
| } | |
| .flashcard-question { | |
| font-size: 1.1rem; | |
| } | |
| .flashcards-controls { | |
| flex-direction: column; | |
| gap: 15px; | |
| } | |
| } | |
| @media (max-width: 480px) { | |
| .flashcard { | |
| height: 300px; | |
| } | |
| .flashcard-content { | |
| padding: 1rem; | |
| } | |
| .flashcard-title { | |
| font-size: 1.3rem; | |
| } | |
| .flashcard-question { | |
| font-size: 1rem; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <!-- Header --> | |
| <header class="header"> | |
| <h1><i class="fas fa-graduation-cap"></i> Compagnon Pédagogique</h1> | |
| <p>PerseverAI (AI–Aid–Perseverance) – Apprendre à manager l'effort et maintenir la persistance</p> | |
| <div class="badge">PerseverAId (AI + Aid + Perseverance)</div> | |
| </header> | |
| <!-- Navigation - 7 onglets --> | |
| <nav class="nav-tabs"> | |
| <button class="nav-tab active" onclick="showTab('profile')"> | |
| <i class="fas fa-user-circle"></i> Profil Apprenant | |
| </button> | |
| <button class="nav-tab" onclick="showTab('objectif')"> | |
| <i class="fas fa-bullseye"></i> Objectif | |
| </button> | |
| <button class="nav-tab" onclick="showTab('planner')"> | |
| <i class="fas fa-calendar-alt"></i> Planner | |
| </button> | |
| <button class="nav-tab" onclick="showTab('flashcards')"> | |
| <i class="fas fa-layer-group"></i> Métacognition | |
| </button> | |
| <button class="nav-tab" onclick="showTab('journal')"> | |
| <i class="fas fa-book"></i> Journal SRL | |
| </button> | |
| <button class="nav-tab" onclick="showTab('notifications')"> | |
| <i class="fas fa-bell"></i> Notifications IA | |
| </button> | |
| <button class="nav-tab" onclick="showTab('stats')"> | |
| <i class="fas fa-chart-line"></i> Statistiques | |
| </button> | |
| </nav> | |
| <!-- Profil Apprenant Section --> | |
| <section id="profile" class="tab-content active"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <h3><i class="fas fa-user-circle"></i> Profil d'Apprentissage Personnalisé</h3> | |
| <div> | |
| <button class="btn btn-secondary" onclick="completeAllSections()"> | |
| <i class="fas fa-magic"></i> Remplir automatiquement | |
| </button> | |
| <button class="btn btn-secondary" onclick="saveProfile()"> | |
| <i class="fas fa-save"></i> Sauvegarder | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Barre de progression globale --> | |
| <div class="progress-section"> | |
| <div class="progress-header"> | |
| <div class="progress-title">Complétion du Profil</div> | |
| <div class="progress-percentage" id="profileCompletion">40%</div> | |
| </div> | |
| <div class="progress-bar-container"> | |
| <div class="progress-bar-fill" id="profileProgressBar" style="width: 40%"></div> | |
| </div> | |
| <div class="questionnaire-progress"> | |
| <span>Questionnaires complétés: <span id="completedSections">2/5</span></span> | |
| <span>Profil personnalisé: <span id="personalizationLevel">Intermédiaire</span></span> | |
| </div> | |
| </div> | |
| <!-- Section 1: Big Five Traits (BFI-10) --> | |
| <div class="questionnaire-section" id="big5-section"> | |
| <div class="questionnaire-header"> | |
| <div class="questionnaire-icon"> | |
| <i class="fas fa-brain"></i> | |
| </div> | |
| <div> | |
| <div class="questionnaire-title">Profil de Personnalité (Big Five Traits)</div> | |
| <div class="questionnaire-description">Évaluez vos traits de personnalité sur une échelle de 1 à 5</div> | |
| </div> | |
| </div> | |
| <div class="question-item"> | |
| <div class="question-text">Je suis quelqu'un de sociable, extraverti, énergique</div> | |
| <div class="scale-options"> | |
| <div class="scale-option" onclick="selectScale('extraversion', 1)">1</div> | |
| <div class="scale-option" onclick="selectScale('extraversion', 2)">2</div> | |
| <div class="scale-option selected" onclick="selectScale('extraversion', 3)">3</div> | |
| <div class="scale-option" onclick="selectScale('extraversion', 4)">4</div> | |
| <div class="scale-option" onclick="selectScale('extraversion', 5)">5</div> | |
| </div> | |
| </div> | |
| <div class="question-item"> | |
| <div class="question-text">Je fais preuve de curiosité intellectuelle, j'aime les nouvelles expériences</div> | |
| <div class="scale-options"> | |
| <div class="scale-option" onclick="selectScale('openness', 1)">1</div> | |
| <div class="scale-option" onclick="selectScale('openness', 2)">2</div> | |
| <div class="scale-option selected" onclick="selectScale('openness', 3)">3</div> | |
| <div class="scale-option" onclick="selectScale('openness', 4)">4</div> | |
| <div class="scale-option" onclick="selectScale('openness', 5)">5</div> | |
| </div> | |
| </div> | |
| <div class="question-item"> | |
| <div class="question-text">Je suis organisé, fiable, je respecte mes engagements</div> | |
| <div class="scale-options"> | |
| <div class="scale-option" onclick="selectScale('conscientiousness', 1)">1</div> | |
| <div class="scale-option" onclick="selectScale('conscientiousness', 2)">2</div> | |
| <div class="scale-option" onclick="selectScale('conscientiousness', 3)">3</div> | |
| <div class="scale-option selected" onclick="selectScale('conscientiousness', 4)">4</div> | |
| <div class="scale-option" onclick="selectScale('conscientiousness', 5)">5</div> | |
| </div> | |
| </div> | |
| <div class="question-item"> | |
| <div class="question-text">Je suis coopératif, serviable, empathique</div> | |
| <div class="scale-options"> | |
| <div class="scale-option" onclick="selectScale('agreeableness', 1)">1</div> | |
| <div class="scale-option" onclick="selectScale('agreeableness', 2)">2</div> | |
| <div class="scale-option selected" onclick="selectScale('agreeableness', 3)">3</div> | |
| <div class="scale-option" onclick="selectScale('agreeableness', 4)">4</div> | |
| <div class="scale-option" onclick="selectScale('agreeableness', 5)">5</div> | |
| </div> | |
| </div> | |
| <div class="question-item"> | |
| <div class="question-text">Je ressens facilement de l'anxiété, du stress, de la nervosité</div> | |
| <div class="scale-options"> | |
| <div class="scale-option" onclick="selectScale('neuroticism', 1)">1</div> | |
| <div class="scale-option" onclick="selectScale('neuroticism', 2)">2</div> | |
| <div class="scale-option" onclick="selectScale('neuroticism', 3)">3</div> | |
| <div class="scale-option selected" onclick="selectScale('neuroticism', 4)">4</div> | |
| <div class="scale-option" onclick="selectScale('neuroticism', 5)">5</div> | |
| </div> | |
| </div> | |
| <div class="section-completion section-complete" id="big5-completion"> | |
| <i class="fas fa-check-circle" style="color: #10b981;"></i> | |
| <span>Section complétée - <strong>Score neuroticisme: 4.0</strong> (qualité du sommeil importante)</span> | |
| </div> | |
| </div> | |
| <!-- Section 2: Motivation Académique --> | |
| <div class="questionnaire-section" id="motivation-section"> | |
| <div class="questionnaire-header"> | |
| <div class="questionnaire-icon" style="background: linear-gradient(135deg, #10b981, #059669);"> | |
| <i class="fas fa-fire"></i> | |
| </div> | |
| <div> | |
| <div class="questionnaire-title">Profil Motivationnel</div> | |
| <div class="questionnaire-description">Pourquoi étudiez-vous ? Sélectionnez vos principales motivations</div> | |
| </div> | |
| </div> | |
| <div class="question-item"> | |
| <div class="question-text">J'étudie parce que j'aime apprendre, je trouve cela intéressant et plaisant</div> | |
| <div class="scale-options"> | |
| <div class="scale-option" onclick="selectMotivation('intrinsic', 1)">1</div> | |
| <div class="scale-option" onclick="selectMotivation('intrinsic', 2)">2</div> | |
| <div class="scale-option selected" onclick="selectMotivation('intrinsic', 3)">3</div> | |
| <div class="scale-option" onclick="selectMotivation('intrinsic', 4)">4</div> | |
| <div class="scale-option" onclick="selectMotivation('intrinsic', 5)">5</div> | |
| </div> | |
| </div> | |
| <div class="question-item"> | |
| <div class="question-text">J'étudie pour obtenir de bonnes notes et faire plaisir à mes parents/professeurs</div> | |
| <div class="scale-options"> | |
| <div class="scale-option" onclick="selectMotivation('introjected', 1)">1</div> | |
| <div class="scale-option" onclick="selectMotivation('introjected', 2)">2</div> | |
| <div class="scale-option" onclick="selectMotivation('introjected', 3)">3</div> | |
| <div class="scale-option selected" onclick="selectMotivation('introjected', 4)">4</div> | |
| <div class="scale-option" onclick="selectMotivation('introjected', 5)">5</div> | |
| </div> | |
| </div> | |
| <div class="section-completion section-complete" id="motivation-completion"> | |
| <i class="fas fa-check-circle" style="color: #10b981;"></i> | |
| <span>Section complétée - <strong>Motivation introjectée: 4.0</strong> (pression interne modérée)</span> | |
| </div> | |
| </div> | |
| <!-- Résumé du Profil et Recommandations --> | |
| <div class="profile-summary"> | |
| <div class="profile-card"> | |
| <div class="profile-card-header"> | |
| <div class="profile-card-icon" style="background: linear-gradient(135deg, #3b82f6, #1d4ed8);"> | |
| <i class="fas fa-brain"></i> | |
| </div> | |
| <div class="profile-card-title">Big Five Traits</div> | |
| </div> | |
| <div class="trait-list"> | |
| <div class="trait-item"> | |
| <span class="trait-name">Extraversion</span> | |
| <span class="trait-value" id="extraversion-value">3.0</span> | |
| </div> | |
| <div class="trait-item"> | |
| <span class="trait-name">Ouverture</span> | |
| <span class="trait-value" id="openness-value">3.0</span> | |
| </div> | |
| <div class="trait-item"> | |
| <span class="trait-name">Conscience</span> | |
| <span class="trait-value" id="conscientiousness-value">4.0</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="profile-card"> | |
| <div class="profile-card-header"> | |
| <div class="profile-card-icon" style="background: linear-gradient(135deg, #10b981, #059669);"> | |
| <i class="fas fa-fire"></i> | |
| </div> | |
| <div class="profile-card-title">Motivation</div> | |
| </div> | |
| <div class="trait-list"> | |
| <div class="trait-item"> | |
| <span class="trait-name">Intrinsèque</span> | |
| <span class="trait-value" id="intrinsic-value">3.0</span> | |
| </div> | |
| <div class="trait-item"> | |
| <span class="trait-name">Introjectée</span> | |
| <span class="trait-value" id="introjected-value">4.0</span> | |
| </div> | |
| </div> | |
| <div class="motivation-chart"> | |
| <canvas id="motivationChart"></canvas> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Recommandations Personnalisées --> | |
| <div class="recommendations-section"> | |
| <h4><i class="fas fa-lightbulb"></i> Recommandations Personnalisées Basées sur Votre Profil</h4> | |
| <div class="recommendation-item"> | |
| <div class="recommendation-icon">💤</div> | |
| <div> | |
| <strong>Qualité du sommeil: </strong> Avec un névrosisme modéré, il est important de maintenir 7-8 heures de sommeil de qualité. | |
| </div> | |
| </div> | |
| <div class="recommendation-item"> | |
| <div class="recommendation-icon">📅</div> | |
| <div> | |
| <strong>Planification: </strong> Votre conscience est bonne. Établissez un planning régulier mais évitez le surmenage. | |
| </div> | |
| </div> | |
| </div> | |
| <button class="btn btn-primary btn-large" onclick="completeProfile()" style="margin-top: 2rem;"> | |
| <i class="fas fa-check-circle"></i> Finaliser et Générer le Profil Personnalisé | |
| </button> | |
| </div> | |
| </section> | |
| <!-- Objectif Section --> | |
| <section id="objectif" class="tab-content"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <h3><i class="fas fa-bullseye"></i> Définir mon Objectif d'Apprentissage</h3> | |
| </div> | |
| <div class="form-row"> | |
| <div class="form-col"> | |
| <label class="form-label"><i class="fas fa-language"></i> Compétence Cible</label> | |
| <select id="competence" class="form-control"> | |
| <option value="">Sélectionnez une compétence...</option> | |
| <option value="maitriser_conjugaison">Maîtriser les marques de la conjugaison</option> | |
| <option value="determiner_points_vue">Déterminer les points de vue adoptés</option> | |
| <option value="comprendre_mots">Comprendre les mots</option> | |
| <option value="choisir_mots_expressions">Choisir ses mots et ses expressions</option> | |
| <option value="construire_phrases">Construire ses phrases</option> | |
| <option value="developper_vocabulaire">Développer un vocabulaire étendu</option> | |
| <option value="maitriser_orthographe_mots">Maîtriser l'orthographe des mots</option> | |
| <option value="articuler_termes">Articuler les termes entre eux</option> | |
| <option value="utiliser_reprises">Utiliser des reprises</option> | |
| <option value="maitriser_orthographe_grammaticale">Maîtriser l'orthographe grammaticale</option> | |
| <option value="maitriser_modalites_phrases">Maîtriser les modalités et les types de phrases</option> | |
| <option value="enchainer_phrases">Enchaîner les phrases</option> | |
| <option value="organiser_textes">Organiser ses textes</option> | |
| <option value="effets_style">Jouer avec les effets de style</option> | |
| </select> | |
| </div> | |
| <div class="form-col"> | |
| <label class="form-label"><i class="fas fa-brain"></i> Niveau Actuel</label> | |
| <select id="level" class="form-control"> | |
| <option value="0">Débutant</option> | |
| <option value="1" selected>Intermédiaire</option> | |
| <option value="2">Avancé</option> | |
| <option value="3">Expert</option> | |
| </select> | |
| </div> | |
| </div> | |
| <div class="form-row"> | |
| <div class="form-col"> | |
| <label class="form-label"><i class="fas fa-calendar-start"></i> Date de Début</label> | |
| <input type="date" id="start" class="form-control" value="2024-01-15"> | |
| </div> | |
| <div class="form-col"> | |
| <label class="form-label"><i class="fas fa-calendar-end"></i> Date de Fin</label> | |
| <input type="date" id="end" class="form-control" value="2024-12-31"> | |
| </div> | |
| </div> | |
| <div class="form-group"> | |
| <label class="form-label"><i class="fas fa-clock"></i> Durée par Session (minutes)</label> | |
| <select id="duration" class="form-control"> | |
| <option value="10">10 minutes (Micro-learning)</option> | |
| <option value="20" selected>20 minutes (Optimal)</option> | |
| <option value="30">30 minutes (Approfondissement)</option> | |
| <option value="45">45 minutes (Session intensive)</option> | |
| </select> | |
| </div> | |
| <!-- Section Méthode Productivité --> | |
| <div class="productivity-grid"> | |
| <div class="option-section"> | |
| <h4><i class="fas fa-chart-line"></i> Méthode Productivité</h4> | |
| <div class="option-grid"> | |
| <div class="option-item selected" onclick="selectProductivityMethod('pomodoro')"> | |
| <span class="option-icon"><i class="fas fa-hourglass-half"></i></span> | |
| <div class="option-title">Pomodoro</div> | |
| <div class="option-description">25 min / 5 min pause</div> | |
| </div> | |
| <div class="option-item" onclick="selectProductivityMethod('deepwork')"> | |
| <span class="option-icon"><i class="fas fa-brain"></i></span> | |
| <div class="option-title">Deep Work</div> | |
| <div class="option-description">90 min focus intense</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="option-section"> | |
| <h4><i class="fas fa-bolt"></i> Type d'Énergie</h4> | |
| <div class="option-grid"> | |
| <div class="option-item selected" onclick="selectEnergyPattern('morning')"> | |
| <span class="option-icon"><i class="fas fa-sun"></i></span> | |
| <div class="option-title">Matinale</div> | |
| <div class="option-description">Productif le matin</div> | |
| </div> | |
| <div class="option-item" onclick="selectEnergyPattern('evening')"> | |
| <span class="option-icon"><i class="fas fa-moon"></i></span> | |
| <div class="option-title">Vespérale</div> | |
| <div class="option-description">Productif le soir</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Créneaux Disponibles --> | |
| <div class="form-group"> | |
| <label class="form-label"><i class="fas fa-calendar-check"></i> Créneaux Disponibles</label> | |
| <div class="time-slots"> | |
| <div class="time-slot selected" onclick="toggleTimeSlot('morning')">08:00-10:00</div> | |
| <div class="time-slot" onclick="toggleTimeSlot('late_morning')">10:00-12:00</div> | |
| <div class="time-slot" onclick="toggleTimeSlot('afternoon')">14:00-16:00</div> | |
| </div> | |
| </div> | |
| <!-- Qualité Estimée --> | |
| <div class="form-group"> | |
| <label class="form-label"><i class="fas fa-chart-line"></i> Qualité Estimée de Rétention</label> | |
| <div class="quality-indicator"> | |
| <div class="quality-dot quality-0" onclick="selectQuality(0)">0</div> | |
| <div class="quality-dot quality-1" onclick="selectQuality(1)">1</div> | |
| <div class="quality-dot quality-2 active" onclick="selectQuality(2)">2</div> | |
| <div class="quality-dot quality-3" onclick="selectQuality(3)">3</div> | |
| </div> | |
| <small id="quality-description">Bon - Consolidation progressive</small> | |
| </div> | |
| <button class="btn btn-primary btn-large" onclick="generatePlanner()"> | |
| <i class="fas fa-cogs"></i> Générer le Planner Personnalisé | |
| </button> | |
| </div> | |
| </section> | |
| <!-- Planner Section --> | |
| <section id="planner" class="tab-content"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <h3><i class="fas fa-calendar-alt"></i> Planner Personnalisé</h3> | |
| <button class="btn btn-secondary" onclick="exportPlanner()"> | |
| <i class="fas fa-download"></i> Exporter | |
| </button> | |
| </div> | |
| <div id="plannerStats" class="stats-grid"></div> | |
| <div id="plannerContent" class="planning-grid"></div> | |
| <div class="visualization-container"> | |
| <h4><i class="fas fa-chart-line"></i> Visualisation des Intervalles SM-2</h4> | |
| <div class="chart-container"> | |
| <canvas id="sm2Visualization"></canvas> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Flashcards Section --> | |
| <section id="flashcards" class="tab-content"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <h3><i class="fas fa-layer-group"></i> Flashcards Cognitives - Persévérance & Métacognition</h3> | |
| <div> | |
| <button class="btn btn-secondary" onclick="showCardByCategory('all')"> | |
| <i class="fas fa-filter"></i> Toutes | |
| </button> | |
| <button class="btn btn-secondary" onclick="resetFlashcards()"> | |
| <i class="fas fa-redo"></i> Réinitialiser | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Statistiques des flashcards --> | |
| <div id="flashcardsStats" class="stats-grid"> | |
| <div class="stat-card"> | |
| <div class="stat-value">20</div> | |
| <div class="stat-label">Cartes disponibles</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">0</div> | |
| <div class="stat-label">Cartes consultées</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">0/5</div> | |
| <div class="stat-label">Score moyen</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">Toutes</div> | |
| <div class="stat-label">Catégorie active</div> | |
| </div> | |
| </div> | |
| <!-- Filtres par catégorie --> | |
| <div class="category-filters"> | |
| <div class="category-filter active" onclick="showCardByCategory('all')"> | |
| <i class="fas fa-layer-group"></i> Toutes | |
| </div> | |
| <div class="category-filter" onclick="showCardByCategory('awareness')"> | |
| <i class="fas fa-eye"></i> Prise de conscience | |
| </div> | |
| <div class="category-filter" onclick="showCardByCategory('perseverance')"> | |
| <i class="fas fa-mountain"></i> Persévérance | |
| </div> | |
| <div class="category-filter" onclick="showCardByCategory('effort')"> | |
| <i class="fas fa-bolt"></i> Gestion de l'effort | |
| </div> | |
| </div> | |
| <!-- Contrôles de navigation --> | |
| <div class="flashcards-controls"> | |
| <button class="btn" onclick="prevCard()" id="prevBtn"> | |
| <i class="fas fa-chevron-left"></i> Précédente | |
| </button> | |
| <div style="display: flex; flex-direction: column; align-items: center;"> | |
| <span id="cardCounter" style="font-weight: 600; color: var(--dark-color);"> | |
| Carte 1/20 | |
| </span> | |
| <div class="flashcard-progress"> | |
| <div class="flashcard-progress-bar" id="flashcardProgressBar" style="width: 5%"></div> | |
| </div> | |
| </div> | |
| <button class="btn" onclick="nextCard()" id="nextBtn"> | |
| Suivante <i class="fas fa-chevron-right"></i> | |
| </button> | |
| </div> | |
| <!-- Carte actuelle --> | |
| <div class="flashcard-container"> | |
| <div class="flashcard" id="flashcard" onclick="flipCard()"> | |
| <div class="flashcard-face flashcard-front"> | |
| <div class="flashcard-category" style="background: rgba(59, 130, 246, 0.1); color: #3b82f6;"> | |
| <i class="fas fa-brain"></i> Persévérance | |
| </div> | |
| <div class="flashcard-content"> | |
| <div class="flashcard-title">Persévérer face à la difficulté</div> | |
| <div class="flashcard-question"> | |
| Cette difficulté signifie-t-elle que je suis incapable, ou est-ce simplement une étape normale de l'apprentissage ? | |
| </div> | |
| <div class="flashcard-instruction"> | |
| <i class="fas fa-hand-point-up"></i> Cliquez pour retourner la carte | |
| </div> | |
| </div> | |
| </div> | |
| <div class="flashcard-face flashcard-back" style="background: linear-gradient(135deg, #10b981, #059669);"> | |
| <div class="flashcard-content"> | |
| <div class="flashcard-title">Persévérer face à la difficulté</div> | |
| <div class="flashcard-question"> | |
| Ai-je déjà surmonté une difficulté similaire par le passé ? Se rappeler des succès passés renforce la confiance. | |
| </div> | |
| <div style="margin: 2rem 0; padding: 1.5rem; background: rgba(255, 255, 255, 0.1); border-radius: 10px;"> | |
| <div style="font-weight: bold; margin-bottom: 0.5rem;">Action proposée :</div> | |
| <div>Chercher un exemple où j'ai déjà surmonté une difficulté similaire</div> | |
| </div> | |
| <div class="flashcard-evaluation"> | |
| <div style="font-weight: bold; margin-bottom: 0.5rem;">Utilité de cette réflexion (1-5) :</div> | |
| <input type="range" min="1" max="5" value="3" class="evaluation-slider" id="evaluationSlider"> | |
| <div class="evaluation-label"> | |
| <span>Peu utile</span> | |
| <span>Très utile</span> | |
| </div> | |
| <button class="flashcard-action" onclick="saveEvaluation()"> | |
| <i class="fas fa-save"></i> Enregistrer et continuer | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- DashboardEM --> | |
| <div class="dashboardEM-container"> | |
| <h4><i class="fas fa-chart-bar"></i> DashboardEM - Métriques Métacognitives</h4> | |
| <div class="dashboardEM-grid"> | |
| <div class="dashboardEM-card"> | |
| <div class="dashboardEM-header"> | |
| <div class="dashboardEM-icon" style="background: linear-gradient(135deg, #3b82f6, #1d4ed8);"> | |
| <i class="fas fa-brain"></i> | |
| </div> | |
| <div> | |
| <h4>Persévérance</h4> | |
| <div style="font-size: 0.9rem; color: var(--gray-color);">Capacité à maintenir l'effort</div> | |
| </div> | |
| </div> | |
| <div class="dashboardEM-metric"> | |
| <div class="dashboardEM-value">0/5</div> | |
| <div class="dashboardEM-change">+0%</div> | |
| </div> | |
| <div class="dashboardEM-trend"> | |
| <i class="fas fa-chart-line" style="color: #ef4444;"></i> | |
| <span>À démarrer</span> | |
| </div> | |
| </div> | |
| <div class="dashboardEM-card"> | |
| <div class="dashboardEM-header"> | |
| <div class="dashboardEM-icon" style="background: linear-gradient(135deg, #10b981, #059669);"> | |
| <i class="fas fa-bolt"></i> | |
| </div> | |
| <div> | |
| <h4>Gestion de l'Effort</h4> | |
| <div style="font-size: 0.9rem; color: var(--gray-color);">Efficacité énergétique</div> | |
| </div> | |
| </div> | |
| <div class="dashboardEM-metric"> | |
| <div class="dashboardEM-value">0/5</div> | |
| <div class="dashboardEM-change">0%</div> | |
| </div> | |
| <div class="dashboardEM-trend"> | |
| <i class="fas fa-chart-line" style="color: #ef4444;"></i> | |
| <span>À améliorer</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Journal Section --> | |
| <section id="journal" class="tab-content"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <h3><i class="fas fa-book"></i> Journal d'Apprentissage Autorégulé</h3> | |
| <button class="btn btn-secondary" onclick="loadJournalEntries()"> | |
| <i class="fas fa-history"></i> Historique | |
| </button> | |
| </div> | |
| <div class="form-row"> | |
| <div class="form-col"> | |
| <label class="form-label"><i class="fas fa-tasks"></i> Planifié (To-Do)</label> | |
| <textarea id="todo" class="form-control" rows="3" placeholder="Ce que vous prévoyez d'apprendre..."></textarea> | |
| </div> | |
| <div class="form-col"> | |
| <label class="form-label"><i class="fas fa-spinner"></i> En Cours (Doing)</label> | |
| <textarea id="doing" class="form-control" rows="3" placeholder="Ce que vous faites actuellement..."></textarea> | |
| </div> | |
| </div> | |
| <div class="form-group"> | |
| <label class="form-label"><i class="fas fa-check-circle"></i> Accompli (Done)</label> | |
| <textarea id="done" class="form-control" rows="3" placeholder="Ce que vous avez accompli..."></textarea> | |
| </div> | |
| <div class="form-group"> | |
| <label class="form-label"><i class="fas fa-star"></i> Auto-évaluation (1-5)</label> | |
| <div class="quality-indicator"> | |
| <div class="quality-dot" onclick="setEvaluation(1)" style="background: linear-gradient(135deg, #ef4444, #dc2626);">1</div> | |
| <div class="quality-dot" onclick="setEvaluation(2)" style="background: linear-gradient(135deg, #f59e0b, #d97706);">2</div> | |
| <div class="quality-dot active" onclick="setEvaluation(3)" style="background: linear-gradient(135deg, #10b981, #059669);">3</div> | |
| <div class="quality-dot" onclick="setEvaluation(4)" style="background: linear-gradient(135deg, #3b82f6, #1d4ed8);">4</div> | |
| <div class="quality-dot" onclick="setEvaluation(5)" style="background: linear-gradient(135deg, #8b5cf6, #7c3aed);">5</div> | |
| </div> | |
| </div> | |
| <div class="form-group"> | |
| <label class="form-label"><i class="fas fa-lightbulb"></i> Stratégie Métacognitive</label> | |
| <textarea id="metacognition" class="form-control" rows="3" placeholder="Quelle stratégie avez-vous utilisée ? Que changeriez-vous ?"></textarea> | |
| </div> | |
| <button class="btn btn-primary btn-large" onclick="saveJournal()"> | |
| <i class="fas fa-save"></i> Sauvegarder l'Entrée | |
| </button> | |
| <div id="journalHistory" style="display: none; margin-top: 2rem;"> | |
| <h4><i class="fas fa-history"></i> Dernières Entrées</h4> | |
| <div id="journalEntries"></div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Notifications Section --> | |
| <section id="notifications" class="tab-content"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <h3><i class="fas fa-bell"></i> Notifications Intelligentes par Bandits Multi-Bras</h3> | |
| <button class="btn btn-secondary" onclick="getIntelligentReminder()"> | |
| <i class="fas fa-sync"></i> Nouveau Rappel | |
| </button> | |
| </div> | |
| <div id="notificationContainer"> | |
| <div class="notification-card"> | |
| <p><i class="fas fa-info-circle"></i> Cliquez sur "Nouveau Rappel" pour recevoir une notification personnalisée basée sur vos habitudes d'apprentissage.</p> | |
| </div> | |
| </div> | |
| <div class="visualization-container"> | |
| <h4><i class="fas fa-chart-bar"></i> Efficacité des Types de Notifications</h4> | |
| <div class="chart-container"> | |
| <canvas id="notificationChart"></canvas> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Statistics Section --> | |
| <section id="stats" class="tab-content"> | |
| <div class="card"> | |
| <div class="card-header"> | |
| <h3><i class="fas fa-chart-line"></i> Tableau de Bord d'Apprentissage</h3> | |
| <button class="btn btn-secondary" onclick="refreshStats()"> | |
| <i class="fas fa-redo"></i> Actualiser | |
| </button> | |
| </div> | |
| <div id="statsContainer" class="stats-grid"> | |
| <div class="stat-card"> | |
| <div class="stat-value">12</div> | |
| <div class="stat-label">Sessions Complétées</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">85%</div> | |
| <div class="stat-label">Taux de Réussite</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">7</div> | |
| <div class="stat-label">Jours d'Activité</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">4.2/5</div> | |
| <div class="stat-label">Satisfaction</div> | |
| </div> | |
| </div> | |
| <!-- Heatmap d'activité --> | |
| <div class="heatmap-container"> | |
| <div class="heatmap-header"> | |
| <div class="heatmap-title"> | |
| <i class="fas fa-fire"></i> Heatmap d'activité | |
| </div> | |
| <div class="heatmap-controls"> | |
| <button class="heatmap-period active" onclick="changeHeatmapPeriod('month')">Mois</button> | |
| <button class="heatmap-period" onclick="changeHeatmapPeriod('quarter')">Trimestre</button> | |
| <button class="heatmap-period" onclick="changeHeatmapPeriod('year')">Année</button> | |
| </div> | |
| </div> | |
| <div id="heatmapContent"> | |
| <!-- La heatmap sera générée ici par JavaScript --> | |
| </div> | |
| <div class="heatmap-legend"> | |
| <div class="legend-item"> | |
| <div class="legend-color heatmap-intensity-0"></div> | |
| <span>0 min</span> | |
| </div> | |
| <div class="legend-item"> | |
| <div class="legend-color heatmap-intensity-1"></div> | |
| <span>15 min</span> | |
| </div> | |
| <div class="legend-item"> | |
| <div class="legend-color heatmap-intensity-2"></div> | |
| <span>30 min</span> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Indicateurs de gestion du temps --> | |
| <div class="time-management-stats"> | |
| <div class="time-stat-card"> | |
| <div class="time-stat-header"> | |
| <div class="time-stat-icon"> | |
| <i class="fas fa-calendar-check"></i> | |
| </div> | |
| <div> | |
| <h4>Régularité du travail</h4> | |
| <div class="time-stat-description">Constance de l'activité dans le temps</div> | |
| </div> | |
| </div> | |
| <div class="progress-circle"> | |
| <svg viewBox="0 0 100 100"> | |
| <circle cx="50" cy="50" r="45" fill="none" stroke="#e2e8f0" stroke-width="8"/> | |
| <circle cx="50" cy="50" r="45" fill="none" stroke="#10b981" stroke-width="8" | |
| stroke-linecap="round" stroke-dasharray="283" stroke-dashoffset="28.3"/> | |
| </svg> | |
| <div class="progress-text">90%</div> | |
| </div> | |
| </div> | |
| <div class="time-stat-card"> | |
| <div class="time-stat-header"> | |
| <div class="time-stat-icon" style="background: linear-gradient(135deg, #3b82f6, #1d4ed8);"> | |
| <i class="fas fa-clock"></i> | |
| </div> | |
| <div> | |
| <h4>Gestion des échéances</h4> | |
| <div class="time-stat-description">Capacité à respecter les délais</div> | |
| </div> | |
| </div> | |
| <div class="progress-circle"> | |
| <svg viewBox="0 0 100 100"> | |
| <circle cx="50" cy="50" r="45" fill="none" stroke="#e2e8f0" stroke-width="8"/> | |
| <circle cx="50" cy="50" r="45" fill="none" stroke="#3b82f6" stroke-width="8" | |
| stroke-linecap="round" stroke-dasharray="283" stroke-dashoffset="53.77"/> | |
| </svg> | |
| <div class="progress-text">81%</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| </div> | |
| <script> | |
| // ============================================ | |
| // VARIABLES GLOBALES | |
| // ============================================ | |
| // Variables pour le profil | |
| let learnerProfile = { | |
| bigFive: { | |
| extraversion: 3, | |
| openness: 3, | |
| conscientiousness: 4, | |
| agreeableness: 3, | |
| neuroticism: 4 | |
| }, | |
| motivation: { | |
| intrinsic: 3, | |
| introjected: 4, | |
| identified: 3, | |
| external: 1 | |
| }, | |
| habits: {}, | |
| wellbeing: {}, | |
| support: {}, | |
| completionStatus: { | |
| big5: true, | |
| motivation: true, | |
| habits: false, | |
| wellbeing: false, | |
| support: false | |
| } | |
| }; | |
| // Variables pour le planner | |
| let selectedTimeSlots = ['morning']; | |
| let currentQuality = 2; | |
| let productivityMethod = 'pomodoro'; | |
| let energyPattern = 'morning'; | |
| // Variables pour la heatmap | |
| let currentHeatmapPeriod = 'month'; | |
| // Variables pour le journal | |
| let journalEntries = []; | |
| // Variables pour les flashcards | |
| let flashcards = []; | |
| let currentCardIndex = 0; | |
| let currentCategory = 'all'; | |
| let flashcardsData = []; | |
| let flashcardsStats = { | |
| totalCards: 0, | |
| reviewedCards: 0, | |
| averageScore: 0, | |
| favoriteCategory: '' | |
| }; | |
| // ============================================ | |
| // INITIALISATION | |
| // ============================================ | |
| document.addEventListener('DOMContentLoaded', function() { | |
| // Initialiser le profil | |
| updateProfileProgress(); | |
| updateProfileSummary(); | |
| createMotivationChart(); | |
| // Initialiser la heatmap | |
| generateHeatmap(); | |
| // Initialiser le graphique des notifications | |
| createNotificationChart(); | |
| // Initialiser les flashcards | |
| initializeFlashcards(); | |
| // Charger les données sauvegardées | |
| loadSavedData(); | |
| }); | |
| // ============================================ | |
| // FONCTIONS DE NAVIGATION | |
| // ============================================ | |
| function showTab(tabId) { | |
| // Masquer toutes les sections | |
| document.querySelectorAll('.tab-content').forEach(section => { | |
| section.classList.remove('active'); | |
| }); | |
| // Désactiver tous les onglets | |
| document.querySelectorAll('.nav-tab').forEach(tab => { | |
| tab.classList.remove('active'); | |
| }); | |
| // Activer la section sélectionnée | |
| document.getElementById(tabId).classList.add('active'); | |
| // Activer l'onglet correspondant | |
| const tabNames = { | |
| 'profile': 'Profil Apprenant', | |
| 'objectif': 'Objectif', | |
| 'planner': 'Planner ', | |
| 'flashcards': 'Métacognition', | |
| 'journal': 'Journal SRL', | |
| 'notifications': 'Notifications IA', | |
| 'stats': 'Statistiques' | |
| }; | |
| document.querySelectorAll('.nav-tab').forEach(tab => { | |
| if (tab.textContent.includes(tabNames[tabId])) { | |
| tab.classList.add('active'); | |
| } | |
| }); | |
| // Actions spécifiques par onglet | |
| if (tabId === 'stats') { | |
| refreshStats(); | |
| generateHeatmap(); | |
| } else if (tabId === 'flashcards') { | |
| updateFlashcardsStats(); | |
| updateDashboardEM(); | |
| } | |
| } | |
| // ============================================ | |
| // PROFIL APPRENANT | |
| // ============================================ | |
| // Sélectionner une échelle | |
| function selectScale(trait, value) { | |
| learnerProfile.bigFive[trait] = value; | |
| updateScaleUI(trait, value); | |
| updateProfileSummary(); | |
| updateSectionCompletion('big5-section'); | |
| } | |
| // Sélectionner une motivation | |
| function selectMotivation(type, value) { | |
| learnerProfile.motivation[type] = value; | |
| updateScaleUI(type, value); | |
| updateProfileSummary(); | |
| updateSectionCompletion('motivation-section'); | |
| } | |
| // Mettre à jour l'UI de l'échelle | |
| function updateScaleUI(type, value) { | |
| // Trouver tous les boutons d'échelle pour ce type | |
| const scaleOptions = document.querySelectorAll(`[onclick*="${type}"]`); | |
| scaleOptions.forEach(option => { | |
| option.classList.remove('selected'); | |
| // Extraire la valeur du bouton | |
| const match = option.getAttribute('onclick').match(/(\d+)/); | |
| if (match && parseInt(match[1]) === value) { | |
| option.classList.add('selected'); | |
| } | |
| }); | |
| } | |
| // Vérifier si toutes les questions d'une section sont répondues | |
| function checkSectionCompletion(sectionId) { | |
| const section = document.getElementById(sectionId); | |
| const scaleOptions = section.querySelectorAll('.scale-option.selected'); | |
| // Nombre attendu de questions par section | |
| const expectedCount = { | |
| 'big5-section': 5, | |
| 'motivation-section': 2 | |
| }; | |
| return scaleOptions.length >= expectedCount[sectionId]; | |
| } | |
| // Mettre à jour l'indicateur de complétion d'une section | |
| function updateSectionCompletion(sectionId) { | |
| const isComplete = checkSectionCompletion(sectionId); | |
| const sectionKey = sectionId.replace('-section', ''); | |
| const completionElement = document.getElementById(`${sectionKey}-completion`); | |
| // Mettre à jour le statut dans le profil | |
| learnerProfile.completionStatus[sectionKey] = isComplete; | |
| if (isComplete) { | |
| completionElement.className = 'section-completion section-complete'; | |
| let message = "Section complétée"; | |
| if (sectionKey === 'big5') { | |
| const neuroticism = learnerProfile.bigFive.neuroticism || 3; | |
| message += ` - <strong>Score neuroticisme: ${neuroticism}</strong> (qualité du sommeil ${neuroticism >= 4 ? 'importante' : 'modérée'})`; | |
| } else if (sectionKey === 'motivation') { | |
| const introjected = learnerProfile.motivation.introjected || 3; | |
| message += ` - <strong>Motivation introjectée: ${introjected}</strong> (pression ${introjected >= 4 ? 'élevée' : 'modérée'})`; | |
| } | |
| completionElement.innerHTML = `<i class="fas fa-check-circle" style="color: #10b981;"></i><span>${message}</span>`; | |
| } else { | |
| completionElement.className = 'section-completion section-incomplete'; | |
| completionElement.innerHTML = `<i class="fas fa-exclamation-circle" style="color: #ef4444;"></i><span>Section incomplète - Remplissez toutes les questions</span>`; | |
| } | |
| // Mettre à jour la progression globale | |
| updateProfileProgress(); | |
| } | |
| // Mettre à jour la progression du profil | |
| function updateProfileProgress() { | |
| const sections = Object.values(learnerProfile.completionStatus); | |
| const completedCount = sections.filter(status => status).length; | |
| const totalSections = sections.length; | |
| const percentage = Math.round((completedCount / totalSections) * 100); | |
| // Mettre à jour la barre de progression | |
| document.getElementById('profileCompletion').textContent = `${percentage}%`; | |
| document.getElementById('profileProgressBar').style.width = `${percentage}%`; | |
| // Mettre à jour le compteur | |
| document.getElementById('completedSections').textContent = `${completedCount}/${totalSections}`; | |
| // Mettre à jour le niveau de personnalisation | |
| let level = "Basique"; | |
| if (percentage >= 20) level = "Débutant"; | |
| if (percentage >= 40) level = "Intermédiaire"; | |
| if (percentage >= 60) level = "Avancé"; | |
| if (percentage >= 80) level = "Expert"; | |
| if (percentage === 100) level = "Personnalisé"; | |
| document.getElementById('personalizationLevel').textContent = level; | |
| } | |
| // Mettre à jour le résumé du profil | |
| function updateProfileSummary() { | |
| // Mettre à jour les valeurs Big Five | |
| document.getElementById('extraversion-value').textContent = learnerProfile.bigFive.extraversion.toFixed(1); | |
| document.getElementById('openness-value').textContent = learnerProfile.bigFive.openness.toFixed(1); | |
| document.getElementById('conscientiousness-value').textContent = learnerProfile.bigFive.conscientiousness.toFixed(1); | |
| document.getElementById('agreeableness-value').textContent = learnerProfile.bigFive.agreeableness.toFixed(1); | |
| document.getElementById('neuroticism-value').textContent = learnerProfile.bigFive.neuroticism.toFixed(1); | |
| // Mettre à jour les valeurs de motivation | |
| document.getElementById('intrinsic-value').textContent = learnerProfile.motivation.intrinsic.toFixed(1); | |
| document.getElementById('introjected-value').textContent = learnerProfile.motivation.introjected.toFixed(1); | |
| document.getElementById('identified-value').textContent = learnerProfile.motivation.identified.toFixed(1); | |
| document.getElementById('external-value').textContent = learnerProfile.motivation.external.toFixed(1); | |
| // Mettre à jour le graphique de motivation | |
| updateMotivationChart(); | |
| } | |
| // Créer le graphique de motivation | |
| function createMotivationChart() { | |
| const ctx = document.getElementById('motivationChart').getContext('2d'); | |
| window.motivationChart = new Chart(ctx, { | |
| type: 'radar', | |
| data: { | |
| labels: ['Intrinsèque', 'Introjectée', 'Identifiée', 'Externe'], | |
| datasets: [{ | |
| label: 'Motivation', | |
| data: [ | |
| learnerProfile.motivation.intrinsic, | |
| learnerProfile.motivation.introjected, | |
| learnerProfile.motivation.identified, | |
| learnerProfile.motivation.external | |
| ], | |
| backgroundColor: 'rgba(59, 130, 246, 0.2)', | |
| borderColor: 'rgb(59, 130, 246)', | |
| pointBackgroundColor: 'rgb(59, 130, 246)', | |
| pointBorderColor: '#fff', | |
| pointHoverBackgroundColor: '#fff', | |
| pointHoverBorderColor: 'rgb(59, 130, 246)' | |
| }] | |
| }, | |
| options: { | |
| scales: { | |
| r: { | |
| beginAtZero: true, | |
| max: 5, | |
| ticks: { | |
| stepSize: 1 | |
| } | |
| } | |
| }, | |
| responsive: true, | |
| maintainAspectRatio: false | |
| } | |
| }); | |
| } | |
| // Mettre à jour le graphique de motivation | |
| function updateMotivationChart() { | |
| if (window.motivationChart) { | |
| window.motivationChart.data.datasets[0].data = [ | |
| learnerProfile.motivation.intrinsic, | |
| learnerProfile.motivation.introjected, | |
| learnerProfile.motivation.identified, | |
| learnerProfile.motivation.external | |
| ]; | |
| window.motivationChart.update(); | |
| } | |
| } | |
| // Compléter automatiquement toutes les sections | |
| function completeAllSections() { | |
| // Remplir les sections manquantes avec des valeurs par défaut | |
| const defaultValues = { | |
| study_hours: 3, | |
| late_submissions: 2, | |
| completion_rate: 4, | |
| forum_participation: 2, | |
| sleep_hours: 4, | |
| study_stress: 3, | |
| relaxation: 3, | |
| burnout_risk: 2, | |
| family_support: 4, | |
| parental_expectations: 4, | |
| study_environment: 4, | |
| peer_collaboration: 3 | |
| }; | |
| // Marquer toutes les sections comme complètes | |
| Object.keys(learnerProfile.completionStatus).forEach(key => { | |
| learnerProfile.completionStatus[key] = true; | |
| }); | |
| // Mettre à jour l'interface | |
| updateProfileProgress(); | |
| updateProfileSummary(); | |
| // Mettre à jour les indicateurs de section | |
| updateSectionCompletion('habits-section'); | |
| updateSectionCompletion('wellbeing-section'); | |
| updateSectionCompletion('support-section'); | |
| showNotification('Toutes les sections ont été complétées automatiquement !', 'success'); | |
| } | |
| // Sauvegarder le profil | |
| function saveProfile() { | |
| try { | |
| localStorage.setItem('learnerProfile', JSON.stringify(learnerProfile)); | |
| showNotification('Profil sauvegardé avec succès !', 'success'); | |
| } catch (error) { | |
| showNotification('Erreur lors de la sauvegarde du profil', 'error'); | |
| } | |
| } | |
| // Finaliser le profil | |
| function completeProfile() { | |
| // Vérifier si toutes les sections sont complétées | |
| const incompleteSections = Object.entries(learnerProfile.completionStatus) | |
| .filter(([section, completed]) => !completed) | |
| .map(([section]) => section); | |
| if (incompleteSections.length > 0) { | |
| showNotification(`Veuillez compléter les sections suivantes: ${incompleteSections.join(', ')}`, 'warning'); | |
| return; | |
| } | |
| // Sauvegarder le profil | |
| saveProfile(); | |
| // Générer des recommandations personnalisées | |
| generatePersonalizedRecommendations(); | |
| showNotification('Profil finalisé avec succès ! Les recommandations ont été mises à jour.', 'success'); | |
| } | |
| // Générer des recommandations personnalisées | |
| function generatePersonalizedRecommendations() { | |
| const recommendations = []; | |
| // Recommandations basées sur le Big Five | |
| if (learnerProfile.bigFive.neuroticism >= 4) { | |
| recommendations.push({ | |
| icon: '💤', | |
| text: `Avec un névrosisme élevé (${learnerProfile.bigFive.neuroticism}), planifiez 8 heures de sommeil de qualité avec des activités de relaxation.` | |
| }); | |
| } | |
| if (learnerProfile.bigFive.conscientiousness >= 4) { | |
| recommendations.push({ | |
| icon: '📅', | |
| text: `Votre conscience élevée (${learnerProfile.bigFive.conscientiousness}) est excellente pour l'auto-discipline. Évitez le surmenage.` | |
| }); | |
| } | |
| // Recommandations basées sur la motivation | |
| if (learnerProfile.motivation.introjected >= 4) { | |
| recommendations.push({ | |
| icon: '🎯', | |
| text: `Motivation introjectée élevée (${learnerProfile.motivation.introjected}). Pratiquez des techniques de gestion du stress.` | |
| }); | |
| } | |
| // Mettre à jour l'affichage des recommandations | |
| updateRecommendationsDisplay(recommendations); | |
| } | |
| // Mettre à jour l'affichage des recommandations | |
| function updateRecommendationsDisplay(recommendations) { | |
| const container = document.querySelector('.recommendations-section'); | |
| let html = '<h4><i class="fas fa-lightbulb"></i> Recommandations Personnalisées Basées sur Votre Profil</h4>'; | |
| recommendations.forEach(rec => { | |
| html += ` | |
| <div class="recommendation-item"> | |
| <div class="recommendation-icon">${rec.icon}</div> | |
| <div>${rec.text}</div> | |
| </div> | |
| `; | |
| }); | |
| container.innerHTML = html; | |
| } | |
| // ============================================ | |
| // OBJECTIF ET PLANNER | |
| // ============================================ | |
| // Sélectionner la méthode de productivité | |
| function selectProductivityMethod(method) { | |
| productivityMethod = method; | |
| document.querySelectorAll('.option-item').forEach(item => { | |
| item.classList.remove('selected'); | |
| }); | |
| event.target.closest('.option-item').classList.add('selected'); | |
| } | |
| // Sélectionner le type d'énergie | |
| function selectEnergyPattern(pattern) { | |
| energyPattern = pattern; | |
| const patternElements = document.querySelectorAll('.option-section:nth-child(2) .option-item'); | |
| patternElements.forEach(item => { | |
| item.classList.remove('selected'); | |
| }); | |
| event.target.closest('.option-item').classList.add('selected'); | |
| } | |
| // Basculer créneau horaire | |
| function toggleTimeSlot(slot) { | |
| const index = selectedTimeSlots.indexOf(slot); | |
| if (index === -1) { | |
| selectedTimeSlots.push(slot); | |
| } else { | |
| selectedTimeSlots.splice(index, 1); | |
| } | |
| // Mettre à jour l'interface | |
| document.querySelectorAll('.time-slot').forEach(element => { | |
| element.classList.remove('selected'); | |
| }); | |
| selectedTimeSlots.forEach(slot => { | |
| document.querySelector(`.time-slot:nth-child(${getTimeSlotIndex(slot) + 1})`).classList.add('selected'); | |
| }); | |
| } | |
| function getTimeSlotIndex(slot) { | |
| const slots = ['morning', 'late_morning', 'afternoon', 'late_afternoon', 'evening']; | |
| return slots.indexOf(slot); | |
| } | |
| // Sélectionner la qualité | |
| function selectQuality(level) { | |
| currentQuality = level; | |
| document.querySelectorAll('.quality-dot').forEach(dot => { | |
| dot.classList.remove('active'); | |
| }); | |
| event.target.classList.add('active'); | |
| const descriptions = [ | |
| "Difficulté - Révision fréquente nécessaire", | |
| "Moyen - Intervalles standard recommandés", | |
| "Bon - Consolidation progressive", | |
| "Excellent - Rétention à long terme optimale" | |
| ]; | |
| document.getElementById('quality-description').textContent = descriptions[level]; | |
| } | |
| // Générer le planner | |
| function generatePlanner() { | |
| const competence = document.getElementById('competence').value; | |
| const startDate = document.getElementById('start').value; | |
| const duration = document.getElementById('duration').value; | |
| if (!competence) { | |
| showNotification('Veuillez sélectionner une compétence', 'warning'); | |
| return; | |
| } | |
| // Générer les intervalles SM-2 basés sur la qualité | |
| const intervals = getSM2Intervals(currentQuality); | |
| // Créer le planning | |
| const plan = createStudyPlan(competence, startDate, duration, intervals); | |
| // Afficher le planning | |
| displayPlanner(plan, intervals); | |
| // Passer à l'onglet planner | |
| showTab('planner'); | |
| showNotification('Planner généré avec succès !', 'success'); | |
| } | |
| // Obtenir les intervalles SM-2 | |
| function getSM2Intervals(quality) { | |
| const intervals = { | |
| 0: [1, 2, 4, 8, 16, 32], // Difficulté | |
| 1: [1, 3, 7, 14, 30, 60], // Moyen | |
| 2: [2, 7, 16, 35, 70, 140], // Bon | |
| 3: [3, 10, 25, 60, 120, 240] // Excellent | |
| }; | |
| return intervals[quality] || intervals[2]; | |
| } | |
| // Créer le plan d'étude | |
| function createStudyPlan(competence, startDate, duration, intervals) { | |
| const plan = []; | |
| const start = new Date(startDate); | |
| for (let i = 0; i < intervals.length; i++) { | |
| const sessionDate = new Date(start); | |
| sessionDate.setDate(sessionDate.getDate() + intervals[i]); | |
| plan.push({ | |
| date: sessionDate.toLocaleDateString('fr-FR'), | |
| jour: sessionDate.toLocaleDateString('fr-FR', { weekday: 'long' }), | |
| competence: competence, | |
| duree: `${duration} minutes`, | |
| intervalle: `${intervals[i]} jours`, | |
| repetition: i + 1, | |
| type: i === 0 ? 'Apprentissage' : i < 3 ? 'Consolidation' : 'Maintien', | |
| strategie: i === 0 ? 'Focus intense' : 'Révision active', | |
| productivity_method: productivityMethod === 'pomodoro' ? 'Pomodoro' : 'Deep Work', | |
| optimal_time: energyPattern === 'morning' ? '08:00-10:00' : | |
| energyPattern === 'evening' ? '19:00-21:00' : 'Adaptable' | |
| }); | |
| } | |
| return plan; | |
| } | |
| // Afficher le planner | |
| function displayPlanner(plan, intervals) { | |
| const container = document.getElementById('plannerContent'); | |
| const statsContainer = document.getElementById('plannerStats'); | |
| // Calculer le total des jours | |
| const totalDays = intervals.reduce((a, b) => a + b, 0); | |
| // Statistiques | |
| statsContainer.innerHTML = ` | |
| <div class="stat-card"> | |
| <div class="stat-value">${plan.length}</div> | |
| <div class="stat-label">Sessions Planifiées</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">${totalDays}</div> | |
| <div class="stat-label">Jours Totaux</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">${currentQuality + 1}/4</div> | |
| <div class="stat-label">Niveau de Qualité</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">${document.getElementById('duration').value}min</div> | |
| <div class="stat-label">Durée/Session</div> | |
| </div> | |
| `; | |
| // Sessions | |
| container.innerHTML = ''; | |
| plan.forEach(session => { | |
| const card = document.createElement('div'); | |
| card.className = 'session-card'; | |
| card.innerHTML = ` | |
| <div class="session-header"> | |
| <div class="session-date"> | |
| <i class="fas fa-calendar-day"></i> ${session.date} | |
| <div style="font-size: 0.9rem; color: #64748b;">${session.jour}</div> | |
| </div> | |
| <div class="session-repetition"> | |
| R${session.repetition} | |
| </div> | |
| </div> | |
| <h4 style="margin: 10px 0; color: #1e293b;">${session.competence}</h4> | |
| <div class="session-details"> | |
| <div class="detail-item"> | |
| <span><i class="fas fa-clock"></i> Durée</span> | |
| <span>${session.duree}</span> | |
| </div> | |
| <div class="detail-item"> | |
| <span><i class="fas fa-sync-alt"></i> Intervalle</span> | |
| <span>${session.intervalle}</span> | |
| </div> | |
| <div class="detail-item"> | |
| <span><i class="fas fa-bullseye"></i> Type</span> | |
| <span>${session.type}</span> | |
| </div> | |
| <div class="detail-item"> | |
| <span><i class="fas fa-lightbulb"></i> Stratégie</span> | |
| <span>${session.strategie}</span> | |
| </div> | |
| <div class="detail-item"> | |
| <span><i class="fas fa-chart-line"></i> Productivité</span> | |
| <span>${session.productivity_method}</span> | |
| </div> | |
| <div class="detail-item"> | |
| <span><i class="fas fa-sun"></i> Heure Optimale</span> | |
| <span>${session.optimal_time}</span> | |
| </div> | |
| </div> | |
| `; | |
| container.appendChild(card); | |
| }); | |
| // Visualisation | |
| createSM2Visualization(intervals, plan[0]?.competence || 'Compétence'); | |
| } | |
| // Créer la visualisation SM-2 | |
| function createSM2Visualization(intervals, competence) { | |
| const ctx = document.getElementById('sm2Visualization').getContext('2d'); | |
| if (window.sm2VisualizationChart) { | |
| window.sm2VisualizationChart.destroy(); | |
| } | |
| const labels = intervals.map((_, i) => `Répétition ${i + 1}`); | |
| window.sm2VisualizationChart = new Chart(ctx, { | |
| type: 'line', | |
| data: { | |
| labels: labels, | |
| datasets: [{ | |
| label: 'Intervalle (jours)', | |
| data: intervals, | |
| borderColor: '#3b82f6', | |
| backgroundColor: 'rgba(59, 130, 246, 0.1)', | |
| borderWidth: 3, | |
| fill: true, | |
| tension: 0.4 | |
| }] | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| plugins: { | |
| title: { | |
| display: true, | |
| text: `Courbe de Répétition Espacée - ${competence}`, | |
| font: { size: 16 } | |
| } | |
| }, | |
| scales: { | |
| y: { | |
| beginAtZero: true, | |
| title: { | |
| display: true, | |
| text: 'Jours' | |
| } | |
| }, | |
| x: { | |
| title: { | |
| display: true, | |
| text: 'Numéro de Répétition' | |
| } | |
| } | |
| } | |
| } | |
| }); | |
| } | |
| // Exporter le planner | |
| function exportPlanner() { | |
| const plannerData = document.getElementById('plannerContent').innerText; | |
| const blob = new Blob([plannerData], { type: 'text/plain' }); | |
| const url = URL.createObjectURL(blob); | |
| const a = document.createElement('a'); | |
| a.href = url; | |
| a.download = 'planner-sm2.txt'; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| URL.revokeObjectURL(url); | |
| showNotification('Planner exporté avec succès !', 'success'); | |
| } | |
| // ============================================ | |
| // FLASHCARDS COGNITIVES | |
| // ============================================ | |
| // Initialiser les flashcards | |
| function initializeFlashcards() { | |
| // Données des flashcards | |
| flashcardsData = [ | |
| { | |
| id: 1, | |
| category: 'awareness', | |
| categoryName: 'Prise de conscience', | |
| icon: '👁️', | |
| color: '#3b82f6', | |
| front: { | |
| title: 'Diagnostic de Blocage', | |
| question: 'Qu\'est-ce qui me bloque exactement dans cette tâche ?' | |
| }, | |
| back: { | |
| reflection: 'Est-ce un problème de compréhension, d\'énergie, ou de motivation ? Identifier précisément le type d\'obstacle.', | |
| action: 'Prendre 2 minutes pour écrire ce qui semble difficile', | |
| evaluationLabel: 'Clarté du diagnostic' | |
| } | |
| }, | |
| { | |
| id: 2, | |
| category: 'perseverance', | |
| categoryName: 'Persévérance', | |
| icon: '🏔️', | |
| color: '#10b981', | |
| front: { | |
| title: 'Persévérer face à la difficulté', | |
| question: 'Cette difficulté signifie-t-elle que je suis incapable ?' | |
| }, | |
| back: { | |
| reflection: 'Ai-je déjà surmonté une difficulté similaire par le passé ? Se rappeler des succès passés renforce la confiance.', | |
| action: 'Chercher un exemple où j\'ai déjà surmonté une difficulté similaire', | |
| evaluationLabel: 'Résilience perçue' | |
| } | |
| }, | |
| { | |
| id: 3, | |
| category: 'effort', | |
| categoryName: 'Gestion de l\'effort', | |
| icon: '⚡', | |
| color: '#f59e0b', | |
| front: { | |
| title: 'Niveau d\'Énergie', | |
| question: 'Mon niveau d\'énergie est-il adapté à cette tâche ?' | |
| }, | |
| back: { | |
| reflection: 'Ai-je besoin d\'une pause ou d\'un changement d\'activité ? Travailler avec un niveau d\'énergie bas réduit l\'efficacité.', | |
| action: 'Faire une pause de 5 minutes avec une activité énergisante', | |
| evaluationLabel: 'Gestion énergétique' | |
| } | |
| } | |
| ]; | |
| // Initialiser les stats | |
| flashcardsStats.totalCards = flashcardsData.length; | |
| flashcardsStats.reviewedCards = 0; | |
| flashcardsStats.averageScore = 0; | |
| // Afficher la première carte | |
| showCardByCategory('all'); | |
| } | |
| // Afficher une carte par catégorie | |
| function showCardByCategory(category) { | |
| currentCategory = category; | |
| currentCardIndex = 0; | |
| // Mettre à jour les filtres | |
| document.querySelectorAll('.category-filter').forEach(filter => { | |
| filter.classList.remove('active'); | |
| }); | |
| document.querySelector(`.category-filter[onclick*="${category}"]`).classList.add('active'); | |
| // Filtrer les cartes par catégorie | |
| if (category === 'all') { | |
| flashcards = [...flashcardsData]; | |
| } else { | |
| flashcards = flashcardsData.filter(card => card.category === category); | |
| } | |
| // Mélanger les cartes | |
| shuffleArray(flashcards); | |
| // Afficher la première carte | |
| displayCurrentCard(); | |
| // Mettre à jour les stats | |
| updateFlashcardsStats(); | |
| } | |
| // Mélanger un tableau | |
| function shuffleArray(array) { | |
| for (let i = array.length - 1; i > 0; i--) { | |
| const j = Math.floor(Math.random() * (i + 1)); | |
| [array[i], array[j]] = [array[j], array[i]]; | |
| } | |
| return array; | |
| } | |
| // Afficher la carte actuelle | |
| function displayCurrentCard() { | |
| if (flashcards.length === 0) return; | |
| const card = flashcards[currentCardIndex]; | |
| const progress = ((currentCardIndex + 1) / flashcards.length * 100).toFixed(1); | |
| // Mettre à jour la carte | |
| const flashcard = document.getElementById('flashcard'); | |
| if (flashcard) { | |
| // Face avant | |
| flashcard.querySelector('.flashcard-category').innerHTML = ` | |
| <i class="fas fa-${card.icon}"></i> ${card.categoryName} | |
| `; | |
| flashcard.querySelector('.flashcard-category').style.background = `${card.color}22`; | |
| flashcard.querySelector('.flashcard-category').style.color = card.color; | |
| flashcard.querySelector('.flashcard-title').textContent = card.front.title; | |
| flashcard.querySelector('.flashcard-question').textContent = card.front.question; | |
| // Face arrière | |
| const backFace = flashcard.querySelector('.flashcard-back'); | |
| backFace.style.background = `linear-gradient(135deg, ${card.color}, ${darkenColor(card.color, 20)})`; | |
| backFace.querySelector('.flashcard-title').textContent = card.front.title; | |
| backFace.querySelector('.flashcard-question').textContent = card.back.reflection; | |
| // Mettre à jour l'action | |
| backFace.querySelector('.flashcard-evaluation .flashcard-question').textContent = card.back.reflection; | |
| backFace.querySelector('.flashcard-evaluation > div:nth-child(2) > div:nth-child(2)').textContent = card.back.action; | |
| // Mettre à jour le label d'évaluation | |
| backFace.querySelector('.flashcard-evaluation > div:nth-child(3) > div:nth-child(1)').textContent = `${card.back.evaluationLabel} (1-5) :`; | |
| } | |
| // Mettre à jour le compteur et la barre de progression | |
| document.getElementById('cardCounter').textContent = `Carte ${currentCardIndex + 1}/${flashcards.length}`; | |
| document.getElementById('flashcardProgressBar').style.width = `${progress}%`; | |
| // Gérer les boutons de navigation | |
| document.getElementById('prevBtn').disabled = currentCardIndex === 0; | |
| document.getElementById('nextBtn').disabled = currentCardIndex === flashcards.length - 1; | |
| // Réinitialiser la rotation de la carte | |
| flashcard.classList.remove('flipped'); | |
| } | |
| // Fonction pour assombrir une couleur | |
| function darkenColor(color, percent) { | |
| const num = parseInt(color.replace("#", ""), 16); | |
| const amt = Math.round(2.55 * percent); | |
| const R = (num >> 16) - amt; | |
| const G = (num >> 8 & 0x00FF) - amt; | |
| const B = (num & 0x0000FF) - amt; | |
| return "#" + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 + | |
| (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 + | |
| (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1); | |
| } | |
| // Retourner la carte | |
| function flipCard() { | |
| const flashcard = document.getElementById('flashcard'); | |
| if (flashcard) { | |
| flashcard.classList.toggle('flipped'); | |
| } | |
| } | |
| // Sauvegarder l'évaluation | |
| function saveEvaluation() { | |
| const slider = document.getElementById('evaluationSlider'); | |
| const score = parseInt(slider.value); | |
| // Mettre à jour les stats | |
| flashcardsStats.reviewedCards++; | |
| // Calculer la moyenne | |
| flashcardsStats.averageScore = ((flashcardsStats.averageScore * (flashcardsStats.reviewedCards - 1) + score) / flashcardsStats.reviewedCards).toFixed(1); | |
| // Passer à la carte suivante | |
| setTimeout(() => { | |
| nextCard(); | |
| flipCard(); // Retourner à la face avant | |
| }, 500); | |
| // Mettre à jour le dashboard | |
| updateDashboardEM(); | |
| showNotification('Évaluation enregistrée !', 'success'); | |
| } | |
| // Carte précédente | |
| function prevCard() { | |
| if (currentCardIndex > 0) { | |
| currentCardIndex--; | |
| displayCurrentCard(); | |
| } | |
| } | |
| // Carte suivante | |
| function nextCard() { | |
| if (currentCardIndex < flashcards.length - 1) { | |
| currentCardIndex++; | |
| displayCurrentCard(); | |
| } else { | |
| // Revenir au début | |
| currentCardIndex = 0; | |
| shuffleArray(flashcards); | |
| displayCurrentCard(); | |
| showNotification('Retour au début des cartes !', 'info'); | |
| } | |
| } | |
| // Mettre à jour les statistiques des flashcards | |
| function updateFlashcardsStats() { | |
| const statsContainer = document.getElementById('flashcardsStats'); | |
| if (statsContainer) { | |
| statsContainer.innerHTML = ` | |
| <div class="stat-card"> | |
| <div class="stat-value">${flashcardsStats.totalCards}</div> | |
| <div class="stat-label">Cartes disponibles</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">${flashcardsStats.reviewedCards}</div> | |
| <div class="stat-label">Cartes consultées</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">${flashcardsStats.averageScore}/5</div> | |
| <div class="stat-label">Score moyen</div> | |
| </div> | |
| <div class="stat-card"> | |
| <div class="stat-value">${currentCategory === 'all' ? 'Toutes' : currentCategory}</div> | |
| <div class="stat-label">Catégorie active</div> | |
| </div> | |
| `; | |
| } | |
| } | |
| // Mettre à jour le DashboardEM | |
| function updateDashboardEM() { | |
| const dashboardContainer = document.querySelector('.dashboardEM-grid'); | |
| if (dashboardContainer) { | |
| dashboardContainer.innerHTML = ` | |
| <div class="dashboardEM-card"> | |
| <div class="dashboardEM-header"> | |
| <div class="dashboardEM-icon" style="background: linear-gradient(135deg, #3b82f6, #1d4ed8);"> | |
| <i class="fas fa-brain"></i> | |
| </div> | |
| <div> | |
| <h4>Persévérance</h4> | |
| <div style="font-size: 0.9rem; color: var(--gray-color);">Capacité à maintenir l'effort</div> | |
| </div> | |
| </div> | |
| <div class="dashboardEM-metric"> | |
| <div class="dashboardEM-value">${flashcardsStats.averageScore}/5</div> | |
| <div class="dashboardEM-change">+${(flashcardsStats.averageScore * 20).toFixed(0)}%</div> | |
| </div> | |
| <div class="dashboardEM-trend"> | |
| <i class="fas fa-chart-line" style="color: ${flashcardsStats.averageScore > 2 ? '#10b981' : '#ef4444'}"></i> | |
| <span>${flashcardsStats.averageScore > 2 ? 'En progression' : 'À améliorer'}</span> | |
| </div> | |
| </div> | |
| <div class="dashboardEM-card"> | |
| <div class="dashboardEM-header"> | |
| <div class="dashboardEM-icon" style="background: linear-gradient(135deg, #10b981, #059669);"> | |
| <i class="fas fa-bolt"></i> | |
| </div> | |
| <div> | |
| <h4>Engagement</h4> | |
| <div style="font-size: 0.9rem; color: var(--gray-color);">Activité métacognitive</div> | |
| </div> | |
| </div> | |
| <div class="dashboardEM-metric"> | |
| <div class="dashboardEM-value">${flashcardsStats.reviewedCards}</div> | |
| <div class="dashboardEM-change">+${(flashcardsStats.reviewedCards * 20).toFixed(0)}%</div> | |
| </div> | |
| <div class="dashboardEM-trend"> | |
| <i class="fas fa-chart-line" style="color: ${flashcardsStats.reviewedCards > 0 ? '#10b981' : '#ef4444'}"></i> | |
| <span>${flashcardsStats.reviewedCards > 0 ? 'Actif' : 'À démarrer'}</span> | |
| </div> | |
| </div> | |
| `; | |
| } | |
| } | |
| // Réinitialiser les flashcards | |
| function resetFlashcards() { | |
| if (confirm('Voulez-vous vraiment réinitialiser toutes les flashcards ?')) { | |
| flashcardsStats.reviewedCards = 0; | |
| flashcardsStats.averageScore = 0; | |
| currentCardIndex = 0; | |
| showCardByCategory(currentCategory); | |
| showNotification('Flashcards réinitialisées avec succès !', 'success'); | |
| } | |
| } | |
| // ============================================ | |
| // JOURNAL | |
| // ============================================ | |
| // Définir l'auto-évaluation | |
| function setEvaluation(score) { | |
| document.querySelectorAll('.quality-indicator .quality-dot').forEach((dot, index) => { | |
| dot.classList.toggle('active', index === score - 1); | |
| }); | |
| } | |
| // Sauvegarder une entrée de journal | |
| function saveJournal() { | |
| const entry = { | |
| todo: document.getElementById('todo').value, | |
| doing: document.getElementById('doing').value, | |
| done: document.getElementById('done').value, | |
| metacognition: document.getElementById('metacognition').value, | |
| timestamp: new Date().toISOString() | |
| }; | |
| journalEntries.push(entry); | |
| // Réinitialiser le formulaire | |
| document.getElementById('todo').value = ''; | |
| document.getElementById('doing').value = ''; | |
| document.getElementById('done').value = ''; | |
| document.getElementById('metacognition').value = ''; | |
| setEvaluation(3); | |
| // Sauvegarder | |
| localStorage.setItem('journalEntries', JSON.stringify(journalEntries)); | |
| showNotification('Journal sauvegardé avec succès !', 'success'); | |
| } | |
| // Charger les entrées de journal | |
| function loadJournalEntries() { | |
| const container = document.getElementById('journalEntries'); | |
| const history = document.getElementById('journalHistory'); | |
| if (journalEntries.length === 0) { | |
| container.innerHTML = '<p>Aucune entrée de journal trouvée.</p>'; | |
| } else { | |
| container.innerHTML = ''; | |
| journalEntries.slice(-5).reverse().forEach(entry => { | |
| const div = document.createElement('div'); | |
| div.className = 'session-card'; | |
| div.innerHTML = ` | |
| <div class="session-header"> | |
| <div class="session-date"> | |
| ${new Date(entry.timestamp).toLocaleDateString('fr-FR')} | |
| </div> | |
| </div> | |
| ${entry.done ? `<div style="margin-top: 10px;"><strong>Accompli:</strong> ${entry.done.substring(0, 100)}...</div>` : ''} | |
| `; | |
| container.appendChild(div); | |
| }); | |
| } | |
| history.style.display = 'block'; | |
| } | |
| // ============================================ | |
| // NOTIFICATIONS | |
| // ============================================ | |
| // Obtenir un rappel intelligent | |
| function getIntelligentReminder() { | |
| const notifications = [ | |
| { | |
| type: 'motivation', | |
| icon: '🌱', | |
| message: "Rappel: Prenez 5 minutes pour planifier votre session d'étude d'aujourd'hui !" | |
| }, | |
| { | |
| type: 'rappel_court', | |
| icon: '⏰', | |
| message: "Il est temps de réviser vos flashcards ! Une courte session maintenant renforcera votre mémoire." | |
| }, | |
| { | |
| type: 'encouragement', | |
| icon: '💪', | |
| message: "Super travail jusqu'à présent ! Continuez à progresser, chaque petite session compte." | |
| } | |
| ]; | |
| const notification = notifications[Math.floor(Math.random() * notifications.length)]; | |
| const container = document.getElementById('notificationContainer'); | |
| const card = document.createElement('div'); | |
| card.className = 'notification-card'; | |
| card.innerHTML = ` | |
| <div style="display: flex; align-items: center; gap: 15px; margin-bottom: 10px;"> | |
| <div style="font-size: 2rem;">${notification.icon}</div> | |
| <div> | |
| <div style="font-weight: bold; color: #1e293b;">${notification.type.charAt(0).toUpperCase() + notification.type.slice(1).replace('_', ' ')}</div> | |
| <div style="font-size: 0.9rem; color: #64748b;"> | |
| Efficacité: ${(Math.random() * 20 + 75).toFixed(1)}% | |
| </div> | |
| </div> | |
| </div> | |
| <p style="font-size: 1.1rem; line-height: 1.5;">${notification.message}</p> | |
| <div style="margin-top: 10px; font-size: 0.8rem; color: #64748b; text-align: right;"> | |
| ${new Date().toLocaleTimeString('fr-FR')} | |
| </div> | |
| `; | |
| container.insertBefore(card, container.firstChild); | |
| // Limiter à 5 notifications | |
| while (container.children.length > 5) { | |
| container.removeChild(container.lastChild); | |
| } | |
| } | |
| // Créer le graphique des notifications | |
| function createNotificationChart() { | |
| const ctx = document.getElementById('notificationChart').getContext('2d'); | |
| window.notificationChart = new Chart(ctx, { | |
| type: 'bar', | |
| data: { | |
| labels: ['Motivation', 'Rappels', 'Encouragement'], | |
| datasets: [{ | |
| label: 'Efficacité (%)', | |
| data: [85, 72, 91], | |
| backgroundColor: [ | |
| 'rgba(59, 130, 246, 0.7)', | |
| 'rgba(16, 185, 129, 0.7)', | |
| 'rgba(245, 158, 11, 0.7)' | |
| ], | |
| borderColor: [ | |
| 'rgb(59, 130, 246)', | |
| 'rgb(16, 185, 129)', | |
| 'rgb(245, 158, 11)' | |
| ], | |
| borderWidth: 2 | |
| }] | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: false, | |
| scales: { | |
| y: { | |
| beginAtZero: true, | |
| max: 100, | |
| title: { | |
| display: true, | |
| text: 'Efficacité (%)' | |
| } | |
| } | |
| }, | |
| plugins: { | |
| title: { | |
| display: true, | |
| text: 'Performance des Types de Notifications', | |
| font: { size: 16 } | |
| } | |
| } | |
| } | |
| }); | |
| } | |
| // ============================================ | |
| // STATISTIQUES | |
| // ============================================ | |
| // Actualiser les statistiques | |
| function refreshStats() { | |
| showNotification('Statistiques actualisées', 'success'); | |
| } | |
| // Générer la heatmap | |
| function generateHeatmap() { | |
| const container = document.getElementById('heatmapContent'); | |
| // Générer des données de démonstration | |
| const heatmapData = generateDemoHeatmapData(currentHeatmapPeriod); | |
| // Créer la structure de la heatmap | |
| let html = '<div class="heatmap-grid">'; | |
| // Ajouter les étiquettes des jours | |
| const days = ['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim']; | |
| html += '<div class="heatmap-day-label"></div>'; | |
| days.forEach(day => { | |
| html += `<div class="heatmap-day-label">${day}</div>`; | |
| }); | |
| // Ajouter les cellules de la heatmap | |
| heatmapData.forEach((week, weekIndex) => { | |
| html += `<div class="heatmap-week-label">S${weekIndex + 1}</div>`; | |
| days.forEach((day, dayIndex) => { | |
| const activity = week[dayIndex]; | |
| if (activity !== null) { | |
| const intensity = getIntensityLevel(activity); | |
| const tooltip = `Jour: ${day}, Semaine ${weekIndex + 1}\nActivité: ${activity} minutes`; | |
| html += ` | |
| <div class="heatmap-cell heatmap-intensity-${intensity}" | |
| title="${tooltip}"> | |
| ${activity} | |
| </div> | |
| `; | |
| } else { | |
| html += '<div class="heatmap-cell" style="visibility: hidden;"></div>'; | |
| } | |
| }); | |
| }); | |
| html += '</div>'; | |
| if (container) { | |
| container.innerHTML = html; | |
| } | |
| } | |
| // Générer des données de démonstration pour la heatmap | |
| function generateDemoHeatmapData(period) { | |
| const data = []; | |
| let weeks = 4; // Par défaut pour le mois | |
| if (period === 'quarter') weeks = 13; | |
| if (period === 'year') weeks = 52; | |
| // Pattern d'activité typique | |
| for (let week = 0; week < weeks; week++) { | |
| const weekData = []; | |
| for (let day = 0; day < 7; day++) { | |
| // Générer une activité aléatoire avec un pattern spécifique | |
| let activity = 0; | |
| // Plus d'activité jeudi (jour 3) et vendredi (jour 4) | |
| if (day === 3 || day === 4) { | |
| activity = Math.floor(Math.random() * 45) + 30; | |
| } else if (day === 0 || day === 6) { | |
| activity = Math.floor(Math.random() * 30) + 15; | |
| } else { | |
| activity = Math.floor(Math.random() * 30); | |
| } | |
| // Ajouter une variabilité hebdomadaire | |
| if (week % 4 === 0) { | |
| activity = Math.min(activity * 1.3, 90); | |
| } else if (week % 4 === 2) { | |
| activity = Math.max(activity * 0.7, 10); | |
| } | |
| activity = Math.round(activity); | |
| weekData.push(activity); | |
| } | |
| data.push(weekData); | |
| } | |
| return data; | |
| } | |
| // Obtenir le niveau d'intensité | |
| function getIntensityLevel(activity) { | |
| if (activity === 0) return 0; | |
| if (activity <= 15) return 1; | |
| if (activity <= 30) return 2; | |
| if (activity <= 45) return 3; | |
| return 4; | |
| } | |
| // Changer la période de la heatmap | |
| function changeHeatmapPeriod(period) { | |
| currentHeatmapPeriod = period; | |
| // Mettre à jour les boutons | |
| document.querySelectorAll('.heatmap-period').forEach(btn => { | |
| btn.classList.remove('active'); | |
| if (btn.textContent.toLowerCase().includes(period)) { | |
| btn.classList.add('active'); | |
| } | |
| }); | |
| // Regénérer la heatmap | |
| generateHeatmap(); | |
| } | |
| // ============================================ | |
| // FONCTIONS UTILITAIRES | |
| // ============================================ | |
| // Afficher une notification | |
| function showNotification(message, type = 'info') { | |
| const colors = { | |
| success: '#10b981', | |
| error: '#ef4444', | |
| warning: '#f59e0b', | |
| info: '#3b82f6' | |
| }; | |
| // Créer une notification temporaire | |
| const notification = document.createElement('div'); | |
| notification.style.cssText = ` | |
| position: fixed; | |
| top: 20px; | |
| right: 20px; | |
| background: white; | |
| color: ${colors[type]}; | |
| padding: 1rem 1.5rem; | |
| border-radius: 10px; | |
| box-shadow: 0 5px 20px rgba(0,0,0,0.1); | |
| border-left: 4px solid ${colors[type]}; | |
| z-index: 1000; | |
| animation: fadeIn 0.3s ease; | |
| `; | |
| notification.innerHTML = ` | |
| <div style="display: flex; align-items: center; gap: 10px;"> | |
| <i class="fas fa-${type === 'success' ? 'check-circle' : type === 'error' ? 'exclamation-circle' : type === 'warning' ? 'exclamation-triangle' : 'info-circle'}"></i> | |
| <div>${message}</div> | |
| </div> | |
| `; | |
| document.body.appendChild(notification); | |
| // Supprimer après 3 secondes | |
| setTimeout(() => { | |
| notification.style.opacity = '0'; | |
| setTimeout(() => notification.remove(), 300); | |
| }, 3000); | |
| } | |
| // Charger les données sauvegardées | |
| function loadSavedData() { | |
| try { | |
| // Charger le profil | |
| const savedProfile = localStorage.getItem('learnerProfile'); | |
| if (savedProfile) { | |
| learnerProfile = JSON.parse(savedProfile); | |
| updateProfileProgress(); | |
| updateProfileSummary(); | |
| } | |
| // Charger les entrées de journal | |
| const savedJournal = localStorage.getItem('journalEntries'); | |
| if (savedJournal) { | |
| journalEntries = JSON.parse(savedJournal); | |
| } | |
| } catch (error) { | |
| console.error('Erreur lors du chargement des données:', error); | |
| } | |
| } | |
| // Sauvegarder toutes les données | |
| function saveAllData() { | |
| try { | |
| localStorage.setItem('learnerProfile', JSON.stringify(learnerProfile)); | |
| localStorage.setItem('journalEntries', JSON.stringify(journalEntries)); | |
| } catch (error) { | |
| console.error('Erreur lors de la sauvegarde:', error); | |
| } | |
| } | |
| // Sauvegarder automatiquement toutes les 30 secondes | |
| setInterval(saveAllData, 30000); | |
| // Sauvegarder aussi quand l'utilisateur quitte la page | |
| window.addEventListener('beforeunload', saveAllData); | |
| </script> | |
| </body> | |
| </html> |