Skip to content

Commit

Permalink
Merge pull request #169 from YAPP-Github/feature/DEV-104
Browse files Browse the repository at this point in the history
  • Loading branch information
Happhee authored Sep 5, 2024
2 parents 6e778ef + 6255093 commit d40748e
Show file tree
Hide file tree
Showing 38 changed files with 1,064 additions and 39 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-switch": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-toast": "^1.1.5",
"@tanstack/react-query": "^5.40.0",
Expand Down
58 changes: 56 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import TopButton from "@common/components/TopButton";
import { Separator } from "@shared/components/ui/separator";

import ArticleCardsWrapper from "@main/components/ArticleCardsWrapper";
import MainHeader from "@main/components/MainHeader";
import WorkbookCardsWrapper from "@main/components/WorkbookCardsWrapper";
import { Separator } from "@shared/components/ui/separator";

import TopButton from "@common/components/TopButton";

export default function MainPage() {
return (
<main className="flex h-auto w-full flex-col">
<main className="relative flex h-auto w-full flex-col overflow-y-auto">
<MainHeader />
<WorkbookCardsWrapper />
<Separator className="h-[20px] bg-background1" />
Expand Down
6 changes: 4 additions & 2 deletions src/common/hooks/useSusbscribeWorkbook.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { toast } from "@shared/components/ui/use-toast";
import { SUBSCRIBE_USER_ACTIONS } from "@subscription/constants/subscribe";
import { subscribeWorkbookOptions } from "@subscription/remotes/postSubscriptionQueryOptions";
import { subscribeWorkbookQueryOptions } from "@subscription/remotes/postSubscriptionQueryOptions";
import { useMutation } from "@tanstack/react-query";

export default function useSusbscribeWorkbook() {
const { mutate: subscribeWorkbook } = useMutation(subscribeWorkbookOptions());
const { mutate: subscribeWorkbook } = useMutation(
subscribeWorkbookQueryOptions(),
);
const postSubscribeWorkbook = ({
workbookId,
handleSucess,
Expand Down
5 changes: 3 additions & 2 deletions src/main/components/DropDownMenuItemList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ export function DropDownMenuItemList() {

const MENU_ITEM_LIST = isLogin ? AUTH_LINK : UNAUTH_LINK;
const lastIdx = MENU_ITEM_LIST.length - 1;

return (
<ul className="absolute left-0 top-[66px] z-20 h-screen w-full bg-white">
<ul className="fixed left-0 top-[66px] z-10 h-screen w-full overflow-y-auto bg-white">
{MENU_ITEM_LIST.map(({ title, component }, idx) => (
<li
key={`link-to-${idx}`}
className={cn(
"flex flex-col justify-center",
"sub2-bold min-h-[66px] w-full px-[20px] py-[10px]",
title === "구독 토글 리스트" && "p-0",
title === "구독 관리 제목" && "p-0",
lastIdx !== idx && "border-b-[0.5px] border-text-gray3",
)}
>
Expand Down
3 changes: 2 additions & 1 deletion src/main/components/DropdownMenuWrapper/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { XIcon } from "lucide-react";
import HamburgerMenu from "public/assets/icon/hamburgerMenu.svg";

import { DropDownMenuItemList } from "../DropDownMenuItemList";
import HamburgerMenu from "public/assets/icon/hamburgerMenu.svg";
interface DropdownMenuWrapperProps {
toggleMenu: boolean;
handleToggleMenu: () => void;
Expand Down
85 changes: 85 additions & 0 deletions src/main/components/EmailDayManagementDialog/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, { useState } from "react";

import { useMutation } from "@tanstack/react-query";

import { Button } from "@shared/components/ui/button";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@shared/components/ui/dialog";
import useModalWidthControl from "@shared/hooks/useModalWidthControl";
import { cn } from "@shared/utils/cn";

import { SUBSCRIPTION_EMAIL_CLIENT_INFO } from "@main/constants/emailInfo";
import { SubscriptionManagementModel } from "@main/models/SubscriptionManagementModel";
import { patchWorkbookEmailDayMutationOptions } from "@main/remotes/patchWorkbookEmailDayMutationOptions";
import { SubscriptionEmailClientInfo } from "@main/types/emailInfo";

export default function EmailDayManagementDialog({
day,
}: Pick<SubscriptionEmailClientInfo, "day">) {
const [currentDay, setCurrentDay] = useState(day);
useModalWidthControl();

const { mutate: patchWorkbookEmailDay } = useMutation({
...patchWorkbookEmailDayMutationOptions(),
});

const onClickUpdateWorkbookEmailDay = () => {
patchWorkbookEmailDay({
date: SubscriptionManagementModel.getDayPostInfo({ day: currentDay }),
});
};

return (
<Dialog>
<DialogTrigger className="sub2-medium rounded-lg bg-text-gray3 px-2 py-1">
{SUBSCRIPTION_EMAIL_CLIENT_INFO.DAY[currentDay]}
</DialogTrigger>
<DialogContent className="z-50 w-full max-w-[380px] rounded bg-white">
<DialogHeader>
<DialogTitle className="h3-bold mb-[35px]">
이메일을 받고 싶은 요일을
<br /> 선택해주세요.
</DialogTitle>
<DialogDescription className="flex justify-between">
{Object.keys(SUBSCRIPTION_EMAIL_CLIENT_INFO.DAY).map((key) => {
const currentKey =
key as keyof typeof SUBSCRIPTION_EMAIL_CLIENT_INFO.DAY;
const value = SUBSCRIPTION_EMAIL_CLIENT_INFO.DAY[currentKey];
return (
<Button
className={cn(
"body3-medium bg-white text-text-gray2",
"min-w-[150px] p-[12px]",
"rounded-[10px] border-[1px] border-text-gray2",
"hover:bg-main hover:text-white",
key === currentDay && "bg-main text-white",
)}
key={`email-day-${key}`}
onClick={() => setCurrentDay(currentKey)}
>
{value}
</Button>
);
})}
</DialogDescription>
</DialogHeader>
<DialogFooter>
<DialogClose
className="body3-medium mt-[34px] bg-black py-[12px] text-white"
onClick={onClickUpdateWorkbookEmailDay}
>
완료
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
103 changes: 103 additions & 0 deletions src/main/components/EmailManagementMenu/EmailManagementMenu.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { useMutation, useQuery } from "@tanstack/react-query";

import { beforeEach, describe, expect, it } from "vitest";

import QueryClientProviders from "@shared/components/queryClientProvider";
import { createQueryProviderWrapper } from "@shared/constants/createQueryProvider";

import { getSubscriptionWorkbooksQueryOptions } from "@main/remotes/getSubscriptionWorkbooksQueryOptions";
import { patchWorkbookEmailDayMutationOptions } from "@main/remotes/patchWorkbookEmailDayMutationOptions";
import { patchWorkbookEmailTimeMutationOptions } from "@main/remotes/patchWorkbookEmailTimeMutationOptions";

import SubscriptionEmailManagement from ".";
import { render, renderHook, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";

describe("이메일 관련 구독 관리 컴포넌트 테스트", () => {
const renderWithClient = () => {
return render(
<QueryClientProviders>
<SubscriptionEmailManagement />
</QueryClientProviders>,
);
};

beforeEach(async () => {
renderWithClient();
const { result } = renderHook(
() =>
useQuery({
...getSubscriptionWorkbooksQueryOptions(),
}),
{ wrapper: createQueryProviderWrapper() },
);
await waitFor(async () => result.current.isLoading);
await waitFor(async () => result.current.isSuccess);
});

it("이메일 시간 변경하기 테스트", async () => {
const { result } = renderHook(
() =>
useMutation({
...patchWorkbookEmailTimeMutationOptions(),
}),
{ wrapper: createQueryProviderWrapper() },
);

const user = userEvent.setup();
const emialTimeButton = screen.getByRole("button", { name: "오전 9시" });

await user.click(emialTimeButton);
const popupHeading = screen.getByRole("heading", {
level: 2,
});

expect(popupHeading).toHaveTextContent("아침에 이메일을 받고 싶은 시간을");

const tenTimeButton = screen.getByRole("button", { name: "10시" });
await user.click(tenTimeButton);

const closeButton = screen.getByRole("button", { name: "완료" });
await user.click(closeButton);

result.current.mutate({ time: "10:00" });
await waitFor(() => expect(result.current.isSuccess).toBeTruthy());

expect(screen.getByRole("button", { name: "오전 10시" }));
});

it("이메일 요일 변경하기 테스트", async () => {
const { result } = renderHook(
() =>
useMutation({
...patchWorkbookEmailDayMutationOptions(),
}),
{ wrapper: createQueryProviderWrapper() },
);

const user = userEvent.setup();
const emialDayButton = screen.getByRole("button", {
name: "매일 받을래요",
});

await user.click(emialDayButton);
const popupHeading = screen.getByRole("heading", {
level: 2,
});

expect(popupHeading).toHaveTextContent("이메일을 받고 싶은 요일을");

const notWeekButton = screen.getByRole("button", {
name: "주말에는 안 받을래요",
});
await user.click(notWeekButton);

const closeButton = screen.getByRole("button", { name: "완료" });
await user.click(closeButton);

result.current.mutate({ date: "0011111" });
await waitFor(() => expect(result.current.isSuccess).toBeTruthy());

expect(screen.getByRole("button", { name: "주말에는 안 받을래요" }));
});
});
38 changes: 38 additions & 0 deletions src/main/components/EmailManagementMenu/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from "react";

import { useQuery } from "@tanstack/react-query";

import { SubscriptionManagementModel } from "@main/models/SubscriptionManagementModel";
import { getSubscriptionWorkbooksQueryOptions } from "@main/remotes/getSubscriptionWorkbooksQueryOptions";

import EmailDayManagementDialog from "../EmailDayManagementDialog";
import EmailTimeManagementDialog from "../EmailTimeManagementDialog";

export default function SubscriptionEmailManagement() {
const { data } = useQuery({
...getSubscriptionWorkbooksQueryOptions(),
select: ({ data }) => {
const subscriptionManagementModel = new SubscriptionManagementModel({
initSubscriptionManagementServerList: data.data.workbooks,
});
return subscriptionManagementModel.SubscriptionEmailManagementClientInfo;
},
});

return (
<section className="flex flex-col">
{data && (
<>
<article className="flex h-[66px] items-center justify-between py-[10px]">
<p className="sub2-medium">이메일 받는 시간</p>
<EmailTimeManagementDialog {...data} />
</article>
<article className="flex h-[66px] items-center justify-between py-[10px]">
<p className="sub2-medium">이메일 받는 요일</p>
<EmailDayManagementDialog {...data} />
</article>
</>
)}
</section>
);
}
Loading

0 comments on commit d40748e

Please sign in to comment.