Skip to content

Commit

Permalink
[feat] 공모전 상세 페이지 (모집중인 팀) 제작 완료 (#20)
Browse files Browse the repository at this point in the history
* feat(#18) : 라우팅, Contest.tsx 제작

* feat(#18) : 공모전 세부정보페이지 완료

* feat(#18) : 팀장, 팀원박스 및 팀원정보 노출 완료

* feat(#18) : 리더infobox 컴포넌트 완료

* feat(#18) : 팀원infobox 컴포넌트 및 스크롤 커스텀 완료

* feat(#18) : 팀 생성버튼 라우팅 및 navigate추가
  • Loading branch information
j2noo authored Nov 9, 2023
1 parent 6242834 commit 45ad34c
Show file tree
Hide file tree
Showing 8 changed files with 553 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Profile from './pages/profile/Profile';
import Recommendation from './pages/recommendation/Recommendation';
import MultipleChoice from './pages/recommendation/MultipleChoice';
import Subjective from './pages/recommendation/Subjective';
import Contest from './pages/contest/Contest';
import CompetitionList from './pages/competitionList/CompetitionList';

function Router() {
Expand All @@ -24,6 +25,8 @@ function Router() {
<Route path="multipleChoice" element={<MultipleChoice />} />
</Route>
<Route path="/profile/:userId" element={<Profile />} />
<Route path='/list/:postId' element={<Contest/>}/>
<Route path='/list/:postId/:teamId' element={<div>팀 생성페이지입니다</div>}/>
<Route path="/list" element={<CompetitionList />} />
</Routes>
<Footer />
Expand Down
76 changes: 76 additions & 0 deletions src/components/contest/ContestInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import styled from 'styled-components';
import { CONTEST_DATA } from '../../constants/Contest';

const ContestInfo = () => {
return (
<ContestInfoLayout>
<ContestInfoTitle>{CONTEST_DATA.title}</ContestInfoTitle>
<ContestContainer>
<ContestImg src={CONTEST_DATA.images[0]} />
<ContestTextBox>
<Dday>D-{CONTEST_DATA.remainDay}</Dday>
{CONTEST_DATA.data}
</ContestTextBox>
</ContestContainer>
</ContestInfoLayout>
);
};
const ContestInfoLayout = styled.div`
display: flex;
flex-direction: column;
max-width: 122.4rem;
margin: auto;
`;
const ContestInfoTitle = styled.div`
${(props) => props.theme.fonts.heading2_1};
color: ${(props) => props.theme.colors.gray90};
margin-top: 3rem;
`;
const ContestContainer = styled.div`
display: flex;
gap: 2rem;
margin: 2rem 0;
`;
const ContestImg = styled.img`
width: 36.8rem;
height: 45.4rem;
border-radius: 1.2rem;
`;

const ContestTextBox = styled.div`
${(props) => props.theme.fonts.subtitleM};
background-color: ${(props) => props.theme.colors.gray5};
border: 1px solid ${(props) => props.theme.colors.primary20};
border-radius: 1.2rem;
height: 45.4rem;
width: 100%;
/* display: flex; */
padding: 1.9rem 3.6rem;
white-space: break-spaces;
overflow-y: scroll;
&::-webkit-scrollbar {
width: 8px;
height: 8px;
border-radius: 6px;
background: rgba(255, 255, 255, 0.4);
}
&::-webkit-scrollbar-thumb {
background: ${(props) => props.theme.colors.gray20};
border-radius: 6px;
}
`;
const Dday = styled.div`
${(props) => props.theme.fonts.heading5};
color: ${(props) => props.theme.colors.error90};
margin-bottom: 2rem;
`;
export default ContestInfo;
43 changes: 43 additions & 0 deletions src/components/contest/LeaderInfoBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import styled from 'styled-components';

const LeaderInfoBox = ({ infoData }: { infoData: any }) => {
return (
<Container>
<LeaderImg src={infoData.image} />{' '}
<hr style={{ width: '100%', margin: '1rem 0', borderColor: '#898BF8' }} />
<Name>{infoData.name}</Name>
<Part>{infoData.part}</Part>
<Part>{infoData.major}</Part>
</Container>
);
};
const Container = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 3rem 4.5rem 2rem 4.5rem;
color: ${(props) => props.theme.colors.primary40};
`;
const LeaderImg = styled.img`
width: 8rem;
height: 8rem;
border: 1px solid ${(props) => props.theme.colors.primary20};
border-radius: 4rem;
object-fit: cover;
`;
const Name = styled.div`
${(props) => props.theme.fonts.heading5};
color: ${(props) => props.theme.colors.gray90};
/* margin: 1rem 0; */
`;
const Part = styled.div`
${(props) => props.theme.fonts.bodyS};
color: ${(props) => props.theme.colors.gray70};
`;
export default LeaderInfoBox;
49 changes: 49 additions & 0 deletions src/components/contest/MemberInfoBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import styled from 'styled-components';

const MemberInfoBox = ({ infoData }: { infoData: any }) => {
return (
<Container>
<MemberImg src={infoData.image} /> <Name>{infoData.name}</Name>
<Part>{infoData.part}</Part>
<Part>{infoData.major}</Part>
</Container>
);
};
const Container = styled.div`
max-width: 13.9rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: 1px solid ${(props) => props.theme.colors.gray20};
border-radius: 0.8rem;
background-color: ${(props) => props.theme.colors.primary20};
padding: 2rem 3rem 2rem 3rem;
`;
const MemberImg = styled.img`
width: 8rem;
height: 8rem;
border: 1px solid ${(props) => props.theme.colors.primary20};
border-radius: 4rem;
object-fit: cover;
`;
const Name = styled.div`
${(props) => props.theme.fonts.subtitleS};
color: ${(props) => props.theme.colors.gray90};
/* margin: 1rem 0; */
`;
const Part = styled.div`
${(props) => props.theme.fonts.bodyXS};
color: ${(props) => props.theme.colors.gray70};
text-align: center;
white-space: nowrap;
`;
export default MemberInfoBox;
143 changes: 143 additions & 0 deletions src/components/contest/RecruitTeamItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import styled from 'styled-components';
import LeaderInfoBox from './LeaderInfoBox';
import MemberInfoBox from './MemberInfoBox';

const RecruitTeamItem = ({ data }: { data: any }) => {
return (
<ItemLayout>
<LeaderBox>
<Role>팀장</Role>
<LeaderInfoBox infoData={data.leader} />
</LeaderBox>
<MemberBox>
<Role>팀원</Role>
<TeamInfoBox>
<TO>
모집 현황 : {data.cur}/{data.max}
</TO>
<IntroduceTitle>팀장의 한 마디</IntroduceTitle>
<IntroduceContent>{data.talk}</IntroduceContent>
<GoTeamButton>팀 자세히 보러가기</GoTeamButton>
</TeamInfoBox>
<MemberInfoContainer>
{data.members.map((member: any, index: any) => (
<MemberInfoBox infoData={member} key={index} />
))}
</MemberInfoContainer>
</MemberBox>
</ItemLayout>
);
};
const ItemLayout = styled.div`
display: flex;
gap: 2.4rem;
`;
const Role = styled.div`
position: absolute;
left: -1px;
top: -1.5rem;
color: ${(props) => props.theme.colors.white};
background-color: ${(props) => props.theme.colors.primary40};
border-radius: 0.8rem;
width: 4.1rem;
height: 3rem;
padding: 0.4rem 0.8rem;
`;
const LeaderBox = styled.div`
position: relative;
${(props) => props.theme.fonts.subtitleS};
color: ${(props) => props.theme.colors.white};
background-color: ${(props) => props.theme.colors.primary10};
border: 1px solid ${(props) => props.theme.colors.primary40};
border-radius: 0.8rem;
width: 17.1rem;
/* height: 23rem; */
`;
const MemberBox = styled.div`
position: relative;
display: flex;
${(props) => props.theme.fonts.subtitleS};
color: ${(props) => props.theme.colors.white};
background-color: ${(props) => props.theme.colors.primary10};
border: 1px solid ${(props) => props.theme.colors.primary40};
border-radius: 0.8rem;
width: 100%;
/* height: 23rem; */
`;
const TeamInfoBox = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 1rem;
width: 25rem;
padding: 2rem;
`;
const TO = styled.div`
${(props) => props.theme.fonts.subtitleXS};
font-weight: 700;
color: ${(props) => props.theme.colors.primary40};
width: 100%;
`;
const IntroduceTitle = styled.div`
${(props) => props.theme.fonts.subtitleS};
color: ${(props) => props.theme.colors.gray90};
`;
const IntroduceContent = styled.div`
${(props) => props.theme.fonts.subtitleM};
color: ${(props) => props.theme.colors.primary90};
background-color: ${(props) => props.theme.colors.white};
border: 1px solid ${(props) => props.theme.colors.primary40};
border-radius: 0.8rem;
width: 100%;
padding: 3.5rem;
text-align: center;
`;
const GoTeamButton = styled.button`
${(props) => props.theme.fonts.subtitleXS};
color: rgba(255, 255, 255, 0.8);
background-color: ${(props) => props.theme.colors.primary40};
border: 1px solid ${(props) => props.theme.colors.primary40};
border-radius: 0.8rem;
width: 100%;
padding: 0.5rem;
`;
const MemberInfoContainer = styled.div`
display: flex;
gap: 1.2rem;
overflow-x: scroll;
max-width: 72rem;
/* max-width: 100%; */
padding: 2.8rem;
&::-webkit-scrollbar {
width: 8px;
height: 8px;
border-radius: 6px;
background: rgba(255, 255, 255, 0.4);
}
&::-webkit-scrollbar-thumb {
background: ${(props) => props.theme.colors.primary60};
border-radius: 6px;
}
`;
export default RecruitTeamItem;
58 changes: 58 additions & 0 deletions src/components/contest/RecruitTeamList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import styled from 'styled-components';
import { TEAMS_DATA } from '../../constants/Contest';
import RecruitTeamItem from './RecruitTeamItem';
import { useNavigate } from 'react-router-dom';

const RecruitTeamList = () => {
const navigate = useNavigate();
const handleBtnClicked = () => {
navigate('3');
};
return (
<RecruitTeamListLayout>
<RecruitTeamListTopContainer>
<RecruitTeamListTitle>모집 중인 팀</RecruitTeamListTitle>
<RecruitTeamButton onClick={handleBtnClicked}>
+팀 오픈하러 가기
</RecruitTeamButton>
</RecruitTeamListTopContainer>{' '}
<RecruitTeamContainer>
{TEAMS_DATA.map((data, index) => {
return <RecruitTeamItem data={data} key={index} />;
})}
</RecruitTeamContainer>
</RecruitTeamListLayout>
);
};

const RecruitTeamListLayout = styled.div`
margin-left: 3rem;
`;
const RecruitTeamListTopContainer = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
margin: 3rem 0 4.5rem 0;
`;

const RecruitTeamListTitle = styled.div`
${(props) => props.theme.fonts.heading3};
color: ${(props) => props.theme.colors.gray100};
`;
const RecruitTeamButton = styled.button`
${(props) => props.theme.fonts.buttonL};
color: ${(props) => props.theme.colors.white};
background-color: ${(props) => props.theme.colors.primary60};
display: inline-block;
width: 20.8rem;
height: 6.4rem;
border-radius: 3.2rem;
`;
const RecruitTeamContainer = styled.div`
display: flex;
flex-direction: column;
gap: 4rem;
`;
export default RecruitTeamList;
Loading

0 comments on commit 45ad34c

Please sign in to comment.