Skip to content

Commit

Permalink
feat: 에러 모달 처리 (#69)
Browse files Browse the repository at this point in the history
* feat: 조회 결과 없음 처리

- 조회 시 404(검색 결과 없음)일 경우 테이블에 [조회된 내역이 없습니다]가 뜨도록 했습니다.

* fix: 결과없음 오류 해결

- <table> 밑에 <div>가 오면 안되는 오류를 수정했습니다.

* feat: 에러 모달 처리

- 필터에서 입력값이 없거나 2글자 미만인 경우,중복으로 수강 신청한 경우, 수강신청에 실패한 경우 에러 모달이 뜨게 했습니다.
- 스토어에 type, field를 저장해서 사용하도록 변경했습니다.
  • Loading branch information
jeewonMoon authored Aug 5, 2024
1 parent 5496920 commit 4ace49a
Show file tree
Hide file tree
Showing 11 changed files with 248 additions and 169 deletions.
3 changes: 2 additions & 1 deletion src/apis/api/course.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export const postCourse = async (id: number) => {
return data;
} catch (error) {
console.error('post course fail: ', error);
return error;
}
};

Expand All @@ -92,7 +93,7 @@ export const deleteCourse = async (id: number) => {

export const deleteAllRegistrations = async () => {
try {
const { data } = await baseAPI.delete('/registrations/all');
const {data} = await baseAPI.delete('/registrations/all');
return data;
} catch (error) {
console.error('모든 수강신청 내역 삭제 실패: ', error);
Expand Down
10 changes: 9 additions & 1 deletion src/apis/utils/instance.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import axios, {AxiosResponse} from 'axios';
import {setModalName} from '@/store/modalSlice';
import {setType} from '@/store/modules/errorSlice';
import {store} from '@/store/store';
import axios, {AxiosError, AxiosResponse} from 'axios';
import Cookies from 'js-cookie';

const baseURL = import.meta.env.VITE_BASE_URL;
Expand Down Expand Up @@ -77,6 +80,11 @@ baseAPI.interceptors.response.use(
}
} else if (status === 404) {
return Promise.resolve({...error.response, data: []} as AxiosResponse);
} else if (status === 409) {
store.dispatch(setModalName('fail'));
store.dispatch(setType(409));

return Promise.resolve({...error.response} as AxiosError);
}

return Promise.reject(error);
Expand Down
13 changes: 7 additions & 6 deletions src/components/CourseRegister/RegisterFilters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import FilterButton from '../common/FilterButton';
import FilterInput from '../common/FilterInput';
import SelectBox from '../common/SelectBox';
import {term, searchOptions} from '@assets/data/filter';
import {
FilterBox,
FilterContainer,
FilterWrap,
} from '../LectureList/Filters';
import {FilterBox, FilterContainer, FilterWrap} from '../LectureList/Filters';

interface FiltersProps {
onSearch: (newList: CourseTypes[], filter: CourseTypes, searchOption: string) => Promise<void>;
onSearch: (
newList: CourseTypes[],
filter: CourseTypes,
searchOption: string,
) => Promise<void>;
}

function RegisterFilters({onSearch}: FiltersProps) {
Expand Down Expand Up @@ -132,6 +132,7 @@ function RegisterFilters({onSearch}: FiltersProps) {
filter={filter}
onSearch={onSearch}
searchOption={searchOption}
isRegister={true}
/>
</RegisterFilterContainer>
);
Expand Down
61 changes: 44 additions & 17 deletions src/components/Wishlist/Filters.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { useState } from 'react';
import {useState} from 'react';
import search from '@assets/img/search.png';
import styled from 'styled-components';
import SelectBox from '@components/common/SelectBox';
import FilterInput from '@components/common/FilterInput';
import { getCourseList } from '@/apis/api/course';
import { CourseTypes } from '@/assets/types/tableType';
import {getCourseList} from '@/apis/api/course';
import {CourseTypes} from '@/assets/types/tableType';
import {openModalHandler} from '../common/Modal/handlers/handler';
import {useDispatch} from 'react-redux';
import {setField, setType} from '@/store/modules/errorSlice';

const searchOptions = [
{ id: 0, value: '학수번호 검색' },
{ id: 1, value: '교과목명 검색' },
{ id: 2, value: '강의교수 검색' },
{id: 0, value: '학수번호 검색'},
{id: 1, value: '교과목명 검색'},
{id: 2, value: '강의교수 검색'},
];

interface SearchParams {
Expand All @@ -31,7 +34,8 @@ interface FiltersProps {
setSearchResults: React.Dispatch<React.SetStateAction<CourseTypes[]>>;
}

function Filters({ setSearchResults }: FiltersProps) {
function Filters({setSearchResults}: FiltersProps) {
const dispatch = useDispatch();
const [searchParams, setSearchParams] = useState({
searchType: '학수번호 검색',
curiNo: '',
Expand All @@ -40,18 +44,40 @@ function Filters({ setSearchResults }: FiltersProps) {
lesnEmp: '',
});

const setError = (option: string) => {
openModalHandler(dispatch, 'fail');
dispatch(setType(422));
dispatch(setField(option));
};

const handleSearch = async () => {
const filter: FilterParams = {};
switch (searchParams.searchType) {
case '학수번호 검색':
if (searchParams.curiNo) filter.curiNo = searchParams.curiNo;
if (searchParams.classNo) filter.classNo = searchParams.classNo;
if (!searchParams.curiNo || searchParams.curiNo.length < 2) {
setError('학수번호');
} else {
filter.curiNm = searchParams.curiNm;
}
if (!searchParams.classNo || searchParams.classNo.length < 2) {
setError('분반');
} else {
filter.curiNm = searchParams.curiNm;
}
break;
case '교과목명 검색':
if (searchParams.curiNm) filter.curiNm = searchParams.curiNm;
if (!searchParams.curiNm || searchParams.curiNm.length < 2) {
setError('교과목명');
} else {
filter.curiNm = searchParams.curiNm;
}
break;
case '강의교수 검색':
if (searchParams.lesnEmp) filter.lesnEmp = searchParams.lesnEmp;
if (!searchParams.lesnEmp || searchParams.lesnEmp.length < 2) {
setError('강의교수');
} else {
filter.curiNm = searchParams.curiNm;
}
break;
}

Expand All @@ -65,7 +91,7 @@ function Filters({ setSearchResults }: FiltersProps) {
};

const handleInputChange = (name: keyof SearchParams, value: string) => {
setSearchParams(prev => ({ ...prev, [name]: value }));
setSearchParams(prev => ({...prev, [name]: value}));
};

const renderSearchForm = () => {
Expand Down Expand Up @@ -121,21 +147,21 @@ function Filters({ setSearchResults }: FiltersProps) {
<FilterWrap>
<span>조직분류</span>
<SelectBox
options={[{ id: 0, value: '학부' }]}
options={[{id: 0, value: '학부'}]}
tagged={true}
disabled={true}
sizes='m'
onSelect={() => { }}
onSelect={() => {}}
/>
</FilterWrap>
<FilterWrap>
<span>년도/학기</span>
<SelectBox
options={[{ id: 0, value: '2024/2학기' }]}
options={[{id: 0, value: '2024/2학기'}]}
tagged={true}
disabled={true}
sizes='m'
onSelect={() => { }}
onSelect={() => {}}
/>
</FilterWrap>
<FilterBreak />
Expand All @@ -152,7 +178,8 @@ function Filters({ setSearchResults }: FiltersProps) {
</FilterBox>
<SearchButton onClick={handleSearch}>
<img src={search} />
검색</SearchButton>
검색
</SearchButton>
</FilterArea>
</FilterContainer>
);
Expand Down
39 changes: 36 additions & 3 deletions src/components/common/FilterButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,56 @@ import styled from 'styled-components';
import search from '@assets/img/search.png';
import {CourseTypes} from '@/assets/types/tableType';
import {getCourseList, getWishlist} from '@/apis/api/course';
import {useAppSelector} from '@/store/hooks';
import {useAppDispatch, useAppSelector} from '@/store/hooks';
import {setField, setType} from '@/store/modules/errorSlice';
import {openModalHandler} from './Modal/handlers/handler';

interface ButtonProps {
label: string;
filter: CourseTypes;
onSearch: (newList: CourseTypes[], filter: CourseTypes, searchOption: string) => Promise<void>;
isRegister?: boolean;
onSearch: (
newList: CourseTypes[],
filter: CourseTypes,
searchOption: string,
) => Promise<void>;
searchOption: string;
}

function FilterButton({label, filter, onSearch, searchOption}: ButtonProps) {
function FilterButton({
label,
filter,
onSearch,
searchOption,
isRegister = false,
}: ButtonProps) {
const dispatch = useAppDispatch();
const studentId = useAppSelector(state => state.userInfo.username);

const setError = () => {
openModalHandler(dispatch, 'fail');
dispatch(setType(422));
dispatch(setField(searchOption));
};

const searchLecture = async () => {
let result: CourseTypes[] = [];

if (searchOption === '관심과목') {
result = await getWishlist(studentId);
} else {
if (isRegister) {
if (Object.keys(filter).length == 0 && filter.constructor === Object) {
setError();
return;
} else {
const checked = Object.values(filter).filter(item => item.length < 2);
if (checked.length !== 0) {
setError();
return;
}
}
}
result = await getCourseList(filter);
}
onSearch(result, filter, searchOption);
Expand Down
Loading

0 comments on commit 4ace49a

Please sign in to comment.