Skip to content

Commit

Permalink
chore: commit for merge
Browse files Browse the repository at this point in the history
  • Loading branch information
yougyung committed May 1, 2024
2 parents 8272373 + 5510a76 commit 6bd06f5
Show file tree
Hide file tree
Showing 28 changed files with 225 additions and 95 deletions.
5 changes: 3 additions & 2 deletions app/(sub-page)/my/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import LectureSearch from '@/app/ui/lecture/lecture-search';
import TakenLecture from '@/app/ui/lecture/taken-lecture';
import UserInfoNavigator, { UserInfoNavigatorSkeleton } from '@/app/ui/user/user-info-navigator/user-info-navigator';
import UserInfoNavigator from '@/app/ui/user/user-info-navigator/user-info-navigator';
import UserInfoNavigatorSkeleton from '@/app/ui/user/user-info-navigator/user-info-navigator.skeleton';
import ContentContainer from '@/app/ui/view/atom/content-container';
import Drawer from '@/app/ui/view/molecule/drawer/drawer';
import { DIALOG_KEY } from '@/app/utils/key/dialog.key';
import { DIALOG_KEY } from '@/app/utils/key/dialog-key.util';
import { Suspense } from 'react';

export default function MyPage() {
Expand Down

This file was deleted.

16 changes: 0 additions & 16 deletions app/(sub-page)/result/layout.tsx

This file was deleted.

14 changes: 11 additions & 3 deletions app/(sub-page)/result/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import ResultCategoryCard from '@/app/ui/result/result-category/result-category-card';
import ResultCategoryCard from '@/app/ui/result/result-category-card/result-category-card';
import UserInfoCard from '@/app/ui/user/user-info-card/user-info-card';
import ContentContainer from '@/app/ui/view/atom/content-container';
import { cn } from '@/app/utils/shadcn/utils';
import { RESULT_CATEGORY, ResultCategoryKey } from '@/app/utils/key/result-category.key';
import { RESULT_CATEGORY } from '@/app/utils/key/result-category.key';
import ResultCategoryDetail from '@/app/ui/result/result-category-detail/result-category-detail';

function ResultPage() {
interface ResultPageProp {
searchParams: { category: string };
}

function ResultPage({ searchParams }: ResultPageProp) {
const { category } = searchParams;
const DUMMY_DATA = {
category: 'COMMON_CULTURE' as keyof typeof RESULT_CATEGORY,
totalCredit: 70,
Expand Down Expand Up @@ -32,7 +38,9 @@ function ResultPage() {
/>
))}
</div>
{category && <ResultCategoryDetail category={category} />}
</div>
);
}

export default ResultPage;
22 changes: 18 additions & 4 deletions app/business/result/result.query.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { LectureInfo } from '@/app/type/lecture';
import { API_PATH } from '../api-path';
import { cookies } from 'next/headers';
import { httpErrorHandler } from '@/app/utils/http/http-error-handler';

