Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

πŸ”€ Feat/NewApplicationUI#271[μ§€μ›μ„œμ™€ 포폴 νŽ˜μ΄μ§€ κ΅¬ν˜„] #274

Merged
merged 7 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
419 changes: 419 additions & 0 deletions gongjakso/package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions gongjakso/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
"date-fns": "^3.3.1",
"eslint-plugin-jsx-a11y": "^6.8.0",
"framer-motion": "^11.0.20",
"html2canvas": "^1.4.1",
"html2pdf.js": "^0.9.3",
"http-proxy-middleware": "^2.0.6",
"jspdf": "^2.5.2",
"moment": "^2.30.1",
"node-sass": "^9.0.0",
"react": "^18.2.0",
Expand Down
4 changes: 4 additions & 0 deletions gongjakso/src/assets/images/applicationLogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions gongjakso/src/assets/images/bottomImg.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
258 changes: 258 additions & 0 deletions gongjakso/src/pages/ProfileRecruit/PdfUserApplication.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
import React, { useEffect, useRef, useState } from 'react';
import * as S from './PdfUserApplicationStyled';
import * as T from '../../features/modal/ApplyModal.styled';
import * as U from '../Portfolio/Portfolio.Styled';
import { useParams } from 'react-router-dom';
import Logo from '../../assets/images/applicationLogo.svg';
import { getMyApplication } from '../../service/apply_service';
import { getPortfolio } from '../../service/portfolio_service';
import bottomLogo from '../../assets/images/bottomImg.svg';
import html2pdf from 'html2pdf.js';

