Spaces:
Running
Running
<html lang="fr"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Philosophie</title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert2/11.7.3/sweetalert2.all.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.3.0/marked.min.js"></script> | |
<link href="https://cdnjs.cloudflare.com/ajax/libs/sweetalert2/11.7.3/sweetalert2.min.css" rel="stylesheet"> | |
<style> | |
.container { | |
max-width: 800px; | |
margin: 0 auto; | |
padding: 20px; | |
} | |
.card { | |
background: white; | |
border-radius: 8px; | |
box-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
padding: 20px; | |
} | |
.form-group { | |
margin-bottom: 20px; | |
} | |
.btn { | |
padding: 10px 20px; | |
border: none; | |
border-radius: 4px; | |
cursor: pointer; | |
margin-right: 10px; | |
font-weight: bold; | |
} | |
.btn-primary { | |
background-color: #4A90E2; | |
color: white; | |
} | |
.btn-secondary { | |
background-color: #6c757d; | |
color: white; | |
} | |
.btn-success { | |
background-color: #28a745; | |
color: white; | |
} | |
.select-wrapper { | |
margin-bottom: 20px; | |
} | |
select, textarea { | |
width: 100%; | |
padding: 8px; | |
border: 1px solid #ddd; | |
border-radius: 4px; | |
margin-top: 5px; | |
} | |
.hidden { | |
display: none; | |
} | |
#loader { | |
text-align: center; | |
padding: 20px; | |
} | |
#response { | |
margin-top: 20px; | |
padding: 15px; | |
background: #f8f9fa; | |
border-radius: 4px; | |
line-height: 1.6; | |
} | |
.course-info { | |
margin-top: 10px; | |
font-size: 0.9em; | |
color: #666; | |
} | |
.course-meta { | |
display: flex; | |
justify-content: space-between; | |
margin-bottom: 10px; | |
padding: 5px; | |
background: #f8f9fa; | |
border-radius: 4px; | |
} | |
.type-label { | |
background: #4A90E2; | |
color: white; | |
padding: 5px 10px; | |
border-radius: 4px; | |
margin-bottom: 15px; | |
display: inline-block; | |
} | |
/* Styles Markdown */ | |
#response h1 { | |
font-size: 2em; | |
margin-bottom: 0.5em; | |
border-bottom: 2px solid #eee; | |
padding-bottom: 0.3em; | |
} | |
#response h2 { | |
font-size: 1.5em; | |
margin-bottom: 0.5em; | |
border-bottom: 1px solid #eee; | |
padding-bottom: 0.3em; | |
} | |
#response h3 { | |
font-size: 1.3em; | |
margin-bottom: 0.5em; | |
} | |
#response p { | |
margin-bottom: 1em; | |
} | |
#response ul, #response ol { | |
margin-bottom: 1em; | |
padding-left: 2em; | |
} | |
#response li { | |
margin-bottom: 0.5em; | |
} | |
#response blockquote { | |
border-left: 4px solid #ddd; | |
padding-left: 1em; | |
margin-left: 0; | |
color: #666; | |
} | |
#response code { | |
background-color: #f5f5f5; | |
padding: 0.2em 0.4em; | |
border-radius: 3px; | |
font-family: monospace; | |
} | |
#response pre { | |
background-color: #f5f5f5; | |
padding: 1em; | |
border-radius: 4px; | |
overflow-x: auto; | |
margin-bottom: 1em; | |
} | |
#response pre code { | |
background-color: transparent; | |
padding: 0; | |
} | |
#response table { | |
border-collapse: collapse; | |
width: 100%; | |
margin-bottom: 1em; | |
} | |
#response th, #response td { | |
border: 1px solid #ddd; | |
padding: 8px; | |
text-align: left; | |
} | |
#response th { | |
background-color: #f5f5f5; | |
} | |
#response img { | |
max-width: 100%; | |
height: auto; | |
} | |
#response hr { | |
border: none; | |
border-top: 1px solid #ddd; | |
margin: 1em 0; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<div class="card"> | |
<h1 class="text-3xl font-bold text-gray-800">Philosophie</h1> | |
<!-- Sélection du type de dissertation --> | |
<div class="form-group"> | |
<label for="type-select">Type de dissertation :</label> | |
<select id="type-select" class="form-control"> | |
<option value="1">Type 1 </option> | |
<option value="2">Type 2 </option> | |
</select> | |
</div> | |
<div class="type-label" id="current-type-label">Sujet de type 1</div> | |
<!-- Sélection du cours --> | |
<div class="form-group"> | |
<label for="course-select">Sélectionner un cours :</label> | |
<select id="course-select" class="form-control"> | |
<option value="">Choisir un cours...</option> | |
</select> | |
<div class="course-info"> | |
<div class="course-meta hidden"> | |
<span id="course-author"></span> | |
<span id="course-date"></span> | |
</div> | |
</div> | |
</div> | |
<!-- Zone de texte pour la question --> | |
<div class="form-group"> | |
<label for="question">Entrez juste le sujet :</label> | |
<textarea id="question" rows="4" class="form-control"></textarea> | |
</div> | |
<!-- Bouton de soumission --> | |
<button id="submit-btn" class="btn btn-success">Soumettre</button> | |
<!-- Loader --> | |
<div id="loader" class="hidden"> | |
Chargement en cours... | |
</div> | |
<!-- Zone de réponse --> | |
<div id="response" class="hidden"></div> | |
<!-- Bouton de copie --> | |
<button id="copy-btn" class="btn btn-secondary hidden">Copier la réponse</button> | |
</div> | |
</div> | |
<script> | |
$(document).ready(function() { | |
// Configuration de marked | |
marked.setOptions({ | |
breaks: true, | |
gfm: true, | |
headerIds: true, | |
langPrefix: 'language-' | |
}); | |
// Configuration des toasts SweetAlert2 | |
const Toast = Swal.mixin({ | |
toast: true, | |
position: 'top-end', | |
showConfirmButton: false, | |
timer: 3000, | |
timerProgressBar: true | |
}); | |
// Gestion du changement de type | |
$('#type-select').change(function() { | |
const type = $(this).val(); | |
$('#current-type-label').text(`Sujet de type ${type}`); | |
}); | |
// Charger les cours depuis la base de données | |
$.ajax({ | |
url: '/api/philosophy/courses', | |
method: 'GET', | |
success: function(courses) { | |
const select = $('#course-select'); | |
courses.forEach(course => { | |
select.append(`<option value="${course.id}">${course.title}</option>`); | |
}); | |
}, | |
error: function() { | |
Toast.fire({ | |
icon: 'error', | |
title: 'Erreur lors du chargement des cours' | |
}); | |
} | |
}); | |
// Gestion du changement de cours | |
$('#course-select').change(function() { | |
const courseId = $(this).val(); | |
if (courseId) { | |
$.ajax({ | |
url: `/api/philosophy/courses/${courseId}`, | |
method: 'GET', | |
success: function(course) { | |
$('.course-meta').removeClass('hidden'); | |
$('#course-author').text(`Professeur: ${course.author}`); | |
$('#course-date').text(`Mis à jour: ${new Date(course.updated_at).toLocaleDateString()}`); | |
Toast.fire({ | |
icon: 'success', | |
title: 'Cours chargé avec succès' | |
}); | |
}, | |
error: function() { | |
Toast.fire({ | |
icon: 'error', | |
title: 'Erreur lors du chargement des détails du cours' | |
}); | |
} | |
}); | |
} else { | |
$('.course-meta').addClass('hidden'); | |
} | |
}); | |
// Gestion de la soumission | |
$('#submit-btn').click(function() { | |
const question = $('#question').val().trim(); | |
const type = $('#type-select').val(); | |
if (!question) { | |
Swal.fire({ | |
icon: 'warning', | |
title: 'Attention', | |
text: 'Veuillez saisir une question.' | |
}); | |
return; | |
} | |
Swal.fire({ | |
title: 'Generation en cours', | |
html: 'Veuillez patienter...', | |
allowOutsideClick: false, | |
didOpen: () => { | |
Swal.showLoading(); | |
} | |
}); | |
// Préparation des données | |
const data = { | |
question: question, | |
type: type | |
}; | |
// Ajout du courseId seulement s'il est sélectionné | |
const courseId = $('#course-select').val(); | |
if (courseId) { | |
data.courseId = courseId; | |
} | |
$.ajax({ | |
url: '/submit_philo', | |
method: 'POST', | |
contentType: 'application/json', | |
data: JSON.stringify(data), | |
success: function(data) { | |
Swal.close(); | |
// Conversion du Markdown en HTML | |
const htmlContent = marked.parse(data.response); | |
$('#response').html(htmlContent).removeClass('hidden'); | |
$('#copy-btn').removeClass('hidden'); | |
Toast.fire({ | |
icon: 'success', | |
title: 'Réponse générée avec succès' | |
}); | |
}, | |
error: function(xhr) { | |
Swal.fire({ | |
icon: 'error', | |
title: 'Erreur', | |
text: 'Une erreur est survenue lors de la génération de la réponse.' | |
}); | |
} | |
}); | |
}); | |
// Gestion de la copie de la réponse | |
$('#copy-btn').click(function() { | |
const response = $('#response').text(); | |
navigator.clipboard.writeText(response).then(function() { | |
Toast.fire({ | |
icon: 'success', | |
title: 'Réponse copiée avec succès' | |
}); | |
}).catch(function() { | |
Toast.fire({ | |
icon: 'error', | |
title: 'Erreur lors de la copie' | |
}); | |
}); | |
}); | |
}); | |
</script> | |
</body> | |
</html> |