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] 초대페이지 기능및디자인 QA #473

Closed
wants to merge 15 commits into from

Conversation

Bowoon1216
Copy link
Contributor

@Bowoon1216 Bowoon1216 commented Feb 18, 2025

해당 이슈 번호

closed #463


체크리스트

  • 🔀 PR 제목의 형식을 잘 작성했나요? e.g. [feat] PR을 등록한다.
  • 💯 테스트는 잘 통과했나요?
  • 🏗️ 빌드는 성공했나요?
  • 🧹 불필요한 코드는 제거했나요?
  • ✅ 컨벤션을 지켰나요?
  • 💭 이슈는 등록했나요?
  • 🏷️ 라벨은 등록했나요?
  • 💻 git rebase를 사용했나요?
  • 🙇‍♂️ 리뷰어를 지정했나요?

📌 내가 알게 된 부분

  • useNavigate vs window.location.replace
    navigate는 진짜 경로만 옮겨주는데요 window.location.replace는 새로고침까지 해줘요!
    그래서 바뀐 것들이 반영이 아주 잘된답니다 😄

💎 PR Point

  1. 대시보드의 height가 늘어나지 않아서 못생긴 이슈가 있었습니다.
  • 이것을 cal(100vh - 어쩌구)로 반응형으로 해결할 수 있었습니다.
  1. 팀이 있는 유저가 로그인했을때 토큰만있고 TEAM_ID가 없는 경우에 onboarding으로 이동하는 이슈가 있었습니다. (즉, snb에는 팀이 있는데 대시보드 페이지가 아닌 온보딩페이지로 가는 현상!)
  • 이것을 Onboarding 페이지에서 내가 속한 팀을 가져오고 useEffect를 이용해 팀이 존재하면 로컬스토리지에 TEAM_ID등을 set하고 대시보드로 이동시켜 해결했습니다.
const { data } = $api.useQuery('get', '/api/v1/members/teams');
 const firstTeam = data?.data?.belongTeamGetResponses[0];
useEffect(() => {
    if (firstTeam) {
      localStorage.setItem(STORAGE_KEY.TEAM_ID, String(firstTeam.id));
      localStorage.setItem(STORAGE_KEY.TEAM_NAME, firstTeam.name);
      navigate(PATH.DASHBOARD);
    }
  1. 로그인 하지 않은 상태로 초대를 받을 때, 로그인페이지로 인터셉트 당하여 아래 페이지가 나오지 않는 이슈가 있었습니다.
image
  • 이는 middleware.ts에서 토큰여부확인하는 로직을 수정했습니다.
  • 원래는 accessToken만 없으면 바로 로그인페이지로 이동하게 되어있었는데,
  • 초대를 받으면 로컬스토리지에 INVITATION_ID를 저장하고 그것을 이용해 로컬스토리지에 초대 아이디가 있는지 까지 확인 한 후에 토큰과 초대아이디 모두 없을때 로그인페이지로 이동합니다.
if (!accessToken && !localStorage.getItem(STORAGE_KEY.INVITATION_ID)) {
      window.location.replace(PATH.LOGIN);
      throw new Error('토큰이 존재하지 않습니다.');
    }
  • (로컬스토리지의 초대아이디는 초대와 관련된 로직이 끝나면 삭제됩니다)

📌스크린샷 (선택)

Copy link

🚀 Storybook 확인하기 🚀

Copy link
Member

@namdaeun namdaeun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다 !! ㅎㅎ
질문 몇 개만 확인해주세융

navigate(PATH.ONBOARDING);
},
}
);
deleteLocalStorageInviteInfo();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clearInvitation은 어떵가요 ??

localStorage.setItem(STORAGE_KEY.TEAM_NAME, firstTeam.name);
navigate(PATH.DASHBOARD);
}
}, [firstTeam, navigate]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

navigate도 의존성 배열에 필요한가유 ??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

navigate를 빼면 의존성으로 eslint가 잡더라구요 !

