diff --git a/src/components/index.ts b/src/components/index.ts index c9903aea..6685592c 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -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, @@ -289,4 +290,5 @@ export { ApproveModal, TabMenu, PostingDelete, + Modal, }; diff --git a/src/components/modal/Modal.styled.ts b/src/components/modal/Modal.styled.ts new file mode 100644 index 00000000..23aa85e6 --- /dev/null +++ b/src/components/modal/Modal.styled.ts @@ -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; diff --git a/src/components/modal/Modal.tsx b/src/components/modal/Modal.tsx new file mode 100644 index 00000000..4d4ae709 --- /dev/null +++ b/src/components/modal/Modal.tsx @@ -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 ( + + + {title} + {content} + +
+ +
+
+ +
+
+
+
+ ); +}; + +export default Modal; diff --git a/src/components/radio/Radio.tsx b/src/components/radio/Radio.tsx index 8a8795c7..a1ff1eb1 100644 --- a/src/components/radio/Radio.tsx +++ b/src/components/radio/Radio.tsx @@ -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)} /> diff --git a/src/constant/validation.ts b/src/constant/validation.ts index e05ac976..ee7b5568 100644 --- a/src/constant/validation.ts +++ b/src/constant/validation.ts @@ -89,7 +89,7 @@ export const INPUT_VALIDATION = { required: '분야를 선택해주세요', }, role: { - required: '역할를 선택해주세요', + required: '역할을 선택해주세요', }, startDate: { required: '시작일을 설정해주세요', diff --git a/src/pages/account/complete/CompleteSignUpPage.tsx b/src/pages/account/complete/CompleteSignUpPage.tsx index 813e435e..c6e84373 100644 --- a/src/pages/account/complete/CompleteSignUpPage.tsx +++ b/src/pages/account/complete/CompleteSignUpPage.tsx @@ -1,11 +1,35 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import S from './CompleteSignUpPage.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 CompleteSignUpPage = () => { 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 ( @@ -14,7 +38,12 @@ const CompleteSignUpPage = () => { 회원가입을 축하합니다!
- navigate('/')} /> + setModalOpen(true)} /> + {modalOpen && ( + + + + )}
); diff --git a/src/pages/portfolio/edit/PortfolioEditPage.tsx b/src/pages/portfolio/edit/PortfolioEditPage.tsx index b0af7809..5cc35219 100644 --- a/src/pages/portfolio/edit/PortfolioEditPage.tsx +++ b/src/pages/portfolio/edit/PortfolioEditPage.tsx @@ -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', ''); }; @@ -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: '' }); }; // 상세 내용 @@ -416,7 +426,7 @@ const PortfolioEditPage = () => { 링크 - addLink(links.length - 1)} /> + addLink()} /> {links?.map((link, index) => ( { - navigate(`/portfolio/${portfolioId}`)} - /> + navigate(-1)} /> { if (skillList.find(skill => newSkill.name === skill.name)) { alert('이미 추가한 스킬입니다.'); // 디자인 요청 setValue('skills', ''); + return; } setSkillList(prev => [...prev, newSkill]); setValue('skills', ''); @@ -254,7 +255,7 @@ const ProfileEditPage = () => { const addLink = () => { if (links.length === 10) { - alert('링크은 최대 10개까지 입력할 수 있습니다.'); // 디자인 요청 + alert('링크는 최대 10개까지 입력할 수 있습니다.'); // 디자인 요청 return; } prependLink({ description: 'Link', url: '' }); @@ -513,7 +514,7 @@ const ProfileEditPage = () => { 수상/활동 {DESCRIPTION.awards} addAward()} /> - + {awards?.map((award, index) => ( @@ -557,7 +558,7 @@ const ProfileEditPage = () => { 링크 {DESCRIPTION.links} addLink()} /> - + {links?.map((link, index) => (