diff --git a/app/__test__/ui/lecture/taken-lecture-list.test.tsx b/app/__test__/ui/lecture/taken-lecture-list.test.tsx index f58a8e31..2e35e816 100644 --- a/app/__test__/ui/lecture/taken-lecture-list.test.tsx +++ b/app/__test__/ui/lecture/taken-lecture-list.test.tsx @@ -1,3 +1,4 @@ +import LectureSearch from '@/app/ui/lecture/lecture-search'; import TakenLecture from '@/app/ui/lecture/taken-lecture'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; @@ -7,24 +8,36 @@ describe('Taken lecture list', () => { render(await TakenLecture()); expect(await screen.findByTestId('table-data')); }); - it('커스텀하기 클릭 시 기이수 과목 리스트가 변경된다.', async () => { + + it('커스텀하기 버튼을 클릭하면 기이수 과목 리스트가 변경되며 과목 검색 컴포넌트가 렌더링된다.', async () => { + //given render(await TakenLecture()); + render(); + //when const customButton = await screen.findByTestId('custom-button'); await userEvent.click(customButton); + //then const deleteButton = await screen.findAllByTestId('taken-lecture-delete-button'); expect(deleteButton[0]).toBeInTheDocument(); + + const lectureSearchComponent = await screen.findByTestId('lecture-search-component'); + expect(lectureSearchComponent).toBeInTheDocument(); }); - it('삭제 버튼 클릭 시 해당하는 lecture가 사라진다', async () => { + + it('커스텀 시 삭제 버튼을 클릭하면 해당하는 lecture가 사라진다', async () => { + //given render(await TakenLecture()); const customButton = await screen.findByTestId('custom-button'); await userEvent.click(customButton); + //when const deleteButton = await screen.findAllByTestId('taken-lecture-delete-button'); await userEvent.click(deleteButton[0]); + //then expect(screen.queryByText('딥러닝')).not.toBeInTheDocument(); }); }); diff --git a/app/store/custom-taken-lecture.ts b/app/store/custom-taken-lecture.ts new file mode 100644 index 00000000..a86ddef4 --- /dev/null +++ b/app/store/custom-taken-lecture.ts @@ -0,0 +1,6 @@ +import { atom } from 'jotai'; +import { LectureInfo } from '../type/lecture'; + +export const isCustomizingAtom = atom(false); + +export const customLectureAtom = atom([]); diff --git a/app/type/lecture.ts b/app/type/lecture.ts index 6265f664..d7223575 100644 --- a/app/type/lecture.ts +++ b/app/type/lecture.ts @@ -1,8 +1,17 @@ -export type LectureInfo = { +export interface LectureInfo { + [index: string]: string | number; id: number; year: string; semester: string; lectureCode: string; lectureName: string; credit: number; -}; +} + +export interface SearchedLectureInfo { + [index: string]: string | number; + id: number; + lectureCode: string; + name: string; + credit: number; +} diff --git a/app/ui/lecture/lecture-search/index.tsx b/app/ui/lecture/lecture-search/index.tsx new file mode 100644 index 00000000..7fa18f13 --- /dev/null +++ b/app/ui/lecture/lecture-search/index.tsx @@ -0,0 +1,17 @@ +'use client'; +import React from 'react'; +import LectureSearchBar from './lecture-search-bar'; +import LectureSearchResultContainer from './lecture-search-result-container'; +import { isCustomizingAtom } from '@/app/store/custom-taken-lecture'; +import { useAtomValue } from 'jotai'; + +export default function LectureSearch() { + const isCustomizing = useAtomValue(isCustomizingAtom); + if (!isCustomizing) return null; + return ( +
+ + +
+ ); +} diff --git a/app/ui/lecture/lecture-search/lecture-search-bar.tsx b/app/ui/lecture/lecture-search/lecture-search-bar.tsx new file mode 100644 index 00000000..a09e9a14 --- /dev/null +++ b/app/ui/lecture/lecture-search/lecture-search-bar.tsx @@ -0,0 +1,20 @@ +import Select from '../../view/molecule/select'; +import TextInput from '../../view/atom/text-input/text-input'; +import { MagnifyingGlassIcon } from '@radix-ui/react-icons'; + +export default function LectureSearchBar() { + // 검색 기능을 해당 컴포넌트에서 구현 예정 + return ( +
+
+ +
+
+ +
+
+ ); +} diff --git a/app/ui/lecture/lecture-search/lecture-search-result-container.tsx b/app/ui/lecture/lecture-search/lecture-search-result-container.tsx new file mode 100644 index 00000000..28bec60d --- /dev/null +++ b/app/ui/lecture/lecture-search/lecture-search-result-container.tsx @@ -0,0 +1,47 @@ +import List from '../../view/molecule/list'; +import Image from 'next/image'; +import searchResultIcon from '@/public/assets/searchResultIcon.svg'; +import Grid from '../../view/molecule/grid'; +import { SearchedLectureInfo } from '@/app/type/lecture'; +import AddTakenLectureButton from '../taken-lecture/add-taken-lecture-button'; + +const emptyDataRender = () => { + return ( +
+ search-result-icon +
검색 결과가 표시됩니다
+
+ ); +}; + +export default function LectureSearchResultContainer() { + const renderAddActionButton = (item: SearchedLectureInfo) => { + return ; + }; + const render = (item: SearchedLectureInfo, index: number) => { + const searchLectureItem = item; + return ( + + + {Object.keys(searchLectureItem).map((key, index) => { + if (key === 'id') return null; + return {searchLectureItem[key]}; + })} + {renderAddActionButton ? {renderAddActionButton(searchLectureItem)} : null} + + + ); + }; + + return ( + + ); +} diff --git a/app/ui/lecture/taken-lecture/add-taken-lecture-button.tsx b/app/ui/lecture/taken-lecture/add-taken-lecture-button.tsx new file mode 100644 index 00000000..06732ae9 --- /dev/null +++ b/app/ui/lecture/taken-lecture/add-taken-lecture-button.tsx @@ -0,0 +1,25 @@ +import { SearchedLectureInfo } from '@/app/type/lecture'; +import Button from '../../view/atom/button/button'; +import { useAtom } from 'jotai'; +import { customLectureAtom } from '@/app/store/custom-taken-lecture'; + +interface AddTakenLectureButtonProps { + lectureItem: SearchedLectureInfo; +} +export default function AddTakenLectureButton({ lectureItem }: AddTakenLectureButtonProps) { + const [customLecture, setCustomLecture] = useAtom(customLectureAtom); + const addLecture = () => { + setCustomLecture([ + ...customLecture, + { + id: lectureItem.id, + year: 'CUSTOM', + semester: 'CUSTOM', + lectureCode: lectureItem.lectureCode, + lectureName: lectureItem.name, + credit: lectureItem.credit, + }, + ]); + }; + return