added missing translations
This commit is contained in:
@@ -34,7 +34,7 @@ interface TenantNotification {
|
||||
|
||||
export function NotificationCenter() {
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation('dashboard');
|
||||
const { t } = useTranslation('management');
|
||||
const [open, setOpen] = React.useState(false);
|
||||
const [loading, setLoading] = React.useState(true);
|
||||
const [notifications, setNotifications] = React.useState<TenantNotification[]>([]);
|
||||
@@ -104,7 +104,7 @@ export function NotificationCenter() {
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="relative rounded-full border border-transparent text-slate-600 hover:text-rose-600 dark:text-slate-200"
|
||||
aria-label={t('notifications.trigger', { defaultValue: 'Benachrichtigungen' })}
|
||||
aria-label={t('notifications.trigger')}
|
||||
>
|
||||
<Bell className="h-5 w-5" />
|
||||
{unreadCount > 0 ? (
|
||||
@@ -116,9 +116,9 @@ export function NotificationCenter() {
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="w-80 space-y-1 p-0">
|
||||
<DropdownMenuLabel className="flex items-center justify-between py-2">
|
||||
<span>{t('notifications.title', { defaultValue: 'Notifications' })}</span>
|
||||
<span>{t('notifications.title')}</span>
|
||||
{!loading && unreadCount === 0 ? (
|
||||
<Badge variant="outline">{t('notifications.empty', { defaultValue: 'Aktuell ruhig' })}</Badge>
|
||||
<Badge variant="outline">{t('notifications.empty')}</Badge>
|
||||
) : null}
|
||||
</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
@@ -131,7 +131,7 @@ export function NotificationCenter() {
|
||||
<div className="max-h-80 space-y-1 overflow-y-auto p-1">
|
||||
{visibleNotifications.length === 0 ? (
|
||||
<p className="px-3 py-4 text-sm text-slate-500">
|
||||
{t('notifications.empty.message', { defaultValue: 'Alles erledigt – wir melden uns bei Neuigkeiten.' })}
|
||||
{t('notifications.empty.message')}
|
||||
</p>
|
||||
) : (
|
||||
visibleNotifications.map((item) => (
|
||||
@@ -163,7 +163,7 @@ export function NotificationCenter() {
|
||||
className="h-7 rounded-full px-3 text-xs text-slate-500 hover:text-rose-600"
|
||||
onClick={() => handleDismiss(item.id)}
|
||||
>
|
||||
{t('notifications.action.dismiss', { defaultValue: 'Ausblenden' })}
|
||||
{t('notifications.action.dismiss')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -183,7 +183,7 @@ export function NotificationCenter() {
|
||||
}}
|
||||
>
|
||||
<Plus className="h-3.5 w-3.5" />
|
||||
{t('notifications.action.refresh', { defaultValue: 'Neue Hinweise laden' })}
|
||||
{t('notifications.action.refresh')}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
@@ -208,13 +208,11 @@ function buildNotifications({
|
||||
if (events.length === 0) {
|
||||
items.push({
|
||||
id: 'no-events',
|
||||
title: t('notifications.noEvents.title', { defaultValue: 'Legen wir los' }),
|
||||
description: t('notifications.noEvents.description', {
|
||||
defaultValue: 'Erstelle dein erstes Event, um Uploads, Aufgaben und Einladungen freizuschalten.',
|
||||
}),
|
||||
title: t('notifications.noEvents.title'),
|
||||
description: t('notifications.noEvents.description'),
|
||||
tone: 'warning',
|
||||
action: {
|
||||
label: t('notifications.noEvents.cta', { defaultValue: 'Event erstellen' }),
|
||||
label: t('notifications.noEvents.cta'),
|
||||
onSelect: () => navigate(ADMIN_EVENT_CREATE_PATH),
|
||||
},
|
||||
});
|
||||
@@ -226,14 +224,12 @@ function buildNotifications({
|
||||
if (event.status !== 'published') {
|
||||
items.push({
|
||||
id: `draft-${event.id}`,
|
||||
title: t('notifications.draftEvent.title', { defaultValue: 'Event noch als Entwurf' }),
|
||||
description: t('notifications.draftEvent.description', {
|
||||
defaultValue: 'Veröffentliche das Event, um Einladungen und Galerie freizugeben.',
|
||||
}),
|
||||
title: t('notifications.draftEvent.title'),
|
||||
description: t('notifications.draftEvent.description'),
|
||||
tone: 'info',
|
||||
action: event.slug
|
||||
? {
|
||||
label: t('notifications.draftEvent.cta', { defaultValue: 'Event öffnen' }),
|
||||
label: t('notifications.draftEvent.cta'),
|
||||
onSelect: () => navigate(ADMIN_EVENT_VIEW_PATH(event.slug!)),
|
||||
}
|
||||
: undefined,
|
||||
@@ -244,37 +240,33 @@ function buildNotifications({
|
||||
if (eventDate && eventDate > now) {
|
||||
const days = Math.round((eventDate - now) / (1000 * 60 * 60 * 24));
|
||||
if (days <= 7) {
|
||||
items.push({
|
||||
id: `upcoming-${event.id}`,
|
||||
title: t('notifications.upcomingEvent.title', { defaultValue: 'Event startet bald' }),
|
||||
description: t('notifications.upcomingEvent.description', {
|
||||
defaultValue: days === 0
|
||||
? 'Heute findet ein Event statt – checke Uploads und Tasks.'
|
||||
: `Noch ${days} Tage – bereite Einladungen und Aufgaben vor.`,
|
||||
}),
|
||||
tone: 'info',
|
||||
action: event.slug
|
||||
? {
|
||||
label: t('notifications.upcomingEvent.cta', { defaultValue: 'Zum Event' }),
|
||||
onSelect: () => navigate(ADMIN_EVENT_VIEW_PATH(event.slug!)),
|
||||
}
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
items.push({
|
||||
id: `upcoming-${event.id}`,
|
||||
title: t('notifications.upcomingEvent.title'),
|
||||
description: days === 0
|
||||
? t('notifications.upcomingEvent.description_today')
|
||||
: t('notifications.upcomingEvent.description_days', { count: days }),
|
||||
tone: 'info',
|
||||
action: event.slug
|
||||
? {
|
||||
label: t('notifications.upcomingEvent.cta'),
|
||||
onSelect: () => navigate(ADMIN_EVENT_VIEW_PATH(event.slug!)),
|
||||
}
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const pendingUploads = Number(event.pending_photo_count ?? 0);
|
||||
if (pendingUploads > 0) {
|
||||
items.push({
|
||||
id: `pending-uploads-${event.id}`,
|
||||
title: t('notifications.pendingUploads.title', { defaultValue: 'Uploads warten auf Freigabe' }),
|
||||
description: t('notifications.pendingUploads.description', {
|
||||
defaultValue: `${pendingUploads} neue Uploads benötigen Moderation.`,
|
||||
}),
|
||||
title: t('notifications.pendingUploads.title'),
|
||||
description: t('notifications.pendingUploads.description', { count: pendingUploads }),
|
||||
tone: 'warning',
|
||||
action: event.slug
|
||||
? {
|
||||
label: t('notifications.pendingUploads.cta', { defaultValue: 'Uploads öffnen' }),
|
||||
label: t('notifications.pendingUploads.cta'),
|
||||
onSelect: () => navigate(`${ADMIN_EVENT_VIEW_PATH(event.slug!)}#photos`),
|
||||
}
|
||||
: undefined,
|
||||
@@ -285,18 +277,16 @@ function buildNotifications({
|
||||
if ((summary?.new_photos ?? 0) > 0) {
|
||||
items.push({
|
||||
id: 'summary-new-photos',
|
||||
title: t('notifications.newPhotos.title', { defaultValue: 'Neue Fotos eingetroffen' }),
|
||||
description: t('notifications.newPhotos.description', {
|
||||
defaultValue: `${summary?.new_photos ?? 0} Uploads warten auf dich.`,
|
||||
}),
|
||||
title: t('notifications.newPhotos.title'),
|
||||
description: t('notifications.newPhotos.description', { count: summary?.new_photos ?? 0 }),
|
||||
tone: 'success',
|
||||
action: primary?.slug
|
||||
? {
|
||||
label: t('notifications.newPhotos.cta', { defaultValue: 'Galerie öffnen' }),
|
||||
label: t('notifications.newPhotos.cta'),
|
||||
onSelect: () => navigate(ADMIN_EVENT_VIEW_PATH(primary.slug!)),
|
||||
}
|
||||
: {
|
||||
label: t('notifications.newPhotos.ctaFallback', { defaultValue: 'Events ansehen' }),
|
||||
label: t('notifications.newPhotos.ctaFallback'),
|
||||
onSelect: () => navigate(ADMIN_EVENTS_PATH),
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user