Next.js Discord

Discord Forum

Is there cleaner implementation for this?

Answered
Rhinelander posted this in #help-forum
Open in Discord
RhinelanderOP
Trying to refactor some code. Help me improve it. Give me criticism. This is decently large project - splitting stuff in to multiple files, enterprise patterns, everything can be mentioned. I also use react-query if i could use it anywhere. Thank you!
Answered by Brown bear
export type InvitationStatus = 'pending' | 'accepted' | 'rejected';

export interface BaseInvitationData {
  id: string;
  email: string;
  inviterEmail: string;
  organizationName: string;
  createdAt: string;
  updatedAt: string;
}

export interface PendingInvitationData extends BaseInvitationData {
  status: 'pending';
}

export interface AcceptedInvitationData extends BaseInvitationData {
  status: 'accepted';
}

export interface RejectedInvitationData extends BaseInvitationData {
  status: 'rejected';
}

export type InvitationData = 
  | PendingInvitationData 
  | AcceptedInvitationData 
  | RejectedInvitationData;
View full answer

7 Replies

RhinelanderOP
Feel free to add feedback via Github or via Discord https://gist.github.com/jan-arnez/0ea1ae36125ff40bef7d0fe5711920da
Brown bear
Move the rendering logic to separate components

export default function InvitationPage() {
  const params = useParams<{ id: string }>();
  const {
    invitation,
    isLoading,
    error,
    acceptInvitation,
    rejectInvitation,
    isAccepting,
    isRejecting,
  } = useInvitation(params.id!);

  if (isLoading) return <InvitationSkeleton />;

  if (error) return <div>{error.message}</div>;

  if (!invitation) return null;

  return (
    <div className="flex min-h-[80vh] items-center justify-center">
      <Card className="w-full max-w-md">
        <CardHeader>
          <CardTitle>Organization Invitation</CardTitle>
          <CardDescription>
            You've been invited to join an organization
          </CardDescription>
        </CardHeader>
        <CardContent>
          <InvitationStatus invitation={invitation} />
        </CardContent>
        {invitation.status === "pending" && (
          <CardFooter>
            <InvitationActions
              onAccept={acceptInvitation}
              onReject={rejectInvitation}
              isAccepting={isAccepting}
              isRejecting={isRejecting}
            />
          </CardFooter>
        )}
      </Card>
    </div>
  );
} 
you can also create a custom hook with react query for handling the invitations
something like
export function useInvitation(id: string) {
  const query = useQuery({
    queryKey: ['invitation', id],
    queryFn: async () => {
      const response = await authClient.organization.getInvitation({
        query: { id },
      });
      return response.data;
    },
    onError: (error: Error) => {
      toast.error("Error", {
        description: error.message,
      });
    },
  });

  const acceptMutation = useMutation({ /* code */ });

  const rejectMutation = useMutation({ /* code */ });

  return {
    invitation: query.data,
    isLoading: query.isLoading,
    error: query.error,
    acceptInvitation: acceptMutation.mutate,
    rejectInvitation: rejectMutation.mutate,
    isAccepting: acceptMutation.isPending,
    isRejecting: rejectMutation.isPending,
  };
} 
finally, you're using typescript but you're not using types so probably a good idea to define them
Brown bear
export type InvitationStatus = 'pending' | 'accepted' | 'rejected';

export interface BaseInvitationData {
  id: string;
  email: string;
  inviterEmail: string;
  organizationName: string;
  createdAt: string;
  updatedAt: string;
}

export interface PendingInvitationData extends BaseInvitationData {
  status: 'pending';
}

export interface AcceptedInvitationData extends BaseInvitationData {
  status: 'accepted';
}

export interface RejectedInvitationData extends BaseInvitationData {
  status: 'rejected';
}

export type InvitationData = 
  | PendingInvitationData 
  | AcceptedInvitationData 
  | RejectedInvitationData;
Answer
RhinelanderOP
Wow that was in depth. I appreciate that. Thank you!