Skip to content

Commit e082d5f

Browse files
authored
Fix: 비로그인 유저 좋아요 제한 (#156)
* style: 토스트 쪼그라드는 이슈 해결 * feat: 비로그인 유저 좋아요 시 redirect 되도록 수정 * feat: login 페이지에 로고 누르면 home으로 이동하도록 추가 * feat: 로그인 완료 후 원래 있던 페이지로 이동 * refactor: 로그인페이지에 suspense 추가 * refactor: 코드리뷰 반영 * refactor: isMine 제거
1 parent d1fd7d5 commit e082d5f

22 files changed

Lines changed: 167 additions & 64 deletions

File tree

app/(auth)/_api/auth.api.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@ const AUTH_ENDPOINTS = {
1010
const AUTH_REDIRECT_URL = (provider: "naver" | "google") =>
1111
`${process.env.NEXT_PUBLIC_REDIRECT_URL}/${provider}`;
1212

13-
export const getOAuthUrl = async (provider: "naver" | "google") => {
13+
export const getOAuthUrl = async (
14+
provider: "naver" | "google",
15+
next?: string,
16+
) => {
17+
const redirectUrl = new URL(AUTH_REDIRECT_URL(provider));
18+
if (next) {
19+
redirectUrl.searchParams.set("next", next);
20+
}
1421
const response = await apiClient.get<OAuthRes>(
1522
AUTH_ENDPOINTS.OAUTH_URL(provider),
16-
{
17-
searchParams: {
18-
redirectUrl: AUTH_REDIRECT_URL(provider),
19-
},
20-
},
23+
{ searchParams: { redirectUrl: redirectUrl.toString() } },
2124
);
2225
return response.result.url;
2326
};

app/(auth)/login/callback/[provider]/page.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,28 @@ export default function CallbackPage() {
88
const searchParams = useSearchParams();
99
const params = useParams();
1010
const code = searchParams.get("code");
11+
const nextUrl = searchParams.get("next");
1112
const provider = params.provider as "naver" | "google";
1213
const router = useRouter();
1314
const { mutate, isPending, isError } = useSocialLogin();
1415

1516
useEffect(() => {
16-
if (!code || !provider) return;
17+
if (!(code && provider)) return;
1718

1819
mutate(
1920
{ provider: provider, code: code },
2021
{
2122
onSuccess: () => {
22-
router.replace("/");
23-
},
24-
onError: () => {
25-
console.log("로그인 실패");
23+
const redirectUrl =
24+
nextUrl?.startsWith("/") && !nextUrl.startsWith("//")
25+
? nextUrl
26+
: "/";
27+
router.replace(redirectUrl);
2628
},
29+
onError: () => {},
2730
},
2831
);
29-
}, [code, provider]);
32+
}, [code, provider, nextUrl]);
3033

3134
if (isPending) return <LoadingSpinner loading={isPending} />;
3235

app/(auth)/login/page.tsx

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,37 @@
11
"use client";
2-
32
import LettieImage from "@/shared/assets/character/lettie_animate.png";
43
import GoogleIcon from "@/shared/assets/icon/google.svg";
54
import NaverIcon from "@/shared/assets/icon/naver.svg";
65
import LogoImage from "@/shared/assets/logo/logo_symbol_wordmark.svg";
6+
import { PATH } from "@/shared/constants/path";
77
import { maxWidth } from "@/shared/styles/base/global.css";
8-
import { getOAuthUrl } from "../_api/auth.api";
9-
8+
import LoadingSpinner from "@/shared/ui/loading-spinner";
109
import Image from "next/image";
11-
10+
import Link from "next/link";
11+
import { useSearchParams } from "next/navigation";
12+
import { Suspense } from "react";
13+
import { getOAuthUrl } from "../_api/auth.api";
1214
import * as styles from "./page.css";
13-
1415
const LoginPage = () => {
16+
const searchParams = useSearchParams();
17+
const nextUrl = searchParams.get("next");
18+
1519
const handleGoToOAuth = (provider: "naver" | "google") => {
16-
getOAuthUrl(provider).then((url) => {
20+
const safeNext =
21+
nextUrl?.startsWith("/") && !nextUrl.startsWith("//")
22+
? nextUrl
23+
: undefined;
24+
getOAuthUrl(provider, safeNext).then((url) => {
1725
window.location.href = url;
1826
});
1927
};
2028

2129
return (
2230
<div className={maxWidth}>
2331
<header className={styles.header}>
24-
<LogoImage />
32+
<Link href={PATH.HOME}>
33+
<LogoImage />
34+
</Link>
2535
</header>
2636
<div className={styles.contentsContainer}>
2737
<h1 className={styles.title}>
@@ -55,4 +65,10 @@ const LoginPage = () => {
5565
);
5666
};
5767

58-
export default LoginPage;
68+
export default function Page() {
69+
return (
70+
<Suspense fallback={<LoadingSpinner loading={true} />}>
71+
<LoginPage />
72+
</Suspense>
73+
);
74+
}

app/(main)/my-capsule/_components/select-tab-section/select-tab-section.css.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ export const chipWrapper = style({
2020

2121
export const dropdown = style({
2222
position: "absolute",
23-
right: 0,
24-
top: 0,
23+
right: "0",
24+
top: "100%",
25+
transform: "translateY(-180%)",
2526
marginRight: "1rem",
2627
...screen.md({
27-
top: 0,
28-
right: 0,
28+
top: "100%",
29+
transform: "translateY(-90%)",
2930
}),
3031
});

app/(sub)/capsule-detail/[invite-code]/[id]/letters/_components/grid-layout/index.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,16 @@ const GridLayout = ({ letters, imageUrls }: GridLayoutProps) => {
1212
<div className={styles.container}>
1313
<div className={styles.grid}>
1414
{letters.map((letter) => {
15-
const imageUrl = imageUrls.find((img) => img.letterId === letter.letterId)?.url;
16-
return <GridLetterCard key={letter.letterId} letter={letter} imageUrl={imageUrl} />;
15+
const imageUrl = imageUrls.find(
16+
(img) => img.letterId === letter.letterId,
17+
)?.url;
18+
return (
19+
<GridLetterCard
20+
key={letter.letterId}
21+
letter={letter}
22+
imageUrl={imageUrl}
23+
/>
24+
);
1725
})}
1826
</div>
1927
</div>

app/(sub)/capsule-detail/[invite-code]/[id]/letters/_components/grid-letter-card/index.tsx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,18 @@ const GridLetterCard = ({ letter, imageUrl, onClick }: LetterCardProps) => {
1313
return (
1414
<HoverMotion>
1515
<section className={styles.card} onClick={onClick}>
16-
{imageUrl && <Image width={200} height={200} className={styles.image} src={imageUrl} alt="편지 이미지" />}
17-
<div className={styles.content}>{!imageUrl && <p>{letter.content}</p>}</div>
16+
{imageUrl && (
17+
<Image
18+
width={200}
19+
height={200}
20+
className={styles.image}
21+
src={imageUrl}
22+
alt="편지 이미지"
23+
/>
24+
)}
25+
<div className={styles.content}>
26+
{!imageUrl && <p>{letter.content}</p>}
27+
</div>
1828

1929
{letter.from && (
2030
<p>

app/(sub)/capsule-detail/[invite-code]/[id]/letters/_components/open-capsule-loading/index.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ interface OpenCapsuleLoadingProps {
1212

1313
const AUTO_CLOSE_DELAY = 3000;
1414

15-
const OpenCapsuleLoading = ({ participantCount, letterCount, onComplete }: OpenCapsuleLoadingProps) => {
15+
const OpenCapsuleLoading = ({
16+
participantCount,
17+
letterCount,
18+
onComplete,
19+
}: OpenCapsuleLoadingProps) => {
1620
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
1721
const isCompletedRef = useRef(false);
1822

app/(sub)/capsule-detail/[invite-code]/[id]/letters/_components/stack-layout/animations.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ const getRotateAngle = (stackIndex: number) => {
44
return stackIndex * -5;
55
};
66

7-
export const createStackAnimations = (direction: number, visibleLetters: VisibleLetter[]) => {
7+
export const createStackAnimations = (
8+
direction: number,
9+
visibleLetters: VisibleLetter[],
10+
) => {
811
return visibleLetters.map(({ stackIndex }) => ({
912
initial:
1013
direction === -1 && stackIndex === 0

app/(sub)/capsule-detail/[invite-code]/[id]/letters/_components/stack-layout/index.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,13 @@ const StackLayout = ({ letters, imageUrls }: StackLayoutProps) => {
104104
<div className={styles.stackContainer}>
105105
<AnimatePresence mode="popLayout">
106106
{visibleLetters.map(({ letter, key }, index) => {
107-
const animationProps = createStackAnimations(direction, visibleLetters)[index];
108-
const imageUrl = imageUrls.find((img) => img.letterId === letter.letterId)?.url;
107+
const animationProps = createStackAnimations(
108+
direction,
109+
visibleLetters,
110+
)[index];
111+
const imageUrl = imageUrls.find(
112+
(img) => img.letterId === letter.letterId,
113+
)?.url;
109114

110115
return (
111116
<motion.div
@@ -129,7 +134,9 @@ const StackLayout = ({ letters, imageUrls }: StackLayoutProps) => {
129134
className={styles.navButton}
130135
onClick={nextLetter}
131136
disabled={isAnimating}
132-
style={{ visibility: currentIndex < letters.length - 1 ? "visible" : "hidden" }}
137+
style={{
138+
visibility: currentIndex < letters.length - 1 ? "visible" : "hidden",
139+
}}
133140
type="button"
134141
>
135142
<Right width={24} height={24} />

app/(sub)/capsule-detail/[invite-code]/[id]/letters/_components/stack-letter-card/index.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,22 @@ const StackLetterCard = ({ letter, imageUrl, onClick }: LetterCardProps) => {
1212
return (
1313
<section className={styles.card} onClick={onClick}>
1414
<div className={styles.contentWrapper}>
15-
{imageUrl && <Image width={240} height={240} className={styles.image} src={imageUrl} alt="편지 이미지" />}
16-
<p className={imageUrl ? styles.contentWithImage : styles.contentWithoutImage}>{letter.content}</p>
15+
{imageUrl && (
16+
<Image
17+
width={240}
18+
height={240}
19+
className={styles.image}
20+
src={imageUrl}
21+
alt="편지 이미지"
22+
/>
23+
)}
24+
<p
25+
className={
26+
imageUrl ? styles.contentWithImage : styles.contentWithoutImage
27+
}
28+
>
29+
{letter.content}
30+
</p>
1731
</div>
1832

1933
{letter.from && (

0 commit comments

Comments
 (0)