Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/hng invite members to organization #1015

17 changes: 9 additions & 8 deletions src/actions/inviteMembers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export const acceptInvite = async (inviteLink: string) => {
if (!token) {
return {
error: "Invalid invite link. No token found.",
status: 400, // Bad Request
};
}

Expand All @@ -115,7 +116,6 @@ export const acceptInvite = async (inviteLink: string) => {
},
);

// Handle the response as needed
return {
data: response.data,
status: response.status,
Expand All @@ -128,30 +128,31 @@ export const acceptInvite = async (inviteLink: string) => {
}
: {
error: "An unexpected error occurred.",
status: 500, // Internal Server Error
};
}
};

export const generateInviteLink = async (
org_id: string,
invite_token: string,
) => {
export const generateInviteLink = async (org_id: 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;
let inviteLink = response.data.data.invite_link;

// Ensure the link has a slash between the domain and the path
if (!inviteLink.includes("/invite")) {
inviteLink = inviteLink.replace("techinvite", "tech/invite");
}

return {
data: inviteLink,
Expand Down
7 changes: 7 additions & 0 deletions src/app/invite/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
"use client";

const InvitePage = () => {
return <div>Processing your invite...</div>;
};

export default InvitePage;
26 changes: 11 additions & 15 deletions src/components/common/modals/invite-member/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ const InviteMemberModal: React.FC<ModalProperties> = ({ show, onClose }) => {
}
};

// Clear error after a timeout
const clearError = () => setTimeout(() => setError(""), 3000);

// Function to handle invite submission via email
const handleSubmit = async () => {
setError("");

Expand All @@ -87,33 +91,25 @@ const InviteMemberModal: React.FC<ModalProperties> = ({ show, onClose }) => {
}
};

const clearError = () => setTimeout(() => setError(""), 3000);
const handleInviteWithLink = async () => {
// Function to generate the invite link
const generateAndCopyInviteLink = async () => {
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);
await generateInviteLink(organization);

if (inviteLinkError) {
setError(inviteLinkError);
clearError();
} else {
setInviteLink(inviteLinkData); // Correctly store the invite link
setInviteLink(inviteLinkData); // 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({
Expand Down Expand Up @@ -183,7 +179,7 @@ const InviteMemberModal: React.FC<ModalProperties> = ({ show, onClose }) => {
<Link2Icon className="pointer-events-none absolute ml-3" />
<CustomButton
variant="subtle"
onClick={handleInviteWithLink}
onClick={generateAndCopyInviteLink}
className="pl-10"
>
Invite with link
Expand All @@ -195,8 +191,8 @@ const InviteMemberModal: React.FC<ModalProperties> = ({ show, onClose }) => {
</CustomButton>
</div>
{linkGenerated && (
<div className="text-green mt-4 text-sm">
Invite link: {inviteLink}
<div className="mt-4 hidden text-sm text-[#f85318]">
<span className="">{inviteLink}</span>
</div>
)}

Expand Down
Loading