v1.0
This commit is contained in:
@@ -12,20 +12,20 @@ Willkommen {{ user.username }}
|
||||
|
||||
{# Navigation #}
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-2 mb-6">
|
||||
<a href="{% url 'invoices:overview' %}" class="group p-4 rounded-xl bg-white dark:bg-slate-800 border border-slate-100 dark:border-slate-700 hover:border-[var(--company-color)]/40 hover:shadow-sm transition-all duration-200">
|
||||
<p class="text-[11px] text-slate-400 mb-0.5">Modul</p>
|
||||
<a href="{% url 'invoices:overview' %}" class="group p-4 rounded-xl bg-white dark:bg-slate-800 company-border hover:shadow-sm transition-all duration-200">
|
||||
<p class="text-sm text-slate-400 mb-0.5">Modul</p>
|
||||
<p class="text-sm font-semibold text-slate-800 dark:text-white">Rechnungswesen</p>
|
||||
</a>
|
||||
<a href="{% url 'inventory_global:overview' %}" class="group p-4 rounded-xl bg-white dark:bg-slate-800 border border-slate-100 dark:border-slate-700 hover:border-[var(--company-color)]/40 hover:shadow-sm transition-all duration-200">
|
||||
<p class="text-[11px] text-slate-400 mb-0.5">Modul</p>
|
||||
<a href="{% url 'inventory_global:overview' %}" class="group p-4 rounded-xl bg-white dark:bg-slate-800 company-border hover:shadow-sm transition-all duration-200">
|
||||
<p class="text-sm text-slate-400 mb-0.5">Modul</p>
|
||||
<p class="text-sm font-semibold text-slate-800 dark:text-white">Inventar</p>
|
||||
</a>
|
||||
<a href="{% url 'accounts:overview' %}" class="group p-4 rounded-xl bg-white dark:bg-slate-800 border border-slate-100 dark:border-slate-700 hover:border-[var(--company-color)]/40 hover:shadow-sm transition-all duration-200">
|
||||
<p class="text-[11px] text-slate-400 mb-0.5">Modul</p>
|
||||
<a href="{% url 'accounts:overview' %}" class="group p-4 rounded-xl bg-white dark:bg-slate-800 company-border hover:shadow-sm transition-all duration-200">
|
||||
<p class="text-sm text-slate-400 mb-0.5">Modul</p>
|
||||
<p class="text-sm font-semibold text-slate-800 dark:text-white">Mitarbeiter</p>
|
||||
</a>
|
||||
<a href="{% url 'masterdata:overview' %}" class="group p-4 rounded-xl bg-white dark:bg-slate-800 border border-slate-100 dark:border-slate-700 hover:border-[var(--company-color)]/40 hover:shadow-sm transition-all duration-200">
|
||||
<p class="text-[11px] text-slate-400 mb-0.5">Modul</p>
|
||||
<a href="{% url 'masterdata:overview' %}" class="group p-4 rounded-xl bg-white dark:bg-slate-800 company-border hover:shadow-sm transition-all duration-200">
|
||||
<p class="text-sm text-slate-400 mb-0.5">Modul</p>
|
||||
<p class="text-sm font-semibold text-slate-800 dark:text-white">Einstellungen</p>
|
||||
</a>
|
||||
</div>
|
||||
@@ -34,8 +34,8 @@ Willkommen {{ user.username }}
|
||||
<div class="bg-white dark:bg-slate-800 rounded-2xl border border-slate-100 dark:border-slate-700 overflow-hidden mb-6">
|
||||
|
||||
{# KPIs #}
|
||||
<div class="px-5 pt-5 pb-4 border-b border-slate-100 dark:border-slate-700">
|
||||
<p class="text-[11px] font-semibold uppercase tracking-widest text-slate-400 mb-3">Handlungsbedarf</p>
|
||||
<div class="p-4 border-b border-slate-100 dark:border-slate-700">
|
||||
<p class="text-sm font-semibold uppercase tracking-widest text-slate-400 mb-3">Handlungsbedarf</p>
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-2" id="kpiMetrics">
|
||||
<div class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4 animate-pulse h-16"></div>
|
||||
<div class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4 animate-pulse h-16"></div>
|
||||
@@ -45,49 +45,49 @@ Willkommen {{ user.username }}
|
||||
</div>
|
||||
|
||||
{# Charts #}
|
||||
<div class="px-5 py-4 border-b border-slate-100 dark:border-slate-700">
|
||||
<p class="text-[11px] font-semibold uppercase tracking-widest text-slate-400 mb-3">Aktueller Monat</p>
|
||||
<div class="p-4 border-b border-slate-100 dark:border-slate-700">
|
||||
<p class="text-sm font-semibold uppercase tracking-widest text-slate-400 mb-3">Aktueller Monat</p>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-2">
|
||||
|
||||
<div class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<p class="text-xs font-semibold text-slate-600 dark:text-slate-300">Rechnungen</p>
|
||||
<a href="{% url 'invoices:invoices_invoices_overview' %}" class="text-[11px] text-[var(--company-color)] hover:underline">Alle →</a>
|
||||
<p class="text-sm text-slate-400 mb-1">Rechnungen</p>
|
||||
<a href="{% url 'invoices:invoices_invoices_overview' %}" class="text-sm text-[var(--company-color)] hover:underline">Alle →</a>
|
||||
</div>
|
||||
<div style="position:relative;height:120px;">
|
||||
<canvas id="invoiceChart" role="img" aria-label="Rechnungen nach Status"></canvas>
|
||||
</div>
|
||||
<div id="invoiceLegend" class="flex flex-wrap gap-x-2 gap-y-1 mt-3"></div>
|
||||
<div id="invoiceLegend" class="flex flex-wrap gap-4 mt-3"></div>
|
||||
</div>
|
||||
|
||||
<div class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<p class="text-xs font-semibold text-slate-600 dark:text-slate-300">Angebote</p>
|
||||
<a href="{% url 'invoices:invoices_offers_overview' %}" class="text-[11px] text-[var(--company-color)] hover:underline">Alle →</a>
|
||||
<p class="text-sm text-slate-400 mb-1">Angebote</p>
|
||||
<a href="{% url 'invoices:invoices_offers_overview' %}" class="text-sm text-[var(--company-color)] hover:underline">Alle →</a>
|
||||
</div>
|
||||
<div style="position:relative;height:120px;">
|
||||
<canvas id="offerChart" role="img" aria-label="Angebote nach Status"></canvas>
|
||||
</div>
|
||||
<div id="offerLegend" class="flex flex-wrap gap-x-2 gap-y-1 mt-3"></div>
|
||||
<div id="offerLegend" class="flex flex-wrap gap-4 mt-3"></div>
|
||||
</div>
|
||||
|
||||
<div class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4">
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<p class="text-xs font-semibold text-slate-600 dark:text-slate-300">Mahnungen</p>
|
||||
<a href="{% url 'invoices:invoices_reminders_overview' %}" class="text-[11px] text-[var(--company-color)] hover:underline">Alle →</a>
|
||||
<p class="text-sm text-slate-400 mb-1">Mahnungen</p>
|
||||
<a href="{% url 'invoices:invoices_reminders_overview' %}" class="text-sm text-[var(--company-color)] hover:underline">Alle →</a>
|
||||
</div>
|
||||
<div style="position:relative;height:120px;">
|
||||
<canvas id="reminderChart" role="img" aria-label="Mahnungen nach Status"></canvas>
|
||||
</div>
|
||||
<div id="reminderLegend" class="flex flex-wrap gap-x-2 gap-y-1 mt-3"></div>
|
||||
<div id="reminderLegend" class="flex flex-wrap gap-4 mt-3"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Kunden #}
|
||||
<div class="px-5 py-4">
|
||||
<p class="text-[11px] font-semibold uppercase tracking-widest text-slate-400 mb-3">Kunden</p>
|
||||
<div class="p-4">
|
||||
<p class="text-sm font-semibold uppercase tracking-widest text-slate-400 mb-3">Kunden</p>
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-2" id="customerMetrics">
|
||||
<div class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4 animate-pulse h-16"></div>
|
||||
<div class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4 animate-pulse h-16"></div>
|
||||
@@ -124,7 +124,7 @@ function buildDonut(canvasId, legendId, data) {
|
||||
const entries = Object.entries(data).filter(([, v]) => v > 0);
|
||||
if (!entries.length) {
|
||||
document.getElementById(canvasId).parentElement.innerHTML =
|
||||
'<p class="text-[11px] text-slate-400 text-center py-8">Keine Einträge diesen Monat</p>';
|
||||
'<p class="text-sm text-slate-400 text-center py-8">Keine Einträge diesen Monat</p>';
|
||||
return;
|
||||
}
|
||||
const keys = entries.map(([k]) => k);
|
||||
@@ -162,7 +162,7 @@ function buildDonut(canvasId, legendId, data) {
|
||||
const legend = document.getElementById(legendId);
|
||||
keys.forEach((k, i) => {
|
||||
const item = document.createElement('span');
|
||||
item.className = 'flex items-center gap-1 text-[11px] text-slate-400 dark:text-slate-400';
|
||||
item.className = 'flex items-center gap-1 text-sm text-slate-400 dark:text-slate-400';
|
||||
item.innerHTML = `
|
||||
<span style="width:6px;height:6px;border-radius:50%;background:${colors[i]};display:inline-block;flex-shrink:0;"></span>
|
||||
${labels[i]}: <span class="font-medium text-slate-700 dark:text-slate-200">${values[i]}</span>
|
||||
@@ -178,7 +178,7 @@ async function fetchAndRender(url, canvasId, legendId) {
|
||||
buildDonut(canvasId, legendId, await r.json());
|
||||
} catch {
|
||||
document.getElementById(canvasId).parentElement.innerHTML =
|
||||
'<p class="text-[11px] text-slate-400 text-center py-8">Keine Daten</p>';
|
||||
'<p class="text-sm text-slate-400 text-center py-8">Keine Daten</p>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,28 +190,28 @@ async function fetchKpis(url) {
|
||||
document.getElementById('kpiMetrics').innerHTML = `
|
||||
<a href="{% url 'invoices:invoices_invoices_overview' %}?status=overdue"
|
||||
class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4 transition-colors block">
|
||||
<p class="text-[11px] text-slate-400 mb-1">Überfällige Rechnungen</p>
|
||||
<p class="text-sm text-slate-400 mb-1">Überfällige Rechnungen</p>
|
||||
<p class="text-2xl font-semibold ${d.overdue_invoices > 0 ? 'text-red-500' : 'text-slate-800 dark:text-white'}">${d.overdue_invoices}</p>
|
||||
</a>
|
||||
<a href="{% url 'invoices:invoices_invoices_overview' %}?status=sent"
|
||||
class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4 transition-colors block">
|
||||
<p class="text-[11px] text-slate-400 mb-1">Offene Rechnungen</p>
|
||||
<p class="text-sm text-slate-400 mb-1">Offene Rechnungen</p>
|
||||
<p class="text-2xl font-semibold text-slate-800 dark:text-white">${d.open_invoices}</p>
|
||||
</a>
|
||||
<a href="{% url 'invoices:invoices_offers_overview' %}?status=sent"
|
||||
class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4 transition-colors block">
|
||||
<p class="text-[11px] text-slate-400 mb-1">Offene Angebote</p>
|
||||
<p class="text-sm text-slate-400 mb-1">Offene Angebote</p>
|
||||
<p class="text-2xl font-semibold text-slate-800 dark:text-white">${d.open_offers}</p>
|
||||
</a>
|
||||
<a href="{% url 'invoices:invoices_reminders_overview' %}?status=sent"
|
||||
class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4 transition-colors block">
|
||||
<p class="text-[11px] text-slate-400 mb-1">Offene Mahnungen</p>
|
||||
<p class="text-sm text-slate-400 mb-1">Offene Mahnungen</p>
|
||||
<p class="text-2xl font-semibold ${d.open_reminders > 0 ? 'text-amber-500' : 'text-slate-800 dark:text-white'}">${d.open_reminders}</p>
|
||||
</a>
|
||||
`;
|
||||
} catch {
|
||||
document.getElementById('kpiMetrics').innerHTML =
|
||||
'<p class="text-[11px] text-slate-400">Keine Daten</p>';
|
||||
'<p class="text-sm text-slate-400">Keine Daten</p>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,25 +222,25 @@ async function fetchCustomers(url) {
|
||||
const d = await r.json();
|
||||
document.getElementById('customerMetrics').innerHTML = `
|
||||
<div class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4">
|
||||
<p class="text-[11px] text-slate-400 mb-1">Gesamt</p>
|
||||
<p class="text-sm text-slate-400 mb-1">Gesamt</p>
|
||||
<p class="text-2xl font-semibold text-slate-800 dark:text-white">${d.total}</p>
|
||||
</div>
|
||||
<div class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4">
|
||||
<p class="text-[11px] text-slate-400 mb-1">Neue diese Woche</p>
|
||||
<p class="text-sm text-slate-400 mb-1">Neue diese Woche</p>
|
||||
<p class="text-2xl font-semibold text-slate-800 dark:text-white">${d.new_this_week}</p>
|
||||
</div>
|
||||
<div class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4">
|
||||
<p class="text-[11px] text-slate-400 mb-1">Privatkunden</p>
|
||||
<p class="text-sm text-slate-400 mb-1">Privatkunden</p>
|
||||
<p class="text-2xl font-semibold text-slate-800 dark:text-white">${d.private}</p>
|
||||
</div>
|
||||
<div class="rounded-xl bg-slate-100 dark:bg-slate-700 p-4">
|
||||
<p class="text-[11px] text-slate-400 mb-1">Unternehmen</p>
|
||||
<p class="text-sm text-slate-400 mb-1">Unternehmen</p>
|
||||
<p class="text-2xl font-semibold text-slate-800 dark:text-white">${d.companies}</p>
|
||||
</div>
|
||||
`;
|
||||
} catch {
|
||||
document.getElementById('customerMetrics').innerHTML =
|
||||
'<p class="text-[11px] text-slate-400">Keine Daten</p>';
|
||||
'<p class="text-sm text-slate-400">Keine Daten</p>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user