diff --git a/.husky/prepare-commit-msg b/.husky/prepare-commit-msg deleted file mode 100755 index 06097bd3..00000000 --- a/.husky/prepare-commit-msg +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh -# -# git prepare-commit-msg hook for automatically prepending an issue key -# from the start of the current branch name to commit messages. - -# check if commit is merge commit or a commit ammend -if [ $2 = "merge" ] || [ $2 = "commit" ]; then - exit -fi -ISSUE_KEY=`git branch | grep -o "\* \(.*/\)*[A-Z]\{2,\}-[0-9]\+" | grep -o "[A-Z]\{2,\}-[0-9]\+"` -if [ $? -ne 0 ]; then - # no issue key in branch, use the default message - exit -fi -# issue key matched from branch prefix, prepend to commit message -TEMP=`mktemp /tmp/commitmsg-XXXXX` -(echo "$(cat $1) [$ISSUE_KEY]") > $TEMP -cat $TEMP > $1 \ No newline at end of file diff --git a/.storybook/preview.js b/.storybook/preview.js index 3ab3169a..2ac2c621 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -3,11 +3,12 @@ import { initialize, mswDecorator } from "msw-storybook-addon"; import "@/styles/globals.css"; import { handlers } from "../mocks/handlers"; import * as NextImage from "next/image"; -import { QueryClientProvider } from "../src/application/queryClient"; +import { QueryClientProvider } from "../src/api/core"; import { Suspense } from "react"; import { RouterContext } from "next/dist/shared/lib/router-context"; -import { ToastContainer, ToastProvider } from "../src/components/common/Toast"; -import { SignUpModal, SignUpModalProvider } from "../src/components/common/Modal"; +import { ToastContainer, ToastProvider } from "../src/common/components/Toast"; +import { SignUpModal, SignUpModalProvider } from "../src/common/components/Modal"; +import { OverlayProvider } from "../src/common/hooks"; // Initialize MSW initialize(); @@ -16,17 +17,19 @@ export const decorators = [ mswDecorator, (Story) => ( - - - -
- - - -
-
-
-
+ + + + +
+ + + +
+
+
+
+
), ]; diff --git a/next.config.js b/next.config.js index efef2d23..8b9a7a8b 100644 --- a/next.config.js +++ b/next.config.js @@ -11,13 +11,7 @@ const IS_DEV = process.env.NODE_ENV === "development"; const IS_PROD = process.env.NODE_ENV === "production"; // The folders containing files importing twin.macro -const includedDirs = [ - path.resolve(__dirname, "./src/application"), - path.resolve(__dirname, "./src/components"), - path.resolve(__dirname, "./src/infra"), - path.resolve(__dirname, "./src/pages"), - path.resolve(__dirname, "./src/styles"), -]; +const includedDirs = [path.resolve(__dirname, "./src")]; // eslint-disable-next-line @typescript-eslint/no-var-requires const withPWA = require("next-pwa")({ diff --git a/src/api/account/index.ts b/src/api/account/index.ts new file mode 100644 index 00000000..ee4efab7 --- /dev/null +++ b/src/api/account/index.ts @@ -0,0 +1,2 @@ +export * from "./useGetMyAccount"; +export * from "./useLogout"; diff --git a/src/api/account/useGetMyAccount.ts b/src/api/account/useGetMyAccount.ts new file mode 100644 index 00000000..d071e237 --- /dev/null +++ b/src/api/account/useGetMyAccount.ts @@ -0,0 +1,19 @@ +import { useQuery, useQueryClient } from "@tanstack/react-query"; + +import { api } from "../core"; + +export const useGetMyAccount = () => { + const queryClient = useQueryClient(); + return useQuery({ + suspense: false, + queryKey: useGetMyAccount.queryKey, + queryFn: useGetMyAccount.queryFn, + onError: () => { + queryClient.setQueryData(useGetMyAccount.queryKey, null); + }, + }); +}; + +useGetMyAccount.queryKey = ["getMyAccount"] as const; + +useGetMyAccount.queryFn = () => api.account.getMyAccount(); diff --git a/src/api/account/useLogout.ts b/src/api/account/useLogout.ts new file mode 100644 index 00000000..ce655f91 --- /dev/null +++ b/src/api/account/useLogout.ts @@ -0,0 +1,15 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; + +import { api } from "../core"; +import { useGetMyAccount } from "./useGetMyAccount"; + +export const useLogout = () => { + const queryClient = useQueryClient(); + + return useMutation(api.auth.logout, { + onSuccess: () => { + api.auth.deleteAccessToken(); + queryClient.setQueryData(useGetMyAccount.queryKey, null); + }, + }); +}; diff --git a/src/api/collection/index.ts b/src/api/collection/index.ts new file mode 100644 index 00000000..47f1a482 --- /dev/null +++ b/src/api/collection/index.ts @@ -0,0 +1,4 @@ +export * from "./useDeleteMemeFromCollection"; +export * from "./useGetCollectionCheck"; +export * from "./usePostMemeToCollection"; +export * from "./usePostMemeToSharedCollection"; diff --git a/src/api/collection/useDeleteMemeFromCollection.ts b/src/api/collection/useDeleteMemeFromCollection.ts new file mode 100644 index 00000000..72c6d328 --- /dev/null +++ b/src/api/collection/useDeleteMemeFromCollection.ts @@ -0,0 +1,40 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; + +import { useGetMyAccount } from "../account"; +import { api } from "../core"; +import { useGetCollectionCheck } from "./useGetCollectionCheck"; +/** + * 콜렉션 삭제 API + */ +export const useDeleteMemeFromCollection = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: api.collection.deleteMemeFromCollection, + onMutate: async (deletedMemeId) => { + await queryClient.cancelQueries({ + queryKey: useGetCollectionCheck.queryKey(deletedMemeId), + }); + + const previousCollectionInfo = queryClient.getQueryData( + useGetCollectionCheck.queryKey(deletedMemeId), + ); + + queryClient.setQueryData(useGetCollectionCheck.queryKey(deletedMemeId), { + collectionId: null, + isAdded: false, + }); + + return { previousCollectionInfo, deletedMemeId }; + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: useGetMyAccount.queryKey }); + }, + onError: (_, deletedMemeId, context) => { + queryClient.setQueryData( + useGetCollectionCheck.queryKey(deletedMemeId), + context?.previousCollectionInfo, + ); + }, + }); +}; diff --git a/src/api/collection/useGetCollectionCheck.ts b/src/api/collection/useGetCollectionCheck.ts new file mode 100644 index 00000000..9e7faf2e --- /dev/null +++ b/src/api/collection/useGetCollectionCheck.ts @@ -0,0 +1,29 @@ +import type { QueryClient, UseQueryOptions } from "@tanstack/react-query"; +import { useQuery } from "@tanstack/react-query"; + +import { api } from "../core"; + +/** + * 밈별 콜렉션 정보 API + */ +export const useGetCollectionCheck = ( + memeId: number, + options?: Pick, +) => { + return useQuery({ + queryKey: useGetCollectionCheck.queryKey(memeId), + queryFn: () => useGetCollectionCheck.queryFn(memeId), + suspense: false, + ...options, + }); +}; + +useGetCollectionCheck.queryKey = (memeId: number) => ["getCollectionCheck", memeId] as const; + +useGetCollectionCheck.queryFn = (memeId: number) => api.collection.getCollectionCheck(memeId); + +useGetCollectionCheck.prefetchQuery = (memeId: number, queryClient: QueryClient) => + queryClient.prefetchQuery({ + queryKey: useGetCollectionCheck.queryKey(memeId), + queryFn: () => useGetCollectionCheck.queryFn(memeId), + }); diff --git a/src/api/collection/usePostMemeToCollection.ts b/src/api/collection/usePostMemeToCollection.ts new file mode 100644 index 00000000..59121c6a --- /dev/null +++ b/src/api/collection/usePostMemeToCollection.ts @@ -0,0 +1,40 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; + +import { useGetMyAccount } from "../account"; +import { api } from "../core"; +import { useGetCollectionCheck } from "./useGetCollectionCheck"; +/** + * 콜렉션 저장 API + */ +export const usePostMemeToCollection = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: api.collection.postMemeToCollection, + onMutate: async (newMemeId) => { + await queryClient.cancelQueries({ + queryKey: useGetCollectionCheck.queryKey(newMemeId), + }); + + const previousCollectionInfo = queryClient.getQueryData( + useGetCollectionCheck.queryKey(newMemeId), + ); + + queryClient.setQueryData(useGetCollectionCheck.queryKey(newMemeId), { + collectionId: 1, + isAdded: true, + }); + + return { previousCollectionInfo, newMemeId }; + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: useGetMyAccount.queryKey }); + }, + onError: (_, newMemeId, context) => { + queryClient.setQueryData( + useGetCollectionCheck.queryKey(newMemeId), + context?.previousCollectionInfo, + ); + }, + }); +}; diff --git a/src/api/collection/usePostMemeToSharedCollection.ts b/src/api/collection/usePostMemeToSharedCollection.ts new file mode 100644 index 00000000..63bcb3bd --- /dev/null +++ b/src/api/collection/usePostMemeToSharedCollection.ts @@ -0,0 +1,23 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; + +import { useGetMyAccount } from "../account"; +import { api } from "../core"; +import { useGetMemesByCollectionId } from "../meme"; + +export const usePostMemeToSharedCollection = ({ + memeId, + sharedId, +}: { + memeId: number; + sharedId: number; +}) => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: () => api.collection.postMemeToSharedCollection(memeId), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: useGetMemesByCollectionId.queryKey(sharedId) }); + queryClient.invalidateQueries({ queryKey: useGetMyAccount.queryKey }); + }, + }); +}; diff --git a/src/infra/api/index.ts b/src/api/core/axios.ts similarity index 84% rename from src/infra/api/index.ts rename to src/api/core/axios.ts index a8b1313c..e6e03c1a 100644 --- a/src/infra/api/index.ts +++ b/src/api/core/axios.ts @@ -2,11 +2,10 @@ import axios from "axios"; import { AccountApi } from "@/infra/api/account"; import { AuthApi } from "@/infra/api/auth"; - -import { CollectionApi } from "./collection"; -import { MemeApi } from "./meme"; -import { SearchApi } from "./search"; -import { TagApi } from "./tags"; +import { CollectionApi } from "@/infra/api/collection"; +import { MemeApi } from "@/infra/api/meme"; +import { SearchApi } from "@/infra/api/search"; +import { TagApi } from "@/infra/api/tags"; export const axiosBasic = axios.create({ baseURL: `${process.env.NEXT_PUBLIC_API_URL}`, diff --git a/src/api/core/index.ts b/src/api/core/index.ts new file mode 100644 index 00000000..6b34748d --- /dev/null +++ b/src/api/core/index.ts @@ -0,0 +1,5 @@ +export * from "./axios"; +export * from "./query-client"; +export * from "./queryKey"; +export * from "./useCoreInfiniteQuery"; +export * from "./useSuspensedQuery"; diff --git a/src/application/queryClient.tsx b/src/api/core/query-client.tsx similarity index 85% rename from src/application/queryClient.tsx rename to src/api/core/query-client.tsx index 78f2a1f6..8b1c46d7 100644 --- a/src/application/queryClient.tsx +++ b/src/api/core/query-client.tsx @@ -5,9 +5,13 @@ import { QueryClientProvider as TanStackQueryClientProvider, } from "@tanstack/react-query"; import { ReactQueryDevtools } from "@tanstack/react-query-devtools"; -import type { ReactNode } from "react"; +import type { ComponentProps, ReactNode } from "react"; import { useState } from "react"; +export interface DefaultPageProps { + hydrateState: ComponentProps["hydrateState"]; +} + interface Props { hydrateState?: DehydratedState; children: ReactNode; diff --git a/src/application/hooks/api/core/queryKey.ts b/src/api/core/queryKey.ts similarity index 100% rename from src/application/hooks/api/core/queryKey.ts rename to src/api/core/queryKey.ts diff --git a/src/application/hooks/api/core/useCoreInfiniteQuery.ts b/src/api/core/useCoreInfiniteQuery.ts similarity index 100% rename from src/application/hooks/api/core/useCoreInfiniteQuery.ts rename to src/api/core/useCoreInfiniteQuery.ts diff --git a/src/application/hooks/api/core/useSuspensedQuery.ts b/src/api/core/useSuspensedQuery.ts similarity index 60% rename from src/application/hooks/api/core/useSuspensedQuery.ts rename to src/api/core/useSuspensedQuery.ts index 57e8ec1c..d3fc6440 100644 --- a/src/application/hooks/api/core/useSuspensedQuery.ts +++ b/src/api/core/useSuspensedQuery.ts @@ -1,13 +1,41 @@ -import type { QueryFunction, QueryKey } from "@tanstack/react-query"; +import type { + QueryFunction, + QueryKey, + UseQueryOptions, + UseQueryResult, +} from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query"; -import type { - BaseSuspendedUseQueryResult, - SuspendedUseQueryOptions, - SuspendedUseQueryResultOnIdle, - SuspendedUseQueryResultOnSuccess, -} from "@/application/hooks/api/core/types"; +export interface BaseSuspendedUseQueryResult + extends Omit< + UseQueryResult, + "data" | "status" | "error" | "isLoading" | "isError" | "isFetching" + > { + data: TData; + status: "success" | "idle"; +} + +export type SuspendedUseQueryResultOnSuccess = BaseSuspendedUseQueryResult & { + status: "success"; + isSuccess: true; + isIdle: false; +}; +export type SuspendedUseQueryResultOnIdle = BaseSuspendedUseQueryResult & { + status: "idle"; + isSuccess: false; + isIdle: true; +}; + +export type SuspendedUseQueryOptions< + TQueryFnData = unknown, + TError = unknown, + TData = TQueryFnData, + TQueryKey extends QueryKey = QueryKey, +> = Omit, "suspense">; +export type QuerySelectOption any> = ( + data: Awaited>, +) => Result; /** * @desc suspense 사용 시 non-nullable data 이도록 wrapping * @link https://github.com/toss/slash/blob/main/packages/react/react-query/src/hooks/useSuspendedQuery.ts diff --git a/src/api/meme/index.ts b/src/api/meme/index.ts new file mode 100644 index 00000000..fa871a7b --- /dev/null +++ b/src/api/meme/index.ts @@ -0,0 +1,3 @@ +export * from "./useGetMemeDetailById"; +export * from "./useGetMemesByCollectionId"; +export * from "./useGetMemesBySort"; diff --git a/src/api/meme/useGetMemeDetailById.ts b/src/api/meme/useGetMemeDetailById.ts new file mode 100644 index 00000000..2d661ff8 --- /dev/null +++ b/src/api/meme/useGetMemeDetailById.ts @@ -0,0 +1,24 @@ +import type { QueryClient } from "@tanstack/react-query"; + +import { api, useSuspendedQuery } from "../core"; + +/** + * 밈 상세 조회 API + * @param id 상세 조회할 밈 id + */ +export const useGetMemeDetailById = (id: string) => { + const { data, isRefetching } = useSuspendedQuery({ + queryKey: useGetMemeDetailById.queryKey(id), + queryFn: () => useGetMemeDetailById.queryFn(id), + staleTime: Infinity, + }); + + return { ...data, isRefetching }; +}; + +useGetMemeDetailById.queryKey = (id: string) => ["getMemeDetailById", id] as const; + +useGetMemeDetailById.queryFn = (id: string) => api.meme.getMemeDetailById(id); + +useGetMemeDetailById.fetchQuery = (id: string, queryClient: QueryClient) => + queryClient.fetchQuery(useGetMemeDetailById.queryKey(id), () => api.meme.getMemeDetailById(id)); diff --git a/src/api/meme/useGetMemesByCollectionId.ts b/src/api/meme/useGetMemesByCollectionId.ts new file mode 100644 index 00000000..56729a97 --- /dev/null +++ b/src/api/meme/useGetMemesByCollectionId.ts @@ -0,0 +1,38 @@ +import type { QueryFunctionContext } from "@tanstack/react-query"; + +import { api, CORE_QUERY_KEY, useCoreInfiniteQuery } from "../core"; + +const PAGE_SIZE = 10; + +/** + * 콜렉션 별 밈 리스트 API + * + * NOTE + * 현재 하나의 콜렉션만이 존재(즉, collectionId가 하나) + * 추후에 여러개의 콜렉션을 다룰 예정(즉, collectionId에 여러개) + * + * 마이페이지(/mypage)에서는 무한스크롤 적용 안함 + * 콜렉션 페이지(/collect) 페이지에서 무한 스크롤 적용함 + */ +export const useGetMemesByCollectionId = (collectionId: number) => { + const { data, isEmpty, isFetchingNextPage, fetchNextPage } = useCoreInfiniteQuery( + useGetMemesByCollectionId.queryKey(collectionId), + ({ pageParam = 0 }: QueryFunctionContext) => + api.meme.getMemesByCollectionId({ collectionId, offset: pageParam, limit: PAGE_SIZE }), + PAGE_SIZE, + { + staleTime: 1000 * 5, + select: (data) => { + return { + pages: data.pages.map((page) => ({ data: page.memes })), + pageParams: data.pageParams, + }; + }, + }, + ); + + return { data, isEmpty, isFetchingNextPage, fetchNextPage }; +}; + +useGetMemesByCollectionId.queryKey = (collectionId: number | null) => + [CORE_QUERY_KEY.infiniteMemeList, "getMemesByCollectionId", collectionId] as const; diff --git a/src/api/meme/useGetMemesBySort.ts b/src/api/meme/useGetMemesBySort.ts new file mode 100644 index 00000000..93d5cfad --- /dev/null +++ b/src/api/meme/useGetMemesBySort.ts @@ -0,0 +1,32 @@ +import type { QueryFunctionContext } from "@tanstack/react-query"; + +import { api, CORE_QUERY_KEY, useCoreInfiniteQuery } from "../core"; + +const PAGE_SIZE = 10; + +const types = { share: "shareCount", recent: "createdDate", popular: "viewCount", user: "user" }; + +/** + * 밈 type 에 따른 리스트 api + * @param sort 밈 리스트 type : share,recent,popular + */ +export const useGetMemesBySort = (sort: keyof typeof types) => { + const { data, isEmpty, isFetchingNextPage, fetchNextPage } = useCoreInfiniteQuery( + useGetMemesBySort.queryKey(sort), + ({ pageParam = 0 }: QueryFunctionContext) => + api.meme.getMemesBySort({ offset: pageParam, limit: PAGE_SIZE, sort: types[sort] }), + PAGE_SIZE, + { + select: (data) => { + return { + pages: data.pages.map((page) => ({ data: page.memes })), + pageParams: data.pageParams, + }; + }, + }, + ); + + return { data, isEmpty, isFetchingNextPage, fetchNextPage }; +}; +useGetMemesBySort.queryKey = (sort: string) => + [CORE_QUERY_KEY.infiniteMemeList, "getMemesBySort", sort] as const; diff --git a/src/api/search/index.ts b/src/api/search/index.ts new file mode 100644 index 00000000..ef658755 --- /dev/null +++ b/src/api/search/index.ts @@ -0,0 +1,3 @@ +export * from "./useGetMemesByKeyword"; +export * from "./useGetMemesByTag"; +export * from "./useGetMemesFromCollectionByKeyword"; diff --git a/src/api/search/useGetMemesByKeyword.ts b/src/api/search/useGetMemesByKeyword.ts new file mode 100644 index 00000000..ace7a461 --- /dev/null +++ b/src/api/search/useGetMemesByKeyword.ts @@ -0,0 +1,35 @@ +import type { QueryFunctionContext } from "@tanstack/react-query"; + +import { api, CORE_QUERY_KEY, useCoreInfiniteQuery } from "../core"; + +const PAGE_SIZE = 20; + +/** + * keyword 밈 검색 API + * @param keyword 검색할 keyword + * @returns + * data - 밈 검색 결과 + * isEmpty - 밈 검색 결과가 없는 경우 true + */ +export const useGetMemesByKeyword = (keyword: string) => { + const { data, isEmpty, isFetchingNextPage, fetchNextPage } = useCoreInfiniteQuery( + useGetMemesByKeyword.queryKey(keyword), + ({ pageParam = 0 }: QueryFunctionContext) => + api.search.getMemesByKeyword({ keyword, offset: pageParam, limit: PAGE_SIZE }), + PAGE_SIZE, + { + enabled: !!keyword, + select: (data) => { + return { + pages: data.pages.map((page) => ({ data: page.memes })), + pageParams: data.pageParams, + }; + }, + }, + ); + + return { data, isEmpty, isFetchingNextPage, fetchNextPage }; +}; + +useGetMemesByKeyword.queryKey = (keyword: string) => + [CORE_QUERY_KEY.infiniteMemeList, "getMemesByKeyword", keyword] as const; diff --git a/src/api/search/useGetMemesByTag.ts b/src/api/search/useGetMemesByTag.ts new file mode 100644 index 00000000..61b32598 --- /dev/null +++ b/src/api/search/useGetMemesByTag.ts @@ -0,0 +1,44 @@ +import type { QueryClient, QueryFunctionContext } from "@tanstack/react-query"; +import { useInfiniteQuery } from "@tanstack/react-query"; + +import { api, CORE_QUERY_KEY } from "../core"; + +const PAGE_SIZE = 20; + +/** + * tag 밈 검색 API + * @param tag 검색할 tag + * @returns + * data - 밈 검색 결과 + * isEmpty - 밈 검색 결과가 없는 경우 true + */ +export const useGetMemesByTag = (tag: string) => { + const { data, isFetchingNextPage, fetchNextPage } = useInfiniteQuery( + useGetMemesByTag.queryKey(tag), + ({ pageParam = 0 }: QueryFunctionContext) => + api.search.getMemesByTag({ keyword: tag, offset: pageParam, limit: PAGE_SIZE }), + { + getNextPageParam: (lastPage, allPages) => { + const { count } = lastPage; + const isLastPage = count < PAGE_SIZE; + const offset = count * (allPages.length - 1); + return isLastPage ? undefined : offset + PAGE_SIZE; + }, + enabled: !!tag, + }, + ); + + const memes = data?.pages.flatMap(({ memes }) => memes) || []; + const totalCount = data?.pages[0].totalCount; + const isEmpty = !memes.length; + + return { data: memes, totalCount, isEmpty, isFetchingNextPage, fetchNextPage }; +}; + +useGetMemesByTag.queryKey = (tag: string) => + [CORE_QUERY_KEY.infiniteMemeList, "getMemesByTag", tag] as const; + +useGetMemesByTag.fetchInfiniteQuery = (tag: string, queryClient: QueryClient) => + queryClient.fetchInfiniteQuery(useGetMemesByTag.queryKey(tag), ({ pageParam = 0 }) => + api.search.getMemesByTag({ keyword: tag, offset: pageParam, limit: PAGE_SIZE }), + ); diff --git a/src/api/search/useGetMemesFromCollectionByKeyword.ts b/src/api/search/useGetMemesFromCollectionByKeyword.ts new file mode 100644 index 00000000..57219128 --- /dev/null +++ b/src/api/search/useGetMemesFromCollectionByKeyword.ts @@ -0,0 +1,53 @@ +import type { QueryFunctionContext } from "@tanstack/react-query"; + +import { api, CORE_QUERY_KEY, useCoreInfiniteQuery } from "../core"; + +const PAGE_SIZE = 20; + +export const useGetMemesFromCollectionByKeyword = ({ + keyword, + collectionId, +}: { + keyword: string; + collectionId: number; +}) => { + const { data, isEmpty, isFetchingNextPage, fetchNextPage } = useCoreInfiniteQuery( + useGetMemesFromCollectionByKeyword.queryKey({ + keyword: keyword, + collectionId: collectionId, + }), + ({ pageParam = 0 }: QueryFunctionContext) => + api.search.getMemesFromCollectionByKeyword({ + keyword: keyword, + collectionId, + offset: pageParam, + limit: PAGE_SIZE, + }), + PAGE_SIZE, + { + enabled: !!keyword && !!collectionId, + keepPreviousData: true, + select: (data) => { + return { + pages: data.pages.map((page) => ({ data: page.memes })), + pageParams: data.pageParams, + }; + }, + }, + ); + + return { data, isEmpty, isFetchingNextPage, fetchNextPage }; +}; + +useGetMemesFromCollectionByKeyword.queryKey = ({ + keyword, + collectionId, +}: { + keyword: string; + collectionId: number; +}) => + [ + CORE_QUERY_KEY.infiniteMemeList, + "getMemesFromCollectionByKeyword", + { keyword, collectionId }, + ] as const; diff --git a/src/api/tag/index.ts b/src/api/tag/index.ts new file mode 100644 index 00000000..321007cc --- /dev/null +++ b/src/api/tag/index.ts @@ -0,0 +1,8 @@ +export * from "./useDeleteFavoriteTag"; +export * from "./useGetCategoryWithTag"; +export * from "./useGetFavoriteTags"; +export * from "./useGetMemeTagsById"; +export * from "./useGetPopularTags"; +export * from "./useGetTagInfo"; +export * from "./useGetTagSearch"; +export * from "./usePostFavoriteTag"; diff --git a/src/api/tag/useDeleteFavoriteTag.ts b/src/api/tag/useDeleteFavoriteTag.ts new file mode 100644 index 00000000..65047d83 --- /dev/null +++ b/src/api/tag/useDeleteFavoriteTag.ts @@ -0,0 +1,49 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; + +import { delay } from "@/common/utils"; + +import { api } from "../core"; +import { useGetFavoriteTags } from "./useGetFavoriteTags"; +import { useGetTagInfo } from "./useGetTagInfo"; + +export const useDeleteFavoriteTag = (wait = 0) => { + const queryClient = useQueryClient(); + + const controller = new AbortController(); + + const mutation = useMutation({ + mutationFn: (id: number) => api.tags.deleteFavoriteTag(id, controller.signal), + onMutate: async (id) => { + await queryClient.cancelQueries({ queryKey: useGetTagInfo.queryKey(id) }); + await queryClient.cancelQueries({ queryKey: useGetFavoriteTags.queryKey }); + + const previousFavoriteCategory = queryClient.getQueryData(useGetFavoriteTags.queryKey); + const previousTagInfo = queryClient.getQueryData(useGetTagInfo.queryKey(id)) as Awaited< + ReturnType + >; + + queryClient.setQueryData>>( + useGetFavoriteTags.queryKey, + (old) => { + if (!old) return; + const newTags = old.tags.filter((tag) => tag.tagId !== id); + return { tags: newTags }; + }, + ); + + queryClient.setQueryData(useGetTagInfo.queryKey(id), (old) => ({ + ...(old as Awaited>), + isFav: false, + })); + + await delay(wait); + return { previousTagInfo, previousFavoriteCategory }; + }, + + onError: (err, id, context) => { + queryClient.setQueryData(useGetTagInfo.queryKey(id), context?.previousTagInfo); + queryClient.setQueryData(useGetFavoriteTags.queryKey, context?.previousFavoriteCategory); + }, + }); + return { ...mutation, onCancel: () => controller.abort() }; +}; diff --git a/src/api/tag/useGetCategoryWithTag.ts b/src/api/tag/useGetCategoryWithTag.ts new file mode 100644 index 00000000..658df775 --- /dev/null +++ b/src/api/tag/useGetCategoryWithTag.ts @@ -0,0 +1,23 @@ +import { useQuery } from "@tanstack/react-query"; + +import type { QuerySelectOption } from "../core"; +import { api } from "../core"; + +/** + * @desc + * Tag Category 에 즐겨찾기를 제외한 태그들 + */ +export const useGetCategoryWithTag = ({ + select, +}: { + select: QuerySelectOption; +}) => + useQuery({ + queryKey: useGetCategoryWithTag.queryKey, + queryFn: useGetCategoryWithTag.queryFn, + select, + }); + +useGetCategoryWithTag.queryKey = ["getCategoryWithTags"] as const; + +useGetCategoryWithTag.queryFn = () => api.tags.getCategoryWithTags(); diff --git a/src/api/tag/useGetFavoriteTags.ts b/src/api/tag/useGetFavoriteTags.ts new file mode 100644 index 00000000..851690e6 --- /dev/null +++ b/src/api/tag/useGetFavoriteTags.ts @@ -0,0 +1,20 @@ +import type { UseQueryOptions } from "@tanstack/react-query"; +import { useQuery } from "@tanstack/react-query"; + +import { api } from "../core"; + +export const useGetFavoriteTags = ( + options: Pick = { enabled: false }, +) => { + const { data } = useQuery({ + queryKey: useGetFavoriteTags.queryKey, + queryFn: useGetFavoriteTags.queryFn, + ...options, + }); + + return { favoriteTags: data?.tags }; +}; + +useGetFavoriteTags.queryKey = ["getFavoriteTags"] as const; + +useGetFavoriteTags.queryFn = () => api.tags.getFavoriteTags(); diff --git a/src/api/tag/useGetMemeTagsById.ts b/src/api/tag/useGetMemeTagsById.ts new file mode 100644 index 00000000..0b8a8ca1 --- /dev/null +++ b/src/api/tag/useGetMemeTagsById.ts @@ -0,0 +1,19 @@ +import type { QueryClient } from "@tanstack/react-query"; + +import { api, useSuspendedQuery } from "../core"; + +export const useGetMemeTagsById = (id: string) => { + const { data, ...rest } = useSuspendedQuery({ + queryKey: useGetMemeTagsById.queryKey(id), + queryFn: () => useGetMemeTagsById.queryFn(id), + staleTime: Infinity, + }); + return { ...data, ...rest }; +}; + +useGetMemeTagsById.queryKey = (id: string) => ["getMemeTagsById", id] as const; + +useGetMemeTagsById.queryFn = (id: string) => api.tags.getMemeTagsById(id); + +useGetMemeTagsById.fetchQuery = (id: string, queryClient: QueryClient) => + queryClient.fetchQuery(useGetMemeTagsById.queryKey(id), () => useGetMemeTagsById.queryFn(id)); diff --git a/src/api/tag/useGetPopularTags.ts b/src/api/tag/useGetPopularTags.ts new file mode 100644 index 00000000..60a3cfbf --- /dev/null +++ b/src/api/tag/useGetPopularTags.ts @@ -0,0 +1,19 @@ +import { useQuery } from "@tanstack/react-query"; + +import { api } from "../core"; + +/** + * 인기 태그 조회 API + */ +export const useGetPopularTags = () => { + const { data } = useQuery({ + queryKey: useGetPopularTags.queryKey, + queryFn: useGetPopularTags.queryFn, + }); + + return { ...data }; +}; + +useGetPopularTags.queryKey = ["getPopularTags"] as const; + +useGetPopularTags.queryFn = () => api.tags.getPopularTags(); diff --git a/src/api/tag/useGetTagInfo.ts b/src/api/tag/useGetTagInfo.ts new file mode 100644 index 00000000..05ec69a1 --- /dev/null +++ b/src/api/tag/useGetTagInfo.ts @@ -0,0 +1,23 @@ +import type { QueryClient, UseQueryOptions } from "@tanstack/react-query"; +import { useQuery } from "@tanstack/react-query"; + +import { api } from "../core"; + +export const useGetTagInfo = ( + tagId: number, + options: Pick = { enabled: true }, +) => { + return useQuery({ + queryKey: useGetTagInfo.queryKey(tagId), + queryFn: () => useGetTagInfo.queryFn(tagId), + staleTime: 0, + ...options, + }); +}; + +useGetTagInfo.queryKey = (tagId: number) => ["getTagInfo", tagId] as const; + +useGetTagInfo.queryFn = (tagId: number) => api.tags.getTagInfo(tagId); + +useGetTagInfo.fetchQuery = (tagId: number, queryClient: QueryClient) => + queryClient.fetchQuery(useGetTagInfo.queryKey(tagId), () => useGetTagInfo.queryFn(tagId)); diff --git a/src/api/tag/useGetTagSearch.ts b/src/api/tag/useGetTagSearch.ts new file mode 100644 index 00000000..c6224f1b --- /dev/null +++ b/src/api/tag/useGetTagSearch.ts @@ -0,0 +1,21 @@ +import { useQuery } from "@tanstack/react-query"; + +import { api } from "../core"; + +/** + * 태그 자동완성 API + * @param value 검색어 + */ +export const useGetTagSearch = (value: string) => { + const { data, ...rest } = useQuery({ + queryKey: useGetTagSearch.queryKey(value), + queryFn: () => useGetTagSearch.queryFn(value), + keepPreviousData: true, + enabled: !!value, + }); + return { autoCompletedTags: data?.tags, ...rest }; +}; + +useGetTagSearch.queryKey = (value: string) => ["getTagSearch", value] as const; + +useGetTagSearch.queryFn = (value: string) => api.tags.getTagSearch(value); diff --git a/src/api/tag/usePostFavoriteTag.ts b/src/api/tag/usePostFavoriteTag.ts new file mode 100644 index 00000000..8cd9823f --- /dev/null +++ b/src/api/tag/usePostFavoriteTag.ts @@ -0,0 +1,48 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; + +import { api } from "../core"; +import { useGetFavoriteTags } from "./useGetFavoriteTags"; +import { useGetTagInfo } from "./useGetTagInfo"; + +export const usePostFavoriteTag = () => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: api.tags.postFavoriteTag, + onMutate: async ({ tagId, name }) => { + await queryClient.cancelQueries({ queryKey: useGetTagInfo.queryKey(tagId) }); + + const previousTagInfo = queryClient.getQueryData(useGetTagInfo.queryKey(tagId)) as Awaited< + ReturnType + >; + + queryClient.setQueryData>>( + useGetFavoriteTags.queryKey, + (old) => { + if (!old) return; + const newTags = [ + ...old.tags, + { + tagId: tagId, + name: name, + isFav: true, + }, + ]; + + return { tags: newTags }; + }, + ); + + queryClient.setQueryData(useGetTagInfo.queryKey(tagId), (old) => ({ + ...(old as Awaited>), + isFav: true, + })); + + return { previousTagInfo }; + }, + + onError: (err, { tagId }, context) => { + queryClient.setQueryData(useGetTagInfo.queryKey(tagId), context?.previousTagInfo); + }, + }); +}; diff --git a/src/application/hooks/api/account/index.ts b/src/application/hooks/api/account/index.ts deleted file mode 100644 index 557bb349..00000000 --- a/src/application/hooks/api/account/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; - -import { api } from "@/infra/api"; - -import { QUERY_KEYS } from "./queryKey"; - -export const useGetMyAccount = () => { - const queryClient = useQueryClient(); - return useQuery({ - suspense: false, - queryKey: QUERY_KEYS.getMyAccount, - queryFn: api.account.getMyAccount, - onError: () => { - queryClient.setQueryData(QUERY_KEYS.getMyAccount, null); - }, - }); -}; - -export const useLogout = () => { - const queryClient = useQueryClient(); - return useMutation(api.auth.logout, { - onSuccess: () => { - api.auth.deleteAccessToken(); - queryClient.setQueryData(QUERY_KEYS.getMyAccount, null); - }, - }); -}; diff --git a/src/application/hooks/api/account/queryKey.ts b/src/application/hooks/api/account/queryKey.ts deleted file mode 100644 index 6bce374f..00000000 --- a/src/application/hooks/api/account/queryKey.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const QUERY_KEYS = { - getMyAccount: ["getMyAccount"], -} as const; diff --git a/src/application/hooks/api/collection/index.ts b/src/application/hooks/api/collection/index.ts deleted file mode 100644 index 02215223..00000000 --- a/src/application/hooks/api/collection/index.ts +++ /dev/null @@ -1,119 +0,0 @@ -import type { QueryClient, UseQueryOptions } from "@tanstack/react-query"; -import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; - -import { api } from "@/infra/api"; -import type { GetCollectionCheckResponse } from "@/infra/api/collection/types"; - -import { QUERY_KEYS as ACCOUNT_QUERY_KEYS } from "../account/queryKey"; -import { QUERY_KEYS as MEME_QUERY_KEYS } from "../meme/queryKey"; -import { QUERY_KEYS } from "./queryKey"; - -/** - * 밈별 콜렉션 정보 API - */ -export const useGetCollectionCheck = ( - memeId: number, - options?: UseQueryOptions, -) => { - return useQuery({ - queryKey: QUERY_KEYS.getCollectionCheck(memeId), - queryFn: () => api.collection.getCollectionCheck(memeId), - suspense: false, - ...options, - }); -}; -export const prefetchCollectionCheck = (memeId: number, queryClient: QueryClient) => - queryClient.prefetchQuery({ - queryKey: QUERY_KEYS.getCollectionCheck(memeId), - queryFn: () => api.collection.getCollectionCheck(memeId), - }); - -/** - * 콜렉션 삭제 API - */ -export const useDeleteMemeFromCollection = () => { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: api.collection.deleteMemeFromCollection, - onMutate: async (deletedMemeId) => { - await queryClient.cancelQueries({ - queryKey: QUERY_KEYS.getCollectionCheck(deletedMemeId), - }); - - const previousCollectionInfo = queryClient.getQueryData( - QUERY_KEYS.getCollectionCheck(deletedMemeId), - ); - - queryClient.setQueryData(QUERY_KEYS.getCollectionCheck(deletedMemeId), { - collectionId: null, - isAdded: false, - }); - - return { previousCollectionInfo, deletedMemeId }; - }, - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ACCOUNT_QUERY_KEYS.getMyAccount }); - }, - onError: (_, deletedMemeId, context) => { - queryClient.setQueryData( - QUERY_KEYS.getCollectionCheck(deletedMemeId), - context?.previousCollectionInfo, - ); - }, - }); -}; - -/** - * 콜렉션 저장 API - */ -export const usePostMemeToCollection = () => { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: api.collection.postMemeToCollection, - onMutate: async (newMemeId) => { - await queryClient.cancelQueries({ - queryKey: QUERY_KEYS.getCollectionCheck(newMemeId), - }); - - const previousCollectionInfo = queryClient.getQueryData( - QUERY_KEYS.getCollectionCheck(newMemeId), - ); - - queryClient.setQueryData(QUERY_KEYS.getCollectionCheck(newMemeId), { - collectionId: 1, - isAdded: true, - }); - - return { previousCollectionInfo, newMemeId }; - }, - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ACCOUNT_QUERY_KEYS.getMyAccount }); - }, - onError: (_, newMemeId, context) => { - queryClient.setQueryData( - QUERY_KEYS.getCollectionCheck(newMemeId), - context?.previousCollectionInfo, - ); - }, - }); -}; - -export const usePostMemeToSharedCollection = ({ - memeId, - sharedId, -}: { - memeId: number; - sharedId: number; -}) => { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: () => api.collection.postMemeToSharedCollection(memeId), - onSuccess: () => { - queryClient.invalidateQueries({ queryKey: MEME_QUERY_KEYS.getMemesByCollectionId(sharedId) }); - queryClient.invalidateQueries({ queryKey: ACCOUNT_QUERY_KEYS.getMyAccount }); - }, - }); -}; diff --git a/src/application/hooks/api/collection/queryKey.ts b/src/application/hooks/api/collection/queryKey.ts deleted file mode 100644 index c5855af9..00000000 --- a/src/application/hooks/api/collection/queryKey.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const QUERY_KEYS = { - getCollectionCheck: (memeId: number) => ["getCollectionCheck", memeId], -} as const; diff --git a/src/application/hooks/api/core/index.ts b/src/application/hooks/api/core/index.ts deleted file mode 100644 index 60ec563b..00000000 --- a/src/application/hooks/api/core/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./useSuspensedQuery"; diff --git a/src/application/hooks/api/core/types.ts b/src/application/hooks/api/core/types.ts deleted file mode 100644 index d05c44ee..00000000 --- a/src/application/hooks/api/core/types.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { QueryKey, UseQueryOptions, UseQueryResult } from "@tanstack/react-query"; - -export interface BaseSuspendedUseQueryResult - extends Omit< - UseQueryResult, - "data" | "status" | "error" | "isLoading" | "isError" | "isFetching" - > { - data: TData; - status: "success" | "idle"; -} - -export type SuspendedUseQueryResultOnSuccess = BaseSuspendedUseQueryResult & { - status: "success"; - isSuccess: true; - isIdle: false; -}; -export type SuspendedUseQueryResultOnIdle = BaseSuspendedUseQueryResult & { - status: "idle"; - isSuccess: false; - isIdle: true; -}; - -export type SuspendedUseQueryOptions< - TQueryFnData = unknown, - TError = unknown, - TData = TQueryFnData, - TQueryKey extends QueryKey = QueryKey, -> = Omit, "suspense">; - -export type QuerySelectOption any> = ( - data: Awaited>, -) => Result; diff --git a/src/application/hooks/api/index.ts b/src/application/hooks/api/index.ts deleted file mode 100644 index 0983ff76..00000000 --- a/src/application/hooks/api/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./account"; -export * from "./collection"; -export * from "./meme"; -export * from "./search"; -export * from "./tags"; diff --git a/src/application/hooks/api/meme/index.ts b/src/application/hooks/api/meme/index.ts deleted file mode 100644 index a235e682..00000000 --- a/src/application/hooks/api/meme/index.ts +++ /dev/null @@ -1,84 +0,0 @@ -import type { QueryClient, QueryFunctionContext } from "@tanstack/react-query"; - -import { useSuspendedQuery } from "@/application/hooks/api/core"; -import { api } from "@/infra/api"; - -import { useCoreInfiniteQuery } from "../core/useCoreInfiniteQuery"; -import { QUERY_KEYS } from "./queryKey"; - -const PAGE_SIZE = 10; - -/** - * 밈 상세 조회 API - * @param id 상세 조회할 밈 id - * @desc staleTime 0 : 조회수 증가를 위해 바로 브라우저에서 재요청 - * - */ - -export const useMemeDetailById = (id: string) => { - const { data, isRefetching } = useSuspendedQuery({ - queryKey: QUERY_KEYS.getMemeDetailById(id), - queryFn: () => api.meme.getMemeDetailById(id), - staleTime: Infinity, - }); - - return { ...data, isRefetching }; -}; - -export const fetchMemeDetailById = (id: string, queryClient: QueryClient) => - queryClient.fetchQuery(QUERY_KEYS.getMemeDetailById(id), () => api.meme.getMemeDetailById(id)); - -/** - * 밈 type 에 따른 리스트 api - * @param sort 밈 리스트 type : share,recent,popular - */ -const types = { share: "shareCount", recent: "createdDate", popular: "viewCount", user: "user" }; - -export const useGetMemesBySort = (sort: keyof typeof types) => { - const { data, isEmpty, isFetchingNextPage, fetchNextPage } = useCoreInfiniteQuery( - QUERY_KEYS.getMemesBySort(sort), - ({ pageParam = 0 }: QueryFunctionContext) => - api.meme.getMemesBySort({ offset: pageParam, limit: PAGE_SIZE, sort: types[sort] }), - PAGE_SIZE, - { - select: (data) => { - return { - pages: data.pages.map((page) => ({ data: page.memes })), - pageParams: data.pageParams, - }; - }, - }, - ); - - return { data, isEmpty, isFetchingNextPage, fetchNextPage }; -}; - -/** - * 콜렉션 별 밈 리스트 API - * - * NOTE - * 현재 하나의 콜렉션만이 존재(즉, collectionId가 하나) - * 추후에 여러개의 콜렉션을 다룰 예정(즉, collectionId에 여러개) - * - * 마이페이지(/mypage)에서는 무한스크롤 적용 안함 - * 콜렉션 페이지(/collect) 페이지에서 무한 스크롤 적용함 - */ -export const useGetMemesByCollectionId = (collectionId: number) => { - const { data, isEmpty, isFetchingNextPage, fetchNextPage } = useCoreInfiniteQuery( - QUERY_KEYS.getMemesByCollectionId(collectionId), - ({ pageParam = 0 }: QueryFunctionContext) => - api.meme.getMemesByCollectionId({ collectionId, offset: pageParam, limit: PAGE_SIZE }), - PAGE_SIZE, - { - staleTime: 1000 * 5, - select: (data) => { - return { - pages: data.pages.map((page) => ({ data: page.memes })), - pageParams: data.pageParams, - }; - }, - }, - ); - - return { data, isEmpty, isFetchingNextPage, fetchNextPage }; -}; diff --git a/src/application/hooks/api/meme/queryKey.ts b/src/application/hooks/api/meme/queryKey.ts deleted file mode 100644 index 02b3c31c..00000000 --- a/src/application/hooks/api/meme/queryKey.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { CORE_QUERY_KEY } from "@/application/hooks/api/core/queryKey"; - -export const QUERY_KEYS = { - getMemeDetailById: (id: string) => ["getMemeDetailById", id], - getMemesBySort: (sort: string) => [CORE_QUERY_KEY.infiniteMemeList, "getMemesBySort", sort], - getMemesByCollectionId: (collectionId: number | null) => [ - CORE_QUERY_KEY.infiniteMemeList, - "getMemesByCollectionId", - collectionId, - ], -} as const; diff --git a/src/application/hooks/api/search/index.ts b/src/application/hooks/api/search/index.ts deleted file mode 100644 index 054ea2b8..00000000 --- a/src/application/hooks/api/search/index.ts +++ /dev/null @@ -1,148 +0,0 @@ -import type { QueryClient, QueryFunctionContext } from "@tanstack/react-query"; -import { useInfiniteQuery } from "@tanstack/react-query"; -import { useEffect, useRef } from "react"; - -import type { RecentSearch } from "@/application/hooks"; -import { useLocalStorage } from "@/application/hooks"; -import { api } from "@/infra/api"; - -import { useCoreInfiniteQuery } from "../core/useCoreInfiniteQuery"; -import { QUERY_KEYS } from "./queryKey"; - -const PAGE_SIZE = 20; - -/** - * keyword 밈 검색 API - * @param keyword 검색할 keyword - * @returns - * data - 밈 검색 결과 - * isEmpty - 밈 검색 결과가 없는 경우 true - */ -export const useGetMemesByKeyword = (keyword: string) => { - const { data, isEmpty, isFetchingNextPage, fetchNextPage } = useCoreInfiniteQuery( - QUERY_KEYS.getMemesByKeyword(keyword), - ({ pageParam = 0 }: QueryFunctionContext) => - api.search.getMemesByKeyword({ keyword, offset: pageParam, limit: PAGE_SIZE }), - PAGE_SIZE, - { - enabled: !!keyword, - select: (data) => { - return { - pages: data.pages.map((page) => ({ data: page.memes })), - pageParams: data.pageParams, - }; - }, - }, - ); - - return { data, isEmpty, isFetchingNextPage, fetchNextPage }; -}; - -/** - * tag 밈 검색 API - * @param tag 검색할 tag - * @returns - * data - 밈 검색 결과 - * isEmpty - 밈 검색 결과가 없는 경우 true - */ -export const useGetMemesByTag = (tag: string) => { - const { data, isFetchingNextPage, fetchNextPage } = useInfiniteQuery( - QUERY_KEYS.getMemesByTag(tag), - ({ pageParam = 0 }: QueryFunctionContext) => - api.search.getMemesByTag({ keyword: tag, offset: pageParam, limit: PAGE_SIZE }), - { - getNextPageParam: (lastPage, allPages) => { - const { count } = lastPage; - const isLastPage = count < PAGE_SIZE; - const offset = count * (allPages.length - 1); - return isLastPage ? undefined : offset + PAGE_SIZE; - }, - enabled: !!tag, - }, - ); - - const memes = data?.pages.flatMap(({ memes }) => memes) || []; - const totalCount = data?.pages[0].totalCount; - const isEmpty = !memes.length; - - return { data: memes, totalCount, isEmpty, isFetchingNextPage, fetchNextPage }; -}; - -export const prefetchMemesByTag = (tag: string, queryClient: QueryClient) => - queryClient.fetchInfiniteQuery(QUERY_KEYS.getMemesByTag(tag), ({ pageParam = 0 }) => - api.search.getMemesByTag({ keyword: tag, offset: pageParam, limit: PAGE_SIZE }), - ); - -/** - * 회원이 찾는 밈 API - */ -export const useGetUserFindMemes = ({ userId }: { userId: number }) => { - const isMount = useRef(false); - useEffect(() => { - isMount.current = true; - }, []); - - const [items] = useLocalStorage("recentSearch", { defaultValue: [] }); - const keywords = items - .map((item) => item.value) - .slice(0, 3) - .join(); - - const { data, isEmpty, isFetchingNextPage, fetchNextPage } = useCoreInfiniteQuery( - QUERY_KEYS.getUserFindMemes(keywords), - ({ pageParam = 0 }: QueryFunctionContext) => - api.search.getUserFindMemes({ - keywords: keywords, - offset: pageParam, - limit: PAGE_SIZE, - userId: String(userId), - }), - PAGE_SIZE, - { - enabled: isMount.current, - select: (data) => { - return { - pages: data.pages.map((page) => ({ data: page.memes })), - pageParams: data.pageParams, - }; - }, - }, - ); - - return { data, isEmpty, isFetchingNextPage, fetchNextPage }; -}; - -export const useGetMemesFromCollectionByKeyword = ({ - keyword, - collectionId, -}: { - keyword: string; - collectionId: number; -}) => { - const { data, isEmpty, isFetchingNextPage, fetchNextPage } = useCoreInfiniteQuery( - QUERY_KEYS.getMemesFromCollectionByKeyword({ - keyword: keyword, - collectionId: collectionId, - }), - ({ pageParam = 0 }: QueryFunctionContext) => - api.search.getMemesFromCollectionByKeyword({ - keyword: keyword, - collectionId, - offset: pageParam, - limit: PAGE_SIZE, - }), - PAGE_SIZE, - { - enabled: !!keyword && !!collectionId, - keepPreviousData: true, - select: (data) => { - return { - pages: data.pages.map((page) => ({ data: page.memes })), - pageParams: data.pageParams, - }; - }, - }, - ); - - return { data, isEmpty, isFetchingNextPage, fetchNextPage }; -}; diff --git a/src/application/hooks/api/search/queryKey.ts b/src/application/hooks/api/search/queryKey.ts deleted file mode 100644 index 17a6ca71..00000000 --- a/src/application/hooks/api/search/queryKey.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { CORE_QUERY_KEY } from "@/application/hooks/api/core/queryKey"; - -export const QUERY_KEYS = { - getMemesByKeyword: (keyword: string) => [ - CORE_QUERY_KEY.infiniteMemeList, - "getMemesByKeyword", - keyword, - ], - getMemesByTag: (tag: string) => [CORE_QUERY_KEY.infiniteMemeList, "getMemesByTag", tag], - getMemesFromCollectionByKeyword: ({ - keyword, - collectionId, - }: { - keyword: string; - collectionId: number; - }) => [ - CORE_QUERY_KEY.infiniteMemeList, - "getMemesFromCollectionByKeyword", - { keyword, collectionId }, - ], - getUserFindMemes: (keywords: string) => [ - CORE_QUERY_KEY.infiniteMemeList, - "getUserFindMemes", - keywords, - ], -} as const; diff --git a/src/application/hooks/api/tags/index.ts b/src/application/hooks/api/tags/index.ts deleted file mode 100644 index 80614d16..00000000 --- a/src/application/hooks/api/tags/index.ts +++ /dev/null @@ -1,179 +0,0 @@ -import type { QueryClient, UseQueryOptions } from "@tanstack/react-query"; -import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; - -import { useSuspendedQuery } from "@/application/hooks/api/core"; -import type { QuerySelectOption } from "@/application/hooks/api/core/types"; -import { delay } from "@/application/util"; -import { api } from "@/infra/api"; -import type { - GetFavoriteTagsResponse, - GetPopularTagsResponse, - GetTagSearchResponse, -} from "@/infra/api/tags/types"; - -import { QUERY_KEYS } from "./queryKey"; - -/** - * 인기 태그 조회 API - */ -export const useGetPopularTags = () => { - const { data } = useQuery({ - queryKey: QUERY_KEYS.getPopularTags, - queryFn: () => api.tags.getPopularTags(), - }); - - return { ...data }; -}; - -/** - * 태그 자동완성 API - * @param value 검색어 - */ -export const useGetTagSearch = (value: string) => { - const { data, ...rest } = useQuery({ - queryKey: QUERY_KEYS.getTagSearch(value), - queryFn: () => api.tags.getTagSearch(value), - keepPreviousData: true, - enabled: !!value, - }); - return { autoCompletedTags: data?.tags, ...rest }; -}; - -/** - * @desc - * Tag Category 에 즐겨찾기를 제외한 태그들 - */ -export const useGetCategoryWithTag = ({ - select, -}: { - select: QuerySelectOption; -}) => - useQuery({ - queryKey: QUERY_KEYS.getCategoryWithTags, - queryFn: api.tags.getCategoryWithTags, - select, - }); - -export const useGetMemeTagsById = (id: string) => { - const { data, ...rest } = useSuspendedQuery({ - queryKey: QUERY_KEYS.getMemeTagsById(id), - queryFn: () => api.tags.getMemeTagsById(id), - staleTime: Infinity, - }); - return { ...data, ...rest }; -}; - -export const fetchMemeTagsById = (id: string, queryClient: QueryClient) => - queryClient.fetchQuery(QUERY_KEYS.getMemeTagsById(id), () => api.tags.getMemeTagsById(id)); - -export const useGetTagInfo = ( - tagId: number, - options: Pick = { enabled: true }, -) => { - return useQuery({ - queryKey: QUERY_KEYS.getTagInfo(tagId), - queryFn: () => api.tags.getTagInfo(tagId), - staleTime: 0, - ...options, - }); -}; - -export const fetchTagInfo = (tagId: number, queryClient: QueryClient) => - queryClient.fetchQuery(QUERY_KEYS.getTagInfo(tagId), () => api.tags.getTagInfo(tagId)); - -export const useGetFavoriteTags = ( - options: Pick = { enabled: false }, -) => { - const { data } = useQuery({ - queryKey: QUERY_KEYS.getFavoriteTags, - queryFn: () => api.tags.getFavoriteTags(), - ...options, - }); - - return { favoriteTags: data?.tags }; -}; - -export const usePostFavoriteTag = () => { - const queryClient = useQueryClient(); - - return useMutation({ - mutationFn: api.tags.postFavoriteTag, - onMutate: async ({ tagId, name }) => { - await queryClient.cancelQueries({ queryKey: QUERY_KEYS.getTagInfo(tagId) }); - - const previousTagInfo = queryClient.getQueryData(QUERY_KEYS.getTagInfo(tagId)) as Awaited< - ReturnType - >; - - queryClient.setQueryData>>( - QUERY_KEYS.getFavoriteTags, - (old) => { - if (!old) return; - const newTags = [ - ...old.tags, - { - tagId: tagId, - name: name, - isFav: true, - }, - ]; - - return { tags: newTags }; - }, - ); - - queryClient.setQueryData(QUERY_KEYS.getTagInfo(tagId), (old) => ({ - ...(old as Awaited>), - isFav: true, - })); - - return { previousTagInfo }; - }, - - onError: (err, { tagId }, context) => { - queryClient.setQueryData(QUERY_KEYS.getTagInfo(tagId), context?.previousTagInfo); - }, - }); -}; - -export const useDeleteFavoriteTag = (wait = 0) => { - const queryClient = useQueryClient(); - - const controller = new AbortController(); - - const mutation = useMutation({ - mutationFn: (id: number) => api.tags.deleteFavoriteTag(id, controller.signal), - onMutate: async (id) => { - await queryClient.cancelQueries({ queryKey: QUERY_KEYS.getTagInfo(id) }); - await queryClient.cancelQueries({ queryKey: QUERY_KEYS.getFavoriteTags }); - - const previousFavoriteCategory = queryClient.getQueryData(QUERY_KEYS.getFavoriteTags); - const previousTagInfo = queryClient.getQueryData(QUERY_KEYS.getTagInfo(id)) as Awaited< - ReturnType - >; - - queryClient.setQueryData>>( - QUERY_KEYS.getFavoriteTags, - (old) => { - if (!old) return; - const newTags = old.tags.filter((tag) => tag.tagId !== id); - return { tags: newTags }; - }, - ); - - queryClient.setQueryData(QUERY_KEYS.getTagInfo(id), (old) => ({ - ...(old as Awaited>), - isFav: false, - })); - - await delay(wait); - return { previousTagInfo, previousFavoriteCategory }; - }, - - onError: (err, id, context) => { - queryClient.setQueryData(QUERY_KEYS.getTagInfo(id), context?.previousTagInfo); - queryClient.setQueryData(QUERY_KEYS.getFavoriteTags, context?.previousFavoriteCategory); - }, - }); - return { ...mutation, onCancel: () => controller.abort() }; -}; diff --git a/src/application/hooks/api/tags/queryKey.ts b/src/application/hooks/api/tags/queryKey.ts deleted file mode 100644 index 3ab109a4..00000000 --- a/src/application/hooks/api/tags/queryKey.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const QUERY_KEYS = { - getPopularTags: ["getPopularTags"], - getTagSearch: (debouncedValue: string) => ["getTagSearch", debouncedValue], - getCategoryWithTags: ["getCategoryWithTags"], - getFavoriteTags: ["getFavoriteTags"], - getMemeTagsById: (id: string) => ["getMemeTagsById", id], - getTagInfo: (tagId: number) => ["getTagInfo", tagId], -} as const; diff --git a/src/application/hooks/domain/auth/index.ts b/src/application/hooks/domain/auth/index.ts deleted file mode 100644 index dabdde66..00000000 --- a/src/application/hooks/domain/auth/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./useAuth"; diff --git a/src/application/hooks/domain/channel/index.ts b/src/application/hooks/domain/channel/index.ts deleted file mode 100644 index 10749675..00000000 --- a/src/application/hooks/domain/channel/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./useChannelIO"; diff --git a/src/application/hooks/domain/collection/index.ts b/src/application/hooks/domain/collection/index.ts deleted file mode 100644 index ee32c2ca..00000000 --- a/src/application/hooks/domain/collection/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./useCollection"; diff --git a/src/application/hooks/domain/index.ts b/src/application/hooks/domain/index.ts deleted file mode 100644 index 670b7acb..00000000 --- a/src/application/hooks/domain/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from "./auth"; -export * from "./channel"; -export * from "./collection"; -export * from "./meme"; -export * from "./search"; -export * from "./share"; diff --git a/src/application/hooks/domain/meme/index.ts b/src/application/hooks/domain/meme/index.ts deleted file mode 100644 index ce59e3a4..00000000 --- a/src/application/hooks/domain/meme/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./useMoveMemeDetail"; diff --git a/src/application/hooks/index.ts b/src/application/hooks/index.ts deleted file mode 100644 index d48f913b..00000000 --- a/src/application/hooks/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./api"; -export * from "./common"; -export * from "./domain"; diff --git a/src/components/common/ActionSheet/ActionSheet.tsx b/src/common/components/ActionSheet/ActionSheet.tsx similarity index 100% rename from src/components/common/ActionSheet/ActionSheet.tsx rename to src/common/components/ActionSheet/ActionSheet.tsx diff --git a/src/components/common/ActionSheet/index.ts b/src/common/components/ActionSheet/index.ts similarity index 100% rename from src/components/common/ActionSheet/index.ts rename to src/common/components/ActionSheet/index.ts diff --git a/src/components/common/Button/Button.stories.tsx b/src/common/components/Button/Button.stories.tsx similarity index 92% rename from src/components/common/Button/Button.stories.tsx rename to src/common/components/Button/Button.stories.tsx index d984975b..7e760f4e 100644 --- a/src/components/common/Button/Button.stories.tsx +++ b/src/common/components/Button/Button.stories.tsx @@ -1,7 +1,7 @@ import type { ComponentMeta, ComponentStory } from "@storybook/react"; import React from "react"; -import { Button } from "@/components/common/Button/Button"; +import { Button } from "./Button"; export default { title: "components/common/Button", diff --git a/src/components/common/Button/Button.tsx b/src/common/components/Button/Button.tsx similarity index 100% rename from src/components/common/Button/Button.tsx rename to src/common/components/Button/Button.tsx diff --git a/src/components/common/Button/index.ts b/src/common/components/Button/index.ts similarity index 100% rename from src/components/common/Button/index.ts rename to src/common/components/Button/index.ts diff --git a/src/components/common/Chip/Chip.stories.tsx b/src/common/components/Chip/Chip.stories.tsx similarity index 94% rename from src/components/common/Chip/Chip.stories.tsx rename to src/common/components/Chip/Chip.stories.tsx index 0d245a8f..b635d70f 100644 --- a/src/components/common/Chip/Chip.stories.tsx +++ b/src/common/components/Chip/Chip.stories.tsx @@ -1,6 +1,6 @@ import type { ComponentMeta, ComponentStory } from "@storybook/react"; -import { Chip } from "."; +import { Chip } from "./Chip"; export default { title: "components/common/Chip", diff --git a/src/components/common/Chip/Chip.tsx b/src/common/components/Chip/Chip.tsx similarity index 100% rename from src/components/common/Chip/Chip.tsx rename to src/common/components/Chip/Chip.tsx diff --git a/src/components/common/Chip/index.ts b/src/common/components/Chip/index.ts similarity index 100% rename from src/components/common/Chip/index.ts rename to src/common/components/Chip/index.ts diff --git a/src/components/common/Drawer/Drawer.tsx b/src/common/components/Drawer/Drawer.tsx similarity index 96% rename from src/components/common/Drawer/Drawer.tsx rename to src/common/components/Drawer/Drawer.tsx index df08d350..659d64dd 100644 --- a/src/components/common/Drawer/Drawer.tsx +++ b/src/common/components/Drawer/Drawer.tsx @@ -1,9 +1,9 @@ import type { PropsWithChildren, ReactNode } from "react"; import { css } from "twin.macro"; -import { useScrollLocker } from "@/application/hooks"; -import { Portal } from "@/components/common/Portal"; +import { useScrollLocker } from "@/common/hooks"; +import { Portal } from "../Portal"; import { DrawerContextProvider, useDrawerContext, useSetDrawerContext } from "./context"; interface DrawerProps { diff --git a/src/components/common/Drawer/context.tsx b/src/common/components/Drawer/context.tsx similarity index 93% rename from src/components/common/Drawer/context.tsx rename to src/common/components/Drawer/context.tsx index ad4a57d2..49e55d2c 100644 --- a/src/components/common/Drawer/context.tsx +++ b/src/common/components/Drawer/context.tsx @@ -1,5 +1,5 @@ import type { PropsWithChildren } from "react"; -import { createContext, useCallback, useContext, useEffect, useState } from "react"; +import { createContext, useCallback, useContext, useState } from "react"; const DrawerContext = createContext(false); const DrawerSetContext = createContext<(state: boolean) => void>(() => null); diff --git a/src/components/common/Drawer/index.ts b/src/common/components/Drawer/index.ts similarity index 100% rename from src/components/common/Drawer/index.ts rename to src/common/components/Drawer/index.ts diff --git a/src/components/common/DropDown/DropDown.tsx b/src/common/components/DropDown/DropDown.tsx similarity index 94% rename from src/components/common/DropDown/DropDown.tsx rename to src/common/components/DropDown/DropDown.tsx index b23db7a1..5d382f75 100644 --- a/src/components/common/DropDown/DropDown.tsx +++ b/src/common/components/DropDown/DropDown.tsx @@ -7,10 +7,10 @@ import type { SetStateAction, } from "react"; import { createContext, useContext, useState } from "react"; -import { css, theme } from "twin.macro"; +import { css } from "twin.macro"; -import { useClickOutside } from "@/application/hooks"; -import { withDelay } from "@/application/util/delay"; +import { useClickOutside } from "@/common/hooks"; +import { withDelay } from "@/common/utils"; const DropDownContext = createContext(false); const DropDownSetContext = createContext>>(() => null); diff --git a/src/components/common/DropDown/index.ts b/src/common/components/DropDown/index.ts similarity index 100% rename from src/components/common/DropDown/index.ts rename to src/common/components/DropDown/index.ts diff --git a/src/components/common/Error/GlobalError.tsx b/src/common/components/Error/GlobalError.tsx similarity index 86% rename from src/components/common/Error/GlobalError.tsx rename to src/common/components/Error/GlobalError.tsx index 07ee4478..e0ff1232 100644 --- a/src/components/common/Error/GlobalError.tsx +++ b/src/common/components/Error/GlobalError.tsx @@ -1,4 +1,4 @@ -import { Navigation } from "@/components/common/Navigation"; +import { Navigation } from "../Navigation"; export const GlobalError = () => { return ( diff --git a/src/components/common/Error/index.ts b/src/common/components/Error/index.ts similarity index 100% rename from src/components/common/Error/index.ts rename to src/common/components/Error/index.ts diff --git a/src/components/common/ErrorBoundary/QueryErrorBoundary.tsx b/src/common/components/ErrorBoundary/QueryErrorBoundary.tsx similarity index 89% rename from src/components/common/ErrorBoundary/QueryErrorBoundary.tsx rename to src/common/components/ErrorBoundary/QueryErrorBoundary.tsx index 25623ac0..f32d3775 100644 --- a/src/components/common/ErrorBoundary/QueryErrorBoundary.tsx +++ b/src/common/components/ErrorBoundary/QueryErrorBoundary.tsx @@ -2,7 +2,7 @@ import { QueryErrorResetBoundary } from "@tanstack/react-query"; import type { PropsWithChildren } from "react"; import { ErrorBoundary } from "react-error-boundary"; -import { GlobalError } from "@/components/common/Error"; +import { GlobalError } from "../Error/GlobalError"; export const QueryErrorBoundary = ({ children }: PropsWithChildren) => { return ( diff --git a/src/components/common/ErrorBoundary/index.ts b/src/common/components/ErrorBoundary/index.ts similarity index 100% rename from src/components/common/ErrorBoundary/index.ts rename to src/common/components/ErrorBoundary/index.ts diff --git a/src/components/common/Icon/Icon.stories.tsx b/src/common/components/Icon/Icon.stories.tsx similarity index 100% rename from src/components/common/Icon/Icon.stories.tsx rename to src/common/components/Icon/Icon.stories.tsx diff --git a/src/components/common/Icon/assets.ts b/src/common/components/Icon/assets.ts similarity index 100% rename from src/components/common/Icon/assets.ts rename to src/common/components/Icon/assets.ts diff --git a/src/components/common/Icon/index.tsx b/src/common/components/Icon/index.tsx similarity index 100% rename from src/components/common/Icon/index.tsx rename to src/common/components/Icon/index.tsx diff --git a/src/components/common/Input/Input.stories.tsx b/src/common/components/Input/Input.stories.tsx similarity index 100% rename from src/components/common/Input/Input.stories.tsx rename to src/common/components/Input/Input.stories.tsx diff --git a/src/components/common/Input/index.tsx b/src/common/components/Input/index.tsx similarity index 100% rename from src/components/common/Input/index.tsx rename to src/common/components/Input/index.tsx diff --git a/src/components/common/Layout/Layout.tsx b/src/common/components/Layout/Layout.tsx similarity index 100% rename from src/components/common/Layout/Layout.tsx rename to src/common/components/Layout/Layout.tsx diff --git a/src/components/common/Layout/ServiceGuide.tsx b/src/common/components/Layout/ServiceGuide.tsx similarity index 93% rename from src/components/common/Layout/ServiceGuide.tsx rename to src/common/components/Layout/ServiceGuide.tsx index b344fdea..676a6d88 100644 --- a/src/components/common/Layout/ServiceGuide.tsx +++ b/src/common/components/Layout/ServiceGuide.tsx @@ -1,6 +1,6 @@ import Image from "next/image"; -import { thismemeGuideUrl } from "@/application/util"; +import { thismemeGuideUrl } from "@/common/utils"; import { Button } from "../Button"; diff --git a/src/components/common/Layout/index.ts b/src/common/components/Layout/index.ts similarity index 100% rename from src/components/common/Layout/index.ts rename to src/common/components/Layout/index.ts diff --git a/src/components/common/Masonry/Masonry.stories.tsx b/src/common/components/Masonry/Masonry.stories.tsx similarity index 97% rename from src/components/common/Masonry/Masonry.stories.tsx rename to src/common/components/Masonry/Masonry.stories.tsx index 25175a9d..ec7d9844 100644 --- a/src/components/common/Masonry/Masonry.stories.tsx +++ b/src/common/components/Masonry/Masonry.stories.tsx @@ -1,7 +1,7 @@ import type { ComponentMeta, ComponentStory } from "@storybook/react"; import React from "react"; -import { MemeItem } from "@/components/meme/MemeItem"; +import { MemeItem } from "@/features/common"; import { Masonry } from "./Masonry"; diff --git a/src/components/common/Masonry/Masonry.tsx b/src/common/components/Masonry/Masonry.tsx similarity index 100% rename from src/components/common/Masonry/Masonry.tsx rename to src/common/components/Masonry/Masonry.tsx diff --git a/src/components/common/Masonry/index.ts b/src/common/components/Masonry/index.ts similarity index 100% rename from src/components/common/Masonry/index.ts rename to src/common/components/Masonry/index.ts diff --git a/src/components/common/Modal/Modal.stories.tsx b/src/common/components/Modal/Modal.stories.tsx similarity index 100% rename from src/components/common/Modal/Modal.stories.tsx rename to src/common/components/Modal/Modal.stories.tsx diff --git a/src/components/common/Modal/Modal.tsx b/src/common/components/Modal/Modal.tsx similarity index 93% rename from src/components/common/Modal/Modal.tsx rename to src/common/components/Modal/Modal.tsx index 729c81ad..1b0ebea3 100644 --- a/src/components/common/Modal/Modal.tsx +++ b/src/common/components/Modal/Modal.tsx @@ -1,9 +1,10 @@ import type { PropsWithChildren } from "react"; import { Children, createContext, isValidElement, useContext } from "react"; -import { useClickOutside } from "@/application/hooks"; -import { fadeInOut } from "@/application/util"; -import { Icon } from "@/components/common/Icon"; +import { useClickOutside } from "@/common/hooks"; +import { fadeInOut } from "@/common/utils"; + +import { Icon } from "../Icon"; interface ModalProps { open: boolean; diff --git a/src/components/common/Modal/SignOutModal.tsx b/src/common/components/Modal/SignOutModal.tsx similarity index 90% rename from src/components/common/Modal/SignOutModal.tsx rename to src/common/components/Modal/SignOutModal.tsx index e96bf2c6..058b6cb3 100644 --- a/src/components/common/Modal/SignOutModal.tsx +++ b/src/common/components/Modal/SignOutModal.tsx @@ -1,9 +1,10 @@ import { useRouter } from "next/router"; -import { useAuth, useToast } from "@/application/hooks"; -import { PATH } from "@/application/util"; -import { RandomImage } from "@/components/common/RandomImge"; +import { useToast } from "@/common/hooks"; +import { PATH } from "@/common/utils"; +import { useAuth } from "@/features/common"; +import { RandomImage } from "../RandomImge"; import { Modal } from "./Modal"; import type { ModalProps } from "./types"; diff --git a/src/components/common/Modal/SignUpModal/SignUpModal.tsx b/src/common/components/Modal/SignUpModal/SignUpModal.tsx similarity index 88% rename from src/components/common/Modal/SignUpModal/SignUpModal.tsx rename to src/common/components/Modal/SignUpModal/SignUpModal.tsx index eb12f13b..59be1f49 100644 --- a/src/components/common/Modal/SignUpModal/SignUpModal.tsx +++ b/src/common/components/Modal/SignUpModal/SignUpModal.tsx @@ -1,8 +1,8 @@ -import { IS_CSR } from "@/application/util"; -import { Button } from "@/components/common/Button"; -import { Icon } from "@/components/common/Icon"; -import { RandomImage } from "@/components/common/RandomImge"; +import { IS_CSR } from "@/common/utils"; +import { Button } from "../../Button"; +import { Icon } from "../../Icon"; +import { RandomImage } from "../../RandomImge"; import { Modal } from "../Modal"; import { useSignUpModalContext } from "./context"; diff --git a/src/components/common/Modal/SignUpModal/context.tsx b/src/common/components/Modal/SignUpModal/context.tsx similarity index 92% rename from src/components/common/Modal/SignUpModal/context.tsx rename to src/common/components/Modal/SignUpModal/context.tsx index 259d33d7..0d268176 100644 --- a/src/components/common/Modal/SignUpModal/context.tsx +++ b/src/common/components/Modal/SignUpModal/context.tsx @@ -1,7 +1,7 @@ import type { PropsWithChildren } from "react"; import { createContext, useContext } from "react"; -import { useModal } from "@/application/hooks"; +import { useModal } from "@/common/hooks"; import type { ModalProps } from "../types"; diff --git a/src/components/common/Modal/SignUpModal/index.ts b/src/common/components/Modal/SignUpModal/index.ts similarity index 100% rename from src/components/common/Modal/SignUpModal/index.ts rename to src/common/components/Modal/SignUpModal/index.ts diff --git a/src/components/common/Modal/index.ts b/src/common/components/Modal/index.ts similarity index 77% rename from src/components/common/Modal/index.ts rename to src/common/components/Modal/index.ts index a8acafd9..6661f64b 100644 --- a/src/components/common/Modal/index.ts +++ b/src/common/components/Modal/index.ts @@ -1,5 +1,4 @@ export * from "./Modal"; -export * from "./ProfileModal"; export * from "./SignOutModal"; export * from "./SignUpModal"; export * from "./types"; diff --git a/src/components/common/Modal/types.ts b/src/common/components/Modal/types.ts similarity index 50% rename from src/components/common/Modal/types.ts rename to src/common/components/Modal/types.ts index 693e0255..92b4c266 100644 --- a/src/components/common/Modal/types.ts +++ b/src/common/components/Modal/types.ts @@ -1,3 +1,3 @@ -import type { useModal } from "@/application/hooks"; +import type { useModal } from "@/common/hooks"; export type ModalProps = ReturnType; diff --git a/src/components/common/Navigation/BackButton/BackButton.tsx b/src/common/components/Navigation/BackButton/BackButton.tsx similarity index 78% rename from src/components/common/Navigation/BackButton/BackButton.tsx rename to src/common/components/Navigation/BackButton/BackButton.tsx index 17726f18..60ab9298 100644 --- a/src/components/common/Navigation/BackButton/BackButton.tsx +++ b/src/common/components/Navigation/BackButton/BackButton.tsx @@ -1,8 +1,9 @@ import { useRouter } from "next/router"; import type { ComponentProps } from "react"; -import { useRouteTracking } from "@/application/hooks"; -import { Icon } from "@/components/common/Icon"; +import { useRouteTracking } from "@/common/hooks"; + +import { Icon } from "../../Icon"; export const BackButton = (props: ComponentProps<"button">) => { const router = useRouter(); diff --git a/src/components/common/Navigation/BackButton/index.ts b/src/common/components/Navigation/BackButton/index.ts similarity index 100% rename from src/components/common/Navigation/BackButton/index.ts rename to src/common/components/Navigation/BackButton/index.ts diff --git a/src/components/common/Navigation/BackButtonNavigation.tsx b/src/common/components/Navigation/BackButtonNavigation.tsx similarity index 100% rename from src/components/common/Navigation/BackButtonNavigation.tsx rename to src/common/components/Navigation/BackButtonNavigation.tsx diff --git a/src/components/common/Navigation/CloseButton/CloseButton.tsx b/src/common/components/Navigation/CloseButton/CloseButton.tsx similarity index 82% rename from src/components/common/Navigation/CloseButton/CloseButton.tsx rename to src/common/components/Navigation/CloseButton/CloseButton.tsx index 24d7f04f..29cb2c84 100644 --- a/src/components/common/Navigation/CloseButton/CloseButton.tsx +++ b/src/common/components/Navigation/CloseButton/CloseButton.tsx @@ -1,6 +1,6 @@ import { useRouter } from "next/router"; -import { Icon } from "@/components/common/Icon"; +import { Icon } from "../../Icon"; export const CloseButton = () => { const router = useRouter(); diff --git a/src/components/common/Navigation/CloseButton/index.ts b/src/common/components/Navigation/CloseButton/index.ts similarity index 100% rename from src/components/common/Navigation/CloseButton/index.ts rename to src/common/components/Navigation/CloseButton/index.ts diff --git a/src/components/common/Navigation/ExplorePageNavigation.tsx b/src/common/components/Navigation/ExplorePageNavigation.tsx similarity index 74% rename from src/components/common/Navigation/ExplorePageNavigation.tsx rename to src/common/components/Navigation/ExplorePageNavigation.tsx index a89e4d3d..93ccea06 100644 --- a/src/components/common/Navigation/ExplorePageNavigation.tsx +++ b/src/common/components/Navigation/ExplorePageNavigation.tsx @@ -1,8 +1,8 @@ -import { Logo } from "@/components/common/Navigation/Logo"; -import { SearchHeader } from "@/components/common/Navigation/SearchHeader"; - +import { Logo } from "./Logo"; import { Navigation } from "./Navigation"; +import { SearchHeader } from "./SearchHeader"; import { SideBar } from "./SideBar"; +import { UploadButton } from "./UploadButton"; interface Props { title?: string; @@ -16,6 +16,7 @@ export const ExplorePageNavigation = ({ title }: Props) => { + diff --git a/src/components/common/Navigation/IntroPageNavigation.tsx b/src/common/components/Navigation/IntroPageNavigation.tsx similarity index 77% rename from src/components/common/Navigation/IntroPageNavigation.tsx rename to src/common/components/Navigation/IntroPageNavigation.tsx index 26b4ef5e..0be5ca48 100644 --- a/src/components/common/Navigation/IntroPageNavigation.tsx +++ b/src/common/components/Navigation/IntroPageNavigation.tsx @@ -1,8 +1,8 @@ -import { SearchHeader } from "@/components/common/Navigation/SearchHeader"; - import { Logo } from "./Logo"; import { Navigation } from "./Navigation"; +import { SearchHeader } from "./SearchHeader"; import { SideBar } from "./SideBar"; +import { UploadButton } from "./UploadButton"; export const IntroPageNavigation = () => { return ( @@ -12,6 +12,7 @@ export const IntroPageNavigation = () => { + diff --git a/src/components/common/Navigation/Logo/Logo.tsx b/src/common/components/Navigation/Logo/Logo.tsx similarity index 86% rename from src/components/common/Navigation/Logo/Logo.tsx rename to src/common/components/Navigation/Logo/Logo.tsx index 848e6892..7a4b4331 100644 --- a/src/components/common/Navigation/Logo/Logo.tsx +++ b/src/common/components/Navigation/Logo/Logo.tsx @@ -1,6 +1,6 @@ import { useRouter } from "next/router"; -import { Icon } from "@/components/common/Icon"; +import { Icon } from "../../Icon"; export const Logo = () => { const router = useRouter(); diff --git a/src/components/common/Navigation/Logo/index.ts b/src/common/components/Navigation/Logo/index.ts similarity index 100% rename from src/components/common/Navigation/Logo/index.ts rename to src/common/components/Navigation/Logo/index.ts diff --git a/src/components/common/Navigation/MyPageNavigation.tsx b/src/common/components/Navigation/MyPageNavigation.tsx similarity index 100% rename from src/components/common/Navigation/MyPageNavigation.tsx rename to src/common/components/Navigation/MyPageNavigation.tsx diff --git a/src/components/common/Navigation/Navigation.tsx b/src/common/components/Navigation/Navigation.tsx similarity index 100% rename from src/components/common/Navigation/Navigation.tsx rename to src/common/components/Navigation/Navigation.tsx diff --git a/src/components/common/Navigation/SearchHeader/SearchHeader.tsx b/src/common/components/Navigation/SearchHeader/SearchHeader.tsx similarity index 86% rename from src/components/common/Navigation/SearchHeader/SearchHeader.tsx rename to src/common/components/Navigation/SearchHeader/SearchHeader.tsx index f2781c3a..3bdd3efa 100644 --- a/src/components/common/Navigation/SearchHeader/SearchHeader.tsx +++ b/src/common/components/Navigation/SearchHeader/SearchHeader.tsx @@ -2,10 +2,11 @@ import { useRouter } from "next/router"; import { CSSTransition } from "react-transition-group"; import { css } from "twin.macro"; -import { useScrollDirection } from "@/application/hooks"; -import { BackButton } from "@/components/common/Navigation/BackButton"; -import { SearchInput } from "@/components/search"; -import { TagCategory } from "@/components/tags"; +import { useScrollDirection } from "@/common/hooks"; +import { TagCategory } from "@/features/common"; +import { SearchInput } from "@/features/search/components"; + +import { BackButton } from "../BackButton"; const DELAY = 300; diff --git a/src/components/common/Navigation/SearchHeader/index.ts b/src/common/components/Navigation/SearchHeader/index.ts similarity index 100% rename from src/components/common/Navigation/SearchHeader/index.ts rename to src/common/components/Navigation/SearchHeader/index.ts diff --git a/src/components/common/Navigation/SearchPageNavigation.tsx b/src/common/components/Navigation/SearchPageNavigation.tsx similarity index 84% rename from src/components/common/Navigation/SearchPageNavigation.tsx rename to src/common/components/Navigation/SearchPageNavigation.tsx index 153413bf..9efbf964 100644 --- a/src/components/common/Navigation/SearchPageNavigation.tsx +++ b/src/common/components/Navigation/SearchPageNavigation.tsx @@ -1,6 +1,5 @@ -import { Logo } from "@/components/common/Navigation/Logo"; - import { CloseButton } from "./CloseButton"; +import { Logo } from "./Logo"; import { Navigation } from "./Navigation"; export const SearchPageNavigation = () => { diff --git a/src/components/common/Navigation/SideBar/LoginSideBarContent.tsx b/src/common/components/Navigation/SideBar/LoginSideBarContent.tsx similarity index 87% rename from src/components/common/Navigation/SideBar/LoginSideBarContent.tsx rename to src/common/components/Navigation/SideBar/LoginSideBarContent.tsx index bf9180db..a4a5a2eb 100644 --- a/src/components/common/Navigation/SideBar/LoginSideBarContent.tsx +++ b/src/common/components/Navigation/SideBar/LoginSideBarContent.tsx @@ -1,11 +1,11 @@ import Link from "next/link"; -import type { useAuth } from "@/application/hooks"; -import { useModal } from "@/application/hooks"; -import { channelUrl } from "@/application/util"; -import { Icon } from "@/components/common/Icon"; -import { SignOutModal } from "@/components/common/Modal"; -import { Photo } from "@/components/common/Photo"; +import { Icon } from "@/common/components/Icon"; +import { SignOutModal } from "@/common/components/Modal"; +import { Photo } from "@/common/components/Photo"; +import { useModal } from "@/common/hooks"; +import { channelUrl } from "@/common/utils"; +import type { useAuth } from "@/features/common"; type LoginSideBarContentProps = ReturnType; diff --git a/src/components/common/Navigation/SideBar/LogoutSideBarContent.tsx b/src/common/components/Navigation/SideBar/LogoutSideBarContent.tsx similarity index 89% rename from src/components/common/Navigation/SideBar/LogoutSideBarContent.tsx rename to src/common/components/Navigation/SideBar/LogoutSideBarContent.tsx index c1b9bbfa..ca246dce 100644 --- a/src/components/common/Navigation/SideBar/LogoutSideBarContent.tsx +++ b/src/common/components/Navigation/SideBar/LogoutSideBarContent.tsx @@ -1,7 +1,7 @@ -import type { useAuth } from "@/application/hooks"; -import { channelUrl } from "@/application/util"; -import { Icon } from "@/components/common/Icon"; -import { Photo } from "@/components/common/Photo"; +import { Icon } from "@/common/components/Icon"; +import { Photo } from "@/common/components/Photo"; +import { channelUrl } from "@/common/utils"; +import type { useAuth } from "@/features/common"; const defaultAvatarUrl = "/img/default-avatar.png"; const defaultName = "로그인하기"; diff --git a/src/components/common/Navigation/SideBar/SideBar.tsx b/src/common/components/Navigation/SideBar/SideBar.tsx similarity index 83% rename from src/components/common/Navigation/SideBar/SideBar.tsx rename to src/common/components/Navigation/SideBar/SideBar.tsx index 142aa862..9678d1c6 100644 --- a/src/components/common/Navigation/SideBar/SideBar.tsx +++ b/src/common/components/Navigation/SideBar/SideBar.tsx @@ -1,9 +1,8 @@ -import { useAuth } from "@/application/hooks"; -import { instagramUrl, twitterUrl } from "@/application/util"; -import { Drawer } from "@/components/common/Drawer"; -import { Icon } from "@/components/common/Icon"; -import { useTagCategoryContext } from "@/components/tags"; +import { instagramUrl, twitterUrl } from "@/common/utils"; +import { useAuth, useTagCategoryContext } from "@/features/common"; +import { Drawer } from "../../Drawer"; +import { Icon } from "../../Icon"; import { LoginSideBarContent } from "./LoginSideBarContent"; import { LogoutSideBarContent } from "./LogoutSideBarContent"; diff --git a/src/components/common/Navigation/SideBar/index.ts b/src/common/components/Navigation/SideBar/index.ts similarity index 100% rename from src/components/common/Navigation/SideBar/index.ts rename to src/common/components/Navigation/SideBar/index.ts diff --git a/src/common/components/Navigation/UploadButton/UploadButton.tsx b/src/common/components/Navigation/UploadButton/UploadButton.tsx new file mode 100644 index 00000000..04de8263 --- /dev/null +++ b/src/common/components/Navigation/UploadButton/UploadButton.tsx @@ -0,0 +1,25 @@ +import { useOverlay } from "@/common/hooks"; + +import { UploadModal } from "./UploadModal"; + +export const UploadButton = () => { + const overlay = useOverlay(); + const handleClick = () => { + /** + * TODO + * 업로드 기능 완료 후, + * 1. 업로드 페이지로 이동하는 버튼으로 변경 + * 2. UploadModal 삭제 + */ + overlay.open(({ isOpen, close }) => ); + }; + + return ( + + ); +}; diff --git a/src/common/components/Navigation/UploadButton/UploadModal.tsx b/src/common/components/Navigation/UploadButton/UploadModal.tsx new file mode 100644 index 00000000..b6193cba --- /dev/null +++ b/src/common/components/Navigation/UploadButton/UploadModal.tsx @@ -0,0 +1,45 @@ +import { Modal } from "../../Modal"; + +interface Props { + open: boolean; + onClose: () => void; +} + +/** + * TODO + * 업로드 기능 완성 후 제거 + */ +export const UploadModal = ({ open, onClose }: Props) => { + return ( + + +
+

