gmao/app_new/templates/admin/settings.html

200 lines
8.6 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block title %}Paramètres - Administration{% endblock %}
{% block content %}
<div class="container-fluid">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h1><i class="bi bi-gear"></i> Paramètres de l'application</h1>
<p class="text-muted">Configuration des intégrations et services</p>
</div>
<a href="{{ url_for('admin.index') }}" class="btn btn-outline-secondary">
<i class="bi bi-arrow-left"></i> Retour
</a>
</div>
<div class="row">
<div class="col-lg-6 mb-4">
<div class="card h-100"><div class="card-header"><h5 class="mb-0"><i class="bi bi-shield-lock"></i> API REST GMAO</h5></div><div class="card-body">
<p class="text-muted small">La clé donne un accès en lecture à lAPI. Elle nest jamais conservée en clair et ne sera affichée quune fois.</p>
<form method="post" action="{{ url_for('admin.generate_api_key') }}" class="d-inline"><button class="btn btn-primary" type="submit"><i class="bi bi-arrow-repeat"></i> Générer ou renouveler</button></form>
<form method="post" action="{{ url_for('admin.revoke_api_key') }}" class="d-inline"><button class="btn btn-outline-danger" type="submit"><i class="bi bi-x-circle"></i> Révoquer</button></form>
</div></div>
</div>
<!-- Section OpenRouter -->
<div class="col-lg-6 mb-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0">
<i class="bi bi-key"></i> OpenRouter API
</h5>
</div>
<div class="card-body">
<p class="text-muted small mb-3">
La clé API OpenRouter est utilisée pour l'interprétation des emails par l'IA.
Obtenez votre clé sur <a href="https://openrouter.ai/keys" target="_blank">openrouter.ai/keys</a>
</p>
<form id="openrouter-form">
<div class="mb-3">
<label for="openrouter-key" class="form-label">Clé API OpenRouter</label>
<div class="input-group">
<input type="password" class="form-control" id="openrouter-key"
placeholder="sk-or-v1-..."
value="{{ openrouter_key or '' }}">
<button class="btn btn-outline-secondary" type="button" onclick="toggleKeyVisibility()">
<i class="bi bi-eye" id="eye-icon"></i>
</button>
</div>
<div class="form-text">
{% if openrouter_key %}
<span class="text-success"><i class="bi bi-check-circle"></i> Clé configurée ({{ openrouter_key[:10] }}...{{ openrouter_key[-4:] }})</span>
{% else %}
<span class="text-warning"><i class="bi bi-exclamation-triangle"></i> Aucune clé configurée</span>
{% endif %}
</div>
</div>
<button type="submit" class="btn btn-primary">
<i class="bi bi-save"></i> Sauvegarder
</button>
<button type="button" class="btn btn-outline-secondary ms-2" onclick="testApiKey()">
<i class="bi bi-play"></i> Tester
</button>
</form>
<div id="test-result" class="mt-3" style="display:none;"></div>
</div>
</div>
</div>
<!-- Section Modèle IA -->
<div class="col-lg-6 mb-4">
<div class="card">
<div class="card-header">
<h5 class="mb-0">
<i class="bi bi-cpu"></i> Modèle IA
</h5>
</div>
<div class="card-body">
<p class="text-muted small mb-3">
Modèle utilisé pour l'interprétation des emails GMAO.
</p>
<div class="mb-3">
<label class="form-label">Modèle actuel</label>
<input type="text" class="form-control" value="poolside/laguna-m.1:free" readonly>
<div class="form-text">
<span class="text-success"><i class="bi bi-check-circle"></i> Modèle gratuit et rapide</span>
</div>
</div>
<div class="alert alert-info small">
<i class="bi bi-info-circle"></i>
<strong>Modèles recommandés:</strong>
<ul class="mb-0 mt-1">
<li><code>poolside/laguna-m.1:free</code> - Gratuit, rapide</li>
<li><code>openrouter/optimus-alpha</code> - Plus puissant</li>
<li><code>anthropic/claude-3-haiku</code> - Haute qualité</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<!-- Section Contexte GMAO -->
<div class="card mb-4">
<div class="card-header">
<h5 class="mb-0">
<i class="bi bi-building"></i> Contexte GMAO
</h5>
</div>
<div class="card-body">
<p class="text-muted">
Le contexte GMAO est utilisé par l'IA pour mieux interpréter les emails.
Il contient des informations sur votre établissement, équipements, procédures, etc.
</p>
<a href="{{ url_for('outlook_dashboard.context_config') }}" class="btn btn-primary">
<i class="bi bi-pencil"></i> Configurer le contexte GMAO
</a>
</div>
</div>
</div>
<script>
function toggleKeyVisibility() {
const input = document.getElementById('openrouter-key');
const icon = document.getElementById('eye-icon');
if (input.type === 'password') {
input.type = 'text';
icon.classList.remove('bi-eye');
icon.classList.add('bi-eye-slash');
} else {
input.type = 'password';
icon.classList.remove('bi-eye-slash');
icon.classList.add('bi-eye');
}
}
document.getElementById('openrouter-form').addEventListener('submit', function(e) {
e.preventDefault();
const key = document.getElementById('openrouter-key').value;
const btn = e.target.querySelector('button[type="submit"]');
const originalText = btn.innerHTML;
btn.disabled = true;
btn.innerHTML = '<span class="spinner-border spinner-border-sm"></span> Sauvegarde...';
fetch('/admin/settings/openrouter', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({api_key: key})
})
.then(response => response.json())
.then(data => {
if (data.success) {
location.reload();
} else {
alert('Erreur: ' + data.error);
}
})
.catch(error => {
alert('Erreur: ' + error.message);
})
.finally(() => {
btn.disabled = false;
btn.innerHTML = originalText;
});
});
function testApiKey() {
const key = document.getElementById('openrouter-key').value;
if (!key) {
alert('Entrez une clé API');
return;
}
const resultDiv = document.getElementById('test-result');
resultDiv.style.display = 'block';
resultDiv.innerHTML = '<div class="alert alert-info"><i class="bi bi-hourglass-split"></i> Test en cours...</div>';
fetch('https://openrouter.ai/api/v1/models', {
headers: {'Authorization': 'Bearer ' + key}
})
.then(response => {
if (response.ok) {
resultDiv.innerHTML = '<div class="alert alert-success"><i class="bi bi-check-circle"></i> Clé API valide !</div>';
} else {
resultDiv.innerHTML = '<div class="alert alert-danger"><i class="bi bi-x-circle"></i> Clé API invalide</div>';
}
})
.catch(error => {
resultDiv.innerHTML = '<div class="alert alert-danger"><i class="bi bi-x-circle"></i> Erreur: ' + error.message + '</div>';
});
}
</script>
{% endblock %}