Docfile commited on
Commit
db14463
·
verified ·
1 Parent(s): e000c95

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +144 -40
templates/index.html CHANGED
@@ -77,40 +77,71 @@
77
  opacity: 0;
78
  }
79
 
80
- /* Styles pour l'effet de rotation */
81
- .card-container {
82
  perspective: 1000px;
83
- position: relative;
84
- width: 100%;
85
- height: 250px; /* Ajustez la hauteur selon vos besoins */
86
  }
87
 
88
- .card-inner {
89
  position: relative;
90
  width: 100%;
91
  height: 100%;
 
92
  transition: transform 0.8s;
93
  transform-style: preserve-3d;
 
94
  }
95
 
96
- .card-container.is-flipped .card-inner {
97
  transform: rotateY(180deg);
98
  }
99
 
100
- .card-face {
101
  position: absolute;
102
  width: 100%;
103
  height: 100%;
 
104
  backface-visibility: hidden;
 
 
 
 
 
105
  }
106
 
107
- .card-front {
108
- /* Vos styles existants pour la face avant */
109
  }
110
 
111
- .card-back {
 
112
  transform: rotateY(180deg);
113
- /* Vos styles pour la face arrière */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  }
115
  </style>
116
  </head>
@@ -133,6 +164,7 @@
133
  type="text"
134
  id="topic"
135
  v-model="topic"
 
136
  class="w-full px-6 py-4 bg-gray-800/50 rounded-xl border border-gray-700 focus:ring-2 focus:ring-blue-500 focus:border-transparent text-lg transition-all duration-300"
137
  placeholder="Ex: Intelligence Artificielle, Quantum Computing..."
138
  :disabled="isLoading"
@@ -161,6 +193,11 @@
161
  <!-- Results Section -->
162
  <transition name="fade">
163
  <div v-if="flashcards.length > 0" class="glass-morph rounded-2xl overflow-hidden">
 
 
 
 
 
164
  <!-- Tabs -->
165
  <div class="border-b border-gray-700/50">
166
  <div class="flex">
@@ -184,32 +221,49 @@
184
  <div class="p-6">
185
  <!-- Study Mode -->
186
  <div v-if="activeTab === 'study'" class="space-y-6">
187
- <div
188
- v-for="(card, index) in flashcards"
189
- :key="index"
190
- class="card-container"
191
- :class="{'is-flipped': card.isFlipped}"
192
- @click="card.isFlipped = !card.isFlipped"
193
- >
194
- <div class="card-inner glass-morph rounded-xl">
195
- <div class="card-face card-front p-6 flex items-start space-x-4">
196
- <div class="w-12 h-12 flex items-center justify-center rounded-full bg-blue-500/20 text-blue-400 font-bold">
197
- [[index + 1]]
198
- </div>
199
- <div class="flex-1">
200
- <h3 class="text-xl font-medium">[[card.question]]</h3>
201
  </div>
202
  </div>
203
- <div class="card-face card-back p-6 flex items-start space-x-4">
204
- <div class="w-12 h-12 flex items-center justify-center rounded-full bg-blue-500/20 text-blue-400 font-bold">
205
- [[index + 1]]
206
- </div>
207
- <div class="flex-1">
208
- <p class="text-gray-300">[[card.answer]]</p>
209
  </div>
210
  </div>
211
  </div>
212
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  </div>
214
 
215
  <!-- JSON Mode -->
@@ -233,12 +287,22 @@
233
  flashcards: [],
234
  activeTab: 'study',
235
  isLoading: false,
236
- error: null
 
 
 
 
 
 
 
 
 
 
237
  }
238
  },
