Skip to content

Commit

Permalink
Merge pull request #52 from KUSITMS-29th-TEAM-D/feature/#51/detail
Browse files Browse the repository at this point in the history
[FEAT] 상세페이지 신청하기 섹션 구현
  • Loading branch information
mungjin01 authored May 22, 2024
2 parents 42deb2f + aa5fd39 commit 575d9a4
Show file tree
Hide file tree
Showing 6 changed files with 434 additions and 10 deletions.
3 changes: 3 additions & 0 deletions src/components/ExperienceDetailPage/BubbleSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const BubbleSection = () => {
return <div>여긴 버블버블</div>;
};
171 changes: 171 additions & 0 deletions src/components/ExperienceDetailPage/DetailSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
import { useState } from 'react';

import { styled } from 'styled-components';

import { PlainButton } from '@/components/common/Button/PlainButton';
import { PlainChip } from '@/components/common/Chip/PlainChip';
import { ExperienceDetailModal } from '@/components/common/Modal/ExperienceDetailModal';
import { DetailData } from '@/pages/ExperienceDetailPage';

const DetailSection = ({ data }: { data: DetailData }) => {
const [isModalOpen, setModalOpen] = useState(false);
const [participants, setParticipants] = useState(data.participants);
const [isButtonDisabled, setButtonDisabled] = useState(false);

const handleOpenModal = () => {
setModalOpen(true);
};

const handleCloseModal = () => {
setModalOpen(false);
};

const handleIncreaseParticipants = () => {
setParticipants((prevParticipants) => prevParticipants + 1);
setButtonDisabled(true);
setModalOpen(false);
};

return (
<StyledContainer>
<ImageContainer>
<img src={data.imageURL} alt="Detail" />
</ImageContainer>
<DetailContainer>
<TextContainer>
<PlainChip primary={true}>{participants}명 참여 중!</PlainChip>
<TitleContainer>{data.title}</TitleContainer>
<SubTitleContainer>{data.subtitle}</SubTitleContainer>
</TextContainer>
<ProfileContainer>
<ProfileImageContainer>
<img src={data.profileImageURL} alt="profile" />
</ProfileImageContainer>
<ProfileTextContainer>
<ProfileTitleContainer>{data.providerName}</ProfileTitleContainer>
<ProfileSubTitleContainer>
{data.providerJob} | {data.providerTitle} | {data.providerKeyword}
</ProfileSubTitleContainer>
</ProfileTextContainer>
</ProfileContainer>
<PlainButton
variant="gray"
height="48px"
onClick={handleOpenModal}
disabled={isButtonDisabled}
>
신청하기
</PlainButton>
</DetailContainer>
<ExperienceDetailModal
isOpen={isModalOpen}
onClose={handleCloseModal}
onConfirm={handleIncreaseParticipants}
/>
</StyledContainer>
);
};

export default DetailSection;
const StyledContainer = styled.div`
width: 100%;
height: 100%;
justify-content: flex-start;
align-items: flex-start;
gap: 32px;
display: inline-flex;
`;

const ImageContainer = styled.div`
width: 597px;
height: 373px;
position: relative;
border-radius: 8px;
overflow: hidden;
flex-shrink: 0;
img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 8px;
}
`;

const DetailContainer = styled.div`
flex: 1 1 0;
align-self: stretch;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
gap: 16px;
display: inline-flex;
`;

const TextContainer = styled.div`
align-self: stretch;
flex: 1 1 0;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
gap: 10px;
display: flex;
`;

const TitleContainer = styled.div`
align-self: stretch;
color: ${({ theme }) => `${theme.color.gray700}`};
${({ theme }) => theme.font.desktop.title1};
`;

const SubTitleContainer = styled.div`
align-self: stretch;
color: ${({ theme }) => `${theme.color.gray500}`};
${({ theme }) => theme.font.desktop.body2m};
`;

const ProfileContainer = styled.div`
align-self: stretch;
padding: 16px;
background-color: ${({ theme }) => `${theme.color.white}`};
border-radius: 8px;
overflow: hidden;
border: 2px solid ${({ theme }) => `${theme.color.gray150}`};
justify-content: flex-start;
align-items: center;
gap: 16px;
display: inline-flex;
flex-shrink: 0;
`;

const ProfileImageContainer = styled.div`
width: 56px;
height: 56px;
background: linear-gradient(0deg, #f4efff 0%, #f4efff 100%);
border-radius: 8px;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
`;

