diff --git a/packages/console/src/assets/icons/invitation.svg b/packages/console/src/assets/icons/invitation.svg
index 7ee86538506b..2c245c59f2e8 100644
--- a/packages/console/src/assets/icons/invitation.svg
+++ b/packages/console/src/assets/icons/invitation.svg
@@ -1,3 +1,3 @@
diff --git a/packages/console/src/cloud/pages/Main/InvitationList/index.module.scss b/packages/console/src/cloud/pages/Main/InvitationList/index.module.scss
index e4ecad534305..3f223613fc5e 100644
--- a/packages/console/src/cloud/pages/Main/InvitationList/index.module.scss
+++ b/packages/console/src/cloud/pages/Main/InvitationList/index.module.scss
@@ -5,7 +5,7 @@
flex-direction: column;
height: 100%;
min-height: 600px;
- background: var(--color-surface-1);
+ background: var(--color-base);
align-items: center;
justify-content: center;
overflow-y: auto;
@@ -16,17 +16,11 @@
width: 540px;
padding: _.unit(20) _.unit(17.5);
gap: _.unit(6);
- background: var(--color-bg-float);
+ background: var(--color-layer-1);
border-radius: 16px;
box-shadow: var(--shadow-1);
white-space: pre-wrap;
- .icon {
- width: 40px;
- height: 40px;
- flex-shrink: 0;
- }
-
.title {
font: var(--font-headline-2);
}
diff --git a/packages/console/src/cloud/pages/Main/InvitationList/index.tsx b/packages/console/src/cloud/pages/Main/InvitationList/index.tsx
index 1b96bb6415ba..6f5c718817b6 100644
--- a/packages/console/src/cloud/pages/Main/InvitationList/index.tsx
+++ b/packages/console/src/cloud/pages/Main/InvitationList/index.tsx
@@ -2,11 +2,12 @@ import { OrganizationInvitationStatus, getTenantIdFromOrganizationId } from '@lo
import { useContext, useState } from 'react';
import { useTranslation } from 'react-i18next';
-import Icon from '@/assets/icons/organization-preview.svg';
+import OrganizationIcon from '@/assets/icons/organization-preview.svg';
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
import { type TenantResponse, type InvitationListResponse } from '@/cloud/types/router';
import CreateTenantModal from '@/components/CreateTenantModal';
import TenantEnvTag from '@/components/TenantEnvTag';
+import ThemedIcon from '@/components/ThemedIcon';
import { TenantsContext } from '@/contexts/TenantsProvider';
import Button from '@/ds-components/Button';
import Spacer from '@/ds-components/Spacer';
@@ -32,7 +33,7 @@ function InvitationList({ invitations }: Props) {
{t('invitation.find_tenants_description')}
{invitations.map(({ id, organizationId, tenantName, tenantTag }) => (
-
+
{tenantName}
diff --git a/packages/console/src/components/ItemPreview/index.module.scss b/packages/console/src/components/ItemPreview/index.module.scss
index 3a09bf4d61c8..ee9ce986c924 100644
--- a/packages/console/src/components/ItemPreview/index.module.scss
+++ b/packages/console/src/components/ItemPreview/index.module.scss
@@ -31,9 +31,12 @@
.title {
display: block;
font: var(--font-body-2);
- color: var(--color-text-link);
text-decoration: none;
@include _.text-ellipsis;
+
+ &.withLink {
+ color: var(--color-text-link);
+ }
}
.subtitle {
diff --git a/packages/console/src/components/ItemPreview/index.tsx b/packages/console/src/components/ItemPreview/index.tsx
index 5e6d4544f525..ae29ac65697e 100644
--- a/packages/console/src/components/ItemPreview/index.tsx
+++ b/packages/console/src/components/ItemPreview/index.tsx
@@ -27,7 +27,7 @@ function ItemPreview({ title, subtitle, icon, to, size = 'default', suffix, toTa
{to && (
{
diff --git a/packages/console/src/components/Topbar/TenantSelector/index.module.scss b/packages/console/src/components/Topbar/TenantSelector/index.module.scss
index f06ff2128af3..8697a8b955cb 100644
--- a/packages/console/src/components/Topbar/TenantSelector/index.module.scss
+++ b/packages/console/src/components/Topbar/TenantSelector/index.module.scss
@@ -19,6 +19,7 @@ $dropdown-item-height: 40px;
position: relative;
border: none;
background-color: transparent;
+ gap: _.unit(2);
&:hover {
cursor: pointer;
@@ -31,12 +32,14 @@ $dropdown-item-height: 40px;
.name {
font: var(--font-title-2);
- margin-right: _.unit(1.5);
@include _.text-ellipsis;
}
- .tag {
- margin-right: _.unit(2);
+ .redDot {
+ width: 10px;
+ height: 10px;
+ border-radius: 50%;
+ background-color: var(--color-on-error-container);
}
.arrowIcon {
diff --git a/packages/console/src/components/Topbar/TenantSelector/index.tsx b/packages/console/src/components/Topbar/TenantSelector/index.tsx
index 99e4eee98b7b..07555f0effc8 100644
--- a/packages/console/src/components/Topbar/TenantSelector/index.tsx
+++ b/packages/console/src/components/Topbar/TenantSelector/index.tsx
@@ -54,7 +54,8 @@ export default function TenantSelector() {
}}
>
{currentTenantInfo.name}
-
+
+ {Boolean(pendingInvitations?.length) &&
}
;
+ }
+
return (
diff --git a/packages/console/src/pages/AcceptInvitation/index.tsx b/packages/console/src/pages/AcceptInvitation/index.tsx
index 849bf9edbd19..6c804241b846 100644
--- a/packages/console/src/pages/AcceptInvitation/index.tsx
+++ b/packages/console/src/pages/AcceptInvitation/index.tsx
@@ -47,10 +47,10 @@ function AcceptInvitation() {
resetTenants(data);
navigateTenant(getTenantIdFromOrganizationId(organizationId));
})();
- }, [cloudApi, error, invitation, navigateTenant, t]);
+ }, [cloudApi, error, invitation, navigateTenant, resetTenants, t]);
// No invitation returned, indicating the current signed-in user is not the invitee.
- if (error?.status === 404) {
+ if (error?.status === 403) {
return (
{
@@ -63,6 +63,10 @@ function AcceptInvitation() {
);
}
+ if (error?.status === 404) {
+ return ;
+ }
+
if (invitation && invitation.status !== OrganizationInvitationStatus.Pending) {
return ;
}
diff --git a/packages/console/src/pages/TenantSettings/TenantMembers/InviteMemberModal/index.tsx b/packages/console/src/pages/TenantSettings/TenantMembers/InviteMemberModal/index.tsx
index 69db6b0520f7..b922a9097e23 100644
--- a/packages/console/src/pages/TenantSettings/TenantMembers/InviteMemberModal/index.tsx
+++ b/packages/console/src/pages/TenantSettings/TenantMembers/InviteMemberModal/index.tsx
@@ -1,5 +1,5 @@
import { ReservedPlanId, TenantRole } from '@logto/schemas';
-import { useContext, useMemo, useState } from 'react';
+import { useContext, useEffect, useMemo, useState } from 'react';
import { Controller, FormProvider, useForm } from 'react-hook-form';
import { toast } from 'react-hot-toast';
import { useTranslation } from 'react-i18next';
@@ -50,9 +50,16 @@ function InviteMemberModal({ isOpen, onClose }: Props) {
control,
handleSubmit,
setError,
+ reset,
formState: { errors },
} = formMethods;
+ useEffect(() => {
+ return () => {
+ reset();
+ };
+ }, [isOpen, reset]);
+
const roleOptions: Array