DocTranslator / frontend /index.html
yasmine110's picture
Update frontend/index.html
857db6f verified
raw
history blame
17.3 kB
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DocTranslator Pro - Traduction Intelligente</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css">
<style>
:root {
--primary-color: #4361ee;
--secondary-color: #f8f9fc;
--accent-color: #3a0ca3;
--success-color: #2ecc71;
--warning-color: #f39c12;
--dark-color: #2c3e50;
}
body {
padding: 20px;
background-color: var(--secondary-color);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
min-height: 100vh;
}
.container {
max-width: 900px;
margin-top: 30px;
margin-bottom: 50px;
}
.card {
border-radius: 12px;
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
border: none;
background: linear-gradient(145deg, #ffffff, #f0f2f5);
transition: transform 0.3s ease;
overflow: hidden;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15);
}
.card-header {
background-color: var(--primary-color);
color: white;
font-weight: 600;
padding: 15px 20px;
}
.result-area {
margin-top: 30px;
padding: 30px;
background-color: white;
border-radius: 12px;
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.1);
border: 1px solid rgba(0, 0, 0, 0.05);
}
.loading {
display: none;
text-align: center;
margin: 40px 0;
}
.text-display {
height: 350px;
overflow-y: auto;
white-space: pre-wrap;
background-color: var(--secondary-color);
padding: 20px;
border-radius: 8px;
border: 1px solid #e3e6f0;
font-size: 0.95rem;
line-height: 1.8;
transition: all 0.3s ease;
}
.text-display:hover {
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.05);
}
#downloadBtn {
transition: all 0.3s ease;
font-weight: 600;
padding: 10px 20px;
border-radius: 8px;
}
#downloadBtn:hover {
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(46, 204, 113, 0.3);
}
.file-info {
font-size: 0.85rem;
color: #6c757d;
margin-top: 8px;
padding: 8px 12px;
background-color: rgba(108, 117, 125, 0.05);
border-radius: 6px;
}
.alert-warning {
border-left: 4px solid var(--warning-color);
background-color: rgba(243, 156, 18, 0.1);
}
.alert-info {
border-left: 4px solid var(--primary-color);
background-color: rgba(67, 97, 238, 0.1);
}
.btn-primary {
background-color: var(--primary-color);
border: none;
padding: 12px;
font-weight: 600;
letter-spacing: 0.5px;
transition: all 0.3s ease;
}
.btn-primary:hover {
background-color: var(--accent-color);
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(58, 12, 163, 0.3);
}
.btn-success {
background-color: var(--success-color);
border: none;
}
.spinner-border {
width: 3.5rem;
height: 3.5rem;
border-width: 0.3em;
}
.language-selector {
position: relative;
}
.language-selector::after {
content: "\F282";
font-family: "bootstrap-icons";
position: absolute;
right: 15px;
top: 50%;
transform: translateY(-50%);
pointer-events: none;
color: var(--primary-color);
}
.toast-notification {
position: fixed;
bottom: 20px;
right: 20px;
background: var(--dark-color);
color: white;
padding: 15px 25px;
border-radius: 10px;
box-shadow: 0 8px 20px rgba(0,0,0,0.2);
display: none;
z-index: 1000;
animation: fadeIn 0.5s;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.progress-container {
display: none;
margin: 25px 0;
}
.progress {
height: 10px;
border-radius: 5px;
background-color: rgba(67, 97, 238, 0.1);
}
.progress-bar {
background-color: var(--primary-color);
border-radius: 5px;
}
.feature-icon {
font-size: 1.5rem;
margin-bottom: 15px;
color: var(--primary-color);
}
footer {
margin-top: 50px;
padding: 20px 0;
text-align: center;
color: #6c757d;
font-size: 0.9rem;
}
.animate-spin {
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Mode mobile */
@media (max-width: 768px) {
.container {
padding: 15px;
}
.text-display {
height: 250px;
}
.result-area {
padding: 20px;
}
}
</style>
</head>
<body>
<div class="container animate__animated animate__fadeIn">
<header class="text-center mb-5">
<div class="d-flex justify-content-center align-items-center mb-3">
<i class="bi bi-translate feature-icon me-3" style="font-size: 2.5rem;"></i>
<h1 style="color: var(--primary-color); font-weight: 700;">DocTranslator <span class="badge bg-success">Pro</span></h1>
</div>
<p class="lead text-muted">Traduction intelligente de documents avec IA</p>
</header>
<div class="card mb-4 animate__animated animate__fadeInUp">
<div class="card-header">
<i class="bi bi-upload me-2"></i> Téléverser un document
</div>
<div class="card-body py-4">
<form id="uploadForm">
<div class="mb-4">
<label for="document" class="form-label fw-bold mb-3">
<i class="bi bi-file-earmark-arrow-up me-2"></i>
Sélectionnez votre document
</label>
<input class="form-control form-control-lg" type="file" id="document" accept=".pdf,.docx,.xlsx,.pptx" required>
<div class="file-info mt-2" id="fileInfo">Aucun fichier sélectionné</div>
</div>
<div class="mb-4 language-selector">
<label for="targetLang" class="form-label fw-bold mb-3">
<i class="bi bi-translate me-2"></i>
Langue de traduction
</label>
<select class="form-select form-select-lg" id="targetLang">
<option value="en">Anglais 🇬🇧</option>
<option value="es">Espagnol 🇪🇸</option>
<option value="ar">Arabe 🇸🇦</option>
<option value="de">Allemand 🇩🇪</option>
</select>
</div>
<button type="submit" class="btn btn-primary w-100 py-3 mt-2">
<i class="bi bi-magic me-2"></i> Traduire automatiquement
</button>
</form>
</div>
</div>
<!-- Zone de progression améliorée -->
<div class="progress-container" id="progressContainer">
<div class="d-flex justify-content-between mb-2">
<small class="text-muted fw-bold">Progression de la traduction</small>
<small class="fw-bold" id="progressPercent">0%</small>
</div>
<div class="progress">
<div id="progressBar" class="progress-bar progress-bar-striped progress-bar-animated"
role="progressbar" style="width: 0%"></div>
</div>
</div>
<!-- Avertissement amélioré -->
<div class="alert alert-warning mt-3 animate__animated animate__fadeIn" id="sizeWarning" style="display: none;">
<div class="d-flex align-items-center">
<i class="bi bi-exclamation-triangle-fill me-3" style="font-size: 1.5rem;"></i>
<div>
<h6 class="alert-heading mb-1">Attention</h6>
<span id="warningText" class="small"></span>
</div>
</div>
</div>
<!-- Loader amélioré -->
<div class="loading" id="loading">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Chargement...</span>
</div>
<p class="mt-3 fw-bold" id="loadingText">
<i class="bi bi-gear-fill animate-spin me-2"></i>
Analyse du document en cours...
</p>
<div class="progress mt-3" style="height: 6px; width: 50%; margin: 0 auto;">
<div class="progress-bar bg-primary" style="width: 45%"></div>
</div>
</div>
<!-- Résultats améliorés -->
<div class="result-area animate__animated animate__fadeIn" id="resultArea" style="display: none;">
<div class="d-flex justify-content-between align-items-center mb-4">
<h4 class="mb-0 text-primary">
<i class="bi bi-file-text me-2"></i>Résultats de la traduction
</h4>
<button id="downloadBtn" class="btn btn-success">
<i class="bi bi-file-earmark-arrow-down me-2"></i>Exporter
</button>
</div>
<hr>
<div class="mb-4">
<div class="d-flex align-items-center mb-2">
<i class="bi bi-file-earmark-text me-2" style="font-size: 1.2rem;"></i>
<h5 class="mb-0 d-flex align-items-center">
<span id="filename" class="fw-bold"></span>
<small id="fileSize" class="text-muted ms-2"></small>
</h5>
</div>
<div class="alert alert-info">
<i class="bi bi-info-circle-fill me-2"></i>
<span id="infoText">Traduction effectuée avec succès</span>
</div>
</div>
<div class="row mt-4">
<div class="col-lg-6 mb-4 mb-lg-0">
<div class="d-flex align-items-center mb-3">
<i class="bi bi-text-left me-2" style="font-size: 1.2rem;"></i>
<h5 class="mb-0">Texte original</h5>
</div>
<div class="text-display" id="originalText"></div>
</div>
<div class="col-lg-6">
<div class="d-flex align-items-center mb-3">
<i class="bi bi-translate me-2" style="font-size: 1.2rem;"></i>
<h5 class="mb-0">Texte traduit</h5>
</div>
<div class="text-display" id="translatedText"></div>
</div>
</div>
<div class="mt-4 pt-3 border-top">
<button class="btn btn-outline-primary me-2" id="copyTranslatedBtn">
<i class="bi bi-clipboard me-2"></i>Copier le texte
</button>
<button class="btn btn-outline-secondary" id="newTranslationBtn">
<i class="bi bi-arrow-repeat me-2"></i>Nouvelle traduction
</button>
</div>
</div>
<!-- Notifications toast -->
<div class="toast-notification" id="toastNotification">
<div class="d-flex align-items-center">
<i class="bi bi-check-circle-fill me-3" style="font-size: 1.5rem;"></i>
<span id="toastMessage">Opération réussie!</span>
</div>
</div>
</div>
<footer class="text-center text-muted">
<div class="container">
<p class="mb-2">DocTranslator Pro - Solution de traduction IA</p>
<p class="small mb-0">
<i class="bi bi-c-circle"></i> 2024 Tous droits réservés
<span class="mx-2"></span>
<a href="#" class="text-decoration-none">Conditions d'utilisation</a>
<span class="mx-2"></span>
<a href="#" class="text-decoration-none">Politique de confidentialité</a>
</p>
</div>
</footer>
<!-- Scripts -->
<script src="/static/script.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script>
// Affiche les infos du fichier sélectionné
document.getElementById('document').addEventListener('change', function(e) {
const file = e.target.files[0];
if (file) {
const fileInfo = document.getElementById('fileInfo');
const sizeMB = (file.size / (1024 * 1024)).toFixed(2);
fileInfo.innerHTML = `
<i class="bi bi-file-earmark-text me-1"></i>
<strong>${file.name}</strong> • ${sizeMB} MB • ${file.type || 'Type inconnu'}
`;
// Animation du card
document.querySelector('.card').classList.add('animate__animated', 'animate__pulse');
setTimeout(() => {
document.querySelector('.card').classList.remove('animate__animated', 'animate__pulse');
}, 1000);
// Avertissement pour fichiers volumineux
const warning = document.getElementById('sizeWarning');
if (file.size > 5 * 1024 * 1024) { // >5MB
document.getElementById('warningText').textContent =
`Vous avez sélectionné un fichier volumineux (${sizeMB} MB). Le traitement peut prendre plusieurs minutes.`;
warning.style.display = 'block';
} else {
warning.style.display = 'none';
}
}
});
// Bouton nouvelle traduction
document.getElementById('newTranslationBtn').addEventListener('click', function() {
document.getElementById('document').value = '';
document.getElementById('fileInfo').innerHTML = 'Aucun fichier sélectionné';
document.getElementById('resultArea').style.display = 'none';
document.getElementById('sizeWarning').style.display = 'none';
});
// Bouton copier le texte
document.getElementById('copyTranslatedBtn').addEventListener('click', function() {
const translatedText = document.getElementById('translatedText').textContent;
navigator.clipboard.writeText(translatedText).then(() => {
showToast('Texte copié dans le presse-papiers!');
});
});
// Fonction d'affichage des notifications
function showToast(message) {
const toast = document.getElementById('toastNotification');
document.getElementById('toastMessage').textContent = message;
toast.style.display = 'flex';
setTimeout(() => {
toast.style.animation = 'fadeIn 0.5s reverse';
setTimeout(() => {
toast.style.display = 'none';
toast.style.animation = 'fadeIn 0.5s';
}, 500);
}, 3000);
}
</script>
</body>
</html>