"feat: Implement SSL configuration for frontend and backend"
This commit is contained in:
parent
f063d07232
commit
7893e1b904
@ -11,11 +11,10 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="admin-container">
|
<div class="admin-container">
|
||||||
<h1 class="text-3xl font-bold mb-6 text-slate-900 dark:text-white">Admin Panel</h1>
|
<h1 class="text-4xl font-extrabold mb-10 text-slate-900 dark:text-white tracking-tight">Admin Panel</h1>
|
||||||
|
|
||||||
<!-- Admin Stats -->
|
<!-- Admin Stats -->
|
||||||
<div class="admin-stats">
|
<div class="admin-stats">
|
||||||
<div class="stat-card">
|
<div class="stat-card flex flex-col gap-2">
|
||||||
<div class="stat-icon">
|
<div class="stat-icon">
|
||||||
<svg class="w-10 h-10" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-10 h-10" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
|
||||||
@ -25,8 +24,7 @@
|
|||||||
<div class="stat-value">{{ stats.total_users }}</div>
|
<div class="stat-value">{{ stats.total_users }}</div>
|
||||||
<div class="stat-desc">Registrierte Benutzer</div>
|
<div class="stat-desc">Registrierte Benutzer</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="stat-card flex flex-col gap-2">
|
||||||
<div class="stat-card">
|
|
||||||
<div class="stat-icon">
|
<div class="stat-icon">
|
||||||
<svg class="w-10 h-10" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-10 h-10" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z" />
|
||||||
@ -36,8 +34,7 @@
|
|||||||
<div class="stat-value">{{ stats.total_printers }}</div>
|
<div class="stat-value">{{ stats.total_printers }}</div>
|
||||||
<div class="stat-desc">Verbundene Drucker</div>
|
<div class="stat-desc">Verbundene Drucker</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="stat-card flex flex-col gap-2">
|
||||||
<div class="stat-card">
|
|
||||||
<div class="stat-icon">
|
<div class="stat-icon">
|
||||||
<svg class="w-10 h-10" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-10 h-10" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
|
||||||
@ -47,8 +44,7 @@
|
|||||||
<div class="stat-value">{{ stats.active_jobs }}</div>
|
<div class="stat-value">{{ stats.active_jobs }}</div>
|
||||||
<div class="stat-desc">Laufende Druckaufträge</div>
|
<div class="stat-desc">Laufende Druckaufträge</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="stat-card flex flex-col gap-2">
|
||||||
<div class="stat-card">
|
|
||||||
<div class="stat-icon">
|
<div class="stat-icon">
|
||||||
<svg class="w-10 h-10" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-10 h-10" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
@ -59,9 +55,8 @@
|
|||||||
<div class="stat-desc">Erfolgreiche Druckaufträge</div>
|
<div class="stat-desc">Erfolgreiche Druckaufträge</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tabs Navigation -->
|
<!-- Tabs Navigation -->
|
||||||
<div class="nav-tabs">
|
<div class="nav-tabs mt-8">
|
||||||
<a href="{{ url_for('admin_page', tab='users') }}" class="nav-tab {{ 'active' if active_tab == 'users' else '' }}">
|
<a href="{{ url_for('admin_page', tab='users') }}" class="nav-tab {{ 'active' if active_tab == 'users' else '' }}">
|
||||||
<svg class="inline-block w-5 h-5 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="inline-block w-5 h-5 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
|
||||||
@ -93,17 +88,15 @@
|
|||||||
Logs
|
Logs
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Tab Content -->
|
<!-- Tab Content -->
|
||||||
<div class="tab-content mt-8">
|
<div class="tab-content mt-8">
|
||||||
<!-- Users Tab -->
|
|
||||||
{% if active_tab == 'users' %}
|
{% if active_tab == 'users' %}
|
||||||
<div id="users-tab" class="tab-pane active">
|
<div id="users-tab" class="tab-pane active">
|
||||||
<div class="bg-white dark:bg-dark-card rounded-xl shadow-lg p-6 transition-colors">
|
<div class="bg-white dark:bg-dark-card rounded-xl shadow-lg p-8 transition-colors">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex flex-col md:flex-row md:justify-between md:items-center mb-8 gap-4">
|
||||||
<h3 class="text-xl font-bold text-slate-900 dark:text-white">Benutzer</h3>
|
<h3 class="text-2xl font-bold text-slate-900 dark:text-white">Benutzer</h3>
|
||||||
<form action="{{ url_for('admin_page', tab='users') }}" method="get">
|
<form action="{{ url_for('admin_page', tab='users') }}" method="get">
|
||||||
<button type="submit" class="btn btn-primary">
|
<button type="submit" class="btn btn-primary flex items-center">
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
|
||||||
</svg>
|
</svg>
|
||||||
@ -111,41 +104,41 @@
|
|||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="overflow-x-auto rounded-lg border border-light-border dark:border-dark-border">
|
<div class="overflow-x-auto rounded-lg border border-light-border dark:border-dark-border mb-8">
|
||||||
<table class="min-w-full divide-y divide-light-border dark:divide-dark-border">
|
<table class="admin-table">
|
||||||
<thead class="bg-slate-50 dark:bg-slate-800 transition-colors">
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Benutzer</th>
|
<th>Benutzer</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Rolle</th>
|
<th>Rolle</th>
|
||||||
<th class="px-6 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Status</th>
|
<th>Status</th>
|
||||||
<th class="px-6 py-3 text-right text-xs font-medium text-slate-500 dark:text-slate-400 uppercase tracking-wider">Aktionen</th>
|
<th class="text-right">Aktionen</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="bg-white dark:bg-dark-card divide-y divide-light-border dark:divide-dark-border transition-colors">
|
<tbody>
|
||||||
{% for user in users %}
|
{% for user in users %}
|
||||||
<tr class="transition-colors hover:bg-slate-50 dark:hover:bg-slate-700">
|
<tr>
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
<td>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center gap-4">
|
||||||
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 dark:bg-blue-900 flex items-center justify-center text-blue-700 dark:text-blue-300 font-medium transition-colors">
|
<div class="flex-shrink-0 h-10 w-10 rounded-full bg-blue-100 dark:bg-blue-900 flex items-center justify-center text-blue-700 dark:text-blue-300 font-medium">
|
||||||
{{ user.email[0]|upper if user.email else 'U' }}
|
{{ user.email[0]|upper if user.email else 'U' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4">
|
<div>
|
||||||
<div class="text-sm font-medium text-slate-900 dark:text-white transition-colors">{{ user.name }}</div>
|
<div class="text-base font-medium text-slate-900 dark:text-white">{{ user.name }}</div>
|
||||||
<div class="text-sm text-slate-500 dark:text-slate-400 transition-colors">{{ user.email }}</div>
|
<div class="text-sm text-slate-500 dark:text-slate-400">{{ user.email }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
<td>
|
||||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full {{ 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200' if user.is_admin else 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200' }} transition-colors">
|
<span class="badge {{ 'badge-info' if user.is_admin else 'badge' }}">
|
||||||
{{ 'Administrator' if user.is_admin else 'Benutzer' }}
|
{{ 'Administrator' if user.is_admin else 'Benutzer' }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap">
|
<td>
|
||||||
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full {{ 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200' if user.active else 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200' }} transition-colors">
|
<span class="badge {{ 'badge-success' if user.active else 'badge-error' }}">
|
||||||
{{ 'Aktiv' if user.active else 'Inaktiv' }}
|
{{ 'Aktiv' if user.active else 'Inaktiv' }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
<td class="text-right">
|
||||||
<form method="post" action="{{ url_for('delete_user', user_id=user.id) }}" class="inline" onsubmit="return confirm('Benutzer wirklich löschen?');">
|
<form method="post" action="{{ url_for('delete_user', user_id=user.id) }}" class="inline" onsubmit="return confirm('Benutzer wirklich löschen?');">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
<button type="submit" class="text-red-600 hover:text-red-900 dark:text-red-400 dark:hover:text-red-300 transition-colors">
|
<button type="submit" class="text-red-600 hover:text-red-900 dark:text-red-400 dark:hover:text-red-300 transition-colors">
|
||||||
@ -160,13 +153,11 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Add User Form -->
|
<!-- Add User Form -->
|
||||||
<div class="mt-8 bg-slate-50 dark:bg-slate-800 rounded-lg p-6 transition-colors">
|
<div class="mt-8 bg-slate-50 dark:bg-slate-800 rounded-lg p-8">
|
||||||
<h4 class="text-lg font-semibold text-slate-900 dark:text-white mb-4 transition-colors">Neuen Benutzer hinzufügen</h4>
|
<h4 class="text-xl font-semibold text-slate-900 dark:text-white mb-4">Neuen Benutzer hinzufügen</h4>
|
||||||
<form action="{{ url_for('create_user') }}" method="post" class="space-y-4">
|
<form action="{{ url_for('create_user') }}" method="post" class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="user-email" class="form-label">Email</label>
|
<label for="user-email" class="form-label">Email</label>
|
||||||
<input type="email" id="user-email" name="email" class="form-input" required>
|
<input type="email" id="user-email" name="email" class="form-input" required>
|
||||||
@ -186,8 +177,7 @@
|
|||||||
<option value="admin">Administrator</option>
|
<option value="admin">Administrator</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col-span-1 md:col-span-2 flex justify-end">
|
||||||
<div class="flex justify-end">
|
|
||||||
<button type="submit" class="btn btn-primary">Benutzer hinzufügen</button>
|
<button type="submit" class="btn btn-primary">Benutzer hinzufügen</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -195,15 +185,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- Printers Tab -->
|
<!-- Printers Tab -->
|
||||||
{% if active_tab == 'printers' %}
|
{% if active_tab == 'printers' %}
|
||||||
<div id="printers-tab" class="tab-pane active">
|
<div id="printers-tab" class="tab-pane active">
|
||||||
<div class="bg-white dark:bg-dark-card rounded-xl shadow-lg p-6 transition-colors">
|
<div class="bg-white dark:bg-dark-card rounded-xl shadow-lg p-8 transition-colors">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex flex-col md:flex-row md:justify-between md:items-center mb-8 gap-4">
|
||||||
<h3 class="text-xl font-bold text-slate-900 dark:text-white transition-colors">Drucker</h3>
|
<h3 class="text-2xl font-bold text-slate-900 dark:text-white">Drucker</h3>
|
||||||
<form action="{{ url_for('admin_page', tab='printers') }}" method="get">
|
<form action="{{ url_for('admin_page', tab='printers') }}" method="get">
|
||||||
<button type="submit" class="btn btn-primary">
|
<button type="submit" class="btn btn-primary flex items-center">
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
|
||||||
</svg>
|
</svg>
|
||||||
@ -211,7 +200,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||||
{% for printer in printers %}
|
{% for printer in printers %}
|
||||||
<div class="printer-card transition-colors">
|
<div class="printer-card transition-colors">
|
||||||
<div class="printer-header">
|
<div class="printer-header">
|
||||||
@ -229,62 +218,59 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="printer-info">
|
<div class="printer-info">
|
||||||
<div>
|
<div>
|
||||||
<span class="text-sm text-slate-500 dark:text-slate-400 transition-colors">Modell:</span>
|
<span class="text-sm text-slate-500 dark:text-slate-400">Modell:</span>
|
||||||
<span class="text-sm font-medium text-slate-900 dark:text-white transition-colors">{{ printer.model }}</span>
|
<span class="text-sm font-medium text-slate-900 dark:text-white">{{ printer.model }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="text-sm text-slate-500 dark:text-slate-400 transition-colors">IP-Adresse:</span>
|
<span class="text-sm text-slate-500 dark:text-slate-400">IP-Adresse:</span>
|
||||||
<span class="text-sm font-medium text-slate-900 dark:text-white transition-colors">{{ printer.ip_address }}</span>
|
<span class="text-sm font-medium text-slate-900 dark:text-white">{{ printer.ip_address }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="text-sm text-slate-500 dark:text-slate-400 transition-colors">Standort:</span>
|
<span class="text-sm text-slate-500 dark:text-slate-400">Standort:</span>
|
||||||
<span class="text-sm font-medium text-slate-900 dark:text-white transition-colors">{{ printer.location or 'Nicht angegeben' }}</span>
|
<span class="text-sm font-medium text-slate-900 dark:text-white">{{ printer.location or 'Nicht angegeben' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="printer-status">
|
<div class="printer-status">
|
||||||
<div class="status-indicator {{ 'status-running' if printer.status == 'online' else 'status-stopped' }} transition-colors"></div>
|
<div class="status-indicator {{ 'status-running' if printer.status == 'online' else 'status-stopped' }}"></div>
|
||||||
<span class="status-text transition-colors">{{ 'Online' if printer.status == 'online' else 'Offline' }}</span>
|
<span class="status-text">{{ 'Online' if printer.status == 'online' else 'Offline' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Add Printer Form -->
|
<!-- Add Printer Form -->
|
||||||
<div class="mt-8 bg-slate-50 dark:bg-slate-800 rounded-lg p-6 transition-colors">
|
<div class="mt-8 bg-slate-50 dark:bg-slate-800 rounded-lg p-8">
|
||||||
<h4 class="text-lg font-semibold text-slate-900 dark:text-white mb-4 transition-colors">Neuen Drucker hinzufügen</h4>
|
<h4 class="text-xl font-semibold text-slate-900 dark:text-white mb-4">Neuen Drucker hinzufügen</h4>
|
||||||
<form action="{{ url_for('create_printer') }}" method="post" class="space-y-4">
|
<form action="{{ url_for('create_printer') }}" method="post" class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="printer-name" class="form-label transition-colors">Name</label>
|
<label for="printer-name" class="form-label">Name</label>
|
||||||
<input type="text" id="printer-name" name="name" class="form-input transition-colors" required>
|
<input type="text" id="printer-name" name="name" class="form-input" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="printer-model" class="form-label transition-colors">Modell</label>
|
<label for="printer-model" class="form-label">Modell</label>
|
||||||
<input type="text" id="printer-model" name="model" class="form-input transition-colors" required>
|
<input type="text" id="printer-model" name="model" class="form-input" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="printer-mac" class="form-label transition-colors">MAC-Adresse</label>
|
<label for="printer-mac" class="form-label">MAC-Adresse</label>
|
||||||
<input type="text" id="printer-mac" name="mac_address" class="form-input transition-colors" required>
|
<input type="text" id="printer-mac" name="mac_address" class="form-input" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="printer-location" class="form-label transition-colors">Standort</label>
|
<label for="printer-location" class="form-label">Standort</label>
|
||||||
<input type="text" id="printer-location" name="location" class="form-input transition-colors">
|
<input type="text" id="printer-location" name="location" class="form-input">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="printer-plug-ip" class="form-label transition-colors">Steckdosen-IP</label>
|
<label for="printer-plug-ip" class="form-label">Steckdosen-IP</label>
|
||||||
<input type="text" id="printer-plug-ip" name="plug_ip" class="form-input transition-colors">
|
<input type="text" id="printer-plug-ip" name="plug_ip" class="form-input">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="printer-plug-username" class="form-label transition-colors">Steckdosen-Benutzername</label>
|
<label for="printer-plug-username" class="form-label">Steckdosen-Benutzername</label>
|
||||||
<input type="text" id="printer-plug-username" name="plug_username" class="form-input transition-colors">
|
<input type="text" id="printer-plug-username" name="plug_username" class="form-input">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="printer-plug-password" class="form-label transition-colors">Steckdosen-Passwort</label>
|
<label for="printer-plug-password" class="form-label">Steckdosen-Passwort</label>
|
||||||
<input type="password" id="printer-plug-password" name="plug_password" class="form-input transition-colors">
|
<input type="password" id="printer-plug-password" name="plug_password" class="form-input">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="col-span-1 md:col-span-2 flex justify-end">
|
||||||
<div class="flex justify-end">
|
|
||||||
<button type="submit" class="btn btn-primary">Drucker hinzufügen</button>
|
<button type="submit" class="btn btn-primary">Drucker hinzufügen</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -292,17 +278,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- Scheduler Tab -->
|
<!-- Scheduler Tab -->
|
||||||
{% if active_tab == 'scheduler' %}
|
{% if active_tab == 'scheduler' %}
|
||||||
<div id="scheduler-tab" class="tab-pane active">
|
<div id="scheduler-tab" class="tab-pane active">
|
||||||
<div class="bg-white dark:bg-dark-card rounded-xl shadow-lg p-6 transition-colors">
|
<div class="bg-white dark:bg-dark-card rounded-xl shadow-lg p-8 transition-colors">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex flex-col md:flex-row md:justify-between md:items-center mb-8 gap-4">
|
||||||
<h3 class="text-xl font-bold text-slate-900 dark:text-white transition-colors">Scheduler Status</h3>
|
<h3 class="text-2xl font-bold text-slate-900 dark:text-white">Scheduler Status</h3>
|
||||||
<div class="flex space-x-4">
|
<div class="flex space-x-4">
|
||||||
<form action="{{ url_for('start_scheduler') }}" method="post" class="inline">
|
<form action="{{ url_for('start_scheduler') }}" method="post" class="inline">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
<button type="submit" class="btn btn-success">
|
<button type="submit" class="btn btn-success flex items-center">
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
@ -312,7 +297,7 @@
|
|||||||
</form>
|
</form>
|
||||||
<form action="{{ url_for('stop_scheduler') }}" method="post" class="inline">
|
<form action="{{ url_for('stop_scheduler') }}" method="post" class="inline">
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
||||||
<button type="submit" class="btn btn-error">
|
<button type="submit" class="btn btn-error flex items-center">
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 10a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4z" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 10a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4z" />
|
||||||
@ -323,121 +308,103 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="scheduler-status">
|
<div class="scheduler-status">
|
||||||
<div class="bg-slate-50 dark:bg-slate-800 rounded-lg p-6 flex items-center justify-between transition-colors">
|
<div class="bg-slate-50 dark:bg-slate-800 rounded-lg p-6 flex flex-col md:flex-row items-center justify-between gap-4 transition-colors">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="status-indicator {{ 'status-running pulse' if scheduler_status.running else 'status-stopped' }}"></div>
|
<div class="status-indicator {{ 'status-running pulse' if scheduler_status.running else 'status-stopped' }}"></div>
|
||||||
<span class="text-xl font-medium ml-3 {{ 'text-green-600 dark:text-green-400' if scheduler_status.running else 'text-red-600 dark:text-red-400' }} transition-colors">
|
<span class="text-xl font-medium ml-3 {{ 'text-green-600 dark:text-green-400' if scheduler_status.running else 'text-red-600 dark:text-red-400' }}">{{ 'Aktiv' if scheduler_status.running else 'Inaktiv' }}</span>
|
||||||
{{ 'Aktiv' if scheduler_status.running else 'Inaktiv' }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="text-slate-700 dark:text-slate-300 transition-colors">
|
<div class="text-slate-700 dark:text-slate-300">{{ scheduler_status.message }}</div>
|
||||||
{{ scheduler_status.message }}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="mt-6 bg-slate-50 dark:bg-slate-800 rounded-lg p-6">
|
||||||
|
<h4 class="text-lg font-semibold text-slate-900 dark:text-white mb-4">Scheduler Informationen</h4>
|
||||||
<div class="mt-6 bg-slate-50 dark:bg-slate-800 rounded-lg p-6 transition-colors">
|
|
||||||
<h4 class="text-lg font-semibold text-slate-900 dark:text-white mb-4 transition-colors">Scheduler Informationen</h4>
|
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<p class="text-slate-700 dark:text-slate-300 transition-colors">
|
<p class="text-slate-700 dark:text-slate-300">
|
||||||
Der Scheduler ist verantwortlich für die automatische Zuweisung und Ausführung von Druckaufträgen.
|
Der Scheduler ist verantwortlich für die automatische Zuweisung und Ausführung von Druckaufträgen. Er überwacht kontinuierlich den Status der Drucker und der anstehenden Jobs.
|
||||||
Er überwacht kontinuierlich den Status der Drucker und der anstehenden Jobs.
|
|
||||||
</p>
|
</p>
|
||||||
<p class="text-slate-700 dark:text-slate-300 transition-colors">
|
<ul class="list-disc list-inside mt-2 space-y-1 text-slate-700 dark:text-slate-300">
|
||||||
<strong>Wichtige Hinweise:</strong>
|
|
||||||
<ul class="list-disc list-inside mt-2 space-y-1">
|
|
||||||
<li>Der Scheduler sollte während des normalen Betriebs immer aktiv sein</li>
|
<li>Der Scheduler sollte während des normalen Betriebs immer aktiv sein</li>
|
||||||
<li>Bei Wartungsarbeiten kann der Scheduler vorübergehend deaktiviert werden</li>
|
<li>Bei Wartungsarbeiten kann der Scheduler vorübergehend deaktiviert werden</li>
|
||||||
<li>Nach einem Neustart des Systems muss der Scheduler manuell gestartet werden</li>
|
<li>Nach einem Neustart des Systems muss der Scheduler manuell gestartet werden</li>
|
||||||
</ul>
|
</ul>
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- System Tab -->
|
<!-- System Tab -->
|
||||||
{% if active_tab == 'system' %}
|
{% if active_tab == 'system' %}
|
||||||
<div id="system-tab" class="tab-pane active">
|
<div id="system-tab" class="tab-pane active">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
|
||||||
<div class="bg-white dark:bg-dark-card rounded-xl shadow-lg p-6 transition-colors">
|
<div class="bg-white dark:bg-dark-card rounded-xl shadow-lg p-8">
|
||||||
<h3 class="text-xl font-bold text-slate-900 dark:text-white mb-6 transition-colors">System Ressourcen</h3>
|
<h3 class="text-2xl font-bold text-slate-900 dark:text-white mb-6">System Ressourcen</h3>
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<div class="flex justify-between mb-2">
|
<div class="flex justify-between mb-2">
|
||||||
<span class="text-slate-700 dark:text-slate-300 transition-colors">CPU Auslastung</span>
|
<span class="text-slate-700 dark:text-slate-300">CPU Auslastung</span>
|
||||||
<span class="text-slate-900 dark:text-white font-medium transition-colors">{{ system_info.cpu }}%</span>
|
<span class="text-slate-900 dark:text-white font-medium">{{ system_info.cpu }}%</span>
|
||||||
</div>
|
</div>
|
||||||
{{ render_progress_bar(system_info.cpu, 'blue')|safe }}
|
{{ render_progress_bar(system_info.cpu, 'blue')|safe }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="flex justify-between mb-2">
|
<div class="flex justify-between mb-2">
|
||||||
<span class="text-slate-700 dark:text-slate-300 transition-colors">Arbeitsspeicher</span>
|
<span class="text-slate-700 dark:text-slate-300">Arbeitsspeicher</span>
|
||||||
<span class="text-slate-900 dark:text-white font-medium transition-colors">{{ system_info.memory }}%</span>
|
<span class="text-slate-900 dark:text-white font-medium">{{ system_info.memory }}%</span>
|
||||||
</div>
|
</div>
|
||||||
{{ render_progress_bar(system_info.memory, 'green')|safe }}
|
{{ render_progress_bar(system_info.memory, 'green')|safe }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="flex justify-between mb-2">
|
<div class="flex justify-between mb-2">
|
||||||
<span class="text-slate-700 dark:text-slate-300 transition-colors">Festplattenspeicher</span>
|
<span class="text-slate-700 dark:text-slate-300">Festplattenspeicher</span>
|
||||||
<span class="text-slate-900 dark:text-white font-medium transition-colors">{{ system_info.disk }}%</span>
|
<span class="text-slate-900 dark:text-white font-medium">{{ system_info.disk }}%</span>
|
||||||
</div>
|
</div>
|
||||||
{{ render_progress_bar(system_info.disk, 'purple')|safe }}
|
{{ render_progress_bar(system_info.disk, 'purple')|safe }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="pt-4 border-t border-gray-200 dark:border-gray-700">
|
||||||
<div class="pt-4 border-t border-gray-200 dark:border-gray-700 transition-colors">
|
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<span class="text-slate-700 dark:text-slate-300 transition-colors">System Uptime</span>
|
<span class="text-slate-700 dark:text-slate-300">System Uptime</span>
|
||||||
<span class="text-slate-900 dark:text-white font-medium transition-colors">{{ system_info.uptime }} Tage</span>
|
<span class="text-slate-900 dark:text-white font-medium">{{ system_info.uptime }} Tage</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="bg-white dark:bg-dark-card rounded-xl shadow-lg p-8">
|
||||||
<div class="bg-white dark:bg-dark-card rounded-xl shadow-lg p-6 transition-colors">
|
<h3 class="text-2xl font-bold text-slate-900 dark:text-white mb-6">Dienste Status</h3>
|
||||||
<h3 class="text-xl font-bold text-slate-900 dark:text-white mb-6 transition-colors">Dienste Status</h3>
|
|
||||||
<div class="space-y-4">
|
<div class="space-y-4">
|
||||||
<div class="flex justify-between items-center p-3 bg-slate-50 dark:bg-slate-800 rounded-lg transition-colors">
|
<div class="flex justify-between items-center p-3 bg-slate-50 dark:bg-slate-800 rounded-lg">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="status-indicator status-running"></div>
|
<div class="status-indicator status-running"></div>
|
||||||
<span class="ml-3 text-slate-900 dark:text-white transition-colors">Webserver</span>
|
<span class="ml-3 text-slate-900 dark:text-white">Webserver</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-green-600 dark:text-green-400 font-medium transition-colors">Online</span>
|
<span class="text-green-600 dark:text-green-400 font-medium">Online</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex justify-between items-center p-3 bg-slate-50 dark:bg-slate-800 rounded-lg">
|
||||||
<div class="flex justify-between items-center p-3 bg-slate-50 dark:bg-slate-800 rounded-lg transition-colors">
|
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="status-indicator {{ 'status-running' if scheduler_status.running else 'status-stopped' }}"></div>
|
<div class="status-indicator {{ 'status-running' if scheduler_status.running else 'status-stopped' }}"></div>
|
||||||
<span class="ml-3 text-slate-900 dark:text-white transition-colors">Scheduler</span>
|
<span class="ml-3 text-slate-900 dark:text-white">Scheduler</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="{{ 'text-green-600 dark:text-green-400' if scheduler_status.running else 'text-red-600 dark:text-red-400' }} font-medium transition-colors">
|
<span class="{{ 'text-green-600 dark:text-green-400' if scheduler_status.running else 'text-red-600 dark:text-red-400' }} font-medium">
|
||||||
{{ 'Online' if scheduler_status.running else 'Offline' }}
|
{{ 'Online' if scheduler_status.running else 'Offline' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex justify-between items-center p-3 bg-slate-50 dark:bg-slate-800 rounded-lg">
|
||||||
<div class="flex justify-between items-center p-3 bg-slate-50 dark:bg-slate-800 rounded-lg transition-colors">
|
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="status-indicator status-running"></div>
|
<div class="status-indicator status-running"></div>
|
||||||
<span class="ml-3 text-slate-900 dark:text-white transition-colors">Datenbank</span>
|
<span class="ml-3 text-slate-900 dark:text-white">Datenbank</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-green-600 dark:text-green-400 font-medium transition-colors">Online</span>
|
<span class="text-green-600 dark:text-green-400 font-medium">Online</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex justify-between items-center p-3 bg-slate-50 dark:bg-slate-800 rounded-lg">
|
||||||
<div class="flex justify-between items-center p-3 bg-slate-50 dark:bg-slate-800 rounded-lg transition-colors">
|
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="status-indicator status-running"></div>
|
<div class="status-indicator status-running"></div>
|
||||||
<span class="ml-3 text-slate-900 dark:text-white transition-colors">Drucker-Manager</span>
|
<span class="ml-3 text-slate-900 dark:text-white">Drucker-Manager</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-green-600 dark:text-green-400 font-medium transition-colors">Online</span>
|
<span class="text-green-600 dark:text-green-400 font-medium">Online</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
<form action="{{ url_for('admin_page', tab='system') }}" method="get">
|
<form action="{{ url_for('admin_page', tab='system') }}" method="get">
|
||||||
<button type="submit" class="btn btn-primary w-full">
|
<button type="submit" class="btn btn-primary w-full flex items-center justify-center">
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
|
||||||
</svg>
|
</svg>
|
||||||
@ -449,13 +416,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<!-- Logs Tab -->
|
<!-- Logs Tab -->
|
||||||
{% if active_tab == 'logs' %}
|
{% if active_tab == 'logs' %}
|
||||||
<div id="logs-tab" class="tab-pane active">
|
<div id="logs-tab" class="tab-pane active">
|
||||||
<div class="bg-white dark:bg-dark-card rounded-xl shadow-lg p-6 transition-colors">
|
<div class="bg-white dark:bg-dark-card rounded-xl shadow-lg p-8 transition-colors">
|
||||||
<div class="flex justify-between items-center mb-6">
|
<div class="flex flex-col md:flex-row md:justify-between md:items-center mb-8 gap-4">
|
||||||
<h3 class="text-xl font-bold text-slate-900 dark:text-white transition-colors">System Logs</h3>
|
<h3 class="text-2xl font-bold text-slate-900 dark:text-white">System Logs</h3>
|
||||||
<div class="flex space-x-4">
|
<div class="flex space-x-4">
|
||||||
<form action="{{ url_for('admin_page', tab='logs') }}" method="get">
|
<form action="{{ url_for('admin_page', tab='logs') }}" method="get">
|
||||||
<div class="flex space-x-2">
|
<div class="flex space-x-2">
|
||||||
@ -466,7 +432,7 @@
|
|||||||
<option value="INFO" {{ 'selected' if request.args.get('log_level') == 'INFO' else '' }}>Info</option>
|
<option value="INFO" {{ 'selected' if request.args.get('log_level') == 'INFO' else '' }}>Info</option>
|
||||||
<option value="DEBUG" {{ 'selected' if request.args.get('log_level') == 'DEBUG' else '' }}>Debug</option>
|
<option value="DEBUG" {{ 'selected' if request.args.get('log_level') == 'DEBUG' else '' }}>Debug</option>
|
||||||
</select>
|
</select>
|
||||||
<button type="submit" class="btn btn-secondary">
|
<button type="submit" class="btn btn-secondary flex items-center">
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
|
||||||
</svg>
|
</svg>
|
||||||
@ -476,18 +442,18 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-slate-50 dark:bg-slate-800 rounded-lg p-4 max-h-[600px] overflow-y-auto transition-colors">
|
<div class="bg-slate-50 dark:bg-slate-800 rounded-lg p-4 max-h-[600px] overflow-y-auto">
|
||||||
{% if logs %}
|
{% if logs %}
|
||||||
{% for log in logs %}
|
{% for log in logs %}
|
||||||
<div class="log-entry log-{{ log.level|lower }}">
|
<div class="log-entry log-{{ log.level|lower }}">
|
||||||
<div class="flex items-start">
|
<div class="flex items-start gap-4">
|
||||||
<div class="min-w-[160px] text-xs text-slate-500 dark:text-slate-400">{{ log.timestamp }}</div>
|
<div class="min-w-[160px] text-xs text-slate-500 dark:text-slate-400">{{ log.timestamp }}</div>
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center gap-2">
|
||||||
<span class="badge badge-{{ 'success' if log.level == 'INFO' else ('warning' if log.level == 'WARNING' else ('error' if log.level == 'ERROR' else ('info' if log.level == 'DEBUG' else 'error'))) }}">
|
<span class="badge badge-{{ 'success' if log.level == 'INFO' else ('warning' if log.level == 'WARNING' else ('error' if log.level == 'ERROR' else ('info' if log.level == 'DEBUG' else 'error'))) }}">
|
||||||
{{ log.level }}
|
{{ log.level }}
|
||||||
</span>
|
</span>
|
||||||
<span class="ml-2 text-xs font-medium text-slate-700 dark:text-slate-300">[{{ log.category }}]</span>
|
<span class="text-xs font-medium text-slate-700 dark:text-slate-300">[{{ log.category }}]</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-1 text-sm text-slate-700 dark:text-slate-300">{{ log.message }}</div>
|
<div class="mt-1 text-sm text-slate-700 dark:text-slate-300">{{ log.message }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -151,7 +151,20 @@ def install_certificate_system():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
import subprocess
|
import subprocess
|
||||||
ssl_cert_path = os.path.abspath("app/instance/ssl/myp.crt")
|
import os
|
||||||
|
ssl_cert_path = os.path.abspath(os.path.join("app", "instance", "ssl", "myp.crt"))
|
||||||
|
|
||||||
|
# Prüfen, ob Datei existiert
|
||||||
|
if not os.path.exists(ssl_cert_path):
|
||||||
|
print(f"Zertifikat nicht gefunden unter: {ssl_cert_path}")
|
||||||
|
# Alternativen Pfad versuchen
|
||||||
|
alt_path = os.path.abspath(os.path.join("backend", "app", "instance", "ssl", "myp.crt"))
|
||||||
|
if os.path.exists(alt_path):
|
||||||
|
ssl_cert_path = alt_path
|
||||||
|
print(f"Verwende alternativen Pfad: {ssl_cert_path}")
|
||||||
|
else:
|
||||||
|
print("Zertifikat konnte nicht gefunden werden.")
|
||||||
|
return False
|
||||||
|
|
||||||
# Befehle zum Installieren des Zertifikats im Windows-Zertifikatsspeicher
|
# Befehle zum Installieren des Zertifikats im Windows-Zertifikatsspeicher
|
||||||
commands = [
|
commands = [
|
||||||
|
@ -17,13 +17,30 @@ const NEXT_CONFIG_PATH = path.join(__dirname, 'next.config.js');
|
|||||||
|
|
||||||
console.log('=== Frontend-SSL-Konfiguration ===');
|
console.log('=== Frontend-SSL-Konfiguration ===');
|
||||||
|
|
||||||
// Prüfen, ob SSL-Verzeichnis und Zertifikate existieren
|
// Verzeichnis erstellen, falls es nicht existiert
|
||||||
if (!fs.existsSync(SSL_DIR) ||
|
if (!fs.existsSync(SSL_DIR)) {
|
||||||
!fs.existsSync(path.join(SSL_DIR, 'myp.crt')) ||
|
console.log(`SSL-Verzeichnis wird erstellt: ${SSL_DIR}`);
|
||||||
!fs.existsSync(path.join(SSL_DIR, 'myp.key'))) {
|
fs.mkdirSync(SSL_DIR, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prüfen, ob SSL-Zertifikate existieren
|
||||||
|
if (!fs.existsSync(path.join(SSL_DIR, 'myp.crt')) || !fs.existsSync(path.join(SSL_DIR, 'myp.key'))) {
|
||||||
|
console.log('SSL-Zertifikate nicht gefunden. Prüfe Backend-Verzeichnis...');
|
||||||
|
|
||||||
|
// Versuche, die Zertifikate aus dem Backend zu kopieren
|
||||||
|
const backendCertPath = path.join('..', 'backend', 'app', 'instance', 'ssl', 'myp.crt');
|
||||||
|
const backendKeyPath = path.join('..', 'backend', 'app', 'instance', 'ssl', 'myp.key');
|
||||||
|
|
||||||
|
if (fs.existsSync(backendCertPath) && fs.existsSync(backendKeyPath)) {
|
||||||
|
console.log('Zertifikate im Backend-Verzeichnis gefunden. Kopiere...');
|
||||||
|
fs.copyFileSync(backendCertPath, path.join(SSL_DIR, 'myp.crt'));
|
||||||
|
fs.copyFileSync(backendKeyPath, path.join(SSL_DIR, 'myp.key'));
|
||||||
|
console.log('Zertifikate erfolgreich in das Frontend-Verzeichnis kopiert.');
|
||||||
|
} else {
|
||||||
console.error('SSL-Zertifikate nicht gefunden. Bitte zuerst das Backend-Skript ausführen.');
|
console.error('SSL-Zertifikate nicht gefunden. Bitte zuerst das Backend-Skript ausführen.');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
console.log('SSL-Zertifikate gefunden. Konfiguriere Frontend...');
|
console.log('SSL-Zertifikate gefunden. Konfiguriere Frontend...');
|
||||||
|
|
||||||
|
36
frontend/next.config.js
Normal file
36
frontend/next.config.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const nextConfig = {
|
||||||
|
reactStrictMode: true,
|
||||||
|
webpack: (config) => {
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
// HTTPS-Konfiguration für die Entwicklung
|
||||||
|
devServer: {
|
||||||
|
https: {
|
||||||
|
key: fs.readFileSync(path.resolve(__dirname, 'ssl/myp.key')),
|
||||||
|
cert: fs.readFileSync(path.resolve(__dirname, 'ssl/myp.crt')),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Konfiguration für selbstsignierte Zertifikate
|
||||||
|
serverOptions: {
|
||||||
|
https: {
|
||||||
|
key: fs.readFileSync(path.resolve(__dirname, 'ssl/myp.key')),
|
||||||
|
cert: fs.readFileSync(path.resolve(__dirname, 'ssl/myp.crt')),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Zusätzliche Konfigurationen
|
||||||
|
async rewrites() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
source: '/api/:path*',
|
||||||
|
destination: 'https://raspberrypi:443/api/:path*',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = nextConfig;
|
1164
frontend/package-lock.json
generated
1164
frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -75,6 +75,7 @@
|
|||||||
"@types/react": "^18.3.11",
|
"@types/react": "^18.3.11",
|
||||||
"@types/react-dom": "^18.3.1",
|
"@types/react-dom": "^18.3.1",
|
||||||
"drizzle-kit": "^0.21.4",
|
"drizzle-kit": "^0.21.4",
|
||||||
|
"https-localhost": "^4.7.1",
|
||||||
"postcss": "^8.4.47",
|
"postcss": "^8.4.47",
|
||||||
"tailwindcss": "^3.4.13",
|
"tailwindcss": "^3.4.13",
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
// SSL-Verbindungen akzeptieren (selbstsignierte Zertifikate)
|
||||||
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
||||||
|
|
||||||
// Basis-URL für Backend-API
|
// Basis-URL für Backend-API
|
||||||
// Versucht verschiedene Verbindungsoptionen mit Fallbacks
|
// Versucht verschiedene Verbindungsoptionen mit Fallbacks
|
||||||
const getApiBaseUrl = () => {
|
const getApiBaseUrl = () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user