From 554bc6652f3326a90a7a46f602e969150ef8f912 Mon Sep 17 00:00:00 2001 From: soomin9106 Date: Wed, 26 Jun 2024 22:21:45 +0900 Subject: [PATCH 01/11] refactor: divide subscription and workbook --- .eslintrc.json | 1 + src/app/unsubscribe/page.tsx | 4 ++-- src/app/workbook/[id]/page.tsx | 3 ++- src/app/workbook/[id]/unsubscribe/page.tsx | 4 ++-- .../components/SubscribeForm/SubscribeForm.test.tsx | 0 .../components/SubscribeForm/index.tsx | 0 .../components/SubscribeFormField/index.tsx | 0 .../components/UnsubscribeForm/UnsubscribeForm.test.tsx | 0 .../components/UnsubscribeForm/index.tsx | 0 .../components/UnsubscribeFormField/index.tsx | 0 .../components/UnsubscribeTitle/index.tsx | 0 src/{workbook => subscription}/hooks/useUnsubscribeForm.tsx | 0 src/{workbook => subscription}/schemas/index.ts | 0 src/subscription/types/subscription.ts | 5 +++++ src/workbook/types/index.ts | 6 ------ tsconfig.json | 3 ++- vitest.config.ts | 1 + 17 files changed, 15 insertions(+), 12 deletions(-) rename src/{workbook => subscription}/components/SubscribeForm/SubscribeForm.test.tsx (100%) rename src/{workbook => subscription}/components/SubscribeForm/index.tsx (100%) rename src/{workbook => subscription}/components/SubscribeFormField/index.tsx (100%) rename src/{workbook => subscription}/components/UnsubscribeForm/UnsubscribeForm.test.tsx (100%) rename src/{workbook => subscription}/components/UnsubscribeForm/index.tsx (100%) rename src/{workbook => subscription}/components/UnsubscribeFormField/index.tsx (100%) rename src/{workbook => subscription}/components/UnsubscribeTitle/index.tsx (100%) rename src/{workbook => subscription}/hooks/useUnsubscribeForm.tsx (100%) rename src/{workbook => subscription}/schemas/index.ts (100%) create mode 100644 src/subscription/types/subscription.ts diff --git a/.eslintrc.json b/.eslintrc.json index bc8590f2..d368db34 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -45,6 +45,7 @@ ["^@api/(.*)$"], ["^@shared/(.*)$"], ["^@workbook/(.*)$"], + ["^@subscription/(.*)$"], ["^@article/(.*)$"], ["^@quiz/(.*)$"], ["^@main/(.*)$"], diff --git a/src/app/unsubscribe/page.tsx b/src/app/unsubscribe/page.tsx index d1caf7e5..95ebf52f 100644 --- a/src/app/unsubscribe/page.tsx +++ b/src/app/unsubscribe/page.tsx @@ -1,7 +1,7 @@ "use client"; -import UnsubscribeForm from "@workbook/components/UnsubscribeForm"; -import UnsubscribeTitle from "@workbook/components/UnsubscribeTitle"; +import UnsubscribeForm from "@subscription/components/UnsubscribeForm"; +import UnsubscribeTitle from "@subscription/components/UnsubscribeTitle"; export default function UnsubscribePage() { diff --git a/src/app/workbook/[id]/page.tsx b/src/app/workbook/[id]/page.tsx index 95a5e571..2b42934a 100644 --- a/src/app/workbook/[id]/page.tsx +++ b/src/app/workbook/[id]/page.tsx @@ -13,12 +13,13 @@ import TitleSection from "@shared/components/TitleSection"; import CurriculumSection from "@workbook/components/CurriculumSection"; import OverviewSection from "@workbook/components/OverviewSection"; -import SubscribeForm from "@workbook/components/SubscribeForm"; import WorkbookSkeleton from "@workbook/components/WorkbookSkeleton"; import WriterInfo from "@workbook/components/WriterInfo"; import { getWorkbookQueryOptions } from "@workbook/remotes/getWorkbookQueryOptions"; import { getWorkbookId } from "@workbook/utils"; +import SubscribeForm from "@subscription/components/SubscribeForm"; + import SubscribeBottomBar from "@main/components/SubscribeBottomBar"; import { SUBSCRIBE_TITLES } from "@main/constants/main"; diff --git a/src/app/workbook/[id]/unsubscribe/page.tsx b/src/app/workbook/[id]/unsubscribe/page.tsx index d0af377d..81fa2209 100644 --- a/src/app/workbook/[id]/unsubscribe/page.tsx +++ b/src/app/workbook/[id]/unsubscribe/page.tsx @@ -1,7 +1,7 @@ "use client" -import UnsubscribeForm from "@workbook/components/UnsubscribeForm"; -import UnsubscribeTitle from "@workbook/components/UnsubscribeTitle"; +import UnsubscribeForm from "@subscription/components/UnsubscribeForm"; +import UnsubscribeTitle from "@subscription/components/UnsubscribeTitle"; export default function SubscriptionCancelPage () { return ( diff --git a/src/workbook/components/SubscribeForm/SubscribeForm.test.tsx b/src/subscription/components/SubscribeForm/SubscribeForm.test.tsx similarity index 100% rename from src/workbook/components/SubscribeForm/SubscribeForm.test.tsx rename to src/subscription/components/SubscribeForm/SubscribeForm.test.tsx diff --git a/src/workbook/components/SubscribeForm/index.tsx b/src/subscription/components/SubscribeForm/index.tsx similarity index 100% rename from src/workbook/components/SubscribeForm/index.tsx rename to src/subscription/components/SubscribeForm/index.tsx diff --git a/src/workbook/components/SubscribeFormField/index.tsx b/src/subscription/components/SubscribeFormField/index.tsx similarity index 100% rename from src/workbook/components/SubscribeFormField/index.tsx rename to src/subscription/components/SubscribeFormField/index.tsx diff --git a/src/workbook/components/UnsubscribeForm/UnsubscribeForm.test.tsx b/src/subscription/components/UnsubscribeForm/UnsubscribeForm.test.tsx similarity index 100% rename from src/workbook/components/UnsubscribeForm/UnsubscribeForm.test.tsx rename to src/subscription/components/UnsubscribeForm/UnsubscribeForm.test.tsx diff --git a/src/workbook/components/UnsubscribeForm/index.tsx b/src/subscription/components/UnsubscribeForm/index.tsx similarity index 100% rename from src/workbook/components/UnsubscribeForm/index.tsx rename to src/subscription/components/UnsubscribeForm/index.tsx diff --git a/src/workbook/components/UnsubscribeFormField/index.tsx b/src/subscription/components/UnsubscribeFormField/index.tsx similarity index 100% rename from src/workbook/components/UnsubscribeFormField/index.tsx rename to src/subscription/components/UnsubscribeFormField/index.tsx diff --git a/src/workbook/components/UnsubscribeTitle/index.tsx b/src/subscription/components/UnsubscribeTitle/index.tsx similarity index 100% rename from src/workbook/components/UnsubscribeTitle/index.tsx rename to src/subscription/components/UnsubscribeTitle/index.tsx diff --git a/src/workbook/hooks/useUnsubscribeForm.tsx b/src/subscription/hooks/useUnsubscribeForm.tsx similarity index 100% rename from src/workbook/hooks/useUnsubscribeForm.tsx rename to src/subscription/hooks/useUnsubscribeForm.tsx diff --git a/src/workbook/schemas/index.ts b/src/subscription/schemas/index.ts similarity index 100% rename from src/workbook/schemas/index.ts rename to src/subscription/schemas/index.ts diff --git a/src/subscription/types/subscription.ts b/src/subscription/types/subscription.ts new file mode 100644 index 00000000..ef21b8e9 --- /dev/null +++ b/src/subscription/types/subscription.ts @@ -0,0 +1,5 @@ +import { z } from "zod"; + +import { unSubscribeSchema } from "@subscription/schemas"; + +export type UnsubscribeFormData = z.infer; \ No newline at end of file diff --git a/src/workbook/types/index.ts b/src/workbook/types/index.ts index 4791df97..2d87c009 100644 --- a/src/workbook/types/index.ts +++ b/src/workbook/types/index.ts @@ -1,7 +1,3 @@ -import { z } from "zod"; - -import { unSubscribeSchema } from "@workbook/schemas"; - export interface CurriculumInfo { id: number; title: string; @@ -29,5 +25,3 @@ export interface WorkbookInfo { writers: Writer[]; articles: Article[]; } - -export type UnsubscribeFormData = z.infer; diff --git a/tsconfig.json b/tsconfig.json index d972257b..eed50c90 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,7 +26,8 @@ "@main/*": ["src/main/*"], "@common/*": ["src/common/*"], "@mocks/*": ["src/mocks/*"], - "@problem/*": ["src/problem/*"] + "@problem/*": ["src/problem/*"], + "@subscription/*": ["src/subscription/*"] } }, "include": [ diff --git a/vitest.config.ts b/vitest.config.ts index 27795c61..822c0436 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -38,6 +38,7 @@ export default defineConfig({ "@mocks": resolve("src/mocks"), "@common": resolve("src/common"), "@problem": resolve("src/problem"), + "@subscription/*": resolve("src/subscription"), public: resolve("public"), }, }, From f50ec616424e1d0271733a4ed3685f1d1d8eed9d Mon Sep 17 00:00:00 2001 From: soomin9106 Date: Wed, 26 Jun 2024 23:08:05 +0900 Subject: [PATCH 02/11] refactor: migrate subscribe bottom bar main to subscription --- src/app/workbook/[id]/page.tsx | 5 ++- src/main/schemas/index.ts | 10 ------ src/main/types/index.ts | 7 ----- .../SubscribeBottomBar.test.tsx | 5 ++- .../components/SubscribeBottomBar/index.tsx | 4 +-- .../SubscribeForm/SubscribeForm.test.tsx | 4 +-- .../components/SubscribeForm/index.tsx | 6 ++-- .../components/SubscribeFormField/index.tsx | 5 +-- .../UnsubscribeForm/UnsubscribeForm.test.tsx | 8 ++--- .../components/UnsubscribeForm/index.tsx | 5 +-- .../components/UnsubscribeFormField/index.tsx | 2 +- src/{main => subscription}/constants/main.ts | 0 .../constants/unsubscribe.ts | 0 .../hooks/useSubscribeForm.tsx | 6 ++-- src/subscription/hooks/useUnsubscribeForm.tsx | 6 ++-- src/subscription/remotes/api.ts | 6 ++++ .../remotes/postSubscriptionQueryOptions.ts | 31 +++++++++++++++++++ src/subscription/schemas/index.ts | 10 +++++- src/subscription/types/subscription.ts | 19 ++++++++++-- vitest.config.ts | 2 +- 20 files changed, 89 insertions(+), 52 deletions(-) delete mode 100644 src/main/schemas/index.ts delete mode 100644 src/main/types/index.ts rename src/{main => subscription}/components/SubscribeBottomBar/SubscribeBottomBar.test.tsx (94%) rename src/{main => subscription}/components/SubscribeBottomBar/index.tsx (94%) rename src/{main => subscription}/constants/main.ts (100%) rename src/{workbook => subscription}/constants/unsubscribe.ts (100%) rename src/{main => subscription}/hooks/useSubscribeForm.tsx (82%) create mode 100644 src/subscription/remotes/api.ts create mode 100644 src/subscription/remotes/postSubscriptionQueryOptions.ts diff --git a/src/app/workbook/[id]/page.tsx b/src/app/workbook/[id]/page.tsx index 2b42934a..49396586 100644 --- a/src/app/workbook/[id]/page.tsx +++ b/src/app/workbook/[id]/page.tsx @@ -18,10 +18,9 @@ import WriterInfo from "@workbook/components/WriterInfo"; import { getWorkbookQueryOptions } from "@workbook/remotes/getWorkbookQueryOptions"; import { getWorkbookId } from "@workbook/utils"; +import SubscribeBottomBar from "@subscription/components/SubscribeBottomBar"; import SubscribeForm from "@subscription/components/SubscribeForm"; - -import SubscribeBottomBar from "@main/components/SubscribeBottomBar"; -import { SUBSCRIBE_TITLES } from "@main/constants/main"; +import { SUBSCRIBE_TITLES } from "@subscription/constants/main"; const SUBSCRIBE_POPUP_TITLE = (
diff --git a/src/main/schemas/index.ts b/src/main/schemas/index.ts deleted file mode 100644 index d6f95fd2..00000000 --- a/src/main/schemas/index.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { z } from "zod" - -import { EMAIL_CONTROL } from "@main/constants/main" - -export const emailSubscribeSchema = z.object({ - email: z - .string() - .min(1, { message: EMAIL_CONTROL.INVALID_EMAIL }) - .email(EMAIL_CONTROL.INVALID_EMAIL) -}) \ No newline at end of file diff --git a/src/main/types/index.ts b/src/main/types/index.ts deleted file mode 100644 index 92e66ff7..00000000 --- a/src/main/types/index.ts +++ /dev/null @@ -1,7 +0,0 @@ - -import { z } from 'zod'; - -import { emailSubscribeSchema } from '@main/schemas'; - -export type variantType = "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" -export type EmailSubscribeFormData = z.infer; \ No newline at end of file diff --git a/src/main/components/SubscribeBottomBar/SubscribeBottomBar.test.tsx b/src/subscription/components/SubscribeBottomBar/SubscribeBottomBar.test.tsx similarity index 94% rename from src/main/components/SubscribeBottomBar/SubscribeBottomBar.test.tsx rename to src/subscription/components/SubscribeBottomBar/SubscribeBottomBar.test.tsx index 062d9881..a57a5cd7 100644 --- a/src/main/components/SubscribeBottomBar/SubscribeBottomBar.test.tsx +++ b/src/subscription/components/SubscribeBottomBar/SubscribeBottomBar.test.tsx @@ -2,8 +2,7 @@ import { Control,useForm } from 'react-hook-form'; import { describe, expect, it, vi } from 'vitest'; -// import as module -import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE, SUBSCRIBE_TITLES,SUBSCRIBE_USER_ACTIONS } from '@main/constants/main'; +import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE, SUBSCRIBE_TITLES, SUBSCRIBE_USER_ACTIONS } from '@subscription/constants/main'; import SubscribeBottomBar from '.'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; @@ -11,7 +10,7 @@ import { fireEvent, render, screen, waitFor } from '@testing-library/react'; // Mock the useSubscribeForm hook const mockOnSubmit = vi.fn(); -vi.mock('@main/hooks/useSubscribeForm', () => ({ +vi.mock('@subscription/hooks/useSubscribeForm', () => ({ useSubscribeForm: () => { const form = useForm({ resolver: async (data) => { diff --git a/src/main/components/SubscribeBottomBar/index.tsx b/src/subscription/components/SubscribeBottomBar/index.tsx similarity index 94% rename from src/main/components/SubscribeBottomBar/index.tsx rename to src/subscription/components/SubscribeBottomBar/index.tsx index 253c9bea..ed20942f 100644 --- a/src/main/components/SubscribeBottomBar/index.tsx +++ b/src/subscription/components/SubscribeBottomBar/index.tsx @@ -10,8 +10,8 @@ import { } from "@shared/components/ui/form" import { Input } from "@shared/components/ui/input"; -import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE, SUBSCRIBE_TITLES,SUBSCRIBE_USER_ACTIONS } from "@main/constants/main"; -import { useSubscribeForm } from "@main/hooks/useSubscribeForm"; +import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE, SUBSCRIBE_TITLES,SUBSCRIBE_USER_ACTIONS } from "@subscription/constants/main"; +import { useSubscribeForm } from "@subscription/hooks/useSubscribeForm"; export default function SubscribeBottomBar() { const { form, onSubmit } = useSubscribeForm(); diff --git a/src/subscription/components/SubscribeForm/SubscribeForm.test.tsx b/src/subscription/components/SubscribeForm/SubscribeForm.test.tsx index c3220e2b..29335025 100644 --- a/src/subscription/components/SubscribeForm/SubscribeForm.test.tsx +++ b/src/subscription/components/SubscribeForm/SubscribeForm.test.tsx @@ -2,7 +2,7 @@ import { useForm } from 'react-hook-form'; import { describe, expect, it, vi } from 'vitest'; -import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE, SUBSCRIBE_USER_ACTIONS } from '@main/constants/main'; +import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE, SUBSCRIBE_USER_ACTIONS } from '@subscription/constants/main'; import SubscribeForm from '.'; import { render, screen, waitFor } from '@testing-library/react'; @@ -11,7 +11,7 @@ import userEvent from '@testing-library/user-event'; const mockSetIsOpen = vi.fn(); const mockOnSubmit = vi.fn(); -vi.mock('@main/hooks/useSubscribeForm', () => ({ +vi.mock('@subscription/hooks/useSubscribeForm', () => ({ useSubscribeForm: () => ({ form: useForm(), onSubmit: mockOnSubmit, diff --git a/src/subscription/components/SubscribeForm/index.tsx b/src/subscription/components/SubscribeForm/index.tsx index 6f9a75ec..8ca6f729 100644 --- a/src/subscription/components/SubscribeForm/index.tsx +++ b/src/subscription/components/SubscribeForm/index.tsx @@ -5,10 +5,8 @@ import { cn } from "@shared/utils/cn"; import { buttonStyle } from "@workbook/constants/buttonStyle"; -import { - SUBSCRIBE_USER_ACTIONS, -} from "@main/constants/main"; -import { useSubscribeForm } from "@main/hooks/useSubscribeForm"; +import { SUBSCRIBE_USER_ACTIONS } from "@subscription/constants/main"; +import { useSubscribeForm } from "@subscription/hooks/useSubscribeForm"; import SubscribeFormField from "../SubscribeFormField"; diff --git a/src/subscription/components/SubscribeFormField/index.tsx b/src/subscription/components/SubscribeFormField/index.tsx index 7ad502c0..9c9153bb 100644 --- a/src/subscription/components/SubscribeFormField/index.tsx +++ b/src/subscription/components/SubscribeFormField/index.tsx @@ -4,10 +4,7 @@ import { Controller,useFormContext } from "react-hook-form"; import { FormControl, FormItem, FormMessage } from "@shared/components/ui/form"; import { Input } from "@shared/components/ui/input"; -import { - EMAIL_CONTROL, - SUBSCRIBE_ANNOUCE, -} from "@main/constants/main"; +import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE } from "@subscription/constants/main"; const SubscribeFormField = () => { const { control, formState } = useFormContext(); diff --git a/src/subscription/components/UnsubscribeForm/UnsubscribeForm.test.tsx b/src/subscription/components/UnsubscribeForm/UnsubscribeForm.test.tsx index c167028f..0b7b6e49 100644 --- a/src/subscription/components/UnsubscribeForm/UnsubscribeForm.test.tsx +++ b/src/subscription/components/UnsubscribeForm/UnsubscribeForm.test.tsx @@ -5,9 +5,9 @@ import { describe, expect, it, vi } from "vitest"; import { UNSUBSCRIBE_CONFIRM, UNSUBSCRIBE_FORM, -} from "@workbook/constants/unsubscribe"; -import { unSubscribeSchema } from "@workbook/schemas"; -import { UnsubscribeFormData } from "@workbook/types"; +} from "@subscription/constants/unsubscribe"; +import { unSubscribeSchema } from "@subscription/schemas"; +import { UnsubscribeFormData } from "@subscription/types/subscription"; import UnsubscribeForm from "."; import { render, screen, waitFor } from "@testing-library/react"; @@ -28,7 +28,7 @@ const mockOnSubmit = vi.fn(async (values: UnsubscribeFormData) => { } }); -vi.mock("@workbook/hooks/useUnsubscribeForm", () => ({ +vi.mock("@subscription/hooks/useUnsubscribeForm", () => ({ useUnsubscribeForm: () => ({ form: useForm(), onSubmit: mockOnSubmit, diff --git a/src/subscription/components/UnsubscribeForm/index.tsx b/src/subscription/components/UnsubscribeForm/index.tsx index 27c7d911..c5f25358 100644 --- a/src/subscription/components/UnsubscribeForm/index.tsx +++ b/src/subscription/components/UnsubscribeForm/index.tsx @@ -4,8 +4,9 @@ import { Button } from "@shared/components/ui/button"; import { cn } from "@shared/utils/cn"; import { buttonStyle } from "@workbook/constants/buttonStyle"; -import { UNSUBSCRIBE_FORM } from "@workbook/constants/unsubscribe"; -import { useUnsubscribeForm } from "@workbook/hooks/useUnsubscribeForm"; + +import { UNSUBSCRIBE_FORM } from "@subscription/constants/unsubscribe"; +import { useUnsubscribeForm } from "@subscription/hooks/useUnsubscribeForm"; import UnsubscribeFormField from "../UnsubscribeFormField"; diff --git a/src/subscription/components/UnsubscribeFormField/index.tsx b/src/subscription/components/UnsubscribeFormField/index.tsx index 5414af72..bb41c089 100644 --- a/src/subscription/components/UnsubscribeFormField/index.tsx +++ b/src/subscription/components/UnsubscribeFormField/index.tsx @@ -4,7 +4,7 @@ import { Controller,useFormContext } from "react-hook-form"; import { FormControl, FormItem, FormLabel, FormMessage } from "@shared/components/ui/form"; import { Textarea } from "@shared/components/ui/textarea"; -import { UNSUBSCRIBE_FORM } from "@workbook/constants/unsubscribe"; +import { UNSUBSCRIBE_FORM } from "@subscription/constants/unsubscribe"; const UnsubscribeFormField = () => { const { control, formState } = useFormContext(); diff --git a/src/main/constants/main.ts b/src/subscription/constants/main.ts similarity index 100% rename from src/main/constants/main.ts rename to src/subscription/constants/main.ts diff --git a/src/workbook/constants/unsubscribe.ts b/src/subscription/constants/unsubscribe.ts similarity index 100% rename from src/workbook/constants/unsubscribe.ts rename to src/subscription/constants/unsubscribe.ts diff --git a/src/main/hooks/useSubscribeForm.tsx b/src/subscription/hooks/useSubscribeForm.tsx similarity index 82% rename from src/main/hooks/useSubscribeForm.tsx rename to src/subscription/hooks/useSubscribeForm.tsx index d750a1f9..f2c6e6f6 100644 --- a/src/main/hooks/useSubscribeForm.tsx +++ b/src/subscription/hooks/useSubscribeForm.tsx @@ -4,9 +4,9 @@ import { z } from 'zod'; import { useToast } from '@shared/components/ui/use-toast'; -import { SUBSCRIBE_USER_ACTIONS } from '@main/constants/main'; -import { emailSubscribeSchema } from '@main/schemas'; -import { EmailSubscribeFormData } from '@main/types'; +import { SUBSCRIBE_USER_ACTIONS } from '@subscription/constants/main'; +import { emailSubscribeSchema } from '@subscription/schemas'; +import { EmailSubscribeFormData } from '@subscription/types/subscription'; import { zodResolver } from '@hookform/resolvers/zod'; diff --git a/src/subscription/hooks/useUnsubscribeForm.tsx b/src/subscription/hooks/useUnsubscribeForm.tsx index 28fd9a91..de8d4ad4 100644 --- a/src/subscription/hooks/useUnsubscribeForm.tsx +++ b/src/subscription/hooks/useUnsubscribeForm.tsx @@ -4,9 +4,9 @@ import { z } from "zod"; import { useToast } from "@shared/components/ui/use-toast"; -import { UNSUBSCRIBE_CONFIRM } from "@workbook/constants/unsubscribe"; -import { unSubscribeSchema } from "@workbook/schemas"; -import { UnsubscribeFormData } from "@workbook/types"; +import { UNSUBSCRIBE_CONFIRM } from "@subscription/constants/unsubscribe"; +import { unSubscribeSchema } from "@subscription/schemas"; +import { UnsubscribeFormData } from "@subscription/types/subscription"; import { zodResolver } from "@hookform/resolvers/zod"; diff --git a/src/subscription/remotes/api.ts b/src/subscription/remotes/api.ts new file mode 100644 index 00000000..7592458a --- /dev/null +++ b/src/subscription/remotes/api.ts @@ -0,0 +1,6 @@ +export const API_ROUTE = { + SUBSCRIBE: (workbookId: string) => `/api/v1/workbooks/${workbookId}/subs`, +}; +export const QUERY_KEY = { + SUBSCRIBE_WORKBOOK: "sub-workbook", +}; diff --git a/src/subscription/remotes/postSubscriptionQueryOptions.ts b/src/subscription/remotes/postSubscriptionQueryOptions.ts new file mode 100644 index 00000000..c9dc6442 --- /dev/null +++ b/src/subscription/remotes/postSubscriptionQueryOptions.ts @@ -0,0 +1,31 @@ +import { UseMutationOptions } from "@tanstack/react-query"; + +import { ApiResponse, axiosRequest } from "@api/api-config"; + +import { + MessageOnlyResponse, + SubscribeBody, + SubscribeParams, +} from "@subscription/types/subscription"; + +import { API_ROUTE, QUERY_KEY } from "./api"; + +export const subscribeWorkbook = ( + params: SubscribeParams, + body: SubscribeBody, +): Promise> => { + return axiosRequest("post", API_ROUTE.SUBSCRIBE(params.workbookId), body); +}; + +export const subscribeWorkbookOptions = ( + params: SubscribeParams +): UseMutationOptions< + ApiResponse, + Error, + SubscribeBody +> => { + return { + mutationKey: [QUERY_KEY.SUBSCRIBE_WORKBOOK, params.workbookId], + mutationFn: (body) => subscribeWorkbook(params, body) + }; +} diff --git a/src/subscription/schemas/index.ts b/src/subscription/schemas/index.ts index 946697b5..32cf5b16 100644 --- a/src/subscription/schemas/index.ts +++ b/src/subscription/schemas/index.ts @@ -1,10 +1,18 @@ import { z } from "zod" -import { UNSUBSCRIBE_FORM } from "@workbook/constants/unsubscribe" +import { EMAIL_CONTROL } from "@subscription/constants/main" +import { UNSUBSCRIBE_FORM } from "@subscription/constants/unsubscribe" export const unSubscribeSchema = z.object({ opinion: z .string() .max(255, { message: UNSUBSCRIBE_FORM.WORD_LIMIT }) +}) + +export const emailSubscribeSchema = z.object({ + email: z + .string() + .min(1, { message: EMAIL_CONTROL.INVALID_EMAIL }) + .email(EMAIL_CONTROL.INVALID_EMAIL) }) \ No newline at end of file diff --git a/src/subscription/types/subscription.ts b/src/subscription/types/subscription.ts index ef21b8e9..a96f4de5 100644 --- a/src/subscription/types/subscription.ts +++ b/src/subscription/types/subscription.ts @@ -1,5 +1,20 @@ import { z } from "zod"; -import { unSubscribeSchema } from "@subscription/schemas"; +import { ApiResponse } from "@api/api-config"; -export type UnsubscribeFormData = z.infer; \ No newline at end of file +import { emailSubscribeSchema, unSubscribeSchema } from "@subscription/schemas"; + +export type variantType = "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" +export type EmailSubscribeFormData = z.infer; + +export type UnsubscribeFormData = z.infer; + +export type SubscribeParams = { + workbookId: string; +} + +export type SubscribeBody = { + email: string +} + +export interface MessageOnlyResponse extends Pick, 'message'> {} \ No newline at end of file diff --git a/vitest.config.ts b/vitest.config.ts index 822c0436..054e4227 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -38,7 +38,7 @@ export default defineConfig({ "@mocks": resolve("src/mocks"), "@common": resolve("src/common"), "@problem": resolve("src/problem"), - "@subscription/*": resolve("src/subscription"), + "@subscription": resolve("src/subscription"), public: resolve("public"), }, }, From 54ec84db7f8e9b1afb434c543ce2202a1ef4f26e Mon Sep 17 00:00:00 2001 From: soomin9106 Date: Thu, 27 Jun 2024 12:24:36 +0900 Subject: [PATCH 03/11] feat: redirect /workbook to /workbook/1 --- src/middleware.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/middleware.ts b/src/middleware.ts index b25414c6..78a49ba6 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -21,6 +21,12 @@ export default function middleware(req: NextRequest) { const nextUrl = req.nextUrl.clone(); const email = nextUrl.searchParams.get("user"); + /** /workbook 으로 진입 시 리다이랙션 */ + if (nextUrl.pathname === "/workbook") { + nextUrl.pathname = "/workbook/1"; + return NextResponse.redirect(nextUrl); + } + if (email) { nextUrl.searchParams.delete("user"); const decodedEmail = decodeURIComponent(email); @@ -39,5 +45,5 @@ export default function middleware(req: NextRequest) { } export const config = { - matcher: ["/unsubscribe/:path*"], + matcher: ["/unsubscribe/:path*", "/workbook/:path*"], }; From 4293852a2c39c5092f2aaf023491d55ff5100c0a Mon Sep 17 00:00:00 2001 From: soomin9106 Date: Thu, 27 Jun 2024 12:46:00 +0900 Subject: [PATCH 04/11] chore: add github domain in next js image --- next.config.mjs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/next.config.mjs b/next.config.mjs index 3c035f58..35c780e7 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -3,6 +3,9 @@ const nextConfig = { experimental: { instrumentationHook: true, }, + images: { + domains: ['github.com'], + }, webpack: (config, context) => { config.module.rules.push({ test: /\.svg$/, From b6f96090b659d318ecafde25f6f137f1a42311b3 Mon Sep 17 00:00:00 2001 From: soomin9106 Date: Thu, 27 Jun 2024 12:56:12 +0900 Subject: [PATCH 05/11] =?UTF-8?q?feat:=20subscribe=20API=20=EC=97=B0?= =?UTF-8?q?=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/subscription/hooks/useSubscribeForm.tsx | 46 +++++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/src/subscription/hooks/useSubscribeForm.tsx b/src/subscription/hooks/useSubscribeForm.tsx index f2c6e6f6..8193bd88 100644 --- a/src/subscription/hooks/useSubscribeForm.tsx +++ b/src/subscription/hooks/useSubscribeForm.tsx @@ -1,10 +1,18 @@ +import { usePathname } from 'next/navigation'; + +import { useEffect, useState } from 'react'; import { useForm } from 'react-hook-form'; +import { useMutation } from '@tanstack/react-query'; + import { z } from 'zod'; import { useToast } from '@shared/components/ui/use-toast'; -import { SUBSCRIBE_USER_ACTIONS } from '@subscription/constants/main'; +import { getWorkbookId } from '@workbook/utils'; + +import { EMAIL_CONTROL, SUBSCRIBE_USER_ACTIONS } from '@subscription/constants/main'; +import { subscribeWorkbookOptions } from '@subscription/remotes/postSubscriptionQueryOptions'; import { emailSubscribeSchema } from '@subscription/schemas'; import { EmailSubscribeFormData } from '@subscription/types/subscription'; @@ -12,7 +20,13 @@ import { zodResolver } from '@hookform/resolvers/zod'; export const useSubscribeForm = () => { const { toast } = useToast(); + const pathname = usePathname() + const [workbookId, setWorkbookId] = useState("") + useEffect(function getId() { + return setWorkbookId(getWorkbookId(pathname)); + }, [pathname]) + const form = useForm({ resolver: zodResolver(emailSubscribeSchema), defaultValues: { @@ -20,20 +34,34 @@ export const useSubscribeForm = () => { }, }); + const { mutate: subscribeWorkbook } = useMutation(subscribeWorkbookOptions({ + workbookId: workbookId, + })); + const onSubmit = (values: EmailSubscribeFormData) => { try { emailSubscribeSchema.safeParse(values); - console.log(values); - // 폼 제출 성공 로직 추가 - form.reset() - toast({ - title: SUBSCRIBE_USER_ACTIONS.SUBSCRIBE_SUCCESS, + + subscribeWorkbook(values, { + onSuccess: () => { + form.reset(); + toast({ + title: SUBSCRIBE_USER_ACTIONS.SUBSCRIBE_SUCCESS, + }); + }, + onError: (error) => { + console.error(error); + toast({ + title: '구독 신청이 되지 않았습니다.' + }); + }, }); } catch (error) { if (error instanceof z.ZodError) { - error.errors.forEach((err) => { - console.error(err.message); - // 오류 메시지를 UI에 표시하는 로직 추가 + error.errors.forEach(() => { + toast({ + title: EMAIL_CONTROL.INVALID_EMAIL, + }); }); } } From a2c81b98377b8506339c4926e5c674ed4a23fe33 Mon Sep 17 00:00:00 2001 From: soomin9106 Date: Thu, 27 Jun 2024 16:04:13 +0900 Subject: [PATCH 06/11] feat: unsubscribe API --- .../components/UnsubscribeTitle/index.tsx | 2 +- src/subscription/hooks/useUnsubscribeForm.tsx | 32 +++++++++++++++---- src/subscription/remotes/api.ts | 2 ++ .../remotes/postUnsubscriptionQueryOptions.ts | 27 ++++++++++++++++ src/subscription/types/subscription.ts | 7 +++- src/subscription/utils/index.ts | 5 +++ 6 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 src/subscription/remotes/postUnsubscriptionQueryOptions.ts create mode 100644 src/subscription/utils/index.ts diff --git a/src/subscription/components/UnsubscribeTitle/index.tsx b/src/subscription/components/UnsubscribeTitle/index.tsx index d53f947c..8aec5a09 100644 --- a/src/subscription/components/UnsubscribeTitle/index.tsx +++ b/src/subscription/components/UnsubscribeTitle/index.tsx @@ -1,4 +1,4 @@ -import { UNSUBSCRIBE_TITLES } from "@workbook/constants/unsubscribe"; +import { UNSUBSCRIBE_TITLES } from "@subscription/constants/unsubscribe"; export default function UnsubscribeTitle () { return ( diff --git a/src/subscription/hooks/useUnsubscribeForm.tsx b/src/subscription/hooks/useUnsubscribeForm.tsx index de8d4ad4..5534e789 100644 --- a/src/subscription/hooks/useUnsubscribeForm.tsx +++ b/src/subscription/hooks/useUnsubscribeForm.tsx @@ -1,12 +1,16 @@ import { useForm } from "react-hook-form"; +import { useMutation } from "@tanstack/react-query"; + import { z } from "zod"; import { useToast } from "@shared/components/ui/use-toast"; import { UNSUBSCRIBE_CONFIRM } from "@subscription/constants/unsubscribe"; +import { unsubscribeWorkbookOptions } from "@subscription/remotes/postUnsubscriptionQueryOptions"; import { unSubscribeSchema } from "@subscription/schemas"; import { UnsubscribeFormData } from "@subscription/types/subscription"; +import { getCookie } from "@subscription/utils"; import { zodResolver } from "@hookform/resolvers/zod"; @@ -20,16 +24,32 @@ export const useUnsubscribeForm = () => { }, }); + const { mutate: unsubscribeWorkbook } = useMutation(unsubscribeWorkbookOptions()); + const onSubmit = (values: UnsubscribeFormData) => { try { const result = unSubscribeSchema.safeParse(values); - + const email = getCookie('user-email'); + // 폼 제출 성공 로직 추가 - if (result.success) { - form.reset(); - toast({ - title: UNSUBSCRIBE_CONFIRM, - }); + if (result.success && typeof email === "string") { + unsubscribeWorkbook( + { email: decodeURIComponent(email), opinion: values.opinion }, + { + onSuccess: () => { + form.reset(); + toast({ + title: UNSUBSCRIBE_CONFIRM, + }); + }, + onError: (error) => { + console.error(error); + toast({ + title: '구독 취소가 되지 않았습니다.' + }); + }, + }, + ); } } catch (error) { if (error instanceof z.ZodError) { diff --git a/src/subscription/remotes/api.ts b/src/subscription/remotes/api.ts index 7592458a..0b9fca90 100644 --- a/src/subscription/remotes/api.ts +++ b/src/subscription/remotes/api.ts @@ -1,6 +1,8 @@ export const API_ROUTE = { SUBSCRIBE: (workbookId: string) => `/api/v1/workbooks/${workbookId}/subs`, + UNSUBSCRIBE: () => `/api/v1/subscriptions/unsubs` }; export const QUERY_KEY = { SUBSCRIBE_WORKBOOK: "sub-workbook", + UNSUBSCRIBE_WORKBOOK: "unsub-workbook" }; diff --git a/src/subscription/remotes/postUnsubscriptionQueryOptions.ts b/src/subscription/remotes/postUnsubscriptionQueryOptions.ts new file mode 100644 index 00000000..db4a3243 --- /dev/null +++ b/src/subscription/remotes/postUnsubscriptionQueryOptions.ts @@ -0,0 +1,27 @@ +import { UseMutationOptions } from "@tanstack/react-query"; + +import { ApiResponse, axiosRequest } from "@api/api-config"; + +import { + MessageOnlyResponse, + UnsubscribeBody, +} from "@subscription/types/subscription"; + +import { API_ROUTE, QUERY_KEY } from "./api"; + +export const unsubscribeWorkbook = ( + body: UnsubscribeBody, +): Promise> => { + return axiosRequest("post", API_ROUTE.UNSUBSCRIBE(), body); +}; + +export const unsubscribeWorkbookOptions = (): UseMutationOptions< + ApiResponse, + Error, + UnsubscribeBody +> => { + return { + mutationKey: [QUERY_KEY.UNSUBSCRIBE_WORKBOOK], + mutationFn: (body) => unsubscribeWorkbook(body), + }; +}; diff --git a/src/subscription/types/subscription.ts b/src/subscription/types/subscription.ts index a96f4de5..09917e53 100644 --- a/src/subscription/types/subscription.ts +++ b/src/subscription/types/subscription.ts @@ -17,4 +17,9 @@ export type SubscribeBody = { email: string } -export interface MessageOnlyResponse extends Pick, 'message'> {} \ No newline at end of file +export interface MessageOnlyResponse extends Pick, 'message'> {} + +export type UnsubscribeBody = { + email: string + opinion: string +} \ No newline at end of file diff --git a/src/subscription/utils/index.ts b/src/subscription/utils/index.ts new file mode 100644 index 00000000..4a48d78d --- /dev/null +++ b/src/subscription/utils/index.ts @@ -0,0 +1,5 @@ +export const getCookie = (name: string) => { + const value = `; ${document.cookie}`; + const parts = value.split(`; ${name}=`); + if (parts.length === 2) return parts.pop()?.split(";").shift(); +}; From 68edba22d50ab2b2c0d3a053f090a9e45eab8ca6 Mon Sep 17 00:00:00 2001 From: soomin9106 Date: Thu, 27 Jun 2024 21:11:56 +0900 Subject: [PATCH 07/11] chore: change file name --- src/app/unsubscribe/layout.tsx | 4 ++-- src/app/workbook/[id]/page.tsx | 2 +- .../components/SubscribeBottomBar/SubscribeBottomBar.test.tsx | 2 +- src/subscription/components/SubscribeBottomBar/index.tsx | 2 +- .../components/SubscribeForm/SubscribeForm.test.tsx | 2 +- src/subscription/components/SubscribeForm/index.tsx | 2 +- src/subscription/components/SubscribeFormField/index.tsx | 2 +- src/subscription/constants/{main.ts => subscribe.ts} | 0 src/subscription/hooks/useSubscribeForm.tsx | 2 +- src/subscription/schemas/index.ts | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) rename src/subscription/constants/{main.ts => subscribe.ts} (100%) diff --git a/src/app/unsubscribe/layout.tsx b/src/app/unsubscribe/layout.tsx index 8b615f2e..e8849107 100644 --- a/src/app/unsubscribe/layout.tsx +++ b/src/app/unsubscribe/layout.tsx @@ -2,10 +2,10 @@ import React, { ReactNode } from "react"; import TopBar from "@common/components/TopBar"; -interface CancelLayoutProps { +interface UnsubscribeLayoutProps { children: ReactNode; } -export default function CancelLayout({ children }: CancelLayoutProps) { +export default function UnsubscribeLayout({ children }: UnsubscribeLayoutProps) { return (
diff --git a/src/app/workbook/[id]/page.tsx b/src/app/workbook/[id]/page.tsx index 49396586..b3491500 100644 --- a/src/app/workbook/[id]/page.tsx +++ b/src/app/workbook/[id]/page.tsx @@ -20,7 +20,7 @@ import { getWorkbookId } from "@workbook/utils"; import SubscribeBottomBar from "@subscription/components/SubscribeBottomBar"; import SubscribeForm from "@subscription/components/SubscribeForm"; -import { SUBSCRIBE_TITLES } from "@subscription/constants/main"; +import { SUBSCRIBE_TITLES } from "@subscription/constants/subscribe"; const SUBSCRIBE_POPUP_TITLE = (
diff --git a/src/subscription/components/SubscribeBottomBar/SubscribeBottomBar.test.tsx b/src/subscription/components/SubscribeBottomBar/SubscribeBottomBar.test.tsx index a57a5cd7..559ff162 100644 --- a/src/subscription/components/SubscribeBottomBar/SubscribeBottomBar.test.tsx +++ b/src/subscription/components/SubscribeBottomBar/SubscribeBottomBar.test.tsx @@ -2,7 +2,7 @@ import { Control,useForm } from 'react-hook-form'; import { describe, expect, it, vi } from 'vitest'; -import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE, SUBSCRIBE_TITLES, SUBSCRIBE_USER_ACTIONS } from '@subscription/constants/main'; +import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE, SUBSCRIBE_TITLES, SUBSCRIBE_USER_ACTIONS } from '@subscription/constants/subscribe'; import SubscribeBottomBar from '.'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; diff --git a/src/subscription/components/SubscribeBottomBar/index.tsx b/src/subscription/components/SubscribeBottomBar/index.tsx index ed20942f..a948a091 100644 --- a/src/subscription/components/SubscribeBottomBar/index.tsx +++ b/src/subscription/components/SubscribeBottomBar/index.tsx @@ -10,7 +10,7 @@ import { } from "@shared/components/ui/form" import { Input } from "@shared/components/ui/input"; -import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE, SUBSCRIBE_TITLES,SUBSCRIBE_USER_ACTIONS } from "@subscription/constants/main"; +import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE, SUBSCRIBE_TITLES,SUBSCRIBE_USER_ACTIONS } from "@subscription/constants/subscribe"; import { useSubscribeForm } from "@subscription/hooks/useSubscribeForm"; export default function SubscribeBottomBar() { diff --git a/src/subscription/components/SubscribeForm/SubscribeForm.test.tsx b/src/subscription/components/SubscribeForm/SubscribeForm.test.tsx index 29335025..05e2366a 100644 --- a/src/subscription/components/SubscribeForm/SubscribeForm.test.tsx +++ b/src/subscription/components/SubscribeForm/SubscribeForm.test.tsx @@ -2,7 +2,7 @@ import { useForm } from 'react-hook-form'; import { describe, expect, it, vi } from 'vitest'; -import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE, SUBSCRIBE_USER_ACTIONS } from '@subscription/constants/main'; +import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE, SUBSCRIBE_USER_ACTIONS } from '@subscription/constants/subscribe'; import SubscribeForm from '.'; import { render, screen, waitFor } from '@testing-library/react'; diff --git a/src/subscription/components/SubscribeForm/index.tsx b/src/subscription/components/SubscribeForm/index.tsx index 8ca6f729..7b9d0ebc 100644 --- a/src/subscription/components/SubscribeForm/index.tsx +++ b/src/subscription/components/SubscribeForm/index.tsx @@ -5,7 +5,7 @@ import { cn } from "@shared/utils/cn"; import { buttonStyle } from "@workbook/constants/buttonStyle"; -import { SUBSCRIBE_USER_ACTIONS } from "@subscription/constants/main"; +import { SUBSCRIBE_USER_ACTIONS } from "@subscription/constants/subscribe"; import { useSubscribeForm } from "@subscription/hooks/useSubscribeForm"; import SubscribeFormField from "../SubscribeFormField"; diff --git a/src/subscription/components/SubscribeFormField/index.tsx b/src/subscription/components/SubscribeFormField/index.tsx index 9c9153bb..8c59028d 100644 --- a/src/subscription/components/SubscribeFormField/index.tsx +++ b/src/subscription/components/SubscribeFormField/index.tsx @@ -4,7 +4,7 @@ import { Controller,useFormContext } from "react-hook-form"; import { FormControl, FormItem, FormMessage } from "@shared/components/ui/form"; import { Input } from "@shared/components/ui/input"; -import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE } from "@subscription/constants/main"; +import { EMAIL_CONTROL, SUBSCRIBE_ANNOUCE } from "@subscription/constants/subscribe"; const SubscribeFormField = () => { const { control, formState } = useFormContext(); diff --git a/src/subscription/constants/main.ts b/src/subscription/constants/subscribe.ts similarity index 100% rename from src/subscription/constants/main.ts rename to src/subscription/constants/subscribe.ts diff --git a/src/subscription/hooks/useSubscribeForm.tsx b/src/subscription/hooks/useSubscribeForm.tsx index 8193bd88..562f71c3 100644 --- a/src/subscription/hooks/useSubscribeForm.tsx +++ b/src/subscription/hooks/useSubscribeForm.tsx @@ -11,7 +11,7 @@ import { useToast } from '@shared/components/ui/use-toast'; import { getWorkbookId } from '@workbook/utils'; -import { EMAIL_CONTROL, SUBSCRIBE_USER_ACTIONS } from '@subscription/constants/main'; +import { EMAIL_CONTROL, SUBSCRIBE_USER_ACTIONS } from '@subscription/constants/subscribe'; import { subscribeWorkbookOptions } from '@subscription/remotes/postSubscriptionQueryOptions'; import { emailSubscribeSchema } from '@subscription/schemas'; import { EmailSubscribeFormData } from '@subscription/types/subscription'; diff --git a/src/subscription/schemas/index.ts b/src/subscription/schemas/index.ts index 32cf5b16..38200d52 100644 --- a/src/subscription/schemas/index.ts +++ b/src/subscription/schemas/index.ts @@ -1,6 +1,6 @@ import { z } from "zod" -import { EMAIL_CONTROL } from "@subscription/constants/main" +import { EMAIL_CONTROL } from "@subscription/constants/subscribe" import { UNSUBSCRIBE_FORM } from "@subscription/constants/unsubscribe" export const unSubscribeSchema = z.object({ From dd5e9b1e2de96ac0d001084f9d55a416ce053aa6 Mon Sep 17 00:00:00 2001 From: soomin9106 Date: Thu, 27 Jun 2024 21:17:06 +0900 Subject: [PATCH 08/11] refactor: interface to type using Omit --- src/subscription/types/subscription.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/subscription/types/subscription.ts b/src/subscription/types/subscription.ts index 09917e53..cac0c3c0 100644 --- a/src/subscription/types/subscription.ts +++ b/src/subscription/types/subscription.ts @@ -17,7 +17,8 @@ export type SubscribeBody = { email: string } -export interface MessageOnlyResponse extends Pick, 'message'> {} +export type MessageOnlyResponse = Omit, 'message'> + export type UnsubscribeBody = { email: string From 6aac329a97f5f9fc11f94ca4d044d5c3e14be899 Mon Sep 17 00:00:00 2001 From: soomin9106 Date: Thu, 27 Jun 2024 21:21:24 +0900 Subject: [PATCH 09/11] refactor: return if conditional statement is not met --- src/subscription/hooks/useUnsubscribeForm.tsx | 2 +- src/subscription/utils/index.ts | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/subscription/hooks/useUnsubscribeForm.tsx b/src/subscription/hooks/useUnsubscribeForm.tsx index 5534e789..ee47087f 100644 --- a/src/subscription/hooks/useUnsubscribeForm.tsx +++ b/src/subscription/hooks/useUnsubscribeForm.tsx @@ -32,7 +32,7 @@ export const useUnsubscribeForm = () => { const email = getCookie('user-email'); // 폼 제출 성공 로직 추가 - if (result.success && typeof email === "string") { + if (result.success && typeof email === "string") { // zod parse 가 가능하고, cookie 에 이메일이 존재한다면 unsubscribeWorkbook( { email: decodeURIComponent(email), opinion: values.opinion }, { diff --git a/src/subscription/utils/index.ts b/src/subscription/utils/index.ts index 4a48d78d..0fdeffd5 100644 --- a/src/subscription/utils/index.ts +++ b/src/subscription/utils/index.ts @@ -1,5 +1,8 @@ -export const getCookie = (name: string) => { +export const getCookie = (name: string): string | undefined => { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); - if (parts.length === 2) return parts.pop()?.split(";").shift(); + if (parts.length === 2) { + return parts.pop()?.split(";").shift(); + } + return undefined; }; From c74e82c54d46a09c795ad594d09a9b6abcc82538 Mon Sep 17 00:00:00 2001 From: soomin9106 Date: Thu, 27 Jun 2024 21:31:17 +0900 Subject: [PATCH 10/11] refactor: use destructuring assignment --- src/middleware.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/middleware.ts b/src/middleware.ts index 78a49ba6..3481d6d8 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -19,10 +19,11 @@ export default function middleware(req: NextRequest) { const isWithOutAuth = false; const nextUrl = req.nextUrl.clone(); - const email = nextUrl.searchParams.get("user"); + const { pathname, searchParams } = nextUrl; + const email = searchParams.get("user"); /** /workbook 으로 진입 시 리다이랙션 */ - if (nextUrl.pathname === "/workbook") { + if (pathname === "/workbook") { nextUrl.pathname = "/workbook/1"; return NextResponse.redirect(nextUrl); } From 9553999beced21e3f65679416cac150b53578911 Mon Sep 17 00:00:00 2001 From: soomin9106 Date: Thu, 27 Jun 2024 22:21:02 +0900 Subject: [PATCH 11/11] refactor: add onSubmit mode and remove safeParse --- src/subscription/hooks/useSubscribeForm.tsx | 17 ++++--------- src/subscription/hooks/useUnsubscribeForm.tsx | 24 ++++++++++--------- .../remotes/postUnsubscriptionQueryOptions.ts | 4 ++-- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/subscription/hooks/useSubscribeForm.tsx b/src/subscription/hooks/useSubscribeForm.tsx index 562f71c3..ca5efdec 100644 --- a/src/subscription/hooks/useSubscribeForm.tsx +++ b/src/subscription/hooks/useSubscribeForm.tsx @@ -5,13 +5,11 @@ import { useForm } from 'react-hook-form'; import { useMutation } from '@tanstack/react-query'; -import { z } from 'zod'; - import { useToast } from '@shared/components/ui/use-toast'; import { getWorkbookId } from '@workbook/utils'; -import { EMAIL_CONTROL, SUBSCRIBE_USER_ACTIONS } from '@subscription/constants/subscribe'; +import { SUBSCRIBE_USER_ACTIONS } from '@subscription/constants/subscribe'; import { subscribeWorkbookOptions } from '@subscription/remotes/postSubscriptionQueryOptions'; import { emailSubscribeSchema } from '@subscription/schemas'; import { EmailSubscribeFormData } from '@subscription/types/subscription'; @@ -32,6 +30,7 @@ export const useSubscribeForm = () => { defaultValues: { email: '', }, + mode: "onSubmit" }); const { mutate: subscribeWorkbook } = useMutation(subscribeWorkbookOptions({ @@ -40,8 +39,6 @@ export const useSubscribeForm = () => { const onSubmit = (values: EmailSubscribeFormData) => { try { - emailSubscribeSchema.safeParse(values); - subscribeWorkbook(values, { onSuccess: () => { form.reset(); @@ -57,13 +54,9 @@ export const useSubscribeForm = () => { }, }); } catch (error) { - if (error instanceof z.ZodError) { - error.errors.forEach(() => { - toast({ - title: EMAIL_CONTROL.INVALID_EMAIL, - }); - }); - } + toast({ + title: '구독 신청이 되지 않았습니다.' + }); } }; diff --git a/src/subscription/hooks/useUnsubscribeForm.tsx b/src/subscription/hooks/useUnsubscribeForm.tsx index ee47087f..0af805e5 100644 --- a/src/subscription/hooks/useUnsubscribeForm.tsx +++ b/src/subscription/hooks/useUnsubscribeForm.tsx @@ -1,3 +1,4 @@ +import { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; import { useMutation } from "@tanstack/react-query"; @@ -16,23 +17,27 @@ import { zodResolver } from "@hookform/resolvers/zod"; export const useUnsubscribeForm = () => { const { toast } = useToast(); + const [email, setEmail] = useState(undefined); + + useEffect(function getEmailFromCookie() { + const userEmail = getCookie('user-email'); + setEmail(userEmail); + }, []); const form = useForm({ resolver: zodResolver(unSubscribeSchema), defaultValues: { opinion: "", }, + mode: "onSubmit" }); - const { mutate: unsubscribeWorkbook } = useMutation(unsubscribeWorkbookOptions()); + const { mutate: unsubscribeWorkbook } = useMutation(unsubscribeWorkbookOptions(email)); const onSubmit = (values: UnsubscribeFormData) => { try { - const result = unSubscribeSchema.safeParse(values); - const email = getCookie('user-email'); - // 폼 제출 성공 로직 추가 - if (result.success && typeof email === "string") { // zod parse 가 가능하고, cookie 에 이메일이 존재한다면 + if (typeof email === "string") { // zod parse 가 가능하고, cookie 에 이메일이 존재한다면 unsubscribeWorkbook( { email: decodeURIComponent(email), opinion: values.opinion }, { @@ -52,12 +57,9 @@ export const useUnsubscribeForm = () => { ); } } catch (error) { - if (error instanceof z.ZodError) { - error.errors.forEach((err) => { - console.error(err.message); - // 오류 메시지를 UI에 표시하는 로직 추가 - }); - } + toast({ + title: '구독 취소가 되지 않았습니다.' + }); } }; diff --git a/src/subscription/remotes/postUnsubscriptionQueryOptions.ts b/src/subscription/remotes/postUnsubscriptionQueryOptions.ts index db4a3243..5c8e60eb 100644 --- a/src/subscription/remotes/postUnsubscriptionQueryOptions.ts +++ b/src/subscription/remotes/postUnsubscriptionQueryOptions.ts @@ -15,13 +15,13 @@ export const unsubscribeWorkbook = ( return axiosRequest("post", API_ROUTE.UNSUBSCRIBE(), body); }; -export const unsubscribeWorkbookOptions = (): UseMutationOptions< +export const unsubscribeWorkbookOptions = (email: string | undefined): UseMutationOptions< ApiResponse, Error, UnsubscribeBody > => { return { - mutationKey: [QUERY_KEY.UNSUBSCRIBE_WORKBOOK], + mutationKey: [QUERY_KEY.UNSUBSCRIBE_WORKBOOK, email], mutationFn: (body) => unsubscribeWorkbook(body), }; };