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] 인터뷰 룸 관련 페이지 반응형 디자인 적용 및 토큰 에러 인터셉터 작성 #58

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import axios from 'axios';
import axios, { isAxiosError } from 'axios';
import { ThemeProvider } from '@emotion/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import Header from './components/Layout/Header';
Expand All @@ -7,19 +7,51 @@ import GlobalStyle from './GlobalStyle';
import Router from './Router';
import { darkMode, lightMode } from './theme';
import { useIsDark } from './hooks/Common';
import { logoutFn, silentRefresh } from './utils/SignIn/signInFn';
import { useNavigate } from 'react-router';
// import { ErrorBoundary } from './components/Util';

const queryClient = new QueryClient();

function App() {
const { VITE_SERVER_URL } = import.meta.env;
const isDark = useIsDark();
const navigate = useNavigate();

// axios 전역 기본값 설정
axios.defaults.baseURL = VITE_SERVER_URL;
axios.defaults.headers['Content-Type'] = 'application/json';
axios.defaults.withCredentials = true;

// 응답 인터셉터 추가하기
axios.interceptors.response.use(
(res) => res,
async (err) => {
const status = err.response.status;
if (status === 419 || status === 401) {
silentRefresh().catch((err) => {
if (isAxiosError(err)) {
logoutFn();
switch (status) {
case 400:
alert('세션이 만료되었습니다. 다시 로그인 해주세요.');
break;
default:
navigate(`/error/500`);
}
navigate('/sign-in');
}
});

// 토큰 재발급 성공시
const originalResponse = await axios.request(err.config);
return originalResponse;
}

return Promise.reject(err);
}
);
Comment on lines +27 to +53
Copy link
Member

Choose a reason for hiding this comment

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

혹시 이부분 테스트 해보셨나요?? 로그인되지 않은 상태에서 로그인이 필요한 페이지로 접근했을 때 auth와 refresh를 무한 재요청하고 있습니다........ㅜㅜ
아마 인터셉터가 전역으로 설정되어 있어서가 아닐까 싶은데 (auth에서 intercept, refresh에서 intercept.... 반복? 그냥 제 예상입니다)
이 문제가 아니더라도 axios 설정 로직이 길어지니까 App.tsx에서 분리하는게 좋을 것 같아서 intercept가 필요한 요청은 따로 axios instance를 만들어서 쓰는게 좀 더 깔끔할 것 같다는 생각이 듭니다...ㅎㅎ

auth, refresh 재요청 하는 부분은 다시 확인해보셔야 할 것 같습니다!!!!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

으아아 죄송합니다 제가 테스트가 부족했어요..ㅠㅠㅠㅠ 다른 요청시 토큰 만료 에러가 잘 동작하는지만 확인하고 로그인 하지 않았을때를 제대로 확인해보지 않은거같아요ㅠ 이부분은 auth, refresh 등 로그인 부분만 별도의 axios 인스턴스를 작성해서 해결해보겠습니다...!!


return (
<>
<ThemeProvider theme={isDark ? darkMode : lightMode}>
Expand Down
24 changes: 23 additions & 1 deletion src/GlobalStyle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ const style = (theme: Theme) =>
h2: {
fontSize: '3.6rem',
fontWeight: 700,
marginBottom: '2.5rem',
margin: '5rem 0 2.5rem',
},

// 페이지 서브타이틀
Expand Down Expand Up @@ -119,15 +119,37 @@ const style = (theme: Theme) =>
fontSize: '1.4rem',
},

h2: {
fontSize: '3rem',
margin: '3rem 0 2rem',
},

h3: {
fontSize: '2.5rem',
},

'.inner': {
width: '90%',
},

'input, select, textarea': {
padding: '0.5rem 1rem',
},
},

[mq[1]]: {
'.container': {
padding: '7rem 0',
},

h2: {
fontSize: '2.4rem',
margin: '2rem 0',
},

h3: {
fontSize: '1.8rem',
},
},
});

Expand Down
5 changes: 5 additions & 0 deletions src/components/Common/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Theme, css, useTheme } from '@emotion/react';
import { MouseEventHandler } from 'react';
import { mq } from '../../theme';

const StyledBtn = (theme: Theme) =>
css({
Expand Down Expand Up @@ -31,6 +32,10 @@ const StyledBtn = (theme: Theme) =>
backgroundColor: `${theme.gray2}`,
cursor: 'default',
},

[mq[0]]: {
padding: '0.5rem 1.5rem',
},
});

interface BtnProps {
Expand Down
25 changes: 19 additions & 6 deletions src/components/Interview/InterviewItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useState } from 'react';
import axios from 'axios';
import { useQueryClient } from '@tanstack/react-query';
import { errMsg } from '../../types/Interview/ListTypes';
import { mq } from '../../theme';

