From 7c07446756caac7183b4d59f16ee95184e719af9 Mon Sep 17 00:00:00 2001 From: rrimm Date: Wed, 29 Mar 2023 22:46:53 +0900 Subject: [PATCH 1/2] =?UTF-8?q?Feat:=20=EC=B6=94=EA=B0=80=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC=EC=9E=90=20=ED=8E=98=EC=9D=B4=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Admin/MemberAdmin/index.jsx | 86 ++++++++ .../Admin/MemberAdmin/index.styled.js | 101 +++++++++ src/components/Admin/MenuTabs/index.jsx | 43 ++++ src/components/Admin/MenuTabs/index.styled.js | 29 +++ src/components/Admin/ProductAdmin/index.jsx | 195 ++++++++++++++++++ .../Admin/ProductAdmin/index.styled.js | 120 +++++++++++ src/components/Admin/index.jsx | 14 ++ src/components/Admin/index.styled.js | 28 +++ .../Details/Carousel/index.styled.js | 6 +- .../Details/Content/RelatedProduct/index.jsx | 4 +- src/constants/path.js | 1 + .../Details/data.json} | 0 src/pages/Admin/index.jsx | 12 ++ src/pages/Login/LoginForm.jsx | 9 +- src/pages/index.jsx | 3 +- src/routes/index.jsx | 7 +- 16 files changed, 648 insertions(+), 10 deletions(-) create mode 100644 src/components/Admin/MemberAdmin/index.jsx create mode 100644 src/components/Admin/MemberAdmin/index.styled.js create mode 100644 src/components/Admin/MenuTabs/index.jsx create mode 100644 src/components/Admin/MenuTabs/index.styled.js create mode 100644 src/components/Admin/ProductAdmin/index.jsx create mode 100644 src/components/Admin/ProductAdmin/index.styled.js create mode 100644 src/components/Admin/index.jsx create mode 100644 src/components/Admin/index.styled.js rename src/{components/Details/Data/detailsdata.json => data/Details/data.json} (100%) create mode 100644 src/pages/Admin/index.jsx diff --git a/src/components/Admin/MemberAdmin/index.jsx b/src/components/Admin/MemberAdmin/index.jsx new file mode 100644 index 0000000..266c9be --- /dev/null +++ b/src/components/Admin/MemberAdmin/index.jsx @@ -0,0 +1,86 @@ +import React, { useState } from "react"; +import * as S from "./index.styled"; + +function ProductAdmin({ user_id, name, email }) { + // 더미데이터 + const data = [ + { + "user_id": 1, + "name": "홍길동", + "email": "project0109@gmail.com", + }, + { + "user_id": 2, + "name": "김기자", + "email": "project02@gmail.com", + }, + { + "user_id": 3, + "name": "이기자", + "email": "project03@gmail.com", + } + ]; + const [members, setMembers] = useState(data); + + return ( +
+ 회원 현황 + + + + + 신규 회원 + 방문 회원 + 전체 회원 수 + + + + + 회원 + 회원 + 회원 + + + + + + 신규 회원: 해당 날짜 회원가입 횟수 카운트
+ 방문 회원: 해당 날짜 로그인 횟수 카운트
+ 전체 회원 수: 등록된 회원 수 카운트 +
+ + 회원 리스트 + + + + + 회원 ID + 회원 이름 + 회원 이메일 + 회원 관리 + + + + {data.map((data, index) => ( + + {data.user_id} + {data.name} + {data.email} + + + + + ))} + + + + 삭제 + + + + +
+ ); +} + +export default ProductAdmin; \ No newline at end of file diff --git a/src/components/Admin/MemberAdmin/index.styled.js b/src/components/Admin/MemberAdmin/index.styled.js new file mode 100644 index 0000000..c6eaf3c --- /dev/null +++ b/src/components/Admin/MemberAdmin/index.styled.js @@ -0,0 +1,101 @@ +import styled from "@emotion/styled"; + +const Text = styled.div` + margin: 30px; + text-align: center; + padding: 10px; + border-collapse: collapse; + font-size: 21px; + // background: #ede3d7; + border-bottom: 1px solid #ede3d7; +`; +const Info = styled.div` + margin: -30px 0 0 500px; + font-size: 12px; + text-align: left; +`; + +const MemberTable = styled.table` + margin: 10px; + width: 50%; + height: 40%; + text-align: center; + border-collapse: collapse; + border: 1px solid #0f010d; +`; + +const MemberContainer = styled.div` + display: flex; + justify-content: center; + margin: 40px; +`; +const StyledTh = styled.th` + text-align: center; + background: #ede3d7; + border: 1px solid #0f010d; + font-size: 18px; +`; +const MemberTd = styled.td` + width: 33%; + text-align: center; + border: 1px solid #0f010d; +`; + +const MemberlistTable = styled.table` + margin: 30px 0; + // height: 200px; + width: 50%; + text-align: center; + border-collapse: collapse; + border: 1px solid #0f010d; +`; + +const MemberlistContainer = styled.div` + display: flex; + justify-content: center; + margin: 30px; +`; + +const MemberlistTh = styled.th` + width: 25%; + text-align: center; + // border-collapse: collapse; + border: 1px solid #0f010d; +`; + +const MemberlistTd = styled.td` + width: 25%; + text-align: center; + border: 1px solid #0f010d; +`; + +const Footer = styled.td` + text-align: center; + border: 1px solid #0f010d; +`; + +const Button = styled.button` + background: #0f010d; + color: white; + + &:hover { + background: #ede3d7; + color: #0f010d; + font-weight: bold; + } +`; + +export { + Text, + Info, + MemberTable, + MemberContainer, + StyledTh, + MemberTd, + MemberlistTable, + MemberlistContainer, + MemberlistTh, + MemberlistTd, + Footer, + Button, +}; diff --git a/src/components/Admin/MenuTabs/index.jsx b/src/components/Admin/MenuTabs/index.jsx new file mode 100644 index 0000000..e69e69b --- /dev/null +++ b/src/components/Admin/MenuTabs/index.jsx @@ -0,0 +1,43 @@ +import React, { useEffect } from "react"; +import { useLocation, useNavigate } from "react-router-dom"; +import * as S from "./index.styled"; +import MemberAdmin from "../MemberAdmin"; +import ProductAdmin from "../ProductAdmin"; + +function MenuTabs() { + const location = useLocation(); + const path = location.pathname; + const member = path.includes("member"); + const product = path.includes("product"); + const navigate = useNavigate(); + + useEffect(() => { + if (!member && !product) { + navigate("/admin/member", { replace: true }); + } + }, [member, product, navigate]); + + var element; + if (member) { + element = ; + } + if (product) { + element = ; + } + + return ( + <> + + + 회원 관리 + + + 상품 관리 + + + {element} + + ); +} + +export default MenuTabs; diff --git a/src/components/Admin/MenuTabs/index.styled.js b/src/components/Admin/MenuTabs/index.styled.js new file mode 100644 index 0000000..1839e2b --- /dev/null +++ b/src/components/Admin/MenuTabs/index.styled.js @@ -0,0 +1,29 @@ +import styled from "@emotion/styled"; +import { Link } from "react-router-dom"; + +const Container = styled.div` + display: flex; + justify-content: center; + // flex-direction: row; + border-bottom: medium solid #807675; + border-width: 1px; +`; + +const Text = styled.div` + color: #807675; + font-size: 24px; + margin: 10px 50px; + padding: 5px 50px; +`; + +const StyledLink = styled(Link)` + text-decoration: none; + color: #807675; + + &:hover { + color: #0f010d; + font-weight: bold; + } +`; + +export { Text, Container, StyledLink }; diff --git a/src/components/Admin/ProductAdmin/index.jsx b/src/components/Admin/ProductAdmin/index.jsx new file mode 100644 index 0000000..4e556b8 --- /dev/null +++ b/src/components/Admin/ProductAdmin/index.jsx @@ -0,0 +1,195 @@ +import React, {useState} from "react"; +import * as S from "./index.styled"; + +function ProductAdmin({ id, image, target, category, name, price }) { + // 더미데이터 + const data = [ + { + "id": 1, + "image": "img/03.jpg", + "target": "women", + "category": "top", + "name": "데님 자켓", + "price": 100000 + }, + { + "id": 2, + "image": "img/04.jpg", + "target": "women", + "category": "pant", + "name": "청바지", + "price": 96000 + }, + { + "id": 3, + "image": "img/05.jpg", + "target": "women", + "category": "pant", + "name": "청바지", + "price": 96000 + }, + { + "id": 4, + "image": "img/06.jpg", + "target": "women", + "category": "pant", + "name": "청바지", + "price": 96000 + } +]; +const [actionMode, setActionMode] = useState(0); +const handleUpdateForm = (e) => { + if (actionMode === 0) { + setActionMode(1); + } else { + setActionMode(0); + } +}; + +if(actionMode===0){ + return ( +
+ 상품 추가 + + + + +ID + 이미지 + 분류 + 카테고리 + 상품명 + 가격 + + + + + + + + + + + +추가 + + + + + +상품 리스트 + + + + + ID + 이미지 + 분류 + 카테고리 + 상품명 + 가격 + 상품 관리 + + + + {data.map((data, index) => ( + + {data.id} + {data.image} + {data.target} + {data.category} + {data.name} + {data.price} + + + + + ))} + + + + 수정 + 삭제 + + + + + +
) +} + +if(actionMode===1){ + return( +
+ 상품 정보 수정 + + + + +ID + 이미지 + 분류 + 카테고리 + 상품명 + 가격 + + + + + + + + + + + +수정 + + + + + +상품 리스트 + + + + + ID + 이미지 + 분류 + 카테고리 + 상품명 + 가격 + 상품 관리 + + + + {data.map((data, index) => ( + + {data.id} + {data.image} + {data.target} + {data.category} + {data.name} + {data.price} + + + + + ))} + + + + + 수정 + 삭제 + + + + +
+ ); +} +} + +export default ProductAdmin; \ No newline at end of file diff --git a/src/components/Admin/ProductAdmin/index.styled.js b/src/components/Admin/ProductAdmin/index.styled.js new file mode 100644 index 0000000..69d8156 --- /dev/null +++ b/src/components/Admin/ProductAdmin/index.styled.js @@ -0,0 +1,120 @@ +import styled from "@emotion/styled"; + +const Text = styled.div` + margin: 30px; + text-align: center; + padding: 10px; + border-collapse: collapse; + font-size: 21px; + border-bottom: 1px solid #ede3d7; +`; + +const Info = styled.div` + margin: -30px 0 0 500px; + font-size: 12px; + text-align: left; +`; +const ProductTable = styled.table` + margin: 10px; + width: 70%; + height: 40%; + text-align: center; + border-collapse: collapse; + border: 1px solid #0f010d; +`; + +const ProductContainer = styled.div` + display: flex; + justify-content: center; + margin: 40px; +`; + +const StyledTh = styled.th` + text-align: center; + background: #ede3d7; + border: 1px solid #0f010d; + font-size: 18px; +`; + +const ProductTd = styled.td` + width: 14.28%; + text-align: center; + border: 1px solid #0f010d; +`; + +const ProductlistTable = styled.table` + margin: 30px 0; + width: 60%; + text-align: center; + border-collapse: collapse; + border: 1px solid #0f010d; +`; + +const ProductlistContainer = styled.div` + display: flex; + justify-content: center; + margin: 30px; +`; + +const ProductlistTh = styled.th` + width: 25%; + text-align: center; + border: 1px solid #0f010d; +`; + +const ProductlistTd = styled.td` + width: 13.3%; + text-align: center; + border: 1px solid #0f010d; +`; + +const Footer = styled.td` + text-align: center; + border: 1px solid #0f010d; +`; + +const Button = styled.button` + background: #0f010d; + color: white; + padding: 5px 10px; + margin: 0 5px; + border: 1px solid #0f010d; + + &:hover { + background: white; + color: #0f010d; + font-weight: bold; + border: 1px solid black; + } +`; + +const ChangeButton = styled.button` + background: #807675; + color: white; + margin: 0 5px; + border: 1px solid #807675; + padding: 5px 10px; + + &:hover { + background: white; + color: #0f010d; + font-weight: bold; + border: 1px solid black; + } +`; + +export { + Text, + Info, + ProductTable, + ProductContainer, + StyledTh, + ProductTd, + ProductlistTable, + ProductlistContainer, + ProductlistTh, + ProductlistTd, + Footer, + Button, + ChangeButton, +}; diff --git a/src/components/Admin/index.jsx b/src/components/Admin/index.jsx new file mode 100644 index 0000000..c1e3ab8 --- /dev/null +++ b/src/components/Admin/index.jsx @@ -0,0 +1,14 @@ +import * as S from "./index.styled"; +import MenuTabs from "./MenuTabs"; + +function AdminPage() { + + return ( +
+ 관리 페이지 + +
+ ); +} + +export default AdminPage; diff --git a/src/components/Admin/index.styled.js b/src/components/Admin/index.styled.js new file mode 100644 index 0000000..33766c3 --- /dev/null +++ b/src/components/Admin/index.styled.js @@ -0,0 +1,28 @@ +import styled from "@emotion/styled"; + +const HeadText = styled.div` + display: flex; + justify-content: center; + font-size: 30px; + // margin: 80px 0; + padding: 80px 0; +`; + +const StyledLink = styled.div` + margin-top: 100px; + padding-left: 50px; +`; + +const Slider = styled.div` + width: 500px; + height: 800px; +`; + +const Order = styled.div` + width: 500px; + height: 800px; + margin-inline: 200px; + margin-top: 30px; +`; + +export { HeadText, Slider, Order }; diff --git a/src/components/Details/Carousel/index.styled.js b/src/components/Details/Carousel/index.styled.js index cb6e19c..50d8294 100644 --- a/src/components/Details/Carousel/index.styled.js +++ b/src/components/Details/Carousel/index.styled.js @@ -1,8 +1,10 @@ import styled from "@emotion/styled"; const Container = styled.div` - padding: 0 30px; - margin: 30px auto; + width: 100%; + height: 500px; + justify-content: center; + margin: 30px 0; `; export { Container }; diff --git a/src/components/Details/Content/RelatedProduct/index.jsx b/src/components/Details/Content/RelatedProduct/index.jsx index 22694b8..68200ad 100644 --- a/src/components/Details/Content/RelatedProduct/index.jsx +++ b/src/components/Details/Content/RelatedProduct/index.jsx @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from "react"; +import React, { useState } from "react"; import c1 from "../../../../assets/Details/c1.jpg"; import c2 from "../../../../assets/Details/c2.jpg"; import c3 from "../../../../assets/Details/c3.jpg"; @@ -7,8 +7,6 @@ import c5 from "../../../../assets/Details/c5.jpg"; import { BsChevronLeft } from "react-icons/bs"; import { BsChevronRight } from "react-icons/bs"; import * as S from "./index.styled"; -import Data from "../../Data/detailsdata.json" -import axios from "axios"; function RelatedProduct() { const data = [ diff --git a/src/constants/path.js b/src/constants/path.js index 9ac3ae5..dcd1658 100644 --- a/src/constants/path.js +++ b/src/constants/path.js @@ -8,6 +8,7 @@ const BROWSER_PATH = { OUTFIT: "/outfit", PRODUCT: "/product", REVIEW: "/review", + ADMIN: "/admin", }; // TODO: 추후 스프링과 연동하기 diff --git a/src/components/Details/Data/detailsdata.json b/src/data/Details/data.json similarity index 100% rename from src/components/Details/Data/detailsdata.json rename to src/data/Details/data.json diff --git a/src/pages/Admin/index.jsx b/src/pages/Admin/index.jsx new file mode 100644 index 0000000..2572782 --- /dev/null +++ b/src/pages/Admin/index.jsx @@ -0,0 +1,12 @@ +import React from "react"; +import AdminPage from "../../components/Admin"; + +function Admin() { + return ( +
+ +
+ ); +} + +export default Admin; \ No newline at end of file diff --git a/src/pages/Login/LoginForm.jsx b/src/pages/Login/LoginForm.jsx index f10e9cb..bbf5d5b 100644 --- a/src/pages/Login/LoginForm.jsx +++ b/src/pages/Login/LoginForm.jsx @@ -13,11 +13,16 @@ function LoginForm() { const handlePwChange = (event) => setInputPw(event.target.value); const login = () => { + // 관리자페이지로 이동 + if (inputEmail === "admin" && inputPw === "1111") { + navigate("/admin"); + return; + } if (inputEmail === "" || inputPw === "") { alert("이메일과 비밀번호를 입력해주세요!"); return; } - }; +} function handleSubmit(event) { event.preventDefault(); @@ -65,4 +70,4 @@ function LoginForm() { ); } -export default LoginForm; +export default LoginForm; \ No newline at end of file diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 1553622..a81b06b 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -10,5 +10,6 @@ const NotFound = lazy(() => import("./NotFound/index")); const Outfit = lazy(() => import("./Outfit/index")); const Product = lazy(() => import("./Product/index")); const Review = lazy(() => import("./Review/index")); +const Admin = lazy(() => import("./Admin/index")); -export { Cart, Details, Join, Login, Main, My, NotFound, Outfit, Product, Review }; +export { Cart, Details, Join, Login, Main, My, NotFound, Outfit, Product, Review, Admin }; diff --git a/src/routes/index.jsx b/src/routes/index.jsx index 0602a5a..1a74f04 100644 --- a/src/routes/index.jsx +++ b/src/routes/index.jsx @@ -1,5 +1,4 @@ -import { Cart, Details, Join, Login, Main, My, NotFound, Outfit, Product, Review } from "../pages/index"; - +import { Cart, Details, Join, Login, Main, My, NotFound, Outfit, Product, Review, Admin } from "../pages/index"; import React from "react"; import { BROWSER_PATH } from "../constants/path"; import { Route, Routes as BrowserRoutes } from "react-router-dom"; @@ -14,6 +13,10 @@ function Routes() { } /> } /> + }> + } /> + } /> + } /> } /> } /> From e3a0add01eb8d3d115a09010917d9fb0828e652c Mon Sep 17 00:00:00 2001 From: rrimm <119832853+rrimm@users.noreply.github.com> Date: Wed, 29 Mar 2023 23:05:08 +0900 Subject: [PATCH 2/2] =?UTF-8?q?Style:=20=EC=84=B8=EB=AF=B8=EC=BD=9C?= =?UTF-8?q?=EB=A1=A0=20=EB=88=84=EB=9D=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Login/LoginForm.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/Login/LoginForm.jsx b/src/pages/Login/LoginForm.jsx index bbf5d5b..27d1a13 100644 --- a/src/pages/Login/LoginForm.jsx +++ b/src/pages/Login/LoginForm.jsx @@ -22,7 +22,7 @@ function LoginForm() { alert("이메일과 비밀번호를 입력해주세요!"); return; } -} +}; function handleSubmit(event) { event.preventDefault(); @@ -70,4 +70,4 @@ function LoginForm() { ); } -export default LoginForm; \ No newline at end of file +export default LoginForm;