Skip to content

Commit 60486b0

Browse files
authored
Merge pull request #22 from Check-Data-Out/release
[25.03.08 / TASK-116,TASK-103] 릴리즈
2 parents 0a45831 + f38f3dc commit 60486b0

File tree

9 files changed

+211
-18
lines changed

9 files changed

+211
-18
lines changed

Diff for: 500.html

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>Velog Dashboard - 500</title>
7+
<style>
8+
@media (min-width: 1200px) {
9+
div.layout {
10+
background: #1e1e1e;
11+
width: 500px;
12+
height: 300px;
13+
display: flex;
14+
align-items: center;
15+
justify-content: center;
16+
flex-direction: column;
17+
gap: 20px;
18+
}
19+
div.titleLayout {
20+
display: flex;
21+
align-items: center;
22+
gap: 20px;
23+
}
24+
div.iconLayout {
25+
width: 100px;
26+
height: 100px;
27+
background: #1ec996;
28+
display: flex;
29+
align-items: center;
30+
justify-content: center;
31+
border-radius: 4px;
32+
}
33+
span.iconText {
34+
font-style: italic;
35+
font-size: 50px;
36+
font-weight: bold;
37+
color: white;
38+
margin-top: 10px;
39+
margin-left: -10px;
40+
}
41+
span.text {
42+
color: white;
43+
font-size: 24px;
44+
font-weight: 500;
45+
}
46+
h2.titleText {
47+
color: white;
48+
font-size: 28px;
49+
font-weight: bold;
50+
}
51+
}
52+
@media (min-width: 992px) and (max-width: 1199px) {
53+
div.layout {
54+
background: #1e1e1e;
55+
width: 450px;
56+
height: 250px;
57+
display: flex;
58+
align-items: center;
59+
justify-content: center;
60+
flex-direction: column;
61+
gap: 20px;
62+
}
63+
div.titleLayout {
64+
display: flex;
65+
align-items: center;
66+
gap: 20px;
67+
}
68+
div.iconLayout {
69+
width: 80px;
70+
height: 80px;
71+
background: #1ec996;
72+
display: flex;
73+
align-items: center;
74+
justify-content: center;
75+
border-radius: 4px;
76+
}
77+
span.iconText {
78+
font-style: italic;
79+
font-size: 40px;
80+
font-weight: bold;
81+
color: white;
82+
margin-top: 10px;
83+
margin-left: -10px;
84+
}
85+
span.text {
86+
color: white;
87+
font-size: 20px;
88+
font-weight: 500;
89+
}
90+
h2.titleText {
91+
color: white;
92+
font-size: 24px;
93+
font-weight: bold;
94+
}
95+
}
96+
97+
@media (max-width: 991px) {
98+
div.layout {
99+
background: #1e1e1e;
100+
width: 350px;
101+
height: 250px;
102+
display: flex;
103+
align-items: center;
104+
justify-content: center;
105+
flex-direction: column;
106+
gap: 20px;
107+
}
108+
div.titleLayout {
109+
display: flex;
110+
align-items: center;
111+
gap: 20px;
112+
}
113+
div.iconLayout {
114+
width: 80px;
115+
height: 80px;
116+
background: #1ec996;
117+
display: flex;
118+
align-items: center;
119+
justify-content: center;
120+
border-radius: 4px;
121+
}
122+
span.iconText {
123+
font-style: italic;
124+
font-size: 40px;
125+
font-weight: normal;
126+
color: white;
127+
margin-top: 10px;
128+
margin-left: -10px;
129+
}
130+
span.text {
131+
color: white;
132+
font-size: 18px;
133+
font-weight: 500;
134+
}
135+
h2.titleText {
136+
color: white;
137+
font-size: 22px;
138+
font-weight: bold;
139+
}
140+
}
141+
* {
142+
transition: all;
143+
transition-duration: 300ms;
144+
}
145+
body {
146+
width: 100%;
147+
height: 100vh;
148+
overflow: hidden;
149+
background: #121212;
150+
display: flex;
151+
align-items: center;
152+
justify-content: center;
153+
}
154+
</style>
155+
</head>
156+
<body>
157+
<div class="layout">
158+
<div class="titleLayout">
159+
<div class="iconLayout">
160+
<span class="iconText"><span style="font-weight: 400">V</span>D</span>
161+
</div>
162+
<h2 class="titleText">Velog Dashboard</h2>
163+
</div>
164+
<span class="text">알 수 없는 오류가 발생했습니다.</span>
165+
</div>
166+
<script
167+
async
168+
src="https://www.googletagmanager.com/gtag/js?id=G-8G3N74JV82"
169+
></script>
170+
<script>
171+
window.dataLayer = window.dataLayer || [];
172+
function gtag() {
173+
dataLayer.push(arguments);
174+
}
175+
gtag('js', new Date());
176+
177+
gtag('config', 'G-8G3N74JV82');
178+
</script>
179+
</body>
180+
</html>

