diff --git a/src/components/studyroomMake/SelectCategory.jsx b/src/components/studyroomMake/SelectCategory.jsx new file mode 100644 index 0000000..2db5d15 --- /dev/null +++ b/src/components/studyroomMake/SelectCategory.jsx @@ -0,0 +1,80 @@ +import { useState } from "react"; +import styled from "styled-components"; +import DropDownIcon from "../../assets/dropdown2.png"; + +export default function SelectCategory() { + const [isShowOption, setShowOptions] = useState(false); + const [currentValue, setCurrentValue] = useState("카테고리 선택"); + + const handleSelectValue = (e) => { + const { innerText } = e.target; + setCurrentValue(innerText); + }; + + return ( + setShowOptions((prev) => !prev)}> + + + + + + + ); +} + +const SelectContainer = styled.div` + position: relative; + width: 866px; + height: 42px; + padding: 5px; + background-color: #3f424e; + align-self: center; + border-radius: 6px; + cursor: pointer; + z-index: 1; +`; + +const Label = styled.label` + font-size: 16px; + display: flex; + justify-content: space-between; + align-items: center; + margin-right: 20px; + margin-top: 10px; +`; + +const Icon = styled.img` + margin-left: 2d5px; + margin-right: 20px; + //margin-top: 15px; +`; + +const SelectOptions = styled.ul` + position: absolute; + list-style: none; + top: 18px; + left: 0; + width: 100%; + overflow: hidden; + height: 90px; + max-height: ${(props) => (props.show ? "none" : "0")}; + padding: 0; + border-radius: 8px; + background-color: #222222; + color: #fefefe; + transition: max-height 0.2s ease-in-out; +`; + +const Option = styled.li` + font-size: 14px; + padding: 6px 8px; + text-align: center; + margin-top: 10px; + transition: background-color 0.2s ease-in; + &:hover { + background-color: #595959; + } +`; diff --git a/src/components/studyroomMake/SelectPeople.jsx b/src/components/studyroomMake/SelectPeople.jsx new file mode 100644 index 0000000..6520f5c --- /dev/null +++ b/src/components/studyroomMake/SelectPeople.jsx @@ -0,0 +1,102 @@ +import { useState } from "react"; +import styled from "styled-components"; +import DropDownIcon from "../../assets/dropdown2.png"; + +export default function SelectPeople() { + const [isShowOption, setShowOptions] = useState(false); + const [currentValue, setCurrentValue] = useState("인원수 선택 (1 ~ 50명)"); + + const handleSelectValue = (e) => { + const { innerText } = e.target; + setCurrentValue(innerText); + }; + + return ( + setShowOptions((prev) => !prev)}> + + + {Array.from({ length: 50 }, (_, index) => ( + + ))} + + + ); +} + +const SelectContainer = styled.div` + position: relative; + width: 866px; + height: 42px; + padding: 5px; + background-color: #3f424e; + align-self: center; + border-radius: 6px; + cursor: pointer; + z-index: 1; +`; + +const Label = styled.label` + font-size: 16px; + display: flex; + justify-content: space-between; + align-items: center; + margin-right: 20px; + margin-top: 10px; +`; + +const Icon = styled.img` + margin-left: 2d5px; + margin-right: 20px; + //margin-top: 15px; +`; + +const SelectOptions = styled.ul` + position: absolute; + list-style: none; + top: 18px; + left: 0; + width: 100%; + overflow: hidden; + height: 130px; + max-height: ${(props) => (props.show ? "none" : "0")}; + overflow-y: auto; + padding: 0; + border-radius: 8px; + background-color: #222222; + color: #fefefe; + transition: max-height 0.2s ease-in-out; + + /* Webkit (Chrome, Safari) 스크롤바 스타일링 */ + &::-webkit-scrollbar { + width: 8px; + } + + &::-webkit-scrollbar-thumb { + background-color: #5263ff; /* 스크롤바 색상 */ + border-radius: 10px; + } + + /* Firefox 스크롤바 스타일링 */ + scrollbar-width: thin; + scrollbar-color: #5263ff transparent; + + & { + scrollbar-color: #5263ff transparent; + } +`; + +const Option = styled.li` + font-size: 14px; + padding: 6px 8px; + text-align: center; + margin-top: 10px; + transition: background-color 0.2s ease-in; + &:hover { + background-color: #595959; + } +`; diff --git a/src/hooks/useModal.js b/src/hooks/useModal.js index 6ee4c57..0074d96 100644 --- a/src/hooks/useModal.js +++ b/src/hooks/useModal.js @@ -61,8 +61,10 @@ const Background = styled.div` `; const ModalBlock = styled.div` - position: absolute; - top: 6.5rem; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); border-radius: 13px; padding: 1.5rem; background-color: #262631; diff --git a/src/pages/StudyMake.jsx b/src/pages/StudyMake.jsx index 860bc15..e9089a3 100644 --- a/src/pages/StudyMake.jsx +++ b/src/pages/StudyMake.jsx @@ -1,5 +1,336 @@ +import styled from "styled-components"; +import SelectCategory from "../components/studyroomMake/SelectCategory"; +import SelectPeople from "../components/studyroomMake/SelectPeople"; +import { useState } from "react"; +import useModal from "../hooks/useModal"; + const StudyMake = () => { - return
스터디방 만들기 페이지입니다
; + const [isDuplicate, setIsDuplicate] = useState(false); // 중복 확인 상태관리 + const [code, setCode] = useState(""); // 비공개 코드 상태관리 + const [isCodeValid, setIsCodeValid] = useState(true); // 비공개 코드 유효성 검사 + const [introduction, setIntroduction] = useState(""); // textarea 글자 제한 유효성 검사 + const [groupName, setGroupName] = useState(""); // 그룹명 상태관리 + const [category, setCategory] = useState(""); // 카테고리 상태관리 + const [peopleLimit, setPeopleLimit] = useState(""); // 제한 인원수 상태관리 + + // useModal 사용해서 그룹방 탈퇴 모달 구현 + const { openModal, Modal } = useModal(); + + // 중복 확인 버튼 + const handleCheckDuplicate = () => { + // 중복 확인 로직 추가 예정 + setIsDuplicate(true); + }; + + const handleCode = (event) => { + const inputValue = event.target.value; + + // 정규식으로 유효성 검사 + const isValid = /^\d{4}$/.test(inputValue); + setIsCodeValid(isValid); + setCode(inputValue); + }; + + const handleIntroduction = (event) => { + const inputValue = event.target.value; + setIntroduction(inputValue); + }; + + // 그룹명 입력 시 상태 업데이트 + const handleGroupName = (event) => { + const inputValue = event.target.value; + setGroupName(inputValue); + }; + + // 카테고리 선택 시 상태 업데이트 + const handleCategory = (selectedCategory) => { + setCategory(selectedCategory); + }; + + // 제한 인원수 선택 시 상태 업데이트 + const handlePeopleLimit = (selectedLimit) => { + setPeopleLimit(selectedLimit); + }; + + // 버튼 활성화 조건 + // const isButtonEnabled = + // groupName !== "" && category !== "" && peopleLimit !== ""; + + // textarea 글자수 제한 + const isIntroductionTooLong = introduction.length > 100000; + + // 만들기 btn 클릭 + const handleCreateStudy = () => { + // if (!isButtonEnabled) { + // alert("그룹명, 카테고리, 제한 인원수를 모두 입력해야 합니다"); + // return; + // } + + // modal open + openModal(); + + console.log("click"); + }; + + return ( + + + + 그룹명<span>*</span> + + + + 중복 확인 + + 사용 가능한 특수문자는 (_/-/@/.)입니다. + {isDuplicate && ( + + 현재 입력한 그룹방은 이미 있는 그룹방 입니다. 새로 입력해주세요. + + )} + + + + + 그룹 카테고리<span>*</span> + + {/* select (front/back) */} + + + + + + 제한 인원수<span>*</span> + + {/* select (1~50) */} + + + + + + 참여코드{" "} + + (선택사항) 공개 스터디방으로 원할 경우 빈칸으로 제출하세요. + + + + {!isCodeValid && ( + + 참여코드는 4자리 숫자로 입력해야 합니다. + + )} + + + + 소개글 + + {introduction.length} / 100,000 + {isIntroductionTooLong && ( + + 해당 글자수를 초과하였습니다. 글자수를 줄여주세요. + + )} + + + 방 만들기 + + {/* modal */} + + +
+ 축하합니다! 스터디방이 만들어졌습니다. +
+ +
+
+
+ ); }; export default StudyMake; + +const Wrapper = styled.div` + max-width: 1090px; + margin: 0 auto; + display: flex; + flex-direction: column; + align-items: center; +`; + +const Container = styled.div` + margin-bottom: 50px; +`; + +const Title = styled.div` + fontsize: 16px; + font-weight: 600; + margin-bottom: 15px; + + span { + color: #ff0000; + } +`; + +const GroupNameContainer = styled.div` + margin-bottom: 15px; +`; + +const GroupNameInput = styled.input` + width: 642px; + height: 42px; + padding: 5px; + background-color: #3f424e; + border: none; + border-radius: 6px; + margin-right: 20px; + color: #ffffff; +`; + +const ConfirmBtn = styled.button` + width: 180px; + height: 42px; + border: none; + border-radius: 5px; + background-color: #5263ff; + color: #ffffff; + font-size: 14px; + font-weight: 600; + margin-left: 20px; +`; + +const GrouptNameText = styled.div` + font-size: 13px; + font-weight: 400; + color: #939393; +`; + +const CheckText = styled.div` + font-size: 13px; + font-weight: 400; + color: #ff0000; +`; + +const CodeInput = styled.input` + width: 866px; + height: 42px; + padding: 5px; + background-color: #3f424e; + border: none; + border-radius: 6px; + color: #ffffff; + + &::placeholder { + color: #ffffff; + padding: 5px; + font-size: 14px; + font-weight: 400; + } +`; + +const CodeTitle = styled.div` + fontsize: 16px; + font-weight: 600; + margin-bottom: 15px; +`; + +const CodeText = styled.span` + font-size: 10px; + font-weight: 400; + color: #939393; + margin-left: 10px; +`; + +const CodeErrorMessage = styled.div` + font-size: 13px; + font-weight: 600; + color: #ff0000; + margin-top: 5px; +`; + +const IntroduceArea = styled.textarea` + width: 866px; + height: 93px; + padding: 5px; + background-color: #3f424e; + border: none; + border-radius: 6px; + color: #ffffff; + + &::placeholder { + color: #ffffff; + padding: 5px; + font-size: 14px; + font-weight: 400; + } +`; + +const CharCountText = styled.div` + font-size: 13px; + color: #939393; + margin-top: 5px; + text-align: right; +`; + +const IntroductionErrorMessage = styled.div` + font-size: 13px; + font-weight: 600; + color: #ff0000; + margin-top: 5px; +`; + +const MakeBtn = styled.button` + width: 866px; + height: 39px; + border: none; + border-radius: 6px; + background-color: #5263ff; + color: #ffffff; + font-size: 14px; + font-weight: 500; + margin-top: 20px; + margin-bottom: 50px; +`; + +const ModalContent = styled.div` + display: flex; + justify-content: center; + flex-direction: column; + align-items: center; + height: 100%; + margin-top: 60px; + font-size: 14px; + text-align: center; +`; + +const ModalBody = styled.div` + margin-bottom: 20px; + color: #c7c7c7; + text-align: center; + margin-bottom: 30px; +`; + +const Button = styled.button` + width: 301px; + height: 37px; + background-color: #5263ff; + font-size: 14px; + color: #ffffff; + border: none; + border-radius: 6px; + margin-top: 20px; +`;