diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz index bb288097..3fed1877 100644 Binary files a/.yarn/install-state.gz and b/.yarn/install-state.gz differ diff --git a/src/api/jobs/index.ts b/src/api/jobs/index.ts index 9243e6f8..08ccec2d 100644 --- a/src/api/jobs/index.ts +++ b/src/api/jobs/index.ts @@ -18,9 +18,9 @@ export const putJobs = ({ }; export const postJobs = ({ - memberId, type, startYear, startMonth, endYear, endMonth, + email, type, startYear, startMonth, endYear, endMonth, }: PostJob) => { - return accessClient.post(`/jobs?memberId=${memberId}&type=${type}&startYear=${startYear}&startMonth=${startMonth}&endYear=${endYear}&endMonth=${endMonth}`); + return accessClient.post(`/jobs?email=${email}&type=${type}&startYear=${startYear}&startMonth=${startMonth}&endYear=${endYear}&endMonth=${endMonth}`); }; export const deleteJobs = (jobId: number) => { diff --git a/src/component/modal/createJobModal/index.tsx b/src/component/modal/createJobModal/index.tsx index feb27b88..72229cf0 100644 --- a/src/component/modal/createJobModal/index.tsx +++ b/src/component/modal/createJobModal/index.tsx @@ -3,7 +3,9 @@ import { useState } from 'react'; import { usePostJobs } from 'query/jobs'; import { useGetMembers } from 'query/members'; import { useSnackBar } from 'ts/useSnackBar'; +import { Member } from 'model/member'; import * as S from './style'; +import SearchNameModal from '../searchNameModal'; interface CreateJobModalProps { open: boolean; @@ -18,6 +20,7 @@ interface InitialInfo { startMonth: string; endYear: string; endMonth: string; + email: string; } export default function CreateJobModal({ open, onClose, setIsSuccess }: CreateJobModalProps) { @@ -28,11 +31,13 @@ export default function CreateJobModal({ open, onClose, setIsSuccess }: CreateJo startMonth: '', endYear: '', endMonth: '', + email: '', }; const [info, setInfo] = useState(initialInfo); const { data: members } = useGetMembers({ pageIndex: 0, pageSize: 1000, trackId: null }); const postJobsMutation = usePostJobs({ setIsSuccess, onClose }); const openSnackBar = useSnackBar(); + const [nameModalOpen, setNameModalOpen] = useState(false); const handleInfoChange = (e: React.ChangeEvent) => { setInfo({ @@ -43,6 +48,7 @@ export default function CreateJobModal({ open, onClose, setIsSuccess }: CreateJo const handleCreateInfoClick = () => { const memberId = members?.content.find((member) => member.name === info.name)?.id; + const email = members?.content.find((member) => member.email === info.email)?.email; if (memberId) { if (info.startYear === '' || info.startMonth === '' || info.endYear === '' || info.endMonth === '') { openSnackBar({ type: 'error', message: '빈 칸을 채워주세요.' }); @@ -54,7 +60,7 @@ export default function CreateJobModal({ open, onClose, setIsSuccess }: CreateJo openSnackBar({ type: 'error', message: '시작 월이 종료 월보다 늦을 수 없습니다.' }); } else { postJobsMutation.mutate({ - memberId, + email, type: info.type, startYear: Number(info.startYear), startMonth: Number(info.startMonth), @@ -70,62 +76,80 @@ export default function CreateJobModal({ open, onClose, setIsSuccess }: CreateJo setInfo(initialInfo); }; + const handleSelectMember = (member: Member) => { + setInfo({ + ...info, + name: member.name, + email: member.email, + }); + setNameModalOpen(false); + }; + return ( -
-

직책 생성

-
- - - - - - -
-
- - + <> +
+

직책 생성

+
+ setNameModalOpen(true)} + css={S.textField} + /> + + + + + +
+
+ + +
-
+ {nameModalOpen && ( + setNameModalOpen(false)} + onSelect={handleSelectMember} + /> + )} + ); } diff --git a/src/component/modal/searchNameModal/index.tsx b/src/component/modal/searchNameModal/index.tsx new file mode 100644 index 00000000..6a9981c6 --- /dev/null +++ b/src/component/modal/searchNameModal/index.tsx @@ -0,0 +1,85 @@ +import { + useState, useEffect, useCallback, memo, useMemo, +} from 'react'; +import { + Typography, Box, List, TextField, ListItemText, Modal, ListItemButton, +} from '@mui/material'; +import { useSearchMembers } from 'query/members'; +import { Member } from 'model/member'; +import * as S from './style'; + +interface SearchMemberModalProps { + open: boolean; + onClose: () => void; + onSelect: (member: Member) => void; +} + +function SearchNameModal({ + open, onClose, onSelect, +}: SearchMemberModalProps) { + const [searchQuery, setSearchQuery] = useState(''); + const [searchResults, setSearchResults] = useState([]); + + const { data: membersResult } = useSearchMembers({ + pageIndex: 0, pageSize: 1000, name: searchQuery, + }); + + useEffect(() => { + if (membersResult) { + setSearchResults(membersResult.content); + } else { + setSearchResults([]); + } + }, [membersResult]); + + const handleSearchChange = useCallback((e: React.ChangeEvent) => { + setSearchQuery(e.target.value); + }, []); + + const renderSearchResults = useMemo(() => ( + searchResults + .filter((member) => (member.isDeleted === false && member.memberType === 'REGULAR')) + .map((member) => ( + { + onSelect(member); + onClose(); + }} + > + + + )) + ), [searchResults, onSelect, onClose]); + + return ( + + + + 추가할 사용자를 검색하세요 + + + + + {renderSearchResults} + + + + + ); +} + +export default memo(SearchNameModal); diff --git a/src/component/modal/searchNameModal/style.ts b/src/component/modal/searchNameModal/style.ts new file mode 100644 index 00000000..bd3746e6 --- /dev/null +++ b/src/component/modal/searchNameModal/style.ts @@ -0,0 +1,27 @@ +export const modalView = { + position: 'absolute', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + width: 400, + bgcolor: 'background.paper', + border: '2px solid #000', + boxShadow: 24, + borderRadius: 1, + p: 4, +}; + +export const searchMemberResult = { + height: 300, + overflow: 'auto', +}; + +export const listButton = { + border: 1, + borderColor: 'gray', + borderRadius: 2, + marginBottom: 1, + '&:hover': { + backgroundColor: '#D6F3FE', + }, +}; diff --git a/src/model/job.ts b/src/model/job.ts index db04efe6..21a37b1f 100644 --- a/src/model/job.ts +++ b/src/model/job.ts @@ -1,5 +1,6 @@ export interface PostJob { - memberId: number; + memberId?: number; + email?: string; type: string; startYear: number; startMonth: number;