From 11333ccb8b126f7973cfeb3ba9477f58878ca1f2 Mon Sep 17 00:00:00 2001 From: Seunghyo Date: Thu, 23 May 2024 00:23:39 +0900 Subject: [PATCH 1/5] feat: datepicker timepicker null --- src/components/JD/JDDeleteModal.tsx | 6 ++--- src/components/common/TimePicker.tsx | 4 ++-- src/pages/JDDetailPage.tsx | 5 +++++ src/pages/JDPlusPage.tsx | 33 +++++++++++----------------- 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/components/JD/JDDeleteModal.tsx b/src/components/JD/JDDeleteModal.tsx index 09fa8ec..f8add14 100644 --- a/src/components/JD/JDDeleteModal.tsx +++ b/src/components/JD/JDDeleteModal.tsx @@ -1,14 +1,14 @@ import React, { FC } from "react"; import styled from "styled-components"; import warning from "../../assets/icons/icon_delete_warning.svg"; -import { useNavigate } from "react-router-dom"; interface ModalProps { isOpen: boolean; onClose: () => void; + onCancel: () => void; } -const JDDeleteModal: FC = ({ isOpen, onClose }) => { +const JDDeleteModal: FC = ({ isOpen, onClose, onCancel }) => { if (!isOpen) { return null; } @@ -25,7 +25,7 @@ const JDDeleteModal: FC = ({ isOpen, onClose }) => { - +
취소
void; }; const TimePicker: React.FC = ({ time, setTime }) => { - const [startDate, setStartDate] = useState(new Date()); + const [startDate, setStartDate] = useState(null); const handleDateChange = (date: Date | null) => { if (date) { diff --git a/src/pages/JDDetailPage.tsx b/src/pages/JDDetailPage.tsx index e794fe6..9b18bc8 100644 --- a/src/pages/JDDetailPage.tsx +++ b/src/pages/JDDetailPage.tsx @@ -54,6 +54,10 @@ const JDDetailPage: React.FC = () => { document.body.style.overflow = "auto"; }; + const cancelModal = () => { + setIsModalOpen(false); + }; + const ExptoggleContainer = () => { if (!active) { setActive(!active); @@ -129,6 +133,7 @@ const JDDetailPage: React.FC = () => { } {!isLoading ? ( diff --git a/src/pages/JDPlusPage.tsx b/src/pages/JDPlusPage.tsx index 15efbff..a6378d8 100644 --- a/src/pages/JDPlusPage.tsx +++ b/src/pages/JDPlusPage.tsx @@ -12,7 +12,7 @@ import { JobAPI } from "../types/type"; import { getCookie } from "../services/cookie"; const JDPlusPage: React.FC = () => { - const [selectedTime, setSelectedTime] = useState("10:00"); + const [selectedTime, setSelectedTime] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); const nav = useNavigate(); const user = getCookie("user"); @@ -48,14 +48,15 @@ const JDPlusPage: React.FC = () => { // endTime 계산 const getEndTime = () => { if (!jobData.endedAt) return null; // endDate가 null이면 null 반환 - - const hours = parseInt(selectedTime.split(":")[0]); - const minutes = parseInt(selectedTime.split(":")[1]); - - const endTime = new Date(jobData.endedAt); // endDate를 기반으로 새 Date 객체 생성 - endTime.setHours(hours, minutes, 0); // 시간과 분 설정 - console.log("최종시간은", endTime); - return endTime; + if (selectedTime) { + const hours = parseInt(selectedTime.split(":")[0]); + const minutes = parseInt(selectedTime.split(":")[1]); + + const endTime = new Date(jobData.endedAt); // endDate를 기반으로 새 Date 객체 생성 + endTime.setHours(hours, minutes, 0); // 시간과 분 설정 + console.log("최종시간은", endTime); + return endTime; + } }; const endTime = getEndTime(); @@ -79,7 +80,6 @@ const JDPlusPage: React.FC = () => { } else if (jobData.endedAt && date < jobData.endedAt) { setJobData({ ...jobData, startAt: date }); } else { - alert("시작 날짜는 끝나는 날짜보다 앞이여야합니다."); setJobData({ ...jobData, startAt: jobData.endedAt }); } }; @@ -90,8 +90,6 @@ const JDPlusPage: React.FC = () => { } else if (jobData.startAt && jobData.startAt) { setJobData({ ...jobData, endedAt: date }); } else { - alert("끝나는 날짜는 시작 날짜보다 뒤여야합니다."); - setJobData({ ...jobData, endedAt: jobData.startAt }); } }; @@ -192,10 +190,7 @@ const JDPlusPage: React.FC = () => { ) : (
- +
)}
~
@@ -208,13 +203,11 @@ const JDPlusPage: React.FC = () => { ) : (
- +
)} clock +
Date: Thu, 23 May 2024 00:50:27 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20=EC=97=AD=EB=9F=89=20=ED=82=A4?= =?UTF-8?q?=EC=9B=8C=EB=93=9C=20=ED=95=84=ED=84=B0=EB=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/JD/ExperienceList.tsx | 186 +++++++++++++++------------ 1 file changed, 104 insertions(+), 82 deletions(-) diff --git a/src/components/JD/ExperienceList.tsx b/src/components/JD/ExperienceList.tsx index 4a3e2f7..0c58cd6 100644 --- a/src/components/JD/ExperienceList.tsx +++ b/src/components/JD/ExperienceList.tsx @@ -23,6 +23,7 @@ import { getCookie } from "../../services/cookie"; import { getAllTags } from "../../services/JD/tagApi"; import { useParams } from "react-router-dom"; import { formatDateRange } from "../../pages/JDListPage"; +import { ExperienceDetailType, KeywordType } from "../../types/experience"; type TabType = "basic" | "my"; @@ -183,30 +184,6 @@ const ExperienceList: React.FC = ({ ]); const jdId = useParams().jdId; - const [anchorEl, setAnchorEl] = React.useState(null); - const open = Boolean(anchorEl); - const id = open ? "tag-popper" : undefined; - - // 기본 역량 키워드 페이지네이션 - const keywordsPerPage = 9; - const [currentBasicKeywordPage, setCurrentBasicKeywordPage] = - React.useState(1); - const firstBasicKeywordIndex = - (currentBasicKeywordPage - 1) * keywordsPerPage; - const lastBasicKeywordIndex = firstBasicKeywordIndex + keywordsPerPage; - const currentBasicKeywords = basicKeywords.slice( - firstBasicKeywordIndex, - lastBasicKeywordIndex - ); - // My 역량 키워드 페이지네이션 - const [currentMyKeywordPage, setCurrentMyKeywordPage] = React.useState(1); - const firstMyKeywordIndex = (currentMyKeywordPage - 1) * keywordsPerPage; - const lastMyKeywordIndex = firstMyKeywordIndex + keywordsPerPage; - const currentMyKeywords = myKeywords.slice( - firstMyKeywordIndex, - lastMyKeywordIndex - ); - useEffect(() => { if (jdId) { // getExperienceList(jdId, user.token); @@ -229,15 +206,15 @@ const ExperienceList: React.FC = ({ searchText: string, token: string ) => { - // try { - // const response = await searchTextExperienceList(jdId, searchText, token); - // console.log(response); - // setExperienceData(response.data.experiences); - // console.log(experienceData); - // } catch (error) { - // console.error(error); - // alert(JSON.stringify(error)); - // } + try { + const response = await searchTextExperienceList(jdId, searchText, token); + console.log(response); + setExperienceData(response.data.experiences); + console.log(experienceData); + } catch (error) { + console.error(error); + alert(JSON.stringify(error)); + } }; const getFilteredExperienceList = async ( @@ -260,45 +237,6 @@ const ExperienceList: React.FC = ({ } }; - // 체크된 역량 키워드 리스트 - const [checkedKeywords, setCheckedKeywords] = React.useState([]); - - // 키워드 체크박스 관리 함수 - const handleCheckedKeywords = (e: React.ChangeEvent) => { - if (e.target) { - e.target.checked - ? setCheckedKeywords([...checkedKeywords, e.target.value]) - : setCheckedKeywords( - checkedKeywords.filter((choice) => choice !== e.target.value) - ); - } - }; - - // 역량 키워드 클릭 함수 - const handleTagPopper = (event: React.MouseEvent) => { - setAnchorEl(anchorEl ? null : event.currentTarget); - }; - - // 역량 키워드 필터된 경험 데이터, 북마크 - const filteredExpData = experienceData.filter((experience) => { - const strongPointNames = experience.strongPoints.map((point) => point.name); - const matchedKeywords = strongPointNames.filter((name) => - checkedKeywords.includes(name) - ); - return matchedKeywords.length > 0; - }); - const bookedData = experienceData.filter((experience) => { - // 북마크가 ON인 요소만 필터링 - return experience.bookmarked === "ON"; - }); - const filteredBookedData = experienceData.filter((experience) => { - const strongPointNames = experience.strongPoints.map((point) => point.name); - const matchedKeywords = strongPointNames.filter((name) => - checkedKeywords.includes(name) - ); - return experience.bookmarked === "ON" && matchedKeywords.length > 0; - }); - //상위태그 하위태그 필터링 const handleTagSelection = ( selectedmainTag: string, @@ -338,6 +276,86 @@ const ExperienceList: React.FC = ({ } }, [searchText]); + //역량키워드 관련 팝업 + const [myKeywordList, setMyKeywordList] = React.useState([]); + const [anchorEl, setAnchorEl] = React.useState(null); + const open = Boolean(anchorEl); + const id = open ? "tag-popper" : undefined; + + // 기본 역량 키워드 페이지네이션 + const keywordsPerPage = 9; + const [currentBasicKeywordPage, setCurrentBasicKeywordPage] = + React.useState(1); + const firstBasicKeywordIndex = + (currentBasicKeywordPage - 1) * keywordsPerPage; + const lastBasicKeywordIndex = firstBasicKeywordIndex + keywordsPerPage; + const currentBasicKeywords = basicKeywords.slice( + firstBasicKeywordIndex, + lastBasicKeywordIndex + ); + + // My 역량 키워드 페이지네이션 + const [currentMyKeywordPage, setCurrentMyKeywordPage] = React.useState(1); + const firstMyKeywordIndex = (currentMyKeywordPage - 1) * keywordsPerPage; + const lastMyKeywordIndex = firstMyKeywordIndex + keywordsPerPage; + const currentMyKeywords = myKeywordList.slice( + firstMyKeywordIndex, + lastMyKeywordIndex + ); + + // 체크된 역량 키워드 리스트 + const [checkedKeywords, setCheckedKeywords] = React.useState( + [] + ); + + // 키워드 체크박스 체크 여부 + const isKeywordChecked = (item: KeywordType) => { + return checkedKeywords.some( + (keyword) => keyword.id === item.id && keyword.name === item.name + ); + }; + + // 키워드 체크박스 핸들러 + const handleKeywordChange = ( + e: React.ChangeEvent, + type: TabType + ) => { + if (e.target) { + if (e.target.checked) { + const keywordId = e.target.value; + const selectedKeyword = ( + type === "basic" ? basicKeywords : myKeywordList + ).find((item) => item.id === keywordId); + setCheckedKeywords([ + ...checkedKeywords, + { id: keywordId, name: selectedKeyword?.name || "" }, + ]); + } else { + setCheckedKeywords( + checkedKeywords.filter((item) => item.id !== e.target.value) + ); + } + } + }; + + // 역량 키워드 클릭 함수 + const handleTagPopper = (event: React.MouseEvent) => { + setAnchorEl(anchorEl ? null : event.currentTarget); + }; + + // 역량 키워드 필터된 경험 데이터, 북마크 + const filteredExpData = experienceData.filter((experience) => + experience.strongPoints.some((item: KeywordType) => isKeywordChecked(item)) + ); + + const bookedData = experienceData.filter((experience) => { + // 북마크가 ON인 요소만 필터링 + return experience.bookmarked === "ON"; + }); + const filteredBookedData = bookedData.filter((experience) => + experience.strongPoints.some((item: KeywordType) => isKeywordChecked(item)) + ); + return ( {!showDetail ? ( @@ -452,7 +470,7 @@ const ExperienceList: React.FC = ({ /> ) : ( = ({ handleKeywordChange(e, "basic")} /> )) : currentMyKeywords.map((item) => ( handleKeywordChange(e, "my")} /> ))}
@@ -489,7 +507,7 @@ const ExperienceList: React.FC = ({ 총 
{checkedKeywords.length === 0 - ? ExpData.length + ? experienceData?.length : filteredExpData.length} 개
@@ -516,7 +534,9 @@ const ExperienceList: React.FC = ({ tags={post.strongPoints.map((point) => point.name)} period={formatDateRange(post.startedAt, post.endedAt)} bookmark={post.bookmarked === "ON" ? true : false} - checkedKeywords={checkedKeywords} + checkedKeywords={checkedKeywords.map( + (item: KeywordType) => item.name + )} onClick={() => setshowDetail(true)} /> ))} @@ -537,7 +557,9 @@ const ExperienceList: React.FC = ({ tags={post.strongPoints.map((point) => point.name)} period={formatDateRange(post.startedAt, post.endedAt)} bookmark={post.bookmarked === "ON" ? true : false} - checkedKeywords={checkedKeywords} + checkedKeywords={checkedKeywords.map( + (item: KeywordType) => item.name + )} onClick={() => setshowDetail(true)} /> ))} From 20fd1799127c23199cf34abb2c6e19219a3466cb Mon Sep 17 00:00:00 2001 From: Seunghyo Date: Thu, 23 May 2024 02:19:42 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20=EA=B3=B5=EA=B3=A0=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B2=84=ED=8A=BC=20=ED=81=AC=EA=B8=B0=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/JD/ExperienceList.tsx | 113 ++++++++++----------------- src/components/common/TimePicker.tsx | 2 +- src/pages/JDPlusPage.tsx | 6 ++ 3 files changed, 48 insertions(+), 73 deletions(-) diff --git a/src/components/JD/ExperienceList.tsx b/src/components/JD/ExperienceList.tsx index 0c58cd6..7aa6b84 100644 --- a/src/components/JD/ExperienceList.tsx +++ b/src/components/JD/ExperienceList.tsx @@ -1,5 +1,4 @@ import React, { useEffect, useState } from "react"; -import ExpData from "../../services/JD/ExpData"; import Experience from "./Experience"; import styled from "styled-components"; import FillfilterIcon from "../../assets/icons/icon_filter_fill.svg"; @@ -12,7 +11,6 @@ import { ArrowDownThin, ArrowUpThin, Options } from "../../assets"; import { Popper } from "@mui/material"; import PopperPagination from "../Experience/PopperPagination"; import { basicKeywords } from "../../assets/data/keywords"; -import { myKeywords } from "../../services/Experience/myKeywords"; import Checkbox from "../common/Checkbox"; import { getAllExperienceList, @@ -23,7 +21,7 @@ import { getCookie } from "../../services/cookie"; import { getAllTags } from "../../services/JD/tagApi"; import { useParams } from "react-router-dom"; import { formatDateRange } from "../../pages/JDListPage"; -import { ExperienceDetailType, KeywordType } from "../../types/experience"; +import { KeywordType } from "../../types/experience"; type TabType = "basic" | "my"; @@ -41,6 +39,11 @@ type ExpTagAPI = { name: string; }; +type MyTagAPI = { + id: string; + name: string | null; +}; + type ContentAPI = { question: string; answer: string; @@ -69,8 +72,8 @@ const ExperienceList: React.FC = ({ const [showDetail, setshowDetail] = useState(false); //경험 상세 보여주기 const [showTagPopup, setShowTagPopup] = useState(false); // 태그 필터링 const [searchText, setSearchText] = useState(""); //검색 입력 - const [mainTag, setMainTag] = useState(""); // 선택된 상위태그 - const [subTag, setSubTag] = useState(""); //선택된 하위태그 + const [mainTag, setMainTag] = useState({ id: "", name: "" }); // 선택된 상위태그 + const [subTag, setSubTag] = useState({ id: "", name: "" }); //선택된 하위태그 const [filterCount, setfilterCount] = useState(-1); //검색된 경험의 숫자, 검색 안된 상태에서는 -1 const [keywordTabOption, setKeywordTabOption] = React.useState("basic"); @@ -146,47 +149,12 @@ const ExperienceList: React.FC = ({ endedAt: "2024-05-23T07:45:23.720832019", bookmarked: "OFF", }, - { - id: "7694c6e7-b7a8-4ee8-a698-67c345932663", - title: "경험 제목 3", - parentTag: { - id: "c191d753-0c59-42eb-8245-79ee5c9c5797", - name: "상위 태그 이름", - }, - childTag: { - id: "860c446b-a021-43d5-9da6-5034a5bdaee7", - name: "하위 태그 이름", - }, - strongPoints: [ - { - id: "fdbf03bf-c1a3-4442-997e-467605868052", - name: "역량 키워드 이름 1", - }, - { - id: "096c3d2e-4073-4724-9a15-c1d6617c63a1", - name: "역량 키워드 이름 2", - }, - ], - contents: [ - { - question: "질문1", - answer: "답변1", - }, - { - question: "질문2", - answer: "답변2", - }, - ], - startedAt: "2023-05-22T07:45:23.720822702", - endedAt: "2024-05-23T07:45:23.720832019", - bookmarked: "ON", - }, ]); const jdId = useParams().jdId; useEffect(() => { if (jdId) { - // getExperienceList(jdId, user.token); + //getExperienceList(jdId, user.token); } }, []); @@ -239,43 +207,39 @@ const ExperienceList: React.FC = ({ //상위태그 하위태그 필터링 const handleTagSelection = ( - selectedmainTag: string, - selectedsubTag?: string + selectedmainTag: MyTagAPI, + selectedsubTag?: MyTagAPI ): void => { setSearchText(""); - setMainTag(selectedmainTag); + setMainTag({ id: selectedmainTag.id, name: selectedmainTag.name }); if (selectedsubTag) { - setSubTag(selectedsubTag); + setSubTag({ id: selectedsubTag.id, name: selectedsubTag.name }); setShowTagPopup(false); } else { - setSubTag(""); + setSubTag({ id: "", name: "" }); } }; useEffect(() => { - if (mainTag) { - console.log("maintag: " + mainTag); + if (mainTag.id !== "") { + console.log("maintag 아이디: " + mainTag.id); + console.log("maintag 이름: " + mainTag.name); if (jdId) { - getFilteredExperienceList(jdId, mainTag, null, user.token); + getFilteredExperienceList(jdId, mainTag.id, null, user.token); } } }, [mainTag]); useEffect(() => { - if (subTag) { - console.log("subtag: " + subTag); + if (subTag.id !== "") { + console.log("subtag 아이디: " + subTag.id); + console.log("subtag 이름: " + subTag.name); if (jdId) { - getFilteredExperienceList(jdId, mainTag, subTag, user.token); + getFilteredExperienceList(jdId, mainTag.id, subTag.id, user.token); } } }, [subTag]); - useEffect(() => { - if (searchText) { - console.log("search: " + searchText); - } - }, [searchText]); - //역량키워드 관련 팝업 const [myKeywordList, setMyKeywordList] = React.useState([]); const [anchorEl, setAnchorEl] = React.useState(null); @@ -349,9 +313,9 @@ const ExperienceList: React.FC = ({ ); const bookedData = experienceData.filter((experience) => { - // 북마크가 ON인 요소만 필터링 return experience.bookmarked === "ON"; }); + const filteredBookedData = bookedData.filter((experience) => experience.strongPoints.some((item: KeywordType) => isKeywordChecked(item)) ); @@ -377,7 +341,7 @@ const ExperienceList: React.FC = ({ - {mainTag ? ( + {mainTag.id !== "" ? ( ) : ( = ({ /> )} - {mainTag} - {subTag && Arrow} - {subTag && subTag} - {mainTag && ( + {mainTag.name} + {subTag.name && Arrow} + {subTag.name && subTag.name} + {mainTag.id && ( remove { - setMainTag(""); - setSubTag(""); + setMainTag({ id: "", name: "" }); + setSubTag({ id: "", name: "" }); }} /> )} filter { setShowTagPopup(!showTagPopup); - setMainTag(""); - setSubTag(""); + setMainTag({ id: "", name: "" }); + setSubTag({ id: "", name: "" }); }} /> = ({ export default ExperienceList; interface TagPopupProps { - onSelect: (mainTag: string, subTag?: string) => void; + onSelect: (mainTag: MyTagAPI, subTag?: MyTagAPI) => void; } interface ChildTag { @@ -630,7 +594,7 @@ const TagPopup: React.FC = ({ onSelect }) => { { toggleSubTags(tag.id); - onSelect(tag.name); + onSelect({ id: tag.id, name: tag.name }); }} > arrow @@ -640,7 +604,12 @@ const TagPopup: React.FC = ({ onSelect }) => { tag.childTags.map((child) => ( onSelect(tag.name, child.name)} + onClick={() => + onSelect( + { id: tag.id, name: tag.name }, + { id: child.id, name: child.name } + ) + } > arrow {child.name} diff --git a/src/components/common/TimePicker.tsx b/src/components/common/TimePicker.tsx index 7da1ba6..6e51cdc 100644 --- a/src/components/common/TimePicker.tsx +++ b/src/components/common/TimePicker.tsx @@ -39,7 +39,7 @@ const TimePicker: React.FC = ({ time, setTime }) => { onChange={handleDateChange} showTimeSelect showTimeSelectOnly - timeIntervals={15} + timeIntervals={30} timeCaption="Time" dateFormat="h:mm aa" /> diff --git a/src/pages/JDPlusPage.tsx b/src/pages/JDPlusPage.tsx index a6378d8..55b2d7f 100644 --- a/src/pages/JDPlusPage.tsx +++ b/src/pages/JDPlusPage.tsx @@ -284,6 +284,9 @@ const CancelButton = styled.button` justify-content: center; align-items: center; border-radius: 0.5rem; + font-size: 16px; + font-style: normal; + font-weight: 600; border: none; color:var(--white); background: var(--main-500, #D9D9D9); @@ -295,6 +298,9 @@ const SaveButton = styled.button` justify-content: center; align-items: center; border-radius: 0.5rem; + font-size: 16px; + font-style: normal; + font-weight: 600; border: none; margin-left: 1rem; color:var(--white); From c2d50bccc5a96448c2ccbd0070f7a1f252227dce Mon Sep 17 00:00:00 2001 From: Seunghyo Date: Thu, 23 May 2024 02:49:27 +0900 Subject: [PATCH 4/5] feat: bookmark api --- src/components/JD/ContentInput.tsx | 2 +- src/components/JD/Experience.tsx | 24 +++++++- src/components/JD/ExperienceList.tsx | 84 +++------------------------- src/pages/JDEditPage.tsx | 7 +++ 4 files changed, 37 insertions(+), 80 deletions(-) diff --git a/src/components/JD/ContentInput.tsx b/src/components/JD/ContentInput.tsx index 589d05c..b3168dc 100644 --- a/src/components/JD/ContentInput.tsx +++ b/src/components/JD/ContentInput.tsx @@ -49,7 +49,7 @@ const Content = styled.textarea` outline: none; resize: none; padding: 0.5rem; - font-size: 1rem; + font-size: 14px; font-size: 0.8125rem; font-style: normal; font-weight: 400; diff --git a/src/components/JD/Experience.tsx b/src/components/JD/Experience.tsx index bcd92b4..005169c 100644 --- a/src/components/JD/Experience.tsx +++ b/src/components/JD/Experience.tsx @@ -7,6 +7,9 @@ import bookmarkFillIcon from "../../assets/icons/icon_bookmark_fill.svg"; import bookmarkBlankIcon from "../../assets/icons/icon_bookmark_blank.svg"; import dayjs from "dayjs"; import { KeywordType, QuestionType } from "../../types/experience"; +import { bookmarkpatch } from "../../services/JD/bookmarkApi"; +import { getCookie } from "../../services/cookie"; +import { useParams } from "react-router-dom"; interface ExpProps { type?: "card" | "section"; @@ -42,7 +45,8 @@ const Experience: React.FC = ({ }) => { const [detailId, setDetailId] = useRecoilState(detailStore); const [localbookmark, setLocalbookmark] = useState(bookmark); - + const user = getCookie("user"); + const jdId = useParams().jdId; // 카드 타입, 섹션 타입 구분 const isSection = type === "section"; @@ -56,10 +60,26 @@ const Experience: React.FC = ({ } }; + const handleBookmarkPost = async ( + token: string, + jobId: string, + expId: string + ) => { + try { + const response = await bookmarkpatch(token, jobId, expId); + console.log(response); + } catch (error) { + console.error(error); + alert(JSON.stringify(error)); + } + }; + const handleBookmarkClick = (event: React.MouseEvent) => { event.stopPropagation(); + if (id && jdId) { + handleBookmarkPost(user.token, jdId, id.toString()); + } setLocalbookmark(!localbookmark); - //북마크 요청 api }; return ( = ({ const [keywordTabOption, setKeywordTabOption] = React.useState("basic"); const user = getCookie("user"); - const [experienceData, setExperienceData] = useState([ - { - id: "fa0a5813-c879-432d-b276-24364847534c", - title: "경험 제목1 ", - parentTag: { - id: "c191d753-0c59-42eb-8245-79ee5c9c5797", - name: "상위 태그 이름", - }, - childTag: { - id: "860c446b-a021-43d5-9da6-5034a5bdaee7", - name: "하위 태그 이름", - }, - strongPoints: [ - { - id: "fdbf03bf-c1a3-4442-997e-467605868052", - name: "역량 키워드 이름 1", - }, - { - id: "096c3d2e-4073-4724-9a15-c1d6617c63a1", - name: "역량 키워드 이름 2", - }, - ], - contents: [ - { - question: "질문1", - answer: "답변1", - }, - { - question: "질문2", - answer: "답변2", - }, - ], - startedAt: "2024-05-22T07:45:23.720822702", - endedAt: "2024-05-23T07:45:23.720832019", - bookmarked: "ON", - }, - { - id: "7694c6e7-b7a8-4ee8-a698-67c345932663", - title: "경험 제목 2", - parentTag: { - id: "c191d753-0c59-42eb-8245-79ee5c9c5797", - name: "상위 태그 이름", - }, - childTag: { - id: "860c446b-a021-43d5-9da6-5034a5bdaee7", - name: "하위 태그 이름", - }, - strongPoints: [ - { - id: "fdbf03bf-c1a3-4442-997e-467605868052", - name: "역량 키워드 이름 1", - }, - { - id: "096c3d2e-4073-4724-9a15-c1d6617c63a1", - name: "역량 키워드 이름 2", - }, - ], - contents: [ - { - question: "질문1", - answer: "답변1", - }, - { - question: "질문2", - answer: "답변2", - }, - ], - startedAt: "2023-05-22T07:45:23.720822702", - endedAt: "2024-05-23T07:45:23.720832019", - bookmarked: "OFF", - }, - ]); + const [experienceData, setExperienceData] = useState([]); const jdId = useParams().jdId; useEffect(() => { if (jdId) { - //getExperienceList(jdId, user.token); + getExperienceList(jdId, user.token); } }, []); @@ -163,6 +92,7 @@ const ExperienceList: React.FC = ({ try { const response = await getAllExperienceList(jdId, token); console.log(response); + setExperienceData(response.data.experiences); } catch (error) { console.error(error); alert(JSON.stringify(error)); @@ -591,7 +521,7 @@ const TagPopup: React.FC = ({ onSelect }) => { {tagList.map((tag) => (
- { toggleSubTags(tag.id); onSelect({ id: tag.id, name: tag.name }); @@ -599,7 +529,7 @@ const TagPopup: React.FC = ({ onSelect }) => { > arrow {tag.name} - + {visibleSubTag === tag.id && tag.childTags.map((child) => ( props.theme.colors.neutral200}; `; -const Tag = styled.div` +const TagWrapper = styled.div` cursor: pointer; display: flex; padding: 0.75rem 0.5rem; @@ -647,7 +577,7 @@ const Tag = styled.div` } `; -const SubTag = styled(Tag)` +const SubTag = styled(TagWrapper)` padding-left: 20px; `; diff --git a/src/pages/JDEditPage.tsx b/src/pages/JDEditPage.tsx index daae7e6..b997791 100644 --- a/src/pages/JDEditPage.tsx +++ b/src/pages/JDEditPage.tsx @@ -139,6 +139,7 @@ const JDEditPage: React.FC = () => { endedAt: response.data.endedAt, }; setJdData(jdApiData); + setSelectedTime(response.data.endedAt); console.log(jdData); } catch (error) { console.error(error); @@ -311,6 +312,9 @@ const CancelButton = styled.button` padding: 0.625rem 4rem; justify-content: center; align-items: center; + font-size: 16px; + font-style: normal; + font-weight: 600; border-radius: 0.5rem; border: none; color:var(--white); @@ -323,6 +327,9 @@ const SaveButton = styled.button` justify-content: center; align-items: center; border-radius: 0.5rem; + font-size: 16px; + font-style: normal; + font-weight: 600; border: none; margin-left: 1rem; color:var(--white); From 3ac91186902edaa997773fbf94b535fe3ae27d53 Mon Sep 17 00:00:00 2001 From: Seunghyo Date: Thu, 23 May 2024 03:26:39 +0900 Subject: [PATCH 5/5] feat: filter count --- src/components/JD/ExperienceList.tsx | 47 ++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/src/components/JD/ExperienceList.tsx b/src/components/JD/ExperienceList.tsx index 6e74223..a4ba6ca 100644 --- a/src/components/JD/ExperienceList.tsx +++ b/src/components/JD/ExperienceList.tsx @@ -22,6 +22,7 @@ import { getAllTags } from "../../services/JD/tagApi"; import { useParams } from "react-router-dom"; import { formatDateRange } from "../../pages/JDListPage"; import { KeywordType } from "../../types/experience"; +import { getKeywords } from "../../services/Experience/keywordApi"; type TabType = "basic" | "my"; @@ -80,6 +81,7 @@ const ExperienceList: React.FC = ({ const user = getCookie("user"); const [experienceData, setExperienceData] = useState([]); const jdId = useParams().jdId; + const [searching, setSearching] = useState(false); useEffect(() => { if (jdId) { @@ -105,10 +107,10 @@ const ExperienceList: React.FC = ({ token: string ) => { try { + setSearching(true); const response = await searchTextExperienceList(jdId, searchText, token); console.log(response); setExperienceData(response.data.experiences); - console.log(experienceData); } catch (error) { console.error(error); alert(JSON.stringify(error)); @@ -129,6 +131,7 @@ const ExperienceList: React.FC = ({ token ); console.log(response); + setExperienceData(response.data.experiences); } catch (error) { console.error(error); alert(JSON.stringify(error)); @@ -152,8 +155,6 @@ const ExperienceList: React.FC = ({ useEffect(() => { if (mainTag.id !== "") { - console.log("maintag 아이디: " + mainTag.id); - console.log("maintag 이름: " + mainTag.name); if (jdId) { getFilteredExperienceList(jdId, mainTag.id, null, user.token); } @@ -162,8 +163,6 @@ const ExperienceList: React.FC = ({ useEffect(() => { if (subTag.id !== "") { - console.log("subtag 아이디: " + subTag.id); - console.log("subtag 이름: " + subTag.name); if (jdId) { getFilteredExperienceList(jdId, mainTag.id, subTag.id, user.token); } @@ -187,7 +186,6 @@ const ExperienceList: React.FC = ({ firstBasicKeywordIndex, lastBasicKeywordIndex ); - // My 역량 키워드 페이지네이션 const [currentMyKeywordPage, setCurrentMyKeywordPage] = React.useState(1); const firstMyKeywordIndex = (currentMyKeywordPage - 1) * keywordsPerPage; @@ -198,9 +196,7 @@ const ExperienceList: React.FC = ({ ); // 체크된 역량 키워드 리스트 - const [checkedKeywords, setCheckedKeywords] = React.useState( - [] - ); + const [checkedKeywords, setCheckedKeywords] = useState([]); // 키워드 체크박스 체크 여부 const isKeywordChecked = (item: KeywordType) => { @@ -232,6 +228,39 @@ const ExperienceList: React.FC = ({ } }; + useEffect(() => { + if (selectedTab === "경험검색" && (searching || mainTag.id !== "")) { + if (checkedKeywords.length !== 0) { + setfilterCount(filteredExpData.length); + } else { + setfilterCount(experienceData.length); + } + } else if (selectedTab === "북마크" && (searching || mainTag.id !== "")) { + if (checkedKeywords.length !== 0) { + setfilterCount(filteredBookedData.length); + } else { + setfilterCount(bookedData.length); + } + } else if (searchText === "" && mainTag.id === "") { + setfilterCount(-1); + } + }, [searching, mainTag, subTag, selectedTab, experienceData]); + + useEffect(() => { + if (searchText === "") { + setSearching(false); + } + }, [searchText]); + + // My 역량 키워드 조회 + useEffect(() => { + if (user?.token) { + getKeywords(user?.token) + .then((res) => setMyKeywordList(res.data.strongPoints)) + .catch((err) => console.log(err)); + } + }, [user?.token]); + // 역량 키워드 클릭 함수 const handleTagPopper = (event: React.MouseEvent) => { setAnchorEl(anchorEl ? null : event.currentTarget);