Skip to content

Commit

Permalink
비회원일 경우 특정 버튼 클릭시, 로그인 팝업 띄우기 (SWYP-team-2th#182)
Browse files Browse the repository at this point in the history
* 비회원일 경우 특정 버튼 클릭시, 로그인 팝업 띄우기

* 비회원 문구 추가

* 마감 시 UI 반영 안되는 문제 수정
  • Loading branch information
YOOJS1205 committed Mar 2, 2025
1 parent 99d6f8c commit f9f7cbf
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 17 deletions.
12 changes: 5 additions & 7 deletions src/api/usePostKaKaoLogin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useMutation } from '@tanstack/react-query';
import { useMutation, UseMutationOptions } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import { request } from '@/api/config';
import { setAccessToken } from '@/components/login/Auth/token';

interface LoginResponseType {
accessToken: string;
Expand All @@ -13,7 +12,9 @@ interface LoginRequestType {
redirectUri: string;
}

export default function usePostKakaoLogin() {
export default function usePostKakaoLogin(
options?: UseMutationOptions<LoginResponseType, Error, LoginRequestType>,
) {
const navigate = useNavigate();

return useMutation<LoginResponseType, Error, LoginRequestType>({
Expand All @@ -24,13 +25,10 @@ export default function usePostKakaoLogin() {
data,
});
},
onSuccess: (data) => {
setAccessToken(data.accessToken);
navigate(`/user/${data.userId}`);
},
onError: (err) => {
console.error('로그인 실패:', err);
navigate('/onboarding');
},
...options,
});
}
3 changes: 2 additions & 1 deletion src/components/common/Dialog/Dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useDialog } from './hooks';
import { Button } from '@/components/common/Button/Button';

