OUAREDAEK commited on
Commit
0b2701f
·
verified ·
1 Parent(s): 75a24de

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +1171 -695
index.html CHANGED
@@ -821,178 +821,6 @@
821
  font-size: 1.1rem;
822
  }
823
 
824
- /* Flashcard Application */
825
- .flashcard-section {
826
- margin-top: 2rem;
827
- border-top: 2px solid #f1f5f9;
828
- padding-top: 2rem;
829
- }
830
-
831
- .flashcard-container {
832
- max-width: 800px;
833
- margin: 0 auto;
834
- }
835
-
836
- .flashcard {
837
- background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
838
- border-radius: 15px;
839
- padding: 3rem 2rem;
840
- margin: 2rem 0;
841
- min-height: 300px;
842
- display: flex;
843
- flex-direction: column;
844
- justify-content: center;
845
- align-items: center;
846
- position: relative;
847
- cursor: pointer;
848
- transition: all 0.3s;
849
- box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
850
- border: 2px solid #e2e8f0;
851
- }
852
-
853
- .flashcard:hover {
854
- transform: translateY(-5px);
855
- box-shadow: 0 15px 30px rgba(0, 0, 0, 0.15);
856
- }
857
-
858
- .flashcard.flipped {
859
- background: linear-gradient(135deg, #dbeafe 0%, #bfdbfe 100%);
860
- }
861
-
862
- .flashcard-front, .flashcard-back {
863
- text-align: center;
864
- width: 100%;
865
- }
866
-
867
- .flashcard-category {
868
- position: absolute;
869
- top: 15px;
870
- left: 15px;
871
- background: var(--primary-color);
872
- color: white;
873
- padding: 5px 15px;
874
- border-radius: 20px;
875
- font-size: 0.8rem;
876
- }
877
-
878
- .flashcard-content {
879
- font-size: 1.5rem;
880
- font-weight: 600;
881
- color: var(--dark-color);
882
- margin: 1.5rem 0;
883
- line-height: 1.6;
884
- }
885
-
886
- .flashcard-example {
887
- font-size: 1rem;
888
- color: var(--gray-color);
889
- font-style: italic;
890
- margin-top: 1rem;
891
- border-left: 3px solid var(--secondary-color);
892
- padding-left: 15px;
893
- }
894
-
895
- .flashcard-stats {
896
- position: absolute;
897
- top: 15px;
898
- right: 15px;
899
- display: flex;
900
- gap: 10px;
901
- align-items: center;
902
- }
903
-
904
- .flashcard-score {
905
- background: #10b981;
906
- color: white;
907
- padding: 5px 10px;
908
- border-radius: 15px;
909
- font-size: 0.8rem;
910
- font-weight: bold;
911
- }
912
-
913
- .flashcard-difficulty {
914
- background: #f59e0b;
915
- color: white;
916
- padding: 5px 10px;
917
- border-radius: 15px;
918
- font-size: 0.8rem;
919
- }
920
-
921
- .flashcard-controls {
922
- display: flex;
923
- justify-content: center;
924
- gap: 15px;
925
- margin-top: 2rem;
926
- }
927
-
928
- .flashcard-btn {
929
- padding: 10px 25px;
930
- border: none;
931
- border-radius: 10px;
932
- font-size: 1rem;
933
- font-weight: 600;
934
- cursor: pointer;
935
- transition: all 0.3s;
936
- display: flex;
937
- align-items: center;
938
- gap: 8px;
939
- }
940
-
941
- .flashcard-btn.easy {
942
- background: #10b981;
943
- color: white;
944
- }
945
-
946
- .flashcard-btn.medium {
947
- background: #f59e0b;
948
- color: white;
949
- }
950
-
951
- .flashcard-btn.hard {
952
- background: #ef4444;
953
- color: white;
954
- }
955
-
956
- .flashcard-btn:hover {
957
- transform: translateY(-2px);
958
- box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
959
- }
960
-
961
- .flashcard-progress {
962
- margin-top: 2rem;
963
- text-align: center;
964
- }
965
-
966
- .progress-bar {
967
- height: 8px;
968
- background: #e2e8f0;
969
- border-radius: 4px;
970
- margin: 10px 0;
971
- overflow: hidden;
972
- }
973
-
974
- .progress-fill {
975
- height: 100%;
976
- background: linear-gradient(90deg, #3b82f6, #8b5cf6);
977
- border-radius: 4px;
978
- transition: width 0.3s ease;
979
- }
980
-
981
- .flashcard-stats-summary {
982
- display: grid;
983
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
984
- gap: 15px;
985
- margin-top: 2rem;
986
- }
987
-
988
- .flashcard-stat-item {
989
- background: white;
990
- padding: 1.5rem;
991
- border-radius: 10px;
992
- text-align: center;
993
- box-shadow: 0 3px 10px rgba(0, 0, 0, 0.05);
994
- }
995
-
996
  /* Productivity Options - STYLE MODIFIÉ */
997
  .productivity-grid {
998
  display: grid;
@@ -1269,28 +1097,290 @@
1269
  box-shadow: 0 0 0 3px white, 0 0 0 6px currentColor;
1270
  }
1271
 
1272
- /* Flashcard Progress in Stats */
1273
- .flashcard-stats-card {
1274
- grid-column: span 2;
 
 
 
 
 
 
 
 
1275
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
 
1276
  }
1277
 
1278
- .flashcard-stats-header {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1279
  display: flex;
1280
- justify-content: space-between;
 
1281
  align-items: center;
1282
- margin-bottom: 1rem;
 
1283
  }
1284
 
1285
- .streak-counter {
1286
- background: linear-gradient(135deg, #f59e0b, #d97706);
 
 
 
 
 
1287
  color: white;
 
 
 
 
 
 
 
 
1288
  padding: 5px 15px;
1289
  border-radius: 20px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1290
  font-weight: bold;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1291
  display: flex;
1292
  align-items: center;
1293
  gap: 5px;
 
 
1294
  }
1295
 
1296
  /* Responsive */
@@ -1324,19 +1414,6 @@
1324
  justify-content: center;
1325
  }
1326
 
1327
- .flashcard-controls {
1328
- flex-direction: column;
1329
- }
1330
-
1331
- .flashcard-btn {
1332
- width: 100%;
1333
- justify-content: center;
1334
- }
1335
-
1336
- .flashcard-stats-summary {
1337
- grid-template-columns: 1fr;
1338
- }
1339
-
1340
  .heatmap-grid {
1341
  gap: 4px;
1342
  }
@@ -1356,6 +1433,41 @@
1356
  .profile-summary {
1357
  grid-template-columns: 1fr;
1358
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1359
  }
1360
  </style>
1361
  </head>
@@ -1364,11 +1476,12 @@
1364
  <!-- Header -->
1365
  <header class="header">
1366
  <h1><i class="fas fa-graduation-cap"></i> Compagnon Pédagogique</h1>
1367
- <p>PerseverAId Analyse intelligente de la persistance et du management de l'effort</p>
 
1368
  <div class="badge">PerseverAId (AI + Aid + Perseverance)</div>
1369
  </header>
1370
 
1371
- <!-- Navigation -->
1372
  <nav class="nav-tabs">
1373
  <button class="nav-tab active" onclick="showTab('profile')">
1374
  <i class="fas fa-user-circle"></i> Profil Apprenant
@@ -1379,21 +1492,19 @@
1379
  <button class="nav-tab" onclick="showTab('planner')">
1380
  <i class="fas fa-calendar-alt"></i> Planner SM-2
1381
  </button>
1382
- <button class="nav-tab" onclick="showTab('flashcards')">
1383
- <i class="fas fa-layer-group"></i> Flashcards
1384
- </button>
1385
  <button class="nav-tab" onclick="showTab('journal')">
1386
  <i class="fas fa-book"></i> Journal SRL
1387
  </button>
 
 
 
1388
  <button class="nav-tab" onclick="showTab('notifications')">
1389
  <i class="fas fa-bell"></i> Notifications IA
1390
  </button>
1391
  <button class="nav-tab" onclick="showTab('stats')">
1392
  <i class="fas fa-chart-line"></i> Statistiques
1393
  </button>
1394
- <button class="nav-tab" onclick="showTab('learn')">
1395
- <i class="fas fa-graduation-cap"></i> Apprendre à manager l'effort
1396
- </button>
1397
  </nav>
1398
 
1399
  <!-- Profil Apprenant Section -->
@@ -2010,94 +2121,75 @@
2010
  <section id="flashcards" class="tab-content">
2011
  <div class="card">
2012
  <div class="card-header">
2013
- <h3><i class="fas fa-layer-group"></i> Application Flashcards avec Répétition Espacée</h3>
2014
  <div>
2015
- <span class="streak-counter">
2016
- <i class="fas fa-fire"></i> Série: <span id="streakCount">0</span> jours
2017
- </span>
 
 
 
2018
  </div>
2019
  </div>
2020
 
2021
- <div class="flashcard-container">
2022
- <div class="flashcard" id="flashcard" onclick="flipCard()">
2023
- <div class="flashcard-category" id="flashcardCategory">Conjugaison</div>
2024
- <div class="flashcard-stats">
2025
- <span class="flashcard-score" id="flashcardScore">Score: 85%</span>
2026
- <span class="flashcard-difficulty" id="flashcardDifficulty">Moyen</span>
2027
- </div>
2028
-
2029
- <div class="flashcard-front" id="flashcardFront">
2030
- <div class="flashcard-content" id="flashcardQuestion">
2031
- Je (être) content de te voir.
2032
- </div>
2033
- <div class="flashcard-example" id="flashcardHint">
2034
- Cliquez pour voir la réponse
2035
- </div>
2036
- </div>
2037
-
2038
- <div class="flashcard-back" id="flashcardBack" style="display: none;">
2039
- <div class="flashcard-content" id="flashcardAnswer">
2040
- suis
2041
- </div>
2042
- <div class="flashcard-example" id="flashcardExplanation">
2043
- 'Être' au présent: je suis, tu es, il est, nous sommes, vous êtes, ils sont
2044
- </div>
2045
- </div>
2046
  </div>
2047
-
2048
- <div class="flashcard-controls">
2049
- <button class="flashcard-btn hard" onclick="rateCard(0)">
2050
- <i class="fas fa-times"></i> Difficile
2051
- </button>
2052
- <button class="flashcard-btn medium" onclick="rateCard(1)">
2053
- <i class="fas fa-minus"></i> Moyen
2054
- </button>
2055
- <button class="flashcard-btn easy" onclick="rateCard(2)">
2056
- <i class="fas fa-check"></i> Facile
2057
- </button>
2058
  </div>
2059
-
2060
- <div class="flashcard-progress">
2061
- <div>Progression: <span id="currentCard">1</span>/<span id="totalCards">3</span></div>
2062
- <div class="progress-bar">
2063
- <div class="progress-fill" id="progressFill" style="width: 33%"></div>
2064
- </div>
2065
  </div>
2066
-
2067
- <div class="flashcard-section">
2068
- <h4><i class="fas fa-plus-circle"></i> Ajouter une Nouvelle Flashcard</h4>
2069
- <div class="form-row">
2070
- <div class="form-col">
2071
- <label class="form-label"><i class="fas fa-question"></i> Question</label>
2072
- <textarea id="newQuestion" class="form-control" rows="2" placeholder="Entrez la question..."></textarea>
2073
- </div>
2074
- <div class="form-col">
2075
- <label class="form-label"><i class="fas fa-lightbulb"></i> Réponse</label>
2076
- <textarea id="newAnswer" class="form-control" rows="2" placeholder="Entrez la réponse..."></textarea>
2077
- </div>
2078
- </div>
2079
- <div class="form-row">
2080
- <div class="form-col">
2081
- <label class="form-label"><i class="fas fa-tag"></i> Catégorie</label>
2082
- <select id="newCategory" class="form-control">
2083
- <option value="conjugaison">Conjugaison</option>
2084
- <option value="grammaire">Grammaire</option>
2085
- <option value="vocabulaire">Vocabulaire</option>
2086
- <option value="expression_ecrite">Expression écrite</option>
2087
- </select>
2088
- </div>
2089
- <div class="form-col">
2090
- <label class="form-label"><i class="fas fa-star"></i> Difficulté</label>
2091
- <select id="newDifficulty" class="form-control">
2092
- <option value="facile">Facile</option>
2093
- <option value="moyen" selected>Moyen</option>
2094
- <option value="difficile">Difficile</option>
2095
- </select>
2096
- </div>
2097
  </div>
2098
- <button class="btn btn-primary" onclick="addNewFlashcard()">
2099
- <i class="fas fa-plus"></i> Ajouter la Flashcard
2100
- </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
2101
  </div>
2102
  </div>
2103
  </div>
@@ -2293,71 +2385,6 @@
2293
  </div>
2294
  </div>
2295
  </div>
2296
-
2297
- <!-- Flashcard Statistics -->
2298
- <div class="flashcard-section">
2299
- <h4><i class="fas fa-layer-group"></i> Statistiques des Flashcards</h4>
2300
- <div class="flashcard-stats-summary">
2301
- <div class="flashcard-stat-item">
2302
- <div style="font-size: 2rem; color: #3b82f6; font-weight: bold;" id="statsTotalCards">3</div>
2303
- <div>Total Flashcards</div>
2304
- </div>
2305
- <div class="flashcard-stat-item">
2306
- <div style="font-size: 2rem; color: #10b981; font-weight: bold;" id="statsMastered">1</div>
2307
- <div>Maîtrisées</div>
2308
- </div>
2309
- <div class="flashcard-stat-item">
2310
- <div style="font-size: 2rem; color: #f59e0b; font-weight: bold;" id="statsLearning">2</div>
2311
- <div>En Apprentissage</div>
2312
- </div>
2313
- <div class="flashcard-stat-item">
2314
- <div style="font-size: 2rem; color: #ef4444; font-weight: bold;" id="statsDue">1</div>
2315
- <div>À Réviser</div>
2316
- </div>
2317
- </div>
2318
-
2319
- <div class="chart-container" style="height: 300px; margin-top: 2rem;">
2320
- <canvas id="flashcardProgressChart"></canvas>
2321
- </div>
2322
- </div>
2323
- </div>
2324
- </section>
2325
-
2326
- <!-- Learn SM-2 Section -->
2327
- <section id="learn" class="tab-content">
2328
- <div class="card">
2329
- <div class="card-header">
2330
- <h3><i class="fas fa-graduation-cap"></i> Apprendre l'Algorithme SM-2</h3>
2331
- </div>
2332
-
2333
- <div class="questionnaire-section">
2334
- <div class="questionnaire-header">
2335
- <div class="questionnaire-icon" style="background: linear-gradient(135deg, #3b82f6, #1d4ed8);">
2336
- <i class="fas fa-brain"></i>
2337
- </div>
2338
- <div>
2339
- <div class="questionnaire-title">Algorithme SM-2 - Répétition Espacée</div>
2340
- <div class="questionnaire-description">Optimisez votre mémorisation à long terme</div>
2341
- </div>
2342
- </div>
2343
-
2344
- <h4><i class="fas fa-info-circle"></i> Qu'est-ce que l'algorithme SM-2 ?</h4>
2345
- <p>L'algorithme SM-2 est un système de répétition espacée développé pour optimiser la mémorisation à long terme.</p>
2346
-
2347
- <h4 style="margin-top: 20px;"><i class="fas fa-chart-line"></i> Comment ça marche ?</h4>
2348
- <ul style="padding-left: 20px; margin-bottom: 20px;">
2349
- <li>Plus vous connaissez bien une information, plus l'intervalle de révision augmente</li>
2350
- <li>Les intervalles typiques sont: 1 jour, 3 jours, 7 jours, 14 jours, etc.</li>
2351
- <li>Le système s'adapte à vos performances</li>
2352
- </ul>
2353
-
2354
- <div class="visualization-container">
2355
- <h4><i class="fas fa-chart-network"></i> Comparaison des Niveaux de Qualité SM-2</h4>
2356
- <div class="chart-container">
2357
- <canvas id="comparisonChart"></canvas>
2358
- </div>
2359
- </div>
2360
- </div>
2361
  </div>
2362
  </section>
2363
  </div>
@@ -2394,51 +2421,6 @@
2394
  }
2395
  };
