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: 랜딩페이지 제작 #132

Merged
merged 23 commits into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
9b18e5e
add: 랜딩페이지에 사용되는 이미지 파일들 추가
YesHyeon Aug 18, 2023
a299b0a
feat: 랜딩페이지 파일 추가 및 2번째 섹션까지 작업
YesHyeon Aug 19, 2023
798c2fd
feat: 약속시간 만들기 부분 추가
YesHyeon Aug 19, 2023
a07dd79
feat: 시간 입력하기 부분 추가 및 배치 수정
YesHyeon Aug 19, 2023
bb31e6a
feat: 우선순위 정하기 부분 추가
YesHyeon Aug 19, 2023
2a55d2f
add: 랜딩페이지 배경 추가
YesHyeon Aug 19, 2023
1e3cc0a
fix: 컴포넌트 구조 변경
YesHyeon Aug 19, 2023
a75d8e7
feat: LastWrapper 추가
YesHyeon Aug 19, 2023
d94a5ff
style:LastWrapper 스타일 수정
YesHyeon Aug 19, 2023
afba8ee
feat: Components 공통 컴포넌트로 구현
YesHyeon Aug 19, 2023
cf9d28c
feat: 스크롤 애니메이션을 위한 hook 파일 추가 및 적용
YesHyeon Aug 19, 2023
16d58b8
feat: 스크롤 해보세요에 적용할 플로팅 애니메이션 추가
YesHyeon Aug 19, 2023
0ce37ce
chore: 불필요헌 코드 삭제
YesHyeon Aug 28, 2023
5c45e6d
Merge branch 'develop' of https://github.com/dnd-side-project/dnd-8th…
YesHyeon Aug 28, 2023
57678c7
fix: 배경이미지 및 배치 수정
YesHyeon Aug 31, 2023
b6592ff
chore: Start 페이지 파일 삭제
YesHyeon Aug 31, 2023
ecf0081
Merge branch 'develop' of https://github.com/dnd-side-project/dnd-8th…
YesHyeon Aug 31, 2023
b0208cc
fix: 파일명 index로 수정
YesHyeon Sep 2, 2023
30aa19d
fix: 토글 기본값 하나씩으로 수정
YesHyeon Sep 2, 2023
da1c21f
chore: 이미지 파일명 수정
YesHyeon Sep 2, 2023
4322b62
style: S dot 네이밍 방식 도입
YesHyeon Sep 4, 2023
220bff8
Merge branch 'develop' of https://github.com/dnd-side-project/dnd-8th…
YesHyeon Sep 4, 2023
d63a7a5
chore: 오탈자 이미지 수정
YesHyeon Sep 4, 2023
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
5 changes: 3 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import AddTime from './pages/addTime';
import Current from './pages/current';
import RoomCalendar from './pages/roomCalendar';
import RoomStart from './pages/roomStart';
import Start from './pages/start';
import Timer from './pages/roomTimer';
import Login from './pages/login';
import Result from './pages/result';
Expand All @@ -14,13 +13,15 @@ import Error from './pages/404';
import useScrollToTop from './hooks/useScrollToTop';
import useGoogleAnalytics from './hooks/useGoogleAnalytics';

import Landing from './pages/landing';

