Skip to content
New issue

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

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

Already on GitHub? # to your account

fix: 프로필 편집 페이지, 포트폴리오 작성/편집 페이지, 회원가입 완료 페이지 2차 QA 피드백 배포 브랜치에 적용 #166

Merged
merged 9 commits into from
May 7, 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
2 changes: 2 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ import RefuseModal from './recruit/applicants/modal/RefuseModal';
import ApproveModal from './recruit/applicants/modal/ApproveModal';
import TabMenu from './tabMenu/TabMenu';
import PostingDelete from './recruit/recruitDetail/modal/postingDelete/PostingDelete';
import Modal from './modal/Modal';

export {
Header,
Expand Down Expand Up @@ -289,4 +290,5 @@ export {
ApproveModal,
TabMenu,
PostingDelete,
Modal,
};
60 changes: 60 additions & 0 deletions src/components/modal/Modal.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import styled from 'styled-components';

const ModalLayout = styled.div`
position: fixed;
left: 0;
top: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background: rgba(21, 21, 21, 0.4);
`;

const ModalContainer = styled.div`
display: flex;
flex-direction: column;
align-items: center;
padding: 1.8rem 2rem;
border-radius: 1rem;
border: 0.1rem solid var(--box_stroke, #e3e3e3);
background: var(--Grayscale-100, #f8fafb);
`;

const ModalTitle = styled.h3`
display: flex;
margin-bottom: 2.8rem;
color: var(--text-color, #151515);

/* Headline/h3 */
font-size: 2rem;
font-weight: 600;
line-height: 2.4rem; /* 120% */
letter-spacing: 0.004rem;
`;

const ModalContent = styled.pre`
display: flex;
margin-bottom: 3.4rem;
text-align: center;
white-space: pre-wrap; // 줄바꿈

/* Body/body2/medium */
font-size: 1.4rem;
font-weight: 500;
line-height: 2.4rem;
letter-spacing: 0.0028rem;
`;

const ModalRow = styled.div<{ $gap?: string }>`
flex: 1;
display: flex;
flex-direction: row;
column-gap: ${props => props.$gap};
align-items: center;
`;

const S = { ModalLayout, ModalContainer, ModalTitle, ModalContent, ModalRow };

export default S;
44 changes: 44 additions & 0 deletions src/components/modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react';
import S from './Modal.styled';
import { DefaultBtn, PrimaryBtn } from '../index';

interface Modal {
title: string;
content: string;
defaultBtn: Button;
primaryBtn: Button;
}

interface Button {
title: string;
handleClick: () => void;
}

const Modal = ({ title, content, defaultBtn, primaryBtn }: Modal) => {
return (
<S.ModalLayout>
<S.ModalContainer>
<S.ModalTitle>{title}</S.ModalTitle>
<S.ModalContent>{content}</S.ModalContent>
<S.ModalRow $gap='1.6rem'>
<div>
<DefaultBtn
title={defaultBtn.title}
type='button'
handleClick={defaultBtn.handleClick}
/>
</div>
<div>
<PrimaryBtn
title={primaryBtn.title}
type='button'
handleClick={primaryBtn.handleClick}
/>
</div>
</S.ModalRow>
</S.ModalContainer>
</S.ModalLayout>
);
};

export default Modal;
2 changes: 1 addition & 1 deletion src/components/radio/Radio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const Radio = ({ register, name, id, validation, state, handleClick, children }:
type='radio'
name={name}
id={id}
defaultChecked={state}
checked={state}
value={id}
onClick={() => handleClick?.(id)}
/>
Expand Down
2 changes: 1 addition & 1 deletion src/constant/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const INPUT_VALIDATION = {
required: '분야를 선택해주세요',
},
role: {
required: '역할를 선택해주세요',
required: '역할을 선택해주세요',
},
startDate: {
required: '시작일을 설정해주세요',
Expand Down
35 changes: 32 additions & 3 deletions src/pages/account/complete/Complete#Page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,35 @@
import React from 'react';
import React, { useState, useEffect } from 'react';
import S from './Complete#Page.styled';
import { PrimaryBtn } from '../../../components';
import { Modal, ModalPortal, PrimaryBtn } from '../../../components';
import { Congratulation } from '../../../assets';
import { useNavigate } from 'react-router-dom';
import { fixModalBackground } from '../../../utils';
import { useRecoilValue } from 'recoil';
import { userState } from '../../../atom';

const Complete#Page = () => {
const navigate = useNavigate();
const user = useRecoilValue(userState);

const [modalOpen, setModalOpen] = useState(false);

useEffect(() => {
fixModalBackground(modalOpen);
}, [modalOpen]);

const modalProps = {
title: '프로필을 추가해보세요!',
content:
'프로필 입력정보를 추가하면\n팀을 만날 확률이 늘어납니다.\n내 프로필로 이동하시겠습니끼?',
defaultBtn: {
title: '나중에 하기',
handleClick: () => navigate('/'),
},
primaryBtn: {
title: '프로필로 이동',
handleClick: () => navigate(`/profile/${user?.userId}`),
},
};

return (
<S.Complete#Layout>
Expand All @@ -14,7 +38,12 @@ const Complete#Page = () => {
</header>
<img src={Congratulation} alt='회원가입을 축하합니다!' />
<div>
<PrimaryBtn title='확인' type='button' handleClick={() => navigate('/')} />
<PrimaryBtn title='확인' type='button' handleClick={() => setModalOpen(true)} />
{modalOpen && (
<ModalPortal>
<Modal {...modalProps} />
</ModalPortal>
)}
</div>
</S.Complete#Layout>
);
Expand Down
28 changes: 17 additions & 11 deletions src/pages/portfolio/edit/PortfolioEditPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,22 @@ const PortfolioEditPage = () => {
const [skillList, setSkillList] = useState(portfolio?.skills ? portfolio?.skills : []);

const addSkill = () => {
if (skillList.length === 10) {
alert('스킬은 최대 10개까지 입력할 수 있습니다.'); // 디자인 요청
setValue('skills', '');
return;
}
const newSkill = {
id: skills?.find(skill => skill.name === getValues('skills'))?.id,
name: getValues('skills'),
} as Skill;
if (getValues('skills')?.length === 0) return;
if (!skillList.find(skill => newSkill.name === skill.name)) {
setSkillList(prev => [...prev, newSkill]);
if (skillList.find(skill => newSkill.name === skill.name)) {
alert('이미 추가한 스킬입니다.'); // 디자인 요청
setValue('skills', '');
return;
}
setSkillList(prev => [...prev, newSkill]);
setValue('skills', '');
};

Expand All @@ -216,10 +224,12 @@ const PortfolioEditPage = () => {
control: control,
});

const addLink = (index: number) => {
if (index === -1 || getValues(`links.0.url`)) {
prependLink({ description: 'Link', url: '' });
const addLink = () => {
if (links.length === 10) {
alert('링크는 최대 10개까지 입력할 수 있습니다.'); // 디자인 요청
return;
}
prependLink({ description: 'Link', url: '' });
};

// 상세 내용
Expand Down Expand Up @@ -416,7 +426,7 @@ const PortfolioEditPage = () => {
<S.PortfolioEditArticle>
<S.PortfolioEditTitle>링크</S.PortfolioEditTitle>
<S.PortfolioEditColumn $width='clamp(50%, 76.4rem, 100%)'>
<AddFormBtn title='링크 추가' handleClick={() => addLink(links.length - 1)} />
<AddFormBtn title='링크 추가' handleClick={() => addLink()} />
<S.PortfolioEditColumn $gap='3.6rem'>
{links?.map((link, index) => (
<LinkForm
Expand All @@ -437,11 +447,7 @@ const PortfolioEditPage = () => {
</S.PortfolioEditColumn>

<S.PortfolioEditButtonBox>
<DefaultBtn
type='button'
title='취소'
handleClick={() => navigate(`/portfolio/${portfolioId}`)}
/>
<DefaultBtn type='button' title='취소' handleClick={() => navigate(-1)} />
<PrimaryBtn
type='submit'
title='등록'
Expand Down
7 changes: 4 additions & 3 deletions src/pages/profile/edit/ProfileEditPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ const ProfileEditPage = () => {
if (skillList.find(skill => newSkill.name === skill.name)) {
alert('이미 추가한 스킬입니다.'); // 디자인 요청
setValue('skills', '');
return;
}
setSkillList(prev => [...prev, newSkill]);
setValue('skills', '');
Expand All @@ -254,7 +255,7 @@ const ProfileEditPage = () => {

const addLink = () => {
if (links.length === 10) {
alert('링크은 최대 10개까지 입력할 수 있습니다.'); // 디자인 요청
alert('링크는 최대 10개까지 입력할 수 있습니다.'); // 디자인 요청
return;
}
prependLink({ description: 'Link', url: '' });
Expand Down Expand Up @@ -513,7 +514,7 @@ const ProfileEditPage = () => {
<S.ProfileTitle>수상/활동</S.ProfileTitle>
<S.ProfileDescription>{DESCRIPTION.awards}</S.ProfileDescription>
<AddFormBtn title='수상/활동 추가' handleClick={() => addAward()} />
<S.ProfileColumn $gap='2.4rem'>
<S.ProfileColumn $gap='3.6rem'>
{awards?.map((award, index) => (
<S.ProfileRow key={award.id} $gap='1rem'>
<S.ProfileColumn $gap='2rem'>
Expand Down Expand Up @@ -557,7 +558,7 @@ const ProfileEditPage = () => {
<S.ProfileTitle>링크</S.ProfileTitle>
<S.ProfileDescription>{DESCRIPTION.links}</S.ProfileDescription>
<AddFormBtn title='링크 추가' handleClick={() => addLink()} />
<S.ProfileColumn $gap='2.4rem'>
<S.ProfileColumn $gap='3.6rem'>
{links?.map((link, index) => (
<LinkForm
key={link.id}
Expand Down