interface InterviewItemProps {
id: number;
Expand All @@ -29,13 +30,10 @@ const StyledInterviewItem = (theme: Theme) =>
gap: '2rem',

'.left': {
flex: '0 0 5%',
'.checkbox': {
padding: '1rem',
},
flex: '0 0 3rem',
},
'.mid': {
flexGrow: 1,
flex: '1 1 0',
width: '80%',
'.type': {
display: 'inline-block',
Expand Down Expand Up @@ -72,7 +70,7 @@ const StyledInterviewItem = (theme: Theme) =>
},
},
'.right': {
flex: '0 0 5%',
flex: '0 0 5rem',
fontSize: '1.8rem',
display: 'flex',
alignItems: 'center',
Expand All @@ -85,6 +83,21 @@ const StyledInterviewItem = (theme: Theme) =>
},
},
},

[mq[0]]: {
'.mid': {
'.title': {
fontSize: '2rem',
},
},
},
[mq[1]]: {
'.mid': {
'.title': {
fontSize: '1.8rem',
},
},
},
});

const InterviewItem = ({
Expand Down
37 changes: 37 additions & 0 deletions src/components/Interview/MessageItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Theme, css, useTheme } from '@emotion/react';
import { bookmarkToggle } from '../../utils/Interview/interviewDetailFn';
import { useQueryClient } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import { mq } from '../../theme';

interface MessageProps {
message: InterviewDetailData;
Expand Down Expand Up @@ -74,6 +75,13 @@ const StyledMessageItem = (theme: Theme) =>
'.icon': {
backgroundColor: `${theme.orange2}`,
},
'.content-wrap': {
'>div': {
p: {
width: '100%',
},
},
},
},
'.list-name': {
fontSize: '1.4rem',
Expand All @@ -85,6 +93,35 @@ const StyledMessageItem = (theme: Theme) =>
borderBottomColor: `${theme.fontColor}`,
},
},

[mq[1]]: {
padding: '1rem',
flexDirection: 'column',
alignItems: 'flex-start',
gap: '1rem',
'.icon': {
padding: 0,
width: '3rem',
height: '3rem',
fontSize: '1.4rem',
},
'.content-wrap': {
width: '100%',
gap: '1rem',
'>div': {
p: {
width: 'calc(100% - 2.5rem)',
},
},
},
'&.user': {
flexDirection: 'column',
alignSelf: 'flex-end',
'> .icon': {
alignSelf: 'flex-end',
},
},
},
});

const MessageItem = ({ message, listName, listId }: MessageProps) => {
Expand Down
7 changes: 7 additions & 0 deletions src/components/Interview/ReplyItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import axios from 'axios';
import { useQueryClient } from '@tanstack/react-query';
import { useNavigate } from 'react-router-dom';
import { Loading } from '../Common';
import { mq } from '../../theme';

interface ReplyItemProps {
questionNum: number;
Expand Down Expand Up @@ -70,6 +71,12 @@ const StyledReplyItem = (theme: Theme) =>
'&.open': {
height: 'auto',
},

[mq[1]]: {
'>div, > ul': {
padding: '1rem',
},
},
});

const ReplyItem = ({
Expand Down
69 changes: 48 additions & 21 deletions src/pages/InterviewDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Theme, css, useTheme } from '@emotion/react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { getChatData } from '../utils/Interview/interviewDetailFn';
import { Loading } from '../components/Common';
import { mq } from '../theme';

const StyledInterviewDetail = (theme: Theme) =>
css({
Expand Down Expand Up @@ -64,6 +65,12 @@ const StyledInterviewDetail = (theme: Theme) =>
width: 'auto',
marginRight: '0.5rem',
},
'> div': {
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
gap: '2rem',
},
},
'.prompt-box': {
flexDirection: 'column',
Expand Down Expand Up @@ -106,6 +113,24 @@ const StyledInterviewDetail = (theme: Theme) =>
gap: '10rem',
},
},
[mq[1]]: {
form: {
marginBottom: '4rem',
padding: '1rem',
'.radio-box p, .count-box label, .prompt-box label': {
fontSize: '1.6rem',
},
'.radio-box': {
flexWrap: 'wrap',
},
},
'.reply-wrap': {
'.reply-list': {
marginTop: '3rem',
gap: '5rem',
},
},
},
});

const InterviewDetail = () => {
Expand Down Expand Up @@ -231,27 +256,29 @@ const InterviewDetail = () => {
<form onSubmit={onSubmit}>
<div className='radio-box'>
<p>면접 유형</p>
{radio.map((item, idx) => {
return (
<label key={idx}>
<input
type='radio'
name='type'
className='type'
value={item}
defaultChecked={
(data && data[0].type === item) ||
(data === undefined && item === '일반')
}
disabled={data && data[0].prompt !== ''}
onChange={(e) =>
handleOnChange(e.target.className, e.target.value)
}
/>
{item}면접
</label>
);
})}
<div>
{radio.map((item, idx) => {
return (
<label key={idx}>
<input
type='radio'
name='type'
className='type'
value={item}
defaultChecked={
(data && data[0].type === item) ||
(data === undefined && item === '일반')
}
disabled={data && data[0].prompt !== ''}
onChange={(e) =>
handleOnChange(e.target.className, e.target.value)
}
/>
{item}면접
</label>
);
})}
</div>
</div>
<div className='count-box'>
<label htmlFor='count'>예상 질문 개수</label>
Expand Down
Loading