diff --git a/server.js b/server.js
index ebd84c7..bc9e13f 100644
--- a/server.js
+++ b/server.js
@@ -1710,6 +1710,46 @@ initializeDatabase().then(async () => {
}
});
+ // Alle Aktivitäten (Statusänderungen), seitenweise. Die Startseite zeigt nur die
+ // jüngsten acht — hier steht der vollständige Verlauf über alle Bewerbungen.
+ const AKTIVITAETEN_PRO_SEITE = 25;
+
+ app.get('/aktivitaeten', async (req, res) => {
+ try {
+ const U = uid();
+ const gesamtRow = await dbGet('SELECT COUNT(*) AS anzahl FROM status_verlauf WHERE user_id = ?', [U]);
+ const gesamt = gesamtRow ? gesamtRow.anzahl : 0;
+ const seiten = Math.max(1, Math.ceil(gesamt / AKTIVITAETEN_PRO_SEITE));
+
+ // Eine Seite außerhalb des Bereichs (getippt oder nach dem Löschen von
+ // Einträgen) klemmen wir auf den gültigen Rand, statt eine leere Seite zu zeigen.
+ const gewuenscht = parseInt(req.query.seite, 10);
+ const seite = Math.min(Math.max(Number.isInteger(gewuenscht) ? gewuenscht : 1, 1), seiten);
+
+ const aktivitaet = await dbAll(`
+ SELECT sv.datum, sv.status, sv.kommentar,
+ b.id AS bewerbung_id, b.firma, b.stelle
+ FROM status_verlauf sv
+ LEFT JOIN bewerbungen b ON b.id = sv.bewerbung_id AND b.user_id = sv.user_id
+ WHERE sv.user_id = ?
+ ORDER BY datetime(sv.created_at) DESC, sv.id DESC
+ LIMIT ? OFFSET ?
+ `, [U, AKTIVITAETEN_PRO_SEITE, (seite - 1) * AKTIVITAETEN_PRO_SEITE]);
+
+ res.render('aktivitaeten', {
+ aktivitaet,
+ gesamt,
+ seite,
+ seiten,
+ proSeite: AKTIVITAETEN_PRO_SEITE,
+ hideSettings: false,
+ });
+ } catch (error) {
+ console.error('Error loading aktivitaeten:', error);
+ res.status(500).send('Serverfehler');
+ }
+ });
+
// Statistik — comprehensive, on its own page. The dashboard only carries a
// quick glance now; everything that needs room to breathe lives here.
app.get('/statistik', async (req, res) => {
diff --git a/views/aktivitaeten.ejs b/views/aktivitaeten.ejs
new file mode 100644
index 0000000..84d8d92
--- /dev/null
+++ b/views/aktivitaeten.ejs
@@ -0,0 +1,157 @@
+
+
+
+ <%- include('partials/head') %>
+
+
+ <%- include('partials/header') %>
+
+
+ <%
+ // Farben synchron zur Startseite (views/index.ejs) halten.
+ const statusDot = {
+ 'Entwurf': 'bg-purple-500',
+ 'Gesendet': 'bg-indigo-500',
+ 'Eingangsbestätigung': 'bg-blue-500',
+ 'In Bearbeitung': 'bg-teal-500',
+ 'Interessiert': 'bg-pink-500',
+ 'Warten auf Rückmeldung': 'bg-orange-500',
+ 'Warten auf meine Antwort': 'bg-fuchsia-500',
+ 'Vorstellungsgespräch': 'bg-yellow-500',
+ 'Vertragsverhandlung': 'bg-lime-500',
+ 'Einstellung': 'bg-green-500',
+ 'Absage': 'bg-red-500',
+ 'Absage von meiner Seite': 'bg-rose-500',
+ 'Keine Rückmeldung': 'bg-gray-400'
+ };
+
+ // Welche Seitenzahlen die Blätterleiste zeigt: erste, letzte, die aktuelle
+ // und je eine daneben — dazwischen Auslassungen (null). Bei wenigen Seiten
+ // stehen ohnehin alle da.
+ const zahlen = [];
+ for (let i = 1; i <= seiten; i++) {
+ const nah = Math.abs(i - seite) <= 1;
+ const rand = (i === 1 || i === seiten);
+ if (nah || rand) {
+ if (zahlen.length && zahlen[zahlen.length - 1] !== null && i - zahlen[zahlen.length - 1] > 1) zahlen.push(null);
+ zahlen.push(i);
+ }
+ }
+ const von = gesamt === 0 ? 0 : (seite - 1) * proSeite + 1;
+ const bis = Math.min(seite * proSeite, gesamt);
+ %>
+
+
+
+
Aktivitäten
+
+ Jede Statusänderung, über alle Bewerbungen hinweg – die jüngste zuerst.
+
+
+
Zurück zu den Bewerbungen
+
+
+
+
+
+ <% if (gesamt) { %>
+ <%= von %>–<%= bis %>
+ von <%= gesamt %>
+ <%= gesamt === 1 ? 'Eintrag' : 'Einträgen' %>
+ <% } else { %>
+ Keine Einträge
+ <% } %>
+
+ <% if (seiten > 1) { %>
+
Seite <%= seite %> von <%= seiten %>
+ <% } %>
+
+
+ <% if (aktivitaet.length) { %>
+
+ <% } else { %>
+
+ Noch keine Statusänderungen protokolliert.
+
+ <% } %>
+
+ <% if (seiten > 1) { %>
+
+
+ <% } %>
+
+
+
+ <%- include('partials/footer') %>
+
+
diff --git a/views/index.ejs b/views/index.ejs
index d746c1b..8ab46b5 100644
--- a/views/index.ejs
+++ b/views/index.ejs
@@ -333,15 +333,22 @@
<% if (aktivitaet && aktivitaet.length) { %>
diff --git a/views/statistik.ejs b/views/statistik.ejs
index 18c66c9..9e349d9 100644
--- a/views/statistik.ejs
+++ b/views/statistik.ejs
@@ -308,7 +308,10 @@
Letzte Aktivität
-
Die jüngsten Statusänderungen deiner Bewerbungen.
+
+ Die jüngsten Statusänderungen deiner Bewerbungen.
+ Alle
+
<% if (aktivitaet.length) {
const statusColor = (s) => ({
'Entwurf':'#94a3b8','Gesendet':'#3b82f6','Eingangsbestätigung':'#0ea5e9','In Bearbeitung':'#6366f1',