2396
 
2397
- // Variables pour les flashcards
2398
- let flashcards = [
2399
- {
2400
- id: 1,
2401
- question: "Je (être) content de te voir.",
2402
- answer: "suis",
2403
- explanation: "'Être' au présent: je suis, tu es, il est, nous sommes, vous êtes, ils sont",
2404
- category: "conjugaison",
2405
- difficulty: "moyen",
2406
- score: 85,
2407
- mastered: false,
2408
- nextReview: new Date()
2409
- },
2410
- {
2411
- id: 2,
2412
- question: "Nous (aller) au marché demain.",
2413
- answer: "allons",
2414
- explanation: "'Aller' au présent: je vais, tu vas, il va, nous allons, vous allez, ils vont",
2415
- category: "conjugaison",
2416
- difficulty: "facile",
2417
- score: 92,
2418
- mastered: true,
2419
- nextReview: new Date(Date.now() + 3 * 24 * 60 * 60 * 1000)
2420
- },
2421
- {
2422
- id: 3,
2423
- question: "Elle (faire) ses devoirs chaque soir.",
2424
- answer: "fait",
2425
- explanation: "'Faire' au présent: je fais, tu fais, il fait, nous faisons, vous faites, ils font",
2426
- category: "conjugaison",
2427
- difficulty: "moyen",
2428
- score: 78,
2429
- mastered: false,
2430
- nextReview: new Date()
2431
- }
2432
- ];
2433
-
2434
- let currentFlashcardIndex = 0;
2435
- let flashcardStats = {
2436
- streak: 0,
2437
- totalReviewed: 0,
2438
- masteryRate: 33,
2439
- avgScore: 85
2440
- };
2441
-
2442
  // Variables pour le planner
2443
  let selectedTimeSlots = ['morning'];
2444
  let currentQuality = 2;
@@ -2451,6 +2433,18 @@
2451
  // Variables pour le journal
2452
  let journalEntries = [];
2453
 
 
 
 
 
 
 
 
 
 
 
 
 
2454
  // ============================================
2455
  // INITIALISATION
2456
  // ============================================
@@ -2461,20 +2455,15 @@
2461
  updateProfileSummary();
2462
  createMotivationChart();
2463
 
2464
- // Initialiser les flashcards
2465
- displayFlashcard(currentFlashcardIndex);
2466
- updateFlashcardStats();
2467
- updateFlashcardProgressChart();
2468
-
2469
  // Initialiser la heatmap
2470
  generateHeatmap();
2471
 
2472
- // Initialiser le graphique de comparaison SM-2
2473
- updateComparisonChart();
2474
-
2475
  // Initialiser le graphique des notifications
2476
  createNotificationChart();
2477
 
 
 
 
2478
  // Charger les données sauvegardées
2479
  loadSavedData();
2480
  });
@@ -2505,8 +2494,7 @@
2505
  'flashcards': 'Flashcards',
2506
  'journal': 'Journal',
2507
  'notifications': 'Notifications',
2508
- 'stats': 'Statistiques',
2509
- 'learn': 'Apprendre'
2510
  };
2511
 
2512
  document.querySelectorAll('.nav-tab').forEach(tab => {
@@ -2519,8 +2507,9 @@
2519
  if (tabId === 'stats') {
2520
  refreshStats();
2521
  generateHeatmap();
2522
- } else if (tabId === 'learn') {
2523
- updateComparisonChart();
 
2524
  }
2525
  }
2526
 
@@ -3064,276 +3053,802 @@
3064
  container.appendChild(card);
3065
  });
3066
 
3067
- // Visualisation
3068
- createSM2Visualization(intervals, plan[0]?.competence || 'Compétence');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3069
  }
3070
 
3071
- // Créer la visualisation SM-2
3072
- function createSM2Visualization(intervals, competence) {
3073
- const ctx = document.getElementById('sm2Visualization').getContext('2d');
 
3074
 
3075
- if (window.sm2VisualizationChart) {
3076
- window.sm2VisualizationChart.destroy();
 
 
 
 
 
 
 
 
 
3077
  }
3078
 
3079
- const labels = intervals.map((_, i) => `Répétition ${i + 1}`);
 
3080
 
3081
- window.sm2VisualizationChart = new Chart(ctx, {
3082
- type: 'line',
3083
- data: {
3084
- labels: labels,
3085
- datasets: [{
3086
- label: 'Intervalle (jours)',
3087
- data: intervals,
3088
- borderColor: '#3b82f6',
3089
- backgroundColor: 'rgba(59, 130, 246, 0.1)',
3090
- borderWidth: 3,
3091
- fill: true,
3092
- tension: 0.4
3093
- }]
3094
- },
3095
- options: {
3096
- responsive: true,
3097
- maintainAspectRatio: false,
3098
- plugins: {
3099
- title: {
3100
- display: true,
3101
- text: `Courbe de Répétition Espacée - ${competence}`,
3102
- font: { size: 16 }
3103
- }
3104
- },
3105
- scales: {
3106
- y: {
3107
- beginAtZero: true,
3108
- title: {
3109
- display: true,
3110
- text: 'Jours'
3111
- }
3112
- },
3113
- x: {
3114
- title: {
3115
- display: true,
3116
- text: 'Numéro de Répétition'
3117
- }
3118
- }
3119
- }
3120
- }
3121
- });
3122
- }
3123
-
3124
- // Exporter le planner
3125
- function exportPlanner() {
3126
- const plannerData = document.getElementById('plannerContent').innerText;
3127
- const blob = new Blob([plannerData], { type: 'text/plain' });
3128
- const url = URL.createObjectURL(blob);
3129
- const a = document.createElement('a');
3130
- a.href = url;
3131
- a.download = 'planner-sm2.txt';
3132
- document.body.appendChild(a);
3133
- a.click();
3134
- document.body.removeChild(a);
3135
- URL.revokeObjectURL(url);
3136
 
3137
- showNotification('Planner exporté avec succès !', 'success');
 
3138
  }
3139
 
3140
- // ============================================
3141
- // FLASHCARDS
3142
- // ============================================
 
 
 
 
 
3143
 