function App() {
useGoogleAnalytics();
useScrollToTop();

return (
<Routes>
<Route path="/" element={<Start />} />
<Route path="/" element={<Landing />} />
<Route path={`${ROUTES.ROOM_START}`} element={<RoomStart />} />
<Route path={`${ROUTES.ROOM_CALENDAR}`} element={<RoomCalendar />} />
<Route path={`${ROUTES.ROOM_TIMER}`} element={<Timer />} />
Expand Down
Binary file added src/assets/icons/scrollArrow.webp
Binary file not shown.
Binary file added src/assets/images/landing1.webp
Binary file not shown.
Binary file added src/assets/images/landing2.webp
Binary file not shown.
Binary file added src/assets/images/landing3.webp
Binary file not shown.
Binary file added src/assets/images/landing4.webp
Binary file not shown.
Binary file added src/assets/images/landing5.webp
Binary file not shown.
Binary file added src/assets/images/landing6.webp
Binary file not shown.
Binary file added src/assets/images/landingBack.webp
Binary file not shown.
Binary file added src/assets/images/logo.webp
Binary file not shown.
Binary file added src/assets/images/rabbit.webp
Binary file not shown.
2 changes: 1 addition & 1 deletion src/components/createRoom/calendar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface Calendar {
}

const Calendar = ({ dates, setDates, setMonth }: Calendar) => {
const [isRange, setIsRange] = useState<boolean>(true);
const [isRange, setIsRange] = useState<boolean>(false);
const [value, setValue] = useState();

const ko = {
Expand Down
4 changes: 2 additions & 2 deletions src/components/createRoom/toggle/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ const Toggle = ({ text, toggle, setData }: ToggleProps) => {

return (
<ToggleBtn onClick={clickedToggle} toggle={isToggle}>
<ToggleText>{text[0]}</ToggleText>
<ToggleText>{text[1]}</ToggleText>
<Circle toggle={isToggle}>{isToggle ? text[0] : text[1]}</Circle>
<ToggleText>{text[0]}</ToggleText>
<Circle toggle={!isToggle}>{isToggle ? text[0] : text[1]}</Circle>
</ToggleBtn>
);
};
Expand Down
26 changes: 26 additions & 0 deletions src/hooks/useComponentOnScreen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { useEffect, RefObject } from 'react';

export const useComponentOnScreen = (refs: RefObject<HTMLDivElement>[]) => {
const handleScroll = (entries: any[]) => {
entries.forEach((item) => {
if (item.isIntersecting) {
item.target.style.opacity = 1;
item.target.style.transform = 'translateZ(0)';
}
});
};

const observer = new IntersectionObserver(handleScroll, {
threshold: 0.2,
});

useEffect(() => {
refs.forEach((ref) => {
if (ref.current) {
observer.observe(ref.current);
}
});

return () => observer && observer.disconnect();
}, []);
};
188 changes: 188 additions & 0 deletions src/pages/landing/index.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import styled from '@emotion/styled';
import theme from '../../styles/theme';
import landingBack from '@/assets/images/landingBack.webp';
import { flotingAnimation } from '@/utils/flotingAnimation';

export const MainContainer = styled.div`
display: flex;
flex-direction: column;
width: 100%;
max-width: 412px;
height: 6000px;
margin: 0 auto;
background-image: url(${landingBack});
background-size: cover;
background-position: center;
background-color: ${theme.colors.purple05};
&::-webkit-scrollbar {
display: none;
}
overflow-x: hidden;
`;

export const StartWrapper = styled.div`
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
padding-top: 150px;

@media screen and (max-width: 375px) {
padding-top: 80px;
}

height: 900px;

.logo-header {
${theme.typography.semibold02}
background: linear-gradient(180deg, #e3e7ff 0%, #f8f8ff 100%);
color: transparent;
-webkit-background-clip: text;
padding-bottom: 12px;
}

.logo {
width: 250px;
height: 42px;
margin-bottom: 58px;
}

.rabbit {
width: 250px;
}
`;

export const ScrollWrapper = styled.div`
display: flex;
flex-direction: row;
padding-top: 55px;
gap: 6px;
position: absolute;
bottom: 100px;

color: ${theme.colors.gray01};
${theme.typography.semibold04}

.arrow {
width: 17px;
height: 19px;
}

animation: ${flotingAnimation} 2s 5;
`;

export const IntroWrapper = styled.div`
display: flex;
flex-direction: column;
width: 100%;
height: 550px;
font-size: 22px;
color: ${theme.colors.gray01};
opacity: 0;
transition: all 2s;
transform: translateY(150px);

align-items: center;
${theme.typography.semibold04}

gap: 40px;

white-space: pre-line;

.title {
text-align: center;
color: ${theme.colors.gray01};
${theme.typography.semibold04};
font-size: 22px;
}

.chat {
width: calc(100% - 42px);
}

.logo {
width: 199px;
margin-inline: 10px;
}

.section {
margin-top: 50px;
display: flex;
flex-direction: column;
align-items: center;

.section-text {
font-size: 28px;
}
}
`;

export const ContentsWrapper = styled.div`
display: flex;
flex-direction: column;
gap: 70px;
padding-top: 340px;

@media screen and (max-width: 375px) {
gap: 170px;
}

white-space: pre-line;
`;

export const ContentWrapper = styled.div<{ index: number }>`
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
font-size: 22px;
opacity: 0;
transition: all 2s;
transform: translateY(150px);

img {
width: ${(props) =>
props.index == 1
? 'calc(100% - 142px)'
: props.index == 2
? 'calc(100% - 41px)'
: props.index == 3
? 'calc(100% - 140px)'
: 'calc(100% - 144px)'};
}
`;

export const LastWrapper = styled.div`
margin-top: 180px;
white-space: pre-line;
text-align: center;
opacity: 0;
transition: all 2s;
transform: translateY(50px);

.title {
color: ${theme.colors.gray01};
${theme.typography.semibold02}
}
`;

export const TitleWrapper = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 8px;
text-align: center;
white-space: pre-line;
padding-bottom: 45px;

.title-header {
color: ${theme.colors.purple06};
${theme.typography.semibold06};
}

.title {
color: ${theme.colors.gray07};
${theme.typography.semibold01};
}
`;
123 changes: 123 additions & 0 deletions src/pages/landing/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import { useRef } from 'react';
import { Link } from 'react-router-dom';

import * as S from './index.styles';

import BottomButton from '@/components/commons/bottomButton';
import { useComponentOnScreen } from '@/hooks/useComponentOnScreen';

import Rabbit from '@/assets/images/rabbit.webp';
import Logo from '@/assets/images/logo.webp';
import ScrollArrow from '@/assets/icons/scrollArrow.webp';
import landing1 from '@/assets/images/landing1.webp';
import landing2 from '@/assets/images/landing2.webp';
import landing3 from '@/assets/images/landing3.webp';
import landing4 from '@/assets/images/landing4.webp';
import landing5 from '@/assets/images/landing5.webp';
import landing6 from '@/assets/images/landing6.webp';

const Landing = () => {
const introRef = useRef<HTMLDivElement>(null);
const firstRef = useRef<HTMLDivElement>(null);
const secondRef = useRef<HTMLDivElement>(null);
const thirdRef = useRef<HTMLDivElement>(null);
const fourthRef = useRef<HTMLDivElement>(null);
const lastRef = useRef<HTMLDivElement>(null);

useComponentOnScreen([
introRef,
firstRef,
secondRef,
thirdRef,
fourthRef,
lastRef,
]);

const CONTENTS = [
{
id: 1,
titleHeader: '약속 시간 만들기',
title: '간단하게 약속 모임을\n만들어보세요',
images: [landing2, landing3],
ref: firstRef,
},
{
id: 2,
titleHeader: '시간 입력하기',
title: '되는 시간/안되는 시간 토글로\n일정을 등록해보세요',
images: [landing4],
ref: secondRef,
},
{
id: 3,
titleHeader: '실시간 확인하기',
title: '일정등록 타이머와 함께\n실시간 참여율을 확인할 수 있어요',
images: [landing5],
ref: thirdRef,
},
{
id: 4,
titleHeader: '우선순위 확인하기',
title: '조율 결과를\n한눈에 확인해볼까요?',
images: [landing6],
ref: fourthRef,
},
];

return (
<S.MainContainer>
<S.StartWrapper>
<div className="logo-header">쉽고 빠른 약속 정하기</div>
<img className="logo" src={Logo} />
<img className="rabbit" src={Rabbit} />
<S.ScrollWrapper>
<img className="arrow" src={ScrollArrow} />
스크롤해보세요
</S.ScrollWrapper>
</S.StartWrapper>
<S.IntroWrapper ref={introRef}>
<div className="title">
{`3인 이상 약속을 잡을 때,
일정 조율하기 어렵지 않으셨나요?`}
</div>
<img className="chat" src={landing1} />
<div className="section">
<div className="section-logo">
<img className="logo" src={Logo} />이
</div>
<div className="section-text">도와드릴게요!</div>
</div>
</S.IntroWrapper>
<S.ContentsWrapper>
{CONTENTS.map((item) => {
return (
<S.ContentWrapper index={item.id} key={item.id} ref={item.ref}>
<S.TitleWrapper>
<div className="title-header">{item.titleHeader}</div>
<div className="title">{item.title}</div>
</S.TitleWrapper>
{item.images.map((image) => {
return <img src={image} key={image} />;
})}
</S.ContentWrapper>
);
})}
</S.ContentsWrapper>
<S.LastWrapper ref={lastRef}>
<div className="title">
{`간편하고 빠르게 약속시간을 정하고 싶다면
모두의 시간과 함께 해보세요!`}
</div>
</S.LastWrapper>
<Link to="/roomStart">
<BottomButton
text="시작하기"
isBackgroundVisible={false}
isActivated={true}
/>
</Link>
</S.MainContainer>
);
};

export default Landing;
2 changes: 1 addition & 1 deletion src/pages/roomStart/index.styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ export const ChceckContainer = styled.div`
padding-right: 20px;
`;

export const CheckListText = styled.text`
export const CheckListText = styled.div`
font-family: Pretendard;
`;

Expand Down
Loading