From 2cf1c737e01d66baa558d5fe28df145863b6e605 Mon Sep 17 00:00:00 2001 From: kimyong8175 Date: Wed, 10 Jan 2024 20:50:06 +0900 Subject: [PATCH 01/14] Jan 10 --- src/App.tsx | 14 + src/assets/images/Group28.png | Bin 0 -> 1681 bytes src/assets/images/index.ts | 3 +- src/component/Common/Button/Button.tsx | 45 +++ src/component/Common/FilterBox/FilterBox.tsx | 38 ++ src/component/Common/FilterBox/styles.ts | 96 ++++++ .../ManageOwnDogs/ContentBox/ContentBox.tsx | 145 ++++++++ .../ManageOwnDogs/ContentBox/styles.ts | 130 +++++++ .../ContentBox/useSearchInput.tsx | 7 + .../ManageOwnDogs/CustomInput/CustomInput.tsx | 62 ++++ .../ManageOwnDogs/Form/OwnDogsForm.tsx | 325 ++++++++++++++++++ .../ManageReview/ContentBox/ContentBox.tsx | 99 ++++++ .../ManageReview/ContentBox/styles.ts | 129 +++++++ .../ManageReview/Form/ReviewForm.tsx | 291 ++++++++++++++++ src/component/ManageReview/Navbar/Navbar.tsx | 48 +++ src/component/ManageReview/Navbar/styles.ts | 55 +++ src/constants.ts | 9 +- src/pages/Breeder-Details1/BreederDetails.tsx | 1 - src/pages/ManageOwnDogs/ManageOwnDogs.tsx | 17 + .../ManageOwnDogs/create/CreateOwnDogs.tsx | 20 ++ src/pages/ManageOwnDogs/styles.ts | 61 ++++ src/pages/ManageReview/ManageReview.tsx | 17 + .../ManageReview/create/CreateReview.tsx | 20 ++ src/pages/ManageReview/edit/EditReview.tsx | 27 ++ src/pages/ManageReview/styles.ts | 60 ++++ src/redux/api/ApiSlice1.ts | 3 +- src/redux/api/ReviewApiSlice1.ts | 19 + 27 files changed, 1733 insertions(+), 8 deletions(-) create mode 100644 src/assets/images/Group28.png create mode 100644 src/component/Common/Button/Button.tsx create mode 100644 src/component/Common/FilterBox/FilterBox.tsx create mode 100644 src/component/Common/FilterBox/styles.ts create mode 100644 src/component/ManageOwnDogs/ContentBox/ContentBox.tsx create mode 100644 src/component/ManageOwnDogs/ContentBox/styles.ts create mode 100644 src/component/ManageOwnDogs/ContentBox/useSearchInput.tsx create mode 100644 src/component/ManageOwnDogs/CustomInput/CustomInput.tsx create mode 100644 src/component/ManageOwnDogs/Form/OwnDogsForm.tsx create mode 100644 src/component/ManageReview/ContentBox/ContentBox.tsx create mode 100644 src/component/ManageReview/ContentBox/styles.ts create mode 100644 src/component/ManageReview/Form/ReviewForm.tsx create mode 100644 src/component/ManageReview/Navbar/Navbar.tsx create mode 100644 src/component/ManageReview/Navbar/styles.ts create mode 100644 src/pages/ManageOwnDogs/ManageOwnDogs.tsx create mode 100644 src/pages/ManageOwnDogs/create/CreateOwnDogs.tsx create mode 100644 src/pages/ManageOwnDogs/styles.ts create mode 100644 src/pages/ManageReview/ManageReview.tsx create mode 100644 src/pages/ManageReview/create/CreateReview.tsx create mode 100644 src/pages/ManageReview/edit/EditReview.tsx create mode 100644 src/pages/ManageReview/styles.ts create mode 100644 src/redux/api/ReviewApiSlice1.ts diff --git a/src/App.tsx b/src/App.tsx index c02b9c5e..7d364e54 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -29,6 +29,10 @@ import Profile from "./pages/MyPage/profile"; import Breeder from "./pages/AdoptionRequestList/Breeder/Breeder"; import Adopter from "./pages/AdoptionRequestList/Adopter/Adopter"; import RemoveAccount from "./pages/RemoveAccount/RemoveAccount"; +import ManageReview from "./pages/ManageReview/ManageReview"; +import ManageOwnDogs from "./pages/ManageOwnDogs/ManageOwnDogs"; +import CreateReview from "./pages/ManageReview/create/CreateReview"; +import EditReview from "./pages/ManageReview/edit/EditReview"; function App() { return ( @@ -61,6 +65,16 @@ function App() { } /> } /> } /> + } /> + } + > + } + > + } /> } /> } /> diff --git a/src/assets/images/Group28.png b/src/assets/images/Group28.png new file mode 100644 index 0000000000000000000000000000000000000000..0e30da8b189551b3bc62426acabbb4b58b679925 GIT binary patch literal 1681 zcmV;C25$L@P) zCiM|JJ3D4%WMqr8GyIGBXIY?0`tC~;QBwQ0EF0J zA4L%mQV=X82*}8HG1VX}2*{*OHGaR=Tv%9WbH1%#@SHlA2A0+JPbvrFGXBWd4KaXL z9#7NiK}bx?35hWJX7E_Dn@m)@NZqZitq4H={{B94Q^wOCqxzl>l{4(k&CNRIGX(%4 z@xUhaVFyYx4}vEqCR!eW5xuI{G)uaNKvBUcP?wx_XCp~@aCJi%9UV2Cd<(r359Io| zEX6zA_fo1v8W9c~TNA@C}VE`vX&KM9$uj(p#l z_kyTYXfKn2gkHGSq;Dz#ZhS!l0yBS<@%k*ZX7|G11h56u-qss+8!%UZnw(qkMNUa_*Wf7 z*{FBO4oVj5KxK^SbTzUFN;If!51reZKzWzI8H9(jqQQ-L!8dfB~w zLkzECJ5(=H1*z4ZHLsG|7aA>|<14c56$GXL3ulAsgIgp;fp2wfQyj+@X=UcqToL9p zR)&-VY@YVvWatg^OlLR1aZ{}?1`mM;<}?+I10W;`W^#e8sEoR)8Y!EdfOTbM{d}g{ z^8y4TZs;B0efdtF2Y~(HZ=ZAB6OQeF`O%#mbO0ft8?R0+%p39u#KME#59a}b+QQ5( zd-kI>H8pioB)o;Ts7LEEwW>XWmn;KU06`BRLD6QQeoM40L0aVLwzUB{{z_1ac^yYP z7Xp=))mJ6>9zgY*wnksU7M5SGBTsLA-__d6Ti4w26w=}0Vfb@HH9$N-a;zkV(@-`I zI7)A4yf>+-d!J z3kkVA)N>gD+QCcGE@4bG?$1QH$e`BTKsW!Miwmkvt^uxvd0aWu>gMjur9szqx1?%@ z_2+j8rJ3guJK_;rroo^)$LZA;0G3|q>DmLPYdcNVH7Z#sxeb98RaAt)wA&ZTXz4!s be!1a4xwKTy8D>#b00000NkvXXu0mjfAjKFD literal 0 HcmV?d00001 diff --git a/src/assets/images/index.ts b/src/assets/images/index.ts index 3b5e0781..1fad7c68 100644 --- a/src/assets/images/index.ts +++ b/src/assets/images/index.ts @@ -4,5 +4,6 @@ import IMG2 from "./Group21.png"; import IMG3 from "./Rectangle6.png"; import IMG4 from "./pome1.png"; import IMG5 from "./golden.png"; +import IMG6 from "./Group28.png"; -export { IMG1, IMG2, IMG3, IMG4, IMG5 }; +export { IMG1, IMG2, IMG3, IMG4, IMG5, IMG6 }; diff --git a/src/component/Common/Button/Button.tsx b/src/component/Common/Button/Button.tsx new file mode 100644 index 00000000..18e4903f --- /dev/null +++ b/src/component/Common/Button/Button.tsx @@ -0,0 +1,45 @@ +import styled from "styled-components"; + +const CustomButton = styled.button<{ + weight: number; + size: number; + customwidth: number; + customheight: number; +}>` + width: ${(props) => props.customwidth}px; + height: ${(props) => props.customheight}px; + border-radius: 16px; + border: none; + background: #4ec1bf; + gap: 10px; + color: #ffffff; + font-family: Noto Sans KR; + font-size: ${(props) => props.size}px; + font-weight: ${(props) => props.weight}; + line-height: 23px; + letter-spacing: -0.03em; + cursor: pointer; +`; + +interface IButtonProps { + children: React.ReactNode; + weight: number; + size: number; + width: number; + height: number; +} + +const Button = ({ children, weight, size, width, height }: IButtonProps) => { + return ( + + {children} + + ); +}; + +export default Button; diff --git a/src/component/Common/FilterBox/FilterBox.tsx b/src/component/Common/FilterBox/FilterBox.tsx new file mode 100644 index 00000000..8adf4b00 --- /dev/null +++ b/src/component/Common/FilterBox/FilterBox.tsx @@ -0,0 +1,38 @@ +import { useState } from "react"; +import { BiSolidDownArrow } from "react-icons/bi"; + +import * as S from "./styles"; + +interface IProps { + content: string[]; + category: string; + onClick: (value: string) => void; +} + +const FilterBox = ({ content, category, onClick }: IProps) => { + const [isSelectClicked, setIsSelectClicked] = useState(false); + return ( + setIsSelectClicked((prev) => !prev)}> + + + + + {isSelectClicked && ( + + {content.map((c, index) => ( + onClick(c)}> + {c} + + ))} + + )} + + ); +}; + +export default FilterBox; diff --git a/src/component/Common/FilterBox/styles.ts b/src/component/Common/FilterBox/styles.ts new file mode 100644 index 00000000..8955ad26 --- /dev/null +++ b/src/component/Common/FilterBox/styles.ts @@ -0,0 +1,96 @@ +import styled from "styled-components"; + +export const SelectContainer = styled.div` + width: 240px; + display: flex; + justify-content: center; + + position: relative; +`; + +export const CustomSelect = styled.input` + // used to deactivate the defualt system level + appearance: none; + + width: 100%; + height: 48px; + border: 1px solid #dddddd; + border-radius: 16px; + padding: 0 30px; + background-color: #ffffff; + + font-family: Noto Sans KR; + font-size: 16px; + font-weight: 500; + line-height: 23px; + letter-spacing: -0.03em; + text-align: left; + color: #939393; + + cursor: pointer; +`; + +export const SelectIconContainer = styled.div<{ isclicked: boolean }>` + width: 32px; + height: 32px; + font-size: 16px; + color: #4ec1bf; + + display: flex; + align-items: center; + justify-content: center; + + transform: ${(props) => (props.isclicked ? "rotate(180deg)" : "rotate(0)")}; + + position: absolute; + top: 7px; + right: 4px; + + cursor: pointer; +`; + +export const SelectUl = styled.ul` + width: 240px; + position: absolute; + top: 50px; + + background: #ffffff; + border: 1px solid #eeeeee; + border-radius: 12px; + box-shadow: 0px 14px 20px 0px #3a3a3a14; + list-style-type: none; + + margin: 0; + padding: 0; + z-index: 999; + + cursor: pointer; +`; + +export const SelectLi = styled.li` + /* width: 100%; */ + height: 58px; + + display: flex; + flex-direction: column; + align-items: flex-start; + justify-content: center; + + border-radius: 16px; + border-bottom: 1px solid #eeeeee; + + padding: 0px 20px; + gap: 10px; + + font-family: Noto Sans KR; + font-size: 16px; + font-weight: 400; + line-height: 23px; + letter-spacing: -0.03em; + text-align: left; + color: #000000; + + &:hover { + background: #4ec1bf; + } +`; diff --git a/src/component/ManageOwnDogs/ContentBox/ContentBox.tsx b/src/component/ManageOwnDogs/ContentBox/ContentBox.tsx new file mode 100644 index 00000000..d1ad00d9 --- /dev/null +++ b/src/component/ManageOwnDogs/ContentBox/ContentBox.tsx @@ -0,0 +1,145 @@ +import { useState, useEffect } from "react"; +import { get } from "../../../api/api"; + +import Pagenation from "../../CollectCOMP1/Pagenation1"; +import FilterBox from "../../Common/FilterBox/FilterBox"; +import Button from "../../Common/Button/Button"; + +import * as S from "./styles"; + +interface IContent { + birthDate: string; + breederNickName: string; + gender: string; + id: number; + imgUrl: string; + isBreederVerified: boolean; + name: string; + status: string; + type: string; +} + +interface IData { + data: { + content: IContent[]; + totalPages: number; + }; + status: string; +} + +const ContentBox = () => { + const [dogs, setDogs] = useState(); + const [page, setPage] = useState(0); + const [category, setCategory] = useState(""); + const [result, setResult] = useState(); + const [inputText, setInputText] = useState(""); + + useEffect(() => { + const fetchData = async () => { + const res = await get( + `${process.env.REACT_APP_API_URL}/breeder/dogs` + ); + console.log(process.env.REACT_APP_API_URL); + console.log(res.data); + + return res.data.data; + }; + + fetchData() + .then((res) => { + setPage(res.totalPages); + setDogs(res.content); + }) + .catch((err) => console.log(err)); + }, []); + + const searchItems = (searchValue: string) => { + setInputText(searchValue); + if (searchValue !== "") { + const filteredData = dogs?.filter((item) => { + return Object.values(item).join("").includes(searchValue); + }); + setResult(filteredData); + } else { + setResult(dogs); + } + }; + + return ( + + 보유견종 관리 + + + + searchItems(e.target.value)} + /> + + + + + {inputText.length > 0 + ? result?.map((d) => ( + + + + {d.name} + + 견종: {d.type} + 성별: {d.name} + 출생일: {d.birthDate} + + + + )) + : dogs?.map((d) => ( + + + + {d.name} + + 견종: {d.type} + 성별: {d.name} + 출생일: {d.birthDate} + + + + ))} + + {/* {dogs?.map((d) => ( + + + + {d.name} + + 견종: {d.type} + 성별: {d.name} + 출생일: {d.birthDate} + + + + ))} */} + + + { + console.log("set page"); + }} + name="_" + /> + + + ); +}; + +export default ContentBox; diff --git a/src/component/ManageOwnDogs/ContentBox/styles.ts b/src/component/ManageOwnDogs/ContentBox/styles.ts new file mode 100644 index 00000000..82bd50f0 --- /dev/null +++ b/src/component/ManageOwnDogs/ContentBox/styles.ts @@ -0,0 +1,130 @@ +import styled from "styled-components"; + +export const Wrapper = styled.div` + background-color: white; + width: 1060px; + height: fit-content; + box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.09); + border-radius: 32px; + padding: 4vw 3vw 2.5vw; + z-index: 100; + + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + gap: 30px; +`; + +export const Title = styled.div` + width: 100%; + font-family: Noto Sans KR; + font-size: 28px; + font-weight: 500; + line-height: 36px; + letter-spacing: 0em; + text-align: left; + color: #000000; +`; + +export const SearchContainer = styled.div` + width: 100%; + height: 52px; + display: flex; + justify-content: flex-end; + align-items: center; + gap: 10px; +`; + +export const SearchBoxContainer = styled.div` + width: 420px; + display: flex; + align-items: center; + gap: 20px; +`; + +export const Input = styled.input` + width: 280px; + height: 48px; + background: #f5f5f5; + padding: 0 15px; + border: none; + border-radius: 16px; + + font-family: Noto Sans KR; + font-size: 16px; + font-weight: 500; + line-height: 23px; + letter-spacing: -0.03em; + text-align: left; + color: #939393; +`; + +export const PaginationContainer = styled.div` + width: 100%; + + display: flex; + justify-content: center; + align-items: center; + + margin: 40px 0 20px 0; +`; + +export const ListContainer = styled.div` + width: 100%; + height: 618px; + + display: flex; + flex-wrap: wrap; + gap: 60px; + + margin-top: 20px; +`; + +export const DogItem = styled.div` + width: 200px; + height: fit-content; + display: flex; + flex-direction: column; + gap: 20px; +`; + +export const DogImg = styled.img` + width: 200px; + height: 120px; + border-radius: 12px; +`; + +export const DogInfoContainer = styled.div` + width: 100%; + display: flex; + flex-direction: column; + gap: 12px; +`; + +export const DogName = styled.div` + width: 100%; + font-family: Noto Sans KR; + font-size: 25px; + font-weight: 400; + line-height: 40px; + letter-spacing: 0em; + text-align: left; + color: #333333; +`; + +export const DogInfo = styled.div` + width: 100%; + display: flex; + flex-direction: column; +`; + +export const DogInfoItem = styled.div` + font-family: Noto Sans KR; + font-size: 18px; + font-weight: 400; + line-height: 27px; + letter-spacing: 0em; + text-align: left; + color: #333333; +`; diff --git a/src/component/ManageOwnDogs/ContentBox/useSearchInput.tsx b/src/component/ManageOwnDogs/ContentBox/useSearchInput.tsx new file mode 100644 index 00000000..0f3672cb --- /dev/null +++ b/src/component/ManageOwnDogs/ContentBox/useSearchInput.tsx @@ -0,0 +1,7 @@ +import { useState } from "react"; + +const useSearchInput = () => { + return
useSearchInput
; +}; + +export default useSearchInput; diff --git a/src/component/ManageOwnDogs/CustomInput/CustomInput.tsx b/src/component/ManageOwnDogs/CustomInput/CustomInput.tsx new file mode 100644 index 00000000..5eea3018 --- /dev/null +++ b/src/component/ManageOwnDogs/CustomInput/CustomInput.tsx @@ -0,0 +1,62 @@ +import styled from "styled-components"; +import { BiSolidDownArrow } from "react-icons/bi"; + +const DOBInputBox = styled.div<{ width: string; height: string }>` + /* width: calc((100% / 3) - 20px); */ + width: ${(props) => props.width}; + height: ${(props) => props.height}; + position: relative; +`; + +const DOBInput = styled.input` + width: 100%; + height: 100%; + + display: flex; + justify-content: space-between; + + padding: 0 0 0 12px; + margin: 0; + + border: 1px solid #dddddd; + border-radius: 12px; + background: #f5f5f5; + + &::placeholder { + font-size: 16px; + } +`; + +const IconContainer = styled.div` + position: absolute; + top: 10px; + right: 0; + width: 26px; + height: 32px; + + display: flex; + justify-content: center; + align-items: center; + + font-size: 20px; + color: #4ec1bf; +`; + +type Props = { + placeHolder: string; + width: string; + height: string; +}; + +const CustomInput = ({ placeHolder, width, height }: Props) => { + return ( + + + + + + + ); +}; + +export default CustomInput; diff --git a/src/component/ManageOwnDogs/Form/OwnDogsForm.tsx b/src/component/ManageOwnDogs/Form/OwnDogsForm.tsx new file mode 100644 index 00000000..ffdef893 --- /dev/null +++ b/src/component/ManageOwnDogs/Form/OwnDogsForm.tsx @@ -0,0 +1,325 @@ +import styled from "styled-components"; +import { IoIosArrowBack } from "react-icons/io"; +import { BiSolidDownArrow } from "react-icons/bi"; + +import CustomInput from "../CustomInput/CustomInput"; + +const Wrapper = styled.div` + background-color: white; + /* width: 1060px; */ + width: 49vw; + height: fit-content; + box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.09); + border-radius: 32px; + padding: 4vw 3vw 2.5vw; + z-index: 100; + + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + position: relative; +`; + +const ReturnBtnContainer = styled.div` + position: absolute; + top: 5%; + right: 5%; + + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + gap: 7px; +`; + +const ReturnButton = styled.div` + width: 48px; + height: 48px; + + display: flex; + justify-content: center; + align-items: center; + color: #aeaeae; + font-size: 32px; + + border: 2px solid #aeaeae; + border-radius: 8px; + + cursor: pointer; +`; + +const ReturnBtnText = styled.div` + font-family: Noto Sans KR; + font-size: 14px; + font-weight: 500; + line-height: 20px; + letter-spacing: -0.03em; + text-align: center; + color: #939393; +`; + +const Title = styled.div` + width: 100%; + font-family: Noto Sans KR; + font-size: 28px; + font-weight: 500; + line-height: 36px; + letter-spacing: 0em; + text-align: left; + color: #000000; +`; + +const InnerContainer = styled.div` + width: 100%; + height: fit-content; + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 40px; + margin-top: 20px; +`; + +const Form = styled.form` + width: 100%; + height: fit-content; + display: flex; + flex-direction: column; + gap: 50px; +`; + +const TopInputContainer = styled.div` + width: 100%; + display: flex; + flex-wrap: wrap; + gap: 40px 82px; +`; + +const InputContainer = styled.div` + width: 429px; + display: flex; + flex-direction: column; + gap: 12px; +`; + +const InputTitle = styled.h1` + font-family: Noto Sans KR; + font-size: 20px; + font-weight: 500; + letter-spacing: -0.03em; + text-align: left; + color: #000000; + padding: 0; + margin: 0; +`; + +const Input = styled.input` + width: 92%; + height: 48px; + padding: 0 15px; + + background: #f5f5f5; + border-radius: 12px; + border: none; + + font-family: Noto Sans KR; + font-size: 16px; + font-weight: 500; + line-height: 23px; + letter-spacing: -0.03em; + text-align: left; + color: #939393; +`; + +const DOBInputContainer = styled.div` + width: 96%; + height: 48px; + + display: flex; + justify-content: space-between; + gap: 20px; +`; + +const ReviewInputContainer = styled.div` + width: 100%; + display: flex; + flex-direction: column; + gap: 12px; + position: relative; +`; + +export const Textarea = styled.textarea` + background: #f5f5f5; + border-radius: 16px; + height: 189px; + padding: 20px; + font-family: Noto Sans KR; + font-size: 16px; + font-weight: 500; + line-height: 23px; + letter-spacing: -0.03em; + text-align: left; + color: #939393; + border: none; + isolation: isolate; + resize: none; + z-index: 1; +`; + +export const TextLength = styled.span` + position: absolute; + width: 50px; + height: 23px; + right: 22px; + bottom: 19px; + + font-family: "Noto Sans KR"; + font-style: normal; + font-weight: 500; + font-size: 16px; + line-height: 23px; + letter-spacing: -0.03em; + + color: #000000; + z-index: 2; +`; + +const ImageUploaderContainer = styled.div` + // 240 * 3 + 36 * 2 + width: 792px; + // 지워야함 + /* height: 212px; */ + + display: flex; + flex-direction: column; + gap: 20px; +`; + +const ImageUploaderTitle = styled.div` + font-family: Noto Sans KR; + font-size: 28px; + font-weight: 500; + line-height: 36px; + letter-spacing: 0em; + text-align: left; + color: #000000; +`; + +const ImageUploaderFlexBox = styled.div` + width: 100%; + display: flex; + gap: 36px; +`; + +const ImageUpoaderbox = styled.div` + width: 240px; + height: 212px; + + display: flex; + flex-direction: column; + gap: 16px; +`; + +const ImageBox = styled.div<{ img?: string }>` + width: 240px; + height: 144px; + border-radius: 12px; + background: #f5f5f5; + background-image: url(${(props) => props.img}); +`; + +const ImageUploaderButton = styled.button` + width: 240px; + height: 52px; + border: none; + border-radius: 16px; + background: #4ec1bf; + + font-family: Noto Sans KR; + font-size: 18px; + font-weight: 700; + line-height: 26px; + letter-spacing: 0em; + text-align: center; + color: #ffffff; + + cursor: pointer; +`; + +const OwnDogsForm = () => { + return ( + + + + + + 이전 페이지로 + + + 보유견종 글쓰기 +
+ + + 강아지 이름 + + + + 출생일 + + + + + + + + 견종 + + + + 성별 + + + + + 분양상태 + + + + + 분양 후기 작성 +