3144
- // Afficher une flashcard
3145
- function displayFlashcard(index) {
3146
- if (flashcards.length === 0) return;
 
 
 
 
 
 
 
 
 
 
 
 
3147
 
3148
- const card = flashcards[index];
3149
- document.getElementById('flashcardQuestion').textContent = card.question;
3150
- document.getElementById('flashcardAnswer').textContent = card.answer;
3151
- document.getElementById('flashcardExplanation').textContent = card.explanation;
3152
- document.getElementById('flashcardCategory').textContent = card.category.charAt(0).toUpperCase() + card.category.slice(1);
3153
- document.getElementById('flashcardScore').textContent = `Score: ${card.score}%`;
3154
- document.getElementById('flashcardDifficulty').textContent = card.difficulty.charAt(0).toUpperCase() + card.difficulty.slice(1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3155
 
3156
- // Mettre à jour la progression
3157
- document.getElementById('currentCard').textContent = index + 1;
3158
- document.getElementById('totalCards').textContent = flashcards.length;
3159
- document.getElementById('progressFill').style.width = `${((index + 1) / flashcards.length) * 100}%`;
3160
 
3161
- // Réinitialiser l'affichage
3162
- document.getElementById('flashcardFront').style.display = 'block';
3163
- document.getElementById('flashcardBack').style.display = 'none';
3164
- document.getElementById('flashcard').classList.remove('flipped');
 
 
 
 
 
 
 
 
 
 
 
3165
  }
3166
 
3167
  // Retourner la carte
3168
  function flipCard() {
3169
- const front = document.getElementById('flashcardFront');
3170
- const back = document.getElementById('flashcardBack');
3171
-
3172
- if (front.style.display !== 'none') {
3173
- front.style.display = 'none';
3174
- back.style.display = 'block';
3175
- document.getElementById('flashcard').classList.add('flipped');
3176
- } else {
3177
- front.style.display = 'block';
3178
- back.style.display = 'none';
3179
- document.getElementById('flashcard').classList.remove('flipped');
3180
  }
3181
  }
3182
 
3183
- // Évaluer la carte
3184
- function rateCard(rating) {
3185
- if (flashcards.length === 0) return;
3186
-
3187
- const card = flashcards[currentFlashcardIndex];
3188
-
3189
- // Mettre à jour le score basé sur l'évaluation (0=difficile, 1=moyen, 2=facile)
3190
- let scoreChange = 0;
3191
- switch(rating) {
3192
- case 0: // Difficile
3193
- scoreChange = -10;
3194
- break;
3195
- case 1: // Moyen
3196
- scoreChange = 5;
3197
- break;
3198
- case 2: // Facile
3199
- scoreChange = 15;
3200
- card.mastered = true;
3201
- break;
3202
- }
3203
 
3204
- // Mettre à jour le score (limité entre 0 et 100)
3205
- card.score = Math.max(0, Math.min(100, card.score + scoreChange));
 
3206
 
3207
- // Mettre à jour la date de révision
3208
- const interval = rating === 2 ? 7 : rating === 1 ? 3 : 1;
3209
- card.nextReview = new Date(Date.now() + interval * 24 * 60 * 60 * 1000);
 
 
 
 
 
 
3210
 
3211
- // Mettre à jour les statistiques
3212
- flashcardStats.totalReviewed++;
3213
- flashcardStats.streak++;
3214
 
3215
- // Calculer le taux de maîtrise
3216
- const mastered = flashcards.filter(c => c.mastered).length;
3217
- flashcardStats.masteryRate = Math.round((mastered / flashcards.length) * 100);
 
 
 
 
3218
 
3219
- // Calculer le score moyen
3220
- const totalScore = flashcards.reduce((sum, c) => sum + c.score, 0);
3221
- flashcardStats.avgScore = Math.round(totalScore / flashcards.length);
3222
 
3223
- // Mettre à jour l'affichage
3224
- updateFlashcardStatsDisplay();
 
3225
 
3226
  // Passer à la carte suivante
3227
  nextCard();
3228
- }
3229
-
3230
- // Carte suivante
3231
- function nextCard() {
3232
- if (flashcards.length === 0) return;
3233
 
3234
- currentFlashcardIndex = (currentFlashcardIndex + 1) % flashcards.length;
3235
- displayFlashcard(currentFlashcardIndex);
3236
- }
3237
-
3238
- // Mettre à jour les statistiques des flashcards
3239
- function updateFlashcardStats() {
3240
- const mastered = flashcards.filter(c => c.mastered).length;
3241
- const due = flashcards.filter(c => new Date(c.nextReview) <= new Date()).length;
3242
- const totalScore = flashcards.reduce((sum, c) => sum + c.score, 0);
3243
-
3244
- flashcardStats = {
3245
- totalReviewed: flashcardStats.totalReviewed,
3246
- masteryRate: Math.round((mastered / flashcards.length) * 100),
3247
- avgScore: Math.round(totalScore / flashcards.length),
3248
- streak: flashcardStats.streak
3249
- };
3250
 
3251
- updateFlashcardStatsDisplay();
3252
- updateFlashcardProgressChart();
3253
  }
3254
 
3255
- // Mettre à jour l'affichage des statistiques
3256
- function updateFlashcardStatsDisplay() {
3257
- document.getElementById('streakCount').textContent = flashcardStats.streak;
3258
- document.getElementById('statsTotalCards').textContent = flashcards.length;
3259
- document.getElementById('statsMastered').textContent = flashcards.filter(c => c.mastered).length;
3260
- document.getElementById('statsLearning').textContent = flashcards.filter(c => !c.mastered).length;
3261
- document.getElementById('statsDue').textContent = flashcards.filter(c => new Date(c.nextReview) <= new Date()).length;
3262
  }
3263
 
3264
- // Ajouter une nouvelle flashcard
3265
- function addNewFlashcard() {
3266
- const question = document.getElementById('newQuestion').value;
3267
- const answer = document.getElementById('newAnswer').value;
3268
- const category = document.getElementById('newCategory').value;
3269
- const difficulty = document.getElementById('newDifficulty').value;
3270
-
3271
- if (!question || !answer) {
3272
- showNotification('Veuillez entrer une question et une réponse', 'warning');
3273
- return;
 
 
3274
  }
 
 
 
 
 
3275
 
3276
- const newCard = {
3277
- id: flashcards.length + 1,
3278
- question: question,
3279
- answer: answer,
3280
- explanation: 'Nouvelle carte à apprendre',
3281
- category: category,
3282
- difficulty: difficulty,
3283
- score: 50,
3284
- mastered: false,
3285
- nextReview: new Date()
3286
- };
3287
-
3288
- flashcards.push(newCard);
3289
-
3290
- // Réinitialiser le formulaire
3291
- document.getElementById('newQuestion').value = '';
3292
- document.getElementById('newAnswer').value = '';
 
 
 
 
3293
 
3294
- // Mettre à jour l'affichage
3295
- updateFlashcardStats();
 
 
 
 
 
 
 
3296
 
3297
- // Afficher la nouvelle carte
3298
- currentFlashcardIndex = flashcards.length - 1;
3299
- displayFlashcard(currentFlashcardIndex);
3300
 
3301
- showNotification('Flashcard ajoutée avec succès !', 'success');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3302
  }
3303
 
3304
- // Créer le graphique de progression des flashcards
3305
- function updateFlashcardProgressChart() {
3306
- const ctx = document.getElementById('flashcardProgressChart').getContext('2d');
3307
 
3308
- if (window.flashcardProgressChart) {
3309
- window.flashcardProgressChart.destroy();
3310
- }
 
 
 
 
 
 
 
 
 
 
3311
 
3312
- const mastered = flashcards.filter(c => c.mastered).length;
3313
- const learning = flashcards.filter(c => !c.mastered).length;
 
 
 
 
 
 
 
3314
 
3315
- window.flashcardProgressChart = new Chart(ctx, {
3316
- type: 'doughnut',
3317
- data: {
3318
- labels: ['Maîtrisées', 'En Apprentissage'],
3319
- datasets: [{
3320
- data: [mastered, learning],
3321
- backgroundColor: ['#10b981', '#f59e0b'],
3322
- borderWidth: 2,
3323
- borderColor: 'white'
3324
- }]
3325
- },
3326
- options: {
3327
- responsive: true,
3328
- maintainAspectRatio: false,
3329
- plugins: {
3330
- legend: {
3331
- position: 'bottom'
3332
- }
3333
- },
3334
- cutout: '60%'
3335
  }
3336
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3337
  }
3338
 
3339
  // ============================================
@@ -3625,68 +4140,6 @@
3625
  generateHeatmap();
3626
  }
3627
 
3628
- // ============================================
3629
- // APPRENDRE SM-2
3630
- // ============================================
3631
-
3632
- // Mettre à jour le graphique de comparaison
3633
- function updateComparisonChart() {
3634
- const ctx = document.getElementById('comparisonChart').getContext('2d');
3635
-
3636
- if (window.comparisonChart) {
3637
- window.comparisonChart.destroy();
3638
- }
3639
-
3640
- // Données des différents niveaux de qualité
3641
- const intervals = {
3642
- 'Difficulté (N0)': [1, 2, 4, 8, 16, 32],
3643
- 'Moyen (N1)': [1, 3, 7, 14, 30, 60],
3644
- 'Bon (N2)': [2, 7, 16, 35, 70, 140],
3645
- 'Excellent (N3)': [3, 10, 25, 60, 120, 240]
3646
- };
3647
-
3648
- const labels = ['R1', 'R2', 'R3', 'R4', 'R5', 'R6'];
3649
- const colors = ['#ef4444', '#f59e0b', '#10b981', '#3b82f6'];
3650
-
3651
- const datasets = Object.entries(intervals).map(([label, data], index) => ({
3652
- label: label,
3653
- data: data,
3654
- borderColor: colors[index],
3655
- backgroundColor: colors[index] + '20',
3656
- borderWidth: 2,
3657
- tension: 0.4,
3658
- fill: false
3659
- }));
3660
-
3661
- window.comparisonChart = new Chart(ctx, {
3662
- type: 'line',
3663
- data: {
3664
- labels: labels,
3665
- datasets: datasets
3666
- },
3667
- options: {
3668
- responsive: true,
3669
- maintainAspectRatio: false,
3670
- scales: {
3671
- y: {
3672
- beginAtZero: true,
3673
- title: {
3674
- display: true,
3675
- text: 'Intervalle (jours)'
3676
- }
3677
- }
3678
- },
3679
- plugins: {
3680
- title: {
3681
- display: true,
3682
- text: 'Comparaison des Courbes SM-2 par Niveau de Qualité',
3683
- font: { size: 16 }
3684
- }
3685
- }
3686
- }
3687
- });
3688
- }
3689
-
3690
  // ============================================
3691
  // FONCTIONS UTILITAIRES
3692
  // ============================================
@@ -3750,11 +4203,31 @@
3750
  }
3751
 
3752
  // Charger les flashcards
3753
- const savedFlashcards = localStorage.getItem('flashcards');
3754
  if (savedFlashcards) {
3755
- flashcards = JSON.parse(savedFlashcards);
3756
- displayFlashcard(currentFlashcardIndex);
3757
- updateFlashcardStats();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3758
  }
3759
  } catch (error) {
3760
  console.error('Erreur lors du chargement des données:', error);
@@ -3766,15 +4239,18 @@
3766
  try {
3767
  localStorage.setItem('learnerProfile', JSON.stringify(learnerProfile));
3768
  localStorage.setItem('journalEntries', JSON.stringify(journalEntries));
3769
- localStorage.setItem('flashcards', JSON.stringify(flashcards));
3770
- showNotification('Toutes les données ont été sauvegardées', 'success');
3771
  } catch (error) {
3772
- showNotification('Erreur lors de la sauvegarde', 'error');
3773
  }
3774
  }
