diff --git a/.env b/.env deleted file mode 100644 index e69de29..0000000 diff --git a/.gitignore b/.gitignore index c4ba8ad..3d91322 100644 --- a/.gitignore +++ b/.gitignore @@ -26,6 +26,7 @@ dist-ssr #각자 알아서 env 파일 만들고 관리하기 ! .env +.yarn/install-state.gz ### yarn ### # used Zero-Install diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz deleted file mode 100644 index 4fc8e2c..0000000 Binary files a/.yarn/install-state.gz and /dev/null differ diff --git a/package.json b/package.json index 86c52e1..eebfa80 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "dependencies": { "@emotion/react": "^11.13.3", "@emotion/styled": "^11.13.0", + "axios": "^1.7.8", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.28.0" diff --git a/public/svgs/ic_right_v.svg b/public/svgs/ic_right_v.svg new file mode 100644 index 0000000..762a666 --- /dev/null +++ b/public/svgs/ic_right_v.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/App.tsx b/src/App.tsx index 9e0ca7a..0e05089 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -10,7 +10,7 @@ const router = createBrowserRouter([ element: , children: [ { - path: '/main', + path: '/', element:
, }, { diff --git a/src/apis/apis.ts b/src/apis/apis.ts index 56b1487..19d8f93 100644 --- a/src/apis/apis.ts +++ b/src/apis/apis.ts @@ -1 +1,6 @@ +import axios from 'axios'; + //예시 +export const instance = axios.create({ + baseURL: import.meta.env.VITE_API_BASE_URL, +}); diff --git a/src/assets/svgs/IcAdd.tsx b/src/assets/svgs/IcAdd.tsx index 5366943..04b6649 100644 --- a/src/assets/svgs/IcAdd.tsx +++ b/src/assets/svgs/IcAdd.tsx @@ -1,3 +1,4 @@ +import * as React from 'react'; import type { SVGProps } from 'react'; const SvgIcAdd = (props: SVGProps) => ( ) => ( ) => ( ) => ( ) => ( + + + +); +export default SvgIcRightV; diff --git a/src/assets/svgs/index.ts b/src/assets/svgs/index.ts index ef0d7de..596063e 100644 --- a/src/assets/svgs/index.ts +++ b/src/assets/svgs/index.ts @@ -1,5 +1,26 @@ +export { default as AladinLogo } from './AladinLogo'; export { default as BtnFFloating } from './BtnFFloating'; +export { default as BtnFloating } from './BtnFloating'; +export { default as Hihi } from './Hihi'; +export { default as HomeSection2Indicator } from './HomeSection2Indicator'; +export { default as IcAdd } from './IcAdd'; +export { default as IcArrowSaleBefore } from './IcArrowSaleBefore'; +export { default as IcCheckbox } from './IcCheckbox'; +export { default as IcChevronSmallRight } from './IcChevronSmallRight'; +export { default as IcLocation } from './IcLocation'; +export { default as IcMenuSmallGray } from './IcMenuSmallGray'; +export { default as IcMypageGray } from './IcMypageGray'; +export { default as IcPick } from './IcPick'; +export { default as IcRemove } from './IcRemove'; export { default as IcRightarrowMediumTextgray40 } from './IcRightarrowMediumTextgray40'; +export { default as IcRightarrowSmall } from './IcRightarrowSmall'; +export { default as IcRightV } from './IcRightV'; +export { default as IcSearch } from './IcSearch'; +export { default as IcShoppingcartGray } from './IcShoppingcartGray'; +export { default as Img11 } from './Img11'; +export { default as Img12 } from './Img12'; +export { default as Img13 } from './Img13'; +export { default as Img14 } from './Img14'; export { default as Img61 } from './Img61'; export { default as Img62 } from './Img62'; export { default as Img63 } from './Img63'; @@ -9,25 +30,12 @@ export { default as Img66 } from './Img66'; export { default as Img67 } from './Img67'; export { default as Img68 } from './Img68'; export { default as Img69 } from './Img69'; -export { default as AladinLogo } from './AladinLogo'; -export { default as BtnFloating } from './BtnFloating'; -export { default as Hihi } from './Hihi'; -export { default as IcArrowSaleBefore } from './IcArrowSaleBefore'; -export { default as IcRightarrowSmall } from './IcRightarrowSmall'; -export { default as Img11 } from './Img11'; -export { default as Img12 } from './Img12'; -export { default as Img13 } from './Img13'; -export { default as Img14 } from './Img14'; +export { default as Img71 } from './Img71'; +export { default as Img72 } from './Img72'; +export { default as Img73 } from './Img73'; +export { default as Img74 } from './Img74'; +export { default as Img75 } from './Img75'; export { default as Playno } from './Playno'; export { default as Playyes } from './Playyes'; -export { default as IcChevronSmallRight } from './IcChevronSmallRight'; -export { default as IcMenuSmallGray } from './IcMenuSmallGray'; -export { default as IcMypageGray } from './IcMypageGray'; -export { default as IcSearch } from './IcSearch'; -export { default as IcShoppingcartGray } from './IcShoppingcartGray'; export { default as SerachUnder } from './SerachUnder'; export { default as XGroup2 } from './XGroup2'; -export { default as IcAdd } from './IcAdd'; -export { default as IcCheckbox } from './IcCheckbox'; -export { default as IcLocation } from './IcLocation'; -export { default as IcRemove } from './IcRemove'; diff --git a/src/components/Footer/Footer.styled.ts b/src/components/Footer/Footer.styled.ts new file mode 100644 index 0000000..7ea5dec --- /dev/null +++ b/src/components/Footer/Footer.styled.ts @@ -0,0 +1,165 @@ +import styled from '@emotion/styled'; + +export const Wrapper = styled.div` + display: flex; + justify-content: center; +`; + +export const FooterWrapper = styled.footer` + display: flex; + width: 136.7rem; + padding-bottom: 5rem; + flex-direction: column; + align-items: center; + gap: 3.6rem; + + background: ${({ theme }) => theme.colors.white}; +`; + +export const FooterTop = styled.div` + display: flex; + width: 100%; + height: 6.2rem; + flex-direction: row; + justify-content: center; + align-items: center; + align-self: stretch; + gap: 2.6rem; + + border-top: 1px solid ${({ theme }) => theme.colors.stroke_gray10}; + border-bottom: 1px solid ${({ theme }) => theme.colors.stroke_gray10}; +`; + +export const FooterTopContent = styled.div<{ $isBold: boolean }>` + display: flex; + height: 1.8rem; + + color: ${({ theme }) => theme.colors.text_gray40}; + ${({ theme, $isBold }) => + $isBold ? theme.fonts.body5_b_13 : theme.fonts.body5_r_13}; + + align-items: center; +`; + +export const FooterBottomWrapper = styled.div` + display: flex; + justify-content: center; + align-items: flex-start; + gap: 0.3rem; + align-self: stretch; + + width: 100%; + height: 15.5rem; +`; + +export const LeftLayout = styled.div` + display: flex; + width: 71rem; + padding-bottom: 3rem; + flex-direction: column; + align-items: flex-start; + gap: 1.5rem; + + background-color: ${({ theme }) => theme.colors.white}; +`; + +export const LeftTitle = styled.div` + align-self: stretch; + + color: ${({ theme }) => theme.colors.text_gray40}; + ${({ theme }) => theme.fonts.title2_b_17}; +`; + +export const LeftContent = styled.div` + display: flex; + padding-bottom: 2rem; + align-items: center; + align-content: center; + align-self: stretch; + flex-wrap: wrap; + max-width: 55rem; +`; + +export const LeftSmallText = styled.span<{ $isHolder?: boolean }>` + display: flex; + padding: 0 1.8rem 0.5rem 0; + justify-content: center; + align-items: center; + gap: ${({ $isHolder }) => ($isHolder ? '0.5rem' : '1rem')}; + + ${({ theme }) => theme.fonts.body7_r_12}; +`; + +export const RightLayout = styled.div` + display: flex; + width: 32rem; + flex-direction: column; + align-items: flex-start; + gap: 0.9rem; +`; + +export const RightTitle = styled.div` + align-self: stretch; + + color: ${({ theme }) => theme.colors.text_gray40}; + ${({ theme }) => theme.fonts.title2_b_17}; +`; + +export const RightContent = styled.div` + display: flex; + padding: 0 0.8rem 0.5rem 0; + align-items: center; + gap: 1rem; + align-self: stretch; + + color: ${({ theme }) => theme.colors.text_gray30}; + ${({ theme }) => theme.fonts.body7_r_12}; +`; + +export const RightBottomBox = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 2rem; + align-self: stretch; +`; + +export const BtnWrapper = styled.div` + display: flex; + align-items: center; + gap: 0.6rem; + align-self: stretch; +`; + +export const Btn = styled.button` + display: flex; + width: 15.7rem; + height: 3.6rem; + padding: 0.7rem 3.7rem; + justify-content: center; + align-items: center; + gap: 1rem; + + border-radius: 0.4rem; + border: 1px solid ${({ theme }) => theme.colors.stroke_gray30}; + background: ${({ theme }) => theme.colors.white}; + + color: ${({ theme }) => theme.colors.text_gray40}; + ${({ theme }) => theme.fonts.body5_r_13}; +`; + +export const LongBtn = styled.button` + display: flex; + height: 36px; + padding: 7px 37px; + justify-content: center; + align-items: center; + align-self: stretch; + + border-radius: 4px; + border: 1px solid ${({ theme }) => theme.colors.stroke_gray30}; + background: ${({ theme }) => theme.colors.white}; + + color: ${({ theme }) => theme.colors.text_gray40}; + ${({ theme }) => theme.fonts.body5_r_13}; +`; diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx new file mode 100644 index 0000000..8e1de72 --- /dev/null +++ b/src/components/Footer/Footer.tsx @@ -0,0 +1,78 @@ +import { IcLocation, IcRightV } from '@assets/svgs'; +import * as S from './Footer.styled'; + +const Footer = () => { + const handleClickBtn = () => { + alert('이스터에그 발견!'); + }; + + return ( + + + + 회사소개 + 채용안내 + 이용약관 + + 개인정보처리방침 + + + 청소년 보호정책 + + 중고매장 + + 제휴,마케팅 안내 + + 판매자 매니저 + + 출판사,공급사 안내 + + 광고 안내 + + 학교,기업,기관 대량구매 + + + + + + (주)알라딘커뮤니케이션 + + 대표이사 최우영 + 고객정보보호 책임자 최우영 + + 사업자등록 201-81-23094 + + 통신판매업신고 중구01520호 + 이메일 privacy@aladin.co.kr + + 호스팅 제공자 알라딘커뮤니케이션 + + + (본사) 서울시 중구 서소문로 89-31 + + + © Aladin Communication. All Rights Reserved. + + + + + 고객센터 1544-2514 (발신자 부담) + + 서울시 마포구 백범로 71 숨도빌딩 7층 Fax 02-6926-2600 + + + 1:1 문의 + FAQ + + + + 중고매장 위치, 영업시간 안내 + + + + + + ); +}; + +export default Footer; diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index fca6178..7acfe75 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import * as S from './Header.styled'; import { AladinLogo, @@ -11,11 +11,52 @@ import { } from '@assets/svgs'; import { SerachUnder } from '@assets/svgs'; import { useNavigate } from 'react-router-dom'; -import { HEADER_MENU } from '@constants/headerMenuConstant'; +import { instance } from '@apis/apis'; + +type Categories = { + domesticBooks: string[]; + foreignBooks: string[]; + eBooks: string[]; + onlineCourses: string[]; + music: string[]; + blueRay: string[]; + aladinGoods: string[]; +}; + +type ResponseData = { + data: { + categories: Categories; + boldCategories: string[]; + }; +}; + +type ApiResponse = { + code: number; + message: string; + data: ResponseData; +}; const Header = () => { const navigate = useNavigate(); const [isShow, setIsShow] = useState(false); + const [headerMenuCategories, setHeaderMenuCategories] = + useState(); + const [boldCategories, setBoldCategories] = useState>( + new Set(...[]), + ); + + useEffect(() => { + const fetchHeaderData = async () => { + try { + const response: ApiResponse = await instance.get('/api/v1/categories'); + setHeaderMenuCategories(response.data.data.categories); + setBoldCategories(new Set(response.data.data.boldCategories)); + } catch (e) { + console.log(e); + } + }; + fetchHeaderData(); + }, []); return ( @@ -125,8 +166,13 @@ const Header = () => { 국내도서 - {HEADER_MENU.categories.domesticBooks.map((cate) => ( - {cate} + {headerMenuCategories?.domesticBooks.map((cate, idx) => ( + + {cate} + ))} @@ -135,8 +181,13 @@ const Header = () => { 알라딘 굿즈 - {HEADER_MENU.categories.aladinGoods.map((cate) => ( - {cate} + {headerMenuCategories?.aladinGoods.map((cate, idx) => ( + + {cate} + ))} @@ -146,8 +197,13 @@ const Header = () => { 외국도서 - {HEADER_MENU.categories.foreignBooks.map((cate) => ( - {cate} + {headerMenuCategories?.foreignBooks.map((cate, idx) => ( + + {cate} + ))} @@ -157,8 +213,13 @@ const Header = () => { eBook - {HEADER_MENU.categories.eBooks.map((cate) => ( - {cate} + {headerMenuCategories?.eBooks.map((cate, idx) => ( + + {cate} + ))} @@ -170,8 +231,13 @@ const Header = () => { 온라인중고 - {HEADER_MENU.categories.onlineCourses.map((cate) => ( - {cate} + {headerMenuCategories?.onlineCourses.map((cate, idx) => ( + + {cate} + ))} @@ -181,16 +247,26 @@ const Header = () => { 음반 - {HEADER_MENU.categories.music.map((cate) => ( - {cate} + {headerMenuCategories?.music.map((cate, idx) => ( + + {cate} + ))} 블루레이 - {HEADER_MENU.categories.bluRay.map((cate) => ( - {cate} + {headerMenuCategories?.blueRay.map((cate, idx) => ( + + {cate} + ))} diff --git a/src/pages/Layout/Layout.tsx b/src/pages/Layout/Layout.tsx index 39a50a2..3c7f025 100644 --- a/src/pages/Layout/Layout.tsx +++ b/src/pages/Layout/Layout.tsx @@ -2,12 +2,14 @@ import Header from '@components/Header/Header'; import * as S from './Layout.styled'; import { Outlet } from 'react-router-dom'; +import Footer from '@components/Footer/Footer'; const Layout = () => { return (
+
); }; diff --git a/yarn.lock b/yarn.lock index 102e42b..687e66f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -20,6 +20,7 @@ __metadata: "@typescript-eslint/parser": "npm:^7.2.0" "@vitejs/plugin-react": "npm:^4.2.1" "@vitejs/plugin-react-swc": "npm:^3.5.0" + axios: "npm:^1.7.8" eslint: "npm:^8.57.0" eslint-config-prettier: "npm:^9.1.0" eslint-plugin-prettier: "npm:^5.2.1" @@ -1835,6 +1836,13 @@ __metadata: languageName: node linkType: hard +"asynckit@npm:^0.4.0": + version: 0.4.0 + resolution: "asynckit@npm:0.4.0" + checksum: 10c0/d73e2ddf20c4eb9337e1b3df1a0f6159481050a5de457c55b14ea2e5cb6d90bb69e004c9af54737a5ee0917fcf2c9e25de67777bbe58261847846066ba75bc9d + languageName: node + linkType: hard + "available-typed-arrays@npm:^1.0.7": version: 1.0.7 resolution: "available-typed-arrays@npm:1.0.7" @@ -1844,6 +1852,17 @@ __metadata: languageName: node linkType: hard +"axios@npm:^1.7.8": + version: 1.7.8 + resolution: "axios@npm:1.7.8" + dependencies: + follow-redirects: "npm:^1.15.6" + form-data: "npm:^4.0.0" + proxy-from-env: "npm:^1.1.0" + checksum: 10c0/23ae2d0105aea9170c34ac9b6f30d9b2ab2fa8b1370205d2f7ce98b9f9510ab420148c13359ee837ea5a4bf2fb028ff225bd2fc92052fb0c478c6b4a836e2d5f + languageName: node + linkType: hard + "babel-plugin-macros@npm:^3.1.0": version: 3.1.0 resolution: "babel-plugin-macros@npm:3.1.0" @@ -2019,6 +2038,15 @@ __metadata: languageName: node linkType: hard +"combined-stream@npm:^1.0.8": + version: 1.0.8 + resolution: "combined-stream@npm:1.0.8" + dependencies: + delayed-stream: "npm:~1.0.0" + checksum: 10c0/0dbb829577e1b1e839fa82b40c07ffaf7de8a09b935cadd355a73652ae70a88b4320db322f6634a4ad93424292fa80973ac6480986247f1734a1137debf271d5 + languageName: node + linkType: hard + "commander@npm:^7.2.0": version: 7.2.0 resolution: "commander@npm:7.2.0" @@ -2282,6 +2310,13 @@ __metadata: languageName: node linkType: hard +"delayed-stream@npm:~1.0.0": + version: 1.0.0 + resolution: "delayed-stream@npm:1.0.0" + checksum: 10c0/d758899da03392e6712f042bec80aa293bbe9e9ff1b2634baae6a360113e708b91326594c8a486d475c69d6259afb7efacdc3537bfcda1c6c648e390ce601b19 + languageName: node + linkType: hard + "dir-glob@npm:^3.0.1": version: 3.0.1 resolution: "dir-glob@npm:3.0.1" @@ -2986,6 +3021,16 @@ __metadata: languageName: node linkType: hard +"follow-redirects@npm:^1.15.6": + version: 1.15.9 + resolution: "follow-redirects@npm:1.15.9" + peerDependenciesMeta: + debug: + optional: true + checksum: 10c0/5829165bd112c3c0e82be6c15b1a58fa9dcfaede3b3c54697a82fe4a62dd5ae5e8222956b448d2f98e331525f05d00404aba7d696de9e761ef6e42fdc780244f + languageName: node + linkType: hard + "for-each@npm:^0.3.3": version: 0.3.3 resolution: "for-each@npm:0.3.3" @@ -3005,6 +3050,17 @@ __metadata: languageName: node linkType: hard +"form-data@npm:^4.0.0": + version: 4.0.1 + resolution: "form-data@npm:4.0.1" + dependencies: + asynckit: "npm:^0.4.0" + combined-stream: "npm:^1.0.8" + mime-types: "npm:^2.1.12" + checksum: 10c0/bb102d570be8592c23f4ea72d7df9daa50c7792eb0cf1c5d7e506c1706e7426a4e4ae48a35b109e91c85f1c0ec63774a21ae252b66f4eb981cb8efef7d0463c8 + languageName: node + linkType: hard + "fs-minipass@npm:^2.0.0": version: 2.1.0 resolution: "fs-minipass@npm:2.1.0" @@ -4026,6 +4082,22 @@ __metadata: languageName: node linkType: hard +"mime-db@npm:1.52.0": + version: 1.52.0 + resolution: "mime-db@npm:1.52.0" + checksum: 10c0/0557a01deebf45ac5f5777fe7740b2a5c309c6d62d40ceab4e23da9f821899ce7a900b7ac8157d4548ddbb7beffe9abc621250e6d182b0397ec7f10c7b91a5aa + languageName: node + linkType: hard + +"mime-types@npm:^2.1.12": + version: 2.1.35 + resolution: "mime-types@npm:2.1.35" + dependencies: + mime-db: "npm:1.52.0" + checksum: 10c0/82fb07ec56d8ff1fc999a84f2f217aa46cb6ed1033fefaabd5785b9a974ed225c90dc72fff460259e66b95b73648596dbcc50d51ed69cdf464af2d237d3149b2 + languageName: node + linkType: hard + "minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" @@ -4610,6 +4682,13 @@ __metadata: languageName: node linkType: hard +"proxy-from-env@npm:^1.1.0": + version: 1.1.0 + resolution: "proxy-from-env@npm:1.1.0" + checksum: 10c0/fe7dd8b1bdbbbea18d1459107729c3e4a2243ca870d26d34c2c1bcd3e4425b7bcc5112362df2d93cc7fb9746f6142b5e272fd1cc5c86ddf8580175186f6ad42b + languageName: node + linkType: hard + "punycode@npm:^2.1.0": version: 2.3.1 resolution: "punycode@npm:2.3.1"