diff --git a/src/actions/inviteMembers.ts b/src/actions/inviteMembers.ts index 2856a9c0d..db484c5d2 100644 --- a/src/actions/inviteMembers.ts +++ b/src/actions/inviteMembers.ts @@ -88,3 +88,84 @@ export const fetchOrganizations = async () => { }; } }; + +export const acceptInvite = async (inviteLink: string) => { + const apiUrl = await getApiUrl(); + const session = await auth(); + + // Extract the token from the invite link + const token = inviteLink.split("?")[1]; // Assuming the token is the only query parameter + + if (!token) { + return { + error: "Invalid invite link. No token found.", + }; + } + + try { + const response = await axios.post( + `${apiUrl}/api/v1/organisations/invites/accept`, + { + invite_token_guid: token, + }, + { + headers: { + Authorization: `Bearer ${session?.access_token}`, + }, + }, + ); + + // Handle the response as needed + return { + data: response.data, + status: response.status, + }; + } catch (error) { + return axios.isAxiosError(error) && error.response + ? { + error: error.response.data.message || "Failed to accept invite.", + status: error.response.status, + } + : { + error: "An unexpected error occurred.", + }; + } +}; + +export const generateInviteLink = async ( + org_id: string, + invite_token: string, +) => { + const apiUrl = await getApiUrl(); + const session = await auth(); + + try { + const response = await axios.get( + `${apiUrl}/api/v1/organisations/${org_id}/invites`, + { + params: { invite_token }, + headers: { + Authorization: `Bearer ${session?.access_token}`, + }, + }, + ); + + // Extract the invite link from the nested data object + const inviteLink = response.data.data.invite_link; + + return { + data: inviteLink, + status: response.status, + }; + } catch (error) { + return axios.isAxiosError(error) && error.response + ? { + error: + error.response.data.message || "Failed to generate invite link.", + status: error.response.status, + } + : { + error: "An unexpected error occurred.", + }; + } +}; diff --git a/src/components/common/modals/invite-member/index.tsx b/src/components/common/modals/invite-member/index.tsx index eddb553db..f79ca57b9 100644 --- a/src/components/common/modals/invite-member/index.tsx +++ b/src/components/common/modals/invite-member/index.tsx @@ -1,10 +1,13 @@ "use client"; -import axios from "axios"; import { Link2Icon } from "lucide-react"; import { useCallback, useState } from "react"; -import { fetchOrganizations, inviteMembers } from "~/actions/inviteMembers"; +import { + fetchOrganizations, + generateInviteLink, + inviteMembers, +} from "~/actions/inviteMembers"; import CustomButton from "~/components/common/common-button/common-button"; import { Dialog, @@ -76,7 +79,7 @@ const InviteMemberModal: React.FC = ({ show, onClose }) => { } else { toast({ title: "Success", - description: "Your invite has been sent successfully to members email", + description: "Your invite has been sent successfully to members' email", variant: "default", }); setEmails(""); @@ -84,20 +87,47 @@ const InviteMemberModal: React.FC = ({ show, onClose }) => { } }; + const clearError = () => setTimeout(() => setError(""), 3000); const handleInviteWithLink = async () => { - try { - const response = await axios.post("/api/v1/invite/create"); - if (response.status === 200) { - setInviteLink(response.data.invite_link); - setLinkGenerated(true); - navigator.clipboard.writeText(response.data.invite_link); - toast({ - title: "Invite Link", - description: "Invite link copied to clipboard!", - }); + if (!organization) { + setError("Please select an organization first."); + clearError(); + return; + } + + const inviteResponse = await inviteMembers(emails, organization); + if (inviteResponse?.error) { + setError(inviteResponse.error); + clearError(); + return; + } + + const { data: inviteLinkData, error: inviteLinkError } = + await generateInviteLink(organization, inviteResponse.data.invite_token); + + if (inviteLinkError) { + setError(inviteLinkError); + clearError(); + } else { + setInviteLink(inviteLinkData); // Correctly store the invite link + setLinkGenerated(true); + + try { + // Ensure the document is focused before attempting to write to the clipboard + if (document.hasFocus()) { + await navigator.clipboard.writeText(inviteLinkData); + toast({ + title: "Invite Link", + description: "Invite link copied to clipboard!", + }); + } else { + setError("Failed to copy invite link. Please manually copy it."); + clearError(); + } + } catch { + setError("Failed to copy invite link to clipboard."); + clearError(); } - } catch { - setError("Failed to generate invite link."); } }; @@ -165,10 +195,11 @@ const InviteMemberModal: React.FC = ({ show, onClose }) => { {linkGenerated && ( -
+
Invite link: {inviteLink}
)} + {error &&
{error}
}