3775
 
3776
  // Sauvegarder automatiquement toutes les 30 secondes
3777
  setInterval(saveAllData, 30000);
 
 
 
3778
  </script>
3779
  </body>
3780
  </html>
 
821
  font-size: 1.1rem;
822
  }
823
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
824
  /* Productivity Options - STYLE MODIFIÉ */
825
  .productivity-grid {
826
  display: grid;
 
1097
  box-shadow: 0 0 0 3px white, 0 0 0 6px currentColor;
1098
  }
1099
 
1100
+ /* ============================================ */
1101
+ /* STYLES POUR LES FLASHCARDS */
1102
+ /* ============================================ */
1103
+
1104
+ .flashcards-controls {
1105
+ display: flex;
1106
+ justify-content: center;
1107
+ align-items: center;
1108
+ gap: 20px;
1109
+ margin: 2rem 0;
1110
+ padding: 1rem;
1111
  background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
1112
+ border-radius: 12px;
1113
  }
1114
 
1115
+ .flashcard-container {
1116
+ min-height: 400px;
1117
+ perspective: 1000px;
1118
+ margin: 2rem 0;
1119
+ }
1120
+
1121
+ .flashcard {
1122
+ width: 100%;
1123
+ height: 400px;
1124
+ position: relative;
1125
+ transform-style: preserve-3d;
1126
+ transition: transform 0.8s cubic-bezier(0.175, 0.885, 0.32, 1.275);
1127
+ cursor: pointer;
1128
+ }
1129
+
1130
+ .flashcard.flipped {
1131
+ transform: rotateY(180deg);
1132
+ }
1133
+
1134
+ .flashcard-face {
1135
+ position: absolute;
1136
+ width: 100%;
1137
+ height: 100%;
1138
+ backface-visibility: hidden;
1139
+ border-radius: 15px;
1140
+ padding: 2rem;
1141
  display: flex;
1142
+ flex-direction: column;
1143
+ justify-content: center;
1144
  align-items: center;
1145
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
1146
+ overflow: hidden;
1147
  }
1148
 
1149
+ .flashcard-front {
1150
+ background: linear-gradient(135deg, #ffffff 0%, #f1f5f9 100%);
1151
+ border: 2px solid var(--primary-color);
1152
+ }
1153
+
1154
+ .flashcard-back {
1155
+ background: linear-gradient(135deg, var(--primary-color) 0%, #1d4ed8 100%);
1156
  color: white;
1157
+ transform: rotateY(180deg);
1158
+ text-align: center;
1159
+ }
1160
+
1161
+ .flashcard-category {
1162
+ position: absolute;
1163
+ top: 15px;
1164
+ left: 15px;
1165
  padding: 5px 15px;
1166
  border-radius: 20px;
1167
+ font-size: 0.8rem;
1168
+ font-weight: 600;
1169
+ background: rgba(255, 255, 255, 0.2);
1170
+ backdrop-filter: blur(10px);
1171
+ }
1172
+
1173
+ .flashcard-content {
1174
+ max-width: 600px;
1175
+ text-align: center;
1176
+ padding: 2rem;
1177
+ }
1178
+
1179
+ .flashcard-title {
1180
+ font-size: 1.8rem;
1181
+ font-weight: bold;
1182
+ margin-bottom: 1.5rem;
1183
+ color: var(--dark-color);
1184
+ }
1185
+
1186
+ .flashcard-question {
1187
+ font-size: 1.3rem;
1188
+ line-height: 1.6;
1189
+ margin-bottom: 2rem;
1190
+ color: var(--dark-color);
1191
+ }
1192
+
1193
+ .flashcard-back .flashcard-title {
1194
+ color: white;
1195
+ }
1196
+
1197
+ .flashcard-back .flashcard-question {
1198
+ color: rgba(255, 255, 255, 0.9);
1199
+ }
1200
+
1201
+ .flashcard-action {
1202
+ background: white;
1203
+ color: var(--primary-color);
1204
+ border: none;
1205
+ padding: 12px 30px;
1206
+ border-radius: 25px;
1207
+ font-weight: 600;
1208
+ cursor: pointer;
1209
+ margin-top: 1.5rem;
1210
+ transition: all 0.3s;
1211
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
1212
+ }
1213
+
1214
+ .flashcard-action:hover {
1215
+ transform: translateY(-3px);
1216
+ box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
1217
+ }
1218
+
1219
+ .flashcard-instruction {
1220
+ position: absolute;
1221
+ bottom: 15px;
1222
+ left: 0;
1223
+ right: 0;
1224
+ text-align: center;
1225
+ font-size: 0.9rem;
1226
+ color: var(--gray-color);
1227
+ opacity: 0.8;
1228
+ }
1229
+
1230
+ .flashcard-evaluation {
1231
+ margin-top: 2rem;
1232
+ display: flex;
1233
+ flex-direction: column;
1234
+ gap: 1rem;
1235
+ width: 100%;
1236
+ max-width: 400px;
1237
+ }
1238
+
1239
+ .evaluation-slider {
1240
+ width: 100%;
1241
+ -webkit-appearance: none;
1242
+ height: 8px;
1243
+ border-radius: 4px;
1244
+ background: rgba(255, 255, 255, 0.3);
1245
+ outline: none;
1246
+ }
1247
+
1248
+ .evaluation-slider::-webkit-slider-thumb {
1249
+ -webkit-appearance: none;
1250
+ width: 24px;
1251
+ height: 24px;
1252
+ border-radius: 50%;
1253
+ background: white;
1254
+ cursor: pointer;
1255
+ box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
1256
+ }
1257
+
1258
+ .evaluation-label {
1259
+ display: flex;
1260
+ justify-content: space-between;
1261
+ font-size: 0.9rem;
1262
+ color: rgba(255, 255, 255, 0.9);
1263
+ }
1264
+
1265
+ .category-filters {
1266
+ display: flex;
1267
+ flex-wrap: wrap;
1268
+ gap: 10px;
1269
+ margin: 1.5rem 0;
1270
+ justify-content: center;
1271
+ }
1272
+
1273
+ .category-filter {
1274
+ padding: 8px 20px;
1275
+ border: 2px solid #e2e8f0;
1276
+ border-radius: 20px;
1277
+ background: white;
1278
+ cursor: pointer;
1279
+ transition: all 0.3s;
1280
+ font-weight: 500;
1281
+ color: var(--dark-color);
1282
+ }
1283
+
1284
+ .category-filter:hover {
1285
+ border-color: var(--primary-color);
1286
+ color: var(--primary-color);
1287
+ }
1288
+
1289
+ .category-filter.active {
1290
+ background: var(--primary-color);
1291
+ color: white;
1292
+ border-color: var(--primary-color);
1293
+ }
1294
+
1295
+ .flashcard-progress {
1296
+ width: 100%;
1297
+ height: 6px;
1298
+ background: #e2e8f0;
1299
+ border-radius: 3px;
1300
+ margin: 1rem 0;
1301
+ overflow: hidden;
1302
+ }
1303
+
1304
+ .flashcard-progress-bar {
1305
+ height: 100%;
1306
+ background: linear-gradient(90deg, var(--primary-color), var(--accent-color));
1307
+ border-radius: 3px;
1308
+ transition: width 0.3s ease;
1309
+ }
1310
+
1311
+ .dashboardEM-container {
1312
+ background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
1313
+ border-radius: 15px;
1314
+ padding: 2rem;
1315
+ margin-top: 2rem;
1316
+ }
1317
+
1318
+ .dashboardEM-grid {
1319
+ display: grid;
1320
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
1321
+ gap: 20px;
1322
+ margin-top: 1.5rem;
1323
+ }
1324
+
1325
+ .dashboardEM-card {
1326
+ background: white;
1327
+ border-radius: 12px;
1328
+ padding: 1.5rem;
1329
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
1330
+ }
1331
+
1332
+ .dashboardEM-header {
1333
+ display: flex;
1334
+ align-items: center;
1335
+ gap: 10px;
1336
+ margin-bottom: 1rem;
1337
+ padding-bottom: 1rem;
1338
+ border-bottom: 2px solid #f1f5f9;
1339
+ }
1340
+
1341
+ .dashboardEM-icon {
1342
+ width: 40px;
1343
+ height: 40px;
1344
+ border-radius: 10px;
1345
+ display: flex;
1346
+ align-items: center;
1347
+ justify-content: center;
1348
+ font-size: 1.2rem;
1349
+ color: white;
1350
+ }
1351
+
1352
+ .dashboardEM-metric {
1353
+ display: flex;
1354
+ align-items: baseline;
1355
+ gap: 10px;
1356
+ margin: 1rem 0;
1357
+ }
1358
+
1359
+ .dashboardEM-value {
1360
+ font-size: 2.5rem;
1361
  font-weight: bold;
1362
+ color: var(--primary-color);
1363
+ }
1364
+
1365
+ .dashboardEM-change {
1366
+ font-size: 0.9rem;
1367
+ padding: 3px 8px;
1368
+ border-radius: 12px;
1369
+ background: rgba(16, 185, 129, 0.1);
1370
+ color: var(--secondary-color);
1371
+ }
1372
+
1373
+ .dashboardEM-change.negative {
1374
+ background: rgba(239, 68, 68, 0.1);
1375
+ color: var(--danger-color);
1376
+ }
1377
+
1378
+ .dashboardEM-trend {
1379
  display: flex;
1380
  align-items: center;
1381
  gap: 5px;
1382
+ font-size: 0.9rem;
1383
+ color: var(--gray-color);
1384
  }
1385
 
1386
  /* Responsive */
 
1414
  justify-content: center;
1415
  }
1416
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1417
  .heatmap-grid {
1418
  gap: 4px;
1419
  }
 
1433
  .profile-summary {
1434
  grid-template-columns: 1fr;
1435
  }
1436
+
1437
+ .flashcard {
1438
+ height: 350px;
1439
+ }
1440
+
1441
+ .flashcard-title {
1442
+ font-size: 1.5rem;
1443
+ }
1444
+
1445
+ .flashcard-question {
1446
+ font-size: 1.1rem;
1447
+ }
1448
+
1449
+ .flashcards-controls {
1450
+ flex-direction: column;
1451
+ gap: 15px;
1452
+ }
1453
+ }
1454
+
1455
+ @media (max-width: 480px) {
1456
+ .flashcard {
1457
+ height: 300px;
1458
+ }
1459
+
1460
+ .flashcard-content {
1461
+ padding: 1rem;
1462
+ }
1463
+
1464
+ .flashcard-title {
1465
+ font-size: 1.3rem;
1466
+ }
1467
+
1468
+ .flashcard-question {
1469
+ font-size: 1rem;
1470
+ }
1471
  }
