Files
amneziavpnphp/templates/settings_old.twig
T
2025-11-07 13:34:06 +03:00

200 lines
9.0 KiB
Twig

{% extends "layout.twig" %}
{% block title %}{{ t('menu.settings') }} - {{ app_name }}{% endblock %}
{% block content %}
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="mb-8">
<h1 class="text-3xl font-bold text-gray-900">{{ t('menu.settings') }}</h1>
<p class="mt-2 text-sm text-gray-600">{{ t('settings.description') }}</p>
</div>
{% if success %}
<div class="mb-4 bg-green-50 border-l-4 border-green-400 p-4">
<div class="flex">
<div class="flex-shrink-0">
<i class="fas fa-check-circle text-green-400"></i>
</div>
<div class="ml-3">
<p class="text-sm text-green-700">{{ success }}</p>
</div>
</div>
</div>
{% endif %}
{% if error %}
<div class="mb-4 bg-red-50 border-l-4 border-red-400 p-4">
<div class="flex">
<div class="flex-shrink-0">
<i class="fas fa-exclamation-circle text-red-400"></i>
</div>
<div class="ml-3">
<p class="text-sm text-red-700">{{ error }}</p>
</div>
</div>
</div>
{% endif %}
<div class="bg-white shadow rounded-lg">
<!-- API Keys Section -->
<div class="px-6 py-5 border-b border-gray-200">
<h2 class="text-lg font-medium text-gray-900">
<i class="fas fa-key mr-2 text-purple-600"></i>
{{ t('settings.api_keys') }}
</h2>
<p class="mt-1 text-sm text-gray-500">{{ t('settings.api_keys_desc') }}</p>
</div>
<div class="px-6 py-5">
<!-- OpenRouter API Key -->
<form method="POST" action="/settings/api-key">
<div class="mb-6">
<label for="openrouter_key" class="block text-sm font-medium text-gray-700 mb-2">
OpenRouter API Key
<span class="text-gray-400 font-normal ml-2">({{ t('settings.for_translation') }})</span>
</label>
<div class="mt-1 flex rounded-md shadow-sm">
<input type="text"
name="api_key"
id="openrouter_key"
value=""
class="flex-1 min-w-0 block w-full px-3 py-2 rounded-l-md border border-gray-300 focus:ring-purple-500 focus:border-purple-500 sm:text-sm"
placeholder="sk-or-v1-...">
<button type="button"
onclick="togglePassword('openrouter_key')"
class="inline-flex items-center px-3 rounded-r-md border border-l-0 border-gray-300 bg-gray-50 text-gray-500 hover:bg-gray-100">
<i class="fas fa-eye"></i>
</button>
</div>
<p class="mt-2 text-sm text-gray-500">
<i class="fas fa-info-circle mr-1"></i>
{{ t('settings.get_key_at') }} <a href="https://openrouter.ai/keys" target="_blank" class="text-purple-600 hover:text-purple-800">openrouter.ai/keys</a>
</p>
</div>
<input type="hidden" name="service" value="openrouter">
<div class="flex justify-end">
<button type="submit" class="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-purple-600 hover:bg-purple-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-purple-500">
<i class="fas fa-save mr-2"></i>
{{ t('form.save') }}
</button>
</div>
</form>
</div>
<!-- Translation Section -->
<div class="px-6 py-5 border-t border-gray-200">
<h3 class="text-lg font-medium text-gray-900 mb-4">
<i class="fas fa-language mr-2 text-purple-600"></i>
{{ t('settings.translation_status') }}
</h3>
<div class="overflow-hidden">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{{ t('settings.language') }}
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{{ t('settings.progress') }}
</th>
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
{{ t('settings.actions') }}
</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
{% for stat in translation_stats %}
<tr>
<td class="px-6 py-4 whitespace-nowrap">
<div class="flex items-center">
<span class="text-2xl mr-3">{{ getFlag(stat.code) }}</span>
<div>
<div class="text-sm font-medium text-gray-900">{{ stat.name }}</div>
<div class="text-sm text-gray-500">({{ stat.code }})</div>
</div>
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
{% set percent = (stat.translated_count / stat.total_count * 100)|round %}
<div class="flex items-center">
<div class="w-full bg-gray-200 rounded-full h-2.5 mr-2">
<div class="bg-purple-600 h-2.5 rounded-full" style="width: {{ percent }}%"></div>
</div>
<span class="text-sm text-gray-700">{{ percent }}%</span>
</div>
<div class="text-xs text-gray-500 mt-1">
{{ stat.translated_count }} / {{ stat.total_count }} {{ t('settings.keys') }}
</div>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm">
{% if stat.code != 'en' and stat.translated_count < stat.total_count %}
<button onclick="translateLanguage('{{ stat.code }}')"
class="text-purple-600 hover:text-purple-900">
<i class="fas fa-robot mr-1"></i>
{{ t('settings.auto_translate') }}
</button>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
<script>
function togglePassword(id) {
const input = document.getElementById(id);
input.type = input.type === 'password' ? 'text' : 'password';
}
function translateLanguage(lang) {
if (!confirm('{{ t('settings.confirm_translate') }}')) return;
const button = event.target.closest('button');
const originalText = button.innerHTML;
button.disabled = true;
button.innerHTML = '<i class="fas fa-spinner fa-spin mr-1"></i> {{ t('form.processing') }}';
// Get JWT token from cookie or session
fetch('/api/auth/token', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: 'email=admin@amnez.ia&password=admin123'
})
.then(r => r.json())
.then(auth => {
return fetch('/api/translations/auto-translate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + auth.token
},
body: JSON.stringify({language: lang})
});
})
.then(r => r.json())
.then(data => {
if (data.success) {
alert('{{ t('settings.translation_complete') }}: ' + data.stats.translated + '/' + data.stats.total);
location.reload();
} else {
alert('{{ t('message.error') }}: ' + (data.error || 'Unknown error'));
button.disabled = false;
button.innerHTML = originalText;
}
})
.catch(err => {
alert('{{ t('message.error') }}: ' + err.message);
button.disabled = false;
button.innerHTML = originalText;
});
}
</script>
{% endblock %}