const PdfUserApplication = () => {
const { id } = useParams();

const [myApp, setmyApp] = useState([]);
const [portId, setPortId] = useState();
const [portfolio, setPortfolio] = useState([]);

useEffect(() => {
// [GET] νŠΉμ • μ§€μ›μž μ§€μ›μ„œ 쑰회 API
getMyApplication(id).then(res => {
setmyApp(res?.data);
setPortId(res?.data.portfolio_id);
});
}, [id]);

useEffect(() => {
if (portId) {
// [GET] 포트폴리였 상세 쑰회 API
getPortfolio(portId).then(res => {
setPortfolio(res?.data);
});
}
}, [portId]);

const downloadPDF = () => {
const element = document.getElementById('pdf-download'); // PDF둜 λ³€ν™˜ν•  μš”μ†Œ 선택
html2pdf(element, {
filename: `${myApp?.applicant_name}.pdf`, // default : file.pdf
html2canvas: { scale: 5 }, // μΊ‘μ²˜ν•œ μ΄λ―Έμ§€μ˜ 크기λ₯Ό 쑰절, 값이 클수둝 더 μ„ λͺ…ν•˜λ‹€.
jsPDF: {
format: 'A2', // 쒅이 크기 ν˜•μ‹
orientation: 'portrait', // or landscape : κ°€λ‘œ
},
// callback: () => {
// console.log('PDF λ‹€μš΄λ‘œλ“œ μ™„λ£Œ');
// },
});
};

return (
<>
<section id="pdf-download">
<S.TopBox>
<img src={Logo} alt="title-logo" />
<S.Title>{myApp?.applicant_name} λ‹˜μ˜ 포트폴리였</S.Title>
<S.Major>{myApp?.applicant_major}</S.Major>
<S.Major>{myApp?.applicant_phone}</S.Major>
</S.TopBox>

<S.GlobalBox>
<S.DetailBox>
<S.SubTitle>지원뢄야</S.SubTitle>
<div>
{myApp?.recruit_part?.map((item, i) => (
<T.RoundForm
key={i}
$isselected={
item.position === myApp?.apply_part
}
style={{ cursor: 'default' }}
>
{item.position}
</T.RoundForm>
))}
</div>
</S.DetailBox>
<S.DetailBox>
<S.SubTitle>μ§€μ›μ΄μœ </S.SubTitle>
<S.ContentBox>{myApp?.body}</S.ContentBox>
</S.DetailBox>

{!myApp?.is_private && (
<div>
<S.DetailBox>
<S.SubTitle>ν•™λ ₯</S.SubTitle>
{portfolio?.data?.educationList?.map(
(education, index) => (
<S.BoxDetail key={index}>
<S.InputContainer>
<S.PortBox $w="50%">
{education.school ||
'학ꡐ 정보 μ—†μŒ'}
</S.PortBox>
<S.PortBox $w="24rem">
{education.grade ||
'ν•™λ…„ 정보 μ—†μŒ'}
</S.PortBox>
<S.PortBox $w="24rem">
{education.state ||
'μƒνƒœ 정보 μ—†μŒ'}
</S.PortBox>
</S.InputContainer>
</S.BoxDetail>
),
)}
</S.DetailBox>

<S.DetailBox>
<S.SubTitle>κ²½λ ₯사항</S.SubTitle>
{portfolio?.data?.workList?.map(
(work, index) => (
<S.BoxDetail key={index}>
<S.InputContainer>
<S.PortBox $w="58%">
(νšŒμ‚¬λͺ…){' '}
{work.company ||
'정보 μ—†μŒ'}
</S.PortBox>
<S.PortBox $w="40%">
(λΆ€μ„œλͺ…/직책){' '}
{work.partition || ''}
</S.PortBox>
</S.InputContainer>

<S.InputContainer>
<S.FlexPortBox $w="32%">
<span>μž…μ‚¬μΌ</span>
<span>
{work.enteredAt ||
'정보 μ—†μŒ'}
</span>
</S.FlexPortBox>
<S.FlexPortBox $w="32%">
<span>퇴사일</span>
<span>
{work.exitedAt ||
'λ―Έμ •'}
</span>
</S.FlexPortBox>
<S.PortBox $w="32%">
{work.isActive
? '재직 쀑'
: '퇴사'}
</S.PortBox>
</S.InputContainer>

<S.InputContainer>
<S.WorkContent>
{work.detail || 'μ—†μŒ'}
</S.WorkContent>
</S.InputContainer>
</S.BoxDetail>
),
)}
</S.DetailBox>

<S.DetailBox>
<S.SubTitle>λŒ€μ™Έν™œλ™</S.SubTitle>
{portfolio?.data?.activityList?.map(
(activity, index) => (
<S.BoxDetail key={index}>
<S.InputContainer>
<S.PortBox $w="70%">
{activity.name ||
'λŒ€μ™Έν™œλ™ μ—†μŒ'}
</S.PortBox>
<S.PortBox $w="22rem">
{activity.isActive
? 'ν™œλ™μ€‘'
: 'ν™œλ™ μ’…λ£Œ' ||
'μƒνƒœ 정보 μ—†μŒ'}
</S.PortBox>
</S.InputContainer>
</S.BoxDetail>
),
)}
</S.DetailBox>

<S.DetailBox>
<S.SubTitle>μˆ˜μƒκ²½λ ₯</S.SubTitle>
{portfolio?.data?.awardList?.map(
(award, index) => (
<S.BoxDetail key={index}>
<S.InputContainer>
<S.PortBox $w="50%">
{award.contestName ||
'μˆ˜μƒκ²½λ ₯ μ—†μŒ'}
</S.PortBox>
<S.PortBox $w="24rem">
{award.awardName ||
'μƒνƒœ 정보 μ—†μŒ'}
</S.PortBox>
<S.PortBox $w="24rem">
{award.awardDate ||
'μƒνƒœ 정보 μ—†μŒ'}
</S.PortBox>
</S.InputContainer>
</S.BoxDetail>
),
)}
</S.DetailBox>

<S.DetailBox>
<S.SubTitle>자격증</S.SubTitle>
{portfolio?.data?.certificateList?.map(
(certificate, index) => (
<S.BoxDetail key={index}>
<S.InputContainer>
<S.PortBox $w="50%">
{certificate.name ||
'자격 정보 μ—†μŒ'}
</S.PortBox>
<S.PortBox $w="24rem">
{certificate.rating ||
'μƒνƒœ 정보 μ—†μŒ'}
</S.PortBox>
<S.PortBox $w="24rem">
{certificate.certificationDate ||
'μƒνƒœ 정보 μ—†μŒ'}
</S.PortBox>
</S.InputContainer>
</S.BoxDetail>
),
)}
</S.DetailBox>

<S.DetailBox>
<S.SubTitle>SNS</S.SubTitle>
{portfolio?.data?.snsList?.map((sns, index) => (
<S.BoxDetail key={index}>
<S.InputContainer>
<S.PortBox $w="90%">
{sns.snsLink || 'SNS 링크 μ—†μŒ'}
</S.PortBox>
</S.InputContainer>
</S.BoxDetail>
))}
</S.DetailBox>
</div>
)}
</S.GlobalBox>
<S.BottomBox>
<img
src={bottomLogo}
alt="footer logo"
style={{ width: '170px', height: 'auto' }}
></img>
</S.BottomBox>
</section>
<S.PdfButton variant="outlined" onClick={downloadPDF}>
pdfλ‹€μš΄
</S.PdfButton>
</>
);
};

