bugfix: invitation link copy option disapearing fixed. route problem for unauthorizrd users opening invitation link fixed.
This commit is contained in:
107
frontend/src/lib/hooks/useOrganizationInviteLinkCopy.ts
Normal file
107
frontend/src/lib/hooks/useOrganizationInviteLinkCopy.ts
Normal file
@@ -0,0 +1,107 @@
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import {
|
||||
organizationApi,
|
||||
type OrganizationInvitationHistoryItemDto,
|
||||
} from '@/lib/api/organization';
|
||||
import {
|
||||
canShareOrganizationInviteLink,
|
||||
readOrganizationInviteLinks,
|
||||
type StoredOrganizationInviteLink,
|
||||
writeOrganizationInviteLinks,
|
||||
} from '@/components/invitations/organizationInviteLinks';
|
||||
|
||||
export function useOrganizationInviteLinkCopy(organizationId: string | undefined) {
|
||||
const [pendingInviteLinks, setPendingInviteLinks] = useState<
|
||||
Record<string, StoredOrganizationInviteLink>
|
||||
>({});
|
||||
const [copiedId, setCopiedId] = useState<string | null>(null);
|
||||
const [copyingInvitationId, setCopyingInvitationId] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!organizationId) return;
|
||||
setPendingInviteLinks(readOrganizationInviteLinks(organizationId));
|
||||
}, [organizationId]);
|
||||
|
||||
const storeInviteLink = useCallback(
|
||||
(invitationId: string, ownerEmail: string, invitationUrl: string) => {
|
||||
if (!organizationId) return;
|
||||
setPendingInviteLinks((prev) => {
|
||||
const next = {
|
||||
...prev,
|
||||
[invitationId]: {
|
||||
invitationId,
|
||||
ownerEmail: ownerEmail.trim().toLowerCase(),
|
||||
invitationUrl,
|
||||
},
|
||||
};
|
||||
writeOrganizationInviteLinks(organizationId, next);
|
||||
return next;
|
||||
});
|
||||
},
|
||||
[organizationId],
|
||||
);
|
||||
|
||||
const pruneAcceptedLinks = useCallback(
|
||||
(items: OrganizationInvitationHistoryItemDto[]) => {
|
||||
if (!organizationId) return;
|
||||
const acceptedIds = new Set(
|
||||
items.filter((item) => item.acceptedAt || item.status === 'ACTIVE').map((item) => item.id),
|
||||
);
|
||||
|
||||
setPendingInviteLinks((prev) => {
|
||||
let changed = false;
|
||||
const next = { ...prev };
|
||||
for (const id of Object.keys(next)) {
|
||||
if (acceptedIds.has(id)) {
|
||||
delete next[id];
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
writeOrganizationInviteLinks(organizationId, next);
|
||||
}
|
||||
return changed ? next : prev;
|
||||
});
|
||||
},
|
||||
[organizationId],
|
||||
);
|
||||
|
||||
const copyInvitationLink = useCallback(
|
||||
async (
|
||||
invitation: OrganizationInvitationHistoryItemDto,
|
||||
options?: { onRegenerated?: () => void | Promise<void> },
|
||||
): Promise<string | null> => {
|
||||
if (!canShareOrganizationInviteLink(invitation)) return null;
|
||||
|
||||
setCopyingInvitationId(invitation.id);
|
||||
try {
|
||||
let invitationUrl = pendingInviteLinks[invitation.id]?.invitationUrl;
|
||||
if (!invitationUrl || invitation.status === 'EXPIRED') {
|
||||
const res = await organizationApi.getInvitationLink(invitation.id);
|
||||
invitationUrl = res.data.invitationUrl;
|
||||
storeInviteLink(invitation.id, invitation.ownerEmail, invitationUrl);
|
||||
await options?.onRegenerated?.();
|
||||
}
|
||||
|
||||
await navigator.clipboard.writeText(invitationUrl);
|
||||
setCopiedId(invitation.id);
|
||||
setTimeout(() => setCopiedId(null), 1500);
|
||||
return invitationUrl;
|
||||
} finally {
|
||||
setCopyingInvitationId(null);
|
||||
}
|
||||
},
|
||||
[pendingInviteLinks, storeInviteLink],
|
||||
);
|
||||
|
||||
return {
|
||||
pendingInviteLinks,
|
||||
copiedId,
|
||||
copyingInvitationId,
|
||||
storeInviteLink,
|
||||
copyInvitationLink,
|
||||
pruneAcceptedLinks,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user