const ProfileTextContainer = styled.div`
flex-direction: column;
justify-content: center;
align-items: flex-start;
gap: 4px;
display: inline-flex;
`;

const ProfileTitleContainer = styled.div`
color: ${({ theme }) => `${theme.color.gray700}`};
${({ theme }) => theme.font.desktop.body1m};
`;

const ProfileSubTitleContainer = styled.div`
color: ${({ theme }) => `${theme.color.gray700}`};
${({ theme }) => theme.font.desktop.body2m};
`;
50 changes: 50 additions & 0 deletions src/components/ExperienceDetailPage/ImageSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { styled } from 'styled-components';

import { Dummy1 } from '@/pages/ExperienceDetailPage';

export const ImageSection = () => {
return (
<StyledContainer>
<TitleContainer>프로그램 소개</TitleContainer>
<ImageBorderContainer>
<ImageContainer>
<img src={Dummy1.imageURL} alt="Detail" />
</ImageContainer>
</ImageBorderContainer>
</StyledContainer>
);
};

const StyledContainer = styled.div`
width: 100%;
height: 100%;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
gap: 24px;
display: inline-flex;
`;

const TitleContainer = styled.div`
text-align: center;
color: ${({ theme }) => `${theme.color.gray900}`};
${({ theme }) => theme.font.desktop.title1};
`;

const ImageBorderContainer = styled.div`
align-self: stretch;
padding: 32px;
background-color: ${({ theme }) => `${theme.color.white}`};
border-radius: 8px;
overflow: hidden;
border: 2px solid ${({ theme }) => `${theme.color.gray150}`};
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
gap: 20px;
display: flex;
`;

const ImageContainer = styled.div`
//연동하면서 수정 예정
`;
103 changes: 103 additions & 0 deletions src/components/common/Modal/ExperienceDetailModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { useEffect } from 'react';

import styled from 'styled-components';

import { PlainButton } from '@/components/common/Button/PlainButton';

interface ModalProps {
isOpen: boolean;
onClose: () => void;
onConfirm: () => void;
}

export const ExperienceDetailModal = ({ isOpen, onClose, onConfirm }: ModalProps) => {
useEffect(() => {
if (isOpen) {
document.body.setAttribute('style', 'overflow: hidden');
} else {
document.body.setAttribute('style', 'overflow: auto');
}
return () => {
document.body.setAttribute('style', 'overflow: auto');
};
}, [isOpen]);
if (!isOpen) return null;

return (
<ModalOverlay>
<ModalContent>
<TitleContainer>프로그램 신청</TitleContainer>
<ContentContainer>
해당 프로그램을 <Highlight>신청</Highlight>하시겠습니까?
</ContentContainer>
<ButtonContainer>
<StyledButton height="48px" onClick={onClose}>
취소하기
</StyledButton>
<PlainButton variant="gray" height="48px" onClick={onConfirm}>
신청하기
</PlainButton>
</ButtonContainer>
</ModalContent>
</ModalOverlay>
);
};

const ModalOverlay = styled.div`
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(17.85, 17.85, 17.85, 0.36);
backdrop-filter: blur(10px);
display: flex;
justify-content: center;
align-items: center;
`;

const ModalContent = styled.div`
width: 618px;
height: 338px;
background: white;
padding: 24px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.25);
border-radius: 16px;
overflow: hidden;
backdrop-filter: blur(8px);
flex-direction: column;
justify-content: space-between;
align-items: center;
display: inline-flex;
`;

const TitleContainer = styled.div`
align-self: stretch;
text-align: center;
color: ${({ theme }) => `${theme.color.gray800}`};
${({ theme }) => theme.font.desktop.body1b};
`;

const ContentContainer = styled.div`
color: ${({ theme }) => `${theme.color.gray700}`};
${({ theme }) => theme.font.desktop.title2};
`;

const ButtonContainer = styled.div`
align-self: stretch;
justify-content: flex-start;
gap: 8px;
display: inline-flex;
`;

const StyledButton = styled(PlainButton)`
background: ${({ theme }) => `${theme.color.gray200}`};
&:hover {
background: ${({ theme }) => `${theme.color.gray200}`};
}
color: inherit;
`;

const Highlight = styled.span`
color: ${({ theme }) => theme.color.primary500};
`;
Loading

0 comments on commit 575d9a4

Please sign in to comment.