Diff for: package.json

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"dependencies": {
1616
"@channel.io/channel-web-sdk-loader": "^2.0.0",
1717
"@next/third-parties": "^15.1.7",
18+
"@sentry/core": "^8.47.0",
1819
"@sentry/nextjs": "^8.47.0",
1920
"@tanstack/react-query": "^5.61.3",
2021
"@tanstack/react-query-devtools": "^5.62.11",

Diff for: pnpm-lock.yaml

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: src/apis/instance.request.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,9 @@ export const instance = async <I, R>(
7575
return (data.body as unknown as SuccessType<R>).data;
7676
} catch (err: unknown) {
7777
const context = err as Response;
78-
if (location && !context.ok && context.status === 403) {
78+
if (location && !context.ok && context.status === 401) {
7979
window.location.replace('/');
8080
}
81-
//context.status === 401 ||
8281
setContext('Request', {
8382
path: context.url,
8483
status: context.status,

Diff for: src/app/(with-tracker)/(login)/Content.tsx

+1-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { useRouter } from 'next/navigation';
44
import { useForm } from 'react-hook-form';
55
import Image from 'next/image';
6-
import { useMutation, useQueryClient } from '@tanstack/react-query';
6+
import { useMutation } from '@tanstack/react-query';
77
import { Input, Button } from '@/components';
88
import { LoginVo } from '@/types';
99
import { login, sampleLogin } from '@/apis';
@@ -14,7 +14,6 @@ const responsiveStyle =
1414

1515
export const Content = () => {
1616
const { replace } = useRouter();
17-
const client = useQueryClient();
1817

1918
const {
2019
register,
@@ -23,7 +22,6 @@ export const Content = () => {
2322
} = useForm<LoginVo>({ mode: 'all' });
2423

2524
const onSuccess = () => {
26-
client.clear();
2725
trackUserEvent(MessageEnum.LOGIN);
2826
replace('/main?asc=false&sort=');
2927
};

Diff for: src/components/auth-required/header/index.tsx

+10-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { NameType } from '@/components';
99
import { useResponsive } from '@/hooks';
1010
import { logout, me } from '@/apis';
1111
import { trackUserEvent, MessageEnum } from '@/utils/trackUtil';
12+
import { revalidate } from '@/utils/revalidateUtil';
13+
1214
import { defaultStyle, Section, textStyle } from './Section';
1315

1416
const PARAMS = {
@@ -37,13 +39,19 @@ export const Header = () => {
3739

3840
const { mutate: out } = useMutation({
3941
mutationFn: logout,
40-
onMutate: () => router.replace('/'),
41-
onSuccess: () => client.removeQueries(),
42+
onSuccess: async () => {
43+
await revalidate();
44+
client.clear();
45+
router.replace('/');
46+
},
4247
});
4348

4449
const { data: profiles } = useQuery({
4550
queryKey: [PATHS.ME],
4651
queryFn: me,
52+
enabled: !!client.getQueryData([PATHS.ME]),
53+
// 로그아웃 후 리렌더링되어 다시 fetch되는 경우 해결
54+
// 어차피 prefetch를 통해 데이터를 불러온 상태에서 렌더하기 때문에, 캐시 여부만 판단하면 됨
4755
});
4856

4957
useEffect(() => {

Diff for: src/components/auth-required/main/Section/index.tsx

+5-10
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,22 @@
11
'use client';
22

3-
import { useQueryClient } from '@tanstack/react-query';
43
import { useState } from 'react';
5-
import { UserNameNotFoundError } from '@/errors';
64
import { trackUserEvent, MessageEnum } from '@/utils/trackUtil';
75
import { parseNumber } from '@/utils/numberUtil';
86
import { COLORS, env, PATHS } from '@/constants';
97
import { PostType, UserDto } from '@/types';
108
import { Icon } from '@/components';
9+
import { getQueryClient } from '@/utils/queryUtil';
1110
import { Graph } from './Graph';
1211

1312
export const Section = (p: PostType) => {
1413
const [open, setOpen] = useState(false);
15-
const client = useQueryClient();
1614

17-
const { username } = client.getQueryData([PATHS.ME]) as UserDto;
18-
const URL = env.VELOG_URL;
15+
const username = (
16+
getQueryClient().getQueryData([PATHS.ME]) as Partial<UserDto>
17+
)?.username;
1918

20-
if (!username) {
21-
throw new UserNameNotFoundError();
22-
}
23-
24-
const url = `${URL}/@${username}/${p.slug}`;
19+
const url = `${env.VELOG_URL}/@${username}/${p.slug}`;
2520

2621
return (
2722
<section className="flex flex-col w-full h-fit relative">

Diff for: src/utils/queryUtil.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { toast } from 'react-toastify';
33

44
let localQueryClient: QueryClient | undefined;
55
const STALE_TIME = 1000 * 60 * 3;
6-
const GC_TIME = 1000;
6+
const GC_TIME = 1000 * 60 * 20;
77

88
const createQueryClient = () =>
99
new QueryClient({

Diff for: src/utils/revalidateUtil.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use server';
2+
3+
import { revalidatePath } from 'next/cache';
4+
import { redirect } from 'next/navigation';
5+
6+
export async function revalidate() {
7+
revalidatePath('/', 'layout');
8+
redirect('/');
9+
}

0 commit comments

Comments
 (0)