Hintergründe zum EventInvitePage Layout Customizer hinzugefügt. Badge und CTA entfernt, Textfelder zu Textareas gemacht. Geschenkgutscheine verbessert, E-Mail-Versand ergänzt + Resend + Confirmationseite mit Code-Copy und Link zur Package-Seite, die den Code als URL-Parameter enthält.

This commit is contained in:
Codex Agent
2025-12-08 16:20:04 +01:00
parent 046e2fe3ec
commit 4784c23e70
35 changed files with 1503 additions and 136 deletions

View File

@@ -0,0 +1,35 @@
import { useMemo } from 'react';
type RateBucket = 'coupon' | 'voucher';
export function useRateLimitHelper(bucket: RateBucket) {
return useMemo(() => {
const key = (code: string) => `${bucket}:${code.toUpperCase()}`;
return {
isLimited: (code: string): boolean => {
const item = localStorage.getItem(key(code));
if (!item) return false;
const parsed = JSON.parse(item) as { attempts: number; ts: number };
const ageSeconds = (Date.now() - parsed.ts) / 1000;
if (ageSeconds > 300) {
localStorage.removeItem(key(code));
return false;
}
return parsed.attempts >= 3;
},
bump: (code: string): void => {
const item = localStorage.getItem(key(code));
if (!item) {
localStorage.setItem(key(code), JSON.stringify({ attempts: 1, ts: Date.now() }));
return;
}
const parsed = JSON.parse(item) as { attempts: number; ts: number };
localStorage.setItem(key(code), JSON.stringify({ attempts: (parsed.attempts || 0) + 1, ts: Date.now() }));
},
clear: (code: string): void => {
localStorage.removeItem(key(code));
},
};
}, [bucket]);
}