diff --git a/src/Router.tsx b/src/Router.tsx
index 94daba7b..dde1771e 100644
--- a/src/Router.tsx
+++ b/src/Router.tsx
@@ -5,6 +5,7 @@ import HealthTest from './HealthTest';
import LecueNotePage from './LecueNote/page/LeceuNotePage';
import Login from './Login/page';
import Register from './Register/page';
+import SelectBookPage from './SelectBook/page/SelectBookPage';
import SplashPage from './Splash/page/SplashPage';
import StickerPack from './StickerPack/page/StickerPack';
import TargetPage from './Target/page/TargetPage';
@@ -21,6 +22,7 @@ function Router() {
} />
} />
} />
+ } />
);
diff --git a/src/SelectBook/components/BookTypeBox/BookTypeBox.style.ts b/src/SelectBook/components/BookTypeBox/BookTypeBox.style.ts
new file mode 100644
index 00000000..19012005
--- /dev/null
+++ b/src/SelectBook/components/BookTypeBox/BookTypeBox.style.ts
@@ -0,0 +1,104 @@
+import styled from '@emotion/styled';
+
+export const BookTypeBoxWrapper = styled.div<{
+ bookType: number;
+ selectedBox: number;
+ isClickedSelectButton: boolean;
+}>`
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ position: absolute;
+
+ width: ${({ bookType, isClickedSelectButton }) =>
+ bookType === 2 && isClickedSelectButton ? '28.4rem' : '16.5rem'};
+ height: 34.9rem;
+
+ border: ${({ bookType, selectedBox, theme }) =>
+ selectedBox === 0
+ ? `0.1rem solid ${theme.colors.LG}`
+ : selectedBox === bookType
+ ? `0.1rem solid ${theme.colors.key}`
+ : `0.1rem solid ${theme.colors.MG}`};
+ border-radius: 0.4rem;
+ background-color: ${({ bookType, selectedBox, theme }) =>
+ bookType === 2 && bookType === selectedBox
+ ? theme.colors.BG
+ : theme.colors.white};
+
+ transition:
+ width 0.5s ease,
+ transform 0.5s ease;
+ opacity: ${({ bookType, selectedBox }) =>
+ selectedBox !== 0 && bookType !== selectedBox ? 0.5 : 1};
+
+ ${({ bookType }) => (bookType === 1 ? 'left' : 'right')}: 0;
+`;
+
+export const BookTypeBoxTitle = styled.p<{
+ bookType: number;
+ selectedBox: number;
+ isClickedSelectButton: boolean;
+}>`
+ display: flex;
+ align-items: center;
+
+ height: 3.7rem;
+ margin-top: 2.5rem;
+ margin-bottom: ${({ bookType, isClickedSelectButton }) =>
+ bookType === 2 && isClickedSelectButton ? '0.7rem' : '2.7rem'};
+
+ color: ${({ bookType, selectedBox, theme }) =>
+ bookType === 2 && bookType === selectedBox
+ ? theme.colors.white
+ : theme.colors.BG};
+ ${({ theme, bookType, isClickedSelectButton }) =>
+ bookType === 2 && isClickedSelectButton
+ ? theme.fonts.Head1_B_20
+ : theme.fonts.Title1_SB_16};
+`;
+
+export const BookTypeBoxPrice = styled.p<{
+ bookType: number;
+ selectedBox: number;
+}>`
+ margin-top: 0.9rem;
+
+ color: ${({ bookType, selectedBox, theme }) =>
+ bookType === 2 && bookType === selectedBox
+ ? theme.colors.key
+ : theme.colors.BG};
+ ${({ theme }) => theme.fonts.Head1_B_20};
+`;
+
+export const BookTypeBoxPriceWrapper = styled.div`
+ display: flex;
+ align-items: flex-end;
+
+ column-gap: 0.7rem;
+`;
+
+export const OneBookText = styled.p`
+ padding-bottom: 0.2rem;
+
+ color: ${({ theme }) => theme.colors.MG};
+ ${({ theme }) => theme.fonts.Body2_M_14};
+`;
+
+export const BookTypeBoxOptionList = styled.div<{
+ bookType: number;
+ selectedBox: number;
+ isClickedSelectButton: boolean;
+}>`
+ display: flex;
+ flex-direction: column;
+ row-gap: 0.6rem;
+
+ margin-top: ${({ bookType, isClickedSelectButton }) =>
+ bookType === 2 && isClickedSelectButton ? '1.5rem' : '3.85rem'};
+
+ color: ${({ bookType, selectedBox, theme }) =>
+ bookType === 2 && bookType === selectedBox
+ ? theme.colors.white
+ : theme.colors.DG};
+`;
diff --git a/src/SelectBook/components/BookTypeBox/index.tsx b/src/SelectBook/components/BookTypeBox/index.tsx
new file mode 100644
index 00000000..ab96de59
--- /dev/null
+++ b/src/SelectBook/components/BookTypeBox/index.tsx
@@ -0,0 +1,78 @@
+import { ReactNode } from 'react';
+
+import { ImgBookOrangeBig, ImgSaleprice } from '../../../assets';
+import BookTypeBoxOption from '../BookTypeBoxOption';
+import * as S from './BookTypeBox.style';
+
+interface BookTypeBoxProps {
+ handleClickBookTypeBox: () => void;
+ selectedBox: number;
+ bookType: number;
+ bookTypeBoxTitle: string;
+ bookTypeBoxImg: ReactNode;
+ bookTypeBoxPrice: number;
+ isClickedSelectButton: boolean;
+ bookTypeBoxOptionList: string[];
+}
+
+function BookTypeBox({
+ handleClickBookTypeBox,
+ bookType,
+ bookTypeBoxTitle,
+ bookTypeBoxImg,
+ bookTypeBoxPrice,
+ selectedBox,
+ isClickedSelectButton,
+ bookTypeBoxOptionList,
+}: BookTypeBoxProps) {
+ return (
+ {
+ if (isClickedSelectButton === false) {
+ handleClickBookTypeBox();
+ }
+ }}
+ bookType={bookType}
+ selectedBox={selectedBox}
+ isClickedSelectButton={isClickedSelectButton}
+ >
+
+ {bookTypeBoxTitle}
+
+ {bookType === 2 && isClickedSelectButton ? (
+
+ ) : (
+ bookTypeBoxImg
+ )}
+
+ {bookType === 2 && isClickedSelectButton && }
+
+
+ {bookType === 2 && isClickedSelectButton
+ ? '0원'
+ : `${bookTypeBoxPrice}원`}
+
+ {bookType === 2 && !isClickedSelectButton ? (
+ /1권
+ ) : (
+ <>>
+ )}
+
+
+ {bookTypeBoxOptionList.map((option, idx) => (
+
+ ))}
+
+
+ );
+}
+
+export default BookTypeBox;
diff --git a/src/SelectBook/components/BookTypeBoxOption/BookTypeBoxOption.style.ts b/src/SelectBook/components/BookTypeBoxOption/BookTypeBoxOption.style.ts
new file mode 100644
index 00000000..a6856627
--- /dev/null
+++ b/src/SelectBook/components/BookTypeBoxOption/BookTypeBoxOption.style.ts
@@ -0,0 +1,12 @@
+import styled from '@emotion/styled';
+
+export const BookTypeBoxOptionWrapper = styled.div`
+ display: flex;
+ column-gap: 0.5rem;
+
+ align-items: center;
+`;
+
+export const BookTypeBoxOptionText = styled.p`
+ ${({ theme }) => theme.fonts.Body2_M_14};
+`;
diff --git a/src/SelectBook/components/BookTypeBoxOption/index.tsx b/src/SelectBook/components/BookTypeBoxOption/index.tsx
new file mode 100644
index 00000000..a4a2b200
--- /dev/null
+++ b/src/SelectBook/components/BookTypeBoxOption/index.tsx
@@ -0,0 +1,17 @@
+import { IcCheck } from '../../../assets';
+import * as S from './BookTypeBoxOption.style';
+
+interface BookTypeBoxOptionProps {
+ bookTypeBoxOption: string;
+}
+
+function BookTypeBoxOption({ bookTypeBoxOption }: BookTypeBoxOptionProps) {
+ return (
+
+
+ {bookTypeBoxOption}
+
+ );
+}
+
+export default BookTypeBoxOption;
diff --git a/src/SelectBook/components/CompleteButton/CompleteButton.style.ts b/src/SelectBook/components/CompleteButton/CompleteButton.style.ts
new file mode 100644
index 00000000..7f21332d
--- /dev/null
+++ b/src/SelectBook/components/CompleteButton/CompleteButton.style.ts
@@ -0,0 +1,6 @@
+import styled from '@emotion/styled';
+
+export const CompleteButtonWrapper = styled.div`
+ width: 100%;
+ margin-bottom: 2rem;
+`;
diff --git a/src/SelectBook/components/CompleteButton/index.tsx b/src/SelectBook/components/CompleteButton/index.tsx
new file mode 100644
index 00000000..92d21efd
--- /dev/null
+++ b/src/SelectBook/components/CompleteButton/index.tsx
@@ -0,0 +1,19 @@
+import Button from '../../../components/common/Button';
+import * as S from './CompleteButton.style';
+
+interface CompleteButtonProps {
+ isActive: boolean;
+ onClick: () => void;
+}
+
+function CompleteButton({ isActive, onClick }: CompleteButtonProps) {
+ return (
+
+
+
+ );
+}
+
+export default CompleteButton;
diff --git a/src/SelectBook/components/MakeLecueBookButton/MakeLecueBookButton.style.ts b/src/SelectBook/components/MakeLecueBookButton/MakeLecueBookButton.style.ts
new file mode 100644
index 00000000..cf99d31c
--- /dev/null
+++ b/src/SelectBook/components/MakeLecueBookButton/MakeLecueBookButton.style.ts
@@ -0,0 +1,6 @@
+import styled from '@emotion/styled';
+
+export const MakeLecueBookButtonWrapper = styled.div`
+ width: 100%;
+ margin-bottom: 2rem;
+`;
diff --git a/src/SelectBook/components/MakeLecueBookButton/index.tsx b/src/SelectBook/components/MakeLecueBookButton/index.tsx
new file mode 100644
index 00000000..bd50a34d
--- /dev/null
+++ b/src/SelectBook/components/MakeLecueBookButton/index.tsx
@@ -0,0 +1,19 @@
+import Button from '../../../components/common/Button';
+import * as S from './MakeLecueBookButton.style';
+
+interface MakeLecueBookButtonProps {
+ isActive: boolean;
+ onClick: () => void;
+}
+
+function MakeLecueBookButton({ isActive, onClick }: MakeLecueBookButtonProps) {
+ return (
+
+
+
+ );
+}
+
+export default MakeLecueBookButton;
diff --git a/src/SelectBook/constants/.gitkeep b/src/SelectBook/constants/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/src/SelectBook/hooks/.gitkeep b/src/SelectBook/hooks/.gitkeep
new file mode 100644
index 00000000..e69de29b
diff --git a/src/SelectBook/page/SelectBookPage/SelectBookPage.style.ts b/src/SelectBook/page/SelectBookPage/SelectBookPage.style.ts
new file mode 100644
index 00000000..15778218
--- /dev/null
+++ b/src/SelectBook/page/SelectBookPage/SelectBookPage.style.ts
@@ -0,0 +1,69 @@
+import styled from '@emotion/styled';
+
+import { ImgEvent } from '../../../assets';
+
+export const SelectBookPageWrapper = styled.div`
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+
+ width: 100vw;
+ height: 100dvh;
+`;
+
+export const SelectBookPageBodyWrapper = styled.div`
+ display: flex;
+ justify-content: space-between;
+ flex-direction: column;
+
+ width: 100%;
+ height: calc(100vh - 5.4rem);
+ padding: 0 1.6rem;
+ margin-top: 5.4rem;
+`;
+
+export const SelectBookContainer = styled.div<{
+ isClickedSelectButton: boolean;
+}>`
+ width: 100%;
+ margin-top: ${({ isClickedSelectButton }) =>
+ isClickedSelectButton ? '3.6rem' : '5.4rem'};
+`;
+
+export const SectionTitle = styled.p`
+ color: ${({ theme }) => theme.colors.BG};
+ ${({ theme }) => theme.fonts.Head2_SB_18};
+`;
+
+export const SectionOrangeTitle = styled.p`
+ color: ${({ theme }) => theme.colors.key};
+ ${({ theme }) => theme.fonts.Head2_SB_18};
+`;
+
+export const BookTypeContainerWrapper = styled.div<{
+ isClickedSelectButton: boolean;
+}>`
+ display: flex;
+ justify-content: center;
+
+ width: 100%;
+ margin-top: ${({ isClickedSelectButton }) =>
+ isClickedSelectButton ? '3.3rem' : '4rem'};
+`;
+
+export const BookTypeContainer = styled.div`
+ display: flex;
+ justify-content: space-between;
+ position: relative;
+
+ width: 34.3rem;
+`;
+
+export const StyledImgEvent = styled(ImgEvent)`
+ position: absolute;
+ top: -3.5rem;
+ right: 1.1rem;
+ z-index: 5;
+
+ transition: width 0.5s ease;
+`;
diff --git a/src/SelectBook/page/SelectBookPage/index.tsx b/src/SelectBook/page/SelectBookPage/index.tsx
new file mode 100644
index 00000000..be8e5f4b
--- /dev/null
+++ b/src/SelectBook/page/SelectBookPage/index.tsx
@@ -0,0 +1,91 @@
+import { useState } from 'react';
+
+import { ImgBookBackgray, ImgBookOrange } from '../../../assets';
+import Header from '../../../components/common/Header';
+import BookTypeBox from '../../components/BookTypeBox';
+import CompleteButton from '../../components/CompleteButton';
+import MakeLecueBookButton from '../../components/MakeLecueBookButton';
+import * as S from './SelectBookPage.style';
+
+const basicLecueBookOptions = ['레큐노트 최대 100장', '텍스트 & 배경색 2종'];
+const premiumLecueBookOptions = [
+ '레큐노트 무제한',
+ '레큐노트 배경색 6종',
+ '스티커 꾸미기',
+];
+
+function SelectBookPage() {
+ const [selectedBox, setSelectedBox] = useState(0);
+ const [isClickedSelectButton, setIsClickedSelectButton] = useState(false);
+
+ const handleClickCompleteButton = () => {
+ setIsClickedSelectButton(true);
+ setSelectedBox(2);
+ };
+
+ const handleClickMakeLecueBookButton = () => {
+ // API 쏘기...
+ };
+
+ return (
+
+
+
+
+ {isClickedSelectButton ? (
+
+ 레큐는 이벤트 중!
+ 무료로 프리미엄 레큐북을 만들어요!
+
+ ) : (
+ 레큐북 타입 선택
+ )}
+
+
+ {isClickedSelectButton && }
+
+ setSelectedBox(selectedBox === 1 ? 0 : 1)
+ }
+ bookType={1}
+ bookTypeBoxTitle="베이직 레큐북"
+ bookTypeBoxImg={}
+ bookTypeBoxPrice={0}
+ selectedBox={selectedBox}
+ isClickedSelectButton={isClickedSelectButton}
+ bookTypeBoxOptionList={basicLecueBookOptions}
+ />
+
+ setSelectedBox(selectedBox === 2 ? 0 : 2)
+ }
+ bookType={2}
+ bookTypeBoxTitle="프리미엄 레큐북"
+ bookTypeBoxImg={}
+ bookTypeBoxPrice={990}
+ selectedBox={selectedBox}
+ isClickedSelectButton={isClickedSelectButton}
+ bookTypeBoxOptionList={premiumLecueBookOptions}
+ />
+
+
+
+ {isClickedSelectButton ? (
+
+ ) : (
+
+ )}
+
+
+ );
+}
+
+export default SelectBookPage;
diff --git a/src/assets/icon/ic_check.svg b/src/assets/icon/ic_check.svg
new file mode 100644
index 00000000..a3ed8914
--- /dev/null
+++ b/src/assets/icon/ic_check.svg
@@ -0,0 +1,3 @@
+
diff --git a/src/assets/img/img_book_backgray.svg b/src/assets/img/img_book_backgray.svg
new file mode 100644
index 00000000..d82a5411
--- /dev/null
+++ b/src/assets/img/img_book_backgray.svg
@@ -0,0 +1,14 @@
+
diff --git a/src/assets/img/img_book_orange.svg b/src/assets/img/img_book_orange.svg
new file mode 100644
index 00000000..47a21ab1
--- /dev/null
+++ b/src/assets/img/img_book_orange.svg
@@ -0,0 +1,14 @@
+
diff --git a/src/assets/img/img_book_orange_big.svg b/src/assets/img/img_book_orange_big.svg
new file mode 100644
index 00000000..d6846b0d
--- /dev/null
+++ b/src/assets/img/img_book_orange_big.svg
@@ -0,0 +1,14 @@
+
diff --git a/src/assets/img/img_event.svg b/src/assets/img/img_event.svg
new file mode 100644
index 00000000..ca64c4dd
--- /dev/null
+++ b/src/assets/img/img_event.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/assets/img/img_saleprice.svg b/src/assets/img/img_saleprice.svg
new file mode 100644
index 00000000..2c08d30d
--- /dev/null
+++ b/src/assets/img/img_saleprice.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/assets/index.ts b/src/assets/index.ts
index 21e013ed..788fb95c 100644
--- a/src/assets/index.ts
+++ b/src/assets/index.ts
@@ -9,6 +9,7 @@ import BtnKakaologin from './button/btn_kakaologin.svg?react';
import IcArrowLeftBlack from './icon/ic_arrow_left_black.svg?react';
import IcArrowLeftWhite from './icon/ic_arrow_left_white.svg?react';
import IcCamera from './icon/ic_camera.svg?react';
+import IcCheck from './icon/ic_check.svg?react';
import IcCrown from './icon/ic_crown.svg?react';
import IcDate from './icon/ic_date.svg?react';
import IcHome from './icon/ic_home.svg?react';
@@ -16,6 +17,10 @@ import IcNotice from './icon/ic_notice.svg?react';
import IcSharing from './icon/ic_sharing.svg?react';
import IcX from './icon/ic_x.svg?react';
import ImgBook from './img/img_book.svg?react';
+import ImgBookBackgray from './img/img_book_backgray.svg?react';
+import ImgBookOrange from './img/img_book_orange.svg?react';
+import ImgBookOrangeBig from './img/img_book_orange_big.svg?react';
+import ImgEvent from './img/img_event.svg?react';
import ImgKakao01 from './img/img_kakao_01.svg?react';
import ImgKakao02 from './img/img_kakao_02.svg?react';
import ImgKakao03 from './img/img_kakao_03.svg?react';
@@ -27,6 +32,7 @@ import ImgKakaoStarWhite from './img/img_kakao_star_white.svg?react';
import ImgLe from './img/img_le.svg?react';
import ImgLogoLecue from './img/img_logo_lecue.svg?react';
import ImgModalEx from './img/img_modal_ex.svg?react';
+import ImgSaleprice from './img/img_saleprice.svg?react';
import ImgSplashLogo from './img/img_splash_logo.svg?react';
import ImgStarOrangeLine from './img/img_star_orangeline.svg?react';
import ImgStarPosit from './img/img_star_postit.svg?react';
@@ -43,6 +49,7 @@ export {
IcArrowLeftBlack,
IcArrowLeftWhite,
IcCamera,
+ IcCheck,
IcCrown,
IcDate,
IcHome,
@@ -50,6 +57,10 @@ export {
IcSharing,
IcX,
ImgBook,
+ ImgBookBackgray,
+ ImgBookOrange,
+ ImgBookOrangeBig,
+ ImgEvent,
ImgKakao01,
ImgKakao02,
ImgKakao03,
@@ -61,6 +72,7 @@ export {
ImgLe,
ImgLogoLecue,
ImgModalEx,
+ ImgSaleprice,
ImgSplashLogo,
ImgStarOrangeLine,
ImgStarPosit,