Skip to content

Commit

Permalink
Release: 업로드 버튼 추가 배포 (#67)
Browse files Browse the repository at this point in the history
  • Loading branch information
ojj1123 authored Oct 1, 2023
2 parents 756a6e7 + 3789716 commit 8ed3f06
Show file tree
Hide file tree
Showing 314 changed files with 1,198 additions and 1,545 deletions.
18 changes: 0 additions & 18 deletions .husky/prepare-commit-msg

This file was deleted.

31 changes: 17 additions & 14 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -16,17 +17,19 @@ export const decorators = [
mswDecorator,
(Story) => (
<QueryClientProvider>
<ToastProvider>
<SignUpModalProvider>
<Suspense fallback="loading...">
<div className="__font_family_variables font-pretendard">
<ToastContainer />
<SignUpModal />
<Story />
</div>
</Suspense>
</SignUpModalProvider>
</ToastProvider>
<OverlayProvider>
<ToastProvider>
<SignUpModalProvider>
<Suspense fallback="loading...">
<div className="__font_family_variables font-pretendard">
<ToastContainer />
<SignUpModal />
<Story />
</div>
</Suspense>
</SignUpModalProvider>
</ToastProvider>
</OverlayProvider>
</QueryClientProvider>
),
];
Expand Down
8 changes: 1 addition & 7 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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")({
Expand Down
2 changes: 2 additions & 0 deletions src/api/account/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./useGetMyAccount";
export * from "./useLogout";
19 changes: 19 additions & 0 deletions src/api/account/useGetMyAccount.ts
Original file line number Diff line number Diff line change
@@ -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();
15 changes: 15 additions & 0 deletions src/api/account/useLogout.ts
Original file line number Diff line number Diff line change
@@ -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);
},
});
};
4 changes: 4 additions & 0 deletions src/api/collection/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from "./useDeleteMemeFromCollection";
export * from "./useGetCollectionCheck";
export * from "./usePostMemeToCollection";
export * from "./usePostMemeToSharedCollection";
40 changes: 40 additions & 0 deletions src/api/collection/useDeleteMemeFromCollection.ts
Original file line number Diff line number Diff line change
@@ -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,
);
},
});
};
29 changes: 29 additions & 0 deletions src/api/collection/useGetCollectionCheck.ts
Original file line number Diff line number Diff line change
@@ -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<UseQueryOptions, "enabled">,
) => {
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),
});
40 changes: 40 additions & 0 deletions src/api/collection/usePostMemeToCollection.ts
Original file line number Diff line number Diff line change
@@ -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,
);
},
});
};
23 changes: 23 additions & 0 deletions src/api/collection/usePostMemeToSharedCollection.ts
Original file line number Diff line number Diff line change
@@ -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 });
},
});
};
9 changes: 4 additions & 5 deletions src/infra/api/index.ts → src/api/core/axios.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}`,
Expand Down
5 changes: 5 additions & 0 deletions src/api/core/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export * from "./axios";
export * from "./query-client";
export * from "./queryKey";
export * from "./useCoreInfiniteQuery";
export * from "./useSuspensedQuery";
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof QueryClientProvider>["hydrateState"];
}

interface Props {
hydrateState?: DehydratedState;
children: ReactNode;
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -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<TData>
extends Omit<
UseQueryResult<TData, never>,
"data" | "status" | "error" | "isLoading" | "isError" | "isFetching"
> {
data: TData;
status: "success" | "idle";
}

export type SuspendedUseQueryResultOnSuccess<TData> = BaseSuspendedUseQueryResult<TData> & {
status: "success";
isSuccess: true;
isIdle: false;
};
export type SuspendedUseQueryResultOnIdle<TData> = BaseSuspendedUseQueryResult<TData> & {
status: "idle";
isSuccess: false;
isIdle: true;
};

export type SuspendedUseQueryOptions<
TQueryFnData = unknown,
TError = unknown,
TData = TQueryFnData,
TQueryKey extends QueryKey = QueryKey,
> = Omit<UseQueryOptions<TQueryFnData, TError, TData, TQueryKey>, "suspense">;

export type QuerySelectOption<Result, API extends (...args: any) => any> = (
data: Awaited<ReturnType<API>>,
) => Result;
/**
* @desc suspense 사용 시 non-nullable data 이도록 wrapping
* @link https://github.com/toss/slash/blob/main/packages/react/react-query/src/hooks/useSuspendedQuery.ts
Expand Down
3 changes: 3 additions & 0 deletions src/api/meme/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from "./useGetMemeDetailById";
export * from "./useGetMemesByCollectionId";
export * from "./useGetMemesBySort";
24 changes: 24 additions & 0 deletions src/api/meme/useGetMemeDetailById.ts
Original file line number Diff line number Diff line change
@@ -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));
Loading

1 comment on commit 8ed3f06

@vercel
Copy link

@vercel vercel bot commented on 8ed3f06 Oct 1, 2023

Choose a reason for hiding this comment

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

Please sign in to comment.