From faab5b794216cd66a1057451d880b9dccf7197c7 Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Thu, 19 Mar 2026 20:02:29 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=EB=A9=94=EC=9D=B8=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20meta=ED=83=9C=EA=B7=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/home/HomePage.tsx | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/pages/home/HomePage.tsx b/src/pages/home/HomePage.tsx index c8657bf..c2fd2eb 100644 --- a/src/pages/home/HomePage.tsx +++ b/src/pages/home/HomePage.tsx @@ -72,13 +72,22 @@ const HomePage = () => { {isSearching - ? `"${debouncedInput}" 검색 결과 | TechFork` - : `${TAB_MAP[selectedTab]} | TechFork`} + ? `"${debouncedInput}" | TechFork` + : `TechFork | ${TAB_MAP[selectedTab]}`} - + + + +
setModal(false)}> From df79ae32c96e48628591d5a67aeafd919fd20929 Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Thu, 19 Mar 2026 20:03:18 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20index.html=20meta=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/index.html b/index.html index 2a7b8af..840ed6b 100644 --- a/index.html +++ b/index.html @@ -3,26 +3,27 @@ - - - 테크포크 (TechFork) | 기업 테크 블로그 모음 + TechFork | 기업 기술 블로그 모음 + - - - + + @@ -30,7 +31,7 @@ property="og:image" content="https://techfork-fe.vercel.app/sub_logo.png" /> - + From 1fed0f4420b29d716996f192258550a29870d986 Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Thu, 19 Mar 2026 20:04:21 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20=EB=B9=84=EB=85=B8=EC=B6=9C=20?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20robots=20=EB=B0=8F=20noindex=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80(=ED=81=AC=EB=A1=A4?= =?UTF-8?q?=EB=A7=81=20=EC=A0=9C=EC=99=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/robots.txt | 10 ++++++++++ src/pages/login/LoginPage.tsx | 1 + src/pages/mypage/AskPage.tsx | 1 + src/pages/mypage/EditInterestPage.tsx | 1 + src/pages/mypage/MyInterstListPage.tsx | 1 + src/pages/mypage/SettingPage.tsx | 1 + src/pages/onboarding/Onboarding.tsx | 1 + src/pages/onboarding/OnboardingTag.tsx | 1 + 8 files changed, 17 insertions(+) diff --git a/public/robots.txt b/public/robots.txt index bf2e6f9..24a1b3c 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -1,3 +1,13 @@ User-agent: * Allow: / + +Disallow: /login +Disallow: /auth/callback +Disallow: /onboarding +Disallow: /onboarding/tag +Disallow: /edit +Disallow: /interested +Disallow: /setting +Disallow: /ask + Sitemap: https://techfork-fe.vercel.app/sitemap.xml \ No newline at end of file diff --git a/src/pages/login/LoginPage.tsx b/src/pages/login/LoginPage.tsx index 5aaaebd..265e64a 100644 --- a/src/pages/login/LoginPage.tsx +++ b/src/pages/login/LoginPage.tsx @@ -16,6 +16,7 @@ const LoginPage = () => { return ( <> + 로그인 하기 | TechFork { return ( <> + 문의하기 | TechFork { return ( <> + 관심사 수정 | TechFork { return ( <> + 내 활동 | TechFork { return ( <> + 계정 설정 | TechFork { return ( <> + 회원가입 | TechFork { return ( <> + 회원가입 | TechFork Date: Thu, 19 Mar 2026 20:38:58 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20readPost=20=EB=82=99=EA=B4=80?= =?UTF-8?q?=EC=A0=81=20ui=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/features/home/ui/PostCardList.tsx | 18 ++----- src/shared/api/activity.ts | 28 +++++++++-- src/shared/lib/updateReadPostState.ts | 70 +++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 18 deletions(-) create mode 100644 src/shared/lib/updateReadPostState.ts diff --git a/src/features/home/ui/PostCardList.tsx b/src/features/home/ui/PostCardList.tsx index f75fe71..1e5d1ee 100644 --- a/src/features/home/ui/PostCardList.tsx +++ b/src/features/home/ui/PostCardList.tsx @@ -5,10 +5,7 @@ import { CardItem } from "@/shared/ui/CardItem"; import { Loading } from "@/shared/ui/Loading"; import { useCompanyStore } from "../model/useCompanyStore"; import useUserStore from "@/shared/model/useUserStore"; -import type { - CardItemProps, - PostResponseDto, -} from "../api/post.types"; +import type { CardItemProps, PostResponseDto } from "../api/post.types"; import { useRef, useEffect } from "react"; interface PostCardListProps { @@ -51,18 +48,13 @@ const PostCardList = ({ selectedTab }: PostCardListProps) => { (page: PostResponseDto) => page.data.posts, ) ?? []); - // console.log(posts); - return ( <>
    - {posts.map((item: CardItemProps) => ( - - ))} + {posts.map((item: CardItemProps) => { + const postId = item.postId ?? item.id; + return ; + })}
{activeQuery?.isFetchingNextPage && } {selectedTab !== 1 &&
} diff --git a/src/shared/api/activity.ts b/src/shared/api/activity.ts index 84fef9c..507de2e 100644 --- a/src/shared/api/activity.ts +++ b/src/shared/api/activity.ts @@ -3,6 +3,7 @@ import type { ActivityPostType, ReadPostType } from "./activity.types"; import api from "./api"; import { SHARED_QUERY_KEY } from "../consts/queryKeys"; import { updateBookmarkState } from "../lib/updateBookmarkState"; +import { updateReadPostState } from "../lib/updateReadPostState"; import { API_ENDPOINTS, getActivityPostsEndpoint, @@ -101,15 +102,32 @@ export const postReadPosts = async (body: ReadPostType) => { export const usePostReadPost = () => { const queryClient = useQueryClient(); - const postsReadQueryKey = [SHARED_QUERY_KEY.POSTS, SHARED_QUERY_KEY.POSTS_READ] as const; + const postsQueryKey = [SHARED_QUERY_KEY.POSTS] as const; return useMutation({ mutationFn: (body: ReadPostType) => postReadPosts(body), - onSuccess: () => { - queryClient.invalidateQueries({ - queryKey: postsReadQueryKey, + onMutate: async ({ postId }) => { + await queryClient.cancelQueries({ queryKey: postsQueryKey }); + + const previousQueries = queryClient.getQueriesData({ + queryKey: postsQueryKey, + }); + + queryClient.setQueriesData( + { queryKey: postsQueryKey, exact: false }, + (old: any) => updateReadPostState(old, postId), + ); + + return { previousQueries }; + }, + onError: (err, _variables, context) => { + console.log(err); + context?.previousQueries?.forEach(([queryKey, data]) => { + queryClient.setQueryData(queryKey, data); }); }, - onError: err => console.log(err), + onSettled: () => { + queryClient.invalidateQueries({ queryKey: postsQueryKey }); + }, }); }; diff --git a/src/shared/lib/updateReadPostState.ts b/src/shared/lib/updateReadPostState.ts new file mode 100644 index 0000000..fbe6052 --- /dev/null +++ b/src/shared/lib/updateReadPostState.ts @@ -0,0 +1,70 @@ +/** old: 현재 캐시 데이터*/ +/** postId: 읽은 글*/ + +export const updateReadPostState = (old: any, postId: number) => { + if (!old) return old; + + /**patchPost: id또는 postId가 일치하면 viewCount를 증가시킨다.*/ + const patchPost = (post: any) => + post.id === postId || post.postId === postId + ? { ...post, viewCount: (post.viewCount ?? 0) + 1 } + : post; + + if (old.pages && Array.isArray(old.pages)) { + /**무한스크롤 데이터 */ + return { + ...old, + pages: old.pages.map((page: any) => { + const dataKey = page.data?.posts + ? "posts" + : page.data?.readPosts + ? "readPosts" + : page.data?.bookmarks + ? "bookmarks" + : null; + + if (!dataKey || !page.data[dataKey]) return page; + + return { + ...page, + data: { + ...page.data, + [dataKey]: page.data[dataKey].map(patchPost), + }, + }; + }), + }; + } + + if (old.recommendations) { + /** 추천 목록이 root에 있을때*/ + return { + ...old, + recommendations: old.recommendations.map(patchPost), + }; + } + + if (old.data?.recommendations) { + return { + ...old, + data: { + ...old.data, + recommendations: old.data.recommendations.map(patchPost), + }, + }; + } + + if (Array.isArray(old)) { + return old.map(patchPost); + } + + if (old.data && Array.isArray(old.data)) { + /** 그냥 배열*/ + return { + ...old, + data: old.data.map(patchPost), + }; + } + + return old; +}; From 4fac003036d5988b3d832849504abdf8ee1a247d Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Thu, 19 Mar 2026 20:59:00 +0900 Subject: [PATCH 5/8] =?UTF-8?q?feat:readPost=20=20queryKey=20=EC=BA=90?= =?UTF-8?q?=EC=8B=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/shared/api/activity.ts | 24 ++------- src/shared/consts/queryKeys.ts | 1 - src/shared/lib/updateReadPostState.ts | 70 --------------------------- 3 files changed, 3 insertions(+), 92 deletions(-) delete mode 100644 src/shared/lib/updateReadPostState.ts diff --git a/src/shared/api/activity.ts b/src/shared/api/activity.ts index 507de2e..c58ef0a 100644 --- a/src/shared/api/activity.ts +++ b/src/shared/api/activity.ts @@ -3,7 +3,6 @@ import type { ActivityPostType, ReadPostType } from "./activity.types"; import api from "./api"; import { SHARED_QUERY_KEY } from "../consts/queryKeys"; import { updateBookmarkState } from "../lib/updateBookmarkState"; -import { updateReadPostState } from "../lib/updateReadPostState"; import { API_ENDPOINTS, getActivityPostsEndpoint, @@ -106,28 +105,11 @@ export const usePostReadPost = () => { return useMutation({ mutationFn: (body: ReadPostType) => postReadPosts(body), - onMutate: async ({ postId }) => { - await queryClient.cancelQueries({ queryKey: postsQueryKey }); - - const previousQueries = queryClient.getQueriesData({ - queryKey: postsQueryKey, - }); - - queryClient.setQueriesData( - { queryKey: postsQueryKey, exact: false }, - (old: any) => updateReadPostState(old, postId), - ); - - return { previousQueries }; + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: postsQueryKey }); }, - onError: (err, _variables, context) => { + onError: err => { console.log(err); - context?.previousQueries?.forEach(([queryKey, data]) => { - queryClient.setQueryData(queryKey, data); - }); - }, - onSettled: () => { - queryClient.invalidateQueries({ queryKey: postsQueryKey }); }, }); }; diff --git a/src/shared/consts/queryKeys.ts b/src/shared/consts/queryKeys.ts index 0c0b32a..94030ad 100644 --- a/src/shared/consts/queryKeys.ts +++ b/src/shared/consts/queryKeys.ts @@ -1,6 +1,5 @@ export const SHARED_QUERY_KEY = { POSTS: "posts", - POSTS_READ: "read", MY: "my", MY_PROFILE: "profile", MY_INTEREST: "interest", diff --git a/src/shared/lib/updateReadPostState.ts b/src/shared/lib/updateReadPostState.ts deleted file mode 100644 index fbe6052..0000000 --- a/src/shared/lib/updateReadPostState.ts +++ /dev/null @@ -1,70 +0,0 @@ -/** old: 현재 캐시 데이터*/ -/** postId: 읽은 글*/ - -export const updateReadPostState = (old: any, postId: number) => { - if (!old) return old; - - /**patchPost: id또는 postId가 일치하면 viewCount를 증가시킨다.*/ - const patchPost = (post: any) => - post.id === postId || post.postId === postId - ? { ...post, viewCount: (post.viewCount ?? 0) + 1 } - : post; - - if (old.pages && Array.isArray(old.pages)) { - /**무한스크롤 데이터 */ - return { - ...old, - pages: old.pages.map((page: any) => { - const dataKey = page.data?.posts - ? "posts" - : page.data?.readPosts - ? "readPosts" - : page.data?.bookmarks - ? "bookmarks" - : null; - - if (!dataKey || !page.data[dataKey]) return page; - - return { - ...page, - data: { - ...page.data, - [dataKey]: page.data[dataKey].map(patchPost), - }, - }; - }), - }; - } - - if (old.recommendations) { - /** 추천 목록이 root에 있을때*/ - return { - ...old, - recommendations: old.recommendations.map(patchPost), - }; - } - - if (old.data?.recommendations) { - return { - ...old, - data: { - ...old.data, - recommendations: old.data.recommendations.map(patchPost), - }, - }; - } - - if (Array.isArray(old)) { - return old.map(patchPost); - } - - if (old.data && Array.isArray(old.data)) { - /** 그냥 배열*/ - return { - ...old, - data: old.data.map(patchPost), - }; - } - - return old; -}; From 013892ac165ef6b2a04f37bdcef7e8072547a2b8 Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Thu, 19 Mar 2026 21:10:34 +0900 Subject: [PATCH 6/8] =?UTF-8?q?rename:=20=ED=83=88=ED=87=B4=20api=20mypage?= =?UTF-8?q?=ED=8F=B4=EB=8D=94=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/features/Login/api/auth.ts | 2 -- src/{shared => features/mypage}/api/account.ts | 4 ++-- src/features/mypage/ui/LeaveModal.tsx | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) rename src/{shared => features/mypage}/api/account.ts (78%) diff --git a/src/features/Login/api/auth.ts b/src/features/Login/api/auth.ts index 8f739c6..90314aa 100644 --- a/src/features/Login/api/auth.ts +++ b/src/features/Login/api/auth.ts @@ -3,8 +3,6 @@ import api from "@/shared/api/api"; import { API_ENDPOINTS } from "@/shared/consts/endpoints"; -export { postRefreshToken } from "@/shared/api/auth"; - //로그아웃,쿠키 export const postLogout = async () => { const { data } = await api.post(API_ENDPOINTS.auth.logout); diff --git a/src/shared/api/account.ts b/src/features/mypage/api/account.ts similarity index 78% rename from src/shared/api/account.ts rename to src/features/mypage/api/account.ts index 0b88d7c..24abb6b 100644 --- a/src/shared/api/account.ts +++ b/src/features/mypage/api/account.ts @@ -1,6 +1,6 @@ import { useMutation } from "@tanstack/react-query"; -import api from "./api"; -import { API_ENDPOINTS } from "../consts/endpoints"; +import api from "../../../shared/api/api"; +import { API_ENDPOINTS } from "../../../shared/consts/endpoints"; export const deleteAccount = async () => { const { data } = await api.patch(API_ENDPOINTS.users.me.withdrawal); diff --git a/src/features/mypage/ui/LeaveModal.tsx b/src/features/mypage/ui/LeaveModal.tsx index 96f3959..e988d47 100644 --- a/src/features/mypage/ui/LeaveModal.tsx +++ b/src/features/mypage/ui/LeaveModal.tsx @@ -5,7 +5,7 @@ import CheckOff from "@/assets/icons/check_off.svg"; import { useState } from "react"; import useUserStore from "@/shared/model/useUserStore"; import { Button } from "@/shared/ui/button/Button"; -import { useDeleteAccount } from "@/shared/api/account"; +import { useDeleteAccount } from "@/features/mypage/api/account"; interface LeaveModalProps { onClose?: () => void; } From 817f62d376a012252119b9d7659153dccc12ad86 Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Thu, 19 Mar 2026 21:11:58 +0900 Subject: [PATCH 7/8] =?UTF-8?q?feat:=20=EC=A0=88=EB=8C=80=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/features/mypage/api/account.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/features/mypage/api/account.ts b/src/features/mypage/api/account.ts index 24abb6b..fb63ae0 100644 --- a/src/features/mypage/api/account.ts +++ b/src/features/mypage/api/account.ts @@ -1,6 +1,6 @@ +import api from "@/shared/api/api"; +import { API_ENDPOINTS } from "@/shared/consts/endpoints"; import { useMutation } from "@tanstack/react-query"; -import api from "../../../shared/api/api"; -import { API_ENDPOINTS } from "../../../shared/consts/endpoints"; export const deleteAccount = async () => { const { data } = await api.patch(API_ENDPOINTS.users.me.withdrawal); From f22394f3bb062349115ffb29053d342e043d7ccb Mon Sep 17 00:00:00 2001 From: JeonSuna Date: Thu, 19 Mar 2026 21:15:55 +0900 Subject: [PATCH 8/8] build: . --- src/features/Login/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/features/Login/index.ts b/src/features/Login/index.ts index 2f2bbd6..a65546a 100644 --- a/src/features/Login/index.ts +++ b/src/features/Login/index.ts @@ -1,3 +1,3 @@ -export { postLogout, postRefreshToken } from "./api/auth"; +export { postLogout } from "./api/auth"; export type { OAuthProvider } from "./consts/oauth"; export { getOAuthUrl } from "./lib/getOAuthUrl";