From 2903e56cf6cf03fa10d450ff66decdf01ee726b8 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Wed, 6 May 2026 00:45:37 +0200 Subject: [PATCH] fix: align calendar invitation icon with sender avatar column --- .../email/calendar-invitation-banner.tsx | 543 +++++++++--------- components/email/email-viewer.tsx | 2 +- locales/cs/common.json | 1 + locales/de/common.json | 1 + locales/en/common.json | 1 + locales/es/common.json | 1 + locales/fr/common.json | 1 + locales/it/common.json | 1 + locales/ja/common.json | 1 + locales/ko/common.json | 1 + locales/lv/common.json | 1 + locales/nl/common.json | 1 + locales/pl/common.json | 1 + locales/pt/common.json | 1 + locales/ru/common.json | 1 + locales/tr/common.json | 1 + locales/uk/common.json | 1 + locales/zh/common.json | 1 + 18 files changed, 304 insertions(+), 257 deletions(-) diff --git a/components/email/calendar-invitation-banner.tsx b/components/email/calendar-invitation-banner.tsx index 735f7375..8373de39 100644 --- a/components/email/calendar-invitation-banner.tsx +++ b/components/email/calendar-invitation-banner.tsx @@ -37,6 +37,7 @@ import { } from '@/lib/calendar-invitation'; import { cn } from '@/lib/utils'; import { sanitizeColor } from '@/components/calendar/event-card'; +import { RecipientPopover } from './recipient-popover'; interface InvitationChangeItem { label: string; @@ -327,25 +328,26 @@ function buildParticipantsForRsvp( ); } -function getMethodAccentClass(method: InvitationMethod, actorStatus?: string | null): string { +function getMethodIconTone(method: InvitationMethod, actorStatus?: string | null): string { switch (method) { case 'cancel': case 'declinecounter': - return 'border-l-red-500 dark:border-l-red-400'; - case 'request': - case 'add': - return 'border-l-blue-500 dark:border-l-blue-400'; + return 'bg-destructive/15 text-destructive'; case 'counter': - return 'border-l-amber-500 dark:border-l-amber-400'; + return 'bg-warning/15 text-warning'; case 'reply': switch (actorStatus) { - case 'accepted': return 'border-l-green-500 dark:border-l-green-400'; - case 'tentative': return 'border-l-amber-500 dark:border-l-amber-400'; - case 'declined': return 'border-l-red-500 dark:border-l-red-400'; - default: return 'border-l-blue-500 dark:border-l-blue-400'; + case 'accepted': return 'bg-success/15 text-success'; + case 'tentative': return 'bg-warning/15 text-warning'; + case 'declined': return 'bg-destructive/15 text-destructive'; + default: return 'bg-primary/15 text-primary'; } + case 'request': + case 'add': + case 'publish': + return 'bg-primary/15 text-primary'; default: - return 'border-l-slate-400 dark:border-l-slate-500'; + return 'bg-muted text-muted-foreground'; } } @@ -500,7 +502,6 @@ export function CalendarInvitationBanner({ email }: CalendarInvitationBannerProp const actorName = actorSummary?.name || actorSummary?.email || t('actor_unknown'); const actorStatus = getParticipationLabel(t, actorSummary?.participationStatus ?? null); const actorMessage = actorSummary ? getActorMessage(t, method, actorName, actorStatus) : null; - const actionFeedback = actionNotice; // For REQUEST method, allow RSVP even if we can't find the user in participants: // the email was sent TO the user, so they are an attendee. handleRsvp handles // the import-then-find-participant flow for this case. @@ -735,130 +736,151 @@ export function CalendarInvitationBanner({ email }: CalendarInvitationBannerProp } }; - const accentClass = getMethodAccentClass(method, actorSummary?.participationStatus); - if (state === 'loading') { return ( -
{bannerInfo}
+{actorMessage}
- )} - {actorSummary?.participationComment && ( -- {t('actor_note', { comment: actorSummary.participationComment })} -
+ {canCollapse && ( + )}{bannerInfo}
} + {actorMessage &&{actorMessage}
} + {actorSummary?.participationComment && ( +{t('actor_note', { comment: actorSummary.participationComment })}
+ )} +