Skip to content

Commit 6071f76

Browse files
wldnjs990tifsyAAminhanirii00
authored
deploy : 배포준비 (#104)
* feat: 임시저장된 편지 삭제 기능 구현 (#84) * fix: 공유 게시글 목록 페이지네이션에서 무한 스크롤로 전환 * refactor: 필요없는 코드 삭제 * feat: 임시저장된 편지 삭제 기능 구현 * design: 임시저장 편지 삭제 아이콘 클릭 시 색상 변경 * feat: 롤링페이퍼 배포된 api로 연결 수정 (#85) * style:롤링페이퍼 공지 애니메이션 수정 * fix: 롤링페이퍼가 진행되지 않을 때 화면에 보여지지 않도록 처리 * feat: 새로운 롤링페이퍼 생성 api 연동 * feat: 롤링페이퍼 목록 조회 api 연동 * feat: 롤링페이퍼 삭제 api 연동 * feat: 롤링페이퍼 사용여부 변경 api 연동 * feat: 롤링페이퍼 코멘트 목록 조회 api 연동 * feat: 롤링페이퍼 등록 및 삭제 api 연동 - api 응답 구조 수정 * feat : 알림 2차 기능 구현 (#81) * feat:알림 컨텐츠 상호작용, 라우팅 기능 구현 * feat : SSE구현시도 * feat : SSE전역변수로 관리할지 store 하나 만들어서 만들면서 고민중 * feat : 알림구독 테스트용 App.tsx에 훅 호출한 코드 * fix: 자잘한 이슈 수정 (#86) * fix: 401 에러가 아닌 경우 바로 로그아웃 되는 문제 해결 * fix: 토큰 만료로 reissue 실패시 로그아웃 안되는 문제 해결 * fix: reissue 에러 시 에러 처리 안되는 문제 해결 - client.ts의 interceptors.response.use 구문 내에서 api 호출및 데이터 가공을 함수 밖으로 꺼냄 * fix: mailbox에서 isClosed 옵션 반대로 보여주는 문제 해결 - isClosed 상태를 반대로 받아와서 상태를 잘못 보여주는 문제 해결 * fix: mailBox 배포 api에 따른 수정 작업 - sharePost 요청 요청자 id 삭제 - 상세 페이지 api 경로 수정 - 우편함 상세체이지 날짜 잘못표기하는 에러 수정 * fix: reissue시 access token을 사용하지 않도록 수정 * feat: 신고 모달 파라미터 변경으로 인한, 파라미터 추가(게시판 상세) * fix: 마이페이지 api 수정 * feat: 임시저장된 편지 삭제 기능 구현 (#84) * fix: 공유 게시글 목록 페이지네이션에서 무한 스크롤로 전환 * refactor: 필요없는 코드 삭제 * feat: 임시저장된 편지 삭제 기능 구현 * design: 임시저장 편지 삭제 아이콘 클릭 시 색상 변경 * feat: 롤링페이퍼 배포된 api로 연결 수정 (#85) * style:롤링페이퍼 공지 애니메이션 수정 * fix: 롤링페이퍼가 진행되지 않을 때 화면에 보여지지 않도록 처리 * feat: 새로운 롤링페이퍼 생성 api 연동 * feat: 롤링페이퍼 목록 조회 api 연동 * feat: 롤링페이퍼 삭제 api 연동 * feat: 롤링페이퍼 사용여부 변경 api 연동 * feat: 롤링페이퍼 코멘트 목록 조회 api 연동 * feat: 롤링페이퍼 등록 및 삭제 api 연동 - api 응답 구조 수정 * fix: type 에러 수정 * fix: 데이터가 없는 경우 컴포넌트 에러가 나는 부분 수정 - 배열이 없거나, 길이가 0이면 placeholder를 보여줌 * Update index.tsx 이상한 import 지움 --------- Co-authored-by: nirii00 <[email protected]> Co-authored-by: Seungyeon Han (Tiffany) <[email protected]> Co-authored-by: Minha Ahn <[email protected]> * feat : 재사용 가능한 페이지네이션 구현 (#92) * feat: 편지 공유 요청 수신 조회 기능 구현 (#90) * feat: 편지 공유 요청 수신 조회 기능 구현 * refactor: incomingLetters.ts 코드 리팩토링 * refactor: incomingLettersStore.ts에서 필요 없는 필드 정리 * feat: 오고 있는 편지 도착까지 걸리는 시간 카운트다운 기능 구현 * design: 오고 있는 편지 모달에서 데이터가 없을 때 대체 텍스트 추가 * design: 임시저장된 편지 모달에서 데이터가 없을 때 대체 텍스트 추가 * design: 편지 공유 요청 수신 조회 모달에서 데이터가 없을 때 대체 텍스트 추가 * feat : 편지작성, 랜덤편지, 상세페이지 3차 기능구현 (#94) * feat : 게시글 신고기능 구현 * feat : 카테고리 전체 선택 안되는 오류 수정 + 답장 전송시 도착시간 1시간으로 텍스트 고정 * feat : getPrevLetter api 엔드포인트 변경 * feat : 디테일 페이지 답장버튼 분기처리 * feat : 편지상세페이지 zipCode바인딩 * refactor : 편지상세 페이지 컴포넌트 분리 * feat : 편지 상세 컴포넌트 추가 분리 + 편지 평가 기능 구현 완료 * refactor : 신고모달 타입에서 null 제거 + 이전편지 가져오기, 타입 조금 수정 * feat : 랜덤편지 편지 없을 경우 예외처리 UI 추가 * design : 편지작성, 편지상세 resize속성 제거 * feat : 랜덤편지 데이터가 없을시 예외처리 UI 추가 + 쿨타임 상태일때 예외처리 UI 수정 * chore : 랜덤편지 api console 제거 * feat : 임시저장 api 생성(연결 테스트 아직 안함) * feat : 편지 작성 페이지 임시저장 버튼 구현 * feat : 편지 임시저장 80% 구현(승연님 작업 이후 임시저장 업데이트 분기 나눠야함) * feat : 임시저장 최초답장 예외처리 * feat: 롤링페이퍼 추가 기능 구현 (#95) * fix: 더미데이터 제거 * feat: 롤링페이퍼 무한 스크롤 적용 * feat: 관리자 페이지 롤링 페이퍼 설정 화면에 페이지네이션 적용 * design: 롤링페이퍼 작성 버튼 위치 수정 * fix: 데이터 변경 후 캐싱 초기화 하는 조건 수정 * design: 하단 언덕 이미지 깨지는 문제 해결 --------- Co-authored-by: wldnjs990 <[email protected]> * feat: 임시저장 편지 조회 기능 완성 (#97) * design: 편지 공유 요청 모달 텍스트 수정 * fix: 임시저장 편지 조회 데이터 구조 수정 * feat: 임시저장 편지 작성 페이지로 데이터 넘겨주기 * design: 홈 페이지에서 새 이미지를 눌러도 랜덤응원메시지가 바뀌도록 --------- Co-authored-by: wldnjs990 <[email protected]> * feat : 토스트 UI 구현 + 알림 페이지 코드 작업 90% 완료 + 실시간 알림, 편지 작성 예외처리에 토스트UI 연결 (#98) * feat : 알림 타입에 SENDING 추가 * feat : 알림 페이지 타임라인 데이터바인딩 + 알림타입에 따른 UI작업 완료(구독 UI작업만 남음) * feat : 토스트UI 작업중 * feat : SSE훅 호출 위치 App에서 PrivateRouter로 이동 + Home 라우트 PrivateRouter 안으로 이동 * feat : 토스트 기능 1차 구현(알림기능 알림도착, 편지작성 내용 미입력시 토스트 넣어둠) * feat : 토스트알림 최대넓이 지정 * feat : 토스트 컨텐츠 타입별 이모지 추가 * refactor : 토스트UI 알림 1개만 표시 => 알림 1개 이상 표시 되도록 업그레이드(단일 객체 -> 객체 배열로 데이터값 수정) * refactor : 토스트UI position 타입 수정 * fix: reissue 문제, 내 편지함 data 최신화 문제 해결 (#100) * fix: 에러나는 경우 무조건 로그아웃되는 현상 해결 * fix: client.ts 주석 제거 * fix: 탈퇴시 로그아웃 자동적으로 되도록 수정 * feat: 탈퇴 에러시 alert 추가 * fix: 마이페이지, 내 공유 게시물 데이터 없을때 자잘한 에러 수정 * fix: 편치 쿼리 갱신 로직 추가 - queryClient.invalidateQueries로 쿼리를 갱신 * fix: 에러시 alert 추가 * fix: 탈퇴한 회원 로직 추가, 온보딩 from 왼쪽 정렬 * fix: 편지 전송/삭제 시 편지함에서 바로 수정사항 반영되도록 함 - 편지 삭제/전송시 queryClient.invalidateQueries 적용 * fix: 게시판에서 response 없을 경우 페이지 로딩이 안되는 문제 해결 - 추후 지속적으로 확인 예정 * fix: 파비콘, 사이트 이름 수정 * feat: ToastUI 적용 -내 편지함의 alert를 toastUI로 변경했습니다. * fix: reissue token 담기지 않는 문제 해결 * fix: letterBoard length 없음 문제 해결 - 계속 확인 필 --------- Co-authored-by: nirii00 <[email protected]> * feat : 알림 페이지 알림 확인 처리 안되던 현상 수정 + 신고페이지 4차 구현 (#101) * refactor : API 일부 리팩토링 * feat : 알림페이지 알림 단일확인시 읽음알림으로 처리되지않던 현상 수정 * feat : 신고 페이지 status 필터링 임시 구현(수정해야함) * deploy : 오류 수정 --------- Co-authored-by: Seungyeon Han (Tiffany) <[email protected]> Co-authored-by: Minha Ahn <[email protected]> Co-authored-by: Sebin Kim <[email protected]> Co-authored-by: nirii00 <[email protected]>
1 parent 3914a00 commit 6071f76

File tree

76 files changed

+1653
-671
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1653
-671
lines changed

eslint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ export default tseslint.config(
3131
...reactHooks.configs.recommended.rules,
3232
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
3333
'@tanstack/query/exhaustive-deps': 'error',
34+
'@typescript-eslint/no-empty-object-type': off,
3435
'import/order': [
3536
'error',
3637
{

index.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<!doctype html>
2-
<html lang="en">
2+
<html lang="kr">
33
<head>
44
<meta charset="UTF-8" />
5-
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
5+
<link rel="icon" type="image/svg+xml" href="/public/favicon.ico" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7-
<title>Vite + React + TS</title>
7+
<title>36.5</title>
88
<link
99
rel="stylesheet"
1010
as="style"

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"@tailwindcss/vite": "^4.0.6",
1919
"@tanstack/react-query": "^5.66.0",
2020
"axios": "^1.7.9",
21+
"event-source-polyfill": "^1.0.31",
2122
"gsap": "^3.12.7",
2223
"react": "^18.3.1",
2324
"react-dom": "^18.3.1",
@@ -31,6 +32,7 @@
3132
"devDependencies": {
3233
"@eslint/js": "^9.19.0",
3334
"@tanstack/eslint-plugin-query": "^5.66.1",
35+
"@types/event-source-polyfill": "^1.0.5",
3436
"@types/react": "^19.0.8",
3537
"@types/react-dom": "^19.0.3",
3638
"@vitejs/plugin-react-swc": "^3.5.0",

pnpm-lock.yaml

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/favicon.ico

15 KB
Binary file not shown.

public/vite.svg

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/App.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import AdminPage from './pages/Admin';
88
import FilteredLetterManage from './pages/Admin/FilteredLetter';
99
import FilteringManage from './pages/Admin/Filtering';
1010
import ReportManage from './pages/Admin/Report';
11+
import AdminRollingPaper from './pages/Admin/RollingPaper';
1112
import AuthCallbackPage from './pages/Auth';
1213
import Home from './pages/Home';
1314
import Landing from './pages/Landing';
@@ -36,10 +37,10 @@ const App = () => {
3637
<Route path="landing" element={<Landing />} />
3738
<Route path="*" element={<NotFoundPage />} />
3839
<Route path="auth-callback" element={<AuthCallbackPage />} />
39-
<Route index element={<Home />} />
4040
<Route path="onboarding" element={<OnboardingPage />} />
4141

4242
<Route element={<PrivateRoute />}>
43+
<Route index element={<Home />} />
4344
<Route path="letter">
4445
<Route element={<Layout />}>
4546
<Route path="random" element={<RandomLettersPage />} />
@@ -69,6 +70,7 @@ const App = () => {
6970
<Route path="report" element={<ReportManage />} />
7071
<Route path="badwords" element={<FilteringManage />} />
7172
<Route path="filtered-letter" element={<FilteredLetterManage />} />
73+
<Route path="rolling-paper" element={<AdminRollingPaper />} />
7274
</Route>
7375
</Route>
7476
</Routes>

src/apis/admin.ts

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ import client from './client';
33
const postReports = async (postReportRequest: PostReportRequest) => {
44
try {
55
const res = await client.post(`/api/reports`, postReportRequest);
6-
if (res.status === 200) {
7-
return res;
8-
}
6+
if (!res) throw new Error('신고 요청중 에러가 발생했습니다.');
7+
return res;
98
} catch (error) {
109
console.error(error);
1110
}
@@ -51,25 +50,22 @@ const getBadWords = async (setBadWords: React.Dispatch<React.SetStateAction<BadW
5150
}
5251
};
5352

54-
const postBadWords = async (badWordsRequest: BadWords, callBack?: () => void) => {
53+
const postBadWords = async (badWordsRequest: BadWords) => {
5554
try {
5655
const res = await client.post('/api/bad-words', badWordsRequest);
57-
if (callBack) callBack();
5856
console.log(res);
57+
if (!res) throw new Error('금칙어 등록 도중 에러가 발생했습니다.');
58+
return res;
5959
} catch (error) {
6060
console.error(error);
6161
}
6262
};
6363

6464
// 내 상상대로 만든 필터링 단어 취소 버튼
65-
const patchBadWords = async (
66-
badWordId: number,
67-
badWordsRequest: BadWords,
68-
callBack?: () => void,
69-
) => {
65+
const patchBadWords = async (badWordId: number) => {
7066
try {
71-
const res = await client.patch(`/api/bad-words/${badWordId}/status`, badWordsRequest);
72-
if (callBack) callBack();
67+
const res = await client.patch(`/api/bad-words/${badWordId}/status`, { isUsed: false });
68+
if (!res) throw new Error('검열 단어 삭제 도중 에러가 발생했습니다.');
7369
console.log(res);
7470
} catch (error) {
7571
console.error(error);

src/apis/auth.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export const getNewToken = async () => {
3333
try {
3434
const response = await client.post('/api/reissue', {}, { withCredentials: true });
3535
if (!response) throw new Error('getNewToken: no response data');
36+
console.log(response.data);
3637
return response;
3738
} catch (error) {
3839
console.error(error);

src/apis/client.ts

Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,13 @@ const client = axios.create({
99
headers: { 'Content-Type': 'application/json' },
1010
});
1111

12-
// type FailedRequest = {
13-
// resolve: (token: string) => void;
14-
// reject: (error: unknown) => void;
15-
// };
16-
1712
let isRefreshing = false;
18-
// let failedQueue: FailedRequest[] = [];
19-
20-
// const processQueue = (error: unknown, token: string | null = null) => {
21-
// failedQueue.forEach((prom) => {
22-
// if (error) {
23-
// prom.reject(error);
24-
// } else {
25-
// if (token) {
26-
// prom.resolve(token);
27-
// }
28-
// }
29-
// });
30-
31-
// failedQueue = [];
32-
// };
3313

3414
const callReissue = async () => {
3515
try {
3616
const response = await getNewToken();
37-
const newToken = response?.data.accessToken;
17+
if(response?.status !== 200) throw new Error('error while fetching newToken');
18+
const newToken = response?.data.data.accessToken;
3819
return newToken;
3920
} catch (e) {
4021
return Promise.reject(e);
@@ -45,11 +26,10 @@ let retry = false;
4526

4627
client.interceptors.request.use(
4728
(config) => {
48-
console.log('response again', config);
49-
5029
const accessToken = useAuthStore.getState().accessToken;
51-
if (config.url !== '/auth/reissue' && accessToken) {
30+
if (config.url !== '/api/reissue' && accessToken) {
5231
config.headers.Authorization = `Bearer ${accessToken}`;
32+
console.log('interceptor', config);
5333
}
5434
return config;
5535
},
@@ -74,38 +54,21 @@ client.interceptors.response.use(
7454
retry = true;
7555
if (isRefreshing) {
7656
if (isLoggedIn) logout();
77-
// try {
78-
// return new Promise((resolve, reject) => {
79-
// failedQueue.push({
80-
// resolve: (token: string) => {
81-
// originalRequest.headers.Authorization = `Bearer ${token}`;
82-
// resolve(client(originalRequest));
83-
// },
84-
// reject: (err: unknown) => reject(err),
85-
// });
86-
// });
87-
// } catch (e) {
88-
// return Promise.reject(e);
89-
// }
9057
} else {
9158
isRefreshing = true;
9259
try {
9360
const newToken = await callReissue();
9461
setAccessToken(newToken);
95-
// processQueue(null, newToken);
9662
isRefreshing = false;
9763
originalRequest.headers.Authorization = `Bearer ${newToken}`;
9864
return client(originalRequest);
9965
} catch (e) {
100-
// processQueue(e, null);
10166
isRefreshing = false;
10267
if (isLoggedIn) logout();
10368
return Promise.reject(e);
10469
}
10570
}
10671
}
107-
if (isLoggedIn) logout();
108-
console.error('Failed to refresh token', error);
10972
return Promise.reject(error);
11073
},
11174
);

0 commit comments

Comments
 (0)