| <!DOCTYPE html>
|
| <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>
|
|
|
|
|
| <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
|
|
| <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 {
|
| 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;
|
| }
|
|
|
|
|
| .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);
|
| }
|
|
|
|
|
| .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-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);
|
| }
|
|
|
|
|
| .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;
|
| }
|
|
|
|
|
| .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;
|
| }
|
|
|
|
|
| .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;
|
| }
|
|
|
| .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);
|
| }
|
|
|
|
|
| .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);
|
| }
|
|
|
|
|
| .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;
|
| }
|
|
|
|
|
| .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;
|
| }
|
|
|
|
|
| .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;
|
| }
|
|
|
|
|
| .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-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 {
|
| 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);
|
| }
|
|
|
|
|
| .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%;
|
| }
|
|
|
|
|
| .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;
|
| }
|
|
|
|
|
| .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: slideIn 0.5s ease;
|
| }
|
|
|
|
|
| .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;
|
| }
|
|
|
|
|
| .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;
|
| }
|
|
|
|
|
|
|
|
|
|
|
| .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);
|
| }
|
|
|
|
|
| @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 class="header">
|
| <h1><i class="fas fa-graduation-cap"></i> Compagnon Pédagogique</h1>
|
| <p>PerseverAId (AI + Aid + Perseverance) –
|
| Apprendre à manager l'effort et maintenir la persistance </p>
|
| <div class="badge">PerseverAId (AI + Aid + Perseverance)</div>
|
| </header>
|
|
|
|
|
| <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 SM-2
|
| </button>
|
|
|
| <button class="nav-tab" onclick="showTab('journal')">
|
| <i class="fas fa-book"></i> Journal SRL
|
| </button>
|
| <button class="nav-tab" onclick="showTab('flashcards')">
|
| <i class="fas fa-layer-group"></i> Métacognition
|
| </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>
|
|
|
|
|
| <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>
|
|
|
|
|
| <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>
|
|
|
|
|
| <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<br><span class="scale-label">Pas du tout</span>
|
| </div>
|
| <div class="scale-option" onclick="selectScale('extraversion', 2)">
|
| 2<br><span class="scale-label">Un peu</span>
|
| </div>
|
| <div class="scale-option selected" onclick="selectScale('extraversion', 3)">
|
| 3<br><span class="scale-label">Modérément</span>
|
| </div>
|
| <div class="scale-option" onclick="selectScale('extraversion', 4)">
|
| 4<br><span class="scale-label">Beaucoup</span>
|
| </div>
|
| <div class="scale-option" onclick="selectScale('extraversion', 5)">
|
| 5<br><span class="scale-label">Extrêmement</span>
|
| </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>
|
|
|
|
|
| <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 (Théorie de l'Autodétermination)</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="question-item">
|
| <div class="question-text">J'étudie parce que c'est important pour mon futur, pour atteindre mes objectifs personnels</div>
|
| <div class="scale-options">
|
| <div class="scale-option" onclick="selectMotivation('identified', 1)">1</div>
|
| <div class="scale-option" onclick="selectMotivation('identified', 2)">2</div>
|
| <div class="scale-option selected" onclick="selectMotivation('identified', 3)">3</div>
|
| <div class="scale-option" onclick="selectMotivation('identified', 4)">4</div>
|
| <div class="scale-option" onclick="selectMotivation('identified', 5)">5</div>
|
| </div>
|
| </div>
|
|
|
| <div class="question-item">
|
| <div class="question-text">J'étudie pour éviter les punitions ou les conséquences négatives</div>
|
| <div class="scale-options">
|
| <div class="scale-option selected" onclick="selectMotivation('external', 1)">1</div>
|
| <div class="scale-option" onclick="selectMotivation('external', 2)">2</div>
|
| <div class="scale-option" onclick="selectMotivation('external', 3)">3</div>
|
| <div class="scale-option" onclick="selectMotivation('external', 4)">4</div>
|
| <div class="scale-option" onclick="selectMotivation('external', 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>
|
|
|
|
|
| <div class="questionnaire-section" id="habits-section">
|
| <div class="questionnaire-header">
|
| <div class="questionnaire-icon" style="background: linear-gradient(135deg, #8b5cf6, #7c3aed);">
|
| <i class="fas fa-clock"></i>
|
| </div>
|
| <div>
|
| <div class="questionnaire-title">Habitudes et Préférences d'Étude</div>
|
| <div class="questionnaire-description">Décrivez vos habitudes d'apprentissage actuelles</div>
|
| </div>
|
| </div>
|
|
|
| <div class="question-item">
|
| <div class="question-text">En moyenne, combien d'heures par jour consacrez-vous à l'étude ?</div>
|
| <div class="scale-options">
|
| <div class="scale-option" onclick="selectHabit('study_hours', 1)">< 1h</div>
|
| <div class="scale-option" onclick="selectHabit('study_hours', 2)">1-2h</div>
|
| <div class="scale-option" onclick="selectHabit('study_hours', 3)">2-3h</div>
|
| <div class="scale-option" onclick="selectHabit('study_hours', 4)">3-4h</div>
|
| <div class="scale-option" onclick="selectHabit('study_hours', 5)">> 4h</div>
|
| </div>
|
| </div>
|
|
|
| <div class="question-item">
|
| <div class="question-text">À quelle fréquence remettez-vous vos travaux en retard ?</div>
|
| <div class="scale-options">
|
| <div class="scale-option" onclick="selectHabit('late_submissions', 1)">Jamais</div>
|
| <div class="scale-option" onclick="selectHabit('late_submissions', 2)">Rarement</div>
|
| <div class="scale-option" onclick="selectHabit('late_submissions', 3)">Parfois</div>
|
| <div class="scale-option" onclick="selectHabit('late_submissions', 4)">Souvent</div>
|
| <div class="scale-option" onclick="selectHabit('late_submissions', 5)">Toujours</div>
|
| </div>
|
| </div>
|
|
|
| <div class="question-item">
|
| <div class="question-text">Quel est votre taux de complétion des vidéos/ressources ?</div>
|
| <div class="scale-options">
|
| <div class="scale-option" onclick="selectHabit('completion_rate', 1)">< 25%</div>
|
| <div class="scale-option" onclick="selectHabit('completion_rate', 2)">25-50%</div>
|
| <div class="scale-option" onclick="selectHabit('completion_rate', 3)">50-75%</div>
|
| <div class="scale-option" onclick="selectHabit('completion_rate', 4)">75-95%</div>
|
| <div class="scale-option" onclick="selectHabit('completion_rate', 5)">100%</div>
|
| </div>
|
| </div>
|
|
|
| <div class="question-item">
|
| <div class="question-text">Participez-vous aux forums de discussion ?</div>
|
| <div class="scale-options">
|
| <div class="scale-option" onclick="selectHabit('forum_participation', 1)">Jamais</div>
|
| <div class="scale-option" onclick="selectHabit('forum_participation', 2)">Rarement</div>
|
| <div class="scale-option" onclick="selectHabit('forum_participation', 3)">Parfois</div>
|
| <div class="scale-option" onclick="selectHabit('forum_participation', 4)">Souvent</div>
|
| <div class="scale-option" onclick="selectHabit('forum_participation', 5)">Toujours</div>
|
| </div>
|
| </div>
|
|
|
| <div class="section-completion section-incomplete" id="habits-completion">
|
| <i class="fas fa-exclamation-circle" style="color: #ef4444;"></i>
|
| <span>Section incomplète - Remplissez toutes les questions</span>
|
| </div>
|
| </div>
|
|
|
|
|
| <div class="questionnaire-section" id="wellbeing-section">
|
| <div class="questionnaire-header">
|
| <div class="questionnaire-icon" style="background: linear-gradient(135deg, #f59e0b, #d97706);">
|
| <i class="fas fa-heart"></i>
|
| </div>
|
| <div>
|
| <div class="questionnaire-title">Bien-être et Gestion du Stress</div>
|
| <div class="questionnaire-description">Évaluez votre état émotionnel et votre gestion du stress</div>
|
| </div>
|
| </div>
|
|
|
| <div class="question-item">
|
| <div class="question-text">Combien d'heures dormez-vous en moyenne par nuit ?</div>
|
| <div class="scale-options">
|
| <div class="scale-option" onclick="selectWellbeing('sleep_hours', 1)">< 5h</div>
|
| <div class="scale-option" onclick="selectWellbeing('sleep_hours', 2)">5-6h</div>
|
| <div class="scale-option" onclick="selectWellbeing('sleep_hours', 3)">6-7h</div>
|
| <div class="scale-option" onclick="selectWellbeing('sleep_hours', 4)">7-8h</div>
|
| <div class="scale-option" onclick="selectWellbeing('sleep_hours', 5)">> 8h</div>
|
| </div>
|
| </div>
|
|
|
| <div class="question-item">
|
| <div class="question-text">À quelle fréquence ressentez-vous du stress lié aux études ?</div>
|
| <div class="scale-options">
|
| <div class="scale-option" onclick="selectWellbeing('study_stress', 1)">Jamais</div>
|
| <div class="scale-option" onclick="selectWellbeing('study_stress', 2)">Rarement</div>
|
| <div class="scale-option" onclick="selectWellbeing('study_stress', 3)">Parfois</div>
|
| <div class="scale-option" onclick="selectWellbeing('study_stress', 4)">Souvent</div>
|
| <div class="scale-option" onclick="selectWellbeing('study_stress', 5)">Toujours</div>
|
| </div>
|
| </div>
|
|
|
| <div class="question-item">
|
| <div class="question-text">Pratiquez-vous des activités de relaxation ou de méditation ?</div>
|
| <div class="scale-options">
|
| <div class="scale-option" onclick="selectWellbeing('relaxation', 1)">Jamais</div>
|
| <div class="scale-option" onclick="selectWellbeing('relaxation', 2)">Rarement</div>
|
| <div class="scale-option" onclick="selectWellbeing('relaxation', 3)">Parfois</div>
|
| <div class="scale-option" onclick="selectWellbeing('relaxation', 4)">Souvent</div>
|
| <div class="scale-option" onclick="selectWellbeing('relaxation', 5)">Toujours</div>
|
| </div>
|
| </div>
|
|
|
| <div class="question-item">
|
| <div class="question-text">Avez-vous déjà ressenti des symptômes de burnout (épuisement, cynisme) ?</div>
|
| <div class="scale-options">
|
| <div class="scale-option" onclick="selectWellbeing('burnout_risk', 1)">Jamais</div>
|
| <div class="scale-option" onclick="selectWellbeing('burnout_risk', 2)">Rarement</div>
|
| <div class="scale-option" onclick="selectWellbeing('burnout_risk', 3)">Parfois</div>
|
| <div class="scale-option" onclick="selectWellbeing('burnout_risk', 4)">Souvent</div>
|
| <div class="scale-option" onclick="selectWellbeing('burnout_risk', 5)">Toujours</div>
|
| </div>
|
| </div>
|
|
|
| <div class="section-completion section-incomplete" id="wellbeing-completion">
|
| <i class="fas fa-exclamation-circle" style="color: #ef4444;"></i>
|
| <span>Section incomplète - Remplissez toutes les questions</span>
|
| </div>
|
| </div>
|
|
|
|
|
| <div class="questionnaire-section" id="support-section">
|
| <div class="questionnaire-header">
|
| <div class="questionnaire-icon" style="background: linear-gradient(135deg, #ec4899, #db2777);">
|
| <i class="fas fa-users"></i>
|
| </div>
|
| <div>
|
| <div class="questionnaire-title">Soutien et Environnement d'Apprentissage</div>
|
| <div class="questionnaire-description">Décrivez votre environnement d'apprentissage et votre réseau de soutien</div>
|
| </div>
|
| </div>
|
|
|
| <div class="question-item">
|
| <div class="question-text">Comment évaluez-vous le soutien de vos parents/famille ?</div>
|
| <div class="scale-options">
|
| <div class="scale-option" onclick="selectSupport('family_support', 1)">Très faible</div>
|
| <div class="scale-option" onclick="selectSupport('family_support', 2)">Faible</div>
|
| <div class="scale-option" onclick="selectSupport('family_support', 3)">Moyen</div>
|
| <div class="scale-option" onclick="selectSupport('family_support', 4)">Élevé</div>
|
| <div class="scale-option" onclick="selectSupport('family_support', 5)">Très élevé</div>
|
| </div>
|
| </div>
|
|
|
| <div class="question-item">
|
| <div class="question-text">Vos parents ont-ils des attentes élevées concernant vos résultats ?</div>
|
| <div class="scale-options">
|
| <div class="scale-option" onclick="selectSupport('parental_expectations', 1)">Très basses</div>
|
| <div class="scale-option" onclick="selectSupport('parental_expectations', 2)">Basses</div>
|
| <div class="scale-option" onclick="selectSupport('parental_expectations', 3)">Moyennes</div>
|
| <div class="scale-option" onclick="selectSupport('parental_expectations', 4)">Élevées</div>
|
| <div class="scale-option" onclick="selectSupport('parental_expectations', 5)">Très élevées</div>
|
| </div>
|
| </div>
|
|
|
| <div class="question-item">
|
| <div class="question-text">Avez-vous un espace calme et dédié pour étudier ?</div>
|
| <div class="scale-options">
|
| <div class="scale-option" onclick="selectSupport('study_environment', 1)">Non</div>
|
| <div class="scale-option" onclick="selectSupport('study_environment', 2)">Rarement</div>
|
| <div class="scale-option" onclick="selectSupport('study_environment', 3)">Parfois</div>
|
| <div class="scale-option" onclick="selectSupport('study_environment', 4)">Souvent</div>
|
| <div class="scale-option" onclick="selectSupport('study_environment', 5)">Toujours</div>
|
| </div>
|
| </div>
|
|
|
| <div class="question-item">
|
| <div class="question-text">Collaborez-vous avec d'autres étudiants pour étudier ?</div>
|
| <div class="scale-options">
|
| <div class="scale-option" onclick="selectSupport('peer_collaboration', 1)">Jamais</div>
|
| <div class="scale-option" onclick="selectSupport('peer_collaboration', 2)">Rarement</div>
|
| <div class="scale-option" onclick="selectSupport('peer_collaboration', 3)">Parfois</div>
|
| <div class="scale-option" onclick="selectSupport('peer_collaboration', 4)">Souvent</div>
|
| <div class="scale-option" onclick="selectSupport('peer_collaboration', 5)">Toujours</div>
|
| </div>
|
| </div>
|
|
|
| <div class="section-completion section-incomplete" id="support-completion">
|
| <i class="fas fa-exclamation-circle" style="color: #ef4444;"></i>
|
| <span>Section incomplète - Remplissez toutes les questions</span>
|
| </div>
|
| </div>
|
|
|
|
|
| <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 class="trait-item">
|
| <span class="trait-name">Agréabilité</span>
|
| <span class="trait-value" id="agreeableness-value">3.0</span>
|
| </div>
|
| <div class="trait-item">
|
| <span class="trait-name">Névrosisme</span>
|
| <span class="trait-value" id="neuroticism-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 class="trait-item">
|
| <span class="trait-name">Identifiée</span>
|
| <span class="trait-value" id="identified-value">3.0</span>
|
| </div>
|
| <div class="trait-item">
|
| <span class="trait-name">Externe</span>
|
| <span class="trait-value" id="external-value">1.0</span>
|
| </div>
|
| </div>
|
| <div class="motivation-chart">
|
| <canvas id="motivationChart"></canvas>
|
| </div>
|
| </div>
|
| </div>
|
|
|
|
|
| <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 class="recommendation-item">
|
| <div class="recommendation-icon">🎯</div>
|
| <div>
|
| <strong>Gestion de la pression: </strong> Avec une motivation introjectée modérée, pratiquez des techniques de gestion du stress.
|
| </div>
|
| </div>
|
|
|
| <div class="recommendation-item">
|
| <div class="recommendation-icon">⏰</div>
|
| <div>
|
| <strong>Personnalisation: </strong> Complétez toutes les sections pour des recommandations plus précises.
|
| </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>
|
|
|
|
|
| <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="conjugaison">Conjugaison française</option>
|
| <option value="grammaire">Grammaire française</option>
|
| <option value="vocabulaire">Vocabulaire français</option>
|
| <option value="expression_ecrite">Expression écrite</option>
|
| <option value="comprehension_orale">Compréhension orale</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>
|
|
|
|
|
| <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 class="option-item" onclick="selectEnergyPattern('flexible')">
|
| <span class="option-icon"><i class="fas fa-sync-alt"></i></span>
|
| <div class="option-title">Flexible</div>
|
| <div class="option-description">Adaptable</div>
|
| </div>
|
| </div>
|
| </div>
|
| </div>
|
|
|
|
|
| <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 class="time-slot" onclick="toggleTimeSlot('late_afternoon')">16:00-18:00</div>
|
| <div class="time-slot" onclick="toggleTimeSlot('evening')">19:00-21:00</div>
|
| </div>
|
| </div>
|
|
|
|
|
| <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 SM-2 Personnalisé
|
| </button>
|
| </div>
|
| </section>
|
|
|
|
|
| <section id="planner" class="tab-content">
|
| <div class="card">
|
| <div class="card-header">
|
| <h3><i class="fas fa-calendar-alt"></i> Planner SM-2 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>
|
|
|
|
|
| <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>
|
|
|
|
|
| <div id="flashcardsStats" class="stats-grid">
|
|
|
| </div>
|
|
|
|
|
| <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 class="category-filter" onclick="showCardByCategory('strategies')">
|
| <i class="fas fa-tools"></i> Stratégies d'adaptation
|
| </div>
|
| <div class="category-filter" onclick="showCardByCategory('motivation')">
|
| <i class="fas fa-fire"></i> Motivation & Sens
|
| </div>
|
| <div class="category-filter" onclick="showCardByCategory('evaluation')">
|
| <i class="fas fa-star"></i> Auto-évaluation
|
| </div>
|
| </div>
|
|
|
|
|
| <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>
|
|
|
|
|
| <div id="currentCard" class="flashcard-container">
|
|
|
| </div>
|
|
|
|
|
| <div class="dashboardEM-container">
|
| <h4><i class="fas fa-chart-bar"></i> DashboardEM - Métriques Métacognitives</h4>
|
| <div id="dashboardEM" class="dashboardEM-grid">
|
|
|
| </div>
|
| </div>
|
| </div>
|
| </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>
|
|
|
|
|
| <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>
|
|
|
|
|
| <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>
|
|
|
|
|
| <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">
|
|
|
| </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 class="legend-item">
|
| <div class="legend-color heatmap-intensity-3"></div>
|
| <span>45 min</span>
|
| </div>
|
| <div class="legend-item">
|
| <div class="legend-color heatmap-intensity-4"></div>
|
| <span>60+ min</span>
|
| </div>
|
| </div>
|
| </div>
|
|
|
|
|
| <div class="time-management-stats">
|
| <div class="time-stat-card">
|
| <div class="time-stat-header">
|
| <div class="time-stat-icon" style="background: linear-gradient(135deg, #10b981, #059669);">
|
| <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>
|
|
|
|
|
|
|
|
|
|
|
| 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
|
| }
|
| };
|
|
|
|
|
| let selectedTimeSlots = ['morning'];
|
| let currentQuality = 2;
|
| let productivityMethod = 'pomodoro';
|
| let energyPattern = 'morning';
|
|
|
|
|
| let currentHeatmapPeriod = 'month';
|
|
|
|
|
| let journalEntries = [];
|
|
|
|
|
| let flashcards = [];
|
| let currentCardIndex = 0;
|
| let currentCategory = 'all';
|
| let flashcardsData = [];
|
| let flashcardsStats = {
|
| totalCards: 0,
|
| reviewedCards: 0,
|
| averageScore: 0,
|
| favoriteCategory: ''
|
| };
|
|
|
|
|
|
|
|
|
|
|
| document.addEventListener('DOMContentLoaded', function() {
|
|
|
| updateProfileProgress();
|
| updateProfileSummary();
|
| createMotivationChart();
|
|
|
|
|
| generateHeatmap();
|
|
|
|
|
| createNotificationChart();
|
|
|
|
|
| initializeFlashcards();
|
|
|
|
|
| loadSavedData();
|
| });
|
|
|
|
|
|
|
|
|
|
|
| function showTab(tabId) {
|
|
|
| document.querySelectorAll('.tab-content').forEach(section => {
|
| section.classList.remove('active');
|
| });
|
|
|
|
|
| document.querySelectorAll('.nav-tab').forEach(tab => {
|
| tab.classList.remove('active');
|
| });
|
|
|
|
|
| document.getElementById(tabId).classList.add('active');
|
|
|
|
|
| const tabNames = {
|
| 'profile': 'Profil Apprenant',
|
| 'objectif': 'Objectif',
|
| 'planner': 'Planner',
|
| 'flashcards': 'Flashcards',
|
| 'journal': 'Journal',
|
| 'notifications': 'Notifications',
|
| 'stats': 'Statistiques'
|
| };
|
|
|
| document.querySelectorAll('.nav-tab').forEach(tab => {
|
| if (tab.textContent.includes(tabNames[tabId])) {
|
| tab.classList.add('active');
|
| }
|
| });
|
|
|
|
|
| if (tabId === 'stats') {
|
| refreshStats();
|
| generateHeatmap();
|
| } else if (tabId === 'flashcards') {
|
| updateFlashcardsStats();
|
| updateDashboardEM();
|
| }
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
| function checkSectionCompletion(sectionId) {
|
| const section = document.getElementById(sectionId);
|
| const scaleOptions = section.querySelectorAll('.scale-option.selected');
|
|
|
|
|
| const expectedCount = {
|
| 'big5-section': 5,
|
| 'motivation-section': 4,
|
| 'habits-section': 4,
|
| 'wellbeing-section': 4,
|
| 'support-section': 4
|
| };
|
|
|
| return scaleOptions.length >= expectedCount[sectionId];
|
| }
|
|
|
|
|
| function updateSectionCompletion(sectionId) {
|
| const isComplete = checkSectionCompletion(sectionId);
|
| const sectionKey = sectionId.replace('-section', '');
|
| const completionElement = document.getElementById(`${sectionKey}-completion`);
|
|
|
|
|
| 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'})`;
|
| } else if (sectionKey === 'habits') {
|
| const hours = learnerProfile.habits.study_hours || 2;
|
| const hourText = ['< 1h', '1-2h', '2-3h', '3-4h', '> 4h'][hours - 1] || 'modérée';
|
| message += ` - <strong>${hourText} d'étude par jour</strong>`;
|
| } else if (sectionKey === 'wellbeing') {
|
| const sleep = learnerProfile.wellbeing.sleep_hours || 3;
|
| const sleepText = ['< 5h', '5-6h', '6-7h', '7-8h', '> 8h'][sleep - 1] || 'modérée';
|
| message += ` - <strong>${sleepText} de sommeil</strong>`;
|
| } else if (sectionKey === 'support') {
|
| const expectations = learnerProfile.support.parental_expectations || 3;
|
| const expectationText = ['Très basses', 'Basses', 'Moyennes', 'Élevées', 'Très élevées'][expectations - 1] || 'modérées';
|
| message += ` - <strong>Attentes parentales: ${expectationText}</strong>`;
|
| }
|
|
|
| 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>`;
|
| }
|
|
|
|
|
| updateProfileProgress();
|
| }
|
|
|
|
|
| function selectScale(trait, value) {
|
| learnerProfile.bigFive[trait] = value;
|
| updateScaleUI(trait, value);
|
| updateProfileSummary();
|
| updateSectionCompletion('big5-section');
|
| }
|
|
|
|
|
| function selectMotivation(type, value) {
|
| learnerProfile.motivation[type] = value;
|
| updateScaleUI(type, value);
|
| updateProfileSummary();
|
| updateSectionCompletion('motivation-section');
|
| }
|
|
|
|
|
| function selectHabit(habit, value) {
|
| learnerProfile.habits[habit] = value;
|
| updateSectionCompletion('habits-section');
|
| }
|
|
|
|
|
| function selectWellbeing(wellbeing, value) {
|
| learnerProfile.wellbeing[wellbeing] = value;
|
| updateSectionCompletion('wellbeing-section');
|
| }
|
|
|
|
|
| function selectSupport(support, value) {
|
| learnerProfile.support[support] = value;
|
| updateSectionCompletion('support-section');
|
| }
|
|
|
|
|
| function updateScaleUI(type, value) {
|
|
|
| const scaleOptions = document.querySelectorAll(`[onclick*="${type}"]`);
|
|
|
| scaleOptions.forEach(option => {
|
| option.classList.remove('selected');
|
|
|
|
|
| const match = option.getAttribute('onclick').match(/(\d+)/);
|
| if (match && parseInt(match[1]) === value) {
|
| option.classList.add('selected');
|
| }
|
| });
|
| }
|
|
|
|
|
| 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);
|
|
|
|
|
| document.getElementById('profileCompletion').textContent = `${percentage}%`;
|
| document.getElementById('profileProgressBar').style.width = `${percentage}%`;
|
|
|
|
|
| document.getElementById('completedSections').textContent = `${completedCount}/${totalSections}`;
|
|
|
|
|
| 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;
|
| }
|
|
|
|
|
| function updateProfileSummary() {
|
|
|
| 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);
|
|
|
|
|
| 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);
|
|
|
|
|
| updateMotivationChart();
|
| }
|
|
|
|
|
| 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
|
| }
|
| });
|
| }
|
|
|
|
|
| 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();
|
| }
|
| }
|
|
|
|
|
| function completeAllSections() {
|
|
|
| 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
|
| };
|
|
|
|
|
| Object.keys(defaultValues).forEach(key => {
|
| if (key in learnerProfile.habits) {
|
| learnerProfile.habits[key] = defaultValues[key];
|
| }
|
| if (key in learnerProfile.wellbeing) {
|
| learnerProfile.wellbeing[key] = defaultValues[key];
|
| }
|
| if (key in learnerProfile.support) {
|
| learnerProfile.support[key] = defaultValues[key];
|
| }
|
| });
|
|
|
|
|
| Object.keys(learnerProfile.completionStatus).forEach(key => {
|
| learnerProfile.completionStatus[key] = true;
|
| });
|
|
|
|
|
| updateProfileProgress();
|
| updateProfileSummary();
|
|
|
|
|
| updateSectionCompletion('habits-section');
|
| updateSectionCompletion('wellbeing-section');
|
| updateSectionCompletion('support-section');
|
|
|
| showNotification('Toutes les sections ont été complétées automatiquement !', 'success');
|
| }
|
|
|
|
|
| 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');
|
| }
|
| }
|
|
|
|
|
| function completeProfile() {
|
|
|
| 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;
|
| }
|
|
|
|
|
| saveProfile();
|
|
|
|
|
| generatePersonalizedRecommendations();
|
|
|
| showNotification('Profil finalisé avec succès ! Les recommandations ont été mises à jour.', 'success');
|
| }
|
|
|
|
|
| function generatePersonalizedRecommendations() {
|
| const recommendations = [];
|
|
|
|
|
| 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.`
|
| });
|
| }
|
|
|
|
|
| if (learnerProfile.motivation.introjected >= 4) {
|
| recommendations.push({
|
| icon: '🎯',
|
| text: `Motivation introjectée élevée (${learnerProfile.motivation.introjected}). Pratiquez des techniques de gestion du stress.`
|
| });
|
| }
|
|
|
|
|
| updateRecommendationsDisplay(recommendations);
|
| }
|
|
|
|
|
| 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;
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
| function selectProductivityMethod(method) {
|
| productivityMethod = method;
|
| document.querySelectorAll('.option-item').forEach(item => {
|
| item.classList.remove('selected');
|
| });
|
| event.target.closest('.option-item').classList.add('selected');
|
| }
|
|
|
|
|
| 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');
|
| }
|
|
|
|
|
| function toggleTimeSlot(slot) {
|
| const index = selectedTimeSlots.indexOf(slot);
|
| if (index === -1) {
|
| selectedTimeSlots.push(slot);
|
| } else {
|
| selectedTimeSlots.splice(index, 1);
|
| }
|
|
|
|
|
| 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);
|
| }
|
|
|
|
|
| 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];
|
| }
|
|
|
|
|
| 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;
|
| }
|
|
|
|
|
| const intervals = getSM2Intervals(currentQuality);
|
|
|
|
|
| const plan = createStudyPlan(competence, startDate, duration, intervals);
|
|
|
|
|
| displayPlanner(plan, intervals);
|
|
|
|
|
| showTab('planner');
|
|
|
| showNotification('Planner généré avec succès !', 'success');
|
| }
|
|
|
|
|
| function getSM2Intervals(quality) {
|
| const intervals = {
|
| 0: [1, 2, 4, 8, 16, 32],
|
| 1: [1, 3, 7, 14, 30, 60],
|
| 2: [2, 7, 16, 35, 70, 140],
|
| 3: [3, 10, 25, 60, 120, 240]
|
| };
|
| return intervals[quality] || intervals[2];
|
| }
|
|
|
|
|
| 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;
|
| }
|
|
|
|
|
| function displayPlanner(plan, intervals) {
|
| const container = document.getElementById('plannerContent');
|
| const statsContainer = document.getElementById('plannerStats');
|
|
|
|
|
| const totalDays = intervals.reduce((a, b) => a + b, 0);
|
|
|
|
|
| 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>
|
| `;
|
|
|
|
|
| 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);
|
| });
|
|
|
|
|
| createSM2Visualization(intervals, plan[0]?.competence || 'Compétence');
|
| }
|
|
|
|
|
| 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'
|
| }
|
| }
|
| }
|
| }
|
| });
|
| }
|
|
|
|
|
| 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');
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
| function initializeFlashcards() {
|
|
|
| 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 ?',
|
| action: 'Identifier précisément le type d\'obstacle rencontré',
|
| evaluationLabel: 'Clarté du diagnostic'
|
| }
|
| },
|
| {
|
| id: 2,
|
| category: 'awareness',
|
| categoryName: 'Prise de conscience',
|
| icon: '💭',
|
| color: '#3b82f6',
|
| front: {
|
| title: 'État Émotionnel',
|
| question: 'Comment je me sens en ce moment face à cette tâche ?'
|
| },
|
| back: {
|
| reflection: 'Mon état émotionnel influence-t-il ma capacité à apprendre ?',
|
| action: 'Nommer l\'émotion et accepter sa présence',
|
| evaluationLabel: 'Conscience émotionnelle'
|
| }
|
| },
|
| {
|
| id: 3,
|
| category: 'perseverance',
|
| categoryName: 'Persévérance',
|
| icon: '🏔️',
|
| color: '#10b981',
|
| front: {
|
| title: '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é ?',
|
| action: 'Se rappeler un succès passé pour renforcer la confiance',
|
| evaluationLabel: 'Résilience perçue'
|
| }
|
| },
|
| {
|
| id: 4,
|
| category: 'perseverance',
|
| categoryName: 'Persévérance',
|
| icon: '⏳',
|
| color: '#10b981',
|
| front: {
|
| title: 'Test de Persistance',
|
| question: 'Que se passerait-il si je continuais encore 10 minutes ?'
|
| },
|
| back: {
|
| reflection: 'Le pire scénario est-il vraiment si grave ?',
|
| action: 'Se donner un objectif minimal de 10 minutes supplémentaires',
|
| evaluationLabel: 'Volonté de persister'
|
| }
|
| },
|
| {
|
| id: 5,
|
| 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é ?',
|
| action: 'Adapter la tâche à son niveau d\'énergie actuel',
|
| evaluationLabel: 'Gestion énergétique'
|
| }
|
| },
|
| {
|
| id: 6,
|
| category: 'effort',
|
| categoryName: 'Gestion de l\'effort',
|
| icon: '🎯',
|
| color: '#f59e0b',
|
| front: {
|
| title: 'Effort Productif',
|
| question: 'Mon effort actuel est-il concentré et efficace ?'
|
| },
|
| back: {
|
| reflection: 'Est-ce que je travaille "dur" ou "intelligemment" ?',
|
| action: 'Identifier et éliminer une source de distraction',
|
| evaluationLabel: 'Efficacité de l\'effort'
|
| }
|
| },
|
| {
|
| id: 7,
|
| category: 'strategies',
|
| categoryName: 'Stratégies d\'adaptation',
|
| icon: '🔧',
|
| color: '#8b5cf6',
|
| front: {
|
| title: 'Découpage de Tâche',
|
| question: 'Cette tâche peut-elle être divisée en sous-tâches plus petites ?'
|
| },
|
| back: {
|
| reflection: 'Quelle est la plus petite action réalisable maintenant ?',
|
| action: 'Définir une micro-tâche de 5 minutes maximum',
|
| evaluationLabel: 'Capacité à découper'
|
| }
|
| },
|
| {
|
| id: 8,
|
| category: 'strategies',
|
| categoryName: 'Stratégies d\'adaptation',
|
| icon: '🔄',
|
| color: '#8b5cf6',
|
| front: {
|
| title: 'Changement de Modalité',
|
| question: 'Et si j\'essayais une approche différente ?'
|
| },
|
| back: {
|
| reflection: 'Quelle autre méthode d\'apprentissage pourrais-je tester ?',
|
| action: 'Changer de support (écrit/oral/visuel)',
|
| evaluationLabel: 'Flexibilité stratégique'
|
| }
|
| },
|
| {
|
| id: 9,
|
| category: 'motivation',
|
| categoryName: 'Motivation & Sens',
|
| icon: '🌟',
|
| color: '#ec4899',
|
| front: {
|
| title: 'Sens de l\'Apprentissage',
|
| question: 'Pourquoi cette tâche est-elle importante pour moi ?'
|
| },
|
| back: {
|
| reflection: 'Quel bénéfice à long terme vais-je en retirer ?',
|
| action: 'Écrire une raison personnelle de persévérer',
|
| evaluationLabel: 'Clarté du sens'
|
| }
|
| },
|
| {
|
| id: 10,
|
| category: 'motivation',
|
| categoryName: 'Motivation & Sens',
|
| icon: '🎁',
|
| color: '#ec4899',
|
| front: {
|
| title: 'Récompense Future',
|
| question: 'Que vais-je ressentir une fois cette tâche terminée ?'
|
| },
|
| back: {
|
| reflection: 'La satisfaction d\'avoir persévéré vaut-elle l\'effort ?',
|
| action: 'Visualiser le sentiment de réussite',
|
| evaluationLabel: 'Motivation anticipée'
|
| }
|
| },
|
| {
|
| id: 11,
|
| category: 'evaluation',
|
| categoryName: 'Auto-évaluation',
|
| icon: '📊',
|
| color: '#6366f1',
|
| front: {
|
| title: 'Bilan Partiel',
|
| question: 'Qu\'ai-je réussi à accomplir, même partiellement ?'
|
| },
|
| back: {
|
| reflection: 'Quels progrès, aussi minimes soient-ils, puis-je identifier ?',
|
| action: 'Lister 3 petites victoires',
|
| evaluationLabel: 'Reconnaissance des progrès'
|
| }
|
| },
|
| {
|
| id: 12,
|
| category: 'evaluation',
|
| categoryName: 'Auto-évaluation',
|
| icon: '🔍',
|
| color: '#6366f1',
|
| front: {
|
| title: 'Apprentissage de l\'Expérience',
|
| question: 'Qu\'est-ce que cette difficulté m\'apprend sur ma façon d\'apprendre ?'
|
| },
|
| back: {
|
| reflection: 'Que pourrai-je faire différemment la prochaine fois ?',
|
| action: 'Noter un insight métacognitif',
|
| evaluationLabel: 'Apprentissage réflexif'
|
| }
|
| },
|
| {
|
| id: 13,
|
| category: 'awareness',
|
| categoryName: 'Prise de conscience',
|
| icon: '🧠',
|
| color: '#3b82f6',
|
| front: {
|
| title: 'Focus Attentionnel',
|
| question: 'Où se porte actuellement mon attention ?'
|
| },
|
| back: {
|
| reflection: 'Suis-je pleinement présent à la tâche ou mon esprit vagabonde-t-il ?',
|
| action: 'Pratiquer 1 minute de pleine conscience',
|
| evaluationLabel: 'Présence attentionnelle'
|
| }
|
| },
|
| {
|
| id: 14,
|
| category: 'perseverance',
|
| categoryName: 'Persévérance',
|
| icon: '🛡️',
|
| color: '#10b981',
|
| front: {
|
| title: 'Protection contre l\'Abandon',
|
| question: 'Quelle est ma première pensée quand je veux abandonner ?'
|
| },
|
| back: {
|
| reflection: 'Cette pensée est-elle un fait ou une interprétation ?',
|
| action: 'Reformuler la pensée de manière constructive',
|
| evaluationLabel: 'Contrôle des pensées'
|
| }
|
| },
|
| {
|
| id: 15,
|
| category: 'effort',
|
| categoryName: 'Gestion de l\'effort',
|
| icon: '⏰',
|
| color: '#f59e0b',
|
| front: {
|
| title: 'Rythme de Travail',
|
| question: 'Mon rythme actuel est-il soutenable sur la durée ?'
|
| },
|
| back: {
|
| reflection: 'Ai-je besoin d\'accélérer, de ralentir ou de maintenir ?',
|
| action: 'Ajuster le tempo pour éviter l\'épuisement',
|
| evaluationLabel: 'Régulation du rythme'
|
| }
|
| },
|
| {
|
| id: 16,
|
| category: 'strategies',
|
| categoryName: 'Stratégies d\'adaptation',
|
| icon: '🤝',
|
| color: '#8b5cf6',
|
| front: {
|
| title: 'Demande d\'Aide',
|
| question: 'Ai-je besoin d\'aide pour surmonter cet obstacle ?'
|
| },
|
| back: {
|
| reflection: 'Qui ou quoi pourrait m\'aider à avancer ?',
|
| action: 'Identifier une ressource ou une personne aidante',
|
| evaluationLabel: 'Ouverture à l\'aide'
|
| }
|
| },
|
| {
|
| id: 17,
|
| category: 'motivation',
|
| categoryName: 'Motivation & Sens',
|
| icon: '🎯',
|
| color: '#ec4899',
|
| front: {
|
| title: 'Alignement avec les Valeurs',
|
| question: 'En quoi cette tâche est-elle alignée avec mes valeurs ?'
|
| },
|
| back: {
|
| reflection: 'Quelle valeur personnelle cette tâche sert-elle ?',
|
| action: 'Relier la tâche à une valeur fondamentale',
|
| evaluationLabel: 'Alignement valeurs-tâche'
|
| }
|
| },
|
| {
|
| id: 18,
|
| category: 'evaluation',
|
| categoryName: 'Auto-évaluation',
|
| icon: '📈',
|
| color: '#6366f1',
|
| front: {
|
| title: 'Progression Relative',
|
| question: 'Où en étais-je il y a une semaine par rapport à maintenant ?'
|
| },
|
| back: {
|
| reflection: 'Quels progrès, même invisibles, ai-je réalisés ?',
|
| action: 'Identifier un aspect où l\'on s\'est amélioré',
|
| evaluationLabel: 'Conscience des progrès'
|
| }
|
| },
|
| {
|
| id: 19,
|
| category: 'perseverance',
|
| categoryName: 'Persévérance',
|
| icon: '🌱',
|
| color: '#10b981',
|
| front: {
|
| title: 'Mentalité de Croissance',
|
| question: 'Cette difficulté est-elle une menace ou une opportunité d\'apprentissage ?'
|
| },
|
| back: {
|
| reflection: 'Quelle compétence cette difficulté m\'aide-t-elle à développer ?',
|
| action: 'Reconceptualiser l\'obstacle comme défi formateur',
|
| evaluationLabel: 'Growth mindset'
|
| }
|
| },
|
| {
|
| id: 20,
|
| category: 'strategies',
|
| categoryName: 'Stratégies d\'adaptation',
|
| icon: '🎭',
|
| color: '#8b5cf6',
|
| front: {
|
| title: 'Changement de Perspective',
|
| question: 'Comment quelqu\'un que j\'admire aborderait-il cette situation ?'
|
| },
|
| back: {
|
| reflection: 'Quelle stratégie différente puis-je emprunter ?',
|
| action: 'Adopter temporairement une autre perspective',
|
| evaluationLabel: 'Créativité stratégique'
|
| }
|
| }
|
| ];
|
|
|
|
|
| flashcardsStats.totalCards = flashcardsData.length;
|
| flashcardsStats.reviewedCards = 0;
|
| flashcardsStats.averageScore = 0;
|
|
|
|
|
| showCardByCategory('all');
|
| }
|
|
|
|
|
| function showCardByCategory(category) {
|
| currentCategory = category;
|
| currentCardIndex = 0;
|
|
|
|
|
| document.querySelectorAll('.category-filter').forEach(filter => {
|
| filter.classList.remove('active');
|
| });
|
| document.querySelector(`.category-filter[onclick*="${category}"]`).classList.add('active');
|
|
|
|
|
| if (category === 'all') {
|
| flashcards = [...flashcardsData];
|
| } else {
|
| flashcards = flashcardsData.filter(card => card.category === category);
|
| }
|
|
|
|
|
| shuffleArray(flashcards);
|
|
|
|
|
| displayCurrentCard();
|
|
|
|
|
| updateFlashcardsStats();
|
| }
|
|
|
|
|
| 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;
|
| }
|
|
|
|
|
| function displayCurrentCard() {
|
| if (flashcards.length === 0) {
|
| document.getElementById('currentCard').innerHTML = `
|
| <div style="text-align: center; padding: 4rem; color: var(--gray-color);">
|
| <i class="fas fa-inbox" style="font-size: 3rem; margin-bottom: 1rem;"></i>
|
| <h3>Aucune carte disponible dans cette catégorie</h3>
|
| <p>Essayez une autre catégorie ou réinitialisez les cartes</p>
|
| </div>
|
| `;
|
| return;
|
| }
|
|
|
| const card = flashcards[currentCardIndex];
|
| const progress = ((currentCardIndex + 1) / flashcards.length * 100).toFixed(1);
|
|
|
| document.getElementById('currentCard').innerHTML = `
|
| <div class="flashcard" id="flashcard" onclick="flipCard()">
|
| <div class="flashcard-face flashcard-front">
|
| <div class="flashcard-category" style="background: ${card.color}22; color: ${card.color};">
|
| ${card.icon} ${card.categoryName}
|
| </div>
|
| <div class="flashcard-content">
|
| <div class="flashcard-title">${card.front.title}</div>
|
| <div class="flashcard-question">${card.front.question}</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, ${card.color}, ${darkenColor(card.color, 20)});">
|
| <div class="flashcard-content">
|
| <div class="flashcard-title">${card.front.title}</div>
|
| <div class="flashcard-question">${card.back.reflection}</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>${card.back.action}</div>
|
| </div>
|
|
|
| <div class="flashcard-evaluation">
|
| <div style="font-weight: bold; margin-bottom: 0.5rem;">${card.back.evaluationLabel} (1-5) :</div>
|
| <input type="range" min="1" max="5" value="3" class="evaluation-slider" id="evaluationSlider">
|
| <div class="evaluation-label">
|
| <span>Faible</span>
|
| <span>Élevé</span>
|
| </div>
|
| <button class="flashcard-action" onclick="saveEvaluation(event)">
|
| <i class="fas fa-save"></i> Enregistrer et continuer
|
| </button>
|
| </div>
|
| </div>
|
| </div>
|
| </div>
|
| `;
|
|
|
|
|
| document.getElementById('cardCounter').textContent = `Carte ${currentCardIndex + 1}/${flashcards.length}`;
|
| document.getElementById('flashcardProgressBar').style.width = `${progress}%`;
|
|
|
|
|
| document.getElementById('prevBtn').disabled = currentCardIndex === 0;
|
| document.getElementById('nextBtn').disabled = currentCardIndex === flashcards.length - 1;
|
| }
|
|
|
|
|
| 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);
|
| }
|
|
|
|
|
| function flipCard() {
|
| const flashcard = document.getElementById('flashcard');
|
| if (flashcard) {
|
| flashcard.classList.toggle('flipped');
|
| }
|
| }
|
|
|
|
|
| function saveEvaluation(event) {
|
| event.stopPropagation();
|
|
|
| const slider = document.getElementById('evaluationSlider');
|
| const score = parseInt(slider.value);
|
| const card = flashcards[currentCardIndex];
|
|
|
|
|
| if (!card.evaluations) {
|
| card.evaluations = [];
|
| }
|
| card.evaluations.push({
|
| score: score,
|
| date: new Date().toISOString(),
|
| category: card.category
|
| });
|
|
|
|
|
| flashcardsStats.reviewedCards++;
|
|
|
|
|
| const totalScores = flashcardsData.reduce((sum, card) => {
|
| if (card.evaluations && card.evaluations.length > 0) {
|
| return sum + card.evaluations[card.evaluations.length - 1].score;
|
| }
|
| return sum;
|
| }, 0);
|
|
|
| const reviewedWithScores = flashcardsData.filter(card =>
|
| card.evaluations && card.evaluations.length > 0
|
| ).length;
|
|
|
| flashcardsStats.averageScore = reviewedWithScores > 0
|
| ? (totalScores / reviewedWithScores).toFixed(1)
|
| : 0;
|
|
|
|
|
| nextCard();
|
|
|
|
|
| updateDashboardEM();
|
|
|
| showNotification('Évaluation enregistrée !', 'success');
|
| }
|
|
|
|
|
| function prevCard() {
|
| if (currentCardIndex > 0) {
|
| currentCardIndex--;
|
| displayCurrentCard();
|
| }
|
| }
|
|
|
|
|
| function nextCard() {
|
| if (currentCardIndex < flashcards.length - 1) {
|
| currentCardIndex++;
|
| displayCurrentCard();
|
| } else {
|
|
|
| if (confirm('Vous avez terminé toutes les cartes de cette catégorie. Voulez-vous recommencer ?')) {
|
| currentCardIndex = 0;
|
| shuffleArray(flashcards);
|
| displayCurrentCard();
|
| }
|
| }
|
| }
|
|
|
|
|
| function updateFlashcardsStats() {
|
| const statsContainer = document.getElementById('flashcardsStats');
|
|
|
|
|
| const categoryStats = {};
|
| flashcardsData.forEach(card => {
|
| if (!categoryStats[card.category]) {
|
| categoryStats[card.category] = {
|
| name: card.categoryName,
|
| count: 0,
|
| reviewed: 0,
|
| avgScore: 0
|
| };
|
| }
|
| categoryStats[card.category].count++;
|
|
|
| if (card.evaluations && card.evaluations.length > 0) {
|
| categoryStats[card.category].reviewed++;
|
| const lastScore = card.evaluations[card.evaluations.length - 1].score;
|
| categoryStats[card.category].avgScore =
|
| ((categoryStats[card.category].avgScore * (categoryStats[card.category].reviewed - 1) + lastScore) /
|
| categoryStats[card.category].reviewed).toFixed(1);
|
| }
|
| });
|
|
|
|
|
| let favoriteCategory = '';
|
| let maxReviewed = 0;
|
| Object.keys(categoryStats).forEach(cat => {
|
| if (categoryStats[cat].reviewed > maxReviewed) {
|
| maxReviewed = categoryStats[cat].reviewed;
|
| favoriteCategory = categoryStats[cat].name;
|
| }
|
| });
|
|
|
| flashcardsStats.favoriteCategory = favoriteCategory || 'Aucune';
|
|
|
| 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">${flashcardsStats.favoriteCategory}</div>
|
| <div class="stat-label">Catégorie préférée</div>
|
| </div>
|
| `;
|
| }
|
|
|
|
|
| function updateDashboardEM() {
|
| const dashboardContainer = document.getElementById('dashboardEM');
|
|
|
|
|
| const totalEvaluations = flashcardsData.reduce((sum, card) =>
|
| sum + (card.evaluations ? card.evaluations.length : 0), 0);
|
|
|
| const today = new Date().toISOString().split('T')[0];
|
| const evaluationsToday = flashcardsData.reduce((sum, card) => {
|
| if (card.evaluations) {
|
| return sum + card.evaluations.filter(eval =>
|
| eval.date.split('T')[0] === today
|
| ).length;
|
| }
|
| return sum;
|
| }, 0);
|
|
|
|
|
| const perseveranceCards = flashcardsData.filter(card => card.category === 'perseverance');
|
| const perseveranceScore = perseveranceCards.length > 0 ?
|
| perseveranceCards.reduce((sum, card) => {
|
| if (card.evaluations && card.evaluations.length > 0) {
|
| return sum + card.evaluations[card.evaluations.length - 1].score;
|
| }
|
| return sum;
|
| }, 0) / perseveranceCards.filter(c => c.evaluations && c.evaluations.length > 0).length : 0;
|
|
|
|
|
| const usedCategories = new Set();
|
| flashcardsData.forEach(card => {
|
| if (card.evaluations && card.evaluations.length > 0) {
|
| usedCategories.add(card.category);
|
| }
|
| });
|
| const strategyDiversity = (usedCategories.size / 6 * 100).toFixed(0);
|
|
|
| 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">${perseveranceScore.toFixed(1)}/5</div>
|
| <div class="dashboardEM-change">+${(perseveranceScore * 20).toFixed(0)}%</div>
|
| </div>
|
| <div class="dashboardEM-trend">
|
| <i class="fas fa-chart-line" style="color: #10b981;"></i>
|
| <span>Stable cette semaine</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">${flashcardsStats.averageScore}/5</div>
|
| <div class="dashboardEM-change">${flashcardsStats.averageScore > 3 ? '+' : ''}${(flashcardsStats.averageScore * 20 - 60).toFixed(0)}%</div>
|
| </div>
|
| <div class="dashboardEM-trend">
|
| <i class="fas fa-chart-line" style="color: ${flashcardsStats.averageScore > 3 ? '#10b981' : '#ef4444'}"></i>
|
| <span>${flashcardsStats.averageScore > 3 ? 'En progression' : 'À améliorer'}</span>
|
| </div>
|
| </div>
|
|
|
| <div class="dashboardEM-card">
|
| <div class="dashboardEM-header">
|
| <div class="dashboardEM-icon" style="background: linear-gradient(135deg, #8b5cf6, #7c3aed);">
|
| <i class="fas fa-lightbulb"></i>
|
| </div>
|
| <div>
|
| <h4>Métacognition</h4>
|
| <div style="font-size: 0.9rem; color: var(--gray-color);">Diversité des stratégies</div>
|
| </div>
|
| </div>
|
| <div class="dashboardEM-metric">
|
| <div class="dashboardEM-value">${strategyDiversity}%</div>
|
| <div class="dashboardEM-change">+${(strategyDiversity / 2).toFixed(0)}%</div>
|
| </div>
|
| <div class="dashboardEM-trend">
|
| <i class="fas fa-chart-line" style="color: #10b981;"></i>
|
| <span>${strategyDiversity > 50 ? 'Diversifié' : 'À élargir'}</span>
|
| </div>
|
| </div>
|
|
|
| <div class="dashboardEM-card">
|
| <div class="dashboardEM-header">
|
| <div class="dashboardEM-icon" style="background: linear-gradient(135deg, #ec4899, #db2777);">
|
| <i class="fas fa-fire"></i>
|
| </div>
|
| <div>
|
| <h4>Activité</h4>
|
| <div style="font-size: 0.9rem; color: var(--gray-color);">Engagement quotidien</div>
|
| </div>
|
| </div>
|
| <div class="dashboardEM-metric">
|
| <div class="dashboardEM-value">${evaluationsToday}</div>
|
| <div class="dashboardEM-change">${evaluationsToday > 0 ? '+100%' : '0%'}</div>
|
| </div>
|
| <div class="dashboardEM-trend">
|
| <i class="fas fa-calendar-day" style="color: ${evaluationsToday > 0 ? '#10b981' : '#ef4444'}"></i>
|
| <span>${evaluationsToday > 0 ? 'Actif aujourd\'hui' : 'Pas d\'activité'}</span>
|
| </div>
|
| </div>
|
| `;
|
| }
|
|
|
|
|
| function resetFlashcards() {
|
| if (confirm('Voulez-vous vraiment réinitialiser toutes les flashcards ? Cela effacera toutes vos évaluations.')) {
|
| flashcardsData.forEach(card => {
|
| delete card.evaluations;
|
| });
|
| flashcardsStats.reviewedCards = 0;
|
| flashcardsStats.averageScore = 0;
|
| flashcardsStats.favoriteCategory = 'Aucune';
|
|
|
| currentCardIndex = 0;
|
| showCardByCategory(currentCategory);
|
|
|
| showNotification('Flashcards réinitialisées avec succès !', 'success');
|
| }
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
| function setEvaluation(score) {
|
| document.querySelectorAll('.quality-indicator .quality-dot').forEach((dot, index) => {
|
| dot.classList.toggle('active', index === score - 1);
|
| });
|
| }
|
|
|
|
|
| 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);
|
|
|
|
|
| document.getElementById('todo').value = '';
|
| document.getElementById('doing').value = '';
|
| document.getElementById('done').value = '';
|
| document.getElementById('metacognition').value = '';
|
| setEvaluation(3);
|
|
|
|
|
| localStorage.setItem('journalEntries', JSON.stringify(journalEntries));
|
|
|
| showNotification('Journal sauvegardé avec succès !', 'success');
|
| }
|
|
|
|
|
| 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';
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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."
|
| },
|
| {
|
| type: 'metacognition',
|
| icon: '🤔',
|
| message: "Posez-vous cette question: quelle stratégie d'apprentissage fonctionne le mieux pour vous aujourd'hui ?"
|
| }
|
| ];
|
|
|
| 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);
|
|
|
|
|
| while (container.children.length > 5) {
|
| container.removeChild(container.lastChild);
|
| }
|
| }
|
|
|
|
|
| function createNotificationChart() {
|
| const ctx = document.getElementById('notificationChart').getContext('2d');
|
|
|
| window.notificationChart = new Chart(ctx, {
|
| type: 'bar',
|
| data: {
|
| labels: ['Motivation', 'Rappels', 'Encouragement', 'Métacognition'],
|
| datasets: [{
|
| label: 'Efficacité (%)',
|
| data: [85, 72, 91, 68],
|
| backgroundColor: [
|
| 'rgba(59, 130, 246, 0.7)',
|
| 'rgba(16, 185, 129, 0.7)',
|
| 'rgba(245, 158, 11, 0.7)',
|
| 'rgba(139, 92, 246, 0.7)'
|
| ],
|
| borderColor: [
|
| 'rgb(59, 130, 246)',
|
| 'rgb(16, 185, 129)',
|
| 'rgb(245, 158, 11)',
|
| 'rgb(139, 92, 246)'
|
| ],
|
| 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 }
|
| }
|
| }
|
| }
|
| });
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
| function refreshStats() {
|
|
|
|
|
| showNotification('Statistiques actualisées', 'success');
|
| }
|
|
|
|
|
| function generateHeatmap() {
|
| const container = document.getElementById('heatmapContent');
|
|
|
|
|
| const heatmapData = generateDemoHeatmapData(currentHeatmapPeriod);
|
|
|
|
|
| let html = '<div class="heatmap-grid">';
|
|
|
|
|
| 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>`;
|
| });
|
|
|
|
|
| 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>';
|
| container.innerHTML = html;
|
| }
|
|
|
|
|
| function generateDemoHeatmapData(period) {
|
| const data = [];
|
| let weeks = 4;
|
|
|
| if (period === 'quarter') weeks = 13;
|
| if (period === 'year') weeks = 52;
|
|
|
|
|
| for (let week = 0; week < weeks; week++) {
|
| const weekData = [];
|
| for (let day = 0; day < 7; day++) {
|
|
|
| let activity = 0;
|
|
|
|
|
| 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);
|
| }
|
|
|
|
|
| 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;
|
| }
|
|
|
|
|
| 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;
|
| }
|
|
|
|
|
| function changeHeatmapPeriod(period) {
|
| currentHeatmapPeriod = period;
|
|
|
|
|
| document.querySelectorAll('.heatmap-period').forEach(btn => {
|
| btn.classList.remove('active');
|
| if (btn.textContent.toLowerCase().includes(period)) {
|
| btn.classList.add('active');
|
| }
|
| });
|
|
|
|
|
| generateHeatmap();
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
| function showNotification(message, type = 'info') {
|
| const colors = {
|
| success: '#10b981',
|
| error: '#ef4444',
|
| warning: '#f59e0b',
|
| info: '#3b82f6'
|
| };
|
|
|
|
|
| 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: slideIn 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);
|
|
|
|
|
| setTimeout(() => {
|
| notification.style.animation = 'slideIn 0.3s ease reverse';
|
| setTimeout(() => notification.remove(), 300);
|
| }, 3000);
|
| }
|
|
|
|
|
| function loadSavedData() {
|
| try {
|
|
|
| const savedProfile = localStorage.getItem('learnerProfile');
|
| if (savedProfile) {
|
| learnerProfile = JSON.parse(savedProfile);
|
| updateProfileProgress();
|
| updateProfileSummary();
|
| }
|
|
|
|
|
| const savedJournal = localStorage.getItem('journalEntries');
|
| if (savedJournal) {
|
| journalEntries = JSON.parse(savedJournal);
|
| }
|
|
|
|
|
| const savedFlashcards = localStorage.getItem('flashcardsData');
|
| if (savedFlashcards) {
|
| const parsed = JSON.parse(savedFlashcards);
|
| if (parsed && parsed.length > 0) {
|
| flashcardsData = parsed;
|
|
|
|
|
| flashcardsStats.reviewedCards = flashcardsData.reduce((sum, card) =>
|
| sum + (card.evaluations ? card.evaluations.length : 0), 0);
|
|
|
| const totalScores = flashcardsData.reduce((sum, card) => {
|
| if (card.evaluations && card.evaluations.length > 0) {
|
| return sum + card.evaluations[card.evaluations.length - 1].score;
|
| }
|
| return sum;
|
| }, 0);
|
|
|
| const reviewedWithScores = flashcardsData.filter(card =>
|
| card.evaluations && card.evaluations.length > 0
|
| ).length;
|
|
|
| flashcardsStats.averageScore = reviewedWithScores > 0
|
| ? (totalScores / reviewedWithScores).toFixed(1)
|
| : 0;
|
| }
|
| }
|
| } catch (error) {
|
| console.error('Erreur lors du chargement des données:', error);
|
| }
|
| }
|
|
|
|
|
| function saveAllData() {
|
| try {
|
| localStorage.setItem('learnerProfile', JSON.stringify(learnerProfile));
|
| localStorage.setItem('journalEntries', JSON.stringify(journalEntries));
|
| localStorage.setItem('flashcardsData', JSON.stringify(flashcardsData));
|
|
|
| } catch (error) {
|
| console.error('Erreur lors de la sauvegarde:', error);
|
| }
|
| }
|
|
|
|
|
| setInterval(saveAllData, 30000);
|
|
|
|
|
| window.addEventListener('beforeunload', saveAllData);
|
| </script>
|
| </body>
|
| </html> |