1472
  </style>
1473
  </head>
 
1476
  <!-- Header -->
1477
  <header class="header">
1478
  <h1><i class="fas fa-graduation-cap"></i> Compagnon Pédagogique</h1>
1479
+ <p>PerseverAId (AI + Aid + Perseverance)
1480
+ Apprendre à manager l'effort et maintenir la persistance </p>
1481
  <div class="badge">PerseverAId (AI + Aid + Perseverance)</div>
1482
  </header>
1483
 
1484
+ <!-- Navigation - 7 onglets avec Flashcards -->
1485
  <nav class="nav-tabs">
1486
  <button class="nav-tab active" onclick="showTab('profile')">
1487
  <i class="fas fa-user-circle"></i> Profil Apprenant
 
1492
  <button class="nav-tab" onclick="showTab('planner')">
1493
  <i class="fas fa-calendar-alt"></i> Planner SM-2
1494
  </button>
1495
+
 
 
1496
  <button class="nav-tab" onclick="showTab('journal')">
1497
  <i class="fas fa-book"></i> Journal SRL
1498
  </button>
1499
+ <button class="nav-tab" onclick="showTab('flashcards')">
1500
+ <i class="fas fa-layer-group"></i> Métacognition
1501
+ </button>
1502
  <button class="nav-tab" onclick="showTab('notifications')">
1503
  <i class="fas fa-bell"></i> Notifications IA
1504
  </button>
1505
  <button class="nav-tab" onclick="showTab('stats')">
1506
  <i class="fas fa-chart-line"></i> Statistiques
1507
  </button>
 
 
 
1508
  </nav>
1509
 
1510
  <!-- Profil Apprenant Section -->
 
2121
  <section id="flashcards" class="tab-content">
2122
  <div class="card">
2123
  <div class="card-header">
2124
+ <h3><i class="fas fa-layer-group"></i> Flashcards Cognitives - Persévérance & Métacognition</h3>
2125
  <div>
2126
+ <button class="btn btn-secondary" onclick="showCardByCategory('all')">
2127
+ <i class="fas fa-filter"></i> Toutes
2128
+ </button>
2129
+ <button class="btn btn-secondary" onclick="resetFlashcards()">
2130
+ <i class="fas fa-redo"></i> Réinitialiser
2131
+ </button>
2132
  </div>
2133
  </div>
2134
 
2135
+ <!-- Statistiques des flashcards -->
2136
+ <div id="flashcardsStats" class="stats-grid">
2137
+ <!-- Généré dynamiquement -->
2138
+ </div>
2139
+
2140
+ <!-- Filtres par catégorie -->
2141
+ <div class="category-filters">
2142
+ <div class="category-filter active" onclick="showCardByCategory('all')">
2143
+ <i class="fas fa-layer-group"></i> Toutes
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2144
  </div>
2145
+ <div class="category-filter" onclick="showCardByCategory('awareness')">
2146
+ <i class="fas fa-eye"></i> Prise de conscience
 
 
 
 
 
 
 
 
 
2147
  </div>
2148
+ <div class="category-filter" onclick="showCardByCategory('perseverance')">
2149
+ <i class="fas fa-mountain"></i> Persévérance
 
 
 
 
2150
  </div>
2151
+ <div class="category-filter" onclick="showCardByCategory('effort')">
2152
+ <i class="fas fa-bolt"></i> Gestion de l'effort
2153
+ </div>
2154
+ <div class="category-filter" onclick="showCardByCategory('strategies')">
2155
+ <i class="fas fa-tools"></i> Stratégies d'adaptation
2156
+ </div>
2157
+ <div class="category-filter" onclick="showCardByCategory('motivation')">
2158
+ <i class="fas fa-fire"></i> Motivation & Sens
2159
+ </div>
2160
+ <div class="category-filter" onclick="showCardByCategory('evaluation')">
2161
+ <i class="fas fa-star"></i> Auto-évaluation
2162
+ </div>
2163
+ </div>
2164
+
2165
+ <!-- Contrôles de navigation -->
2166
+ <div class="flashcards-controls">
2167
+ <button class="btn" onclick="prevCard()" id="prevBtn">
2168
+ <i class="fas fa-chevron-left"></i> Précédente
2169
+ </button>
2170
+ <div style="display: flex; flex-direction: column; align-items: center;">
2171
+ <span id="cardCounter" style="font-weight: 600; color: var(--dark-color);">
2172
+ Carte 1/20
2173
+ </span>
2174
+ <div class="flashcard-progress">
2175
+ <div class="flashcard-progress-bar" id="flashcardProgressBar" style="width: 5%"></div>
 
 
 
 
 
 
2176
  </div>
2177
+ </div>
2178
+ <button class="btn" onclick="nextCard()" id="nextBtn">
2179
+ Suivante <i class="fas fa-chevron-right"></i>
2180
+ </button>
2181
+ </div>
2182
+
2183
+ <!-- Carte actuelle -->
2184
+ <div id="currentCard" class="flashcard-container">
2185
+ <!-- Contenu généré dynamiquement -->
2186
+ </div>
2187
+
2188
+ <!-- DashboardEM -->
2189
+ <div class="dashboardEM-container">
2190
+ <h4><i class="fas fa-chart-bar"></i> DashboardEM - Métriques Métacognitives</h4>
2191
+ <div id="dashboardEM" class="dashboardEM-grid">
2192
+ <!-- Généré dynamiquement -->
2193
  </div>
2194
  </div>
2195
  </div>
 
2385
  </div>
2386
  </div>
2387
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2388
  </div>
2389
  </section>
2390
  </div>
 
2421
  }
2422
  };
2423
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2424
  // Variables pour le planner
2425
  let selectedTimeSlots = ['morning'];
2426
  let currentQuality = 2;
 
2433
  // Variables pour le journal
2434
  let journalEntries = [];
2435
 
2436
+ // Variables pour les flashcards
2437
+ let flashcards = [];
2438
+ let currentCardIndex = 0;
2439
+ let currentCategory = 'all';
2440
+ let flashcardsData = [];
2441
+ let flashcardsStats = {
2442
+ totalCards: 0,
2443
+ reviewedCards: 0,
2444
+ averageScore: 0,
2445
+ favoriteCategory: ''
2446
+ };
2447
+
2448
  // ============================================
2449
  // INITIALISATION
2450
  // ============================================
 
2455
  updateProfileSummary();
2456
  createMotivationChart();
2457
 
 
 
 
 
 
2458
  // Initialiser la heatmap
2459
  generateHeatmap();
2460
 
 
 
 
2461
  // Initialiser le graphique des notifications
2462
  createNotificationChart();
2463
 
2464
+ // Initialiser les flashcards
2465
+ initializeFlashcards();
2466
+
2467
  // Charger les données sauvegardées
2468
  loadSavedData();
2469
  });
 
2494
  'flashcards': 'Flashcards',
2495
  'journal': 'Journal',
2496
  'notifications': 'Notifications',
2497
+ 'stats': 'Statistiques'
 
2498
  };
2499
 
2500
  document.querySelectorAll('.nav-tab').forEach(tab => {
 
2507
  if (tabId === 'stats') {
2508
  refreshStats();
2509
  generateHeatmap();
2510
+ } else if (tabId === 'flashcards') {
2511
+ updateFlashcardsStats();
2512
+ updateDashboardEM();
2513
  }
2514
  }
2515
 
 
3053
  container.appendChild(card);
3054
  });
3055
 
