From 890bd12e995cbdd76df6e41335ccf3b79d3a8089 Mon Sep 17 00:00:00 2001 From: Pablo Lara Date: Wed, 13 Nov 2024 18:52:06 +0100 Subject: [PATCH] feat: workflow to invite an user is working --- actions/invitations/invitation.ts | 24 ++++ .../(send-invite)/check-details/page.tsx | 44 ++++++- components/invitations/index.ts | 1 + components/invitations/invitation-details.tsx | 112 ++++++++++++++++++ .../workflow/forms/send-invitation-form.tsx | 4 +- components/invitations/workflow/index.ts | 1 + .../workflow/skeleton-invitation-info.tsx | 65 ++++++++++ types/components.ts | 24 ++++ 8 files changed, 271 insertions(+), 4 deletions(-) create mode 100644 components/invitations/invitation-details.tsx create mode 100644 components/invitations/workflow/skeleton-invitation-info.tsx diff --git a/actions/invitations/invitation.ts b/actions/invitations/invitation.ts index 7fe129c92f..1a11900422 100644 --- a/actions/invitations/invitation.ts +++ b/actions/invitations/invitation.ts @@ -2,6 +2,7 @@ import { auth } from "@/auth.config"; import { getErrorMessage, parseStringify } from "@/lib"; + export const sendInvite = async (formData: FormData) => { const session = await auth(); const keyServer = process.env.API_BASE_URL; @@ -38,3 +39,26 @@ export const sendInvite = async (formData: FormData) => { }; } }; + +export const getInvitationInfoById = async (invitationId: string) => { + const session = await auth(); + const keyServer = process.env.API_BASE_URL; + const url = new URL(`${keyServer}/tenants/invitations/${invitationId}`); + + try { + const response = await fetch(url.toString(), { + method: "GET", + headers: { + Accept: "application/vnd.api+json", + Authorization: `Bearer ${session?.accessToken}`, + }, + }); + + const data = await response.json(); + return parseStringify(data); + } catch (error) { + return { + error: getErrorMessage(error), + }; + } +}; diff --git a/app/(prowler)/invitations/(send-invite)/check-details/page.tsx b/app/(prowler)/invitations/(send-invite)/check-details/page.tsx index 824d642093..939667cdc1 100644 --- a/app/(prowler)/invitations/(send-invite)/check-details/page.tsx +++ b/app/(prowler)/invitations/(send-invite)/check-details/page.tsx @@ -1,3 +1,43 @@ -export default function CheckDetailsPage() { - return
CheckDetailsPage
; +import { Suspense } from "react"; + +import { getInvitationInfoById } from "@/actions/invitations/invitation"; +import { InvitationDetails } from "@/components/invitations"; +import { SkeletonInvitationInfo } from "@/components/invitations/workflow"; +import { SearchParamsProps } from "@/types"; + +export default async function CheckDetailsPage({ + searchParams, +}: { + searchParams: SearchParamsProps; +}) { + const searchParamsKey = JSON.stringify(searchParams || {}); + + return ( + }> + + + ); } + +const SSRDataInvitation = async ({ + searchParams, +}: { + searchParams: SearchParamsProps; +}) => { + const invitationId = searchParams.id; + + if (!invitationId) { + return
Invalid invitation ID
; + } + + const invitationData = (await getInvitationInfoById(invitationId as string)) + .data; + + if (!invitationData) { + return
Invitation not found
; + } + + const { attributes, links } = invitationData; + + return ; +}; diff --git a/components/invitations/index.ts b/components/invitations/index.ts index 7eabbf93fe..e381a114df 100644 --- a/components/invitations/index.ts +++ b/components/invitations/index.ts @@ -1 +1,2 @@ +export * from "./invitation-details"; export * from "./send-invitation-button"; diff --git a/components/invitations/invitation-details.tsx b/components/invitations/invitation-details.tsx new file mode 100644 index 0000000000..12c6209920 --- /dev/null +++ b/components/invitations/invitation-details.tsx @@ -0,0 +1,112 @@ +"use client"; + +import { Card, CardBody, Divider, Snippet } from "@nextui-org/react"; + +import { AddIcon } from "../icons"; +import { CustomButton } from "../ui/custom"; +import { DateWithTime } from "../ui/entities"; + +interface InvitationDetailsProps { + attributes: { + email: string; + state: string; + token: string; + expires_at: string; + inserted_at: string; + updated_at: string; + }; + relationships?: { + inviter: { + data: { + id: string; + }; + }; + }; + selfLink: string; +} + +export const InvitationDetails = ({ + attributes, + selfLink, +}: InvitationDetailsProps) => { + return ( +
+ + +

+ Invitation Details +

+ + +
+
+ Email: + {attributes.email} +
+ +
+ State: + {attributes.state} +
+ +
+ Token: + {attributes.token} +
+ +
+ Expires At: + +
+ +
+ Inserted At: + +
+ +
+ Updated At: + +
+
+ + +

+ Share this link with the user: +

+ +
+ +

+ {selfLink} +

+
+
+
+
+
+ } + > + Back to Invitations + +
+
+ ); +}; diff --git a/components/invitations/workflow/forms/send-invitation-form.tsx b/components/invitations/workflow/forms/send-invitation-form.tsx index 39dd42803b..a75c6a60c6 100644 --- a/components/invitations/workflow/forms/send-invitation-form.tsx +++ b/components/invitations/workflow/forms/send-invitation-form.tsx @@ -57,8 +57,8 @@ export const SendInvitationForm = () => { } }); } else { - const token = data?.data?.attributes.token || ""; - router.push(`invitations/check-details/?invitation_token=${token}`); + const invitationId = data?.data?.id || ""; + router.push(`/invitations/check-details/?id=${invitationId}`); } } catch (error) { toast({ diff --git a/components/invitations/workflow/index.ts b/components/invitations/workflow/index.ts index 41589b2616..a9a860f213 100644 --- a/components/invitations/workflow/index.ts +++ b/components/invitations/workflow/index.ts @@ -1,2 +1,3 @@ +export * from "./skeleton-invitation-info"; export * from "./vertical-steps"; export * from "./workflow-send-invite"; diff --git a/components/invitations/workflow/skeleton-invitation-info.tsx b/components/invitations/workflow/skeleton-invitation-info.tsx new file mode 100644 index 0000000000..12abeb9da7 --- /dev/null +++ b/components/invitations/workflow/skeleton-invitation-info.tsx @@ -0,0 +1,65 @@ +import { Card, Skeleton } from "@nextui-org/react"; +import React from "react"; + +export const SkeletonInvitationInfo = () => { + return ( + + {/* Table headers */} +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ + {/* Table body */} +
+ {[...Array(3)].map((_, index) => ( +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+ ))} +
+
+ ); +}; diff --git a/types/components.ts b/types/components.ts index d753bac9d9..2299d0bffe 100644 --- a/types/components.ts +++ b/types/components.ts @@ -101,6 +101,30 @@ export interface ApiError { code: string; } +export interface InvitationProps { + type: "Invitation"; + id: string; + attributes: { + inserted_at: string; + updated_at: string; + email: string; + state: string; + token: string; + expires_at: string; + }; + relationships: { + inviter: { + data: { + type: "User"; + id: string; + }; + }; + }; + links: { + self: string; + }; +} + export interface UserProps { type: "User"; id: string;