diff --git a/public/image/result/fail.svg b/public/image/result/fail.svg new file mode 100644 index 0000000..a9c99b9 --- /dev/null +++ b/public/image/result/fail.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/image/result/pass.svg b/public/image/result/pass.svg new file mode 100644 index 0000000..5fc5d15 --- /dev/null +++ b/public/image/result/pass.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/apis/recruiting.ts b/src/apis/recruiting.ts index 32233b7..35f776d 100644 --- a/src/apis/recruiting.ts +++ b/src/apis/recruiting.ts @@ -6,3 +6,6 @@ export const getAllRecruitings = () => export const getRecruitingById = (id: Recruiting["id"]) => getRequest(`/recruitings/${id}`); + +export const getRecruitingResult = (id: Recruiting["id"]) => + getRequest<{ status: number }>(`/recruitings/${id}/result`); diff --git a/src/components/home/NotificationModal.tsx b/src/components/home/NotificationModal.tsx index 2e90f15..94fa074 100644 --- a/src/components/home/NotificationModal.tsx +++ b/src/components/home/NotificationModal.tsx @@ -1,5 +1,6 @@ import styled from "styled-components"; import { Link } from "react-router-dom"; +import MarkdownRenderer from "../../lib/MarkdownRenderer"; import { TAnnouncement } from "../../types/apiTypes"; type NotificationModalProps = { @@ -22,7 +23,12 @@ export default function NotificationModal({ {announcement.title} - {announcement.content} + + + 자세히보기 @@ -68,7 +74,7 @@ const ContentsWapper = styled.div` `; const ImageContainer = styled.div` width: 56px; - height: "56px"; + height: 56px; margin-bottom: 11px; `; const Title = styled.h1` @@ -80,15 +86,8 @@ const Title = styled.h1` `; const MainText = styled.p` width: 100%; + max-height: 100%; overflow-y: auto; - white-space: pre-wrap; - word-break: break-all; - margin-top: 18px; - font-size: 16px; - line-height: 170%; - letter-spacing: 0; - text-align: center; - color: #737373; /* code start: scrollbar css design */ &::-webkit-scrollbar { @@ -132,3 +131,29 @@ const DivideLine = styled.div` height: 30px; border-left: 1px solid #fff; `; + +const MarkdownStyledWrapper = styled.div` + font-size: 16px; + line-height: 170%; + letter-spacing: 0; + color: #737373; + p { + margin-top: 18px; + white-space: pre-wrap; + word-break: keep-all; + } + ul, + ol { + padding: 0; + } + li { + white-space: pre-wrap; + word-break: keep-all; + } + a { + text-decoration: underline; + &:hover { + color: #f0745f; + } + } +`; diff --git a/src/main.tsx b/src/main.tsx index 7cca3fc..3732679 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -14,6 +14,8 @@ import Sso from "./pages/Sso"; import Announcement from "./pages/Announcement"; import { dashboardLoader } from "./pages/Loader/DashboardLoader"; import { resumeLoader } from "./pages/Loader/ResumeLoader"; +import Result, { NoResult } from "./pages/Result"; +import { resultLoader } from "./pages/Loader/ResultLoader"; const queryClient = new QueryClient(); @@ -42,6 +44,12 @@ const router = createBrowserRouter([ loader: dashboardLoader(queryClient), errorElement:
리크루팅을 찾을 수 없습니다
, }, + { + path: "result", + element: , + loader: resultLoader(queryClient), + errorElement: , + }, ], }, { path: "announcement", element: }, diff --git a/src/pages/Announcement.tsx b/src/pages/Announcement.tsx index 5d7239d..680f36d 100644 --- a/src/pages/Announcement.tsx +++ b/src/pages/Announcement.tsx @@ -212,5 +212,13 @@ const MarkdownStyledWrapper = styled.div` font-weight: normal; line-height: 185%; color: #373737; + white-space: pre-wrap; + work-break: keep-all; + } + a { + text-decoration: underline; + &:hover { + color: #f0745f; + } } `; diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx index 7ba9a9f..67a40e3 100644 --- a/src/pages/Dashboard.tsx +++ b/src/pages/Dashboard.tsx @@ -49,7 +49,7 @@ export default function Dashboard() { StyledWrapper={InformationMarkdownStyledWrapper} /> - navigate("/announcement")}> + {/* navigate("/announcement")}> 공지 및 변경사항 안내
+
*/} + navigate("./result")}> + 지원 결과 확인하기 +
+ → + → +
({ + queryKey: ["recruiting", "result", id], + queryFn: () => getRecruitingResult(id), + staleTime: Infinity, +}); + +export const resultLoader = + (queryClient: QueryClient) => + async ({ params }: { params: Record }) => { + const resultQuery = recruitingResultQuery(Number(params.recruit_id)); + const cachedResult = queryClient.getQueryData<{ status: number }>( + resultQuery.queryKey, + ); + return { + result: + cachedResult !== undefined + ? cachedResult + : await queryClient.fetchQuery(resultQuery), + }; + }; + +export type ResultLoaderReturnType = LoaderReturnType; diff --git a/src/pages/Result.tsx b/src/pages/Result.tsx new file mode 100644 index 0000000..45992f1 --- /dev/null +++ b/src/pages/Result.tsx @@ -0,0 +1,158 @@ +import { useLoaderData, useNavigate } from "react-router-dom"; +import styled from "styled-components"; +import Header from "../components/home/Header/Header"; +import { ResultLoaderReturnType } from "./Loader/ResultLoader"; +import { useEffect } from "react"; + +export default function Result() { + const { result } = useLoaderData() as ResultLoaderReturnType; + if (result.status === 3) { + //불합격 시 + return ( + <> +
+
+ + + + + 합격자 명단에 없습니다. + + 와플스튜디오 리크루팅에 참여해 주셔서 감사드립니다. +
+ 지원서를 검토한 결과, 아쉽게도 21.5기 루키 합격자 명단에 포함되지 + 않았음을 알려드립니다. +
+ 지원해 주신 노력에 진심으로 감사드리며, 미래에 더 나은 기회가 + 있기를 바라며 응원하겠습니다. 감사합니다. +
+ + 기타 문의사항은{" "} + + mailto:recruit@wafflestudio.com + {" "} + 이메일로 문의주세요. + {" "} +
+
+ + ); + } + + if (result.status === 2) { + //합격 시 + return ( + <> +
+
+ + + + + + 와플스튜디오 <Emphasis>합격</Emphasis>을 축하드립니다! + + + 지원 시 적어주셨던 이메일로 슬랙 및 노션 초대 예정입니다.
+ 또한 8월 20일 (일요일) 오후 2시에 루키 오리엔테이션이 진행될 + 예정이니 참고 바랍니다. 오티 참석은 필수입니다. +
+ + 기타 문의사항은{" "} + + mailto:recruit@wafflestudio.com + {" "} + 이메일로 문의주세요. + +
+
+ + ); + } + + //결과가 없을 시 + return ( + <> +
+
+ + + + + 아직 합/불 결과가 나오지 않았습니다. + + 기타 문의사항은{" "} + + mailto:recruit@wafflestudio.com + {" "} + 이메일로 문의주세요. + + +
+ + ); +} + +export function NoResult() { + const navigate = useNavigate(); + useEffect(() => { + alert("지원하지 않은 리크루팅입니다."); + navigate("../"); + }, []); + return
; +} +const Main = styled.main` + width: 100%; + min-height: 100vh; + display: flex; + align-items: center; + justify-content: center; +`; + +const Container = styled.div` + display: flex; + flex-direction: column; + align-items: center; + width: 1100px; + padding: 60px 0; +`; + +const LogoWrapper = styled.div` + margin-bottom: 48px; +`; + +const Title = styled.div` + color: #222; + font-size: 52px; + font-weight: 700; + margin-bottom: 36px; +`; +const Emphasis = styled.span` + color: #f0745f; + font-size: 64px; + font-weight: 700; +`; +const Description = styled.div` + color: #484848; + text-align: center; + font-size: 24px; + font-weight: 500; + line-height: 150%; + margin-bottom: 36px; + word-break: keep-all; +`; +const Contact = styled.div` + color: #484848; + font-family: Pretendard; + font-size: 16px; + font-weight: 400; + text-align: center; + a { + color: #484848; + font-family: Pretendard; + font-size: 16px; + font-weight: 500; + text-decoration-line: underline; + cursor: pointer; + } +`;