3056
+ // Visualisation
3057
+ createSM2Visualization(intervals, plan[0]?.competence || 'Compétence');
3058
+ }
3059
+
3060
+ // Créer la visualisation SM-2
3061
+ function createSM2Visualization(intervals, competence) {
3062
+ const ctx = document.getElementById('sm2Visualization').getContext('2d');
3063
+
3064
+ if (window.sm2VisualizationChart) {
3065
+ window.sm2VisualizationChart.destroy();
3066
+ }
3067
+
3068
+ const labels = intervals.map((_, i) => `Répétition ${i + 1}`);
3069
+
3070
+ window.sm2VisualizationChart = new Chart(ctx, {
3071
+ type: 'line',
3072
+ data: {
3073
+ labels: labels,
3074
+ datasets: [{
3075
+ label: 'Intervalle (jours)',
3076
+ data: intervals,
3077
+ borderColor: '#3b82f6',
3078
+ backgroundColor: 'rgba(59, 130, 246, 0.1)',
3079
+ borderWidth: 3,
3080
+ fill: true,
3081
+ tension: 0.4
3082
+ }]
3083
+ },
3084
+ options: {
3085
+ responsive: true,
3086
+ maintainAspectRatio: false,
3087
+ plugins: {
3088
+ title: {
3089
+ display: true,
3090
+ text: `Courbe de Répétition Espacée - ${competence}`,
3091
+ font: { size: 16 }
3092
+ }
3093
+ },
3094
+ scales: {
3095
+ y: {
3096
+ beginAtZero: true,
3097
+ title: {
3098
+ display: true,
3099
+ text: 'Jours'
3100
+ }
3101
+ },
3102
+ x: {
3103
+ title: {
3104
+ display: true,
3105
+ text: 'Numéro de Répétition'
3106
+ }
3107
+ }
3108
+ }
3109
+ }
3110
+ });
3111
+ }
3112
+
3113
+ // Exporter le planner
3114
+ function exportPlanner() {
3115
+ const plannerData = document.getElementById('plannerContent').innerText;
3116
+ const blob = new Blob([plannerData], { type: 'text/plain' });
3117
+ const url = URL.createObjectURL(blob);
3118
+ const a = document.createElement('a');
3119
+ a.href = url;
3120
+ a.download = 'planner-sm2.txt';
3121
+ document.body.appendChild(a);
3122
+ a.click();
3123
+ document.body.removeChild(a);
3124
+ URL.revokeObjectURL(url);
3125
+
3126
+ showNotification('Planner exporté avec succès !', 'success');
3127
+ }
3128
+
3129
+ // ============================================
3130
+ // FLASHCARDS COGNITIVES
3131
+ // ============================================
3132
+
3133
+ // Initialiser les flashcards
3134
+ function initializeFlashcards() {
3135
+ // Données des flashcards basées sur les catégories proposées
3136
+ flashcardsData = [
3137
+ {
3138
+ id: 1,
3139
+ category: 'awareness',
3140
+ categoryName: 'Prise de conscience',
3141
+ icon: '👁️',
3142
+ color: '#3b82f6',
3143
+ front: {
3144
+ title: 'Diagnostic de Blocage',
3145
+ question: 'Qu\'est-ce qui me bloque exactement dans cette tâche ?'
3146
+ },
3147
+ back: {
3148
+ reflection: 'Est-ce un problème de compréhension, d\'énergie, ou de motivation ?',
3149
+ action: 'Identifier précisément le type d\'obstacle rencontré',
3150
+ evaluationLabel: 'Clarté du diagnostic'
3151
+ }
3152
+ },
3153
+ {
3154
+ id: 2,
3155
+ category: 'awareness',
3156
+ categoryName: 'Prise de conscience',
3157
+ icon: '💭',
3158
+ color: '#3b82f6',
3159
+ front: {
3160
+ title: 'État Émotionnel',
3161
+ question: 'Comment je me sens en ce moment face à cette tâche ?'
3162
+ },
3163
+ back: {
3164
+ reflection: 'Mon état émotionnel influence-t-il ma capacité à apprendre ?',
3165
+ action: 'Nommer l\'émotion et accepter sa présence',
3166
+ evaluationLabel: 'Conscience émotionnelle'
3167
+ }
3168
+ },
3169
+ {
3170
+ id: 3,
3171
+ category: 'perseverance',
3172
+ categoryName: 'Persévérance',
3173
+ icon: '🏔️',
3174
+ color: '#10b981',
3175
+ front: {
3176
+ title: 'Face à la Difficulté',
3177
+ question: 'Cette difficulté signifie-t-elle que je suis incapable ?'
3178
+ },
3179
+ back: {
3180
+ reflection: 'Ai-je déjà surmonté une difficulté similaire par le passé ?',
3181
+ action: 'Se rappeler un succès passé pour renforcer la confiance',
3182
+ evaluationLabel: 'Résilience perçue'
3183
+ }
3184
+ },
3185
+ {
3186
+ id: 4,
3187
+ category: 'perseverance',
3188
+ categoryName: 'Persévérance',
3189
+ icon: '⏳',
3190
+ color: '#10b981',
3191
+ front: {
3192
+ title: 'Test de Persistance',
3193
+ question: 'Que se passerait-il si je continuais encore 10 minutes ?'
3194
+ },
3195
+ back: {
3196
+ reflection: 'Le pire scénario est-il vraiment si grave ?',
3197
+ action: 'Se donner un objectif minimal de 10 minutes supplémentaires',
3198
+ evaluationLabel: 'Volonté de persister'
3199
+ }
3200
+ },
3201
+ {
3202
+ id: 5,
3203
+ category: 'effort',
3204
+ categoryName: 'Gestion de l\'effort',
3205
+ icon: '⚡',
3206
+ color: '#f59e0b',
3207
+ front: {
3208
+ title: 'Niveau d\'Énergie',
3209
+ question: 'Mon niveau d\'énergie est-il adapté à cette tâche ?'
3210
+ },
3211
+ back: {
3212
+ reflection: 'Ai-je besoin d\'une pause ou d\'un changement d\'activité ?',
3213
+ action: 'Adapter la tâche à son niveau d\'énergie actuel',
3214
+ evaluationLabel: 'Gestion énergétique'
3215
+ }
3216
+ },
3217
+ {
3218
+ id: 6,
3219
+ category: 'effort',
3220
+ categoryName: 'Gestion de l\'effort',
3221
+ icon: '🎯',
3222
+ color: '#f59e0b',
3223
+ front: {
3224
+ title: 'Effort Productif',
3225
+ question: 'Mon effort actuel est-il concentré et efficace ?'
3226
+ },
3227
+ back: {
3228
+ reflection: 'Est-ce que je travaille "dur" ou "intelligemment" ?',
3229
+ action: 'Identifier et éliminer une source de distraction',
3230
+ evaluationLabel: 'Efficacité de l\'effort'
3231
+ }
3232
+ },
3233
+ {
3234
+ id: 7,
3235
+ category: 'strategies',
3236
+ categoryName: 'Stratégies d\'adaptation',
3237
+ icon: '🔧',
3238
+ color: '#8b5cf6',
3239
+ front: {
3240
+ title: 'Découpage de Tâche',
3241
+ question: 'Cette tâche peut-elle être divisée en sous-tâches plus petites ?'
3242
+ },
3243
+ back: {
3244
+ reflection: 'Quelle est la plus petite action réalisable maintenant ?',
3245
+ action: 'Définir une micro-tâche de 5 minutes maximum',
3246
+ evaluationLabel: 'Capacité à découper'
3247
+ }
3248
+ },
3249
+ {
3250
+ id: 8,
3251
+ category: 'strategies',
3252
+ categoryName: 'Stratégies d\'adaptation',
3253
+ icon: '🔄',
3254
+ color: '#8b5cf6',
3255
+ front: {
3256
+ title: 'Changement de Modalité',
3257
+ question: 'Et si j\'essayais une approche différente ?'
3258
+ },
3259
+ back: {
3260
+ reflection: 'Quelle autre méthode d\'apprentissage pourrais-je tester ?',
3261
+ action: 'Changer de support (écrit/oral/visuel)',
3262
+ evaluationLabel: 'Flexibilité stratégique'
3263
+ }
3264
+ },
3265
+ {
3266
+ id: 9,
3267
+ category: 'motivation',
3268
+ categoryName: 'Motivation & Sens',
3269
+ icon: '🌟',
3270
+ color: '#ec4899',
3271
+ front: {
3272
+ title: 'Sens de l\'Apprentissage',
3273
+ question: 'Pourquoi cette tâche est-elle importante pour moi ?'
3274
+ },
3275
+ back: {
3276
+ reflection: 'Quel bénéfice à long terme vais-je en retirer ?',
3277
+ action: 'Écrire une raison personnelle de persévérer',
3278
+ evaluationLabel: 'Clarté du sens'
3279
+ }
3280
+ },
3281
+ {
3282
+ id: 10,
3283
+ category: 'motivation',
3284
+ categoryName: 'Motivation & Sens',
3285
+ icon: '🎁',
3286
+ color: '#ec4899',
3287
+ front: {
3288
+ title: 'Récompense Future',
3289
+ question: 'Que vais-je ressentir une fois cette tâche terminée ?'
3290
+ },
3291
+ back: {
3292
+ reflection: 'La satisfaction d\'avoir persévéré vaut-elle l\'effort ?',
3293
+ action: 'Visualiser le sentiment de réussite',
3294
+ evaluationLabel: 'Motivation anticipée'
3295
+ }
3296
+ },
3297
+ {
3298
+ id: 11,
3299
+ category: 'evaluation',
3300
+ categoryName: 'Auto-évaluation',
3301
+ icon: '📊',
3302
+ color: '#6366f1',
3303
+ front: {
3304
+ title: 'Bilan Partiel',
3305
+ question: 'Qu\'ai-je réussi à accomplir, même partiellement ?'
3306
+ },
3307
+ back: {
3308
+ reflection: 'Quels progrès, aussi minimes soient-ils, puis-je identifier ?',
3309
+ action: 'Lister 3 petites victoires',
3310
+ evaluationLabel: 'Reconnaissance des progrès'
3311
+ }
3312
+ },
3313
+ {
3314
+ id: 12,
3315
+ category: 'evaluation',
3316
+ categoryName: 'Auto-évaluation',
3317
+ icon: '🔍',
3318
+ color: '#6366f1',
3319
+ front: {
3320
+ title: 'Apprentissage de l\'Expérience',
3321
+ question: 'Qu\'est-ce que cette difficulté m\'apprend sur ma façon d\'apprendre ?'
3322
+ },
3323
+ back: {
3324
+ reflection: 'Que pourrai-je faire différemment la prochaine fois ?',
3325
+ action: 'Noter un insight métacognitif',
3326
+ evaluationLabel: 'Apprentissage réflexif'
3327
+ }
3328
+ },
3329
+ {
3330
+ id: 13,
3331
+ category: 'awareness',
3332
+ categoryName: 'Prise de conscience',
3333
+ icon: '🧠',
3334
+ color: '#3b82f6',
3335
+ front: {
3336
+ title: 'Focus Attentionnel',
3337
+ question: 'Où se porte actuellement mon attention ?'
3338
+ },
3339
+ back: {
3340
+ reflection: 'Suis-je pleinement présent à la tâche ou mon esprit vagabonde-t-il ?',
3341
+ action: 'Pratiquer 1 minute de pleine conscience',
3342
+ evaluationLabel: 'Présence attentionnelle'
3343
+ }
3344
+ },
3345
+ {
3346
+ id: 14,
3347
+ category: 'perseverance',
3348
+ categoryName: 'Persévérance',
3349
+ icon: '🛡️',
3350
+ color: '#10b981',
3351
+ front: {
3352
+ title: 'Protection contre l\'Abandon',
3353
+ question: 'Quelle est ma première pensée quand je veux abandonner ?'
3354
+ },
3355
+ back: {
3356
+ reflection: 'Cette pensée est-elle un fait ou une interprétation ?',
3357
+ action: 'Reformuler la pensée de manière constructive',
3358
+ evaluationLabel: 'Contrôle des pensées'
3359
+ }
3360
+ },
3361
+ {
3362
+ id: 15,
3363
+ category: 'effort',
3364
+ categoryName: 'Gestion de l\'effort',
3365
+ icon: '⏰',
3366
+ color: '#f59e0b',
3367
+ front: {
3368
+ title: 'Rythme de Travail',
3369
+ question: 'Mon rythme actuel est-il soutenable sur la durée ?'
3370
+ },
3371
+ back: {
3372
+ reflection: 'Ai-je besoin d\'accélérer, de ralentir ou de maintenir ?',
3373
+ action: 'Ajuster le tempo pour éviter l\'épuisement',
3374
+ evaluationLabel: 'Régulation du rythme'
3375
+ }
3376
+ },
3377
+ {
3378
+ id: 16,
3379
+ category: 'strategies',
3380
+ categoryName: 'Stratégies d\'adaptation',
3381
+ icon: '🤝',
3382
+ color: '#8b5cf6',
3383
+ front: {
3384
+ title: 'Demande d\'Aide',
3385
+ question: 'Ai-je besoin d\'aide pour surmonter cet obstacle ?'
3386
+ },
3387
+ back: {
3388
+ reflection: 'Qui ou quoi pourrait m\'aider à avancer ?',
3389
+ action: 'Identifier une ressource ou une personne aidante',
3390
+ evaluationLabel: 'Ouverture à l\'aide'
3391
+ }
3392
+ },
3393
+ {
3394
+ id: 17,
3395
+ category: 'motivation',
3396
+ categoryName: 'Motivation & Sens',
3397
+ icon: '🎯',
3398
+ color: '#ec4899',
3399
+ front: {
3400
+ title: 'Alignement avec les Valeurs',
3401
+ question: 'En quoi cette tâche est-elle alignée avec mes valeurs ?'
3402
+ },
3403
+ back: {
3404
+ reflection: 'Quelle valeur personnelle cette tâche sert-elle ?',
3405
+ action: 'Relier la tâche à une valeur fondamentale',
3406
+ evaluationLabel: 'Alignement valeurs-tâche'
3407
+ }
3408
+ },
3409
+ {
3410
+ id: 18,
3411
+ category: 'evaluation',
3412
+ categoryName: 'Auto-évaluation',
3413
+ icon: '📈',
3414
+ color: '#6366f1',
3415
+ front: {
3416
+ title: 'Progression Relative',
3417
+ question: 'Où en étais-je il y a une semaine par rapport à maintenant ?'
3418
+ },
3419
+ back: {
3420
+ reflection: 'Quels progrès, même invisibles, ai-je réalisés ?',
3421
+ action: 'Identifier un aspect où l\'on s\'est amélioré',
3422
+ evaluationLabel: 'Conscience des progrès'
3423
+ }
3424
+ },
3425
+ {
3426
+ id: 19,
3427
+ category: 'perseverance',
3428
+ categoryName: 'Persévérance',
3429
+ icon: '🌱',
3430
+ color: '#10b981',
3431
+ front: {
3432
+ title: 'Mentalité de Croissance',
3433
+ question: 'Cette difficulté est-elle une menace ou une opportunité d\'apprentissage ?'
3434
+ },
3435
+ back: {
3436
+ reflection: 'Quelle compétence cette difficulté m\'aide-t-elle à développer ?',
3437
+ action: 'Reconceptualiser l\'obstacle comme défi formateur',
3438
+ evaluationLabel: 'Growth mindset'
3439
+ }
3440
+ },
3441
+ {
3442
+ id: 20,
3443
+ category: 'strategies',
3444
+ categoryName: 'Stratégies d\'adaptation',
3445
+ icon: '🎭',
3446
+ color: '#8b5cf6',
3447
+ front: {
3448
+ title: 'Changement de Perspective',
3449
+ question: 'Comment quelqu\'un que j\'admire aborderait-il cette situation ?'
3450
+ },
3451
+ back: {
3452
+ reflection: 'Quelle stratégie différente puis-je emprunter ?',
3453
+ action: 'Adopter temporairement une autre perspective',
3454
+ evaluationLabel: 'Créativité stratégique'
3455
+ }
3456
+ }
3457
+ ];
3458
+
3459
+ // Initialiser les stats
3460
+ flashcardsStats.totalCards = flashcardsData.length;
3461
+ flashcardsStats.reviewedCards = 0;
3462
+ flashcardsStats.averageScore = 0;
3463
+
3464
+ // Afficher la première carte
3465
+ showCardByCategory('all');
3466
  }
