From 4e1d1d3ffb6595a8b3d066ffd5b3221ff4b36eee Mon Sep 17 00:00:00 2001 From: YangJJune Date: Tue, 20 Aug 2024 12:16:28 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20=EB=A9=A4=EB=B2=84=20=EC=B4=88?= =?UTF-8?q?=EB=8C=80=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 2 + src/apis/Space/SpaceJoinInfoApi.ts | 2 +- src/pages/HomePage/HomePageMember.tsx | 41 ++++- src/pages/SpacePage/InviteSpace2.tsx | 209 ++++++++++++++++++++++++++ 4 files changed, 251 insertions(+), 3 deletions(-) create mode 100644 src/pages/SpacePage/InviteSpace2.tsx diff --git a/src/App.tsx b/src/App.tsx index f6623cf..eae6292 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -45,6 +45,7 @@ import InviteSpace from "./pages/SpacePage/InviteSpace"; import HomePageMemberPage from "./pages/HomePage/HomePageMember"; import HomePageProfile from "./pages/HomePage/HomePageProfile"; import SpecialVoiceRoom from "./pages/VoiceRoomPage/SpecialVoiceRoom"; +import InviteSpace2 from "./pages/SpacePage/InviteSpace2"; // will we need constant path in later..? // const PATH = { @@ -138,6 +139,7 @@ function App() { { path: "/space/spaceoption/profilemanage", element: }, { path: "/space/spaceoption/alarmmanage", element: }, { path: "/invite", element: }, + { path: "/invite/:spaceId", element: }, ]; const routes_children_login = [ diff --git a/src/apis/Space/SpaceJoinInfoApi.ts b/src/apis/Space/SpaceJoinInfoApi.ts index 3f7d102..d5e97cd 100644 --- a/src/apis/Space/SpaceJoinInfoApi.ts +++ b/src/apis/Space/SpaceJoinInfoApi.ts @@ -1,6 +1,6 @@ import { createRequestOptionsJSON_AUTH, fetchApi } from "@/apis/_createRequestOptions"; -interface SpaceJoinInfo { +export interface SpaceJoinInfo { spaceProfileImg: string | null; // 스페이스 썸네일 이미지 url spaceName: string; // 스페이스 이름 createdAt: string; // 스페이스 개설일 (yyyy년 mm월 dd일 형식) diff --git a/src/pages/HomePage/HomePageMember.tsx b/src/pages/HomePage/HomePageMember.tsx index 37b990c..f1bdf5d 100644 --- a/src/pages/HomePage/HomePageMember.tsx +++ b/src/pages/HomePage/HomePageMember.tsx @@ -6,9 +6,10 @@ import AddMemberImg from "@/assets/ChatPage/btn_add_member.svg"; import TopBarText, { LeftEnum } from "@/components/TopBarText"; import { Member, MemberContainer } from "@/pages/ChatPage/ChatCreatePage/ChatCreatePage.styled"; import { getUserDefaultImageURL } from "@/utils/getUserDefaultImageURL"; +import * as s from "@/pages/HomePage/HomePage.styled"; +import { ToastContainer, toast } from "react-toastify"; const HomePageMemberPage = () => { - const { id } = useParams(); const navigate = useNavigate(); const [userList, setUserList] = useState([]); @@ -23,6 +24,23 @@ const HomePageMemberPage = () => { }); }, []); + const clickInviteHandler = async () => { + const spaceId = localStorage.getItem("spaceId"); + await navigator.clipboard + .writeText(`${window.location.origin}/KUIT-Space-front/invite/${spaceId}`) + .then(() => { + toast.success("클립보드에 초대링크가 복사되었습니다!", { + position: "bottom-center", + autoClose: 3000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + theme: "dark", + }); + }); + }; return ( <> { {/* //TODO: 자신이 관리자일 때만 뜨는 뷰 */} - + + +
스페이스에 초대하기
+
{userList.map((member, index) => ( { ))}
+ ); }; diff --git a/src/pages/SpacePage/InviteSpace2.tsx b/src/pages/SpacePage/InviteSpace2.tsx new file mode 100644 index 0000000..12a96bf --- /dev/null +++ b/src/pages/SpacePage/InviteSpace2.tsx @@ -0,0 +1,209 @@ +import { ChangeEvent, useEffect, useState } from "react"; +import { useLocation, useNavigate, useParams } from "react-router-dom"; +import styled from "styled-components"; + +import { SpaceInfo as SpaceInfoType } from "@/apis/Space/SpaceSelectApi"; +import { SpaceUserJoinApi } from "@/apis/Space/SpaceUserJoinApi"; +import { CharacterImgs } from "@/assets/Characters"; +import ChatroomImg from "@/assets/ChatPage/btn_chatroom_img.svg"; +import back from "@/assets/icon_back.svg"; +import { BottomBtn } from "@/components/BottomBtn"; +import { Input } from "@/components/Input"; +import { getUserDefaultImageURL } from "@/utils/getUserDefaultImageURL"; +import { svgComponentToFile } from "@/utils/svgComponentToFile"; + +import { ChatroomAddImgBtn } from "../ChatPage/ChatCreatePage/ChatCreatePage.styled"; +import { SpaceJoinInfo, SpaceJoinInfoApi } from "@/apis"; + +const TopBarContainer = styled.div` + display: flex; + height: 52px; + align-items: center; +`; + +const BackBtn = styled.img` + width: 36px; + height: 36px; + cursor: pointer; +`; + +const InfoContainer = styled.div` + display: flex; + flex-direction: column; + align-items: center; + margin-top: 132px; +`; + +const SpaceImage = styled.img` + width: 160px; + height: 160px; + border-radius: 12px; + margin-bottom: 20px; +`; + +const SpaceTitle = styled.span` + font-size: 24px; + font-weight: semi-bold; + margin-bottom: 20px; +`; +const SpaceInfo = styled.span` + height: 22px; + font-size: 16px; + color: ${({ theme }) => theme.colors.BG500}; +`; + +const Count = styled.span` + position: absolute; + right: 1rem; + top: 50%; + transform: translateY(-50%); + font-size: 16px; + color: ${({ theme }) => theme.colors.BG500}; +`; + +const NameInput = styled(Input)` + padding-right: 4rem; /* Count를 위한 여유 공간 */ + margin-top: 8px; +`; + +const SpaceJoinBottomBtn = styled(BottomBtn)` + display: fixed; + bottom: 1; + margin: 0; +`; + +const InviteSpace2 = () => { + const navigate = useNavigate(); + const { spaceId } = useParams(); + + const [spaceInfo, setSpaceInfo] = useState(); + const [currentStep, setCurrentStep] = useState(1); + const [spacename, setSpacename] = useState(""); + const [spaceUserMsg, setSpaceUserMsg] = useState(""); + const maxChars = 12; + + const [uploadedImage, setUploadedImage] = useState(null); + const defaultImage: File = svgComponentToFile( + CharacterImgs[Math.floor(Math.random() * CharacterImgs.length)], + ); + + useEffect(() => { + //TODO: spaceInfo가 없을 때의 더미 데이터 + console.log(spaceId); + const response = SpaceJoinInfoApi(Number.parseInt(spaceId!)).then((data) => { + setSpaceInfo(data?.result); + }); + }, []); + + const handleInputChange = (e: ChangeEvent) => { + const value = e.target.value; + if (value.length <= maxChars) { + setSpacename(value); + } + }; + + const handleNextButtonClick = () => { + if (currentStep === 2) { + //TODO: 가입하기 API 호출 / userImg, userName + SpaceUserJoinApi( + Number.parseInt(spaceId!), + uploadedImage ?? defaultImage, + spacename, + spaceUserMsg, + ).then((res) => { + if (res) navigate("/"); + }); + } + setCurrentStep((prevStep) => prevStep + 1); + }; + + const handlePreviousButtonClick = () => { + setCurrentStep((prevStep) => prevStep - 1); + }; + + const handleImageImport = (e: React.ChangeEvent) => { + const image = e.target.files?.[0]; + image && setUploadedImage(image); + }; + + return ( +
+ {currentStep === 1 && ( + + + {spaceInfo?.spaceName} +
+
+ 개설일 + + {isNaN(Date.parse(spaceInfo?.createdAt ?? "")) + ? spaceInfo?.createdAt + : spaceInfo?.createdAt && + new Date(spaceInfo?.createdAt).toLocaleDateString("ko-KR")} + +
+
+ 멤버 + {spaceInfo?.memberNum}명 +
+
+
+ )} + {currentStep === 2 && ( +
+ + + + + + Chatroom Image + + + +
+ 이름 +
+ + + {spacename.length}/{maxChars} + +
+
+ +
+ 상태 메세지 +
+ { + const value = e.target.value; + if (value.length <= maxChars * 5) { + setSpaceUserMsg(value); + } + }} + placeholder="스페이스 상태 메세지" + /> + + {spaceUserMsg.length}/{maxChars * 5} + +
+
+
+ )} + + 가입하기 + +
+ ); +}; + +export default InviteSpace2;