@@ -48,14 +49,14 @@ const WorkspaceDelete = ({ position }: WorkspaceDeleteProps) => {

closeModal();

localStorage.removeItem('teamId');
localStorage.removeItem(STORAGE_KEY.TEAM_ID);
localStorage.removeItem(STORAGE_KEY.TEAM_NAME);

navigate(PATH.DASHBOARD);
window.location.reload();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요거 reload 없이는 이상하게 동작할까요 ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그러게요 대쉬보드로만 돌아가면 되지 않나용?

Copy link
Contributor Author

@Bowoon1216 Bowoon1216 Feb 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

없어도 정상동작해서 삭제했숩니다!!

Copy link
Contributor

@rtttr1 rtttr1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다~~!! 코멘트 몇개 남겼으니 확인해주세요!

@@ -54,17 +54,18 @@ const InvitedPage = () => {
},
{
onSuccess: () => {
deleteLocalStorageInviteInfo();
createToast('초대 승인에 성공하셨습니다.', 'success');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상수화 하면 좋을거같아요!

navigate(PATH.DASHBOARD);
},
onError: (error: components['schemas']['ErrorResponse']) => {
deleteLocalStorageInviteInfo();
createToast(error.message, 'error');
createToast(`초대 승인에 실패하셨습니다: ${error.message}`, 'error');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도~

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요거 error 타입 뮤에이트 함수에서 axios 사용하고 있다면 axiosError 타입일 것 같은데 ?? 아닌가유

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞네요!
서버에서 에러 분기처리가 되지 않아서 error를 받을 필요없이 상수화된 에러메시지 띄워줬습니다~!

localStorage.setItem(STORAGE_KEY.TEAM_NAME, firstTeam.name);
navigate(PATH.DASHBOARD);
}
}, [firstTeam, navigate]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이미 비동기 로직을 처리하는 리액트 쿼리를 사용하여 데이터를 받아왔고, 데이터 값에 따라서 navigate를 해주는 것이니 굳이 useEffect를 안쓰고 아래와 같이 if문으로만 처리해도 동작할것 같은데 어떻게 생각하시나요!

  const { data, isSuccess } = $api.useQuery('get', '/api/v1/members/teams');

  const firstTeam = data?.data?.belongTeamGetResponses[0];

  if (isSuccess && firstTeam) {
    localStorage.setItem(STORAGE_KEY.TEAM_ID, String(firstTeam.id));
    localStorage.setItem(STORAGE_KEY.TEAM_NAME, firstTeam.name);
    navigate(PATH.DASHBOARD);
  }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 ! 될거같다 !

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오! 됩니다!!!!! 좋은의견 감사합니다 👍

@@ -48,14 +49,14 @@ const WorkspaceDelete = ({ position }: WorkspaceDeleteProps) => {

closeModal();

localStorage.removeItem('teamId');
localStorage.removeItem(STORAGE_KEY.TEAM_ID);
localStorage.removeItem(STORAGE_KEY.TEAM_NAME);

navigate(PATH.DASHBOARD);
window.location.reload();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그러게요 대쉬보드로만 돌아가면 되지 않나용?

@@ -55,9 +55,9 @@ const InvitedPage = () => {
{
onSuccess: () => {
createToast('초대 승인에 성공하셨습니다.', 'success');
window.location.replace(PATH.DASHBOARD);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 값이 변한게 안반영되어서 window.location을 navigate 대신에 사용한거라면 invalidquries를 사용해서 값을 리패치해주는건 어떨까요?

Copy link
Member

@wuzoo wuzoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셧슴다 !!~

navigate(PATH.DASHBOARD);
},
onError: (error: components['schemas']['ErrorResponse']) => {
deleteLocalStorageInviteInfo();
createToast(error.message, 'error');
createToast(`초대 승인에 실패하셨습니다: ${error.message}`, 'error');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요거 error 타입 뮤에이트 함수에서 axios 사용하고 있다면 axiosError 타입일 것 같은데 ?? 아닌가유

localStorage.setItem(STORAGE_KEY.TEAM_NAME, firstTeam.name);
navigate(PATH.DASHBOARD);
}
}, [firstTeam, navigate]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 ! 될거같다 !

@@ -19,7 +19,7 @@ export const authMiddleware: Middleware = {
async onRequest({ request }) {
const accessToken = localStorage.getItem(STORAGE_KEY.ACCESS_TOKEN_KEY);

if (!accessToken) {
if (!accessToken && !localStorage.getItem(STORAGE_KEY.INVITATION_ID)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요거 왜 ?? 추가하신건지 설명해주세용 ..

아 그리고 둘 다 isNil 사용해주세용 !

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

액세스 토큰이 없을때 초대를 받으면 로그인 화면으로 이동되더라구요.
그래서 액세스 토큰이 없어도 초대 아이디가 있다면 로그인페이지로 이동하지 않도록 막은 것입니다!
액세스 토큰과 초대 아이디가 모두 없을 때 로그인 페이지로 이동하게끔했습니다.

Copy link

🚀 Storybook 확인하기 🚀

@Bowoon1216 Bowoon1216 force-pushed the feature/invite/#463-QA branch 2 times, most recently from eda08a0 to 31202cc Compare February 20, 2025 14:46
@Bowoon1216 Bowoon1216 force-pushed the feature/invite/#463-QA branch from b6055f2 to 8e7a5c5 Compare February 20, 2025 16:07
@Bowoon1216 Bowoon1216 closed this Feb 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

초대 페이지 Design QA
4 participants