server-verwaltung/fleetledger/app/templates/servers_list.html
nocci b9cfefa3a9 feat(fleetledger): add initial implementation of FleetLedger app
- introduce Dockerfile for Python environment setup
- create FastAPI app with authentication and user management
- implement server management features with CRUD operations
- add PWA support with service worker and manifest
- set up initial templates for UI components

📝 docs(fleetledger): add README for FleetLedger application

- describe app features and functionalities
- provide security notes and quick start guide

📦 build(fleetledger): configure Docker and docker-compose setup

- define Dockerfile for application container
- create docker-compose.yml for service orchestration
- specify environment variables and volumes for persistence
2025-12-06 11:40:51 +00:00

125 lines
5.3 KiB
HTML
Raw 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 content %}
<div class="flex flex-col gap-4">
<div class="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
<div>
<h1 class="text-lg font-semibold tracking-tight">Deine Server</h1>
<p class="text-xs text-slate-400">
Übersicht aller gemieteten VPS, dedizierten Server und Storage-Systeme.
</p>
</div>
<div class="flex items-center gap-3 text-xs text-slate-400">
{% if not can_encrypt %}
<span class="px-2 py-1 rounded-md border border-amber-500/60 bg-amber-500/10 text-amber-200">
Hinweis: ENCRYPTION_KEY nicht gesetzt Passwörter werden nicht gespeichert.
</span>
{% endif %}
</div>
</div>
{% if stats %}
<!-- Small dashboard summary row -->
<div class="grid grid-cols-2 sm:grid-cols-4 gap-3 text-xs">
<div class="rounded-xl border border-slate-800 bg-slate-900/70 px-3 py-3 flex flex-col">
<span class="text-[11px] text-slate-400 mb-1">Gesamt</span>
<span class="text-lg font-semibold text-slate-100">
{{ stats.total_servers }}
</span>
<span class="text-[11px] text-slate-500 mt-1">aktive Server</span>
</div>
<div class="rounded-xl border border-slate-800 bg-slate-900/70 px-3 py-3 flex flex-col">
<span class="text-[11px] text-slate-400 mb-1">Laufende Kosten</span>
<span class="text-lg font-semibold text-slate-100">
{{ "%.2f"|format(stats.monthly_total) }}
{% if stats.monthly_currency %} {{ stats.monthly_currency }}{% endif %}
</span>
<span class="text-[11px] text-slate-500 mt-1">
pro Monat{% if stats.mixed_currencies %} (gemischte Währungen){% endif %}
</span>
</div>
<div class="rounded-xl border border-amber-500/40 bg-amber-500/10 px-3 py-3 flex flex-col">
<span class="text-[11px] text-amber-200 mb-1">Laufen bald aus</span>
<span class="text-lg font-semibold text-amber-100">
{{ stats.expiring_soon }}
</span>
<span class="text-[11px] text-amber-200/80 mt-1">≤ 30 Tage</span>
</div>
<div class="rounded-xl border border-rose-600/60 bg-rose-600/10 px-3 py-3 flex flex-col">
<span class="text-[11px] text-rose-100 mb-1">Abgelaufen</span>
<span class="text-lg font-semibold text-rose-50">
{{ stats.expired }}
</span>
<span class="text-[11px] text-rose-100/80 mt-1">Vertrag beendet</span>
</div>
</div>
{% endif %}
{% if servers %}
<div class="overflow-hidden rounded-xl border border-slate-800 bg-slate-900/60">
<table class="min-w-full text-sm">
<thead class="bg-slate-900/80">
<tr class="text-xs uppercase tracking-wide text-slate-400">
<th class="px-3 py-2 text-left">Name</th>
<th class="px-3 py-2 text-left">Provider</th>
<th class="px-3 py-2 text-left">Type</th>
<th class="px-3 py-2 text-left">Location</th>
<th class="px-3 py-2 text-left">IPv4</th>
<th class="px-3 py-2 text-right">Kosten</th>
</tr>
</thead>
<tbody>
{% for s in servers %}
<tr class="border-t border-slate-800/80 hover:bg-slate-800/50">
<td class="px-3 py-2">
<div class="flex items-center gap-2">
<div>
<a href="/servers/{{ s.id }}" class="text-slate-100 hover:text-indigo-300 font-medium">
{{ s.name }}
</a>
{% if s.hostname %}
<div class="text-[11px] text-slate-400">{{ s.hostname }}</div>
{% endif %}
</div>
{% if s.is_expired %}
<span class="inline-flex items-center rounded-full bg-rose-600/15 border border-rose-600/60 px-2 py-0.5 text-[10px] text-rose-200">
abgelaufen
</span>
{% elif s.is_expiring_soon %}
<span class="inline-flex items-center rounded-full bg-amber-500/15 border border-amber-500/60 px-2 py-0.5 text-[10px] text-amber-200">
läuft bald aus
</span>
{% endif %}
</div>
</td>
<td class="px-3 py-2 text-slate-200">{{ s.provider }}</td>
<td class="px-3 py-2">
<span class="inline-flex rounded-full bg-slate-800 px-2 py-0.5 text-[11px] text-slate-300">
{{ s.type }}
</span>
</td>
<td class="px-3 py-2 text-slate-200">
{% if s.location %}{{ s.location }}{% else %}<span class="text-slate-500"></span>{% endif %}
</td>
<td class="px-3 py-2 text-slate-200">
{% if s.ipv4 %}{{ s.ipv4 }}{% else %}<span class="text-slate-500"></span>{% endif %}
</td>
<td class="px-3 py-2 text-right text-slate-200">
{% if s.price %}
{{ "%.2f"|format(s.price) }} {{ s.currency }}
<span class="text-[11px] text-slate-400">/ {{ "Monat" if s.billing_period == "monthly" else "Jahr" }}</span>
{% else %}
<span class="text-slate-500"></span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="rounded-xl border border-dashed border-slate-700 bg-slate-900/40 p-6 text-sm text-slate-300">
Noch keine Server erfasst. Leg den ersten mit „Server anlegen“ oben rechts an.
</div>
{% endif %}
</div>
{% endblock %}