@burdenoff/microfe-organization 2026.625.3 → 2026.626.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/organization-management/modules/members/pages/InviteMemberPage.js +58 -53
- package/dist/organization-management/modules/members/pages/InviteMemberPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/InvitePeoplePage.js +47 -40
- package/dist/organization-management/modules/members/pages/InvitePeoplePage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/MemberDetailPage.js +72 -68
- package/dist/organization-management/modules/members/pages/MemberDetailPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/MembersListPage.js +216 -208
- package/dist/organization-management/modules/members/pages/MembersListPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/MyInvitesPage.js +164 -158
- package/dist/organization-management/modules/members/pages/MyInvitesPage.js.map +1 -1
- package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js +132 -128
- package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js +42 -37
- package/dist/organization-management/modules/organizations/pages/OrganizationCreatePage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js +310 -258
- package/dist/organization-management/modules/organizations/pages/OrganizationDetailPage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationEditPage.js +52 -47
- package/dist/organization-management/modules/organizations/pages/OrganizationEditPage.js.map +1 -1
- package/dist/organization-management/modules/organizations/pages/OrganizationsListPage.js +66 -59
- package/dist/organization-management/modules/organizations/pages/OrganizationsListPage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspaceCreatePage.js +43 -38
- package/dist/organization-management/modules/workspaces/pages/WorkspaceCreatePage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js +315 -258
- package/dist/organization-management/modules/workspaces/pages/WorkspaceDetailPage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspaceEditPage.js +50 -45
- package/dist/organization-management/modules/workspaces/pages/WorkspaceEditPage.js.map +1 -1
- package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js +246 -238
- package/dist/organization-management/modules/workspaces/pages/WorkspacesListPage.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MyInvitesPage.js","names":[],"sources":["../../../../../src/organization-management/modules/members/pages/MyInvitesPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { NavLink } from 'react-router-dom';\nimport { Mail, Loader2, AlertCircle, BriefcaseBusiness } from 'lucide-react';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport {\n ActorIdentity,\n useActorProfiles,\n type ActorInput,\n type ActorProfileMap,\n} from '@burdenoff/fe-libs/shared';\nimport { Badge, GlassCard, IllustratedEmptyState } from '@burdenoff/fe-libs/ui';\nimport { useMyInvites, useAcceptInvite, useRejectInvite } from '../hooks/useInvites';\nimport {\n useAcceptWorkspaceInvite,\n useMyWorkspaceInvites,\n useRejectWorkspaceInvite,\n} from '../hooks/useWorkspaceInvites';\nimport { MyInviteCard } from '../components/MyInviteCard';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { InviteStatus as OrganizationInviteStatus } from '../../../../generated/global-types';\nimport { useTr } from '../../../shared/hooks/useTr';\nimport { useOrganizationPageView } from '../../../hooks/useOrganizationPageView';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport {\n getProjectDisplayNames,\n getRoleDisplayNames,\n getWorkspaceDisplayName,\n} from '../utils/workspaceInvitationDisplay';\n\n/**\n * My Invites Page\n * Shows pending invites for the current user with accept/reject actions\n */\ntype MyInvitesTab = 'workspace' | 'organization';\n\ninterface MyInvitesPageProps {\n activeTab?: MyInvitesTab;\n}\n\ninterface TabActionError {\n tab: MyInvitesTab;\n message: string;\n}\n\ninterface InvitesTabNavProps {\n activeTab: MyInvitesTab;\n basePath: string;\n tr: ReturnType<typeof useTr>;\n}\n\nfunction formatDate(value?: string | null) {\n if (!value) return null;\n\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return null;\n\n return date.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nfunction joinPath(base: string, path: string): string {\n const cleanBase = base.endsWith('/') ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return cleanBase + cleanPath;\n}\n\nfunction InvitesTabNav({ activeTab, basePath, tr }: InvitesTabNavProps) {\n const getTabClassName = (isActive: boolean) =>\n [\n 'border-b-2 px-4 py-2 text-sm font-medium transition-colors',\n isActive\n ? 'border-[var(--color-border-focus)] text-[var(--color-text-primary)]'\n : 'border-transparent text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)]',\n ].join(' ');\n\n return (\n <div className=\"mb-6 flex gap-2 border-b border-[var(--color-border-default)]\">\n <NavLink\n to={joinPath(basePath, '/invites')}\n end\n className={getTabClassName(activeTab === 'workspace')}\n >\n {tr('members.myInvites.workspaceTab', 'Workspace Invites')}\n </NavLink>\n <NavLink\n to={joinPath(basePath, '/invites/organizations')}\n className={getTabClassName(activeTab === 'organization')}\n >\n {tr('members.myInvites.organizationTab', 'Organization Invites')}\n </NavLink>\n </div>\n );\n}\n\nexport function MyInvitesPage({ activeTab = 'workspace' }: MyInvitesPageProps) {\n useOrganizationPageView(\n activeTab === 'workspace'\n ? 'organizations.my-workspace-invites'\n : 'organizations.my-organization-invites'\n );\n const tr = useTr();\n const { isLoading: permissionsLoading } = usePermissions();\n const { basePath = '/organizations', currentUser, authToken, apiGatewayUrl } = useOrgConsole();\n const orgInvitesEnabled = activeTab === 'organization';\n const workspaceInvitesEnabled = activeTab === 'workspace';\n const { invites, loading, error, total } = useMyInvites(\n OrganizationInviteStatus.Pending,\n 20,\n 0,\n orgInvitesEnabled\n );\n const {\n invites: workspaceInvites,\n loading: workspaceLoading,\n error: workspaceError,\n total: workspaceTotal,\n refetch: refetchWorkspaceInvites,\n } = useMyWorkspaceInvites(currentUser?.email, workspaceInvitesEnabled);\n const { acceptInvite, loading: accepting } = useAcceptInvite();\n const { rejectInvite, loading: rejecting } = useRejectInvite();\n const { acceptInvite: acceptWorkspaceInvite, loading: acceptingWorkspace } =\n useAcceptWorkspaceInvite();\n const { rejectInvite: rejectWorkspaceInvite, loading: rejectingWorkspace } =\n useRejectWorkspaceInvite();\n const [actionError, setActionError] = useState<TabActionError | null>(null);\n\n const visibleActionError = actionError?.tab === activeTab ? actionError.message : null;\n const [processingWorkspaceAction, setProcessingWorkspaceAction] = useState<{\n inviteId: string;\n action: 'accept' | 'reject';\n } | null>(null);\n\n const workspaceInviteActors = useMemo<ActorInput[]>(\n () =>\n workspaceInvites.flatMap((invite) =>\n invite.invitedById ? [{ actorId: invite.invitedById, actorType: 'user' as const }] : []\n ),\n [workspaceInvites]\n );\n\n const inviterProfiles: ActorProfileMap = useActorProfiles(workspaceInviteActors, {\n apiGatewayUrl,\n authToken,\n });\n\n const sortedWorkspaceInvites = useMemo(\n () =>\n [...workspaceInvites].sort(\n (left: (typeof workspaceInvites)[number], right: (typeof workspaceInvites)[number]) =>\n new Date(right.createdAt).getTime() - new Date(left.createdAt).getTime()\n ),\n [workspaceInvites]\n );\n\n const totalCount = activeTab === 'workspace' ? workspaceTotal : total;\n\n const handleAccept = async (inviteId: string) => {\n try {\n setActionError(null);\n await acceptInvite(inviteId);\n } catch (err) {\n setActionError({\n tab: 'organization',\n message:\n err instanceof Error\n ? err.message\n : tr('members.myInvites.acceptFailed', 'Failed to accept invite'),\n });\n }\n };\n\n const handleReject = async (inviteId: string) => {\n try {\n setActionError(null);\n await rejectInvite(inviteId);\n } catch (err) {\n setActionError({\n tab: 'organization',\n message:\n err instanceof Error\n ? err.message\n : tr('members.myInvites.rejectFailed', 'Failed to reject invite'),\n });\n }\n };\n\n const handleAcceptWorkspace = async (inviteId: string) => {\n try {\n setProcessingWorkspaceAction({ inviteId, action: 'accept' });\n setActionError(null);\n await acceptWorkspaceInvite(inviteId);\n await refetchWorkspaceInvites().catch(() => undefined);\n } catch (err) {\n setActionError({\n tab: 'workspace',\n message:\n err instanceof Error\n ? err.message\n : tr('members.myInvites.workspaceAcceptFailed', 'Failed to accept workspace invite'),\n });\n } finally {\n setProcessingWorkspaceAction((current) =>\n current?.inviteId === inviteId && current.action === 'accept' ? null : current\n );\n }\n };\n\n const handleRejectWorkspace = async (inviteId: string) => {\n try {\n setProcessingWorkspaceAction({ inviteId, action: 'reject' });\n setActionError(null);\n await rejectWorkspaceInvite(inviteId);\n await refetchWorkspaceInvites().catch(() => undefined);\n } catch (err) {\n setActionError({\n tab: 'workspace',\n message:\n err instanceof Error\n ? err.message\n : tr('members.myInvites.workspaceRejectFailed', 'Failed to reject workspace invite'),\n });\n } finally {\n setProcessingWorkspaceAction((current) =>\n current?.inviteId === inviteId && current.action === 'reject' ? null : current\n );\n }\n };\n\n // Own invites are always accessible — no permission denial needed.\n // We still wait for permissions to load to ensure consistent UX.\n if (permissionsLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loadingPermissions', 'Loading permissions...')} />\n </div>\n );\n }\n\n if (workspaceInvitesEnabled && !currentUser?.email) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <div className=\"max-w-4xl mx-auto\">\n <div className=\"mb-6 flex items-center gap-3\">\n <Mail size={24} className=\"text-[var(--color-text-primary)]\" />\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.myInvites.title', 'My Invites')}\n </h1>\n </div>\n\n <InvitesTabNav activeTab={activeTab} basePath={basePath} tr={tr} />\n\n <div className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] p-6 text-center\">\n <p className=\"text-[var(--color-text-secondary)]\">\n {tr('members.myInvites.signInWorkspace', 'Sign in to view your workspace invites.')}\n </p>\n </div>\n </div>\n </div>\n );\n }\n\n if (orgInvitesEnabled && loading && invites.length === 0) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <div className=\"max-w-4xl mx-auto\">\n <div className=\"mb-6 flex items-center gap-3\">\n <Mail size={24} className=\"text-[var(--color-text-primary)]\" />\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.myInvites.title', 'My Invites')}\n </h1>\n </div>\n\n <InvitesTabNav activeTab={activeTab} basePath={basePath} tr={tr} />\n\n <div className=\"flex items-center justify-center min-h-[300px] rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)]\">\n <Loader2 size={24} className=\"animate-spin text-[var(--color-text-muted)]\" />\n </div>\n </div>\n </div>\n );\n }\n\n if (workspaceInvitesEnabled && workspaceLoading && workspaceInvites.length === 0) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <div className=\"max-w-4xl mx-auto\">\n <div className=\"mb-6 flex items-center gap-3\">\n <Mail size={24} className=\"text-[var(--color-text-primary)]\" />\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.myInvites.title', 'My Invites')}\n </h1>\n </div>\n\n <InvitesTabNav activeTab={activeTab} basePath={basePath} tr={tr} />\n\n <div className=\"flex items-center justify-center min-h-[300px] rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)]\">\n <Loader2 size={24} className=\"animate-spin text-[var(--color-text-muted)]\" />\n </div>\n </div>\n </div>\n );\n }\n\n if (orgInvitesEnabled && error) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <div className=\"max-w-4xl mx-auto\">\n <div className=\"mb-6 flex items-center gap-3\">\n <Mail size={24} className=\"text-[var(--color-text-primary)]\" />\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.myInvites.title', 'My Invites')}\n </h1>\n </div>\n\n <InvitesTabNav activeTab={activeTab} basePath={basePath} tr={tr} />\n\n <div className=\"rounded-xl border border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] p-6 text-center\">\n <p className=\"text-[var(--color-status-error-text)]\">\n {tr('members.myInvites.loadFailed', 'Failed to load invites')}: {error.message}\n </p>\n </div>\n </div>\n </div>\n );\n }\n\n if (workspaceInvitesEnabled && workspaceError) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <div className=\"max-w-4xl mx-auto\">\n <div className=\"mb-6 flex items-center gap-3\">\n <Mail size={24} className=\"text-[var(--color-text-primary)]\" />\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.myInvites.title', 'My Invites')}\n </h1>\n </div>\n\n <InvitesTabNav activeTab={activeTab} basePath={basePath} tr={tr} />\n\n <div className=\"rounded-xl border border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] p-6 text-center\">\n <p className=\"text-[var(--color-status-error-text)]\">\n {tr('members.myInvites.workspaceLoadFailed', 'Failed to load workspace invites')}:{' '}\n {workspaceError.message}\n </p>\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <div className=\"max-w-4xl mx-auto\">\n {/* Header */}\n <div className=\"flex items-center gap-3 mb-6\">\n <Mail size={24} className=\"text-[var(--color-text-primary)]\" />\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.myInvites.title', 'My Invites')}\n </h1>\n {totalCount > 0 && (\n <span className=\"px-2.5 py-0.5 rounded-full text-xs font-medium bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)]\">\n {totalCount}\n </span>\n )}\n </div>\n\n <InvitesTabNav activeTab={activeTab} basePath={basePath} tr={tr} />\n\n {visibleActionError && (\n <div className=\"mb-4 flex items-center gap-2 rounded-lg border border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] p-3\">\n <AlertCircle size={16} className=\"shrink-0 text-[var(--color-status-error-text)]\" />\n <p className=\"text-sm text-[var(--color-status-error-text)]\">{visibleActionError}</p>\n </div>\n )}\n\n {workspaceInvitesEnabled ? (\n sortedWorkspaceInvites.length === 0 ? (\n <GlassCard treatment=\"glass\" className=\"rounded-xl\">\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title={tr('members.myInvites.workspaceEmptyTitle', 'No pending workspace invites')}\n description={tr(\n 'members.myInvites.workspaceEmptyDescription',\n 'When someone invites you to a workspace, it will appear here.'\n )}\n />\n </GlassCard>\n ) : (\n <div className=\"space-y-3\">\n {sortedWorkspaceInvites.map((invite) => {\n const workspaceName = getWorkspaceDisplayName(invite);\n const roleNames = getRoleDisplayNames(invite);\n const projectNames = getProjectDisplayNames(invite);\n const inviterProfile = invite.invitedById\n ? inviterProfiles[invite.invitedById]\n : undefined;\n const inviterLabel =\n inviterProfile?.displayName ||\n inviterProfile?.email ||\n tr('members.myInvites.invitedByFallback', 'Someone');\n const isProcessingWorkspaceAccept =\n processingWorkspaceAction?.inviteId === invite.id &&\n processingWorkspaceAction?.action === 'accept' &&\n acceptingWorkspace;\n const isProcessingWorkspaceReject =\n processingWorkspaceAction?.inviteId === invite.id &&\n processingWorkspaceAction?.action === 'reject' &&\n rejectingWorkspace;\n\n return (\n <GlassCard key={invite.id} treatment=\"insight\" className=\"border-border-seam p-5\">\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"min-w-0 space-y-3\">\n <div className=\"flex items-start gap-3\">\n <div className=\"rounded-lg bg-[var(--color-bg-subtle)] p-2\">\n <BriefcaseBusiness\n size={20}\n className=\"text-[var(--color-text-secondary)]\"\n />\n </div>\n <div className=\"min-w-0\">\n <h3 className=\"font-semibold text-[var(--color-text-primary)] break-words\">\n {workspaceName}\n </h3>\n <p className=\"mt-1 text-sm text-[var(--color-text-secondary)] break-all\">\n {invite.email}\n </p>\n </div>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"secondary\">{invite.status}</Badge>\n {roleNames.map((roleName) => (\n <Badge key={`${invite.id}-${roleName}`} variant=\"outline\">\n {roleName}\n </Badge>\n ))}\n </div>\n\n <dl className=\"grid gap-3 text-sm text-[var(--color-text-secondary)] sm:grid-cols-2\">\n <div>\n <dt className=\"font-medium text-[var(--color-text-primary)]\">\n {tr('members.myInvites.invitedByLabel', 'Invited by')}\n </dt>\n <dd className=\"break-all\">\n {inviterProfile ? (\n <ActorIdentity\n profile={inviterProfile}\n variant=\"inline\"\n hideIdDrilldown\n />\n ) : (\n inviterLabel\n )}\n </dd>\n </div>\n <div>\n <dt className=\"font-medium text-[var(--color-text-primary)]\">\n {tr('members.myInvites.receivedLabel', 'Received')}\n </dt>\n <dd>{formatDate(invite.createdAt) ?? '—'}</dd>\n </div>\n <div>\n <dt className=\"font-medium text-[var(--color-text-primary)]\">\n {tr('members.myInvites.expiresLabel', 'Expires')}\n </dt>\n <dd>{formatDate(invite.expiresAt) ?? '—'}</dd>\n </div>\n {projectNames.length > 0 ? (\n <div className=\"sm:col-span-2\">\n <dt className=\"font-medium text-[var(--color-text-primary)]\">\n {tr('members.myInvites.projectsLabel', 'Projects')}\n </dt>\n <dd className=\"mt-1 flex flex-wrap gap-2\">\n {projectNames.map((projectName) => (\n <Badge key={`${invite.id}-${projectName}`} variant=\"outline\">\n {projectName}\n </Badge>\n ))}\n </dd>\n </div>\n ) : null}\n </dl>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2 shrink-0\">\n <button\n type=\"button\"\n onClick={() => void handleAcceptWorkspace(invite.id)}\n disabled={isProcessingWorkspaceAccept || isProcessingWorkspaceReject}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-[var(--color-status-success-bg)] px-4 py-2 text-sm font-medium text-[var(--color-text-inverse)] transition-all duration-200 hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {isProcessingWorkspaceAccept ? (\n <Loader2 size={14} className=\"animate-spin\" />\n ) : null}\n {tr('members.myInvites.accept', 'Accept')}\n </button>\n <button\n type=\"button\"\n onClick={() => void handleRejectWorkspace(invite.id)}\n disabled={isProcessingWorkspaceAccept || isProcessingWorkspaceReject}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-[var(--color-border-default)] bg-transparent px-4 py-2 text-sm font-medium text-[var(--color-text-primary)] transition-all duration-200 hover:border-[var(--color-status-error-border)] hover:bg-[var(--color-status-error-bgSubtle)] hover:text-[var(--color-status-error-text)] disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {isProcessingWorkspaceReject ? (\n <Loader2 size={14} className=\"animate-spin\" />\n ) : null}\n {tr('members.myInvites.decline', 'Decline')}\n </button>\n </div>\n </div>\n </GlassCard>\n );\n })}\n </div>\n )\n ) : invites.length === 0 ? (\n <GlassCard treatment=\"glass\" className=\"rounded-xl\">\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title={tr('members.myInvites.emptyTitle', 'No pending invites')}\n description={tr(\n 'members.myInvites.emptyDescription',\n 'When someone invites you to an organization, it will appear here.'\n )}\n />\n </GlassCard>\n ) : (\n <div className=\"space-y-3\">\n {invites.map((invite) => (\n <MyInviteCard\n key={invite.id}\n invite={invite}\n onAccept={handleAccept}\n onReject={handleReject}\n accepting={accepting}\n rejecting={rejecting}\n />\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MyInvitesPage.js","names":[],"sources":["../../../../../src/organization-management/modules/members/pages/MyInvitesPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { NavLink } from 'react-router-dom';\nimport { Mail, Loader2, AlertCircle, BriefcaseBusiness } from 'lucide-react';\nimport { usePermissions } from '@burdenoff/fe-libs/shared/providers/shell';\nimport {\n ActorIdentity,\n useActorProfiles,\n type ActorInput,\n type ActorProfileMap,\n} from '@burdenoff/fe-libs/shared';\nimport { Badge, GlassCard, IllustratedEmptyState, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { useMyInvites, useAcceptInvite, useRejectInvite } from '../hooks/useInvites';\nimport {\n useAcceptWorkspaceInvite,\n useMyWorkspaceInvites,\n useRejectWorkspaceInvite,\n} from '../hooks/useWorkspaceInvites';\nimport { MyInviteCard } from '../components/MyInviteCard';\nimport { LoadingState } from '../../../shared/components/feedback/LoadingState';\nimport { InviteStatus as OrganizationInviteStatus } from '../../../../generated/global-types';\nimport { useTr } from '../../../shared/hooks/useTr';\nimport { useOrganizationPageView } from '../../../hooks/useOrganizationPageView';\nimport { useOrgConsole } from '../../../providers/OrgConsoleProvider';\nimport {\n getProjectDisplayNames,\n getRoleDisplayNames,\n getWorkspaceDisplayName,\n} from '../utils/workspaceInvitationDisplay';\n\n/**\n * My Invites Page\n * Shows pending invites for the current user with accept/reject actions\n */\ntype MyInvitesTab = 'workspace' | 'organization';\n\ninterface MyInvitesPageProps {\n activeTab?: MyInvitesTab;\n}\n\ninterface TabActionError {\n tab: MyInvitesTab;\n message: string;\n}\n\ninterface InvitesTabNavProps {\n activeTab: MyInvitesTab;\n basePath: string;\n tr: ReturnType<typeof useTr>;\n}\n\nfunction formatDate(value?: string | null) {\n if (!value) return null;\n\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return null;\n\n return date.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nfunction joinPath(base: string, path: string): string {\n const cleanBase = base.endsWith('/') ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return cleanBase + cleanPath;\n}\n\nfunction InvitesTabNav({ activeTab, basePath, tr }: InvitesTabNavProps) {\n const getTabClassName = (isActive: boolean) =>\n [\n 'border-b-2 px-4 py-2 text-sm font-medium transition-colors',\n isActive\n ? 'border-[var(--color-border-focus)] text-[var(--color-text-primary)]'\n : 'border-transparent text-[var(--color-text-muted)] hover:text-[var(--color-text-primary)]',\n ].join(' ');\n\n return (\n <div className=\"mb-6 flex gap-2 border-b border-[var(--color-border-default)]\">\n <NavLink\n to={joinPath(basePath, '/invites')}\n end\n className={getTabClassName(activeTab === 'workspace')}\n >\n {tr('members.myInvites.workspaceTab', 'Workspace Invites')}\n </NavLink>\n <NavLink\n to={joinPath(basePath, '/invites/organizations')}\n className={getTabClassName(activeTab === 'organization')}\n >\n {tr('members.myInvites.organizationTab', 'Organization Invites')}\n </NavLink>\n </div>\n );\n}\n\nexport function MyInvitesPage({ activeTab = 'workspace' }: MyInvitesPageProps) {\n useOrganizationPageView(\n activeTab === 'workspace'\n ? 'organizations.my-workspace-invites'\n : 'organizations.my-organization-invites'\n );\n const tr = useTr();\n const { isLoading: permissionsLoading } = usePermissions();\n const { basePath = '/organizations', currentUser, authToken, apiGatewayUrl } = useOrgConsole();\n const orgInvitesEnabled = activeTab === 'organization';\n const workspaceInvitesEnabled = activeTab === 'workspace';\n const { invites, loading, error, total } = useMyInvites(\n OrganizationInviteStatus.Pending,\n 20,\n 0,\n orgInvitesEnabled\n );\n const {\n invites: workspaceInvites,\n loading: workspaceLoading,\n error: workspaceError,\n total: workspaceTotal,\n refetch: refetchWorkspaceInvites,\n } = useMyWorkspaceInvites(currentUser?.email, workspaceInvitesEnabled);\n const { acceptInvite, loading: accepting } = useAcceptInvite();\n const { rejectInvite, loading: rejecting } = useRejectInvite();\n const { acceptInvite: acceptWorkspaceInvite, loading: acceptingWorkspace } =\n useAcceptWorkspaceInvite();\n const { rejectInvite: rejectWorkspaceInvite, loading: rejectingWorkspace } =\n useRejectWorkspaceInvite();\n const [actionError, setActionError] = useState<TabActionError | null>(null);\n\n const visibleActionError = actionError?.tab === activeTab ? actionError.message : null;\n const [processingWorkspaceAction, setProcessingWorkspaceAction] = useState<{\n inviteId: string;\n action: 'accept' | 'reject';\n } | null>(null);\n\n const workspaceInviteActors = useMemo<ActorInput[]>(\n () =>\n workspaceInvites.flatMap((invite) =>\n invite.invitedById ? [{ actorId: invite.invitedById, actorType: 'user' as const }] : []\n ),\n [workspaceInvites]\n );\n\n const inviterProfiles: ActorProfileMap = useActorProfiles(workspaceInviteActors, {\n apiGatewayUrl,\n authToken,\n });\n\n const sortedWorkspaceInvites = useMemo(\n () =>\n [...workspaceInvites].sort(\n (left: (typeof workspaceInvites)[number], right: (typeof workspaceInvites)[number]) =>\n new Date(right.createdAt).getTime() - new Date(left.createdAt).getTime()\n ),\n [workspaceInvites]\n );\n\n const totalCount = activeTab === 'workspace' ? workspaceTotal : total;\n\n const handleAccept = async (inviteId: string) => {\n try {\n setActionError(null);\n await acceptInvite(inviteId);\n } catch (err) {\n setActionError({\n tab: 'organization',\n message:\n err instanceof Error\n ? err.message\n : tr('members.myInvites.acceptFailed', 'Failed to accept invite'),\n });\n }\n };\n\n const handleReject = async (inviteId: string) => {\n try {\n setActionError(null);\n await rejectInvite(inviteId);\n } catch (err) {\n setActionError({\n tab: 'organization',\n message:\n err instanceof Error\n ? err.message\n : tr('members.myInvites.rejectFailed', 'Failed to reject invite'),\n });\n }\n };\n\n const handleAcceptWorkspace = async (inviteId: string) => {\n try {\n setProcessingWorkspaceAction({ inviteId, action: 'accept' });\n setActionError(null);\n await acceptWorkspaceInvite(inviteId);\n await refetchWorkspaceInvites().catch(() => undefined);\n } catch (err) {\n setActionError({\n tab: 'workspace',\n message:\n err instanceof Error\n ? err.message\n : tr('members.myInvites.workspaceAcceptFailed', 'Failed to accept workspace invite'),\n });\n } finally {\n setProcessingWorkspaceAction((current) =>\n current?.inviteId === inviteId && current.action === 'accept' ? null : current\n );\n }\n };\n\n const handleRejectWorkspace = async (inviteId: string) => {\n try {\n setProcessingWorkspaceAction({ inviteId, action: 'reject' });\n setActionError(null);\n await rejectWorkspaceInvite(inviteId);\n await refetchWorkspaceInvites().catch(() => undefined);\n } catch (err) {\n setActionError({\n tab: 'workspace',\n message:\n err instanceof Error\n ? err.message\n : tr('members.myInvites.workspaceRejectFailed', 'Failed to reject workspace invite'),\n });\n } finally {\n setProcessingWorkspaceAction((current) =>\n current?.inviteId === inviteId && current.action === 'reject' ? null : current\n );\n }\n };\n\n // Own invites are always accessible — no permission denial needed.\n // We still wait for permissions to load to ensure consistent UX.\n if (permissionsLoading) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] p-6\">\n <LoadingState message={tr('common.loadingPermissions', 'Loading permissions...')} />\n </div>\n );\n }\n\n if (workspaceInvitesEnabled && !currentUser?.email) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <div className=\"max-w-4xl mx-auto\">\n <div className=\"mb-6 flex items-center gap-3\">\n <Mail size={24} className=\"text-[var(--color-text-primary)]\" />\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.myInvites.title', 'My Invites')}\n </h1>\n </div>\n\n <InvitesTabNav activeTab={activeTab} basePath={basePath} tr={tr} />\n\n <div className=\"rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)] p-6 text-center\">\n <p className=\"text-[var(--color-text-secondary)]\">\n {tr('members.myInvites.signInWorkspace', 'Sign in to view your workspace invites.')}\n </p>\n </div>\n </div>\n </div>\n );\n }\n\n if (orgInvitesEnabled && loading && invites.length === 0) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <div className=\"max-w-4xl mx-auto\">\n <div className=\"mb-6 flex items-center gap-3\">\n <Mail size={24} className=\"text-[var(--color-text-primary)]\" />\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.myInvites.title', 'My Invites')}\n </h1>\n </div>\n\n <InvitesTabNav activeTab={activeTab} basePath={basePath} tr={tr} />\n\n <div className=\"flex items-center justify-center min-h-[300px] rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)]\">\n <Loader2 size={24} className=\"animate-spin text-[var(--color-text-muted)]\" />\n </div>\n </div>\n </div>\n );\n }\n\n if (workspaceInvitesEnabled && workspaceLoading && workspaceInvites.length === 0) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <div className=\"max-w-4xl mx-auto\">\n <div className=\"mb-6 flex items-center gap-3\">\n <Mail size={24} className=\"text-[var(--color-text-primary)]\" />\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.myInvites.title', 'My Invites')}\n </h1>\n </div>\n\n <InvitesTabNav activeTab={activeTab} basePath={basePath} tr={tr} />\n\n <div className=\"flex items-center justify-center min-h-[300px] rounded-xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)]\">\n <Loader2 size={24} className=\"animate-spin text-[var(--color-text-muted)]\" />\n </div>\n </div>\n </div>\n );\n }\n\n if (orgInvitesEnabled && error) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <div className=\"max-w-4xl mx-auto\">\n <div className=\"mb-6 flex items-center gap-3\">\n <Mail size={24} className=\"text-[var(--color-text-primary)]\" />\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.myInvites.title', 'My Invites')}\n </h1>\n </div>\n\n <InvitesTabNav activeTab={activeTab} basePath={basePath} tr={tr} />\n\n <div className=\"rounded-xl border border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] p-6 text-center\">\n <p className=\"text-[var(--color-status-error-text)]\">\n {tr('members.myInvites.loadFailed', 'Failed to load invites')}: {error.message}\n </p>\n </div>\n </div>\n </div>\n );\n }\n\n if (workspaceInvitesEnabled && workspaceError) {\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <div className=\"max-w-4xl mx-auto\">\n <div className=\"mb-6 flex items-center gap-3\">\n <Mail size={24} className=\"text-[var(--color-text-primary)]\" />\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.myInvites.title', 'My Invites')}\n </h1>\n </div>\n\n <InvitesTabNav activeTab={activeTab} basePath={basePath} tr={tr} />\n\n <div className=\"rounded-xl border border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] p-6 text-center\">\n <p className=\"text-[var(--color-status-error-text)]\">\n {tr('members.myInvites.workspaceLoadFailed', 'Failed to load workspace invites')}:{' '}\n {workspaceError.message}\n </p>\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"min-h-full bg-[var(--color-bg-canvas)] px-4 py-6 sm:px-6\">\n <div className=\"max-w-4xl mx-auto\">\n {/* Header */}\n <div className=\"flex items-center gap-3 mb-6\">\n <Mail size={24} className=\"text-[var(--color-text-primary)]\" />\n <h1 className=\"text-2xl font-bold text-[var(--color-text-primary)]\">\n {tr('members.myInvites.title', 'My Invites')}\n </h1>\n {totalCount > 0 && (\n <span className=\"px-2.5 py-0.5 rounded-full text-xs font-medium bg-[var(--color-action-primary-bg)] text-[var(--color-action-primary-text)]\">\n {totalCount}\n </span>\n )}\n </div>\n\n <InvitesTabNav activeTab={activeTab} basePath={basePath} tr={tr} />\n\n <PagePurpose className=\"mb-4 max-w-3xl\">\n {tr(\n 'members.myInvites.purpose',\n 'This is your personal inbox for invitations — when someone invites you to a workspace or organization, accept it here to gain access, or decline if it was not meant for you. Switch tabs to review each type of invite.'\n )}\n </PagePurpose>\n\n {visibleActionError && (\n <div className=\"mb-4 flex items-center gap-2 rounded-lg border border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] p-3\">\n <AlertCircle size={16} className=\"shrink-0 text-[var(--color-status-error-text)]\" />\n <p className=\"text-sm text-[var(--color-status-error-text)]\">{visibleActionError}</p>\n </div>\n )}\n\n {workspaceInvitesEnabled ? (\n sortedWorkspaceInvites.length === 0 ? (\n <GlassCard treatment=\"glass\" glow className=\"rounded-xl\">\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title={tr('members.myInvites.workspaceEmptyTitle', 'No pending workspace invites')}\n description={tr(\n 'members.myInvites.workspaceEmptyDescription',\n 'When someone invites you to a workspace, it will appear here.'\n )}\n />\n </GlassCard>\n ) : (\n <div className=\"space-y-3\">\n {sortedWorkspaceInvites.map((invite) => {\n const workspaceName = getWorkspaceDisplayName(invite);\n const roleNames = getRoleDisplayNames(invite);\n const projectNames = getProjectDisplayNames(invite);\n const inviterProfile = invite.invitedById\n ? inviterProfiles[invite.invitedById]\n : undefined;\n const inviterLabel =\n inviterProfile?.displayName ||\n inviterProfile?.email ||\n tr('members.myInvites.invitedByFallback', 'Someone');\n const isProcessingWorkspaceAccept =\n processingWorkspaceAction?.inviteId === invite.id &&\n processingWorkspaceAction?.action === 'accept' &&\n acceptingWorkspace;\n const isProcessingWorkspaceReject =\n processingWorkspaceAction?.inviteId === invite.id &&\n processingWorkspaceAction?.action === 'reject' &&\n rejectingWorkspace;\n\n return (\n <GlassCard key={invite.id} treatment=\"insight\" className=\"border-border-seam p-5\">\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"min-w-0 space-y-3\">\n <div className=\"flex items-start gap-3\">\n <div className=\"rounded-lg bg-[var(--color-bg-subtle)] p-2\">\n <BriefcaseBusiness\n size={20}\n className=\"text-[var(--color-text-secondary)]\"\n />\n </div>\n <div className=\"min-w-0\">\n <h3 className=\"font-semibold text-[var(--color-text-primary)] break-words\">\n {workspaceName}\n </h3>\n <p className=\"mt-1 text-sm text-[var(--color-text-secondary)] break-all\">\n {invite.email}\n </p>\n </div>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"secondary\">{invite.status}</Badge>\n {roleNames.map((roleName) => (\n <Badge key={`${invite.id}-${roleName}`} variant=\"outline\">\n {roleName}\n </Badge>\n ))}\n </div>\n\n <dl className=\"grid gap-3 text-sm text-[var(--color-text-secondary)] sm:grid-cols-2\">\n <div>\n <dt className=\"font-medium text-[var(--color-text-primary)]\">\n {tr('members.myInvites.invitedByLabel', 'Invited by')}\n </dt>\n <dd className=\"break-all\">\n {inviterProfile ? (\n <ActorIdentity\n profile={inviterProfile}\n variant=\"inline\"\n hideIdDrilldown\n />\n ) : (\n inviterLabel\n )}\n </dd>\n </div>\n <div>\n <dt className=\"font-medium text-[var(--color-text-primary)]\">\n {tr('members.myInvites.receivedLabel', 'Received')}\n </dt>\n <dd>{formatDate(invite.createdAt) ?? '—'}</dd>\n </div>\n <div>\n <dt className=\"font-medium text-[var(--color-text-primary)]\">\n {tr('members.myInvites.expiresLabel', 'Expires')}\n </dt>\n <dd>{formatDate(invite.expiresAt) ?? '—'}</dd>\n </div>\n {projectNames.length > 0 ? (\n <div className=\"sm:col-span-2\">\n <dt className=\"font-medium text-[var(--color-text-primary)]\">\n {tr('members.myInvites.projectsLabel', 'Projects')}\n </dt>\n <dd className=\"mt-1 flex flex-wrap gap-2\">\n {projectNames.map((projectName) => (\n <Badge key={`${invite.id}-${projectName}`} variant=\"outline\">\n {projectName}\n </Badge>\n ))}\n </dd>\n </div>\n ) : null}\n </dl>\n </div>\n\n <div className=\"flex flex-wrap items-center gap-2 shrink-0\">\n <button\n type=\"button\"\n onClick={() => void handleAcceptWorkspace(invite.id)}\n disabled={isProcessingWorkspaceAccept || isProcessingWorkspaceReject}\n className=\"inline-flex items-center gap-1.5 rounded-lg bg-[var(--color-status-success-bg)] px-4 py-2 text-sm font-medium text-[var(--color-text-inverse)] transition-all duration-200 hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {isProcessingWorkspaceAccept ? (\n <Loader2 size={14} className=\"animate-spin\" />\n ) : null}\n {tr('members.myInvites.accept', 'Accept')}\n </button>\n <button\n type=\"button\"\n onClick={() => void handleRejectWorkspace(invite.id)}\n disabled={isProcessingWorkspaceAccept || isProcessingWorkspaceReject}\n className=\"inline-flex items-center gap-1.5 rounded-lg border border-[var(--color-border-default)] bg-transparent px-4 py-2 text-sm font-medium text-[var(--color-text-primary)] transition-all duration-200 hover:border-[var(--color-status-error-border)] hover:bg-[var(--color-status-error-bgSubtle)] hover:text-[var(--color-status-error-text)] disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {isProcessingWorkspaceReject ? (\n <Loader2 size={14} className=\"animate-spin\" />\n ) : null}\n {tr('members.myInvites.decline', 'Decline')}\n </button>\n </div>\n </div>\n </GlassCard>\n );\n })}\n </div>\n )\n ) : invites.length === 0 ? (\n <GlassCard treatment=\"glass\" glow className=\"rounded-xl\">\n <IllustratedEmptyState\n illustration=\"empty-notifications\"\n title={tr('members.myInvites.emptyTitle', 'No pending invites')}\n description={tr(\n 'members.myInvites.emptyDescription',\n 'When someone invites you to an organization, it will appear here.'\n )}\n />\n </GlassCard>\n ) : (\n <div className=\"space-y-3\">\n {invites.map((invite) => (\n <MyInviteCard\n key={invite.id}\n invite={invite}\n onAccept={handleAccept}\n onReject={handleReject}\n accepting={accepting}\n rejecting={rejecting}\n />\n ))}\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
package/dist/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.js
CHANGED
|
@@ -5,11 +5,11 @@ import { useTr as a } from "../../../shared/hooks/useTr.js";
|
|
|
5
5
|
import { useOrganizationPageView as o } from "../../../hooks/useOrganizationPageView.js";
|
|
6
6
|
import { useState as s } from "react";
|
|
7
7
|
import { AlertTriangle as c, Ban as l, Building2 as u, CheckCircle as d, Clock as f, Home as p, Loader2 as m, Mail as h, XCircle as g } from "lucide-react";
|
|
8
|
-
import { Badge as _, EmphasisPanel as v, GlassCard as y } from "@burdenoff/fe-libs/ui";
|
|
9
|
-
import { jsx as
|
|
10
|
-
import { useParams as
|
|
8
|
+
import { Badge as _, EmphasisPanel as v, GlassCard as y, PagePurpose as b } from "@burdenoff/fe-libs/ui";
|
|
9
|
+
import { jsx as x, jsxs as S } from "react/jsx-runtime";
|
|
10
|
+
import { useParams as C } from "react-router-dom";
|
|
11
11
|
//#region src/organization-management/modules/members/pages/OrganizationInviteAcceptancePage.tsx
|
|
12
|
-
function
|
|
12
|
+
function w(e) {
|
|
13
13
|
if (!e) return null;
|
|
14
14
|
let t = new Date(e);
|
|
15
15
|
return Number.isNaN(t.getTime()) ? null : t.toLocaleDateString("en-US", {
|
|
@@ -20,270 +20,274 @@ function C(e) {
|
|
|
20
20
|
minute: "2-digit"
|
|
21
21
|
});
|
|
22
22
|
}
|
|
23
|
-
function
|
|
24
|
-
return /* @__PURE__ */
|
|
23
|
+
function T({ children: e }) {
|
|
24
|
+
return /* @__PURE__ */ x("div", {
|
|
25
25
|
className: "min-h-full bg-[var(--color-bg-canvas)] px-4 py-10 sm:px-6",
|
|
26
|
-
children: /* @__PURE__ */
|
|
26
|
+
children: /* @__PURE__ */ x("div", {
|
|
27
27
|
className: "mx-auto max-w-2xl",
|
|
28
28
|
children: e
|
|
29
29
|
})
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
|
-
function
|
|
33
|
-
return /* @__PURE__ */
|
|
32
|
+
function E({ icon: e, iconClass: t, title: n, description: r, email: i, primaryLabel: a, onPrimary: o }) {
|
|
33
|
+
return /* @__PURE__ */ x(T, { children: /* @__PURE__ */ S(y, {
|
|
34
34
|
treatment: "plain",
|
|
35
35
|
className: "border-border-seam p-8 text-center",
|
|
36
36
|
children: [
|
|
37
|
-
/* @__PURE__ */
|
|
37
|
+
/* @__PURE__ */ x("div", {
|
|
38
38
|
className: `mx-auto mb-4 flex size-14 items-center justify-center rounded-2xl ${t}`,
|
|
39
|
-
children: /* @__PURE__ */
|
|
39
|
+
children: /* @__PURE__ */ x(e, { size: 28 })
|
|
40
40
|
}),
|
|
41
|
-
/* @__PURE__ */
|
|
41
|
+
/* @__PURE__ */ x("h1", {
|
|
42
42
|
className: "text-2xl font-bold text-[var(--color-text-primary)]",
|
|
43
43
|
children: n
|
|
44
44
|
}),
|
|
45
|
-
/* @__PURE__ */
|
|
45
|
+
/* @__PURE__ */ x("p", {
|
|
46
46
|
className: "mt-2 text-[var(--color-text-secondary)]",
|
|
47
47
|
children: r
|
|
48
48
|
}),
|
|
49
|
-
i ? /* @__PURE__ */
|
|
49
|
+
i ? /* @__PURE__ */ x("p", {
|
|
50
50
|
className: "mt-1 break-all text-sm text-[var(--color-text-muted)]",
|
|
51
51
|
children: i
|
|
52
52
|
}) : null,
|
|
53
|
-
/* @__PURE__ */
|
|
53
|
+
/* @__PURE__ */ S("button", {
|
|
54
54
|
type: "button",
|
|
55
55
|
onClick: o,
|
|
56
56
|
className: "mt-6 inline-flex items-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-6 py-2.5 font-medium text-[var(--color-action-primary-text)] transition-all duration-200 hover:opacity-90",
|
|
57
|
-
children: [/* @__PURE__ */
|
|
57
|
+
children: [/* @__PURE__ */ x(p, { size: 16 }), a]
|
|
58
58
|
})
|
|
59
59
|
]
|
|
60
60
|
}) });
|
|
61
61
|
}
|
|
62
|
-
function
|
|
62
|
+
function D() {
|
|
63
63
|
o("organizations.invite-acceptance");
|
|
64
|
-
let
|
|
65
|
-
if (
|
|
66
|
-
|
|
64
|
+
let D = a(), { inviteId: O = "" } = C(), { basePath: k = "/organizations", navigate: A, currentUser: j, authToken: M } = e(), N = !!(M || j?.email), { invite: P, loading: F, error: I, refetch: L } = n(O, N), { acceptInvite: R } = t(), { rejectInvite: z } = r(), [B, V] = s(null), [H, U] = s(null), W = () => A(`${k}/invites/organizations`), G = async () => {
|
|
65
|
+
if (O) try {
|
|
66
|
+
V("accept"), U(null), await R(O), A(P?.organizationId ? `${k}/${P.organizationId}` : k);
|
|
67
67
|
} catch (e) {
|
|
68
|
-
|
|
68
|
+
U(e instanceof Error ? e.message : D("members.inviteAcceptance.acceptFailed", "Failed to accept invitation"));
|
|
69
69
|
} finally {
|
|
70
|
-
|
|
70
|
+
V(null);
|
|
71
71
|
}
|
|
72
|
-
},
|
|
73
|
-
if (
|
|
74
|
-
|
|
72
|
+
}, K = async () => {
|
|
73
|
+
if (O) try {
|
|
74
|
+
V("reject"), U(null), await z(O), W();
|
|
75
75
|
} catch (e) {
|
|
76
|
-
|
|
76
|
+
U(e instanceof Error ? e.message : D("members.inviteAcceptance.rejectFailed", "Failed to reject invitation"));
|
|
77
77
|
} finally {
|
|
78
|
-
|
|
78
|
+
V(null);
|
|
79
79
|
}
|
|
80
80
|
};
|
|
81
|
-
if (!
|
|
82
|
-
let e = encodeURIComponent(`${
|
|
83
|
-
return /* @__PURE__ */
|
|
81
|
+
if (!N) {
|
|
82
|
+
let e = encodeURIComponent(`${k}/invite/${O}`);
|
|
83
|
+
return /* @__PURE__ */ x(T, { children: /* @__PURE__ */ S(y, {
|
|
84
84
|
treatment: "plain",
|
|
85
85
|
className: "border-border-seam p-8",
|
|
86
86
|
children: [
|
|
87
|
-
/* @__PURE__ */
|
|
87
|
+
/* @__PURE__ */ S("div", {
|
|
88
88
|
className: "mb-4 flex items-center gap-3",
|
|
89
|
-
children: [/* @__PURE__ */
|
|
89
|
+
children: [/* @__PURE__ */ x("div", {
|
|
90
90
|
className: "rounded-xl bg-[var(--color-bg-subtle)] p-3",
|
|
91
|
-
children: /* @__PURE__ */
|
|
91
|
+
children: /* @__PURE__ */ x(h, {
|
|
92
92
|
size: 24,
|
|
93
93
|
className: "text-[var(--color-text-primary)]"
|
|
94
94
|
})
|
|
95
|
-
}), /* @__PURE__ */
|
|
95
|
+
}), /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("h1", {
|
|
96
96
|
className: "text-2xl font-bold text-[var(--color-text-primary)]",
|
|
97
|
-
children:
|
|
98
|
-
}), /* @__PURE__ */
|
|
97
|
+
children: D("members.inviteAcceptance.signInRequired", "Sign in to view your invitation")
|
|
98
|
+
}), /* @__PURE__ */ x("p", {
|
|
99
99
|
className: "text-[var(--color-text-secondary)]",
|
|
100
|
-
children:
|
|
100
|
+
children: D("members.inviteAcceptance.signInDescription", "Organization invitations require an authenticated account before you can review or accept them.")
|
|
101
101
|
})] })]
|
|
102
102
|
}),
|
|
103
|
-
/* @__PURE__ */
|
|
103
|
+
/* @__PURE__ */ x("p", {
|
|
104
104
|
className: "mb-6 text-sm text-[var(--color-text-muted)]",
|
|
105
|
-
children:
|
|
105
|
+
children: D("members.inviteAcceptance.signInHint", "Use the same email address that received the invitation, then come back here to accept or decline it.")
|
|
106
106
|
}),
|
|
107
|
-
/* @__PURE__ */
|
|
107
|
+
/* @__PURE__ */ S("div", {
|
|
108
108
|
className: "flex flex-col gap-3 sm:flex-row",
|
|
109
|
-
children: [/* @__PURE__ */
|
|
109
|
+
children: [/* @__PURE__ */ x("a", {
|
|
110
110
|
href: `/auth/login?returnTo=${e}`,
|
|
111
111
|
className: "inline-flex items-center justify-center gap-2 rounded-lg bg-[var(--color-action-primary-bg)] px-6 py-2.5 font-medium text-[var(--color-action-primary-text)] transition-all duration-200 hover:opacity-90",
|
|
112
|
-
children:
|
|
113
|
-
}), /* @__PURE__ */
|
|
112
|
+
children: D("members.inviteAcceptance.signInButton", "Sign In")
|
|
113
|
+
}), /* @__PURE__ */ S("button", {
|
|
114
114
|
type: "button",
|
|
115
|
-
onClick: () => k
|
|
115
|
+
onClick: () => A(k),
|
|
116
116
|
className: "inline-flex items-center justify-center gap-2 rounded-lg border border-[var(--color-border-default)] bg-transparent px-6 py-2.5 font-medium text-[var(--color-text-primary)] transition-all duration-200 hover:bg-[var(--color-bg-subtle)]",
|
|
117
|
-
children: [/* @__PURE__ */
|
|
117
|
+
children: [/* @__PURE__ */ x(p, { size: 16 }), D("members.inviteAcceptance.backToOrganizations", "Back to Organizations")]
|
|
118
118
|
})]
|
|
119
119
|
})
|
|
120
120
|
]
|
|
121
121
|
}) });
|
|
122
122
|
}
|
|
123
|
-
if (
|
|
123
|
+
if (F) return /* @__PURE__ */ x(T, { children: /* @__PURE__ */ x("div", {
|
|
124
124
|
className: "flex min-h-[300px] items-center justify-center rounded-2xl border border-[var(--color-border-default)] bg-[var(--color-bg-surface)]",
|
|
125
|
-
children: /* @__PURE__ */
|
|
125
|
+
children: /* @__PURE__ */ x(m, {
|
|
126
126
|
size: 28,
|
|
127
127
|
className: "animate-spin text-[var(--color-text-muted)]"
|
|
128
128
|
})
|
|
129
129
|
}) });
|
|
130
|
-
if (
|
|
130
|
+
if (I) return /* @__PURE__ */ x(E, {
|
|
131
131
|
icon: c,
|
|
132
132
|
iconClass: "bg-[var(--color-status-error-bgSubtle)] text-[var(--color-status-error-text)]",
|
|
133
|
-
title:
|
|
134
|
-
description:
|
|
135
|
-
primaryLabel:
|
|
133
|
+
title: D("members.inviteAcceptance.errorTitle", "Error Loading Invitation"),
|
|
134
|
+
description: I.message,
|
|
135
|
+
primaryLabel: D("members.inviteAcceptance.tryAgain", "Try Again"),
|
|
136
136
|
onPrimary: () => {
|
|
137
|
-
|
|
137
|
+
L();
|
|
138
138
|
}
|
|
139
139
|
});
|
|
140
|
-
if (!
|
|
140
|
+
if (!P) return /* @__PURE__ */ x(E, {
|
|
141
141
|
icon: c,
|
|
142
142
|
iconClass: "bg-[var(--color-bg-subtle)] text-[var(--color-text-muted)]",
|
|
143
|
-
title:
|
|
144
|
-
description:
|
|
145
|
-
primaryLabel:
|
|
146
|
-
onPrimary: () => k
|
|
143
|
+
title: D("members.inviteAcceptance.notFoundTitle", "Invitation Not Found"),
|
|
144
|
+
description: D("members.inviteAcceptance.notFoundDescription", "This invitation link is invalid, has been removed, or was addressed to a different account."),
|
|
145
|
+
primaryLabel: D("members.inviteAcceptance.goToOrganizations", "Go to Organizations"),
|
|
146
|
+
onPrimary: () => A(k)
|
|
147
147
|
});
|
|
148
|
-
let
|
|
149
|
-
if (
|
|
148
|
+
let q = P.expiresAt && new Date(P.expiresAt) < /* @__PURE__ */ new Date(), J = P.status === i.Pending && q ? i.Expired : P.status;
|
|
149
|
+
if (J === i.Accepted) return /* @__PURE__ */ x(E, {
|
|
150
150
|
icon: d,
|
|
151
151
|
iconClass: "bg-[var(--color-status-success-bgSubtle)] text-[var(--color-status-success-text)]",
|
|
152
|
-
title:
|
|
153
|
-
description:
|
|
154
|
-
email:
|
|
155
|
-
primaryLabel:
|
|
156
|
-
onPrimary: () =>
|
|
152
|
+
title: D("members.inviteAcceptance.alreadyAcceptedTitle", "Invitation Already Accepted"),
|
|
153
|
+
description: D("members.inviteAcceptance.alreadyAcceptedDescription", "You have already accepted this invitation."),
|
|
154
|
+
email: P.email,
|
|
155
|
+
primaryLabel: D("members.inviteAcceptance.goToOrganization", "Go to Organization"),
|
|
156
|
+
onPrimary: () => A(`${k}/${P.organizationId}`)
|
|
157
157
|
});
|
|
158
|
-
if (
|
|
158
|
+
if (J === i.Rejected) return /* @__PURE__ */ x(E, {
|
|
159
159
|
icon: g,
|
|
160
160
|
iconClass: "bg-[var(--color-bg-subtle)] text-[var(--color-text-muted)]",
|
|
161
|
-
title:
|
|
162
|
-
description:
|
|
163
|
-
email:
|
|
164
|
-
primaryLabel:
|
|
165
|
-
onPrimary: () => k
|
|
161
|
+
title: D("members.inviteAcceptance.rejectedTitle", "Invitation Declined"),
|
|
162
|
+
description: D("members.inviteAcceptance.rejectedDescription", "This invitation was previously declined."),
|
|
163
|
+
email: P.email,
|
|
164
|
+
primaryLabel: D("members.inviteAcceptance.goToOrganizations", "Go to Organizations"),
|
|
165
|
+
onPrimary: () => A(k)
|
|
166
166
|
});
|
|
167
|
-
if (
|
|
167
|
+
if (J === i.Expired) return /* @__PURE__ */ x(E, {
|
|
168
168
|
icon: f,
|
|
169
169
|
iconClass: "bg-[var(--color-status-warning-bgSubtle)] text-[var(--color-status-warning-text)]",
|
|
170
|
-
title:
|
|
171
|
-
description:
|
|
172
|
-
email:
|
|
173
|
-
primaryLabel:
|
|
174
|
-
onPrimary: () => k
|
|
170
|
+
title: D("members.inviteAcceptance.expiredTitle", "Invitation Expired"),
|
|
171
|
+
description: D("members.inviteAcceptance.expiredDescription", "This invitation has expired. Please contact an organization admin for a new one."),
|
|
172
|
+
email: P.email,
|
|
173
|
+
primaryLabel: D("members.inviteAcceptance.goToOrganizations", "Go to Organizations"),
|
|
174
|
+
onPrimary: () => A(k)
|
|
175
175
|
});
|
|
176
|
-
if (
|
|
176
|
+
if (J === i.Cancelled) return /* @__PURE__ */ x(E, {
|
|
177
177
|
icon: l,
|
|
178
178
|
iconClass: "bg-[var(--color-status-error-bgSubtle)] text-[var(--color-status-error-text)]",
|
|
179
|
-
title:
|
|
180
|
-
description:
|
|
181
|
-
email:
|
|
182
|
-
primaryLabel:
|
|
183
|
-
onPrimary: () => k
|
|
179
|
+
title: D("members.inviteAcceptance.cancelledTitle", "Invitation Cancelled"),
|
|
180
|
+
description: D("members.inviteAcceptance.cancelledDescription", "This invitation was cancelled by the sender and is no longer valid."),
|
|
181
|
+
email: P.email,
|
|
182
|
+
primaryLabel: D("members.inviteAcceptance.goToOrganizations", "Go to Organizations"),
|
|
183
|
+
onPrimary: () => A(k)
|
|
184
184
|
});
|
|
185
|
-
let
|
|
186
|
-
return /* @__PURE__ */
|
|
185
|
+
let Y = P.organization?.name ?? P.organizationId, X = w(P.expiresAt), Z = B !== null;
|
|
186
|
+
return /* @__PURE__ */ x(T, { children: /* @__PURE__ */ S(v, {
|
|
187
187
|
className: "p-8",
|
|
188
188
|
children: [
|
|
189
|
-
/* @__PURE__ */
|
|
189
|
+
/* @__PURE__ */ S("div", {
|
|
190
190
|
className: "mb-6 flex items-center gap-3",
|
|
191
|
-
children: [/* @__PURE__ */
|
|
191
|
+
children: [/* @__PURE__ */ x("div", {
|
|
192
192
|
className: "rounded-xl bg-[var(--color-bg-subtle)] p-3",
|
|
193
|
-
children: /* @__PURE__ */
|
|
193
|
+
children: /* @__PURE__ */ x(u, {
|
|
194
194
|
size: 24,
|
|
195
195
|
className: "text-[var(--color-text-primary)]"
|
|
196
196
|
})
|
|
197
|
-
}), /* @__PURE__ */
|
|
197
|
+
}), /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("h1", {
|
|
198
198
|
className: "text-2xl font-bold text-[var(--color-text-primary)]",
|
|
199
|
-
children:
|
|
200
|
-
}), /* @__PURE__ */
|
|
199
|
+
children: D("members.inviteAcceptance.pageTitle", "Organization Invitation")
|
|
200
|
+
}), /* @__PURE__ */ S("p", {
|
|
201
201
|
className: "text-[var(--color-text-secondary)]",
|
|
202
202
|
children: [
|
|
203
|
-
|
|
203
|
+
D("members.inviteAcceptance.pageSubtitle", "You've been invited to join"),
|
|
204
204
|
" ",
|
|
205
|
-
/* @__PURE__ */
|
|
205
|
+
/* @__PURE__ */ x("span", {
|
|
206
206
|
className: "font-medium text-[var(--color-text-primary)]",
|
|
207
|
-
children:
|
|
207
|
+
children: Y
|
|
208
208
|
})
|
|
209
209
|
]
|
|
210
210
|
})] })]
|
|
211
211
|
}),
|
|
212
|
-
/* @__PURE__ */ x(
|
|
212
|
+
/* @__PURE__ */ x(b, {
|
|
213
|
+
className: "mb-6",
|
|
214
|
+
children: D("members.inviteAcceptance.purpose", "Review the details of this invitation below. Accept it to join the organization and gain access to its workspaces, or decline if it was not meant for you.")
|
|
215
|
+
}),
|
|
216
|
+
/* @__PURE__ */ S("dl", {
|
|
213
217
|
className: "space-y-4 rounded-xl bg-[var(--color-bg-subtle)] p-5",
|
|
214
218
|
children: [
|
|
215
|
-
/* @__PURE__ */
|
|
219
|
+
/* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("dt", {
|
|
216
220
|
className: "text-sm font-medium text-[var(--color-text-muted)]",
|
|
217
|
-
children:
|
|
218
|
-
}), /* @__PURE__ */
|
|
221
|
+
children: D("members.inviteAcceptance.emailLabel", "Email Address")
|
|
222
|
+
}), /* @__PURE__ */ x("dd", {
|
|
219
223
|
className: "mt-1 break-all text-[var(--color-text-primary)]",
|
|
220
|
-
children:
|
|
224
|
+
children: P.email
|
|
221
225
|
})] }),
|
|
222
|
-
/* @__PURE__ */
|
|
226
|
+
/* @__PURE__ */ S("div", {
|
|
223
227
|
className: "flex flex-wrap items-center gap-2",
|
|
224
|
-
children: [/* @__PURE__ */
|
|
228
|
+
children: [/* @__PURE__ */ x("dt", {
|
|
225
229
|
className: "text-sm font-medium text-[var(--color-text-muted)]",
|
|
226
|
-
children:
|
|
227
|
-
}), /* @__PURE__ */
|
|
230
|
+
children: D("members.inviteAcceptance.roleLabel", "Role")
|
|
231
|
+
}), /* @__PURE__ */ x("dd", { children: /* @__PURE__ */ x(_, {
|
|
228
232
|
variant: "secondary",
|
|
229
|
-
children:
|
|
233
|
+
children: P.role
|
|
230
234
|
}) })]
|
|
231
235
|
}),
|
|
232
|
-
|
|
236
|
+
X ? /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("dt", {
|
|
233
237
|
className: "text-sm font-medium text-[var(--color-text-muted)]",
|
|
234
|
-
children:
|
|
235
|
-
}), /* @__PURE__ */
|
|
238
|
+
children: D("members.inviteAcceptance.expiresLabel", "Expires")
|
|
239
|
+
}), /* @__PURE__ */ S("dd", {
|
|
236
240
|
className: "mt-1 flex items-center gap-2 text-[var(--color-text-primary)]",
|
|
237
|
-
children: [/* @__PURE__ */
|
|
241
|
+
children: [/* @__PURE__ */ x(f, {
|
|
238
242
|
size: 16,
|
|
239
243
|
className: "text-[var(--color-text-muted)]"
|
|
240
|
-
}),
|
|
244
|
+
}), X]
|
|
241
245
|
})] }) : null,
|
|
242
|
-
|
|
246
|
+
P.message ? /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("dt", {
|
|
243
247
|
className: "text-sm font-medium text-[var(--color-text-muted)]",
|
|
244
|
-
children:
|
|
245
|
-
}), /* @__PURE__ */
|
|
248
|
+
children: D("members.inviteAcceptance.messageLabel", "Message")
|
|
249
|
+
}), /* @__PURE__ */ x("dd", {
|
|
246
250
|
className: "mt-1 text-[var(--color-text-secondary)]",
|
|
247
|
-
children:
|
|
251
|
+
children: P.message
|
|
248
252
|
})] }) : null
|
|
249
253
|
]
|
|
250
254
|
}),
|
|
251
|
-
|
|
255
|
+
H ? /* @__PURE__ */ S("div", {
|
|
252
256
|
className: "mt-4 flex items-center gap-2 rounded-lg border border-[var(--color-status-error-border)] bg-[var(--color-status-error-bgSubtle)] p-3",
|
|
253
|
-
children: [/* @__PURE__ */
|
|
257
|
+
children: [/* @__PURE__ */ x(c, {
|
|
254
258
|
size: 16,
|
|
255
259
|
className: "shrink-0 text-[var(--color-status-error-text)]"
|
|
256
|
-
}), /* @__PURE__ */
|
|
260
|
+
}), /* @__PURE__ */ x("p", {
|
|
257
261
|
className: "text-sm text-[var(--color-status-error-text)]",
|
|
258
|
-
children:
|
|
262
|
+
children: H
|
|
259
263
|
})]
|
|
260
264
|
}) : null,
|
|
261
|
-
/* @__PURE__ */
|
|
265
|
+
/* @__PURE__ */ S("div", {
|
|
262
266
|
className: "mt-6 flex flex-col gap-3 border-t border-[var(--color-border-seam)] pt-6 sm:flex-row",
|
|
263
|
-
children: [/* @__PURE__ */
|
|
267
|
+
children: [/* @__PURE__ */ S("button", {
|
|
264
268
|
type: "button",
|
|
265
|
-
onClick: () => void
|
|
266
|
-
disabled:
|
|
269
|
+
onClick: () => void G(),
|
|
270
|
+
disabled: Z,
|
|
267
271
|
className: "inline-flex flex-1 items-center justify-center gap-2 rounded-lg bg-[var(--color-status-success-bg)] px-6 py-3 font-medium text-[var(--color-text-inverse)] transition-all duration-200 hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-50",
|
|
268
|
-
children: [
|
|
272
|
+
children: [B === "accept" ? /* @__PURE__ */ x(m, {
|
|
269
273
|
size: 16,
|
|
270
274
|
className: "animate-spin"
|
|
271
|
-
}) : /* @__PURE__ */
|
|
272
|
-
}), /* @__PURE__ */
|
|
275
|
+
}) : /* @__PURE__ */ x(d, { size: 16 }), D("members.inviteAcceptance.acceptButton", "Accept Invitation")]
|
|
276
|
+
}), /* @__PURE__ */ S("button", {
|
|
273
277
|
type: "button",
|
|
274
|
-
onClick: () => void
|
|
275
|
-
disabled:
|
|
278
|
+
onClick: () => void K(),
|
|
279
|
+
disabled: Z,
|
|
276
280
|
className: "inline-flex flex-1 items-center justify-center gap-2 rounded-lg border border-[var(--color-border-default)] bg-transparent px-6 py-3 font-medium text-[var(--color-text-primary)] transition-all duration-200 hover:border-[var(--color-status-error-border)] hover:bg-[var(--color-status-error-bgSubtle)] hover:text-[var(--color-status-error-text)] disabled:cursor-not-allowed disabled:opacity-50",
|
|
277
|
-
children: [
|
|
281
|
+
children: [B === "reject" ? /* @__PURE__ */ x(m, {
|
|
278
282
|
size: 16,
|
|
279
283
|
className: "animate-spin"
|
|
280
|
-
}) : /* @__PURE__ */
|
|
284
|
+
}) : /* @__PURE__ */ x(g, { size: 16 }), D("members.inviteAcceptance.declineButton", "Decline")]
|
|
281
285
|
})]
|
|
282
286
|
})
|
|
283
287
|
]
|
|
284
288
|
}) });
|
|
285
289
|
}
|
|
286
290
|
//#endregion
|
|
287
|
-
export {
|
|
291
|
+
export { D as OrganizationInviteAcceptancePage };
|
|
288
292
|
|
|
289
293
|
//# sourceMappingURL=OrganizationInviteAcceptancePage.js.map
|