diff --git a/.gitmessage.txt b/.gitmessage.txt
new file mode 100644
index 00000000..94c20c7e
--- /dev/null
+++ b/.gitmessage.txt
@@ -0,0 +1,25 @@
+[Type] title
+
+# [Type] 입력 목록
+# 1. Feat: 새로운 기능 추가
+# 2. Fix: 오류 해결
+# 3. Rename: 파일 혹은 폴더명을 수정만 한 경우
+# 4. Remove: 파일을 삭제만 한 경우
+# 5. Style: 기능 수정 없이 코드 스타일만 변경한 경우 (코드 포매팅, 세미콜론 누락 등)
+# 6. Design: 사용자 UI 디자인 변경 (CSS 등)
+# 7. Refactor: 코드 베이스의 특정 부분을 재정렬 (Refactoring)
+# 8. Test: 테스트와 관련된 모든 것
+# 9. Docs: 문서화에 관한 모든 것
+# 10. Chore: 빌드 업무 수정, 패키지 매니저 수정 (gitignore 수정 등)
+# 11. Perf: 성능 개선
+#
+# [Title] 규칙
+# 1. 50자 이내 짧은 요약 (영어의 경우 첫글자는 대문자로)
+# 2. 명령형으로 작성 (과거형X)
+# 3. 제목 끝에 .(마침표) 금지
+#
+# [Body] 작성 규칙
+# 1. 제목과 본문 사이 빈 칸 한줄 필수 (제목과 본문 분리)
+# 2. 생략 가능, 필요 시 자세한 설명 작성 (72자 내외로 마무리)
+# 3. 적용한 변경사항과 그것을 만든 이유에 대해 설명
+# - 어떻게보다는 "무엇을", "왜"
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..aed4b0cb
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "cSpell.words": ["inputwidth"]
+}
diff --git a/README.md b/README.md
index 58beeacc..9b8ede35 100644
--- a/README.md
+++ b/README.md
@@ -1,70 +1,2 @@
-# Getting Started with Create React App
-
-This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
-
-## Available Scripts
-
-In the project directory, you can run:
-
-### `npm start`
-
-Runs the app in the development mode.\
-Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
-
-The page will reload when you make changes.\
-You may also see any lint errors in the console.
-
-### `npm test`
-
-Launches the test runner in the interactive watch mode.\
-See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
-
-### `npm run build`
-
-Builds the app for production to the `build` folder.\
-It correctly bundles React in production mode and optimizes the build for the best performance.
-
-The build is minified and the filenames include the hashes.\
-Your app is ready to be deployed!
-
-See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
-
-### `npm run eject`
-
-**Note: this is a one-way operation. Once you `eject`, you can't go back!**
-
-If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
-
-Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
-
-You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
-
-## Learn More
-
-You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
-
-To learn React, check out the [React documentation](https://reactjs.org/).
-
-### Code Splitting
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
-
-### Analyzing the Bundle Size
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
-
-### Making a Progressive Web App
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
-
-### Advanced Configuration
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
-
-### Deployment
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
-
-### `npm run build` fails to minify
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
+13기 프론트엔드 개인 스프린트 미션4
+제출일 12월 3일
diff --git a/faq.html b/faq.html
new file mode 100644
index 00000000..2c9486f5
--- /dev/null
+++ b/faq.html
@@ -0,0 +1,7 @@
+
+
+
+
+ faq 페이지
+
+
diff --git a/img/.DS_Store b/img/.DS_Store
new file mode 100644
index 00000000..276786cb
Binary files /dev/null and b/img/.DS_Store differ
diff --git a/img/OG_img.svg b/img/OG_img.svg
new file mode 100644
index 00000000..b4b8d797
--- /dev/null
+++ b/img/OG_img.svg
@@ -0,0 +1,3 @@
+
-
+
+
+
+
+
);
}
diff --git a/src/App.test.js b/src/App.test.js
deleted file mode 100644
index 1f03afee..00000000
--- a/src/App.test.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import { render, screen } from '@testing-library/react';
-import App from './App';
-
-test('renders learn react link', () => {
- render(
);
- const linkElement = screen.getByText(/learn react/i);
- expect(linkElement).toBeInTheDocument();
-});
diff --git a/src/Hooks/useWindowSize.js b/src/Hooks/useWindowSize.js
new file mode 100644
index 00000000..23c8426f
--- /dev/null
+++ b/src/Hooks/useWindowSize.js
@@ -0,0 +1,25 @@
+import { useState, useEffect } from "react";
+
+const useWindowSize = () => {
+ const [deviceType, setDeviceType] = useState("desktop");
+ const handleResize = () => {
+ if (window.matchMedia("(max-width: 767px)").matches) {
+ setDeviceType("mobile");
+ } else if (window.matchMedia("(max-width: 1199px)").matches) {
+ setDeviceType("tablet");
+ } else {
+ setDeviceType("desktop");
+ }
+ };
+
+ useEffect(() => {
+ handleResize();
+ window.addEventListener("resize", handleResize);
+ return () => {
+ window.removeEventListener("resize", handleResize);
+ };
+ }, []);
+ return deviceType;
+};
+
+export default useWindowSize;
diff --git a/src/api.js b/src/api.js
new file mode 100644
index 00000000..e8001b33
--- /dev/null
+++ b/src/api.js
@@ -0,0 +1,30 @@
+const BASE_URL = "https://panda-market-api.vercel.app";
+
+export async function getProducts({
+ device = "desktop",
+ page = 1,
+ selectedOrder = "최신순",
+}) {
+ const order = selectedOrder === "최신순" ? "recent" : "favorite";
+ const pageSize = device === "mobile" ? 4 : device === "tablet" ? 6 : 10;
+ const query = `?orderBy=${order}&page=${page}&pageSize=${pageSize}`;
+ const response = await fetch(`${BASE_URL}/products${query}`);
+
+ if (!response.ok) {
+ throw new Error("상품을 불러오지 못했습니다. 다시 시도해주세요");
+ }
+ const body = await response.json();
+ return body;
+}
+
+export async function bestProducts({ device }) {
+ const pageSize = device === "mobile" ? 1 : device === "tablet" ? 2 : 4;
+ const response = await fetch(
+ `${BASE_URL}/products?orderBy=favorite&pageSize=${pageSize}`
+ );
+ if (!response.ok) {
+ throw new Error("베스트 상품을 불러오지 못했습니다. 다시 시도해주세요");
+ }
+ const body = await response.json();
+ return body;
+}
diff --git a/src/assets/OG_img.svg b/src/assets/OG_img.svg
new file mode 100644
index 00000000..b4b8d797
--- /dev/null
+++ b/src/assets/OG_img.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/btn_sort.svg b/src/assets/btn_sort.svg
new file mode 100644
index 00000000..41751e7b
--- /dev/null
+++ b/src/assets/btn_sort.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/src/assets/favoriteLogo.svg b/src/assets/favoriteLogo.svg
new file mode 100644
index 00000000..282d802a
--- /dev/null
+++ b/src/assets/favoriteLogo.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/ic_google.svg b/src/assets/ic_google.svg
new file mode 100644
index 00000000..39de6337
--- /dev/null
+++ b/src/assets/ic_google.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/ic_kakao.svg b/src/assets/ic_kakao.svg
new file mode 100644
index 00000000..15dc4d0f
--- /dev/null
+++ b/src/assets/ic_kakao.svg
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/myLogo.svg b/src/assets/myLogo.svg
new file mode 100644
index 00000000..1b788296
--- /dev/null
+++ b/src/assets/myLogo.svg
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/panda_logo_img.svg b/src/assets/panda_logo_img.svg
new file mode 100644
index 00000000..e6529d0d
--- /dev/null
+++ b/src/assets/panda_logo_img.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/root_img/Img_home_01.svg b/src/assets/root_img/Img_home_01.svg
new file mode 100644
index 00000000..56aa0038
--- /dev/null
+++ b/src/assets/root_img/Img_home_01.svg
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/root_img/Img_home_02.svg b/src/assets/root_img/Img_home_02.svg
new file mode 100644
index 00000000..4137dc0b
--- /dev/null
+++ b/src/assets/root_img/Img_home_02.svg
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/root_img/Img_home_03.svg b/src/assets/root_img/Img_home_03.svg
new file mode 100644
index 00000000..93e003c3
--- /dev/null
+++ b/src/assets/root_img/Img_home_03.svg
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/root_img/home_bottom_img.svg b/src/assets/root_img/home_bottom_img.svg
new file mode 100644
index 00000000..8aac2a05
--- /dev/null
+++ b/src/assets/root_img/home_bottom_img.svg
@@ -0,0 +1,111 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/root_img/home_top_img.svg b/src/assets/root_img/home_top_img.svg
new file mode 100644
index 00000000..1b6c8523
--- /dev/null
+++ b/src/assets/root_img/home_top_img.svg
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/root_img/ic_facebook.svg b/src/assets/root_img/ic_facebook.svg
new file mode 100644
index 00000000..8491c2f8
--- /dev/null
+++ b/src/assets/root_img/ic_facebook.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/root_img/ic_instagram.svg b/src/assets/root_img/ic_instagram.svg
new file mode 100644
index 00000000..c83306f8
--- /dev/null
+++ b/src/assets/root_img/ic_instagram.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/root_img/ic_twitter.svg b/src/assets/root_img/ic_twitter.svg
new file mode 100644
index 00000000..14a6069a
--- /dev/null
+++ b/src/assets/root_img/ic_twitter.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/assets/root_img/ic_youtube.svg b/src/assets/root_img/ic_youtube.svg
new file mode 100644
index 00000000..8270b35a
--- /dev/null
+++ b/src/assets/root_img/ic_youtube.svg
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/root_img/textLogo.svg b/src/assets/root_img/textLogo.svg
new file mode 100644
index 00000000..010acd45
--- /dev/null
+++ b/src/assets/root_img/textLogo.svg
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/assets/textLogo.svg b/src/assets/textLogo.svg
new file mode 100644
index 00000000..ccdc9bcf
--- /dev/null
+++ b/src/assets/textLogo.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/components/ItemsList.js b/src/components/ItemsList.js
new file mode 100644
index 00000000..56e59ef1
--- /dev/null
+++ b/src/components/ItemsList.js
@@ -0,0 +1,145 @@
+import favoriteImg from "../assets/favoriteLogo.svg";
+import styled from "styled-components";
+import useWindowSize from "../Hooks/useWindowSize";
+//
+
+const ByDevice = {
+ best: {
+ mobile: {
+ gap: "none",
+ gridTemplate: "repeat(1, 343px)",
+ gridRow: "434px",
+ height: "343px",
+ ulWidth: "343px",
+ },
+ tablet: {
+ gap: "10px",
+ gridTemplate: "repeat(3, 343px)",
+ gridRow: "434px",
+ height: "343px",
+ ulWidth: "696px",
+ },
+ desktop: {
+ gap: "24px",
+ gridTemplate: "repeat(4, 282px)",
+ gridRow: "378px",
+ height: "282px",
+ ulWidth: "1200px",
+ },
+ },
+ products: {
+ mobile: {
+ gap: "32px 8px",
+ gridTemplate: "repeat(2, 168px)",
+ gridRow: "343px",
+ height: "168px",
+ ulWidth: "343px",
+ },
+ tablet: {
+ gap: "40px 24px",
+ gridTemplate: "repeat(3, 221px)",
+ height: "221px",
+ ulWidth: "696px",
+ },
+ desktop: {
+ gap: "40px 24px",
+ gridTemplate: "repeat(5, 221px)",
+ height: "221px",
+ ulWidth: "1200px",
+ },
+ },
+};
+const Title = styled.h4`
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 24px;
+ text-align: left;
+ color: #1f2937;
+ margin: 0px;
+`;
+const Price = styled.div`
+ font-size: 16px;
+ font-weight: 700;
+ line-height: 26px;
+ text-align: left;
+ color: #1f2937;
+ margin-top: 6px;
+ margin-bottom: 6px;
+`;
+
+const FavoriteCount = styled.span`
+ color: #4b5563;'
+ font-size: 12px;
+ font-weight: 500;
+ line-height: 18px;
+ text-align: left;
+
+`;
+
+const ProductImg = styled.img`
+ width: 100%;
+ height: ${({ device, value }) => ByDevice[value][device].height || "auto"};
+`;
+
+const ItemListStyle = styled.ul`
+ margin: 24px auto;
+ padding: 0px;
+ width: ${({ device, value }) => ByDevice[value][device].ulWidth};
+ display: grid;
+ list-style: none;
+ gap: ${({ device, value }) => ByDevice[value][device].gap};
+ grid-template-columns: ${({ device, value }) =>
+ ByDevice[value][device].gridTemplate};
+ grid-auto-rows: ${({ value, device }) => ByDevice[value][device].gridRow};
+`;
+
+const Item = styled.div`
+ display: flex;
+ height: 317px;
+ flex-direction: column;
+ gap: 16px;
+`;
+
+//
+
+function ListItem({ value, items }) {
+ const device = useWindowSize();
+ return (
+
-
+
+
+
+
{items.name}
+
{items.price} 원
+
+
+
{items.favoriteCount}
+
+
+
+ );
+}
+function ItemsList({ value, items, device }) {
+ return (
+
+
+
+ {items.map((item) => {
+ return (
+
+
+
+ );
+ })}
+
+
+
+ );
+}
+
+export default ItemsList;
diff --git a/src/components/Main.js b/src/components/Main.js
new file mode 100644
index 00000000..20b27a9c
--- /dev/null
+++ b/src/components/Main.js
@@ -0,0 +1,44 @@
+import useWindowSize from "../Hooks/useWindowSize";
+import App from "../App";
+import HomePage from "../pages/HomePage";
+import AddItem from "../pages/AddItem";
+//
+import { Route, BrowserRouter, Routes } from "react-router-dom";
+import { createGlobalStyle } from "styled-components"; //import
+
+const GlobalStyle = createGlobalStyle`
+ * {
+ box-sizing: border-box;
+ }
+
+ body {
+ font-family: 'Pretendard', sans-serif;
+ font-display: swap;
+ }
+ img {
+ border-radius: 16px;
+ }
+ a {
+ text-decoration: none;
+ color: #ffffff;
+ }
+`;
+
+//
+function Main() {
+ const deviceType = useWindowSize();
+ return (
+ <>
+
+
+
+ }>
+ } />
+ } />
+
+
+
+ >
+ );
+}
+export default Main;
diff --git a/src/components/Nav.js b/src/components/Nav.js
new file mode 100644
index 00000000..06bd2bf5
--- /dev/null
+++ b/src/components/Nav.js
@@ -0,0 +1,90 @@
+import { Link, NavLink } from "react-router-dom";
+import Logo from "../assets/root_img/textLogo.svg";
+import myLogo from "../assets/myLogo.svg";
+import styled from "styled-components";
+import useWindowSize from "../Hooks/useWindowSize";
+import textLogo from "../assets/textLogo.svg";
+
+const PandaMarketLogo = styled.img`
+ width: 153px;
+ height: 51px;
+ margin-left: 200px;
+ cursor: pointer;
+ margin-left: 200px;
+ margin-left: ${({ $device }) => ($device === "desktop" ? "200px" : "15px")};
+`;
+
+const MobilePandaMarketLogo = styled.img`
+ width: 81px;
+ height: 27px;
+ margin-left: 15px;
+`;
+
+const activeLink = ({ isActive, $device }) => {
+ return {
+ color: isActive ? "#3692FF" : "#4b5563",
+ width: "108px",
+ padding: "21px 15px 21px 15px",
+ fontSize: "18px",
+ fontWeight: "700px",
+ gap: $device === "mobile" ? "8px" : "21px",
+ lineHeight: "26px",
+ textAlign: "center",
+ border: "none",
+ backgroundColor: "#ffffff",
+ };
+};
+const MyLogoButton = styled.img`
+ width: 40px;
+ height: 40px;
+ margin-right: ${({ $device }) => ($device === "desktop" ? "200px" : "15px")};
+`;
+
+const NavArea = styled.div`
+ position: fixed;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 70px;
+ display: flex;
+ justify-content: space-between;
+ flex-direction: row;
+ align-items: center;
+ background-color: #ffffff;
+`;
+
+const NavButtonLeft = styled.div`
+ display: flex;
+ align-items: center;
+ gap: ${({ $device }) => ($device === "mobile" ? "8px" : "21px")};
+`;
+function Nav() {
+ const device = useWindowSize();
+ return (
+
+
+
+ {device === "mobile" && (
+
+ )}
+ {device !== "mobile" && (
+
+ )}
+
+
+ 자유게시판
+
+
+ 중고마켓
+
+
+
+
+
+
+
+
+ );
+}
+
+export default Nav;
diff --git a/src/components/SelectBox.js b/src/components/SelectBox.js
new file mode 100644
index 00000000..aed0ea76
--- /dev/null
+++ b/src/components/SelectBox.js
@@ -0,0 +1,75 @@
+import Select from "react-select";
+import SelectImg from "../assets/btn_sort.svg";
+import useWindowSize from "../Hooks/useWindowSize";
+import styled from "styled-components";
+
+//
+const CustomSelectWrapper = styled.div`
+ width: ${({ device }) => (device !== "mobile" ? "130px" : "42px")};
+ height: 42px;
+ order: ${({ device }) => (device === "mobile" ? 3 : 4)};
+ padding: "0px 0px";
+ border-radius: 12px;
+`;
+const customStyles = () => ({
+ control: (styles) => ({
+ ...styles,
+ padding: "0px 0px",
+ width: `${({ device }) => (device !== "mobile" ? "130px" : "42px")}`,
+ backgroundColor: "#ffffff",
+ border: "none",
+ }),
+ valueContainer: (styles) => ({
+ ...styles,
+ width: "100%",
+ padding: "0px 0px",
+ }),
+ indicatorsContainer: (styles) => ({
+ ...styles,
+ display: "none",
+ }),
+ menu: (styles) => ({
+ ...styles,
+ borderRadius: "14px",
+ padding: "0px 0px",
+ }),
+ option: (styles) => ({
+ ...styles,
+ backgroundColor: "#ffffff",
+ color: "#1F2937",
+ width: "130px",
+ padding: "0px 0px",
+ }),
+ placeholder: (styles) => ({
+ ...styles,
+ textAlign: "center",
+ padding: "0px 0px",
+ backgroundImage: `url(${SelectImg}) no-repeat center/cover`,
+ }),
+});
+
+const options = [
+ { value: "recent", label: "최신순" },
+
+ { value: "favorite", label: "좋아요" },
+];
+function SelectBox({ value, onChange }) {
+ const device = useWindowSize();
+
+ return (
+
+ null }}
+ value={value}
+ onChange={onChange}
+ styles={customStyles}
+ options={options}
+ isSearchable={false}
+ placeholder={
+ device !== "mobile" ? value :
+ }
+ >
+
+ );
+}
+export default SelectBox;
diff --git a/src/components/pageCount.js b/src/components/pageCount.js
new file mode 100644
index 00000000..2d1ab579
--- /dev/null
+++ b/src/components/pageCount.js
@@ -0,0 +1,61 @@
+import styled from "styled-components";
+
+const PageBtn = styled.div`
+ display: flex;
+ gap: 4px;
+ margin: 43px auto 58px;
+ text-align: center;
+ width: 304px;
+`;
+
+const Btn = styled.button`
+ width: 40px;
+ height: 40px;
+ border-radius: 40px;
+ border: 1px solid #e5e7eb;
+ opacity: 0px;
+ font-size: 16px;
+ font-weight: 600;
+ line-height: 26px;
+ background-color: ${({ page, value }) =>
+ page === value ? "#2f80ed" : "#ffffff"};
+ color: ${({ page, value }) => (page === value ? "#f9fafb" : "#6b7280")};
+
+ &:active {
+ background-color: #2f80ed;
+ color: #f9fafb;
+ }
+
+ &:hover {
+ background-color: #2f80ed;
+ color: #f9fafb;
+ }
+`;
+
+export function PageButton({ page, value, onClick }) {
+ return (
+
+ {value}
+
+ );
+}
+function PageCount({ page, onClick }) {
+ const BtnArray = ["<", 1, 2, 3, 4, 5, ">"];
+ const handleClickBtn = (e) => {
+ const currentPage = e.target.value;
+ onClick(currentPage);
+ };
+
+ return (
+
+ {BtnArray.map((btn) => {
+ return (
+
+
+
+ );
+ })}
+
+ );
+}
+export default PageCount;
diff --git a/src/index.css b/src/index.css
deleted file mode 100644
index ec2585e8..00000000
--- a/src/index.css
+++ /dev/null
@@ -1,13 +0,0 @@
-body {
- margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
- sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-
-code {
- font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
- monospace;
-}
diff --git a/src/index.js b/src/index.js
index d563c0fb..b1170bcf 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,17 +1,6 @@
-import React from 'react';
-import ReactDOM from 'react-dom/client';
-import './index.css';
-import App from './App';
-import reportWebVitals from './reportWebVitals';
+import React from "react";
+import ReactDOM from "react-dom/client";
+import Main from "./components/Main";
-const root = ReactDOM.createRoot(document.getElementById('root'));
-root.render(
-
-
-
-);
-
-// If you want to start measuring performance in your app, pass a function
-// to log results (for example: reportWebVitals(console.log))
-// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
-reportWebVitals();
+const root = ReactDOM.createRoot(document.getElementById("root"));
+root.render(
);
diff --git a/src/login.js b/src/login.js
new file mode 100644
index 00000000..5d6e45e4
--- /dev/null
+++ b/src/login.js
@@ -0,0 +1,105 @@
+const Email = document.querySelector("#user_email");
+const password = document.querySelector("#login_password");
+const Error_message = document.querySelectorAll(".error_message");
+const Btn = document.querySelector("#Btn");
+const eyes = document.querySelector("i");
+const Input = document.querySelectorAll(".input_area");
+
+const pattern = /^[A-Za-z0-9_\.\-]+@[A-Za-z0-9\-]+\.[A-za-z0-9\-]+/;
+
+document.addEventListener("DOMContentLoaded", () => {
+ Button_inactive();
+}); //초기 Button 상태 설정
+
+Btn.addEventListener("click", () => {
+ if (!Btn.disabled) {
+ location.href = "./items.html";
+ }
+});
+
+//이메일 유효성 검사 함수
+function email_check(email) {
+ return pattern.test(email);
+}
+//비밀번호 8자리 이상 체크 함수
+function password_checked(password) {
+ return password.length > 7;
+}
+
+//a태그 존재시 삭제
+function tag_delete(i) {
+ let isTag = Error_message[i].querySelector("a");
+ if (isTag) {
+ Error_message[i].lastChild.remove();
+ }
+}
+
+function Email_focus_out(e) {
+ let input = e.target.value;
+ tag_delete(0);
+ if (!email_check(input)) {
+ e.target.classList.add("input_red_border");
+ const text = document.createElement("a");
+ if (input == "") {
+ text.textContent = "이메일을 입력해주세요";
+ Error_message[0].prepend(text);
+ } else {
+ text.textContent = "잘못된 이메일 형식 입니다.";
+ Error_message[0].prepend(text);
+ }
+ } else {
+ e.target.classList.remove("input_red_border");
+ }
+}
+
+//비밀번호 함수
+function Password_focus_out(e, x) {
+ let input = e.target.value;
+ tag_delete(x);
+ if (!password_checked(input)) {
+ e.target.classList.add("input_red_border");
+ const text = document.createElement("a");
+ text.textContent =
+ input === ""
+ ? "비밀번호를 입력해주세요"
+ : "비밀번호를 8자 이상 입력해주세요";
+ Error_message[x].prepend(text);
+ } else {
+ e.target.classList.remove("input_red_border");
+ }
+}
+
+//버튼 함수
+function Button_inactive(e) {
+ switch (email_check(Email.value) && password_checked(password.value)) {
+ case true:
+ Btn.disabled = false;
+
+ break;
+ case false:
+ Btn.disabled = true;
+
+ break;
+ }
+}
+//패스워드 숨김 핸들러 함수
+function Password_hide(e) {
+ if (password.type == "password") {
+ password.type = "text";
+ e.target.classList.remove("fa-eye-slash");
+ e.target.classList.add("fa-eye");
+ } else {
+ password.type = "password";
+ e.target.classList.remove("fa-eye");
+ e.target.classList.add("fa-eye-slash");
+ }
+}
+//이벤트 핸들러 등록
+password.addEventListener("focusout", Password_focus_out);
+Email.addEventListener("focusout", Email_focus_out);
+password.addEventListener("focusout", (e) => Password_focus_out(e, 1));
+eyes.addEventListener("click", Password_hide);
+
+Input.forEach((input) => {
+ input.addEventListener("change", Button_inactive);
+});
diff --git a/src/logo.svg b/src/logo.svg
deleted file mode 100644
index 9dfc1c05..00000000
--- a/src/logo.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/src/pages/AddItem.js b/src/pages/AddItem.js
new file mode 100644
index 00000000..973d569b
--- /dev/null
+++ b/src/pages/AddItem.js
@@ -0,0 +1,8 @@
+function AddItem() {
+ return (
+
+ );
+}
+export default AddItem;
diff --git a/src/pages/HomePage.js b/src/pages/HomePage.js
new file mode 100644
index 00000000..430da9e9
--- /dev/null
+++ b/src/pages/HomePage.js
@@ -0,0 +1,109 @@
+import { useEffect, useState } from "react";
+import ItemsList from "../components/ItemsList";
+import { getProducts, bestProducts } from "../api";
+import { Link } from "react-router-dom";
+import PageCount from "../components/pageCount";
+import styled from "styled-components";
+import useWindowSize from "../Hooks/useWindowSize";
+import SelectBox from "../components/SelectBox";
+
+//
+
+const Contents = styled.div`
+ width: ${({ device }) =>
+ device === "desktop" ? "1200px" : device === "tablet" ? "696px" : "344px"};
+ margin: 70px auto;
+`;
+const InputDiv = styled.div`
+ display: flex;
+ justify-content: space-between;
+ width: 100%;
+ margin: 0 auto;
+ flex-wrap: wrap;
+ gap: 12px;
+`;
+
+const SearchBtn = styled.button`
+ height: 42px;
+ padding: 12px 23px;
+ border-radius: 8px;
+ color: #f3f4f6;
+ background-color: #3692ff;
+ border: none;
+ font-size: 16px;
+ font-weight: 600;
+ line-height: 26px;
+ order: ${({ device }) => (device === "mobile" ? 1 : "auto")};
+`;
+
+const InputForm = styled.input`
+ width: ${({ device }) =>
+ device === "desktop" ? "325px" : device === "tablet" ? "242px" : "288px"};
+ height: 42px;
+ padding: 9px 20px 9px 16px;
+ border-radius: 12px;
+ border: none;
+ background-color: #f3f4f6;
+ color: #9ca3af;
+ font-size: 16px;
+ font-weight: 400;
+ line-height: 26px;
+ text-align: left;
+ order: ${({ device }) => (device === "mobile" ? 2 : "auto")};
+ margin-left: ${({ device }) =>
+ device === "desktop" ? "500px" : device === "tablet" ? "80px" : "0px"};
+`;
+
+//
+function HomePage() {
+ const [items, setItems] = useState([]);
+ const [selectedOrder, setSelectedOrder] = useState("최신순");
+ const [bestItems, setBestItems] = useState([]);
+ const [page, setPage] = useState(1);
+ const device = useWindowSize();
+ //
+ const handleChangeSort = (selected) => {
+ const { label } = selected;
+ setSelectedOrder(label);
+ };
+
+ const handleLoad = async (options) => {
+ const { list: bestItems } = await bestProducts(options);
+ const { list } = await getProducts(options);
+ setItems(list);
+ setBestItems(bestItems);
+ };
+
+ const handleClickPageChange = (value) => {
+ setPage(Number(value));
+ };
+
+ useEffect(() => {
+ handleLoad({ selectedOrder, device, page });
+ }, [selectedOrder, page, device]);
+
+ return (
+
+
+
베스트 상품
+
+
+
+ 전체 상품
+
+
+ 상품 등록하기
+
+
+
+
+
+
+ );
+}
+
+export default HomePage;
diff --git a/src/pages/docs.js b/src/pages/docs.js
new file mode 100644
index 00000000..c9623e6b
--- /dev/null
+++ b/src/pages/docs.js
@@ -0,0 +1 @@
+export default docs;
diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js
deleted file mode 100644
index 5253d3ad..00000000
--- a/src/reportWebVitals.js
+++ /dev/null
@@ -1,13 +0,0 @@
-const reportWebVitals = onPerfEntry => {
- if (onPerfEntry && onPerfEntry instanceof Function) {
- import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
- getCLS(onPerfEntry);
- getFID(onPerfEntry);
- getFCP(onPerfEntry);
- getLCP(onPerfEntry);
- getTTFB(onPerfEntry);
- });
- }
-};
-
-export default reportWebVitals;
diff --git a/src/signup.js b/src/signup.js
new file mode 100644
index 00000000..5dbd068d
--- /dev/null
+++ b/src/signup.js
@@ -0,0 +1,171 @@
+const Email = document.querySelector("#user_email");
+const nickname = document.querySelector("#user_nickname");
+const password = document.querySelector("#password");
+const check_pass = document.querySelector("#password_correct");
+const Btn = document.querySelector("#Btn");
+const Error_message = document.querySelectorAll(".error_message");
+const Input = document.querySelectorAll(".input_area");
+const eyes = document.querySelectorAll("i");
+
+const pattern = /^[A-Za-z0-9_\.\-]+@[A-Za-z0-9\-]+\.[A-za-z0-9\-]+/;
+
+document.addEventListener("DOMContentLoaded", () => {
+ Btn.disabled = true;
+}); //초기 Button 상태 설정
+
+Btn.addEventListener("click", () => {
+ if (!Btn.disabled) {
+ location.href = "./signin.html";
+ }
+});
+
+//이메일 유효성 검사 함수
+function email_check(email) {
+ return pattern.test(email);
+}
+//비밀번호 8자리 이상 체크 함수
+function password_checked(password) {
+ return password.length > 7;
+}
+
+//a태그 존재시 삭제
+function tag_delete(i) {
+ let isTag = Error_message[i].querySelector("a");
+ if (isTag) {
+ Error_message[i].lastChild.remove();
+ }
+}
+
+//이메일 함수
+function Email_focus_out(e) {
+ let input = e.target.value;
+ tag_delete(0);
+ if (!email_check(input)) {
+ e.target.classList.add("input_red_border");
+ const text = document.createElement("a");
+ if (input == "") {
+ text.textContent = "이메일을 입력해주세요";
+ Error_message[0].prepend(text);
+ } else {
+ text.textContent = "잘못된 이메일 형식 입니다.";
+ Error_message[0].prepend(text);
+ }
+ } else {
+ e.target.classList.remove("input_red_border");
+ }
+}
+
+//닉네임 함수
+function Nickname_focus_out(e) {
+ tag_delete(1);
+ if (e.target.value == "") {
+ e.target.classList.add("input_red_border");
+ const text = document.createElement("a");
+ text.textContent = "닉네임을 입력해 주세요";
+ Error_message[1].append(text);
+ } else {
+ e.target.classList.remove("input_red_border");
+ }
+}
+
+//비밀번호 함수
+function Password_focus_out(e, x) {
+ let input = e.target.value;
+ tag_delete(x);
+ if (!password_checked(input)) {
+ e.target.classList.add("input_red_border");
+ const text = document.createElement("a");
+ text.textContent =
+ input === ""
+ ? "비밀번호를 입력해주세요"
+ : "비밀번호를 8자 이상 입력해주세요";
+ Error_message[x].prepend(text);
+ } else {
+ e.target.classList.remove("input_red_border");
+ }
+}
+
+//비밀번호 확인 함수
+function Password_correct(e, x) {
+ let input = e.target.value;
+ tag_delete(x);
+ if (input !== password.value) {
+ const text = document.createElement("a");
+ e.target.classList.add("input_red_border");
+ text.textContent = "비밀번호가 일치하지 않습니다..";
+ Error_message[x].append(text);
+ } else {
+ e.target.classList.remove("input_red_border");
+ }
+}
+
+//form에 값이 다 있는지 보는 함수
+function is_form_value() {
+ let array = [];
+ for (let i = 0; i < 4; i++) {
+ array.push(Boolean(Input[i].value));
+ }
+ return array.every((x) => x == true);
+}
+
+//에러 메시지가 없는지 보는 함수
+function is_error() {
+ let array = [];
+ for (let i = 0; i < 4; i++) {
+ let x = Boolean(Error_message[i].querySelector("a"));
+ array.push(x);
+ }
+ console.log(array);
+ return array.every((x) => x == false);
+}
+
+//패스워드 숨김 핸들러 함수
+function Password_hide(e) {
+ if (password.type == "password") {
+ password.type = "text";
+ e.target.classList.remove("fa-eye-slash");
+ e.target.classList.add("fa-eye");
+ } else {
+ password.type = "password";
+ e.target.classList.remove("fa-eye");
+ e.target.classList.add("fa-eye-slash");
+ }
+}
+
+//패스워드 확인 숨김 핸들러 함수
+
+function check_pass_hide(e) {
+ if (password.type == "password") {
+ check_pass.type = "text";
+ e.target.classList.remove("fa-eye-slash");
+ e.target.classList.add("fa-eye");
+ } else {
+ check_pass.type = "password";
+ e.target.classList.remove("fa-eye");
+ e.target.classList.add("fa-eye-slash");
+ }
+}
+//버튼 함수
+
+function Button_inactive(e) {
+ switch (is_form_value() && is_error()) {
+ case true:
+ Btn.disabled = false;
+ break;
+ case false:
+ Btn.disabled = true;
+ break;
+ }
+}
+
+//이벤트 핸들러 등록
+Email.addEventListener("focusout", Email_focus_out);
+nickname.addEventListener("focusout", Nickname_focus_out);
+password.addEventListener("focusout", (e) => Password_focus_out(e, 2));
+check_pass.addEventListener("keyup", (e) => Password_correct(e, 3));
+eyes[0].addEventListener("click", Password_hide);
+eyes[1].addEventListener("click", check_pass_hide);
+
+Input.forEach((input) => {
+ input.addEventListener("change", Button_inactive);
+});
diff --git a/src/test.js b/src/test.js
new file mode 100644
index 00000000..bc60018a
--- /dev/null
+++ b/src/test.js
@@ -0,0 +1,155 @@
+const Email = document.querySelector("#user_email");
+const nickname = document.querySelector("#user_nickname");
+const LoginPassword = document.querySelector("#login_password");
+const Password = document.querySelector("#password");
+const check_pass = document.querySelector("#password_correct");
+const eyes = document.querySelector("i");
+const Btn = document.querySelector("#Btn");
+const Error_message = document.querySelectorAll(".error_message");
+const Input = document.querySelectorAll(".input_area");
+
+import { email_check, password_checked, tag_delete } from "./utils";
+
+const pattern = /^[A-Za-z0-9_\.\-]+@[A-Za-z0-9\-]+\.[A-za-z0-9\-]+/;
+
+document.addEventListener("DOMContentLoaded", () => {
+ Button_inactive();
+}); //초기 Button 상태 설정
+
+Btn.addEventListener("click", () => {
+ if (!Btn.disabled) {
+ location.href = "./items.html";
+ }
+});
+
+//이메일 확인
+function Email_focus_out(e, i) {
+ let input = e.target.value;
+ tag_delete(i);
+ if (!email_check(input)) {
+ e.target.classList.add("input_red_border");
+ const text = document.createElement("a");
+ text.textContent =
+ input === "" ? "이메일을 입력해주세요" : "잘못된 이메일 형식 입니다.";
+ Error_message[i].prepend(text);
+ } else {
+ e.target.classList.remove("input_red_border");
+ }
+}
+
+//비밀번호
+function Password_focus_out(e, i) {
+ let input = e.target.value;
+ tag_delete(i);
+ if (input.length < 8) {
+ e.target.classList.add("input_red_border");
+ const text = document.createElement("a");
+ text.textContent =
+ input === ""
+ ? "비밀번호를 입력해주세요"
+ : "비밀번호를 8자 이상 입력해주세요";
+ Error_message[i].prepend(text);
+ } else {
+ e.target.classList.remove("input_red_border");
+ }
+}
+
+//닉네임 함수
+function Nickname_focus_out(e, i) {
+ tag_delete(i);
+ if (e.target.value == "") {
+ e.target.classList.add("input_red_border");
+ const text = document.createElement("a");
+ text.textContent = "닉네임을 입력해 주세요";
+ Error_message[i].append(text);
+ } else {
+ e.target.classList.remove("input_red_border");
+ }
+}
+
+//비밀번호 확인 함수
+function Password_correct(e, x) {
+ let input = e.target.value;
+ tag_delete(x);
+ if (input !== Password.value) {
+ const text = document.createElement("a");
+ e.target.classList.add("input_red_border");
+ text.textContent = "비밀번호가 일치하지 않습니다..";
+ Error_message[x].append(text);
+ } else {
+ e.target.classList.remove("input_red_border");
+ }
+}
+
+//패스워드 숨김 핸들러 함수
+function Password_hide(e, el) {
+ if (el.type == "password") {
+ el.type = "text";
+ e.target.classList.remove("fa-eye-slash");
+ e.target.classList.add("fa-eye");
+ } else {
+ el.type = "password";
+ e.target.classList.remove("fa-eye");
+ e.target.classList.add("fa-eye-slash");
+ }
+}
+
+//form에 값이 다 있는지 보는 함수
+function is_form_value() {
+ let array = [];
+ for (let i = 0; i < 4; i++) {
+ array.push(Boolean(Input[i].value));
+ }
+ return array.every((x) => x == true);
+}
+
+//에러 메시지가 없는지 보는 함수
+function is_error() {
+ let array = [];
+ for (let i = 0; i < 4; i++) {
+ let x = Boolean(Error_message[i].querySelector("a"));
+ array.push(x);
+ }
+ console.log(array);
+ return array.every((x) => x == false);
+}
+//버튼
+function Button_inactive(e, condition1, condition2) {
+ switch (condition1 && condition2) {
+ case true:
+ Btn.disabled = false;
+ break;
+ case false:
+ Btn.disabled = true;
+ break;
+ }
+}
+
+//이벤트 핸들러 등록--------------------------------------------------------//
+
+Email.addEventListener("focusout", (e) => Email_focus_out(e, 0)); //이메일은 두 페이지 모드 0번 인덱스
+LoginPassword.addEventListener("focusout", (e) => Password_focus_out(e, 1)); //로그인페이지 비밀번호
+eyes[0].addEventListener("click", (e) => Password_hide(e, LoginPassword)); //로그인 페이지 비밀번호 눈
+
+nickname.addEventListener("focusout", (e) => Nickname_focus_out(e, 1)); //회원가입 페이지 닉네임
+Password.addEventListener("focusout", (e) => Password_focus_out(e, 2)); //회원가입페이지 비밀번호
+check_pass.addEventListener("keyup", (e) => Password_correct(e, 3)); //회원가입페이지 비밀번호 확인
+eyes[0].addEventListener("click", (e) => Password_hide(e, Password)); //회원가입 페이지 비밀번호 눈
+eyes[1].addEventListener("click", (e) => Password_hide(e, check_pass)); //회원가입 페이지 비밀번호 확인 눈
+
+Input.forEach((input) => {
+ input.addEventListener(
+ "change",
+ (e) => Button_inactive(e, is_form_value(), is_error()) //회원가입 페이지 버튼
+ );
+});
+Input.forEach((input) => {
+ input.addEventListener(
+ "change",
+ Button_inactive(
+ e,
+ email_check(Email.value),
+ password_checked(Password.value)
+ )
+ ); //로그인 페이지 버튼
+});
diff --git a/style/HomePage.js b/style/HomePage.js
new file mode 100644
index 00000000..a99eeef9
--- /dev/null
+++ b/style/HomePage.js
@@ -0,0 +1,7 @@
+import styled from "styled-components";
+import ItemsList from "../components/ItemsList";
+// import HomePage from '../pages/HomePage';
+
+const ListGrid = styled(ItemsList)`
+ display: grid;
+`;
diff --git a/style/color.css b/style/color.css
new file mode 100644
index 00000000..4d04dabe
--- /dev/null
+++ b/style/color.css
@@ -0,0 +1,16 @@
+:root {
+ --gray900: #111827;
+ --gray800: #1f2937;
+ --gray700: #374151;
+ --gray600: #4b5563;
+ --gray500: #6b7280;
+ --gray400: #9ca3af;
+ --gray200: #e5e7eb;
+ --gray100: #f3f4f6;
+ --gray50: #f9fafb;
+ --blue: #3692ff;
+ --white: #ffffff;
+ --backgroundLightBlue: #cfe5ff;
+ --backgroundLightGray: #fcfcfc;
+ --inputRed: #f74747;
+}
diff --git a/style/main.css b/style/main.css
new file mode 100644
index 00000000..0f15a95d
--- /dev/null
+++ b/style/main.css
@@ -0,0 +1,477 @@
+@import url(./color.css);
+
+* {
+ box-sizing: border-box;
+ text-align: center;
+ font-family: pretendard, sans-serif;
+}
+
+.head {
+ height: 70px;
+ position: fixed;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ display: flex;
+ justify-content: space-between;
+ flex-direction: row;
+ height: 70px;
+ align-items: center;
+ background-color: var(--white);
+}
+
+#pandamarket_logo {
+ width: 153px;
+ height: 51px;
+ margin-left: 200px;
+ cursor: pointer;
+}
+
+#login_button {
+ margin-right: 200px;
+ width: 128px;
+ height: 48px;
+ border-radius: 8px;
+ border: 0 none;
+ cursor: pointer;
+ background-color: var(--blue);
+ width: 128px;
+ height: 48px;
+ padding: 12px 23px 12px 23px;
+ color: var(--gray100);
+ font-size: 16px;
+ font-weight: 600px;
+ line-height: 26px;
+}
+
+/* 여기까지 판다로고,로그인 버튼 */
+
+main {
+ margin-top: 70px;
+}
+
+.background_color {
+ background-color: var(--backgroundLightBlue);
+ width: 100%;
+ height: 540px;
+}
+/* 배경색 늘어남 */
+
+.contents_top {
+ display: flex;
+ gap: 7px;
+ width: 1110px;
+ height: 340px;
+ padding-top: 200px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.top_text {
+ width: 357px;
+ height: 260px;
+ padding-bottom: 60px;
+ display: flex;
+ flex-direction: column;
+ gap: 32px;
+}
+.top_text > p {
+ font-size: 40px;
+ line-height: 56px;
+ font-weight: 700;
+ text-align: left;
+ color: var(--gray700);
+}
+
+#items_Button {
+ width: 357px;
+ height: 56px;
+ cursor: pointer;
+ border-radius: 40px;
+ border: none;
+ font-family: Pretendard;
+ font-size: 20px;
+ font-weight: 600;
+ line-height: 32px;
+ color: var(--gray50);
+ background-color: var(--blue);
+}
+
+.pandaimg_top {
+ width: 746px;
+ height: 340px;
+}
+
+/* 여기까지 첫번째 섹션 (더보러가기 )부분 */
+
+.content_area {
+ border-radius: 12px;
+ height: 444px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 998px;
+ margin: 138px auto;
+ gap: 64px;
+ background-color: var(--backgroundLightGray);
+}
+
+.content_text {
+ display: flex;
+ flex-direction: column;
+ padding-right: 24px;
+ width: 100%;
+}
+
+.content_text > span {
+ color: var(--blue);
+ font-size: 18px;
+ font-weight: 700;
+ line-height: 26px;
+ text-align: left;
+}
+.content_text > p {
+ color: var(--gray700);
+ font-size: 22px;
+ line-height: 32px;
+ font-weight: 500px;
+ text-align: left;
+}
+.content_text .content_text_title {
+ font-size: 40px;
+ font-weight: 700px;
+ line-height: 56px;
+}
+
+.text_right > p {
+ text-align: right;
+}
+.text_right > span {
+ text-align: right;
+ padding-right: 0px;
+ padding-left: 24px;
+}
+
+/* 여기까지 컨텐츠 3개 */
+
+.content_bottom_area {
+ padding-top: 143px;
+}
+.contents_bottom {
+ width: 1110px;
+ height: 397px;
+ display: flex;
+ margin-left: auto;
+ margin-right: auto;
+ align-items: center;
+ gap: 69px;
+}
+
+.bottom_text {
+ width: 295px;
+ height: 112px;
+ padding-bottom: 60px;
+ color: var(--gray700);
+ font-size: 40px;
+ font-weight: 700px;
+ line-height: 56px;
+ text-align: left;
+}
+.bottom_text > img {
+ width: 746px;
+ height: 397px;
+}
+/* 여기까지 bottom (믿을수 있는 판다마켓 중고거래 부분) */
+/* 여기부터 하단영역 */
+
+footer {
+ background-color: var(--gray900);
+ width: 100%;
+ height: 160px;
+ padding: 32px 40px 108px 40px;
+}
+
+.footer_content {
+ display: flex;
+ color: var(--gray400);
+ gap: 366.5px;
+ justify-content: space-between;
+ width: 1120px;
+ height: 20px;
+ margin-right: auto;
+ margin-left: auto;
+}
+
+.footer_content_text {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ gap: 366.5px;
+ margin: 0px;
+}
+.footer_content_policy {
+ width: 159px;
+ height: 19px;
+ display: flex;
+ gap: 30px;
+ font-size: 16px;
+ line-height: 19px;
+ font-weight: 400px;
+ text-align: center;
+}
+
+.footer_content_policy > a {
+ text-decoration: none;
+ color: var(--gray200);
+ cursor: pointer;
+}
+.sns_icon {
+ display: flex;
+ gap: 12px;
+ width: 116px;
+ height: 20px;
+ cursor: pointer;
+}
+
+/*-----------------------------------------------*/
+/* 화면 너비기준 1199px ~768px 타블렛 */
+
+@media (max-width: 1199px) {
+ body {
+ width: 100%;
+ margin: 0 auto;
+ }
+
+ #pandamarket_logo {
+ margin-left: 24px;
+ }
+
+ #login_button {
+ margin-right: 24px;
+ }
+
+ .background_color {
+ height: auto;
+ }
+
+ .contents_top {
+ flex-direction: column;
+ align-items: center;
+ width: 100%;
+ height: 100%;
+ padding-top: 84px;
+ gap: 211px;
+ }
+
+ .top_text {
+ width: auto;
+ height: auto;
+ padding-bottom: 0px;
+ gap: 24px;
+ }
+ .top_text > p {
+ text-align: center;
+ margin: 0px;
+ }
+
+ .pandaimg_top,
+ .footer_content,
+ .content_img {
+ width: 100%;
+ }
+
+ section {
+ display: flex;
+ flex-direction: column;
+ gap: 52px;
+ margin: 24px 24px 56px 24px;
+ }
+
+ .content_area {
+ margin: 0px;
+ height: auto;
+ width: 100%;
+ flex-direction: column;
+ gap: 24px;
+ }
+
+ .content_text {
+ padding-right: 0px;
+ width: 100%;
+ }
+
+ .content_text > p {
+ margin: 0px;
+ font-size: 18px;
+ }
+
+ .content_text .content_text_title {
+ font-size: 32px;
+ margin-top: 16px;
+ margin-bottom: 24px;
+ }
+
+ .text_right > p,
+ .text_right > span {
+ text-align: right;
+ }
+
+ #reverse_column {
+ flex-direction: column-reverse;
+ }
+
+ .content_bottom_area {
+ padding-top: 201px;
+ }
+ .contents_bottom {
+ width: 100%;
+ height: 100%;
+ flex-direction: column;
+ gap: 217px;
+ }
+
+ .bottom_text {
+ width: 100%;
+ text-align: center;
+ padding-bottom: 0px;
+ }
+
+ footer {
+ padding-left: 104px;
+ padding-right: 104px;
+ }
+ .footer_content {
+ gap: 71px;
+ width: 100%;
+ margin: 0 auto;
+ justify-content: space-between;
+ }
+ .footer_content_text {
+ display: flex;
+ flex-direction: row;
+ gap: 71px;
+ margin: 0px;
+ width: 65%;
+ }
+
+ .footer_content > span {
+ width: 100%;
+ }
+ .sns_icon {
+ width: 116px;
+ }
+ .footer_content_policy {
+ width: 181px;
+ font-family: Abel;
+ }
+}
+
+/*----------------------------------*/
+/* 화면 너비기준 375~ 767모바일 */
+@media (min-width: 375px) and (max-width: 767px) {
+ #pandamarket_logo {
+ margin-left: 16px;
+ }
+
+ #login_button {
+ margin-right: 16px;
+ }
+ body {
+ width: 100%;
+ margin: 0 auto;
+ }
+
+ .background_color {
+ height: auto;
+ }
+
+ .contents_top {
+ padding-top: 48px;
+ gap: 132px;
+ }
+
+ .top_text {
+ width: 240px;
+ height: 90px;
+ gap: 18px;
+ }
+ .top_text > p {
+ font-size: 32px;
+ }
+
+ #items_Button,
+ .pandaimg_top,
+ .footer_content,
+ .content_img {
+ width: 100%;
+ }
+ .pandaimg_top {
+ height: 100%;
+ }
+
+ section {
+ gap: 40px;
+ margin: 52px 16px 83px 16px;
+ }
+
+ .content_text > p {
+ font-size: 16px;
+ }
+
+ .content_text .content_text_title {
+ font-size: 24px;
+ margin-top: 8px;
+ margin-bottom: 16px;
+ }
+
+ .text_right > p,
+ .text_right > span {
+ text-align: right;
+ }
+ .text_right > span {
+ font-size: 16px;
+ }
+
+ .content_bottom_area {
+ padding-top: 121px;
+ }
+ .contents_bottom {
+ gap: 131px;
+ }
+
+ .bottom_text {
+ font-size: 32px;
+ line-height: 44.8px;
+ }
+ .pandaimg_bottom {
+ width: 100%;
+ } /**/
+
+ .footer_content_text {
+ display: flex;
+ flex-direction: column-reverse;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: 60px;
+ }
+ footer {
+ padding: 0px;
+ }
+ .footer_content {
+ padding: 32px;
+ height: 100%;
+ gap: 13px;
+ align-items: start;
+ }
+
+ .footer_content > span {
+ width: 100%;
+ }
+ .footer_content_policy {
+ width: 181px;
+ font-family: Abel;
+ }
+ .sns_icon {
+ width: 116px;
+ }
+}
diff --git a/style/signup_login.css b/style/signup_login.css
new file mode 100644
index 00000000..18574cd6
--- /dev/null
+++ b/style/signup_login.css
@@ -0,0 +1,236 @@
+@import url(./color.css);
+* {
+ box-sizing: border-box;
+ margin: 0 auto;
+}
+
+body {
+ width: 640px;
+ margin: 231px auto;
+ text-align: center;
+}
+
+header {
+ width: 369px;
+ height: 132px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.panda_logo_img {
+ width: 103.53px;
+ height: 103.88px;
+}
+
+.pandamarket_logo {
+ width: 266px;
+ height: 90px;
+ font-family: "ROKAF Sans";
+ font-weight: 700;
+ font-size: 66.34px;
+ line-height: 89.56px;
+ text-decoration: none;
+ color: var(--blue);
+}
+/* 여기까지 header 영역 */
+
+main {
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
+ margin-top: 40px;
+}
+
+/* form,간편로그인, 외부링크a 링크 모두 24px 갭 */
+
+.form_area {
+ display: flex;
+ flex-direction: column;
+ width: 640px;
+ gap: 24px;
+}
+
+.label_text {
+ text-align: left;
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ font-family: Pretendard;
+ font-size: 18px;
+ font-weight: 700px;
+ color: var(--gray800);
+}
+
+.input_area {
+ width: 640px;
+ height: 56px;
+ background-color: var(--gray100);
+ border: none;
+ border-radius: 12px;
+ font-weight: 400px;
+ font-size: 16px;
+ line-height: 26px;
+ font-family: Pretendard;
+ color: var(--gray400);
+ padding: 16px 24px;
+}
+
+.active_blue_button {
+ width: 640px;
+ height: 56px;
+ background-color: var(--gray400);
+ border: none;
+ border-radius: 40px;
+ padding: 16px 124px;
+ font-size: 20px;
+ font-weight: 600px;
+ color: var(--gray100);
+}
+
+/* 여기까지 form 기본 영역 */
+
+.i_tag_position {
+ margin: 0;
+ position: relative;
+}
+i {
+ position: absolute;
+ right: 5%;
+ bottom: 30%;
+}
+/* 눈모양 i태그 */
+
+.active_blue_button:active {
+ background-color: var(--blue);
+}
+/* 로그인 버튼 active상태일때(눌렀을때 색깔 변화) */
+
+.input_area:focus {
+ border: 1px solid var(--blue);
+}
+
+/* input에 포커스일때 테두리색깔 변화 */
+
+.sns_login_area {
+ width: 640px;
+ height: 74px;
+ border-radius: 8px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+
+ padding: 16px 23px;
+ background-color: #e6f2ff;
+}
+
+.sns_login_text {
+ font-size: 16px;
+ font-weight: 500px;
+ line-height: 26px;
+ color: var(--gray800);
+ margin: 0;
+}
+.sns_icons {
+ display: flex;
+ gap: 16px;
+ align-items: center;
+ margin: 0;
+}
+
+.sns_icon {
+ width: 42px;
+ height: 42px;
+}
+
+/* 간편sns로그인 부분 */
+
+.signup_or_login_area {
+ color: var(--gray800);
+ font-size: 14px;
+ font-weight: 500px;
+ font: Pretendard;
+ line-height: 24px;
+ display: flex;
+ gap: 4px;
+}
+
+.signup_or_login_link {
+ color: var(--blue);
+}
+
+/*------------------------------------------------------*/
+/*js 기능 css*/
+.input_red_border {
+ border: 1px solid var(--inputRed);
+}
+.error_message {
+ width: 100%;
+}
+.error_message > a {
+ color: var(--inputRed);
+ font-size: 14px;
+ line-height: 24px;
+ font-weight: 600;
+ text-align: left;
+}
+
+/* 화면 너비기준 1199px ~768px 타블렛 */
+
+@media (max-width: 1199px) {
+ #body {
+ margin: 190px auto;
+ }
+}
+
+/*------------------------------------------------------*/
+/* 화면 너비기준 375~ 767모바일 */
+
+@media (max-width: 767px) {
+ #body {
+ width: 100%;
+ max-width: 400px;
+ margin: 80px auto;
+ padding-right: 16px;
+ padding-left: 16px;
+ }
+
+ header {
+ width: 50%;
+ height: 50%;
+ }
+
+ .panda_logo_img {
+ width: 25%;
+ }
+
+ .pandamarket_logo {
+ width: 70%;
+ font-size: 200%;
+ }
+
+ main {
+ margin-top: 24px;
+ }
+
+ .form_area {
+ gap: 16px;
+ }
+
+ .label_text {
+ gap: 8px;
+ font-size: 87.5%;
+ margin: 0;
+ }
+ main,
+ .form_area,
+ .input_area,
+ .active_blue_button,
+ .sns_login_area {
+ width: 100%;
+ max-width: 400px;
+ }
+}
+
+@media (max-width: 375px) {
+}