interface DialogProps {
title: string;
title: React.ReactNode;
description?: string;
cancelButtonProps?: {
text: string;
Expand Down Expand Up @@ -61,6 +61,7 @@ export default function Dialog({
variant="solid"
size="large"
buttonType={confirmButtonProps.isLoading ? 'disabled' : 'primary'}
onClick={confirmButtonProps.onClick}
>
{confirmButtonProps.isLoading ? <Loading /> : confirmButtonProps.text}
</Button>
Expand Down
10 changes: 10 additions & 0 deletions src/components/common/Layout/DefaultLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { useNavigate, Outlet } from 'react-router-dom';
import useGetMyInfo from '@/api/useGetMyInfo';
import { FloatingButton } from '@/components/common/Button/FloatingButton';
import { useDialog } from '@/components/common/Dialog/hooks';
import Icon from '@/components/common/Icon';
import LoginDialog from '@/components/common/LoginDialog/LoginDialog';

export default function DefaultLayout() {
const navigate = useNavigate();
const { openDialog } = useDialog();
const { data: myInfo } = useGetMyInfo();

const handleClickFloatingButton = () => {
if (!myInfo) {
openDialog(<LoginDialog />);
return;
}

navigate('/votes/regist');
};

Expand Down
27 changes: 27 additions & 0 deletions src/components/common/LoginDialog/LoginDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Dialog from '../Dialog';
import useLoginDialog from './hooks';

export default function LoginDialog() {
const { handleLogin } = useLoginDialog();

return (
<Dialog
title={
<>
당신의 선택은?
<br />
로그인하고 투표에 참여하세요!
</>
}
description="로그인하고 나만의 투표를 만들고 공유하세요."
confirmButtonProps={{
text: '카카오로 계속하기',
onClick: () => {
console.log('hi');
handleLogin();
},
}}
showLaterButton={true}
/>
);
}
15 changes: 15 additions & 0 deletions src/components/common/LoginDialog/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { getIsDevelopment } from '@/utils/cn/getEnvironment';

export default function useLoginDialog() {
const isDevelopment = getIsDevelopment();
const pathname = window.location.pathname;

const KAKAO_AUTH_URL = `https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=${isDevelopment ? import.meta.env.VITE_KAKAO_CLIENT_ID : import.meta.env.VITE_KAKAO_PROD_CLIENT_ID}&redirect_uri=${window.location.origin}/oauth&state=${pathname}`;
const handleLogin = () => {
window.location.href = KAKAO_AUTH_URL;
};

return {
handleLogin,
};
}
Empty file.
12 changes: 12 additions & 0 deletions src/components/vote-detail/Input/CommentInput.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { SetStateAction, useRef, useState } from 'react';
import { useParams } from 'react-router-dom';
import useAddComment from '@/api/useAddComment';
import useGetMyInfo from '@/api/useGetMyInfo';
import useGetVoteDetail from '@/api/useGetVoteDetail';
import { useDialog } from '@/components/common/Dialog/hooks';
import Icon from '@/components/common/Icon';
import LoginDialog from '@/components/common/LoginDialog/LoginDialog';
import TextInput from '@/components/common/TextInput';

export default function CommentInput() {
const [content, setContent] = useState('');
const contentRef = useRef<HTMLInputElement>(null);
const { shareUrl } = useParams<{ shareUrl: string }>();
const { data: myInfo } = useGetMyInfo();
const { openDialog } = useDialog();

const { data: voteDetail } = useGetVoteDetail(shareUrl ?? '');

Expand Down Expand Up @@ -43,6 +48,12 @@ export default function CommentInput() {
}
};

const handleFocusInput = () => {
if (!myInfo) {
openDialog(<LoginDialog />);
}
};

return (
<div className="w-full px-lg py-3 bg-gray-100 bottom-0 fixed left-1/2 -translate-x-1/2 z-4 max-w-[480px]">
<TextInput
Expand All @@ -52,6 +63,7 @@ export default function CommentInput() {
value={content}
onChange={onChangeValue}
onKeyDown={handleKeyDown}
onFocus={handleFocusInput}
rightNode={
<button className="cursor-pointer" onClick={handleSendComment}>
<Icon name="Send" size="medium" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useQueryClient } from '@tanstack/react-query';
import { useParams } from 'react-router-dom';
import usePostCloseVote from '@/api/usePostCloseVote';
import { useDialog } from '@/components/common/Dialog/hooks';

Expand All @@ -10,9 +9,9 @@ interface UseCloseConfirmDialogOptions {
export default function useCloseConfirmDialog({
postId,
}: UseCloseConfirmDialogOptions) {
const { shareUrl } = useParams<{ shareUrl: string }>();
const { closeDialog } = useDialog();
const queryClient = useQueryClient();
const shareUrl = window.location.pathname.split('/').pop();
const { mutate: closeVote, isPending: isCloseVotePending } = usePostCloseVote(
{
onSuccess: () => {
Expand Down
25 changes: 19 additions & 6 deletions src/components/vote-detail/Vote/VoteResult/VoteResultList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useParams } from 'react-router-dom';
import useGetMyInfo from '@/api/useGetMyInfo';
import BlurImage from '@/assets/images/vote-detail/voteBlur.png';
import useVoteStatus from '@/components/vote-detail/Vote/VoteResult/hooks';
import VoteResultItem from '@/components/vote-detail/Vote/VoteResult/VoteResultItem';
Expand All @@ -9,6 +10,7 @@ export default function VoteResultList() {
postId: Number(shareUrl),
shareUrl: shareUrl ?? '',
});
const { data: myInfo } = useGetMyInfo();

// 유저가 해당 게시글에 투표 했는지에 대한 유무

Expand All @@ -23,11 +25,11 @@ export default function VoteResultList() {
...(voteStatus?.map((status) => status.voteCount) ?? []),
);

//

return (
<div className="px-1">
{/* 추후에 로그인 (uerId)에 따른 blur 처리 필요 */}
{/* 회원, 비회원 투표시에만 결과 보여주기 */}
{!userHasVoted ? (
{!userHasVoted && (
<div
className="flex items-center justify-center w-full h-18 text-body-1-normal "
style={{
Expand All @@ -36,7 +38,19 @@ export default function VoteResultList() {
>
<p>투표하고, 뽀또들과 함께 결과를 실시간으로 확인해보세요! 🎉</p>
</div>
) : (
)}
{userHasVoted && !myInfo && (
<div
className="flex items-center justify-center w-full h-18 text-body-1-normal "
style={{
backgroundImage: `url(${BlurImage})`,
}}
>
<p>👀 투표 결과는 로그인 후 확인할 수 있어요!</p>
</div>
)}
{userHasVoted &&
myInfo &&
voteStatus?.map((status, index) => {
const calculatedVoteRatio = totalVoted
? ((status.voteCount / totalVoted) * 100).toFixed(1)
Expand All @@ -49,8 +63,7 @@ export default function VoteResultList() {
isHighest={status.voteCount === highestVoted}
/>
);
})
)}
})}
</div>
);
}
11 changes: 10 additions & 1 deletion src/pages/Login/OAuthPage.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import usePostKakaoLogin from '@/api/usePostKaKaoLogin';
import { setAccessToken } from '@/components/login/Auth/token';

export default function OAuthPage() {
const { mutate } = usePostKakaoLogin();
const state = new URL(window.location.href).searchParams.get('state');
const navigate = useNavigate();
const { mutate } = usePostKakaoLogin({
onSuccess: (data) => {
setAccessToken(data.accessToken);
navigate(state ?? `/user/${data.userId}`);
},
});

useEffect(() => {
const code = new URL(window.location.href).searchParams.get('code');
Expand Down
8 changes: 8 additions & 0 deletions src/pages/Vote/VotePage.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import { useNavigate } from 'react-router-dom';
import useGetMyInfo from '@/api/useGetMyInfo';
import Logo from '@/assets/icons/logo.svg?react';
import { useDialog } from '@/components/common/Dialog/hooks';
import { Header } from '@/components/common/Header/Header';
import Icon from '@/components/common/Icon';
import LoginDialog from '@/components/common/LoginDialog/LoginDialog';
import CommentList from '@/components/vote-detail/Comment/CommentList';
import CommentInput from '@/components/vote-detail/Input/CommentInput';
import VoteTopSection from '@/components/vote-detail/Top/VoteTopSection/VoteTopSection';
import VoteSection from '@/components/vote-detail/Vote/VoteSection';

export default function VotePage() {
const navigate = useNavigate();
const { openDialog } = useDialog();
const { data: myInfo } = useGetMyInfo();

const handleClickUserButton = () => {
if (!myInfo) {
openDialog(<LoginDialog />);
return;
}

navigate(`/user/${myInfo?.id}`);
};

Expand Down

0 comments on commit f9f7cbf

Please sign in to comment.