Skip to content

Commit

Permalink
Merge pull request #108 from KUSITMS-29th-TEAM-B/feat/#101
Browse files Browse the repository at this point in the history
Feat/#101 JD 공고 리스트 api get, JD 공고 상세 api get 연동
  • Loading branch information
hyo-4 authored May 19, 2024
2 parents 820c6fc + b236267 commit 4d3d379
Show file tree
Hide file tree
Showing 7 changed files with 352 additions and 258 deletions.
4 changes: 2 additions & 2 deletions src/components/JD/Announcement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ const JobAnnouncementCard: React.FC<JobAnnouncementProps> = ({
<Container onClick={() => nav(`/jd/detail/${id}`)}>
<TopContainer>
<StatusContainer>
{status !== "마감" && <DdayContainer>{"D-" + dday}</DdayContainer>}
{status !== "작성전" && <StateBox status={status} />}
{status !== "CLOSED" && <DdayContainer>{"D-" + dday}</DdayContainer>}
{status !== "NOT_APPLIED" && <StateBox status={status} />}
</StatusContainer>
<DateContainer>24.01.19</DateContainer>
</TopContainer>
Expand Down
30 changes: 19 additions & 11 deletions src/components/JD/StateBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,21 @@ interface StateBoxProps {
}

const StateBox: React.FC<StateBoxProps> = ({ status, className }) => {
const getStatusLabel = (status: string | undefined) => {
switch (status) {
case "WRITING":
return "작성중";
case "WRITTEN":
return "작성완료";
case "CLOSED":
return "마감";
default:
return "";
}
};
return (
<StyledStateBox className={className} status={status}>
{status}
{getStatusLabel(status)}
</StyledStateBox>
);
};
Expand All @@ -20,27 +32,23 @@ const StyledStateBox = styled.div<{ status?: string }>`
font-size: 0.8rem;
background-color: ${(props) => {
switch (props.status) {
case "작성중":
case "WRITING":
return "#E5E6FF";
case "지원완료":
return "#E5E6FF";
case "작성완료":
case "WRITTEN":
return "#FFF5D1";
case "마감":
case "CLOSED":
return "#EEEFF7";
default:
return "transparent";
}
}};
color: ${(props) => {
switch (props.status) {
case "작성중":
return "#5C70DB";
case "지원완료":
case "WRITING":
return "#5C70DB";
case "작성완료":
case "WRITTEN":
return "#FFA63E";
case "마감":
case "CLOSED":
return "#63698D";
default:
return "transparent";
Expand Down
260 changes: 133 additions & 127 deletions src/pages/JDDetailPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { motion, AnimatePresence } from "framer-motion";
import AirplaneToggle from "../components/JD/AirplaneToggle";
import ExperienceList from "../components/JD/ExperienceList";
import { useNavigate, useParams } from "react-router-dom";
import { RecruitmentStatus } from "../types/type";
import { JobDescriptionAPI } from "../types/type";
import arrowIcon from "../assets/icons/icon_arrow_right.svg";
import StateBox from "../components/JD/StateBox";
import { useRecoilState } from "recoil";
Expand All @@ -13,66 +13,31 @@ import { detailStore } from "../store/jdStore";
import calendarIcon from "../assets/icons/icon_calendar.svg";
import linkIcon from "../assets/icons/icon_link.svg";
import ExperienceBox from "../components/JD/ExpContainer";

const jdData = {
id: 3,
title: "백엔드 개발자 채용",
description: "Node.js 경험자",
recruitmentPeriod: "2024-05-10 ~ 2024-06-10",
status: RecruitmentStatus.InProgress,
dday: 30,
link: "https://www.naver.com/",
date: "2013.01.10",
content: `<div>
<h2>Job Description</h2>
<p>
We are looking for a talented frontend developer to join our team. The
ideal candidate should have experience with HTML, CSS, JavaScript, and
modern frontend frameworks such as React.
</p>
<br/>
<h1>Job Description</h1>
<p>
We are looking for a talented frontend developer to join our team. The
ideal candidate should have experience with HTML, CSS, JavaScript, and
modern frontend frameworks such as React.
</p>
<h2>Job Description</h2>
<p>
We are looking for a talented frontend developer to join our team. The
ideal candidate should have experience with HTML, CSS, JavaScript, and
modern frontend frameworks such as React.
</p>
<br/>
<h1>Job Description</h1>
<p>
We are looking for a talented frontend developer to join our team. The
ideal candidate should have experience with HTML, CSS, JavaScript, and
modern frontend frameworks such as React.
</p>
<h2>Job Description</h2>
<p>
We are looking for a talented frontend developer to join our team. The
ideal candidate should have experience with HTML, CSS, JavaScript, and
modern frontend frameworks such as React.
</p>
<br/>
<h1>Job Description</h1>
<p>
We are looking for a talented frontend developer to join our team. The
ideal candidate should have experience with HTML, CSS, JavaScript, and
modern frontend frameworks such as React.
</p>
</div>`,
};
import { formatDateRange } from "./JDListPage";
import { jobdescriptionget } from "../services/jd";
import { getCookie } from "../services/cookie";
import PlaneLoading from "../components/common/Loading";

const JDDetailPage: React.FC = () => {
const [active, setActive] = useState(false);
const [activebutton, setActivebutton] = useState("");
const firstTime = jdData.status === "작성전"; // 자기소개서 작성한 이력 여부
const jdId = useParams().id;
const nav = useNavigate();
const [detailId, setDetailId] = useRecoilState<number>(detailStore);
const [jdData, setJdData] = useState<JobDescriptionAPI>({
enterpriseName: "",
title: "",
remainingDate: "",
content: "",
link: "",
writeStatus: "",
createdAt: null,
startAt: null,
endedAt: null,
});
const firstTime = jdData.writeStatus === "NOT_APPLIED"; // 자기소개서 작성한 이력 여부
const user = getCookie("user");
const [isLoading, setIsLoading] = useState(true);

const ExptoggleContainer = () => {
if (!active) {
Expand All @@ -89,6 +54,9 @@ const JDDetailPage: React.FC = () => {
top: 0,
behavior: "auto",
});
if (jdId) {
getJobData(jdId, user.token);
}
}, []);

useEffect(() => {
Expand All @@ -97,50 +65,78 @@ const JDDetailPage: React.FC = () => {
}
}, [active]);

const getJobData = async (jdId: string, token: string) => {
try {
const response = await jobdescriptionget(jdId, token);
const jdApiData: JobDescriptionAPI = {
enterpriseName: response.data.enterpriseName,
title: response.data.title,
remainingDate: response.data.remainingDate,
content: response.data.link,
writeStatus: response.data.writeStatus,
link: response.data.link,
createdAt: response.data.createdAt,
startAt: response.data.startedAt,
endedAt: response.data.endedAt,
};
setJdData(jdApiData);
console.log(jdData);
} catch (error) {
console.error(error);
alert(JSON.stringify(error));
}
setIsLoading(false);
};

return (
<StyledDivContainer className="page">
<MainContainer>
<CenteredContainer
initial={{ width: "100%" }}
animate={{
x: active ? "7%" : "25%",
width: active ? "50%" : "100%",
}}
transition={{
type: "spring",
stiffness: 40,
when: "beforeChildren",
}}
>
<ToggleContainer>
<AirplaneToggle step={2} />
</ToggleContainer>
<TopTitleBar>
<Title>
<img src={arrowLeft} alt="arrowicon" onClick={() => nav(-1)} />
공고 상세
</Title>
<TopButton onClick={() => nav(`/jd/edit/${jdId}`)}>
<TopButtonText>
{firstTime ? "자기소개서 작성" : "자기소개서 확인"}
<img src={arrowIcon} alt="icon" />
</TopButtonText>
</TopButton>
</TopTitleBar>
<JobContainer>
<div className="job_box">
{!isLoading ? (
<MainContainer>
<CenteredContainer
initial={{ width: "100%" }}
animate={{
x: active ? "7%" : "25%",
width: active ? "50%" : "100%",
}}
transition={{
type: "spring",
stiffness: 40,
when: "beforeChildren",
}}
>
<ToggleContainer>
<AirplaneToggle step={2} />
</ToggleContainer>
<TopTitleBar>
<Title>
<img src={arrowLeft} alt="arrowicon" onClick={() => nav(-1)} />
공고 상세
</Title>
<TopButton onClick={() => nav(`/jd/edit/${jdId}`)}>
<TopButtonText>
{firstTime ? "자기소개서 작성" : "자기소개서 확인"}
<img src={arrowIcon} alt="icon" />
</TopButtonText>
</TopButton>
</TopTitleBar>
<JobContainer>
<JobStatusBar>
{jdData.status !== "작성전" && (
<StateBox className="job_status" status={jdData.status} />
{jdData.writeStatus !== "NOT_APPLIED" && (
<StateBox
className="job_status"
status={jdData.writeStatus}
/>
)}
<div className="job_date">{jdData.date}</div>
<div className="job_date">{jdData.createdAt?.toString()}</div>
</JobStatusBar>
<JobTopBox>
<JobTopTitleBox>
<div className="job_detail_dday">{"D-" + jdData.dday}</div>
<div className="job_detail_dday">
{"D-" + jdData.remainingDate}
</div>
<div className="job_detail_title">{jdData.title}</div>
</JobTopTitleBox>
<JobTopDescription>{jdData.description}</JobTopDescription>
<JobTopDescription>{jdData.enterpriseName}</JobTopDescription>
<JobSubBox>
<div className="period">
<img
Expand All @@ -149,7 +145,12 @@ const JDDetailPage: React.FC = () => {
width={16}
height={16}
/>
{jdData.recruitmentPeriod}
{jdData.startAt &&
jdData.endedAt &&
formatDateRange(
jdData.startAt.toString(),
jdData.endedAt.toString()
)}
</div>
<div className="link">
<img src={linkIcon} alt="link" width={16} height={16} />
Expand All @@ -169,44 +170,48 @@ const JDDetailPage: React.FC = () => {
<div dangerouslySetInnerHTML={{ __html: jdData.content }} />
</JobBottomBox>
</ScrollDiv>
</div>
</JobContainer>
</CenteredContainer>
<AnimatePresence>
<ActiveContainer
isActive={detailId !== 0}
initial={{ x: "100%", width: "45%" }}
animate={{
x: !active ? "110%" : "5%",
width: "45%",
}}
exit={{
x: "0%",
transition: { stiffness: 50, damping: 20 },
}}
transition={{
type: "spring",
stiffness: 40,
}}
>
<ExperienceButton
onClick={ExptoggleContainer}
active={activebutton === "Exp"}
</JobContainer>
</CenteredContainer>
<AnimatePresence>
<ActiveContainer
isActive={detailId !== 0}
initial={{ x: "100%", width: "45%" }}
animate={{
x: !active ? "110%" : "5%",
width: "45%",
}}
exit={{
x: "0%",
transition: { stiffness: 50, damping: 20 },
}}
transition={{
type: "spring",
stiffness: 40,
}}
>
<ButtonText active={activebutton === "Exp"}>경험연결</ButtonText>
</ExperienceButton>
{detailId !== 0 ? (
<ExperienceBox expId={detailId} />
) : (
<ScrollDiv>
<ExpContainer>
<ExperienceList showBookmarksOnly={false} />
</ExpContainer>
</ScrollDiv>
)}
</ActiveContainer>
</AnimatePresence>
</MainContainer>
<ExperienceButton
onClick={ExptoggleContainer}
active={activebutton === "Exp"}
>
<ButtonText active={activebutton === "Exp"}>
경험연결
</ButtonText>
</ExperienceButton>
{detailId !== 0 ? (
<ExperienceBox expId={detailId} />
) : (
<ScrollDiv>
<ExpContainer>
<ExperienceList showBookmarksOnly={false} />
</ExpContainer>
</ScrollDiv>
)}
</ActiveContainer>
</AnimatePresence>
</MainContainer>
) : (
<PlaneLoading />
)}
</StyledDivContainer>
);
};
Expand Down Expand Up @@ -303,6 +308,7 @@ const JobContainer = styled.div`

const ScrollDiv = styled.div`
overflow-y: auto;
width: 100%;
&::-webkit-scrollbar {
width: 4px;
}
Expand Down
Loading

0 comments on commit 4d3d379

Please sign in to comment.