export interface ResultCategoryDetailLectures {
categoryName: string;
Expand All @@ -26,8 +28,20 @@ export interface ResultUserInfo {
takenCredit: number;
}

export const fetchResultCategoryDetailInfo = async (): Promise<ResultCategoryDetailInfo> => {
const response = await fetch(API_PATH.resultCategoryDetailInfo);
const data = await response.json();
return data;
export const fetchResultCategoryDetailInfo = async (category: string): Promise<ResultCategoryDetailInfo> => {
//FIX : category를 querystring으로 호출하는 건은 mock단계에서는 불필요할 것으로 예상, 실제 api 연결시 변경 예정
try {
const response = await fetch(`${API_PATH.resultCategoryDetailInfo}`, {
headers: {
Authorization: `Bearer ${cookies().get('accessToken')?.value}`,
},
});
const result = await response.json();

httpErrorHandler(response, result);

return result;
} catch (error) {
throw error;
}
};
4 changes: 0 additions & 4 deletions app/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import RevenueChart from '@/app/ui/invoice/revenu-chart';
import { RevenueChartSkeleton } from '@/app/ui/skeletons';
import { Suspense } from 'react';

export default async function Page() {
return (
<main>
Expand Down
13 changes: 10 additions & 3 deletions app/hooks/useDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
import { DialogKey } from '../utils/key/dialog.key';
import { DialogKey } from '../utils/key/dialog-key.util';
import { updateDialogAtom } from '../store/dialog';
import { useAtom } from 'jotai';

export default function useDialog(key: DialogKey) {
export default function useDialog(key: DialogKey, onClose?: () => void) {
const [isOpenDialogList, setOpenDialogList] = useAtom(updateDialogAtom);

const isOpen = isOpenDialogList[key];

const open = () => {
setOpenDialogList([key, true]);
};

const close = () => {
setOpenDialogList([key, false]);
onClose?.();
};

const toggle = () => {
const prevState = isOpenDialogList[key];
setOpenDialogList([key, !prevState]);

if (prevState) onClose?.();
};

return { isOpen, close, toggle };
return { isOpen, open, close, toggle };
}
2 changes: 1 addition & 1 deletion app/mocks/handlers/result-handler.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { mockDatabase } from '../db.mock';
export const resultHandlers = [
http.get(API_PATH.resultCategoryDetailInfo, async () => {
const resultCategoryDetailInfo = mockDatabase.getResultCategoryDetailInfo();
await delay(100);
await delay(4000);
return HttpResponse.json(resultCategoryDetailInfo);
}),
];
2 changes: 1 addition & 1 deletion app/store/dialog.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { atom } from 'jotai';
import { DIALOG_KEY } from '../utils/key/dialog.key';
import { DIALOG_KEY } from '../utils/key/dialog-key.util';

const initialState = {
[DIALOG_KEY.RESULT_CATEGORY]: false,
Expand Down
2 changes: 1 addition & 1 deletion app/ui/lecture/lecture-search/lecture-search.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { screen } from '@storybook/testing-library';
import TakenLectureLabel from '../taken-lecture/taken-lecture-label';
import TakenLectureList from '../taken-lecture/taken-lecture-list';
import LectureSearch from '.';
import { DIALOG_KEY } from '@/app/utils/key/dialog.key';
import { DIALOG_KEY } from '@/app/utils/key/dialog-key.util';
import Drawer from '../../view/molecule/drawer/drawer';
import { delay } from 'msw';

Expand Down
2 changes: 1 addition & 1 deletion app/ui/lecture/taken-lecture/taken-lecture-label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Link from 'next/link';
import Button from '../../view/atom/button/button';
import LabelContainer from '../../view/atom/label-container/label-container';
import useDialog from '@/app/hooks/useDialog';
import { DIALOG_KEY } from '@/app/utils/key/dialog.key';
import { DIALOG_KEY } from '@/app/utils/key/dialog-key.util';

export default function TakenLectureLabel() {
const { toggle } = useDialog(DIALOG_KEY.LECTURE_SEARCH);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import Book from '@/public/assets/book.svg';
import Image from 'next/image';
import useDialog from '@/app/hooks/useDialog';
import * as React from 'react';
import { DIALOG_KEY } from '@/app/utils/key/dialog.key';
import { RESULT_CATEGORY, RESULT_CATEGORY_KO, ResultCategoryKey } from '@/app/utils/key/result-category.key';
import { DIALOG_KEY } from '@/app/utils/key/dialog-key.util';
import PieChart from '../../view/molecule/pie-chart/pie-chart';
import Button from '../../view/atom/button/button';
import { RESULT_CATEGORY, RESULT_CATEGORY_KO, ResultCategoryKey } from '@/app/utils/key/result-category.key';
import { useRouter } from 'next/navigation';

interface ResultCategoryCardProps {
category: ResultCategoryKey;
Expand All @@ -34,9 +35,14 @@ const filterSeveralMajor = (category: ResultCategoryKey) => {

function ResultCategoryCard({ category, totalCredit, takenCredit }: ResultCategoryCardProps) {
const { toggle } = useDialog(DIALOG_KEY.RESULT_CATEGORY);
const { replace } = useRouter();

const percentage = Number(((takenCredit / totalCredit) * 100).toFixed(0));

function handleClickButton() {
toggle();
replace('/result?category=COMMON_CULTURE');
}
return (
<div
className={cn('flex flex-col gap-6 zIndex-1 rounded-xl shadow-lg bg-white p-[0.4rem]', 'md:w-80 md:p-[1.8rem]')}
Expand Down Expand Up @@ -64,7 +70,8 @@ function ResultCategoryCard({ category, totalCredit, takenCredit }: ResultCatego
</span>
</div>
</div>
<Button size="sm" label="과목 확인" onClick={toggle} />

<Button size="sm" label="과목 확인" onClick={handleClickButton} />
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import LabelContainerSkeleton from '@/app/ui/view/atom/label-container/label-container.skeleton';
import Skeleton from '@/app/ui/view/atom/skeleton';

export default function ResultCategoryDetailContentSkeleton() {
return (
<div className="md:w-[80vw] max-w-[1200px] p-2">
<div className="flex justify-between mb-14">
<div className="flex flex-col gap-4">
<Skeleton className="h-10 w-40" />
<Skeleton className="h-4 w-80" />
</div>
<Skeleton className="h-10 w-28" />
</div>
{Array.from({ length: 3 }).map((_, index) => (
<div className="my-4 flex flex-col gap-4" key={index}>
<LabelContainerSkeleton rightElement={<Skeleton className="h-10 w-28" />} />
<Skeleton className="h-40 w-30" />
</div>
))}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { Meta, StoryObj } from '@storybook/react';
import { expect, userEvent } from '@storybook/test';
import { mockDatabase } from '@/app/mocks/db.mock';
import ResultCategoryDetailContent from './result-category-detail-content';
import { screen } from '@storybook/testing-library';
import { delay } from 'msw';

const meta = {
title: 'ui/result-category/ResultCategoryDetailContent',
component: ResultCategoryDetailContent,
args: { info: mockDatabase.getResultCategoryDetailInfo() },
decorators: [(Story) => <Story />],
} as Meta<typeof ResultCategoryDetailContent>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
play: async ({ step }) => {
await step('미이수 과목을 노출합니다.', async () => {
await delay(2000);

expect(screen.getByText('영어2')).toBeInTheDocument();
});

await step('토글을 클릭하면 기이수 과목을 노출합니다.', async () => {
const lectureToggle = await screen.findAllByTestId('lecture-toggle');
await userEvent.click(lectureToggle[0]);

await delay(3000);

expect(screen.queryByText('성서와 인간 이해')).not.toBeInTheDocument();
});
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import { cn } from '@/app/utils/shadcn/utils';

import { useState } from 'react';
import { ResultCategoryDetailLectureToggle } from './result-category-detail-lecture-toggle';
import ResultCagegoryDetailLecture from './result-cagegory-detail-lecture';
import { ResultCategoryDetailLectureToggle } from '../result-category-detail-lecture/result-category-detail-lecture-toggle';
import ResultCagegoryDetailLecture from '../result-category-detail-lecture/result-cagegory-detail-lecture';
import { ResultCategoryDetailInfo } from '@/app/business/result/result.query';

interface ResultCategoryDetailContentProps {
Expand All @@ -16,21 +16,22 @@ function ResultCategoryDetailContent({ info }: ResultCategoryDetailContentProps)
const [isTakenLecture, setIsTakenLectrue] = useState(false);

return (
<div className="md:w-[80vw] max-w-[1200px] p-2">
<div className="md:w-[80vw] max-w-[1200px] p-2 overflow-scroll">
<div className="flex justify-between">
<div>
<h1 className={cn('text-2xl font-bold', 'md:text-4xl')}>전공필수</h1>
<p className={cn('relative flex items-center gap-2 text-sm text-gray-6 font-medium my-2', 'md:text-lg')}>
<div className={cn('relative flex items-center gap-2 text-sm text-gray-6 font-medium my-2', 'md:text-lg')}>
<span>전공필수 과목 중</span>
<div className="w-20 h-10">
<ResultCategoryDetailLectureToggle
checked={isTakenLecture}
data-testid="lecture-toggle"
onCheckedChange={setIsTakenLectrue}
className="absolute zIndex-2"
/>
</div>
<span>과목이 표시됩니다.</span>
</p>
</div>
</div>
<div className={cn('text-2xl font-bold', 'md:text-4xl')}>
<span className="text-point-blue">{takenCredit}</span> / {totalCredit}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use client';
import Modal from '../../view/molecule/modal/modal';
import { DIALOG_KEY } from '@/app/utils/key/dialog-key.util';
import Drawer from '../../view/molecule/drawer/drawer';
import Responsive from '@/app/ui/responsive';
import React, { useEffect } from 'react';
import useDialog from '@/app/hooks/useDialog';
import { useRouter } from 'next/navigation';

interface ResultCategoryDetailDialogProp {
children: React.ReactNode;
querystring?: string;
}

export default function ResultCategoryDetailDialog({ children, querystring }: ResultCategoryDetailDialogProp) {
const { replace } = useRouter();
const { isOpen, open } = useDialog(DIALOG_KEY.RESULT_CATEGORY);

useEffect(() => {
if (querystring && !isOpen) open();
}, []);

const handleCloseDialog = () => {
replace('/result');
};

return (
<>
<Responsive maxWidth={767}>
<Drawer drawerKey={DIALOG_KEY.RESULT_CATEGORY} onClose={handleCloseDialog} className="h-[90vh]">
{children}
</Drawer>
</Responsive>
<Responsive minWidth={768}>
<Modal modalKey={DIALOG_KEY.RESULT_CATEGORY} onClose={handleCloseDialog}>
{children}
</Modal>
</Responsive>
</>
);
}
20 changes: 20 additions & 0 deletions app/ui/result/result-category-detail/result-category-detail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import ResultCategoryDetailContent from '@/app/ui/result/result-category-detail-content/result-category-detail-content';
import { fetchResultCategoryDetailInfo } from '@/app/business/result/result.query';
import ResultCategoryDetailContentSkeleton from '@/app/ui/result/result-category-detail-content/result-category-detail-content.skeleton';
import ResultCategoryDetailDialog from './result-category-detail-dialog';
import { Suspense } from 'react';

export default function ResultCategoryDetail({ category }: { category: string }) {
return (
<ResultCategoryDetailDialog querystring={category}>
<Suspense fallback={<ResultCategoryDetailContentSkeleton />}>
<ResultCategoryDetailInfo category={category} />
</Suspense>
</ResultCategoryDetailDialog>
);
}

async function ResultCategoryDetailInfo({ category }: { category: string }) {
const data = await fetchResultCategoryDetailInfo(category);
return <ResultCategoryDetailContent info={data} />;
}
Loading

0 comments on commit 6bd06f5

Please sign in to comment.