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 @@

Letzte Aktivitäten

- Alle in der Statistik + Alle
<% 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',