From 9eca7e012f0749c726512f037fb640b6478c9083 Mon Sep 17 00:00:00 2001
From: vutuanlinh2k2
Date: Thu, 25 Jun 2026 11:36:09 +0700
Subject: [PATCH] fix(teams): color invitation status badges by state
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The lifecycle-status and email-delivery badges in InvitationsPanel
rendered every value in the same neutral gray, so accepted, pending,
expired and revoked invites were distinguishable only by reading the
label. Map each status to the design-system surface tokens: accepted →
success, pending/not-sent → warning, revoked/failed → danger, expired →
muted, sent → muted.
Also switch the failed-email styling off the undefined --text-danger
token (which resolved to no color) onto --surface-danger-text.
---
.../components/InvitationsPanel.tsx | 27 ++++++++++++++-----
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/src/teams-react/components/InvitationsPanel.tsx b/src/teams-react/components/InvitationsPanel.tsx
index 008b6a8..f81431a 100644
--- a/src/teams-react/components/InvitationsPanel.tsx
+++ b/src/teams-react/components/InvitationsPanel.tsx
@@ -21,6 +21,23 @@ const ASSIGNABLE: { value: WorkspaceRole; label: string }[] = [
{ value: 'admin', label: 'Admin' },
]
+const BADGE_BASE = 'inline-flex items-center rounded border px-2 py-0.5 text-[10px] font-medium uppercase'
+
+// Lifecycle status: green = in, amber = awaiting, red = killed, muted = lapsed.
+const STATUS_BADGE: Record = {
+ accepted: 'border-[var(--surface-success-border)] bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]',
+ pending: 'border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]',
+ revoked: 'border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]',
+ expired: 'border-[var(--border-default)] text-[var(--text-muted)]',
+}
+
+// Delivery status: red = bounced, amber = not yet attempted, muted = the normal happy path.
+const EMAIL_BADGE: Record = {
+ sent: 'border-[var(--border-default)] text-[var(--text-muted)]',
+ not_sent: 'border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]',
+ failed: 'border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]',
+}
+
export function InvitationsPanel({
invitations,
currentRole,
@@ -179,18 +196,14 @@ function InvitationRow({ invitation, canManage, busy, onCopy, onResend, onRevoke
{invitation.permissions} · expires {expiry}
{emailFailed && (
- Email was not sent — copy the link to share it.
+ Email was not sent — copy the link to share it.
)}
-
+
{invitation.status}
-
+
{invitation.emailStatus.replace('_', ' ')}