밈 업로드에 관심있는 당신!

+

+ 그밈 팀은 업로드 기능을 준비 중이에요! +
+
+ 이메일을 남겨주시면 +
+ 업로드 기능이 완성되었을 때 +
+ 미리 체험할 수 있도록 알려드릴게요. +
+

+
+ + + + 좋아요 + + +
+ ); +}; diff --git a/src/common/components/Navigation/UploadButton/index.ts b/src/common/components/Navigation/UploadButton/index.ts new file mode 100644 index 00000000..1b9efe82 --- /dev/null +++ b/src/common/components/Navigation/UploadButton/index.ts @@ -0,0 +1 @@ +export * from "./UploadButton"; diff --git a/src/components/common/Navigation/index.ts b/src/common/components/Navigation/index.ts similarity index 100% rename from src/components/common/Navigation/index.ts rename to src/common/components/Navigation/index.ts diff --git a/src/components/common/NextSeo/NextSeo.tsx b/src/common/components/NextSeo/NextSeo.tsx similarity index 100% rename from src/components/common/NextSeo/NextSeo.tsx rename to src/common/components/NextSeo/NextSeo.tsx diff --git a/src/components/common/NextSeo/index.ts b/src/common/components/NextSeo/index.ts similarity index 100% rename from src/components/common/NextSeo/index.ts rename to src/common/components/NextSeo/index.ts diff --git a/src/components/common/NextSeo/types.ts b/src/common/components/NextSeo/types.ts similarity index 100% rename from src/components/common/NextSeo/types.ts rename to src/common/components/NextSeo/types.ts diff --git a/src/components/common/Photo/Photo.stories.tsx b/src/common/components/Photo/Photo.stories.tsx similarity index 92% rename from src/components/common/Photo/Photo.stories.tsx rename to src/common/components/Photo/Photo.stories.tsx index b4c2508a..cdd17998 100644 --- a/src/components/common/Photo/Photo.stories.tsx +++ b/src/common/components/Photo/Photo.stories.tsx @@ -1,6 +1,6 @@ import type { ComponentMeta } from "@storybook/react"; -import { Photo } from "@/components/common/Photo"; +import { Photo } from "./Photo"; export default { title: "components/common/Photo", diff --git a/src/components/common/Photo/Photo.tsx b/src/common/components/Photo/Photo.tsx similarity index 100% rename from src/components/common/Photo/Photo.tsx rename to src/common/components/Photo/Photo.tsx diff --git a/src/components/common/Photo/index.ts b/src/common/components/Photo/index.ts similarity index 100% rename from src/components/common/Photo/index.ts rename to src/common/components/Photo/index.ts diff --git a/src/components/common/Portal/Portal.tsx b/src/common/components/Portal/Portal.tsx similarity index 94% rename from src/components/common/Portal/Portal.tsx rename to src/common/components/Portal/Portal.tsx index a93d384a..b18fd72c 100644 --- a/src/components/common/Portal/Portal.tsx +++ b/src/common/components/Portal/Portal.tsx @@ -2,7 +2,7 @@ import type { ReactNode } from "react"; import { useEffect, useRef } from "react"; import { createPortal } from "react-dom"; -import { useIsMount } from "@/application/hooks"; +import { useIsMount } from "@/common/hooks"; import { pretendard, suit } from "@/styles/fonts"; interface Props { diff --git a/src/components/common/Portal/index.ts b/src/common/components/Portal/index.ts similarity index 100% rename from src/components/common/Portal/index.ts rename to src/common/components/Portal/index.ts diff --git a/src/components/common/PullToRefresh/PullToRefresh.tsx b/src/common/components/PullToRefresh/PullToRefresh.tsx similarity index 98% rename from src/components/common/PullToRefresh/PullToRefresh.tsx rename to src/common/components/PullToRefresh/PullToRefresh.tsx index 754882bb..2faa459f 100644 --- a/src/components/common/PullToRefresh/PullToRefresh.tsx +++ b/src/common/components/PullToRefresh/PullToRefresh.tsx @@ -3,7 +3,7 @@ import type { PropsWithChildren } from "react"; import { useRef, useState } from "react"; import { css } from "twin.macro"; -import { delay } from "@/application/util"; +import { delay } from "@/common/utils"; import { RefreshContent } from "./RefreshContent"; import { getScrollParent, getScrollTop } from "./utils"; diff --git a/src/components/common/PullToRefresh/RefreshContent.tsx b/src/common/components/PullToRefresh/RefreshContent.tsx similarity index 100% rename from src/components/common/PullToRefresh/RefreshContent.tsx rename to src/common/components/PullToRefresh/RefreshContent.tsx diff --git a/src/components/common/PullToRefresh/index.ts b/src/common/components/PullToRefresh/index.ts similarity index 100% rename from src/components/common/PullToRefresh/index.ts rename to src/common/components/PullToRefresh/index.ts diff --git a/src/components/common/PullToRefresh/refresh.json b/src/common/components/PullToRefresh/refresh.json similarity index 100% rename from src/components/common/PullToRefresh/refresh.json rename to src/common/components/PullToRefresh/refresh.json diff --git a/src/components/common/PullToRefresh/utils.ts b/src/common/components/PullToRefresh/utils.ts similarity index 95% rename from src/components/common/PullToRefresh/utils.ts rename to src/common/components/PullToRefresh/utils.ts index 068de749..f4ce9f39 100644 --- a/src/components/common/PullToRefresh/utils.ts +++ b/src/common/components/PullToRefresh/utils.ts @@ -1,4 +1,4 @@ -import { IS_CSR } from "@/application/util"; +import { IS_CSR } from "@/common/utils"; type ScrollElement = HTMLElement | Window; const defaultRoot = IS_CSR ? window : null; diff --git a/src/components/common/RandomImge/RandomImage.stories.tsx b/src/common/components/RandomImge/RandomImage.stories.tsx similarity index 100% rename from src/components/common/RandomImge/RandomImage.stories.tsx rename to src/common/components/RandomImge/RandomImage.stories.tsx diff --git a/src/components/common/RandomImge/RandomImage.tsx b/src/common/components/RandomImge/RandomImage.tsx similarity index 100% rename from src/components/common/RandomImge/RandomImage.tsx rename to src/common/components/RandomImge/RandomImage.tsx diff --git a/src/components/common/RandomImge/index.ts b/src/common/components/RandomImge/index.ts similarity index 100% rename from src/components/common/RandomImge/index.ts rename to src/common/components/RandomImge/index.ts diff --git a/src/components/common/Skeleton/MemeListSkeleton.tsx b/src/common/components/Skeleton/MemeListSkeleton.tsx similarity index 100% rename from src/components/common/Skeleton/MemeListSkeleton.tsx rename to src/common/components/Skeleton/MemeListSkeleton.tsx diff --git a/src/components/common/Skeleton/Skeleton.stories.tsx b/src/common/components/Skeleton/Skeleton.stories.tsx similarity index 100% rename from src/components/common/Skeleton/Skeleton.stories.tsx rename to src/common/components/Skeleton/Skeleton.stories.tsx diff --git a/src/components/common/Skeleton/Skeleton.tsx b/src/common/components/Skeleton/Skeleton.tsx similarity index 100% rename from src/components/common/Skeleton/Skeleton.tsx rename to src/common/components/Skeleton/Skeleton.tsx diff --git a/src/components/common/Skeleton/index.ts b/src/common/components/Skeleton/index.ts similarity index 100% rename from src/components/common/Skeleton/index.ts rename to src/common/components/Skeleton/index.ts diff --git a/src/components/common/Suspense/SSRSuspense.tsx b/src/common/components/Suspense/SSRSuspense.tsx similarity index 84% rename from src/components/common/Suspense/SSRSuspense.tsx rename to src/common/components/Suspense/SSRSuspense.tsx index a50c093f..0191c976 100644 --- a/src/components/common/Suspense/SSRSuspense.tsx +++ b/src/common/components/Suspense/SSRSuspense.tsx @@ -1,7 +1,7 @@ import type { ComponentProps } from "react"; import { Suspense } from "react"; -import { useIsMount } from "@/application/hooks"; +import { useIsMount } from "@/common/hooks"; type Props = ComponentProps; diff --git a/src/components/common/Suspense/index.ts b/src/common/components/Suspense/index.ts similarity index 100% rename from src/components/common/Suspense/index.ts rename to src/common/components/Suspense/index.ts diff --git a/src/components/common/Toast/Toast.stories.tsx b/src/common/components/Toast/Toast.stories.tsx similarity index 87% rename from src/components/common/Toast/Toast.stories.tsx rename to src/common/components/Toast/Toast.stories.tsx index f0c6ba6f..517d4e07 100644 --- a/src/components/common/Toast/Toast.stories.tsx +++ b/src/common/components/Toast/Toast.stories.tsx @@ -1,6 +1,6 @@ -import { useToast } from "@/application/hooks/common"; -import { Button } from "@/components/common/Button"; +import { useToast } from "@/common/hooks"; +import { Button } from "../Button"; import type { Toast } from "./types"; export default { diff --git a/src/components/common/Toast/Toast.tsx b/src/common/components/Toast/Toast.tsx similarity index 84% rename from src/components/common/Toast/Toast.tsx rename to src/common/components/Toast/Toast.tsx index b29a08e6..6673fe53 100644 --- a/src/components/common/Toast/Toast.tsx +++ b/src/common/components/Toast/Toast.tsx @@ -1,6 +1,6 @@ -import { slideUpDown } from "@/application/util"; -import { Icon } from "@/components/common/Icon"; +import { slideUpDown } from "@/common/utils"; +import { Icon } from "../Icon"; import { defaultToastStyle, toastColors, toastIconColors } from "./style"; import type { Toast as Props } from "./types"; diff --git a/src/components/common/Toast/ToastContainer.tsx b/src/common/components/Toast/ToastContainer.tsx similarity index 87% rename from src/components/common/Toast/ToastContainer.tsx rename to src/common/components/Toast/ToastContainer.tsx index 4673f50c..b949ceac 100644 --- a/src/components/common/Toast/ToastContainer.tsx +++ b/src/common/components/Toast/ToastContainer.tsx @@ -1,10 +1,10 @@ import { useRef } from "react"; -import { useIsomorphicLayoutEffect } from "@/application/hooks"; -import { Portal } from "@/components/common/Portal"; -import { Toast } from "@/components/common/Toast/Toast"; +import { useIsomorphicLayoutEffect } from "@/common/hooks"; +import { Portal } from "../Portal"; import { useToastContext } from "./context"; +import { Toast } from "./Toast"; let prevHeight = 0; const EXPAND_DELAY = 200; diff --git a/src/components/common/Toast/context.tsx b/src/common/components/Toast/context.tsx similarity index 100% rename from src/components/common/Toast/context.tsx rename to src/common/components/Toast/context.tsx diff --git a/src/components/common/Toast/index.ts b/src/common/components/Toast/index.ts similarity index 100% rename from src/components/common/Toast/index.ts rename to src/common/components/Toast/index.ts diff --git a/src/components/common/Toast/style.ts b/src/common/components/Toast/style.ts similarity index 100% rename from src/components/common/Toast/style.ts rename to src/common/components/Toast/style.ts diff --git a/src/components/common/Toast/types.ts b/src/common/components/Toast/types.ts similarity index 90% rename from src/components/common/Toast/types.ts rename to src/common/components/Toast/types.ts index cafe3f54..213fccf3 100644 --- a/src/components/common/Toast/types.ts +++ b/src/common/components/Toast/types.ts @@ -1,8 +1,7 @@ import type { CSSInterpolation } from "@emotion/serialize"; import type { ReactElement } from "react"; -import type { IconName } from "@/components/common/Icon"; - +import type { IconName } from "../Icon"; import type { toastColors } from "./style"; export type ToastType = "success" | "custom"; diff --git a/src/application/hooks/common/index.ts b/src/common/hooks/index.ts similarity index 100% rename from src/application/hooks/common/index.ts rename to src/common/hooks/index.ts diff --git a/src/application/hooks/common/useAnalytics.ts b/src/common/hooks/useAnalytics.ts similarity index 92% rename from src/application/hooks/common/useAnalytics.ts rename to src/common/hooks/useAnalytics.ts index 843b3267..c2c51476 100644 --- a/src/application/hooks/common/useAnalytics.ts +++ b/src/common/hooks/useAnalytics.ts @@ -1,7 +1,7 @@ import { useRouter } from "next/router"; import { useEffect } from "react"; -import * as gtag from "@/application/util"; +import * as gtag from "@/common/utils"; export const useAnalytics = () => { const router = useRouter(); diff --git a/src/application/hooks/common/useClickOutside.ts b/src/common/hooks/useClickOutside.ts similarity index 100% rename from src/application/hooks/common/useClickOutside.ts rename to src/common/hooks/useClickOutside.ts diff --git a/src/application/hooks/common/useClipboard.ts b/src/common/hooks/useClipboard.ts similarity index 100% rename from src/application/hooks/common/useClipboard.ts rename to src/common/hooks/useClipboard.ts diff --git a/src/application/hooks/common/useColoredText.tsx b/src/common/hooks/useColoredText.tsx similarity index 100% rename from src/application/hooks/common/useColoredText.tsx rename to src/common/hooks/useColoredText.tsx diff --git a/src/application/hooks/common/useDebounce.ts b/src/common/hooks/useDebounce.ts similarity index 100% rename from src/application/hooks/common/useDebounce.ts rename to src/common/hooks/useDebounce.ts diff --git a/src/application/hooks/common/useEllipsis.stories.tsx b/src/common/hooks/useEllipsis.stories.tsx similarity index 83% rename from src/application/hooks/common/useEllipsis.stories.tsx rename to src/common/hooks/useEllipsis.stories.tsx index 1b24202c..f325c38e 100644 --- a/src/application/hooks/common/useEllipsis.stories.tsx +++ b/src/common/hooks/useEllipsis.stories.tsx @@ -1,5 +1,6 @@ -import { useEllipsis } from "@/application/hooks"; -import { Button } from "@/components/common/Button"; +import { Button } from "@/common/components/Button"; + +import { useEllipsis } from "./useEllipsis"; export default { title: "hooks/common/useEllipsis", diff --git a/src/application/hooks/common/useEllipsis.ts b/src/common/hooks/useEllipsis.ts similarity index 100% rename from src/application/hooks/common/useEllipsis.ts rename to src/common/hooks/useEllipsis.ts diff --git a/src/application/hooks/common/useInput.ts b/src/common/hooks/useInput.ts similarity index 100% rename from src/application/hooks/common/useInput.ts rename to src/common/hooks/useInput.ts diff --git a/src/application/hooks/common/useIntersect.ts b/src/common/hooks/useIntersect.ts similarity index 100% rename from src/application/hooks/common/useIntersect.ts rename to src/common/hooks/useIntersect.ts diff --git a/src/application/hooks/common/useIsMount.ts b/src/common/hooks/useIsMount.ts similarity index 100% rename from src/application/hooks/common/useIsMount.ts rename to src/common/hooks/useIsMount.ts diff --git a/src/application/hooks/common/useIsomorphicLayoutEffect.ts b/src/common/hooks/useIsomorphicLayoutEffect.ts similarity index 100% rename from src/application/hooks/common/useIsomorphicLayoutEffect.ts rename to src/common/hooks/useIsomorphicLayoutEffect.ts diff --git a/src/application/hooks/common/useLocalStorage.ts b/src/common/hooks/useLocalStorage.ts similarity index 97% rename from src/application/hooks/common/useLocalStorage.ts rename to src/common/hooks/useLocalStorage.ts index bc83bc8a..4f2f34db 100644 --- a/src/application/hooks/common/useLocalStorage.ts +++ b/src/common/hooks/useLocalStorage.ts @@ -1,7 +1,7 @@ import type { SetStateAction } from "react"; import { useCallback, useEffect, useState } from "react"; -import { safeLocalStorage } from "@/application/util"; +import { safeLocalStorage } from "@/common/utils"; type Serializable = T extends string | number | boolean | unknown[] | Record ? T diff --git a/src/application/hooks/common/useLongPress/index.ts b/src/common/hooks/useLongPress/index.ts similarity index 100% rename from src/application/hooks/common/useLongPress/index.ts rename to src/common/hooks/useLongPress/index.ts diff --git a/src/application/hooks/common/useLongPress/types.ts b/src/common/hooks/useLongPress/types.ts similarity index 100% rename from src/application/hooks/common/useLongPress/types.ts rename to src/common/hooks/useLongPress/types.ts diff --git a/src/application/hooks/common/useLongPress/utils.ts b/src/common/hooks/useLongPress/utils.ts similarity index 100% rename from src/application/hooks/common/useLongPress/utils.ts rename to src/common/hooks/useLongPress/utils.ts diff --git a/src/application/hooks/common/useModal.ts b/src/common/hooks/useModal.ts similarity index 100% rename from src/application/hooks/common/useModal.ts rename to src/common/hooks/useModal.ts diff --git a/src/application/hooks/common/useOverlay/OverlayController.tsx b/src/common/hooks/useOverlay/OverlayController.tsx similarity index 100% rename from src/application/hooks/common/useOverlay/OverlayController.tsx rename to src/common/hooks/useOverlay/OverlayController.tsx diff --git a/src/application/hooks/common/useOverlay/OverlayProvider.tsx b/src/common/hooks/useOverlay/OverlayProvider.tsx similarity index 100% rename from src/application/hooks/common/useOverlay/OverlayProvider.tsx rename to src/common/hooks/useOverlay/OverlayProvider.tsx diff --git a/src/application/hooks/common/useOverlay/index.ts b/src/common/hooks/useOverlay/index.ts similarity index 100% rename from src/application/hooks/common/useOverlay/index.ts rename to src/common/hooks/useOverlay/index.ts diff --git a/src/application/hooks/common/useOverlay/types.ts b/src/common/hooks/useOverlay/types.ts similarity index 100% rename from src/application/hooks/common/useOverlay/types.ts rename to src/common/hooks/useOverlay/types.ts diff --git a/src/application/hooks/common/useOverlay/useOverlay.tsx b/src/common/hooks/useOverlay/useOverlay.tsx similarity index 100% rename from src/application/hooks/common/useOverlay/useOverlay.tsx rename to src/common/hooks/useOverlay/useOverlay.tsx diff --git a/src/application/hooks/common/useRouteTracking/RouteTrackingProvider.tsx b/src/common/hooks/useRouteTracking/RouteTrackingProvider.tsx similarity index 89% rename from src/application/hooks/common/useRouteTracking/RouteTrackingProvider.tsx rename to src/common/hooks/useRouteTracking/RouteTrackingProvider.tsx index e3be8959..7a463729 100644 --- a/src/application/hooks/common/useRouteTracking/RouteTrackingProvider.tsx +++ b/src/common/hooks/useRouteTracking/RouteTrackingProvider.tsx @@ -2,7 +2,8 @@ import { useRouter } from "next/router"; import type { PropsWithChildren } from "react"; import { createContext, useEffect } from "react"; -import { useIsMount, useSessionStorage } from "@/application/hooks"; +import { useIsMount } from "../useIsMount"; +import { useSessionStorage } from "../useSessionStorage"; const defaultValue: string[] = []; diff --git a/src/application/hooks/common/useRouteTracking/index.ts b/src/common/hooks/useRouteTracking/index.ts similarity index 100% rename from src/application/hooks/common/useRouteTracking/index.ts rename to src/common/hooks/useRouteTracking/index.ts diff --git a/src/application/hooks/common/useRouteTracking/useRouteTracking.ts b/src/common/hooks/useRouteTracking/useRouteTracking.ts similarity index 100% rename from src/application/hooks/common/useRouteTracking/useRouteTracking.ts rename to src/common/hooks/useRouteTracking/useRouteTracking.ts diff --git a/src/application/hooks/common/useScrollDirection.ts b/src/common/hooks/useScrollDirection.ts similarity index 95% rename from src/application/hooks/common/useScrollDirection.ts rename to src/common/hooks/useScrollDirection.ts index dc4b697e..ad5b88b1 100644 --- a/src/application/hooks/common/useScrollDirection.ts +++ b/src/common/hooks/useScrollDirection.ts @@ -1,6 +1,6 @@ import { useEffect, useRef, useState } from "react"; -import { throttle } from "@/application/util"; +import { throttle } from "@/common/utils"; const SCROLL_DIRECTION = { up: "UP", diff --git a/src/application/hooks/common/useScrollLocker.ts b/src/common/hooks/useScrollLocker.ts similarity index 100% rename from src/application/hooks/common/useScrollLocker.ts rename to src/common/hooks/useScrollLocker.ts diff --git a/src/application/hooks/common/useSessionStorage.ts b/src/common/hooks/useSessionStorage.ts similarity index 100% rename from src/application/hooks/common/useSessionStorage.ts rename to src/common/hooks/useSessionStorage.ts diff --git a/src/application/hooks/common/useToast.ts b/src/common/hooks/useToast.ts similarity index 83% rename from src/application/hooks/common/useToast.ts rename to src/common/hooks/useToast.ts index afc9f00f..9492cef1 100644 --- a/src/application/hooks/common/useToast.ts +++ b/src/common/hooks/useToast.ts @@ -1,8 +1,8 @@ import { useCallback } from "react"; -import { delay } from "@/application/util"; -import { useSetToastContext } from "@/components/common/Toast"; -import type { Toast, ToastOption, ToastType } from "@/components/common/Toast/types"; +import { useSetToastContext } from "@/common/components/Toast"; +import type { Toast, ToastOption, ToastType } from "@/common/components/Toast/types"; +import { delay } from "@/common/utils"; const DEFAULT_TOAST_DELAY = 1000; const ANIMATION_EXPIRE_DELAY = 1000; diff --git a/src/application/hooks/common/useValidation.ts b/src/common/hooks/useValidation.ts similarity index 100% rename from src/application/hooks/common/useValidation.ts rename to src/common/hooks/useValidation.ts diff --git a/src/infra/sdk/channelIO.ts b/src/common/libs/channelIO.ts similarity index 98% rename from src/infra/sdk/channelIO.ts rename to src/common/libs/channelIO.ts index 6b2d90e6..1e0826e7 100644 --- a/src/infra/sdk/channelIO.ts +++ b/src/common/libs/channelIO.ts @@ -1,4 +1,4 @@ -import { IS_CSR } from "@/application/util"; +import { IS_CSR } from "@/common/utils"; export class ChannelService { private static sdk: ChannelService; diff --git a/src/infra/sdk/google.tsx b/src/common/libs/google.tsx similarity index 96% rename from src/infra/sdk/google.tsx rename to src/common/libs/google.tsx index 5a4580e8..bee210ec 100644 --- a/src/infra/sdk/google.tsx +++ b/src/common/libs/google.tsx @@ -1,6 +1,6 @@ import Script from "next/script"; -import * as gtag from "@/application/util"; +import * as gtag from "@/common/utils"; export const GTagScript = () => { return ( diff --git a/src/infra/sdk/index.ts b/src/common/libs/index.ts similarity index 100% rename from src/infra/sdk/index.ts rename to src/common/libs/index.ts diff --git a/src/infra/sdk/kakao.ts b/src/common/libs/kakao.ts similarity index 100% rename from src/infra/sdk/kakao.ts rename to src/common/libs/kakao.ts diff --git a/src/application/util/animation.ts b/src/common/utils/animation.ts similarity index 100% rename from src/application/util/animation.ts rename to src/common/utils/animation.ts diff --git a/src/application/util/constant.ts b/src/common/utils/constant.ts similarity index 100% rename from src/application/util/constant.ts rename to src/common/utils/constant.ts diff --git a/src/application/util/delay.ts b/src/common/utils/delay.ts similarity index 100% rename from src/application/util/delay.ts rename to src/common/utils/delay.ts diff --git a/src/application/util/device.ts b/src/common/utils/device.ts similarity index 100% rename from src/application/util/device.ts rename to src/common/utils/device.ts diff --git a/src/application/util/gtag.ts b/src/common/utils/gtag.ts similarity index 100% rename from src/application/util/gtag.ts rename to src/common/utils/gtag.ts diff --git a/src/application/util/image-util.ts b/src/common/utils/image-util.ts similarity index 100% rename from src/application/util/image-util.ts rename to src/common/utils/image-util.ts diff --git a/src/application/util/index.ts b/src/common/utils/index.ts similarity index 100% rename from src/application/util/index.ts rename to src/common/utils/index.ts diff --git a/src/application/util/path.ts b/src/common/utils/path.ts similarity index 100% rename from src/application/util/path.ts rename to src/common/utils/path.ts diff --git a/src/application/util/storage.ts b/src/common/utils/storage.ts similarity index 100% rename from src/application/util/storage.ts rename to src/common/utils/storage.ts diff --git a/src/application/util/throttle.ts b/src/common/utils/throttle.ts similarity index 100% rename from src/application/util/throttle.ts rename to src/common/utils/throttle.ts diff --git a/src/components/collect/Collection/index.ts b/src/components/collect/Collection/index.ts deleted file mode 100644 index cbb3f0f3..00000000 --- a/src/components/collect/Collection/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./Collection"; diff --git a/src/components/collect/SearchedCollection/index.ts b/src/components/collect/SearchedCollection/index.ts deleted file mode 100644 index 74f09e61..00000000 --- a/src/components/collect/SearchedCollection/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./SearchedCollection"; diff --git a/src/components/common/Modal/ProfileModal.tsx b/src/components/common/Modal/ProfileModal.tsx deleted file mode 100644 index 401443eb..00000000 --- a/src/components/common/Modal/ProfileModal.tsx +++ /dev/null @@ -1,64 +0,0 @@ -import Link from "next/link"; -import { useRouter } from "next/router"; - -import { useAuth, useToast } from "@/application/hooks"; -import { PATH } from "@/application/util"; - -import { DropDown } from "../DropDown"; -import { Icon } from "../Icon"; -import { Photo } from "../Photo"; - -export const ProfileModal = () => { - const { user, logout } = useAuth(); - const { show } = useToast(); - const { push } = useRouter(); - - const handleLogout = () => { - logout(undefined, { - onSuccess: () => push(PATH.getMainPage), - onError: () => show("오류가 발생하였습니다"), - }); - }; - - return ( - <> - - -
- -
-
- - - -
- - {user?.name} -
- - -
- -
- {user?.shareCount} - share -
-
- {user?.saveCount} - collect -
-
- - 로그아웃 - -
-
- - ); -}; diff --git a/src/components/common/Navigation/Navigation.stories.tsx b/src/components/common/Navigation/Navigation.stories.tsx deleted file mode 100644 index d21bc5bb..00000000 --- a/src/components/common/Navigation/Navigation.stories.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import type { ComponentStory } from "@storybook/react"; -import React from "react"; - -import { ExplorePageNavigation } from "./ExplorePageNavigation"; -import { IntroPageNavigation } from "./IntroPageNavigation"; -import { SearchPageNavigation } from "./SearchPageNavigation"; - -export default { - title: "components/common/Navigation", - component: null, -}; - -export const IntroNavigation: ComponentStory = () => ( - -); -export const SearchNavigation: ComponentStory = () => ( - -); -export const ExploreNavigation: ComponentStory = () => ( - -); diff --git a/src/components/common/Navigation/SideBar/SideBar.stories.tsx b/src/components/common/Navigation/SideBar/SideBar.stories.tsx deleted file mode 100644 index fbec0bc4..00000000 --- a/src/components/common/Navigation/SideBar/SideBar.stories.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import type { ComponentMeta, ComponentStory } from "@storybook/react"; - -import { SideBar as _SideBar } from "@/components/common/Navigation/SideBar/SideBar"; - -export default { - title: "components/common/Navigation/SideBar", - component: _SideBar, -} as ComponentMeta; - -export const SideBar: ComponentStory = () => <_SideBar />; diff --git a/src/components/common/PostList/PostItem.tsx b/src/components/common/PostList/PostItem.tsx deleted file mode 100644 index caa5c8ee..00000000 --- a/src/components/common/PostList/PostItem.tsx +++ /dev/null @@ -1,17 +0,0 @@ -interface Post { - id: number; - userId: number; - title: string; - body: string; -} -interface PostItemProps { - post: Post; -} -export const PostItem = ({ post }: PostItemProps) => { - return ( -
  • -

    {post.title}

    -

    {post.body}

    -
  • - ); -}; diff --git a/src/components/common/PostList/PostList.stories.tsx b/src/components/common/PostList/PostList.stories.tsx deleted file mode 100644 index 0fe650d8..00000000 --- a/src/components/common/PostList/PostList.stories.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import type { ComponentMeta, ComponentStory } from "@storybook/react"; -import { rest } from "msw"; -import React from "react"; - -import { PostList } from "./PostList"; - -export default { - title: "Example/PostList", - component: PostList, - // More on argTypes: https://storybook.js.org/docs/react/api/argtypes - argTypes: { - backgroundColor: { control: "color" }, - }, -} as ComponentMeta; - -const MockTemplate: ComponentStory = () => ; - -export const MockedSuccess = MockTemplate.bind({}); - -export const MockedError = MockTemplate.bind({}); -MockedError.parameters = { - msw: { - handlers: [ - rest.get("https://jsonplaceholder.typicode.com/posts", (req, res, ctx) => { - return res(ctx.delay(800), ctx.status(403)); - }), - ], - }, -}; diff --git a/src/components/common/PostList/PostList.tsx b/src/components/common/PostList/PostList.tsx deleted file mode 100644 index 31dde204..00000000 --- a/src/components/common/PostList/PostList.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { useEffect, useState } from "react"; - -import { PostItem } from "./PostItem"; - -interface Post { - id: number; - userId: number; - title: string; - body: string; -} -function useFetchPostList() { - const [status, setStatus] = useState("idle"); - const [data, setData] = useState([]); - - useEffect(() => { - setStatus("loading"); - - fetch("https://jsonplaceholder.typicode.com/posts") - .then((res) => { - if (!res.ok) { - throw new Error(res.statusText); - } - return res; - }) - .then((res) => res.json()) - .then((data) => { - setStatus("success"); - setData(data); - }) - .catch(() => { - setStatus("error"); - }); - }, []); - - return { - status, - data, - }; -} - -export const PostList = () => { - const { status, data: posts } = useFetchPostList(); - - if (status === "loading") { - return

    Fetching Star Wars data...

    ; - } - - if (status === "error") { - return

    Could not fetch Star Wars data

    ; - } - return ( -
      - {posts.map((post) => ( - - ))} -
    - ); -}; diff --git a/src/components/explore/EmptyMemesView/index.ts b/src/components/explore/EmptyMemesView/index.ts deleted file mode 100644 index d7d91c38..00000000 --- a/src/components/explore/EmptyMemesView/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./EmptyMemesView"; diff --git a/src/components/explore/MemesByTag/index.ts b/src/components/explore/MemesByTag/index.ts deleted file mode 100644 index 69c35de0..00000000 --- a/src/components/explore/MemesByTag/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./MemesByTag"; diff --git a/src/components/explore/Thumbnail/index.ts b/src/components/explore/Thumbnail/index.ts deleted file mode 100644 index d376b7af..00000000 --- a/src/components/explore/Thumbnail/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./Thumbnail"; diff --git a/src/components/explore/index.ts b/src/components/explore/index.ts deleted file mode 100644 index d415b828..00000000 --- a/src/components/explore/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./EmptyMemesView"; -export * from "./MemesByKeyword"; -export * from "./MemesByTag"; -export * from "./Thumbnail"; diff --git a/src/components/home/MemeListContainer/DropDown/index.ts b/src/components/home/MemeListContainer/DropDown/index.ts deleted file mode 100644 index 859f7da0..00000000 --- a/src/components/home/MemeListContainer/DropDown/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./MemeSortDropDown"; diff --git a/src/components/home/MemeListContainer/MemeList/UserFindMemeList.tsx b/src/components/home/MemeListContainer/MemeList/UserFindMemeList.tsx deleted file mode 100644 index 86082981..00000000 --- a/src/components/home/MemeListContainer/MemeList/UserFindMemeList.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import { useGetUserFindMemes } from "@/application/hooks"; -import { InfiniteMemeList } from "@/components/meme"; - -interface Props { - userId: number | undefined; -} - -export const UserFindMemeList = ({ userId }: Props) => { - const { - data: memeList, - isFetchingNextPage, - fetchNextPage, - } = useGetUserFindMemes({ - userId: userId as number, - }); - - return ( - fetchNextPage({ cancelRefetch: false })} - /> - ); -}; diff --git a/src/components/home/MemeListContainer/MemeList/index.ts b/src/components/home/MemeListContainer/MemeList/index.ts deleted file mode 100644 index ed83a373..00000000 --- a/src/components/home/MemeListContainer/MemeList/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./CommonMemeList"; -export * from "./UserFindMemeList"; diff --git a/src/components/home/Skeleton/SkeletonMeme.tsx b/src/components/home/Skeleton/SkeletonMeme.tsx deleted file mode 100644 index da59cfe9..00000000 --- a/src/components/home/Skeleton/SkeletonMeme.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { Skeleton } from "@/components/common/Skeleton"; - -import { SkeletonTagList } from "./SkeletonTagList"; - -export const SkeletonMeme = () => { - return ( -
    - - -
    - - -
    - -
    - ); -}; diff --git a/src/components/home/Skeleton/SkeletonTagList.tsx b/src/components/home/Skeleton/SkeletonTagList.tsx deleted file mode 100644 index f2466b12..00000000 --- a/src/components/home/Skeleton/SkeletonTagList.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Skeleton } from "@/components/common/Skeleton"; - -export const SkeletonTagList = ({ count }: { count: number }) => { - return ( -
    - {Array.from(Array(count).keys()).map((i) => ( - - ))} -
    - ); -}; diff --git a/src/components/home/Skeleton/index.ts b/src/components/home/Skeleton/index.ts deleted file mode 100644 index 19129f4d..00000000 --- a/src/components/home/Skeleton/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./SkeletonMeme"; -export * from "./SkeletonTagList"; diff --git a/src/components/home/UserSharedMeme/SharedMemeItem.tsx b/src/components/home/UserSharedMeme/SharedMemeItem.tsx deleted file mode 100644 index 6bdc1f34..00000000 --- a/src/components/home/UserSharedMeme/SharedMemeItem.tsx +++ /dev/null @@ -1,38 +0,0 @@ -import Link from "next/link"; - -import { Icon } from "@/components/common/Icon"; -import { Photo } from "@/components/common/Photo"; -import { SSRSuspense } from "@/components/common/Suspense"; -import type { Meme } from "@/types"; - -import { SkeletonTagList } from "../Skeleton"; -import { SharedMemeTagList } from "./SharedMemeTagList"; - -interface Props { - meme: Meme; -} - -export const SharedMemeItem = ({ meme }: Props) => { - return ( -
  • - -
    - -
    -
    - {meme.name} - - - {meme.shareCount} - -
    - - }> - - -
  • - ); -}; diff --git a/src/components/home/UserSharedMeme/SharedMemeTagList.tsx b/src/components/home/UserSharedMeme/SharedMemeTagList.tsx deleted file mode 100644 index 2bf0bc2b..00000000 --- a/src/components/home/UserSharedMeme/SharedMemeTagList.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import Link from "next/link"; - -import { useGetMemeTagsById } from "@/application/hooks"; -import { PATH } from "@/application/util"; -import { Chip } from "@/components/common/Chip"; - -interface Props { - id: string; -} - -export const SharedMemeTagList = ({ id }: Props) => { - const { tags } = useGetMemeTagsById(id); - - return ( -
      - {tags?.slice(0, 3)?.map((tag) => ( -
    • - - - -
    • - ))} -
    - ); -}; diff --git a/src/components/home/UserSharedMeme/UserSharedMemeList.tsx b/src/components/home/UserSharedMeme/UserSharedMemeList.tsx deleted file mode 100644 index d8a6b3ee..00000000 --- a/src/components/home/UserSharedMeme/UserSharedMemeList.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import Link from "next/link"; -import { css } from "twin.macro"; - -import { useGetMemesByCollectionId } from "@/application/hooks"; -import { Icon } from "@/components/common/Icon"; - -import { SharedMemeItem } from "./SharedMemeItem"; - -interface Props { - name?: string; - sharedId?: number; -} -export const UserSharedMemeList = ({ name, sharedId }: Props) => { - const { data: memeList } = useGetMemesByCollectionId(sharedId as number); - if (!memeList.length) return null; - - return ( -
    - -
    - {`${name} 이(가) 공유했던 밈`} - -
    - -
      - {memeList.map((meme) => ( - - ))} -
    -
    - ); -}; diff --git a/src/components/home/UserSharedMeme/index.ts b/src/components/home/UserSharedMeme/index.ts deleted file mode 100644 index 70d508d6..00000000 --- a/src/components/home/UserSharedMeme/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./UserSharedMemeList"; diff --git a/src/components/meme/ActionSheet/index.ts b/src/components/meme/ActionSheet/index.ts deleted file mode 100644 index 9248829a..00000000 --- a/src/components/meme/ActionSheet/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./MemeActionSheet"; diff --git a/src/components/meme/InfiniteMemeList/index.ts b/src/components/meme/InfiniteMemeList/index.ts deleted file mode 100644 index 435c2149..00000000 --- a/src/components/meme/InfiniteMemeList/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./InfiniteMemeList"; diff --git a/src/components/meme/MemeInfo/Button/CollectionSaveButton.tsx b/src/components/meme/MemeInfo/Button/CollectionSaveButton.tsx deleted file mode 100644 index a6825692..00000000 --- a/src/components/meme/MemeInfo/Button/CollectionSaveButton.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import { useAuth, useCollection } from "@/application/hooks"; -import { Button } from "@/components/common/Button"; -import { Icon } from "@/components/common/Icon"; - -interface Props { - id: string; -} - -export const CollectionSaveButton = ({ id }: Props) => { - const { validate, isLogin } = useAuth(); - const { isAdded, onUpdateCollection } = useCollection({ memeId: Number(id), isLogin }); - - return ( - - ); -}; diff --git a/src/components/meme/MemeInfo/Button/index.ts b/src/components/meme/MemeInfo/Button/index.ts deleted file mode 100644 index bc1b9427..00000000 --- a/src/components/meme/MemeInfo/Button/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./ClipboardCopyButton"; -export * from "./CollectionSaveButton"; -export * from "./KakaoShareButton"; -export * from "./NativeShareButton"; diff --git a/src/components/meme/MemeInfo/MemeCTAList.tsx b/src/components/meme/MemeInfo/MemeCTAList.tsx deleted file mode 100644 index 44aa52ae..00000000 --- a/src/components/meme/MemeInfo/MemeCTAList.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { Suspense } from "react"; - -import { useOverlay } from "@/application/hooks"; -import { Button } from "@/components/common/Button"; -import { Icon } from "@/components/common/Icon"; -import { MemeShareModal } from "@/components/meme/MemeInfo/Modal"; - -import { CollectionSaveButton } from "./Button"; - -interface Props { - id: string; -} - -export const MemeCTAList = ({ id }: Props) => { - const overlay = useOverlay(); - - return ( -
    - - - -
    - ); -}; diff --git a/src/components/meme/MemeInfo/Skeleton/SkeletonMemeTagList.tsx b/src/components/meme/MemeInfo/Skeleton/SkeletonMemeTagList.tsx deleted file mode 100644 index cf6b567b..00000000 --- a/src/components/meme/MemeInfo/Skeleton/SkeletonMemeTagList.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { Skeleton } from "@/components/common/Skeleton"; -import { SkeletonTagList } from "@/components/home/Skeleton"; - -export const SkeletonMemeTagList = () => { - return ( - <> - - - - ); -}; diff --git a/src/components/meme/MemeItem/index.ts b/src/components/meme/MemeItem/index.ts deleted file mode 100644 index 204b7d3d..00000000 --- a/src/components/meme/MemeItem/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./MemeItem"; diff --git a/src/components/meme/index.ts b/src/components/meme/index.ts deleted file mode 100644 index fc0951d3..00000000 --- a/src/components/meme/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./ActionSheet"; -export * from "./InfiniteMemeList"; -export * from "./MemeInfo"; -export * from "./MemeItem"; diff --git a/src/components/mypage/index.ts b/src/components/mypage/index.ts deleted file mode 100644 index 2e435930..00000000 --- a/src/components/mypage/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./SummarizedCollection"; diff --git a/src/components/search/SearchRecent/index.ts b/src/components/search/SearchRecent/index.ts deleted file mode 100644 index ec027fa2..00000000 --- a/src/components/search/SearchRecent/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./SearchRecent"; diff --git a/src/components/search/SearchResult/index.ts b/src/components/search/SearchResult/index.ts deleted file mode 100644 index 40ae39a1..00000000 --- a/src/components/search/SearchResult/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./SearchResultList"; diff --git a/src/components/search/index.ts b/src/components/search/index.ts deleted file mode 100644 index 53bccf20..00000000 --- a/src/components/search/index.ts +++ /dev/null @@ -1,5 +0,0 @@ -export * from "./SearchInput"; -export * from "./SearchItem"; -export * from "./SearchPopular"; -export * from "./SearchRecent"; -export * from "./SearchResult"; diff --git a/src/components/tags/TagCategory/Category.stories.tsx b/src/components/tags/TagCategory/Category.stories.tsx deleted file mode 100644 index 211c6359..00000000 --- a/src/components/tags/TagCategory/Category.stories.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import type { ComponentMeta, ComponentStory } from "@storybook/react"; - -import { CategoryContent } from "./CategoryContent"; - -export default { - title: "components/common/Category", - component: CategoryContent, -} as ComponentMeta; - -export const Default: ComponentStory = () => ; diff --git a/src/components/tags/TagFavoriteButton/index.ts b/src/components/tags/TagFavoriteButton/index.ts deleted file mode 100644 index 3858de9d..00000000 --- a/src/components/tags/TagFavoriteButton/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./TagBookmarkButton"; diff --git a/src/components/tags/index.ts b/src/components/tags/index.ts deleted file mode 100644 index 9bcc64e3..00000000 --- a/src/components/tags/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./TagCategory"; -export * from "./TagFavoriteButton"; diff --git a/src/components/collect/Collection/Collection.tsx b/src/features/collect/components/Collection.tsx similarity index 89% rename from src/components/collect/Collection/Collection.tsx rename to src/features/collect/components/Collection.tsx index 14b45a52..51005fff 100644 --- a/src/components/collect/Collection/Collection.tsx +++ b/src/features/collect/components/Collection.tsx @@ -1,5 +1,5 @@ -import { useGetMemesByCollectionId } from "@/application/hooks"; -import { InfiniteMemeList } from "@/components/meme"; +import { useGetMemesByCollectionId } from "@/api/meme"; +import { InfiniteMemeList } from "@/features/common"; interface Props { collectionId: number; diff --git a/src/components/collect/SearchedCollection/SearchedCollection.tsx b/src/features/collect/components/SearchedCollection.tsx similarity index 90% rename from src/components/collect/SearchedCollection/SearchedCollection.tsx rename to src/features/collect/components/SearchedCollection.tsx index 6b36b5f8..f779c8ce 100644 --- a/src/components/collect/SearchedCollection/SearchedCollection.tsx +++ b/src/features/collect/components/SearchedCollection.tsx @@ -1,5 +1,5 @@ -import { useGetMemesFromCollectionByKeyword } from "@/application/hooks"; -import { InfiniteMemeList } from "@/components/meme"; +import { useGetMemesFromCollectionByKeyword } from "@/api/search"; +import { InfiniteMemeList } from "@/features/common"; interface Props { searchQuery: string; diff --git a/src/components/collect/index.ts b/src/features/collect/components/index.ts similarity index 100% rename from src/components/collect/index.ts rename to src/features/collect/components/index.ts diff --git a/src/components/explore/EmptyMemesView/EmptyMemesView.tsx b/src/features/common/components/EmptyMemesView.tsx similarity index 84% rename from src/components/explore/EmptyMemesView/EmptyMemesView.tsx rename to src/features/common/components/EmptyMemesView.tsx index 0173ea25..c7b449e6 100644 --- a/src/components/explore/EmptyMemesView/EmptyMemesView.tsx +++ b/src/features/common/components/EmptyMemesView.tsx @@ -1,6 +1,6 @@ -import { channelUrl } from "@/application/util"; -import { Button } from "@/components/common/Button"; -import { Icon } from "@/components/common/Icon"; +import { Button } from "@/common/components/Button"; +import { Icon } from "@/common/components/Icon"; +import { channelUrl } from "@/common/utils"; export const EmptyMemesView = () => { return ( diff --git a/src/components/meme/InfiniteMemeList/InfiniteMemeList.tsx b/src/features/common/components/InfiniteMemeList.tsx similarity index 78% rename from src/components/meme/InfiniteMemeList/InfiniteMemeList.tsx rename to src/features/common/components/InfiniteMemeList.tsx index 73aebde4..a1af5d76 100644 --- a/src/components/meme/InfiniteMemeList/InfiniteMemeList.tsx +++ b/src/features/common/components/InfiniteMemeList.tsx @@ -2,12 +2,13 @@ import type { UseInfiniteQueryResult } from "@tanstack/react-query"; import { useQueryClient } from "@tanstack/react-query"; import { useCallback, useMemo } from "react"; -import { prefetchCollectionCheck, useIntersect } from "@/application/hooks"; -import { CORE_QUERY_KEY } from "@/application/hooks/api/core/queryKey"; -import { QUERY_KEYS } from "@/application/hooks/api/meme/queryKey"; -import { Masonry } from "@/components/common/Masonry"; -import { renderMemeItemSkeletons } from "@/components/common/Skeleton"; -import { MemeItem } from "@/components/meme/MemeItem"; +import { useGetCollectionCheck } from "@/api/collection"; +import { CORE_QUERY_KEY } from "@/api/core"; +import { useGetMemeDetailById } from "@/api/meme"; +import { Masonry } from "@/common/components/Masonry"; +import { renderMemeItemSkeletons } from "@/common/components/Skeleton"; +import { useIntersect } from "@/common/hooks"; +import { MemeItem } from "@/features/common"; import type { GetMemesResponse, Meme } from "@/types"; const skeletons = renderMemeItemSkeletons(4); @@ -53,15 +54,15 @@ export const InfiniteMemeList = ({ if (cachedMeme) { queryClient.setQueryData( - QUERY_KEYS.getMemeDetailById(String(cachedMeme.memeId)), + useGetMemeDetailById.queryKey(String(cachedMeme.memeId)), cachedMeme, ); // NOTE: 조회수 증가를 위해 한번 더 밈 상세 api를 fetch 합니다 - queryClient.invalidateQueries(QUERY_KEYS.getMemeDetailById(String(cachedMeme.memeId))); + queryClient.invalidateQueries(useGetMemeDetailById.queryKey(String(cachedMeme.memeId))); // NOTE: collection check api에 waterfall 현상이 일어나기 때문에 prefetch 합니다 - prefetchCollectionCheck(cachedMeme.memeId, queryClient); + useGetCollectionCheck.prefetchQuery(cachedMeme.memeId, queryClient); } }, [queryClient], diff --git a/src/components/meme/ActionSheet/MemeActionSheet.tsx b/src/features/common/components/MemeActionSheet.tsx similarity index 85% rename from src/components/meme/ActionSheet/MemeActionSheet.tsx rename to src/features/common/components/MemeActionSheet.tsx index 78155db3..c1080935 100644 --- a/src/components/meme/ActionSheet/MemeActionSheet.tsx +++ b/src/features/common/components/MemeActionSheet.tsx @@ -1,12 +1,14 @@ import { Suspense } from "react"; import tw from "twin.macro"; -import { useAuth, useCollection, useOverlay } from "@/application/hooks"; -import { channelUrl } from "@/application/util"; -import { ActionSheet } from "@/components/common/ActionSheet"; +import { ActionSheet } from "@/common/components/ActionSheet"; +import { useOverlay } from "@/common/hooks"; +import { channelUrl } from "@/common/utils"; +import { useAuth } from "@/features/common"; +import { MemeShareModal } from "@/features/memes/components"; import type { Meme } from "@/types"; -import { MemeShareModal } from "../MemeInfo/Modal"; +import { useCollection } from "../hooks"; interface Props { meme: Meme; diff --git a/src/components/meme/MemeItem/MemeItem.tsx b/src/features/common/components/MemeItem.tsx similarity index 85% rename from src/components/meme/MemeItem/MemeItem.tsx rename to src/features/common/components/MemeItem.tsx index 5aa67b5e..f06ffc3f 100644 --- a/src/components/meme/MemeItem/MemeItem.tsx +++ b/src/features/common/components/MemeItem.tsx @@ -1,13 +1,12 @@ import { memo } from "react"; -import { useMoveMemeDetail, useOverlay } from "@/application/hooks"; -import { isEncodingError } from "@/application/util"; -import { Icon } from "@/components/common/Icon"; -import { Photo } from "@/components/common/Photo"; +import { Icon } from "@/common/components/Icon"; +import { Photo } from "@/common/components/Photo"; +import { useOverlay } from "@/common/hooks"; +import { isEncodingError } from "@/common/utils"; +import { MemeActionSheet, useMoveMemeDetail } from "@/features/common"; import type { Meme } from "@/types"; -import { MemeActionSheet } from "../ActionSheet"; - interface Props { meme: Meme; onClick?: (id: number) => void; diff --git a/src/components/tags/TagCategory/CategoryContent.tsx b/src/features/common/components/TagCategory/CategoryContent.tsx similarity index 95% rename from src/components/tags/TagCategory/CategoryContent.tsx rename to src/features/common/components/TagCategory/CategoryContent.tsx index 34b3a059..b35b1215 100644 --- a/src/components/tags/TagCategory/CategoryContent.tsx +++ b/src/features/common/components/TagCategory/CategoryContent.tsx @@ -2,10 +2,10 @@ import { Content, Header, Item, Root, Trigger } from "@radix-ui/react-accordion" import { useRouter } from "next/router"; import React, { Fragment } from "react"; -import { useGetCategoryWithTag } from "@/application/hooks"; -import { PATH } from "@/application/util"; -import { Icon } from "@/components/common/Icon"; -import { Photo } from "@/components/common/Photo"; +import { useGetCategoryWithTag } from "@/api/tag"; +import { Icon } from "@/common/components/Icon"; +import { Photo } from "@/common/components/Photo"; +import { PATH } from "@/common/utils"; import { CategoryTitle } from "./CategoryTitle"; import { useTagCategoryContext } from "./context"; diff --git a/src/components/tags/TagCategory/CategoryTitle.tsx b/src/features/common/components/TagCategory/CategoryTitle.tsx similarity index 100% rename from src/components/tags/TagCategory/CategoryTitle.tsx rename to src/features/common/components/TagCategory/CategoryTitle.tsx diff --git a/src/components/tags/TagCategory/FavoriteCategory.tsx b/src/features/common/components/TagCategory/FavoriteCategory.tsx similarity index 92% rename from src/components/tags/TagCategory/FavoriteCategory.tsx rename to src/features/common/components/TagCategory/FavoriteCategory.tsx index 726e342c..75321023 100644 --- a/src/components/tags/TagCategory/FavoriteCategory.tsx +++ b/src/features/common/components/TagCategory/FavoriteCategory.tsx @@ -1,10 +1,12 @@ import { Content, Header, Item, Trigger } from "@radix-ui/react-accordion"; import { useRouter } from "next/router"; -import { useAuth, useDeleteFavoriteTag, useGetFavoriteTags, useToast } from "@/application/hooks"; -import { PATH } from "@/application/util"; -import { Icon } from "@/components/common/Icon"; -import { Photo } from "@/components/common/Photo"; +import { useDeleteFavoriteTag, useGetFavoriteTags } from "@/api/tag"; +import { Icon } from "@/common/components/Icon"; +import { Photo } from "@/common/components/Photo"; +import { useToast } from "@/common/hooks"; +import { PATH } from "@/common/utils"; +import { useAuth } from "@/features/common"; import { CategoryTitle } from "./CategoryTitle"; import { useTagCategoryContext } from "./context"; diff --git a/src/components/tags/TagCategory/SlotCategory.tsx b/src/features/common/components/TagCategory/SlotCategory.tsx similarity index 100% rename from src/components/tags/TagCategory/SlotCategory.tsx rename to src/features/common/components/TagCategory/SlotCategory.tsx diff --git a/src/components/tags/TagCategory/TagCategory.tsx b/src/features/common/components/TagCategory/TagCategory.tsx similarity index 88% rename from src/components/tags/TagCategory/TagCategory.tsx rename to src/features/common/components/TagCategory/TagCategory.tsx index 690d7c04..678a3d4b 100644 --- a/src/components/tags/TagCategory/TagCategory.tsx +++ b/src/features/common/components/TagCategory/TagCategory.tsx @@ -1,8 +1,8 @@ import { css } from "twin.macro"; -import { Drawer } from "@/components/common/Drawer"; -import { Icon } from "@/components/common/Icon"; -import { SSRSuspense } from "@/components/common/Suspense"; +import { Drawer } from "@/common/components/Drawer"; +import { Icon } from "@/common/components/Icon"; +import { SSRSuspense } from "@/common/components/Suspense"; import { CategoryContent } from "./CategoryContent"; import { useTagCategoryContext } from "./context"; diff --git a/src/components/tags/TagCategory/context.tsx b/src/features/common/components/TagCategory/context.tsx similarity index 100% rename from src/components/tags/TagCategory/context.tsx rename to src/features/common/components/TagCategory/context.tsx diff --git a/src/components/tags/TagCategory/index.ts b/src/features/common/components/TagCategory/index.ts similarity index 100% rename from src/components/tags/TagCategory/index.ts rename to src/features/common/components/TagCategory/index.ts diff --git a/src/features/common/components/index.ts b/src/features/common/components/index.ts new file mode 100644 index 00000000..f58d37e7 --- /dev/null +++ b/src/features/common/components/index.ts @@ -0,0 +1,5 @@ +export * from "./EmptyMemesView"; +export * from "./InfiniteMemeList"; +export * from "./MemeActionSheet"; +export * from "./MemeItem"; +export * from "./TagCategory"; diff --git a/src/components/hocs/index.ts b/src/features/common/hocs/index.ts similarity index 100% rename from src/components/hocs/index.ts rename to src/features/common/hocs/index.ts diff --git a/src/components/hocs/withAuth/index.ts b/src/features/common/hocs/withAuth/index.ts similarity index 100% rename from src/components/hocs/withAuth/index.ts rename to src/features/common/hocs/withAuth/index.ts diff --git a/src/components/hocs/withAuth/withAuth.tsx b/src/features/common/hocs/withAuth/withAuth.tsx similarity index 90% rename from src/components/hocs/withAuth/withAuth.tsx rename to src/features/common/hocs/withAuth/withAuth.tsx index 5573b614..48e665b8 100644 --- a/src/components/hocs/withAuth/withAuth.tsx +++ b/src/features/common/hocs/withAuth/withAuth.tsx @@ -2,7 +2,8 @@ import { useRouter } from "next/router"; import type { ComponentType } from "react"; import { useEffect } from "react"; -import { useAuth, useToast } from "@/application/hooks"; +import { useToast } from "@/common/hooks"; +import { useAuth } from "@/features/common"; export const withAuth = (WrappedComponent: ComponentType) => { const displayName = WrappedComponent.displayName || WrappedComponent.name || "Component"; diff --git a/src/features/common/hooks/index.ts b/src/features/common/hooks/index.ts new file mode 100644 index 00000000..3431fa9c --- /dev/null +++ b/src/features/common/hooks/index.ts @@ -0,0 +1,4 @@ +export * from "./useAuth"; +export * from "./useChannelIO"; +export * from "./useCollection"; +export * from "./useMoveMemeDetail"; diff --git a/src/application/hooks/domain/auth/useAuth.ts b/src/features/common/hooks/useAuth.ts similarity index 84% rename from src/application/hooks/domain/auth/useAuth.ts rename to src/features/common/hooks/useAuth.ts index 73ad1fa2..4ca5c862 100644 --- a/src/application/hooks/domain/auth/useAuth.ts +++ b/src/features/common/hooks/useAuth.ts @@ -1,8 +1,8 @@ import { useCallback } from "react"; -import { useGetMyAccount, useLogout } from "@/application/hooks"; -import { useSignUpModalContext } from "@/components/common/Modal"; -import { api } from "@/infra/api"; +import { useGetMyAccount, useLogout } from "@/api/account"; +import { api } from "@/api/core"; +import { useSignUpModalContext } from "@/common/components/Modal"; type Handler = (...args: any[]) => unknown; interface ValidatorOptions { diff --git a/src/application/hooks/domain/channel/useChannelIO.ts b/src/features/common/hooks/useChannelIO.ts similarity index 94% rename from src/application/hooks/domain/channel/useChannelIO.ts rename to src/features/common/hooks/useChannelIO.ts index 642f37e8..31de5210 100644 --- a/src/application/hooks/domain/channel/useChannelIO.ts +++ b/src/features/common/hooks/useChannelIO.ts @@ -1,6 +1,6 @@ import { useEffect } from "react"; -import { ChannelService } from "@/infra/sdk"; +import { ChannelService } from "@/common/libs"; import type { User } from "@/types"; interface Props { diff --git a/src/application/hooks/domain/collection/useCollection.tsx b/src/features/common/hooks/useCollection.tsx similarity index 96% rename from src/application/hooks/domain/collection/useCollection.tsx rename to src/features/common/hooks/useCollection.tsx index 1e7e08fa..5ae60c50 100644 --- a/src/application/hooks/domain/collection/useCollection.tsx +++ b/src/features/common/hooks/useCollection.tsx @@ -4,8 +4,8 @@ import { useDeleteMemeFromCollection, useGetCollectionCheck, usePostMemeToCollection, - useToast, -} from "@/application/hooks"; +} from "@/api/collection"; +import { useToast } from "@/common/hooks"; const TAG_DELETE_DELAY = 3000; diff --git a/src/application/hooks/domain/meme/useMoveMemeDetail.ts b/src/features/common/hooks/useMoveMemeDetail.ts similarity index 91% rename from src/application/hooks/domain/meme/useMoveMemeDetail.ts rename to src/features/common/hooks/useMoveMemeDetail.ts index 2a5a8be1..d502c06a 100644 --- a/src/application/hooks/domain/meme/useMoveMemeDetail.ts +++ b/src/features/common/hooks/useMoveMemeDetail.ts @@ -1,6 +1,6 @@ import { useRouter } from "next/router"; -import { PATH } from "@/application/util"; +import { PATH } from "@/common/utils"; export const useMoveMemeDetail = () => { const router = useRouter(); diff --git a/src/features/common/index.ts b/src/features/common/index.ts new file mode 100644 index 00000000..67700710 --- /dev/null +++ b/src/features/common/index.ts @@ -0,0 +1,3 @@ +export * from "./components"; +export * from "./hocs"; +export * from "./hooks"; diff --git a/src/components/explore/MemesByKeyword/MemesByKeyword.tsx b/src/features/explore/keywords/components/MemesByKeyword.tsx similarity index 73% rename from src/components/explore/MemesByKeyword/MemesByKeyword.tsx rename to src/features/explore/keywords/components/MemesByKeyword.tsx index 23f1bfc1..0493af13 100644 --- a/src/components/explore/MemesByKeyword/MemesByKeyword.tsx +++ b/src/features/explore/keywords/components/MemesByKeyword.tsx @@ -1,7 +1,5 @@ -import { useGetMemesByKeyword } from "@/application/hooks"; -import { InfiniteMemeList } from "@/components/meme"; - -import { EmptyMemesView } from "../EmptyMemesView"; +import { useGetMemesByKeyword } from "@/api/search"; +import { EmptyMemesView, InfiniteMemeList } from "@/features/common"; interface Props { searchQuery: string; diff --git a/src/components/explore/MemesByKeyword/index.tsx b/src/features/explore/keywords/components/index.ts similarity index 100% rename from src/components/explore/MemesByKeyword/index.tsx rename to src/features/explore/keywords/components/index.ts diff --git a/src/components/explore/MemesByTag/MemesByTag.tsx b/src/features/explore/tags/components/MemesByTag.tsx similarity index 73% rename from src/components/explore/MemesByTag/MemesByTag.tsx rename to src/features/explore/tags/components/MemesByTag.tsx index 29324cf9..6afe3096 100644 --- a/src/components/explore/MemesByTag/MemesByTag.tsx +++ b/src/features/explore/tags/components/MemesByTag.tsx @@ -1,7 +1,5 @@ -import { useGetMemesByTag } from "@/application/hooks"; -import { InfiniteMemeList } from "@/components/meme"; - -import { EmptyMemesView } from "../EmptyMemesView"; +import { useGetMemesByTag } from "@/api/search"; +import { EmptyMemesView, InfiniteMemeList } from "@/features/common"; interface Props { searchQuery: string; diff --git a/src/components/tags/TagFavoriteButton/TagBookmarkButton.tsx b/src/features/explore/tags/components/TagBookmarkButton.tsx similarity index 90% rename from src/components/tags/TagFavoriteButton/TagBookmarkButton.tsx rename to src/features/explore/tags/components/TagBookmarkButton.tsx index 17e2dde2..5ef79c39 100644 --- a/src/components/tags/TagFavoriteButton/TagBookmarkButton.tsx +++ b/src/features/explore/tags/components/TagBookmarkButton.tsx @@ -1,14 +1,8 @@ -import { - useAuth, - useDeleteFavoriteTag, - useGetTagInfo, - usePostFavoriteTag, - useToast, -} from "@/application/hooks"; -import { Button } from "@/components/common/Button"; -import { Icon } from "@/components/common/Icon"; - -import { useTagCategoryContext } from "../TagCategory"; +import { useDeleteFavoriteTag, useGetTagInfo, usePostFavoriteTag } from "@/api/tag"; +import { Button } from "@/common/components/Button"; +import { Icon } from "@/common/components/Icon"; +import { useToast } from "@/common/hooks"; +import { useAuth, useTagCategoryContext } from "@/features/common"; interface Props { tagId: number; diff --git a/src/components/explore/Thumbnail/Thumbnail.tsx b/src/features/explore/tags/components/Thumbnail.tsx similarity index 86% rename from src/components/explore/Thumbnail/Thumbnail.tsx rename to src/features/explore/tags/components/Thumbnail.tsx index 406479d3..70adce29 100644 --- a/src/components/explore/Thumbnail/Thumbnail.tsx +++ b/src/features/explore/tags/components/Thumbnail.tsx @@ -1,8 +1,9 @@ import { useRouter } from "next/router"; -import { useClipboard, useGetMemesByTag, useToast } from "@/application/hooks"; -import { DOMAIN } from "@/application/util"; -import { Photo } from "@/components/common/Photo"; +import { useGetMemesByTag } from "@/api/search"; +import { Photo } from "@/common/components/Photo"; +import { useClipboard, useToast } from "@/common/hooks"; +import { DOMAIN } from "@/common/utils"; interface Props { tag: string; diff --git a/src/features/explore/tags/components/index.ts b/src/features/explore/tags/components/index.ts new file mode 100644 index 00000000..a1e08c4e --- /dev/null +++ b/src/features/explore/tags/components/index.ts @@ -0,0 +1,3 @@ +export * from "./MemesByTag"; +export * from "./TagBookmarkButton"; +export * from "./Thumbnail"; diff --git a/src/components/home/MemeListContainer/MemeList/CommonMemeList.tsx b/src/features/home/components/MemeListContainer/CommonMemeList.tsx similarity index 70% rename from src/components/home/MemeListContainer/MemeList/CommonMemeList.tsx rename to src/features/home/components/MemeListContainer/CommonMemeList.tsx index 46bcaca1..25a07b46 100644 --- a/src/components/home/MemeListContainer/MemeList/CommonMemeList.tsx +++ b/src/features/home/components/MemeListContainer/CommonMemeList.tsx @@ -1,7 +1,7 @@ -import { useGetMemesBySort } from "@/application/hooks"; -import { InfiniteMemeList } from "@/components/meme"; +import { useGetMemesBySort } from "@/api/meme"; +import { InfiniteMemeList } from "@/features/common"; -import type { MemeListType } from "../type"; +import type { MemeListType } from "./type"; interface Props { sortBy: MemeListType; diff --git a/src/components/home/MemeListContainer/MemeListContainer.tsx b/src/features/home/components/MemeListContainer/MemeListContainer.tsx similarity index 63% rename from src/components/home/MemeListContainer/MemeListContainer.tsx rename to src/features/home/components/MemeListContainer/MemeListContainer.tsx index 609d7cc4..8cca537c 100644 --- a/src/components/home/MemeListContainer/MemeListContainer.tsx +++ b/src/features/home/components/MemeListContainer/MemeListContainer.tsx @@ -1,10 +1,10 @@ import { useState } from "react"; -import { MemeListSkeleton } from "@/components/common/Skeleton"; -import { SSRSuspense } from "@/components/common/Suspense"; +import { MemeListSkeleton } from "@/common/components/Skeleton"; +import { SSRSuspense } from "@/common/components/Suspense"; -import { MemeSortDropDown } from "./DropDown"; -import { CommonMemeList } from "./MemeList"; +import { CommonMemeList } from "./CommonMemeList"; +import { MemeSortDropDown } from "./MemeSortDropDown"; import type { MemeListType } from "./type"; export const MemeListContainer = () => { diff --git a/src/components/home/MemeListContainer/DropDown/MemeSortDropDown.tsx b/src/features/home/components/MemeListContainer/MemeSortDropDown.tsx similarity index 94% rename from src/components/home/MemeListContainer/DropDown/MemeSortDropDown.tsx rename to src/features/home/components/MemeListContainer/MemeSortDropDown.tsx index bb8da01b..7b39d40d 100644 --- a/src/components/home/MemeListContainer/DropDown/MemeSortDropDown.tsx +++ b/src/features/home/components/MemeListContainer/MemeSortDropDown.tsx @@ -2,10 +2,10 @@ import type { Dispatch, SetStateAction } from "react"; import { startTransition, useCallback } from "react"; import { css } from "twin.macro"; -import { DropDown } from "@/components/common/DropDown"; -import { Icon } from "@/components/common/Icon"; +import { DropDown } from "@/common/components/DropDown"; +import { Icon } from "@/common/components/Icon"; -import type { MemeListType } from "../type"; +import type { MemeListType } from "./type"; interface Props { sortBy: MemeListType; diff --git a/src/components/home/MemeListContainer/index.ts b/src/features/home/components/MemeListContainer/index.ts similarity index 100% rename from src/components/home/MemeListContainer/index.ts rename to src/features/home/components/MemeListContainer/index.ts diff --git a/src/components/home/MemeListContainer/type.ts b/src/features/home/components/MemeListContainer/type.ts similarity index 100% rename from src/components/home/MemeListContainer/type.ts rename to src/features/home/components/MemeListContainer/type.ts diff --git a/src/components/home/index.ts b/src/features/home/components/index.ts similarity index 52% rename from src/components/home/index.ts rename to src/features/home/components/index.ts index 36a1e823..460b4644 100644 --- a/src/components/home/index.ts +++ b/src/features/home/components/index.ts @@ -1,2 +1 @@ export * from "./MemeListContainer"; -export * from "./UserSharedMeme"; diff --git a/src/features/memes/components/MemeCTAList.tsx b/src/features/memes/components/MemeCTAList.tsx new file mode 100644 index 00000000..dc92c863 --- /dev/null +++ b/src/features/memes/components/MemeCTAList.tsx @@ -0,0 +1,62 @@ +import { Suspense } from "react"; + +import { Button } from "@/common/components/Button"; +import { Icon } from "@/common/components/Icon"; +import { useOverlay } from "@/common/hooks"; +import { useAuth, useCollection } from "@/features/common"; + +import { MemeShareModal } from "./MemeShareModal"; + +interface MemeCTAListProps { + id: string; +} + +export const MemeCTAList = ({ id }: MemeCTAListProps) => { + const overlay = useOverlay(); + + return ( +
    + + + +
    + ); +}; + +interface CollectionSaveButtonProps { + id: string; +} +const CollectionSaveButton = ({ id }: CollectionSaveButtonProps) => { + const { validate, isLogin } = useAuth(); + const { isAdded, onUpdateCollection } = useCollection({ memeId: Number(id), isLogin }); + + return ( + + ); +}; diff --git a/src/components/meme/MemeInfo/MemeDetail.stories.tsx b/src/features/memes/components/MemeDetail/MemeDetail.stories.tsx similarity index 83% rename from src/components/meme/MemeInfo/MemeDetail.stories.tsx rename to src/features/memes/components/MemeDetail/MemeDetail.stories.tsx index 82c2dd44..ef3f62db 100644 --- a/src/components/meme/MemeInfo/MemeDetail.stories.tsx +++ b/src/features/memes/components/MemeDetail/MemeDetail.stories.tsx @@ -1,6 +1,6 @@ import type { ComponentMeta, ComponentStory } from "@storybook/react"; -import { MemeDetail } from "@/components/meme/MemeInfo"; +import { MemeDetail } from "./MemeDetail"; export default { title: "components/meme/MemeDetail", diff --git a/src/components/meme/MemeInfo/MemeDetail.tsx b/src/features/memes/components/MemeDetail/MemeDetail.tsx similarity index 84% rename from src/components/meme/MemeInfo/MemeDetail.tsx rename to src/features/memes/components/MemeDetail/MemeDetail.tsx index a75cb715..74978b5a 100644 --- a/src/components/meme/MemeInfo/MemeDetail.tsx +++ b/src/features/memes/components/MemeDetail/MemeDetail.tsx @@ -1,9 +1,10 @@ import { css } from "twin.macro"; -import { useMemeDetailById } from "@/application/hooks"; -import { Photo } from "@/components/common/Photo"; -import { SSRSuspense } from "@/components/common/Suspense"; -import { MemeExport } from "@/components/meme/MemeInfo/DropDown/MemeExport"; +import { useGetMemeDetailById } from "@/api/meme"; +import { Photo } from "@/common/components/Photo"; +import { SSRSuspense } from "@/common/components/Suspense"; + +import { MemeExport } from "./MemeExport"; interface Props { id: string; @@ -18,7 +19,7 @@ export const MemeDetail = ({ id }: Props) => { description, image: { images }, isRefetching, - } = useMemeDetailById(id); + } = useGetMemeDetailById(id); const { imageUrl, imageWidth, imageHeight } = images[0]; diff --git a/src/components/meme/MemeInfo/DropDown/MemeExport.tsx b/src/features/memes/components/MemeDetail/MemeExport.tsx similarity index 82% rename from src/components/meme/MemeInfo/DropDown/MemeExport.tsx rename to src/features/memes/components/MemeDetail/MemeExport.tsx index ad365aed..5597d360 100644 --- a/src/components/meme/MemeInfo/DropDown/MemeExport.tsx +++ b/src/features/memes/components/MemeDetail/MemeExport.tsx @@ -1,22 +1,19 @@ import tw from "twin.macro"; -import { - useAuth, - useCollection, - useMemeDetailById, - usePostMemeToSharedCollection, - useToast, -} from "@/application/hooks"; -import { DOMAIN, PATH } from "@/application/util"; -import { DropDown } from "@/components/common/DropDown"; -import { Icon } from "@/components/common/Icon"; +import { usePostMemeToSharedCollection } from "@/api/collection"; +import { useGetMemeDetailById } from "@/api/meme"; +import { DropDown } from "@/common/components/DropDown"; +import { Icon } from "@/common/components/Icon"; +import { useToast } from "@/common/hooks"; +import { DOMAIN, PATH } from "@/common/utils"; +import { useAuth, useCollection } from "@/features/common"; interface Props { id: string; } export const MemeExport = ({ id }: Props) => { - const { name, description } = useMemeDetailById(id); + const { name, description } = useGetMemeDetailById(id); const { validate, isLogin, user } = useAuth(); const { onUpdateCollection } = useCollection({ memeId: Number(id), isLogin }); diff --git a/src/features/memes/components/MemeDetail/index.ts b/src/features/memes/components/MemeDetail/index.ts new file mode 100644 index 00000000..7bfbabb2 --- /dev/null +++ b/src/features/memes/components/MemeDetail/index.ts @@ -0,0 +1 @@ +export * from "./MemeDetail"; diff --git a/src/components/meme/MemeInfo/Button/ClipboardCopyButton.tsx b/src/features/memes/components/MemeShareModal/ClipboardCopyButton.tsx similarity index 75% rename from src/components/meme/MemeInfo/Button/ClipboardCopyButton.tsx rename to src/features/memes/components/MemeShareModal/ClipboardCopyButton.tsx index d07e32df..315e7bda 100644 --- a/src/components/meme/MemeInfo/Button/ClipboardCopyButton.tsx +++ b/src/features/memes/components/MemeShareModal/ClipboardCopyButton.tsx @@ -1,6 +1,6 @@ -import { useClipboard } from "@/application/hooks"; -import { Button } from "@/components/common/Button"; -import { Icon } from "@/components/common/Icon"; +import { Button } from "@/common/components/Button"; +import { Icon } from "@/common/components/Icon"; +import { useClipboard } from "@/common/hooks"; interface Props { target: string; diff --git a/src/components/meme/MemeInfo/Button/KakaoShareButton.tsx b/src/features/memes/components/MemeShareModal/KakaoShareButton.tsx similarity index 68% rename from src/components/meme/MemeInfo/Button/KakaoShareButton.tsx rename to src/features/memes/components/MemeShareModal/KakaoShareButton.tsx index 0b07bf49..d92e444b 100644 --- a/src/components/meme/MemeInfo/Button/KakaoShareButton.tsx +++ b/src/features/memes/components/MemeShareModal/KakaoShareButton.tsx @@ -1,7 +1,8 @@ -import type { KakaoShareOptions } from "@/application/hooks/domain/share"; -import { useKakaoShare } from "@/application/hooks/domain/share"; -import { Button } from "@/components/common/Button"; -import { Icon } from "@/components/common/Icon"; +import { Button } from "@/common/components/Button"; +import { Icon } from "@/common/components/Icon"; + +import type { KakaoShareOptions } from "../../hooks"; +import { useKakaoShare } from "../../hooks"; interface Props { resource: Omit; diff --git a/src/components/meme/MemeInfo/Modal/MemeShareModal.tsx b/src/features/memes/components/MemeShareModal/MemeShareModal.tsx similarity index 81% rename from src/components/meme/MemeInfo/Modal/MemeShareModal.tsx rename to src/features/memes/components/MemeShareModal/MemeShareModal.tsx index 32625fdd..281fcb0a 100644 --- a/src/components/meme/MemeInfo/Modal/MemeShareModal.tsx +++ b/src/features/memes/components/MemeShareModal/MemeShareModal.tsx @@ -1,13 +1,14 @@ -import { useAuth, useMemeDetailById, useToast } from "@/application/hooks"; -import { usePostMemeToSharedCollection } from "@/application/hooks/api/collection"; -import { DOMAIN, PATH } from "@/application/util"; -import { Modal } from "@/components/common/Modal"; -import { Photo } from "@/components/common/Photo"; -import { - ClipboardCopyButton, - KakaoShareButton, - NativeShareButton, -} from "@/components/meme/MemeInfo/Button"; +import { usePostMemeToSharedCollection } from "@/api/collection"; +import { useGetMemeDetailById } from "@/api/meme"; +import { Modal } from "@/common/components/Modal"; +import { Photo } from "@/common/components/Photo"; +import { useToast } from "@/common/hooks"; +import { DOMAIN, PATH } from "@/common/utils"; +import { useAuth } from "@/features/common"; + +import { ClipboardCopyButton } from "./ClipboardCopyButton"; +import { KakaoShareButton } from "./KakaoShareButton"; +import { NativeShareButton } from "./NativeShareButton"; interface Props { id: string; @@ -23,7 +24,7 @@ export const MemeShareModal = ({ id, isOpen, onClose }: Props) => { name, description, image: { images }, - } = useMemeDetailById(id); + } = useGetMemeDetailById(id); const src = images[0].imageUrl; diff --git a/src/components/meme/MemeInfo/Button/NativeShareButton.tsx b/src/features/memes/components/MemeShareModal/NativeShareButton.tsx similarity index 89% rename from src/components/meme/MemeInfo/Button/NativeShareButton.tsx rename to src/features/memes/components/MemeShareModal/NativeShareButton.tsx index 76917b03..5bf0e335 100644 --- a/src/components/meme/MemeInfo/Button/NativeShareButton.tsx +++ b/src/features/memes/components/MemeShareModal/NativeShareButton.tsx @@ -1,5 +1,5 @@ -import { Button } from "@/components/common/Button"; -import { Icon } from "@/components/common/Icon"; +import { Button } from "@/common/components/Button"; +import { Icon } from "@/common/components/Icon"; interface Props { title: string; diff --git a/src/components/meme/MemeInfo/Modal/index.ts b/src/features/memes/components/MemeShareModal/index.ts similarity index 100% rename from src/components/meme/MemeInfo/Modal/index.ts rename to src/features/memes/components/MemeShareModal/index.ts diff --git a/src/components/meme/MemeInfo/MemeTagList.tsx b/src/features/memes/components/MemeTagList.tsx similarity index 88% rename from src/components/meme/MemeInfo/MemeTagList.tsx rename to src/features/memes/components/MemeTagList.tsx index 0b425ac2..3794e0be 100644 --- a/src/components/meme/MemeInfo/MemeTagList.tsx +++ b/src/features/memes/components/MemeTagList.tsx @@ -1,7 +1,7 @@ import Link from "next/link"; -import { useGetMemeTagsById } from "@/application/hooks"; -import { PATH } from "@/application/util"; +import { useGetMemeTagsById } from "@/api/tag"; +import { PATH } from "@/common/utils"; interface Props { id: string; diff --git a/src/components/meme/MemeInfo/RelativeMemeList.tsx b/src/features/memes/components/RelativeMemeList.tsx similarity index 80% rename from src/components/meme/MemeInfo/RelativeMemeList.tsx rename to src/features/memes/components/RelativeMemeList.tsx index 4de95573..cecc1950 100644 --- a/src/components/meme/MemeInfo/RelativeMemeList.tsx +++ b/src/features/memes/components/RelativeMemeList.tsx @@ -1,5 +1,5 @@ -import { useAuth, useGetMemesBySort } from "@/application/hooks"; -import { InfiniteMemeList } from "@/components/meme"; +import { useGetMemesBySort } from "@/api/meme"; +import { InfiniteMemeList, useAuth } from "@/features/common"; export const RelativeMemeList = () => { const { data: memeList, isFetchingNextPage, fetchNextPage } = useGetMemesBySort("popular"); diff --git a/src/components/meme/MemeInfo/Skeleton/SkeletonMemeDetail.tsx b/src/features/memes/components/Skeleton/SkeletonMemeDetail.tsx similarity index 87% rename from src/components/meme/MemeInfo/Skeleton/SkeletonMemeDetail.tsx rename to src/features/memes/components/Skeleton/SkeletonMemeDetail.tsx index 1e20912c..dc156608 100644 --- a/src/components/meme/MemeInfo/Skeleton/SkeletonMemeDetail.tsx +++ b/src/features/memes/components/Skeleton/SkeletonMemeDetail.tsx @@ -1,5 +1,6 @@ -import { Skeleton } from "@/components/common/Skeleton"; -import { SkeletonMemeTagList } from "@/components/meme"; +import { Skeleton } from "@/common/components/Skeleton"; + +import { SkeletonMemeTagList } from "./SkeletonMemeTagList"; export const SkeletonMemeDetail = () => { return ( diff --git a/src/features/memes/components/Skeleton/SkeletonMemeTagList.tsx b/src/features/memes/components/Skeleton/SkeletonMemeTagList.tsx new file mode 100644 index 00000000..4122f556 --- /dev/null +++ b/src/features/memes/components/Skeleton/SkeletonMemeTagList.tsx @@ -0,0 +1,27 @@ +import { Skeleton } from "@/common/components/Skeleton"; + +export const SkeletonMemeTagList = () => { + return ( + <> + +
    + {Array.from(Array(3).keys()).map((i) => ( + + ))} +
    + + ); +}; diff --git a/src/components/meme/MemeInfo/Skeleton/index.ts b/src/features/memes/components/Skeleton/index.ts similarity index 100% rename from src/components/meme/MemeInfo/Skeleton/index.ts rename to src/features/memes/components/Skeleton/index.ts diff --git a/src/components/meme/MemeInfo/index.ts b/src/features/memes/components/index.ts similarity index 82% rename from src/components/meme/MemeInfo/index.ts rename to src/features/memes/components/index.ts index 14c0cb61..d4cfabdf 100644 --- a/src/components/meme/MemeInfo/index.ts +++ b/src/features/memes/components/index.ts @@ -1,5 +1,6 @@ export * from "./MemeCTAList"; export * from "./MemeDetail"; +export * from "./MemeShareModal"; export * from "./MemeTagList"; export * from "./RelativeMemeList"; export * from "./Skeleton"; diff --git a/src/application/hooks/domain/share/index.ts b/src/features/memes/hooks/index.ts similarity index 100% rename from src/application/hooks/domain/share/index.ts rename to src/features/memes/hooks/index.ts diff --git a/src/application/hooks/domain/share/useKakaoShare.ts b/src/features/memes/hooks/useKakaoShare.ts similarity index 97% rename from src/application/hooks/domain/share/useKakaoShare.ts rename to src/features/memes/hooks/useKakaoShare.ts index cedd4272..cbb1a676 100644 --- a/src/application/hooks/domain/share/useKakaoShare.ts +++ b/src/features/memes/hooks/useKakaoShare.ts @@ -1,6 +1,6 @@ import { useCallback } from "react"; -import { KakaoSDK } from "@/infra/sdk"; +import { KakaoSDK } from "@/common/libs"; export interface KakaoShareOptions { title: string; diff --git a/src/components/mypage/SummarizedCollection/SummarizedCollection.tsx b/src/features/mypage/components/SummarizedCollection.tsx similarity index 89% rename from src/components/mypage/SummarizedCollection/SummarizedCollection.tsx rename to src/features/mypage/components/SummarizedCollection.tsx index 2689e8de..c99843b5 100644 --- a/src/components/mypage/SummarizedCollection/SummarizedCollection.tsx +++ b/src/features/mypage/components/SummarizedCollection.tsx @@ -1,6 +1,6 @@ -import { useGetMemesByCollectionId } from "@/application/hooks"; -import { Masonry } from "@/components/common/Masonry"; -import { MemeItem } from "@/components/meme/MemeItem"; +import { useGetMemesByCollectionId } from "@/api/meme"; +import { Masonry } from "@/common/components/Masonry"; +import { MemeItem } from "@/features/common"; interface Props { collectionId: number; diff --git a/src/components/mypage/SummarizedCollection/index.ts b/src/features/mypage/components/index.ts similarity index 100% rename from src/components/mypage/SummarizedCollection/index.ts rename to src/features/mypage/components/index.ts diff --git a/src/components/search/SearchInput/SearchInput.stories.tsx b/src/features/search/components/SearchInput/SearchInput.stories.tsx similarity index 100% rename from src/components/search/SearchInput/SearchInput.stories.tsx rename to src/features/search/components/SearchInput/SearchInput.stories.tsx diff --git a/src/components/search/SearchInput/SearchInput.tsx b/src/features/search/components/SearchInput/SearchInput.tsx similarity index 92% rename from src/components/search/SearchInput/SearchInput.tsx rename to src/features/search/components/SearchInput/SearchInput.tsx index 7813023d..cde405b2 100644 --- a/src/components/search/SearchInput/SearchInput.tsx +++ b/src/features/search/components/SearchInput/SearchInput.tsx @@ -1,7 +1,7 @@ import type { InputHTMLAttributes } from "react"; -import { Icon } from "@/components/common/Icon"; -import { InputBase } from "@/components/common/Input"; +import { Icon } from "@/common/components/Icon"; +import { InputBase } from "@/common/components/Input"; interface Props extends InputHTMLAttributes { onReset?: () => void; diff --git a/src/components/search/SearchInput/index.ts b/src/features/search/components/SearchInput/index.ts similarity index 100% rename from src/components/search/SearchInput/index.ts rename to src/features/search/components/SearchInput/index.ts diff --git a/src/components/search/SearchItem/SearchItem.tsx b/src/features/search/components/SearchItem/SearchItem.tsx similarity index 93% rename from src/components/search/SearchItem/SearchItem.tsx rename to src/features/search/components/SearchItem/SearchItem.tsx index 62290abe..fc1c3911 100644 --- a/src/components/search/SearchItem/SearchItem.tsx +++ b/src/features/search/components/SearchItem/SearchItem.tsx @@ -1,6 +1,6 @@ import type { HTMLAttributes, ReactNode } from "react"; -import { useColoredText } from "@/application/hooks"; +import { useColoredText } from "@/common/hooks"; interface SearchItemProps extends HTMLAttributes { searchText?: string; diff --git a/src/components/search/SearchItem/index.ts b/src/features/search/components/SearchItem/index.ts similarity index 100% rename from src/components/search/SearchItem/index.ts rename to src/features/search/components/SearchItem/index.ts diff --git a/src/components/search/SearchItem/searchItem.stories.tsx b/src/features/search/components/SearchItem/searchItem.stories.tsx similarity index 91% rename from src/components/search/SearchItem/searchItem.stories.tsx rename to src/features/search/components/SearchItem/searchItem.stories.tsx index 28083090..5011c92c 100644 --- a/src/components/search/SearchItem/searchItem.stories.tsx +++ b/src/features/search/components/SearchItem/searchItem.stories.tsx @@ -1,6 +1,6 @@ import type { ComponentMeta } from "@storybook/react"; -import { Chip } from "@/components/common/Chip"; +import { Chip } from "@/common/components/Chip"; import { SearchItem } from "./SearchItem"; diff --git a/src/components/search/SearchPopular/SearchPopularItem.tsx b/src/features/search/components/SearchPopularList/SearchPopularItem.tsx similarity index 93% rename from src/components/search/SearchPopular/SearchPopularItem.tsx rename to src/features/search/components/SearchPopularList/SearchPopularItem.tsx index 8a65ad0f..3fe7808f 100644 --- a/src/components/search/SearchPopular/SearchPopularItem.tsx +++ b/src/features/search/components/SearchPopularList/SearchPopularItem.tsx @@ -1,6 +1,6 @@ import type { HTMLAttributes } from "react"; -import { Photo } from "@/components/common/Photo"; +import { Photo } from "@/common/components/Photo"; interface Props extends HTMLAttributes { name: string; diff --git a/src/components/search/SearchPopular/SearchPopularList.tsx b/src/features/search/components/SearchPopularList/SearchPopularList.tsx similarity index 84% rename from src/components/search/SearchPopular/SearchPopularList.tsx rename to src/features/search/components/SearchPopularList/SearchPopularList.tsx index bf07867c..8922a4f6 100644 --- a/src/components/search/SearchPopular/SearchPopularList.tsx +++ b/src/features/search/components/SearchPopularList/SearchPopularList.tsx @@ -1,9 +1,9 @@ import Link from "next/link"; -import type { RecentSearch } from "@/application/hooks"; -import { useGetPopularTags } from "@/application/hooks"; -import { PATH } from "@/application/util"; +import { useGetPopularTags } from "@/api/tag"; +import { PATH } from "@/common/utils"; +import type { RecentSearch } from "../../hooks"; import { SearchPopularItem } from "./SearchPopularItem"; interface Props { diff --git a/src/components/search/SearchPopular/index.ts b/src/features/search/components/SearchPopularList/index.ts similarity index 100% rename from src/components/search/SearchPopular/index.ts rename to src/features/search/components/SearchPopularList/index.ts diff --git a/src/components/search/SearchRecent/SearchRecent.tsx b/src/features/search/components/SearchRecent.tsx similarity index 86% rename from src/components/search/SearchRecent/SearchRecent.tsx rename to src/features/search/components/SearchRecent.tsx index bd5b4078..ff21f32e 100644 --- a/src/components/search/SearchRecent/SearchRecent.tsx +++ b/src/features/search/components/SearchRecent.tsx @@ -1,11 +1,11 @@ import { useRouter } from "next/router"; -import type { RecentSearch } from "@/application/hooks"; -import { isTagType } from "@/application/hooks"; -import { PATH } from "@/application/util"; -import { Icon } from "@/components/common/Icon"; +import { Icon } from "@/common/components/Icon"; +import { PATH } from "@/common/utils"; -import { SearchItem } from "../SearchItem"; +import type { RecentSearch } from "../hooks"; +import { isTagType } from "../hooks"; +import { SearchItem } from "./SearchItem"; interface Props { items: RecentSearch[]; diff --git a/src/components/search/SearchResult/SearchResultList.tsx b/src/features/search/components/SearchResultList.tsx similarity index 77% rename from src/components/search/SearchResult/SearchResultList.tsx rename to src/features/search/components/SearchResultList.tsx index 00f07d3d..e65485e5 100644 --- a/src/components/search/SearchResult/SearchResultList.tsx +++ b/src/features/search/components/SearchResultList.tsx @@ -1,10 +1,11 @@ import Link from "next/link"; -import type { RecentSearch } from "@/application/hooks"; -import { useGetTagSearch } from "@/application/hooks"; -import { PATH } from "@/application/util"; -import { Icon } from "@/components/common/Icon"; -import { SearchItem } from "@/components/search"; +import { useGetTagSearch } from "@/api/tag"; +import { Icon } from "@/common/components/Icon"; +import { PATH } from "@/common/utils"; + +import type { RecentSearch } from "../hooks"; +import { SearchItem } from "./SearchItem"; interface Prop { value: string; diff --git a/src/components/search/Skeleton/SkeletonTagList.tsx b/src/features/search/components/Skeleton/SkeletonTagList.tsx similarity index 86% rename from src/components/search/Skeleton/SkeletonTagList.tsx rename to src/features/search/components/Skeleton/SkeletonTagList.tsx index 57dfb3d5..8b16184b 100644 --- a/src/components/search/Skeleton/SkeletonTagList.tsx +++ b/src/features/search/components/Skeleton/SkeletonTagList.tsx @@ -1,4 +1,4 @@ -import { Skeleton } from "@/components/common/Skeleton"; +import { Skeleton } from "@/common/components/Skeleton"; export const SkeletonTagList = () => { return ( diff --git a/src/components/search/Skeleton/index.ts b/src/features/search/components/Skeleton/index.ts similarity index 100% rename from src/components/search/Skeleton/index.ts rename to src/features/search/components/Skeleton/index.ts diff --git a/src/features/search/components/index.ts b/src/features/search/components/index.ts new file mode 100644 index 00000000..b410eaed --- /dev/null +++ b/src/features/search/components/index.ts @@ -0,0 +1,6 @@ +export * from "./SearchInput"; +export * from "./SearchItem"; +export * from "./SearchPopularList"; +export * from "./SearchRecent"; +export * from "./SearchResultList"; +export * from "./Skeleton"; diff --git a/src/application/hooks/domain/search/index.ts b/src/features/search/hooks/index.ts similarity index 100% rename from src/application/hooks/domain/search/index.ts rename to src/features/search/hooks/index.ts diff --git a/src/application/hooks/domain/search/useRecentSearch/index.ts b/src/features/search/hooks/useRecentSearch/index.ts similarity index 100% rename from src/application/hooks/domain/search/useRecentSearch/index.ts rename to src/features/search/hooks/useRecentSearch/index.ts diff --git a/src/application/hooks/domain/search/useRecentSearch/types.ts b/src/features/search/hooks/useRecentSearch/types.ts similarity index 100% rename from src/application/hooks/domain/search/useRecentSearch/types.ts rename to src/features/search/hooks/useRecentSearch/types.ts diff --git a/src/application/hooks/domain/search/useRecentSearch/useRecentSearch.ts b/src/features/search/hooks/useRecentSearch/useRecentSearch.ts similarity index 94% rename from src/application/hooks/domain/search/useRecentSearch/useRecentSearch.ts rename to src/features/search/hooks/useRecentSearch/useRecentSearch.ts index c24475f4..bf1fdddb 100644 --- a/src/application/hooks/domain/search/useRecentSearch/useRecentSearch.ts +++ b/src/features/search/hooks/useRecentSearch/useRecentSearch.ts @@ -1,4 +1,4 @@ -import { useLocalStorage } from "@/application/hooks/common"; +import { useLocalStorage } from "@/common/hooks"; import type { RecentSearch } from "./types"; diff --git a/src/application/hooks/domain/search/useRecentSearch/utils.ts b/src/features/search/hooks/useRecentSearch/utils.ts similarity index 100% rename from src/application/hooks/domain/search/useRecentSearch/utils.ts rename to src/features/search/hooks/useRecentSearch/utils.ts diff --git a/src/components/share/SharedMemeList.tsx b/src/features/share/components/SharedMemeList.tsx similarity index 76% rename from src/components/share/SharedMemeList.tsx rename to src/features/share/components/SharedMemeList.tsx index 6ece3a2d..13953f5c 100644 --- a/src/components/share/SharedMemeList.tsx +++ b/src/features/share/components/SharedMemeList.tsx @@ -1,5 +1,5 @@ -import { useGetMemesByCollectionId } from "@/application/hooks"; -import { InfiniteMemeList } from "@/components/meme"; +import { useGetMemesByCollectionId } from "@/api/meme"; +import { InfiniteMemeList } from "@/features/common"; interface Props { sharedId: number; diff --git a/src/components/share/index.ts b/src/features/share/components/index.ts similarity index 100% rename from src/components/share/index.ts rename to src/features/share/components/index.ts diff --git a/src/infra/api/auth/index.ts b/src/infra/api/auth/index.ts index b7557fdd..6e4db499 100644 --- a/src/infra/api/auth/index.ts +++ b/src/infra/api/auth/index.ts @@ -1,7 +1,7 @@ import type { AxiosInstance, AxiosRequestConfig } from "axios"; import { isAxiosError } from "axios"; -import { IS_CSR } from "@/application/util"; +import { IS_CSR } from "@/common/utils"; import type { RefreshResponse } from "@/infra/api/auth/types"; export class AuthApi { diff --git a/src/infra/api/tags/index.ts b/src/infra/api/tags/index.ts index 615ef7ff..fc36e5ae 100644 --- a/src/infra/api/tags/index.ts +++ b/src/infra/api/tags/index.ts @@ -6,6 +6,7 @@ import type { GetMemeTagsByIdResponse, GetPopularTagsResponse, GetTagInfoResponse, + GetTagSearchResponse, } from "./types"; export class TagApi { @@ -25,7 +26,7 @@ export class TagApi { } //NOTE : api response에 categoryName 없음 check return this.api - .get("/tags/search", { + .get("/tags/search", { params: { word: value, }, diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index c1ff7e0a..689c912e 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -5,15 +5,15 @@ import Head from "next/head"; import { useRouter } from "next/router"; import { useEffect } from "react"; -import { OverlayProvider, RouteTrackingProvider, useAnalytics } from "@/application/hooks"; -import { QueryClientProvider } from "@/application/queryClient"; -import { QueryErrorBoundary } from "@/components/common/ErrorBoundary"; -import { Layout } from "@/components/common/Layout"; -import { SignUpModal, SignUpModalProvider } from "@/components/common/Modal"; -import { ToastContainer, ToastProvider } from "@/components/common/Toast"; -import { TagCategoryProvider } from "@/components/tags"; -import { GoogleTagManagerScript, GTagScript } from "@/infra/sdk"; -import type { DefaultPageProps } from "@/types"; +import type { DefaultPageProps } from "@/api/core"; +import { QueryClientProvider } from "@/api/core"; +import { QueryErrorBoundary } from "@/common/components/ErrorBoundary"; +import { Layout } from "@/common/components/Layout"; +import { SignUpModal, SignUpModalProvider } from "@/common/components/Modal"; +import { ToastContainer, ToastProvider } from "@/common/components/Toast"; +import { OverlayProvider, RouteTrackingProvider, useAnalytics } from "@/common/hooks"; +import { GoogleTagManagerScript, GTagScript } from "@/common/libs"; +import { TagCategoryProvider } from "@/features/common"; if (process.env.NEXT_PUBLIC_API_MOCKING === "enabled") { await import("../../mocks"); diff --git a/src/pages/_error.tsx b/src/pages/_error.tsx index 4df9477b..0b75efb9 100644 --- a/src/pages/_error.tsx +++ b/src/pages/_error.tsx @@ -1,7 +1,7 @@ import { captureException } from "@sentry/nextjs"; import type { NextPageContext } from "next"; -import { Navigation } from "@/components/common/Navigation"; +import { Navigation } from "@/common/components/Navigation"; interface Props { statusCode: number; diff --git a/src/pages/collect/index.tsx b/src/pages/collect/index.tsx index b691b6af..b1903d41 100644 --- a/src/pages/collect/index.tsx +++ b/src/pages/collect/index.tsx @@ -1,12 +1,12 @@ import { useDeferredValue } from "react"; -import { useAuth, useDebounce, useInput } from "@/application/hooks"; -import { Collection, SearchedCollection } from "@/components/collect"; -import { BackButtonNavigation } from "@/components/common/Navigation"; -import { MemeListSkeleton } from "@/components/common/Skeleton"; -import { SSRSuspense } from "@/components/common/Suspense"; -import { withAuth } from "@/components/hocs"; -import { SearchInput } from "@/components/search"; +import { BackButtonNavigation } from "@/common/components/Navigation"; +import { MemeListSkeleton } from "@/common/components/Skeleton"; +import { SSRSuspense } from "@/common/components/Suspense"; +import { useDebounce, useInput } from "@/common/hooks"; +import { Collection, SearchedCollection } from "@/features/collect/components"; +import { useAuth, withAuth } from "@/features/common"; +import { SearchInput } from "@/features/search/components"; const CollectPage = () => { const inputProps = useInput(); diff --git a/src/pages/explore/keywords/index.tsx b/src/pages/explore/keywords/index.tsx index 6d7a9cd0..592f8711 100644 --- a/src/pages/explore/keywords/index.tsx +++ b/src/pages/explore/keywords/index.tsx @@ -1,13 +1,13 @@ import type { GetServerSideProps, NextPage } from "next"; -import { DEFAULT_DESCRIPTION, SITE_NAME } from "@/application/util"; -import { ExplorePageNavigation } from "@/components/common/Navigation"; -import type { NextSeoProps } from "@/components/common/NextSeo"; -import { NextSeo } from "@/components/common/NextSeo"; -import { PullToRefresh } from "@/components/common/PullToRefresh"; -import { MemeListSkeleton } from "@/components/common/Skeleton"; -import { SSRSuspense } from "@/components/common/Suspense"; -import { MemesByKeyword } from "@/components/explore"; +import { ExplorePageNavigation } from "@/common/components/Navigation"; +import type { NextSeoProps } from "@/common/components/NextSeo"; +import { NextSeo } from "@/common/components/NextSeo"; +import { PullToRefresh } from "@/common/components/PullToRefresh"; +import { MemeListSkeleton } from "@/common/components/Skeleton"; +import { SSRSuspense } from "@/common/components/Suspense"; +import { DEFAULT_DESCRIPTION, SITE_NAME } from "@/common/utils"; +import { MemesByKeyword } from "@/features/explore/keywords/components"; interface Props { searchQuery: string; diff --git a/src/pages/explore/tags/[tagId].tsx b/src/pages/explore/tags/[tagId].tsx index 653a34af..095d6326 100644 --- a/src/pages/explore/tags/[tagId].tsx +++ b/src/pages/explore/tags/[tagId].tsx @@ -1,13 +1,13 @@ import { dehydrate, QueryClient } from "@tanstack/react-query"; import type { GetStaticPaths, GetStaticProps, NextPage } from "next"; -import { fetchTagInfo, prefetchMemesByTag } from "@/application/hooks"; -import { DEFAULT_DESCRIPTION, SITE_NAME } from "@/application/util"; -import { ExplorePageNavigation } from "@/components/common/Navigation"; -import { NextSeo } from "@/components/common/NextSeo"; -import { PullToRefresh } from "@/components/common/PullToRefresh"; -import { MemesByTag, Thumbnail } from "@/components/explore"; -import { TagBookmarkButton } from "@/components/tags"; +import { useGetMemesByTag } from "@/api/search"; +import { useGetTagInfo } from "@/api/tag"; +import { ExplorePageNavigation } from "@/common/components/Navigation"; +import { NextSeo } from "@/common/components/NextSeo"; +import { PullToRefresh } from "@/common/components/PullToRefresh"; +import { DEFAULT_DESCRIPTION, SITE_NAME } from "@/common/utils"; +import { MemesByTag, TagBookmarkButton, Thumbnail } from "@/features/explore/tags/components"; interface Props { searchQuery: string; @@ -58,10 +58,10 @@ export const getStaticProps: GetStaticProps = async ({ params }) => { } try { - const { name: tagName } = await fetchTagInfo(Number(tagId), queryClient); + const { name: tagName } = await useGetTagInfo.fetchQuery(Number(tagId), queryClient); // NOTE: tag name 이 api request 값이기 때문에 waterfall 한 fetching 이 필요합니다 - await prefetchMemesByTag(tagName, queryClient); + await useGetMemesByTag.fetchInfiniteQuery(tagName, queryClient); return { props: { diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 41311072..c8c0d1d4 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,11 +1,11 @@ import type { NextPage } from "next"; -import { DEFAULT_DESCRIPTION, SITE_NAME } from "@/application/util"; -import { IntroPageNavigation } from "@/components/common/Navigation"; -import type { NextSeoProps } from "@/components/common/NextSeo"; -import { NextSeo } from "@/components/common/NextSeo"; -import { PullToRefresh } from "@/components/common/PullToRefresh"; -import { MemeListContainer } from "@/components/home"; +import { IntroPageNavigation } from "@/common/components/Navigation"; +import type { NextSeoProps } from "@/common/components/NextSeo"; +import { NextSeo } from "@/common/components/NextSeo"; +import { PullToRefresh } from "@/common/components/PullToRefresh"; +import { DEFAULT_DESCRIPTION, SITE_NAME } from "@/common/utils"; +import { MemeListContainer } from "@/features/home/components"; const HomePage: NextPage = () => { return ( diff --git a/src/pages/memes/[id].tsx b/src/pages/memes/[id].tsx index 17d3711a..041ace35 100644 --- a/src/pages/memes/[id].tsx +++ b/src/pages/memes/[id].tsx @@ -2,12 +2,15 @@ import { dehydrate, QueryClient } from "@tanstack/react-query"; import type { GetStaticPaths, GetStaticProps, NextPage } from "next"; import { Suspense } from "react"; -import { fetchMemeDetailById, fetchMemeTagsById, useMoveMemeDetail } from "@/application/hooks"; -import { SITE_NAME } from "@/application/util"; -import { ExplorePageNavigation } from "@/components/common/Navigation"; -import { NextSeo } from "@/components/common/NextSeo"; -import { MemeListSkeleton, Skeleton } from "@/components/common/Skeleton"; -import { SSRSuspense } from "@/components/common/Suspense"; +import type { DefaultPageProps } from "@/api/core"; +import { useGetMemeDetailById } from "@/api/meme"; +import { useGetMemeTagsById } from "@/api/tag"; +import { ExplorePageNavigation } from "@/common/components/Navigation"; +import { NextSeo } from "@/common/components/NextSeo"; +import { MemeListSkeleton, Skeleton } from "@/common/components/Skeleton"; +import { SSRSuspense } from "@/common/components/Suspense"; +import { SITE_NAME } from "@/common/utils"; +import { useMoveMemeDetail } from "@/features/common"; import { MemeCTAList, MemeDetail, @@ -15,8 +18,8 @@ import { RelativeMemeList, SkeletonMemeDetail, SkeletonMemeTagList, -} from "@/components/meme"; -import type { DefaultPageProps, Meme } from "@/types"; +} from "@/features/memes/components"; +import type { Meme } from "@/types"; interface Props { id: string; @@ -86,8 +89,8 @@ export const getStaticProps: GetStaticProps< try { const [{ description, name, image }] = await Promise.all([ - fetchMemeDetailById(id, queryClient), - fetchMemeTagsById(id, queryClient), + useGetMemeDetailById.fetchQuery(id, queryClient), + useGetMemeTagsById.fetchQuery(id, queryClient), ]); return { diff --git a/src/pages/mypage/index.tsx b/src/pages/mypage/index.tsx index 606c17cc..0877649b 100644 --- a/src/pages/mypage/index.tsx +++ b/src/pages/mypage/index.tsx @@ -1,14 +1,13 @@ import Link from "next/link"; import { css } from "twin.macro"; -import { useAuth, useChannelIO } from "@/application/hooks"; -import { Icon } from "@/components/common/Icon"; -import { MyPageNavigation } from "@/components/common/Navigation"; -import { Photo } from "@/components/common/Photo"; -import { MemeListSkeleton, Skeleton } from "@/components/common/Skeleton"; -import { SSRSuspense } from "@/components/common/Suspense"; -import { withAuth } from "@/components/hocs"; -import { SummarizedCollection } from "@/components/mypage"; +import { Icon } from "@/common/components/Icon"; +import { MyPageNavigation } from "@/common/components/Navigation"; +import { Photo } from "@/common/components/Photo"; +import { MemeListSkeleton, Skeleton } from "@/common/components/Skeleton"; +import { SSRSuspense } from "@/common/components/Suspense"; +import { useAuth, useChannelIO, withAuth } from "@/features/common"; +import { SummarizedCollection } from "@/features/mypage/components"; const MyPage = () => { const { isLoading, user } = useAuth(); diff --git a/src/pages/oauth2/redirect/index.tsx b/src/pages/oauth2/redirect/index.tsx index e6f75b0c..90cab596 100644 --- a/src/pages/oauth2/redirect/index.tsx +++ b/src/pages/oauth2/redirect/index.tsx @@ -1,7 +1,7 @@ import Router from "next/router"; import React, { useEffect } from "react"; -import { useAuth } from "@/application/hooks"; +import { useAuth } from "@/features/common"; const KaKaoRedirect = () => { const { login } = useAuth(); diff --git a/src/pages/search/index.tsx b/src/pages/search/index.tsx index 0af014f6..3eebe1ae 100644 --- a/src/pages/search/index.tsx +++ b/src/pages/search/index.tsx @@ -2,19 +2,20 @@ import type { NextPage } from "next"; import { useRouter } from "next/router"; import { Suspense } from "react"; -import { useDebounce, useInput, useRecentSearch } from "@/application/hooks"; -import { DEFAULT_DESCRIPTION, PATH, SITE_NAME } from "@/application/util"; -import { SearchPageNavigation } from "@/components/common/Navigation"; -import type { NextSeoProps } from "@/components/common/NextSeo"; -import { NextSeo } from "@/components/common/NextSeo"; -import { SSRSuspense } from "@/components/common/Suspense"; +import { SearchPageNavigation } from "@/common/components/Navigation"; +import type { NextSeoProps } from "@/common/components/NextSeo"; +import { NextSeo } from "@/common/components/NextSeo"; +import { SSRSuspense } from "@/common/components/Suspense"; +import { useDebounce, useInput } from "@/common/hooks"; +import { DEFAULT_DESCRIPTION, PATH, SITE_NAME } from "@/common/utils"; import { SearchInput, SearchPopularList, SearchRecent, SearchResultList, -} from "@/components/search"; -import { SkeletonTagList } from "@/components/search/Skeleton"; + SkeletonTagList, +} from "@/features/search/components"; +import { useRecentSearch } from "@/features/search/hooks"; /** * FIX diff --git a/src/pages/setting/index.tsx b/src/pages/setting/index.tsx index b10225ec..11aa2272 100644 --- a/src/pages/setting/index.tsx +++ b/src/pages/setting/index.tsx @@ -1,9 +1,9 @@ -import { useAuth, useChannelIO, useModal } from "@/application/hooks"; -import { Button } from "@/components/common/Button"; -import { SignOutModal } from "@/components/common/Modal"; -import { BackButtonNavigation } from "@/components/common/Navigation"; -import { Photo } from "@/components/common/Photo"; -import { withAuth } from "@/components/hocs"; +import { Button } from "@/common/components/Button"; +import { SignOutModal } from "@/common/components/Modal"; +import { BackButtonNavigation } from "@/common/components/Navigation"; +import { Photo } from "@/common/components/Photo"; +import { useModal } from "@/common/hooks"; +import { useAuth, useChannelIO, withAuth } from "@/features/common"; const SettingPage = () => { const modalProps = useModal(); diff --git a/src/pages/share/index.tsx b/src/pages/share/index.tsx index 0e45d561..fbd98830 100644 --- a/src/pages/share/index.tsx +++ b/src/pages/share/index.tsx @@ -1,11 +1,10 @@ import type { NextPage } from "next"; -import { useAuth } from "@/application/hooks"; -import { BackButtonNavigation } from "@/components/common/Navigation"; -import { MemeListSkeleton } from "@/components/common/Skeleton"; -import { SSRSuspense } from "@/components/common/Suspense"; -import { withAuth } from "@/components/hocs"; -import { SharedMemeList } from "@/components/share"; +import { BackButtonNavigation } from "@/common/components/Navigation"; +import { MemeListSkeleton } from "@/common/components/Skeleton"; +import { SSRSuspense } from "@/common/components/Suspense"; +import { useAuth, withAuth } from "@/features/common"; +import { SharedMemeList } from "@/features/share/components"; const SharedHistoryPage: NextPage = () => { const { user } = useAuth(); diff --git a/src/types/index.d.ts b/src/types/index.d.ts index f822ec27..5b69e55b 100644 --- a/src/types/index.d.ts +++ b/src/types/index.d.ts @@ -1,11 +1,3 @@ -import type { ComponentProps } from "react"; - -import type { QueryClientProvider } from "@/application/queryClient"; - -export interface DefaultPageProps { - hydrateState: ComponentProps["hydrateState"]; -} - export interface Meme { memeId: number; name: string; diff --git a/tailwind.config.js b/tailwind.config.js index 4bce28a1..4ca338e0 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -9,8 +9,8 @@ const PX0_50 = { ...Array.from(Array(51)).map((_, i) => `${i / 10}rem`) }; module.exports = { content: [ "./src/pages/**/*.{js,ts,jsx,tsx}", - "./src/components/**/*.{js,ts,jsx,tsx}", - "./src/application/**/*.{js,ts,jsx,tsx}", + "./src/features/**/*.{js,ts,jsx,tsx}", + "./src/common/**/*.{js,ts,jsx,tsx}", ], safelist: [{ pattern: /line-clamp-/ }], theme: {