Add support for menu children and moved invitations under users

This commit is contained in:
grokdesigns
2025-04-09 09:23:47 -07:00
parent c7f3c9da92
commit 7a55c9ad03
8 changed files with 105 additions and 58 deletions

View File

@@ -5,19 +5,25 @@ import { SidebarSettings } from "@app/components/SidebarSettings";
type AccessPageHeaderAndNavProps = {
children: React.ReactNode;
hasInvitations: boolean;
};
export default function AccessPageHeaderAndNav({
children
children,
hasInvitations
}: AccessPageHeaderAndNavProps) {
const sidebarNavItems = [
{
title: "Users",
href: `/{orgId}/settings/access/users`
},
{
title: "Invitations",
href: `/{orgId}/settings/access/invitations`
href: `/{orgId}/settings/access/users`,
children: hasInvitations
? [
{
title: "• Invitations",
href: `/{orgId}/settings/access/invitations`
}
]
: []
},
{
title: "Roles",
@@ -29,8 +35,7 @@ export default function AccessPageHeaderAndNav({
<>
<SettingsSectionTitle
title="Manage Users & Roles"
description="Invite users and add them to roles to manage access to your
organization"
description="Invite users and add them to roles to manage access to your organization"
/>
<SidebarSettings sidebarNavItems={sidebarNavItems}>

View File

@@ -20,7 +20,7 @@ import { useEnvContext } from "@app/hooks/useEnvContext";
export type InvitationRow = {
id: string;
email: string;
expiresAt: string; // ISO string or timestamp
expiresAt: string;
role: string;
};

View File

@@ -28,16 +28,20 @@ export default async function InvitationsPage(props: InvitationsPageProps) {
roleId: string;
roleName?: string;
}[] = [];
let hasInvitations = false;
const res = await internal
.get<
AxiosResponse<{
invitations: typeof invitations;
pagination: { total: number };
}>
>(`/org/${params.orgId}/invitations`, await authCookieHeader())
.catch((e) => {});
if (res && res.status === 200) {
invitations = res.data.data.invitations;
hasInvitations = res.data.data.pagination.total > 0;
}
let org: GetOrgResponse | null = null;
@@ -61,13 +65,13 @@ export default async function InvitationsPage(props: InvitationsPageProps) {
id: invite.inviteId,
email: invite.email,
expiresAt: new Date(Number(invite.expiresAt)).toISOString(),
role: invite.roleName || "Unknown Role" // Use roleName if available
role: invite.roleName || "Unknown Role"
};
});
return (
<>
<AccessPageHeaderAndNav>
<AccessPageHeaderAndNav hasInvitations={hasInvitations}>
<UserProvider user={user!}>
<OrgProvider org={org}>
<InvitationsTable invitations={invitationRows} />

View File

@@ -19,6 +19,8 @@ export default async function RolesPage(props: RolesPageProps) {
const params = await props.params;
let roles: ListRolesResponse["roles"] = [];
let hasInvitations = false;
const res = await internal
.get<
AxiosResponse<ListRolesResponse>
@@ -29,6 +31,21 @@ export default async function RolesPage(props: RolesPageProps) {
roles = res.data.data.roles;
}
const invitationsRes = await internal
.get<
AxiosResponse<{
pagination: { total: number };
}>
>(
`/org/${params.orgId}/invitations?limit=1&offset=0`,
await authCookieHeader()
)
.catch((e) => {});
if (invitationsRes && invitationsRes.status === 200) {
hasInvitations = invitationsRes.data.data.pagination.total > 0;
}
let org: GetOrgResponse | null = null;
const getOrg = cache(async () =>
internal
@@ -47,7 +64,7 @@ export default async function RolesPage(props: RolesPageProps) {
return (
<>
<AccessPageHeaderAndNav>
<AccessPageHeaderAndNav hasInvitations={hasInvitations}>
<OrgProvider org={org}>
<RolesTable roles={roleRows} />
</OrgProvider>

View File

@@ -23,6 +23,8 @@ export default async function UsersPage(props: UsersPageProps) {
const user = await getUser();
let users: ListUsersResponse["users"] = [];
let hasInvitations = false;
const res = await internal
.get<
AxiosResponse<ListUsersResponse>
@@ -33,6 +35,21 @@ export default async function UsersPage(props: UsersPageProps) {
users = res.data.data.users;
}
const invitationsRes = await internal
.get<
AxiosResponse<{
pagination: { total: number };
}>
>(
`/org/${params.orgId}/invitations?limit=1&offset=0`,
await authCookieHeader()
)
.catch((e) => {});
if (invitationsRes && invitationsRes.status === 200) {
hasInvitations = invitationsRes.data.data.pagination.total > 0;
}
let org: GetOrgResponse | null = null;
const getOrg = cache(async () =>
internal
@@ -61,7 +78,7 @@ export default async function UsersPage(props: UsersPageProps) {
return (
<>
<AccessPageHeaderAndNav>
<AccessPageHeaderAndNav hasInvitations={hasInvitations}>
<UserProvider user={user!}>
<OrgProvider org={org}>
<UsersTable users={userRows} />