239
  methods: {
240
  async generateFlashcards() {
241
- if (!this.topic) {
242
  this.error = 'Veuillez entrer un sujet.'
243
  return
244
  }
@@ -246,6 +310,7 @@
246
  this.isLoading = true
247
  this.error = null
248
  this.flashcards = []
 
249
 
250
  try {
251
  const response = await axios.post('/generate', {
@@ -255,18 +320,16 @@
255
  if (response.data.success) {
256
  const cards = response.data.flashcards.map(card => ({
257
  ...card,
258
- isFlipped: false
259
  }))
260
 
261
- // Animation des cartes à leur apparition
262
  setTimeout(() => {
263
  this.flashcards = cards
264
  this.$nextTick(() => {
265
- gsap.from('.card-hover', {
266
  y: 30,
267
  opacity: 0,
268
- duration: 0.5,
269
- stagger: 0.1
270
  })
271
  })
272
  }, 300)
@@ -276,16 +339,57 @@
276
  } finally {
277
  this.isLoading = false
278
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
  }
280
  },
281
  mounted() {
282
- // Animation du titre à l'entrée
283
  gsap.from('.gradient-text', {
284
  y: -50,
285
  opacity: 0,
286
  duration: 1,
287
  ease: 'power3.out'
288
  })
 
 
 
 
 
 
 
 
 
 
 
289
  }
290
  }).mount('#app')
291
  </script>
 
77
  opacity: 0;
78
  }
79
 
80
+ .flip-card {
 
81
  perspective: 1000px;
82
+ height: 300px;
 
 
83
  }
84
 
85
+ .flip-card-inner {
86
  position: relative;
87
  width: 100%;
88
  height: 100%;
89
+ text-align: center;
90
  transition: transform 0.8s;
91
  transform-style: preserve-3d;
92
+ cursor: pointer;
93
  }
94
 
95
+ .flip-card.flipped .flip-card-inner {
96
  transform: rotateY(180deg);
97
  }
98
 
99
+ .flip-card-front, .flip-card-back {
100
  position: absolute;
101
  width: 100%;
102
  height: 100%;
103
+ -webkit-backface-visibility: hidden;
104
  backface-visibility: hidden;
105
+ display: flex;
106
+ align-items: center;
107
+ justify-content: center;
108
+ padding: 2rem;
109
+ border-radius: 1rem;
110
  }
111
 
112
+ .flip-card-front {
113
+ background: rgba(255, 255, 255, 0.05);
114
  }
115
 
116
+ .flip-card-back {
117
+ background: rgba(255, 255, 255, 0.07);
118
  transform: rotateY(180deg);
119
+ }
120
+
121
+ .keyboard-shortcut {
122
+ display: inline-flex;
123
+ align-items: center;
124
+ justify-content: center;
125
+ min-width: 24px;
126
+ height: 24px;
127
+ padding: 0 6px;
128
+ border-radius: 4px;
129
+ background: rgba(255, 255, 255, 0.1);
130
+ font-size: 0.875rem;
131
+ margin: 0 2px;
132
+ }
133
+
134
+ .progress-bar {
135
+ height: 4px;
136
+ background: rgba(96, 165, 250, 0.2);
137
+ border-radius: 2px;
138
+ overflow: hidden;
139
+ }
140
+
141
+ .progress-value {
142
+ height: 100%;
143
+ background: linear-gradient(90deg, #60a5fa, #a855f7);
144
+ transition: width 0.3s ease;
145
  }
146
  </style>
147
  </head>
 
164
  type="text"
165
  id="topic"
166
  v-model="topic"
167
+ @keyup.enter="generateFlashcards"
168
  class="w-full px-6 py-4 bg-gray-800/50 rounded-xl border border-gray-700 focus:ring-2 focus:ring-blue-500 focus:border-transparent text-lg transition-all duration-300"
169
  placeholder="Ex: Intelligence Artificielle, Quantum Computing..."
170
  :disabled="isLoading"
 
193
  <!-- Results Section -->
194
  <transition name="fade">
195
  <div v-if="flashcards.length > 0" class="glass-morph rounded-2xl overflow-hidden">
196
+ <!-- Progress Bar -->
197
+ <div class="progress-bar">
198
+ <div class="progress-value" :style="{ width: `${(currentCardIndex + 1) * 100 / flashcards.length}%` }"></div>
199
+ </div>
200
+
201
  <!-- Tabs -->
202
  <div class="border-b border-gray-700/50">
203
  <div class="flex">
 
221
  <div class="p-6">
222
  <!-- Study Mode -->
223
  <div v-if="activeTab === 'study'" class="space-y-6">
224
+ <!-- Keyboard Shortcuts Info -->
225
+ <div class="text-center mb-6 text-gray-400">
226
+ <span class="keyboard-shortcut">←</span> Précédent
227
+ <span class="keyboard-shortcut mx-2">→</span> Suivant
228
+ <span class="keyboard-shortcut">Espace</span> Retourner la carte
229
+ </div>
230
+
231
+ <div class="flip-card" :class="{ 'flipped': currentCard.showAnswer }" @click="toggleCard">
232
+ <div class="flip-card-inner">
233
+ <div class="flip-card-front">
234
+ <div class="text-center">
235
+ <div class="text-2xl font-medium mb-4">[[currentCard.question]]</div>
236
+ <div class="text-gray-400 text-sm">(Cliquez pour voir la réponse)</div>
 
237
  </div>
238
  </div>
239
+ <div class="flip-card-back">
240
+ <div class="text-center">
241
+ <div class="text-xl">[[currentCard.answer]]</div>
 
 
 
242
  </div>
243
  </div>
244
  </div>
245
  </div>
246
+
247
+ <!-- Navigation Controls -->
248
+ <div class="flex items-center justify-center space-x-4 mt-8">
249
+ <button
250
+ @click="previousCard"
251
+ :disabled="currentCardIndex === 0"
252
+ class="px-6 py-3 bg-blue-500/20 rounded-lg hover:bg-blue-500/30 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-300"
253
+ >
254
+ ← Précédent
255
+ </button>
256
+ <div class="text-lg font-medium">
257
+ [[currentCardIndex + 1]] / [[flashcards.length]]
258
+ </div>
259
+ <button
260
+ @click="nextCard"
261
+ :disabled="currentCardIndex === flashcards.length - 1"
262
+ class="px-6 py-3 bg-blue-500/20 rounded-lg hover:bg-blue-500/30 disabled:opacity-50 disabled:cursor-not-allowed transition-all duration-300"
263
+ >
264
+ Suivant →
265
+ </button>
266
+ </div>
267
  </div>
268
 
269
  <!-- JSON Mode -->
 
287
  flashcards: [],
288
  activeTab: 'study',
289
  isLoading: false,
290
+ error: null,
291
+ currentCardIndex: 0
292
+ }
293
+ },
294
+ computed: {
295
+ currentCard() {
296
+ return this.flashcards[this.currentCardIndex] || {
297
+ question: '',
298
+ answer: '',
299
+ showAnswer: false
300
+ }
301
  }
302
  },
