From 4783d277bbf89cf7548577e53733cc5f1e087a9f Mon Sep 17 00:00:00 2001 From: djk01281 Date: Tue, 3 Dec 2024 16:07:57 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=9B=8C=ED=81=AC=EC=8A=A4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=20=EC=B4=88=EB=8C=80,=20protected=20route=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/frontend/src/app/routes/join/index.tsx | 47 ++++++++++--------- .../workspace/model/useProtectedWorkspace.ts | 14 ++++-- .../workspace/ui/ShareTool/ShareButton.tsx | 17 +------ .../workspace/ui/ShareTool/SharePanel.tsx | 23 +++++---- .../workspace/ui/WorkspaceList/index.tsx | 10 ++-- 5 files changed, 56 insertions(+), 55 deletions(-) diff --git a/apps/frontend/src/app/routes/join/index.tsx b/apps/frontend/src/app/routes/join/index.tsx index 4552382d..11fe3a8a 100644 --- a/apps/frontend/src/app/routes/join/index.tsx +++ b/apps/frontend/src/app/routes/join/index.tsx @@ -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"; @@ -16,43 +16,48 @@ function JoinWrapper() { export const Route = createFileRoute("/join/")({ validateSearch: (search: Record) => { - 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 (
@@ -60,9 +65,9 @@ function JoinComponent() {
워크스페이스 초대 확인 중
- {isPending && ( + {isPending && rawWorkspaceId && (
- 워크스페이스 {workspaceId} 입장 중... + 워크스페이스 {rawWorkspaceId} 입장 중...
)}
diff --git a/apps/frontend/src/features/workspace/model/useProtectedWorkspace.ts b/apps/frontend/src/features/workspace/model/useProtectedWorkspace.ts index a5184efd..7387d00a 100644 --- a/apps/frontend/src/features/workspace/model/useProtectedWorkspace.ts +++ b/apps/frontend/src/features/workspace/model/useProtectedWorkspace.ts @@ -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, }; }; diff --git a/apps/frontend/src/features/workspace/ui/ShareTool/ShareButton.tsx b/apps/frontend/src/features/workspace/ui/ShareTool/ShareButton.tsx index 4e54f944..8eee484b 100644 --- a/apps/frontend/src/features/workspace/ui/ShareTool/ShareButton.tsx +++ b/apps/frontend/src/features/workspace/ui/ShareTool/ShareButton.tsx @@ -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 (
diff --git a/apps/frontend/src/features/workspace/ui/ShareTool/SharePanel.tsx b/apps/frontend/src/features/workspace/ui/ShareTool/SharePanel.tsx index daa4adb6..07de6fd2 100644 --- a/apps/frontend/src/features/workspace/ui/ShareTool/SharePanel.tsx +++ b/apps/frontend/src/features/workspace/ui/ShareTool/SharePanel.tsx @@ -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"; @@ -36,7 +35,6 @@ export function SharePanel() { const isPublic = workspaceId === "main" ? true : workspaceVisibility === "public"; - const isGuest = workspaceId === "main" || currentWorkspace?.workspace?.role === "guest"; @@ -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); } @@ -96,7 +99,7 @@ export function SharePanel() { }`} >
- {getCurrentUrl()} + {getDisplayUrl()}
);