Skip to content

Commit

Permalink
Merge pull request #380 from boostcampwm-2024/bug-fe-#379
Browse files Browse the repository at this point in the history
워크스페이스 초대, protected route 수정
  • Loading branch information
yewonJin authored Dec 3, 2024
2 parents 8481d67 + 4783d27 commit 231a0f7
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 50 deletions.
47 changes: 26 additions & 21 deletions apps/frontend/src/app/routes/join/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect } from "react";
import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useEffect, useState } from "react";
import { createFileRoute } from "@tanstack/react-router";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";

import { useValidateWorkspaceInviteLink } from "@/features/workspace";
Expand All @@ -16,53 +16,58 @@ function JoinWrapper() {

export const Route = createFileRoute("/join/")({
validateSearch: (search: Record<string, unknown>) => {
const workspaceId = search.workspaceId as string;
const token = search.token as string;

if (!workspaceId || !token) {
if (!search.workspaceId || !search.token) {
window.location.href = "/";
throw new Error("유효한 링크가 아닙니다.");
}

return { workspaceId, token };
return {
workspaceId: search.workspaceId as string,
token: search.token as string,
};
},
component: JoinWrapper,
});

function JoinComponent() {
const { workspaceId, token } = Route.useSearch();
const navigate = useNavigate();
const rawWorkspaceId = new URLSearchParams(window.location.search).get(
"workspaceId",
);
const { token } = Route.useSearch();
const { mutate: validateInvite, isPending } =
useValidateWorkspaceInviteLink();
const [validated, setValidated] = useState(false);

useEffect(() => {
if (!token || !workspaceId) {
navigate({ to: "/" });
if (!token || !rawWorkspaceId) {
window.location.href = "/";
return;
}

validateInvite(token, {
validateInvite(String(token), {
onSuccess: () => {
navigate({
to: "/workspace/$workspaceId",
params: { workspaceId },
replace: true,
});
setValidated(true);
},
onError: () => {
navigate({ to: "/" });
window.location.href = "/";
},
});
}, [token, workspaceId, validateInvite, navigate]);
}, [token, rawWorkspaceId, validateInvite]);

if (validated && rawWorkspaceId) {
window.location.href = `/workspace/${rawWorkspaceId}`;
return null;
}

return (
<div className="flex h-screen items-center justify-center">
<div className="text-center">
<div className="mb-2 text-lg font-medium">
워크스페이스 초대 확인 중
</div>
{isPending && (
{isPending && rawWorkspaceId && (
<div className="text-sm text-gray-500">
워크스페이스 {workspaceId} 입장 중...
워크스페이스 {rawWorkspaceId} 입장 중...
</div>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import { useEffect } from "react";
import { useNavigate } from "@tanstack/react-router";
import { useCurrentWorkspace } from "@/features/workspace/model/workspaceQuries";
import { useGetUser } from "@/features/auth";

export const useProtectedWorkspace = () => {
const navigate = useNavigate();
const { data: workspaceData, isLoading, error } = useCurrentWorkspace();
const { isLoading: isUserLoading } = useGetUser();
const {
data: workspaceData,
isLoading: isWorkspaceLoading,
error,
} = useCurrentWorkspace();

useEffect(() => {
if (!isLoading && (error || !workspaceData)) {
if (!isUserLoading && !isWorkspaceLoading && (error || !workspaceData)) {
navigate({ to: "/" });
}
}, [isLoading, workspaceData, error, navigate]);
}, [isUserLoading, isWorkspaceLoading, workspaceData, error, navigate]);

return {
isLoading,
isLoading: isUserLoading || isWorkspaceLoading,
workspaceData,
};
};
17 changes: 2 additions & 15 deletions apps/frontend/src/features/workspace/ui/ShareTool/ShareButton.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,9 @@
// TODO: admin이 아니라면 tooltip 추가 "권한이 없습니다."

import { useWorkspace } from "@/shared/lib";
import { useUserWorkspace } from "../../model/workspaceQuries";

export function Sharebutton() {
const currentWorkspaceId = useWorkspace();
const { data } = useUserWorkspace();
const workspaces = data?.workspaces;
const workspace = workspaces?.find(
(workspace) => workspace.workspaceId === currentWorkspaceId,
);
const isGuest = workspace?.role === "guest";

return (
<div className="flex h-9 items-center justify-center">
<button
disabled={isGuest}
className="rounded-md bg-blue-400 px-2 py-1 text-sm text-white hover:bg-blue-500"
type="button"
className="rounded-md bg-blue-400 px-2 py-1 text-sm text-white hover:bg-blue-500 disabled:cursor-not-allowed disabled:opacity-50"
>
공유
</button>
Expand Down
23 changes: 13 additions & 10 deletions apps/frontend/src/features/workspace/ui/ShareTool/SharePanel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useState } from "react";
import { Globe2, Lock, Copy, CheckCheck } from "lucide-react";

import { useCreateWorkspaceInviteLink } from "../../model/workspaceMutations";
import { useCurrentWorkspace } from "../../model/workspaceQuries";
import { useToggleWorkspaceStatus } from "../../model/workspaceMutations";
Expand Down Expand Up @@ -36,7 +35,6 @@ export function SharePanel() {

const isPublic =
workspaceId === "main" ? true : workspaceVisibility === "public";

const isGuest =
workspaceId === "main" || currentWorkspace?.workspace?.role === "guest";

Expand All @@ -49,21 +47,26 @@ export function SharePanel() {
}
};

const getCurrentUrl = () => {
const getDisplayUrl = () => {
if (isUserLoading || isWorkspaceLoading)
return "워크스페이스를 불러오는 중...";
if (isPending) return "처리 중...";
if (isGuest) return "권한이 없습니다";
if (isPublic) return PUBLIC_URL;
if (createInviteLinkMutation.data) {
return createFrontendUrl(createInviteLinkMutation.data, workspaceId);
}
return "권한이 없습니다";
return `${window.location.origin}/join/***********`;
};

const handleCopy = async () => {
const urlToCopy = getCurrentUrl();
if (!isPending && !isWorkspaceLoading) {
await navigator.clipboard.writeText(urlToCopy);
const urlToCopy = isPublic
? PUBLIC_URL
: createInviteLinkMutation.data
? createFrontendUrl(createInviteLinkMutation.data, workspaceId)
: await createInviteLinkMutation.mutateAsync(workspaceId);

await navigator.clipboard.writeText(
isPublic ? urlToCopy : createFrontendUrl(urlToCopy, workspaceId),
);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
}
Expand Down Expand Up @@ -96,7 +99,7 @@ export function SharePanel() {
}`}
>
<div className="w-48 flex-1 truncate rounded-md bg-gray-100 px-3 py-2 text-sm text-gray-600">
{getCurrentUrl()}
{getDisplayUrl()}
</div>
<button
onClick={handleCopy}
Expand Down

0 comments on commit 231a0f7

Please sign in to comment.