3467
 
3468
+ // Afficher une carte par catégorie
3469
+ function showCardByCategory(category) {
3470
+ currentCategory = category;
3471
+ currentCardIndex = 0;
3472
 
3473
+ // Mettre à jour les filtres
3474
+ document.querySelectorAll('.category-filter').forEach(filter => {
3475
+ filter.classList.remove('active');
3476
+ });
3477
+ document.querySelector(`.category-filter[onclick*="${category}"]`).classList.add('active');
3478
+
3479
+ // Filtrer les cartes par catégorie
3480
+ if (category === 'all') {
3481
+ flashcards = [...flashcardsData];
3482
+ } else {
3483
+ flashcards = flashcardsData.filter(card => card.category === category);
3484
  }
3485
 
3486
+ // Mélanger les cartes
3487
+ shuffleArray(flashcards);
3488
 
3489
+ // Afficher la première carte
3490
+ displayCurrentCard();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3491
 
3492
+ // Mettre à jour les stats
3493
+ updateFlashcardsStats();
3494
  }
3495
 
3496
+ // Mélanger un tableau
3497
+ function shuffleArray(array) {
3498
+ for (let i = array.length - 1; i > 0; i--) {
3499
+ const j = Math.floor(Math.random() * (i + 1));
3500
+ [array[i], array[j]] = [array[j], array[i]];
3501
+ }
3502
+ return array;
3503
+ }
3504
 
3505
+ // Afficher la carte actuelle
3506
+ function displayCurrentCard() {
3507
+ if (flashcards.length === 0) {
3508
+ document.getElementById('currentCard').innerHTML = `
3509
+ <div style="text-align: center; padding: 4rem; color: var(--gray-color);">
3510
+ <i class="fas fa-inbox" style="font-size: 3rem; margin-bottom: 1rem;"></i>
3511
+ <h3>Aucune carte disponible dans cette catégorie</h3>
3512
+ <p>Essayez une autre catégorie ou réinitialisez les cartes</p>
3513
+ </div>
3514
+ `;
3515
+ return;
3516
+ }
3517
+
3518
+ const card = flashcards[currentCardIndex];
3519
+ const progress = ((currentCardIndex + 1) / flashcards.length * 100).toFixed(1);
3520
 
3521
+ document.getElementById('currentCard').innerHTML = `
3522
+ <div class="flashcard" id="flashcard" onclick="flipCard()">
3523
+ <div class="flashcard-face flashcard-front">
3524
+ <div class="flashcard-category" style="background: ${card.color}22; color: ${card.color};">
3525
+ ${card.icon} ${card.categoryName}
3526
+ </div>
3527
+ <div class="flashcard-content">
3528
+ <div class="flashcard-title">${card.front.title}</div>
3529
+ <div class="flashcard-question">${card.front.question}</div>
3530
+ <div class="flashcard-instruction">
3531
+ <i class="fas fa-hand-point-up"></i> Cliquez pour retourner la carte
3532
+ </div>
3533
+ </div>
3534
+ </div>
3535
+ <div class="flashcard-face flashcard-back" style="background: linear-gradient(135deg, ${card.color}, ${darkenColor(card.color, 20)});">
3536
+ <div class="flashcard-content">
3537
+ <div class="flashcard-title">${card.front.title}</div>
3538
+ <div class="flashcard-question">${card.back.reflection}</div>
3539
+
3540
+ <div style="margin: 2rem 0; padding: 1.5rem; background: rgba(255, 255, 255, 0.1); border-radius: 10px;">
3541
+ <div style="font-weight: bold; margin-bottom: 0.5rem;">Action proposée :</div>
3542
+ <div>${card.back.action}</div>
3543
+ </div>
3544
+
3545
+ <div class="flashcard-evaluation">
3546
+ <div style="font-weight: bold; margin-bottom: 0.5rem;">${card.back.evaluationLabel} (1-5) :</div>
3547
+ <input type="range" min="1" max="5" value="3" class="evaluation-slider" id="evaluationSlider">
3548
+ <div class="evaluation-label">
3549
+ <span>Faible</span>
3550
+ <span>Élevé</span>
3551
+ </div>
3552
+ <button class="flashcard-action" onclick="saveEvaluation(event)">
3553
+ <i class="fas fa-save"></i> Enregistrer et continuer
3554
+ </button>
3555
+ </div>
3556
+ </div>
3557
+ </div>
3558
+ </div>
3559
+ `;
3560
 
3561
+ // Mettre à jour le compteur et la barre de progression
3562
+ document.getElementById('cardCounter').textContent = `Carte ${currentCardIndex + 1}/${flashcards.length}`;
3563
+ document.getElementById('flashcardProgressBar').style.width = `${progress}%`;
 
3564
 
3565
+ // Gérer les boutons de navigation
3566
+ document.getElementById('prevBtn').disabled = currentCardIndex === 0;
3567
+ document.getElementById('nextBtn').disabled = currentCardIndex === flashcards.length - 1;
3568
+ }
3569
+
3570
+ // Fonction pour assombrir une couleur
3571
+ function darkenColor(color, percent) {
3572
+ const num = parseInt(color.replace("#", ""), 16);
3573
+ const amt = Math.round(2.55 * percent);
3574
+ const R = (num >> 16) - amt;
3575
+ const G = (num >> 8 & 0x00FF) - amt;
3576
+ const B = (num & 0x0000FF) - amt;
3577
+ return "#" + (0x1000000 + (R < 255 ? R < 1 ? 0 : R : 255) * 0x10000 +
3578
+ (G < 255 ? G < 1 ? 0 : G : 255) * 0x100 +
3579
+ (B < 255 ? B < 1 ? 0 : B : 255)).toString(16).slice(1);
3580
  }
3581
 
3582
  // Retourner la carte
3583
  function flipCard() {
3584
+ const flashcard = document.getElementById('flashcard');
3585
+ if (flashcard) {
3586
+ flashcard.classList.toggle('flipped');
 
 
 
 
 
 
 
 
3587
  }
3588
  }
3589
 
3590
+ // Sauvegarder l'évaluation
3591
+ function saveEvaluation(event) {
3592
+ event.stopPropagation();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3593
 
3594
+ const slider = document.getElementById('evaluationSlider');
3595
+ const score = parseInt(slider.value);
3596
+ const card = flashcards[currentCardIndex];
3597
 
3598
+ // Sauvegarder l'évaluation
3599
+ if (!card.evaluations) {
3600
+ card.evaluations = [];
3601
+ }
3602
+ card.evaluations.push({
3603
+ score: score,
3604
+ date: new Date().toISOString(),
3605
+ category: card.category
3606
+ });
3607
 
3608
+ // Mettre à jour les stats
3609
+ flashcardsStats.reviewedCards++;
 
3610
 
3611
+ // Calculer la moyenne
3612
+ const totalScores = flashcardsData.reduce((sum, card) => {
3613
+ if (card.evaluations && card.evaluations.length > 0) {
3614
+ return sum + card.evaluations[card.evaluations.length - 1].score;
3615
+ }
3616
+ return sum;
3617
+ }, 0);
3618
 
3619
+ const reviewedWithScores = flashcardsData.filter(card =>
3620
+ card.evaluations && card.evaluations.length > 0
3621
+ ).length;
3622
 
3623
+ flashcardsStats.averageScore = reviewedWithScores > 0
3624
+ ? (totalScores / reviewedWithScores).toFixed(1)
3625
+ : 0;
3626
 
3627
  // Passer à la carte suivante
3628
  nextCard();
 
 
 
 
 
3629
 
3630
+ // Mettre à jour le dashboard
3631
+ updateDashboardEM();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3632
 
3633
+ showNotification('Évaluation enregistrée !', 'success');
 
3634
  }
3635
 
3636
+ // Carte précédente
3637
+ function prevCard() {
3638
+ if (currentCardIndex > 0) {
3639
+ currentCardIndex--;
3640
+ displayCurrentCard();
3641
+ }
 
3642
  }
3643
 
3644
+ // Carte suivante
3645
+ function nextCard() {
3646
+ if (currentCardIndex < flashcards.length - 1) {
3647
+ currentCardIndex++;
3648
+ displayCurrentCard();
3649
+ } else {
3650
+ // Revenir au début ou afficher un message
3651
+ if (confirm('Vous avez terminé toutes les cartes de cette catégorie. Voulez-vous recommencer ?')) {
3652
+ currentCardIndex = 0;
3653
+ shuffleArray(flashcards);
3654
+ displayCurrentCard();
3655
+ }
3656
  }
3657
+ }
3658
+
3659
+ // Mettre à jour les statistiques des flashcards
3660
+ function updateFlashcardsStats() {
3661
+ const statsContainer = document.getElementById('flashcardsStats');
3662
 
3663
+ // Calculer les stats par catégorie
3664
+ const categoryStats = {};
3665
+ flashcardsData.forEach(card => {
3666
+ if (!categoryStats[card.category]) {
3667
+ categoryStats[card.category] = {
3668
+ name: card.categoryName,
3669
+ count: 0,
3670
+ reviewed: 0,
3671
+ avgScore: 0
3672
+ };
3673
+ }
3674
+ categoryStats[card.category].count++;
3675
+
3676
+ if (card.evaluations && card.evaluations.length > 0) {
3677
+ categoryStats[card.category].reviewed++;
3678
+ const lastScore = card.evaluations[card.evaluations.length - 1].score;
3679
+ categoryStats[card.category].avgScore =
3680
+ ((categoryStats[card.category].avgScore * (categoryStats[card.category].reviewed - 1) + lastScore) /
3681
+ categoryStats[card.category].reviewed).toFixed(1);
3682
+ }
3683
+ });
3684
 
3685
+ // Trouver la catégorie préférée (avec le plus d'évaluations)
3686
+ let favoriteCategory = '';
3687
+ let maxReviewed = 0;
3688
+ Object.keys(categoryStats).forEach(cat => {
3689
+ if (categoryStats[cat].reviewed > maxReviewed) {
3690
+ maxReviewed = categoryStats[cat].reviewed;
3691
+ favoriteCategory = categoryStats[cat].name;
3692
+ }
3693
+ });
3694
 
3695
+ flashcardsStats.favoriteCategory = favoriteCategory || 'Aucune';
 
 
3696
 
3697
+ statsContainer.innerHTML = `
3698
+ <div class="stat-card">
3699
+ <div class="stat-value">${flashcardsStats.totalCards}</div>
3700
+ <div class="stat-label">Cartes disponibles</div>
3701
+ </div>
3702
+ <div class="stat-card">
3703
+ <div class="stat-value">${flashcardsStats.reviewedCards}</div>
3704
+ <div class="stat-label">Cartes consultées</div>
3705
+ </div>
3706
+ <div class="stat-card">
3707
+ <div class="stat-value">${flashcardsStats.averageScore}/5</div>
3708
+ <div class="stat-label">Score moyen</div>
3709
+ </div>
3710
+ <div class="stat-card">
3711
+ <div class="stat-value">${flashcardsStats.favoriteCategory}</div>
3712
+ <div class="stat-label">Catégorie préférée</div>
3713
+ </div>
3714
+ `;
3715
  }
