Geburtstagskalender + Geburtstagsgruß-Modal im Kundenportal
Admin (Vertrags-Cockpit): - Neue Section "Geburtstage" zeigt Kunden mit Geburtstag - Fenster: -7 bis +30 Tage um heute - Farbcodierung: heute (pink), vergangen (amber), bevorstehend (grau) - Anzeige: Name, Kundennummer, Geburtsdatum, Alter, "Heute!" / "In X Tagen" / "Vor X Tagen" Portal (Kundenportal): - Modal mit Geburtstagsgruß wenn Geburtstag heute oder in den letzten 7 Tagen war - Unterscheidet zwischen aktuellem Geburtstag und nachträglichen Glückwünschen - Schönes Gradient-Design mit Konfetti-Emojis - Wird pro Jahr nur einmal angezeigt (Customer.lastBirthdayGreetingYear) - Bestätigung speichert das aktuelle Jahr Backend: - Neues Feld Customer.lastBirthdayGreetingYear (Int?) - Service birthday.service.ts mit Fenster-Logik + Alter-Berechnung - Endpoints /api/birthdays/upcoming (Admin), /api/birthdays/my-birthday (Portal GET + POST /acknowledge) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
import { Response } from 'express';
|
||||
import { AuthRequest } from '../types/index.js';
|
||||
import * as birthdayService from '../services/birthday.service.js';
|
||||
|
||||
/**
|
||||
* Admin/Mitarbeiter: Kommende und vergangene Geburtstage
|
||||
* Query: ?past=7&future=30 (Default)
|
||||
*/
|
||||
export async function getUpcomingBirthdays(req: AuthRequest, res: Response) {
|
||||
try {
|
||||
const past = req.query.past ? parseInt(String(req.query.past)) : 7;
|
||||
const future = req.query.future ? parseInt(String(req.query.future)) : 30;
|
||||
|
||||
const entries = await birthdayService.getUpcomingBirthdays(past, future);
|
||||
res.json({ success: true, data: entries });
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Abrufen der Geburtstage:', error);
|
||||
res.status(500).json({ success: false, error: 'Fehler beim Abrufen der Geburtstage' });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Portal: Eigenen Geburtstags-Check – soll das Modal angezeigt werden?
|
||||
*/
|
||||
export async function getMyBirthday(req: AuthRequest, res: Response) {
|
||||
try {
|
||||
const user = req.user as any;
|
||||
if (!user?.isCustomerPortal || !user?.customerId) {
|
||||
return res.status(403).json({ success: false, error: 'Nur für Kundenportal-Benutzer' });
|
||||
}
|
||||
|
||||
const data = await birthdayService.checkMyBirthday(user.customerId);
|
||||
res.json({ success: true, data });
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Geburtstags-Check:', error);
|
||||
res.status(500).json({ success: false, error: 'Fehler beim Abruf' });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Portal: Modal als gesehen markieren
|
||||
*/
|
||||
export async function acknowledgeMyBirthday(req: AuthRequest, res: Response) {
|
||||
try {
|
||||
const user = req.user as any;
|
||||
if (!user?.isCustomerPortal || !user?.customerId) {
|
||||
return res.status(403).json({ success: false, error: 'Nur für Kundenportal-Benutzer' });
|
||||
}
|
||||
|
||||
await birthdayService.acknowledgeBirthdayGreeting(user.customerId);
|
||||
res.json({ success: true });
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Bestätigen:', error);
|
||||
res.status(500).json({ success: false, error: 'Fehler beim Speichern' });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user