export default PdfUserApplication;
119 changes: 119 additions & 0 deletions gongjakso/src/pages/ProfileRecruit/PdfUserApplicationStyled.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import styled from 'styled-components';

export const TopBox = styled.div`
height: 21rem;
width: 100%;
background-color: rgba(195, 233, 255, 0.5);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative; /* μƒλŒ€μ  μœ„μΉ˜λ₯Ό μœ„ν•œ μ„€μ • */

img {
width: 72px;
margin-bottom: 2rem;
}
`;

export const Title = styled.p`
font-size: ${({ theme }) => theme.fontSize.xl};
text-align: center;
font-weight: bold;
margin-bottom: 1rem;
`;

export const Major = styled.p`
margin: 0.2rem;
font-size: ${({ theme }) => theme.fontSize.md};
font-family: 'PreMedium';
`;

export const GlobalBox = styled.div`
width: 100%;
display: flex;
flex-direction: column;
padding: 3rem 20rem;
`;

export const SubTitle = styled.p`
font-size: 1.6rem;
font-family: 'PreBold';
`;

export const DetailBox = styled.div`
padding: 1.5rem;
`;

export const ContentBox = styled.div`
margin-top: 1.5rem;
padding: 1.5rem;
width: 100%;
height: 22rem;
border: 1.5px solid ${({ theme }) => theme.Grey};
border-radius: 9px;
font-size: ${({ theme }) => theme.fontSize.m};
`;

export const BoxDetail = styled.div`
display: flex;
flex-direction: column;
width: 100%;
margin-top: -0.5rem;
margin-bottom: 1.5rem;
`;

export const InputContainer = styled.div`
display: flex;
justify-content: space-between;
flex-direction: row;
width: 100%;
`;

export const PortBox = styled.div`
width: ${props => props.$w};
height: 3.438rem;
margin-top: 1.5rem;
margin-right: 0.5rem;
border: 1.5px solid ${({ theme }) => theme.Grey};
padding: 0.983rem 1.125rem;
font-size: ${({ theme }) => theme.fontSize.m};
border-radius: 9px;
color: #828293;
display: flex;
align-items: center;
`;

export const FlexPortBox = styled(PortBox)`
display: flex;
justify-content: space-between;
`;

export const WorkContent = styled.div`
width: 100%;
display: inline-block;
padding: 0.983rem 1.125rem;
margin-top: 1.5rem;
font-size: ${({ theme }) => theme.fontSize.m};
border: 1.5px solid ${({ theme }) => theme.Grey};
border-radius: 9px;
color: #828293;
`;

export const BottomBox = styled.div`
width: 100%;
display: flex;
justify-content: center;
align-items: center;
margin: 1rem 0 2rem 0;
`;

export const PdfButton = styled.button`
width: 100px;
height: 50px;
border-radius: 15px;
background-color: ${({ theme }) => theme.Main2};
position: absolute; /* μ ˆλŒ€ μœ„μΉ˜ μ„€μ • */
top: 100px; /* 상단 μ—¬λ°± */
right: 100px; /* 였λ₯Έμͺ½ μ—¬λ°± */
`;
Loading