3716
 
3717
+ // Mettre à jour le DashboardEM
3718
+ function updateDashboardEM() {
3719
+ const dashboardContainer = document.getElementById('dashboardEM');
3720
 
3721
+ // Calculer les métriques
3722
+ const totalEvaluations = flashcardsData.reduce((sum, card) =>
3723
+ sum + (card.evaluations ? card.evaluations.length : 0), 0);
3724
+
3725
+ const today = new Date().toISOString().split('T')[0];
3726
+ const evaluationsToday = flashcardsData.reduce((sum, card) => {
3727
+ if (card.evaluations) {
3728
+ return sum + card.evaluations.filter(eval =>
3729
+ eval.date.split('T')[0] === today
3730
+ ).length;
3731
+ }
3732
+ return sum;
3733
+ }, 0);
3734
 
3735
+ // Calculer la persévérance (moyenne des scores des cartes persévérance)
3736
+ const perseveranceCards = flashcardsData.filter(card => card.category === 'perseverance');
3737
+ const perseveranceScore = perseveranceCards.length > 0 ?
3738
+ perseveranceCards.reduce((sum, card) => {
3739
+ if (card.evaluations && card.evaluations.length > 0) {
3740
+ return sum + card.evaluations[card.evaluations.length - 1].score;
3741
+ }
3742
+ return sum;
3743
+ }, 0) / perseveranceCards.filter(c => c.evaluations && c.evaluations.length > 0).length : 0;
3744
 
3745
+ // Calculer la diversité stratégique (nombre de catégories utilisées)
3746
+ const usedCategories = new Set();
3747
+ flashcardsData.forEach(card => {
3748
+ if (card.evaluations && card.evaluations.length > 0) {
3749
+ usedCategories.add(card.category);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3750
  }
3751
  });
3752
+ const strategyDiversity = (usedCategories.size / 6 * 100).toFixed(0); // 6 catégories au total
3753
+
3754
+ dashboardContainer.innerHTML = `
3755
+ <div class="dashboardEM-card">
3756
+ <div class="dashboardEM-header">
3757
+ <div class="dashboardEM-icon" style="background: linear-gradient(135deg, #3b82f6, #1d4ed8);">
3758
+ <i class="fas fa-brain"></i>
3759
+ </div>
3760
+ <div>
3761
+ <h4>Persévérance</h4>
3762
+ <div style="font-size: 0.9rem; color: var(--gray-color);">Capacité à maintenir l'effort</div>
3763
+ </div>
3764
+ </div>
3765
+ <div class="dashboardEM-metric">
3766
+ <div class="dashboardEM-value">${perseveranceScore.toFixed(1)}/5</div>
3767
+ <div class="dashboardEM-change">+${(perseveranceScore * 20).toFixed(0)}%</div>
3768
+ </div>
3769
+ <div class="dashboardEM-trend">
3770
+ <i class="fas fa-chart-line" style="color: #10b981;"></i>
3771
+ <span>Stable cette semaine</span>
3772
+ </div>
3773
+ </div>
3774
+
3775
+ <div class="dashboardEM-card">
3776
+ <div class="dashboardEM-header">
3777
+ <div class="dashboardEM-icon" style="background: linear-gradient(135deg, #10b981, #059669);">
3778
+ <i class="fas fa-bolt"></i>
3779
+ </div>
3780
+ <div>
3781
+ <h4>Gestion de l'Effort</h4>
3782
+ <div style="font-size: 0.9rem; color: var(--gray-color);">Efficacité énergétique</div>
3783
+ </div>
3784
+ </div>
3785
+ <div class="dashboardEM-metric">
3786
+ <div class="dashboardEM-value">${flashcardsStats.averageScore}/5</div>
3787
+ <div class="dashboardEM-change">${flashcardsStats.averageScore > 3 ? '+' : ''}${(flashcardsStats.averageScore * 20 - 60).toFixed(0)}%</div>
3788
+ </div>
3789
+ <div class="dashboardEM-trend">
3790
+ <i class="fas fa-chart-line" style="color: ${flashcardsStats.averageScore > 3 ? '#10b981' : '#ef4444'}"></i>
3791
+ <span>${flashcardsStats.averageScore > 3 ? 'En progression' : 'À améliorer'}</span>
3792
+ </div>
3793
+ </div>
3794
+
3795
+ <div class="dashboardEM-card">
3796
+ <div class="dashboardEM-header">
3797
+ <div class="dashboardEM-icon" style="background: linear-gradient(135deg, #8b5cf6, #7c3aed);">
3798
+ <i class="fas fa-lightbulb"></i>
3799
+ </div>
3800
+ <div>
3801
+ <h4>Métacognition</h4>
3802
+ <div style="font-size: 0.9rem; color: var(--gray-color);">Diversité des stratégies</div>
3803
+ </div>
3804
+ </div>
3805
+ <div class="dashboardEM-metric">
3806
+ <div class="dashboardEM-value">${strategyDiversity}%</div>
3807
+ <div class="dashboardEM-change">+${(strategyDiversity / 2).toFixed(0)}%</div>
3808
+ </div>
3809
+ <div class="dashboardEM-trend">
3810
+ <i class="fas fa-chart-line" style="color: #10b981;"></i>
3811
+ <span>${strategyDiversity > 50 ? 'Diversifié' : 'À élargir'}</span>
3812
+ </div>
3813
+ </div>
3814
+
3815
+ <div class="dashboardEM-card">
3816
+ <div class="dashboardEM-header">
3817
+ <div class="dashboardEM-icon" style="background: linear-gradient(135deg, #ec4899, #db2777);">
3818
+ <i class="fas fa-fire"></i>
3819
+ </div>
3820
+ <div>
3821
+ <h4>Activité</h4>
3822
+ <div style="font-size: 0.9rem; color: var(--gray-color);">Engagement quotidien</div>
3823
+ </div>
3824
+ </div>
3825
+ <div class="dashboardEM-metric">
3826
+ <div class="dashboardEM-value">${evaluationsToday}</div>
3827
+ <div class="dashboardEM-change">${evaluationsToday > 0 ? '+100%' : '0%'}</div>
3828
+ </div>
3829
+ <div class="dashboardEM-trend">
3830
+ <i class="fas fa-calendar-day" style="color: ${evaluationsToday > 0 ? '#10b981' : '#ef4444'}"></i>
3831
+ <span>${evaluationsToday > 0 ? 'Actif aujourd\'hui' : 'Pas d\'activité'}</span>
3832
+ </div>
3833
+ </div>
3834
+ `;
3835
+ }
3836
+
3837
+ // Réinitialiser les flashcards
3838
+ function resetFlashcards() {
3839
+ if (confirm('Voulez-vous vraiment réinitialiser toutes les flashcards ? Cela effacera toutes vos évaluations.')) {
3840
+ flashcardsData.forEach(card => {
3841
+ delete card.evaluations;
3842
+ });
3843
+ flashcardsStats.reviewedCards = 0;
3844
+ flashcardsStats.averageScore = 0;
3845
+ flashcardsStats.favoriteCategory = 'Aucune';
3846
+
3847
+ currentCardIndex = 0;
3848
+ showCardByCategory(currentCategory);
3849
+
3850
+ showNotification('Flashcards réinitialisées avec succès !', 'success');
3851
+ }
3852
  }
3853
 
3854
  // ============================================
 
4140
  generateHeatmap();
4141
  }
4142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4143
  // ============================================
4144
  // FONCTIONS UTILITAIRES
4145
  // ============================================
 
4203
  }
4204
 
4205
  // Charger les flashcards
4206
+ const savedFlashcards = localStorage.getItem('flashcardsData');
4207
  if (savedFlashcards) {
4208
+ const parsed = JSON.parse(savedFlashcards);
4209
+ if (parsed && parsed.length > 0) {
4210
+ flashcardsData = parsed;
4211
+
4212
+ // Calculer les stats des flashcards
4213
+ flashcardsStats.reviewedCards = flashcardsData.reduce((sum, card) =>
4214
+ sum + (card.evaluations ? card.evaluations.length : 0), 0);
4215
+
4216
+ const totalScores = flashcardsData.reduce((sum, card) => {
4217
+ if (card.evaluations && card.evaluations.length > 0) {
4218
+ return sum + card.evaluations[card.evaluations.length - 1].score;
4219
+ }
4220
+ return sum;
4221
+ }, 0);
4222
+
4223
+ const reviewedWithScores = flashcardsData.filter(card =>
4224
+ card.evaluations && card.evaluations.length > 0
4225
+ ).length;
4226
+
4227
+ flashcardsStats.averageScore = reviewedWithScores > 0
4228
+ ? (totalScores / reviewedWithScores).toFixed(1)
4229
+ : 0;
4230
+ }
4231
  }
4232
  } catch (error) {
4233
  console.error('Erreur lors du chargement des données:', error);
 
4239
  try {
4240
  localStorage.setItem('learnerProfile', JSON.stringify(learnerProfile));
4241
  localStorage.setItem('journalEntries', JSON.stringify(journalEntries));
4242
+ localStorage.setItem('flashcardsData', JSON.stringify(flashcardsData));
4243
+ // Note: Pas de notification pour éviter de déranger l'utilisateur
4244
  } catch (error) {
4245
+ console.error('Erreur lors de la sauvegarde:', error);
4246
  }
4247
  }
4248
 
4249
  // Sauvegarder automatiquement toutes les 30 secondes
4250
  setInterval(saveAllData, 30000);
4251
+
4252
+ // Sauvegarder aussi quand l'utilisateur quitte la page
4253
+ window.addEventListener('beforeunload', saveAllData);
4254
  </script>
4255
  </body>
4256
  </html>