303
  methods: {
304
  async generateFlashcards() {
305
+ if (!this.topic.trim()) {
306
  this.error = 'Veuillez entrer un sujet.'
307
  return
308
  }
 
310
  this.isLoading = true
311
  this.error = null
312
  this.flashcards = []
313
+ this.currentCardIndex = 0
314
 
315
  try {
316
  const response = await axios.post('/generate', {
 
320
  if (response.data.success) {
321
  const cards = response.data.flashcards.map(card => ({
322
  ...card,
323
+ showAnswer: false
324
  }))
325
 
 
326
  setTimeout(() => {
327
  this.flashcards = cards
328
  this.$nextTick(() => {
329
+ gsap.from('.flip-card', {
330
  y: 30,
331
  opacity: 0,
332
+ duration: 0.5
 
333
  })
334
  })
335
  }, 300)
 
339
  } finally {
340
  this.isLoading = false
341
  }
342
+ },
343
+ nextCard() {
344
+ if (this.currentCardIndex < this.flashcards.length - 1) {
345
+ this.flashcards[this.currentCardIndex].showAnswer = false
346
+ this.currentCardIndex++
347
+ this.animateCardTransition('next')
348
+ }
349
+ },
350
+ previousCard() {
351
+ if (this.currentCardIndex > 0) {
352
+ this.flashcards[this.currentCardIndex].showAnswer = false
353
+ this.currentCardIndex--
354
+ this.animateCardTransition('prev')
355
+ }
356
+ },
357
+ toggleCard() {
358
+ this.flashcards[this.currentCardIndex].showAnswer = !this.flashcards[this.currentCardIndex].showAnswer
359
+ },
360
+ animateCardTransition(direction) {
361
+ const xOffset = direction === 'next' ? -50 : 50
362
+ gsap.fromTo('.flip-card',
363
+ {
364
+ x: xOffset,
365
+ opacity: 0
366
+ },
367
+ {
368
+ x: 0,
369
+ opacity: 1,
370
+ duration: 0.3
371
+ }
372
+ )
373
  }
374
  },
375
  mounted() {
 
376
  gsap.from('.gradient-text', {
377
  y: -50,
378
  opacity: 0,
379
  duration: 1,
380
  ease: 'power3.out'
381
  })
382
+
383
+ window.addEventListener('keydown', (e) => {
384
+ if (this.activeTab === 'study') {
385
+ if (e.key === 'ArrowRight') this.nextCard()
386
+ if (e.key === 'ArrowLeft') this.previousCard()
387
+ if (e.key === ' ') {
388
+ e.preventDefault()
389
+ this.toggleCard()
390
+ }
391
+ }
392
+ })
393
  }
394
  }).mount('#app')
395
  </script>