Commit d8d3d203 authored by Kim, Chaerin's avatar Kim, Chaerin
Browse files

merge-all

parent 3e9c534c
...@@ -5,6 +5,10 @@ import HomeUserPage from "./pages/HomeUserPage"; ...@@ -5,6 +5,10 @@ import HomeUserPage from "./pages/HomeUserPage";
import ProfilePage from "./pages/ProfilePage"; import ProfilePage from "./pages/ProfilePage";
import RoomPage from "./pages/RoomPage"; import RoomPage from "./pages/RoomPage";
import InfoUpdatePage from "./pages/InfoUpdatePage"; import InfoUpdatePage from "./pages/InfoUpdatePage";
import InvitePage from "./pages/InvitePage";
import SingupPage from "./components/SignUp";
import LoginPage from "./components/Login"
import InitRoomPage from "./pages/InitRoomPage";
function App() { function App() {
return ( return (
...@@ -12,10 +16,14 @@ function App() { ...@@ -12,10 +16,14 @@ function App() {
{/* <AuthProvider> */} {/* <AuthProvider> */}
<Switch> <Switch>
<Route exact path="/" component={HomeGuestPage} /> <Route exact path="/" component={HomeGuestPage} />
<Route exact path="/user" component={HomeUserPage} /> <Route exact path="/user/:id" component={HomeUserPage} />
<Route exact path="/signup" component={SingupPage} />
<Route exact path="/login" component={LoginPage} />
<Route path="/profile/:id/update" component={InfoUpdatePage} /> <Route path="/profile/:id/update" component={InfoUpdatePage} />
<Route path="/profile/:id" component={ProfilePage} /> <Route path="/profile/:id" component={ProfilePage} />
<Route path="/room/:roomId/:channelId" component={RoomPage} /> <Route path="/room/:roomId/:channelId" component={RoomPage} />
<Route path="/room/:roomId" component={InitRoomPage} />
<Route path="/room/Invite" component={InvitePage} />
</Switch> </Switch>
{/* </AuthProvider> */} {/* </AuthProvider> */}
</Router> </Router>
......
import axios from "axios"; import axios from "axios";
const getRoom = async (id) => { const getRoom = async (id) => {
const { data } = await axios.get(`/api/room/getRoom/${id}`); const { data } = await axios.post('/api/room/getRoom', id);
return data; return data;
}; };
const create = async (payload) => { const create = async (formData) => {
const { data } = await axios.post("/api/room/create", payload); const { data } = await axios.post("/api/room/create", formData);
return data; return data;
}; };
......
import axios from "axios"; import axios from "axios";
const getUser = async (id) => { const getUser = async (id) => {
// console.log('id222:',id.userID)
const { data } = await axios.get(`/api/getUser/${id}`); const { data } = await axios.get(`/api/getUser/${id}`);
return data; return data;
}; };
......
...@@ -2,6 +2,7 @@ import { Link } from 'react-router-dom' ...@@ -2,6 +2,7 @@ import { Link } from 'react-router-dom'
import { handleLogout } from '../context/auth' import { handleLogout } from '../context/auth'
const Header = () => { const Header = () => {
const id = localStorage.getItem('user');
return ( return (
<div> <div>
<form <form
...@@ -10,7 +11,7 @@ const Header = () => { ...@@ -10,7 +11,7 @@ const Header = () => {
> >
<div className="d-flex justify-content-end"> <div className="d-flex justify-content-end">
<div> <div>
<Link to="/user"> <Link to={`/user/${id}`}>
<img src="/BORA.png" style={{ width: '160px' }} /> <img src="/BORA.png" style={{ width: '160px' }} />
</Link> </Link>
</div> </div>
...@@ -51,14 +52,14 @@ const Header = () => { ...@@ -51,14 +52,14 @@ const Header = () => {
<div className="row mb-3"> <div className="row mb-3">
<div className="d-flex justify-content-evenly"> <div className="d-flex justify-content-evenly">
<Link to="/" className="col-2 p-1 btn btn-primary"> <Link to="/" className="col-2 p-1 btn btn-primary">
<button <button
type="submit" type="submit"
className="btn btn-primary" className="btn btn-primary"
onClick={() => handleLogout()} onClick={() => handleLogout()}
data-bs-dismiss="modal" data-bs-dismiss="modal"
> >
</button> </button>
</Link> </Link>
<button <button
type="submit" type="submit"
......
...@@ -5,14 +5,13 @@ const AddRoom = () => { ...@@ -5,14 +5,13 @@ const AddRoom = () => {
return ( return (
<div> <div>
<div className="mx-4 my-3 d-flex justify-content-between"> <div className="mx-4 my-3 d-flex justify-content-between">
<div className="fs-4"> <div className="fs-4">참여중인 방목록</div>
참여중인 방목록
</div>
<button <button
type="button" type="button"
className="py-1 px-2" className="py-1 px-2"
data-bs-toggle="modal" data-bs-toggle="modal"
data-bs-target="#myModal" data-bs-target="#myModal"
// data-bs-dismiss="modal"
style={{ style={{
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
...@@ -45,7 +44,6 @@ const AddRoom = () => { ...@@ -45,7 +44,6 @@ const AddRoom = () => {
className="p-3" className="p-3"
data-bs-toggle="modal" data-bs-toggle="modal"
data-bs-target="#joinModal" data-bs-target="#joinModal"
// data-bs-dismiss="modal"
style={{ style={{
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
...@@ -54,7 +52,8 @@ const AddRoom = () => { ...@@ -54,7 +52,8 @@ const AddRoom = () => {
backgroundColor: "#E0CEE8", backgroundColor: "#E0CEE8",
borderColor: "#E0CEE8", borderColor: "#E0CEE8",
}} }}
>방참여하기 >
방참여하기
</button> </button>
<div <div
className="modal fade" className="modal fade"
...@@ -83,7 +82,8 @@ const AddRoom = () => { ...@@ -83,7 +82,8 @@ const AddRoom = () => {
backgroundColor: "#f5cfe3", backgroundColor: "#f5cfe3",
borderColor: "#f5cfe3", borderColor: "#f5cfe3",
}} }}
>방생성하기 >
방생성하기
</button> </button>
<div <div
className="modal fade" className="modal fade"
......
...@@ -3,11 +3,9 @@ import { Redirect } from "react-router-dom"; ...@@ -3,11 +3,9 @@ import { Redirect } from "react-router-dom";
import roomApi from "../../apis/room.api"; import roomApi from "../../apis/room.api";
import catchErrors from "../../context/catchError"; import catchErrors from "../../context/catchError";
const userId = localStorage.getItem('user'); const id = localStorage.getItem('user');
const INIT_ROOM = { const INIT_ROOM = {
name: '', name: '',
owner: userId,
member: userId,
profileimg: '', profileimg: '',
} }
...@@ -23,17 +21,26 @@ const CreateRoom = () => { ...@@ -23,17 +21,26 @@ const CreateRoom = () => {
}, [room]); }, [room]);
function handleChange(event) { function handleChange(event) {
// console.log(room) const { name, value, files } = event.target;
const { name, value } = event.target if (files) {
setRoom({ ...room, [name]: value }) setRoom({ ...room, [name]: files[0] })
} else {
setRoom({ ...room, [name]: value })
}
console.log(room)
} }
async function handleSubmit(e) { async function handleSubmit(e) {
e.preventDefault() e.preventDefault()
// console.log('룸룸', room) let formData = new FormData();
console.log('profileimg:', room.profileimg)
console.log('name:', room.name)
formData.append("name", room.name);
formData.append("userId", id);
formData.append("profileimg", room.profileimg);
try { try {
const res = await roomApi.create(room) const res = await roomApi.create(formData)
// console.log(res) console.log(res)
const Id = res.id const Id = res.id
console.log(Id) console.log(Id)
alert(`방참여코드는 ${Id}입니다`) alert(`방참여코드는 ${Id}입니다`)
...@@ -46,9 +53,10 @@ const CreateRoom = () => { ...@@ -46,9 +53,10 @@ const CreateRoom = () => {
} }
if (success) { if (success) {
console.log('success', success) // console.log('success', success)
alert('룸생성이 완료되었습니다!') alert('룸생성이 완료되었습니다!')
return <Redirect to='/user' /> window.location.href=`/user/${id}`
// return <Redirect to={`/user/${id}`} />
} }
const { name, owner, member, profileimg } = room; const { name, owner, member, profileimg } = room;
...@@ -57,7 +65,9 @@ const CreateRoom = () => { ...@@ -57,7 +65,9 @@ const CreateRoom = () => {
<div className="modal-content" > <div className="modal-content" >
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<div className="modal-header"> <div className="modal-header">
<div className="modal-title" id="makeModal">방생성하기</div> <div className="modal-title" id="makeModal">
방생성하기
</div>
<button <button
type="button" type="button"
className="btn-close" className="btn-close"
...@@ -66,6 +76,7 @@ const CreateRoom = () => { ...@@ -66,6 +76,7 @@ const CreateRoom = () => {
></button> ></button>
</div> </div>
<div className="modal-body"> <div className="modal-body">
{error && <div className="alert alert-danger">{error}</div>}
<h6>방프로필사진</h6> <h6>방프로필사진</h6>
<div className="mb-4"> <div className="mb-4">
<input <input
...@@ -74,7 +85,7 @@ const CreateRoom = () => { ...@@ -74,7 +85,7 @@ const CreateRoom = () => {
onChange={handleChange} onChange={handleChange}
accept="image/*" accept="image/*"
name="profileimg" name="profileimg"
value={room.profileimg} /> />
</div> </div>
<h6>방이름</h6> <h6>방이름</h6>
<div className="input-group"> <div className="input-group">
...@@ -86,7 +97,6 @@ const CreateRoom = () => { ...@@ -86,7 +97,6 @@ const CreateRoom = () => {
aria-describedby="basic-addon1" aria-describedby="basic-addon1"
onChange={handleChange} onChange={handleChange}
name="name" name="name"
value={room.name}
/> />
</div> </div>
<div className="modal-footer"> <div className="modal-footer">
......
...@@ -6,28 +6,27 @@ import catchErrors from "../../context/catchError"; ...@@ -6,28 +6,27 @@ import catchErrors from "../../context/catchError";
const userprofile = localStorage.getItem("user"); const userprofile = localStorage.getItem("user");
const INIT_USER = { const INIT_USER = {
id: userprofile, id: userprofile,
email: '', email: "",
img: '', img: "",
} };
const HomeProfile = () => { const HomeProfile = () => {
const [user, setUser] = useState(INIT_USER) const [user, setUser] = useState(INIT_USER);
const [error, setError]= useState("");
async function getSetUser(userID) { async function getSetUser(userID) {
try { try {
console.log('userID', userID) const data = await userApi.getUser(userID);
const data = await userApi.getUser(userID)
console.log(data) setUser(data);
setUser(data)
// console.log(user)
} catch (error) { } catch (error) {
// catchErrors(error, setError) catchErrors(error, setError);
} }
} }
useEffect(() => { useEffect(() => {
getSetUser(userprofile) getSetUser(userprofile);
}, [userprofile]) }, [userprofile]);
return ( return (
<Link to={`/profile/${user.id}`} className="text-decoration-none text-dark"> <Link to={`/profile/${user.id}`} className="text-decoration-none text-dark">
...@@ -40,7 +39,6 @@ const HomeProfile = () => { ...@@ -40,7 +39,6 @@ const HomeProfile = () => {
width: "157px", width: "157px",
height: "157px", height: "157px",
}} }}
// value={user.img}
/> />
</div> </div>
<h1 className="d-flex justify-content-center"> {user.email} </h1> <h1 className="d-flex justify-content-center"> {user.email} </h1>
......
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { Redirect } from "react-router-dom"; import { Redirect } from "react-router-dom";
import roomApi from "../../apis/room.api"; import roomApi from "../../apis/room.api";
import catchErrors from "../../context/catchError";
const userId = localStorage.getItem('user'); const id = localStorage.getItem("user");
const JoinRoom = () => { const JoinRoom = () => {
const [roomId, setRoomId] = useState(''); const [roomId, setRoomId] = useState("");
const [disabled, setDisabled] = useState(true); const [disabled, setDisabled] = useState(true);
const [error, setError] = useState(""); const [error, setError] = useState("");
const [success, setSuccess] = useState(false); const [success, setSuccess] = useState(false);
...@@ -18,34 +19,36 @@ const JoinRoom = () => { ...@@ -18,34 +19,36 @@ const JoinRoom = () => {
function handleChange(event) { function handleChange(event) {
const { value } = event.target; const { value } = event.target;
setRoomId(value); setRoomId(value);
// console.log(roomId);
} }
async function handleSubmit(e) { async function handleSubmit(e) {
e.preventDefault(); e.preventDefault();
try { try {
// setLoading(true); // setLoading(true);
// setError(""); setError("");
// console.log('userId:', userId) const data = await roomApi.join({ userId: id, roomId: roomId });
// console.log('roomId:', roomId) console.log('서버연결됬나요', data)
const data = await roomApi.join({ userId: userId, roomId: roomId });
// console.log(data);
setSuccess(true); setSuccess(true);
} catch (error) { } catch (error) {
// catchErrors(error, setError); catchErrors(error, setError);
} finally { } finally {
// setLoading(false); // setLoading(false);
} }
} }
if (success) { if (success) {
return <Redirect to="/user" />; // console.log('success', success)
alert('룸참여가 완료되었습니다!')
window.location.href=`/room/${roomId}/1`
} }
return ( return (
<div className="modal-content"> <div className="modal-content">
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<div className="modal-header"> <div className="modal-header">
<div className="modal-title" id="joinModal">방참여하기</div> <div className="modal-title" id="joinModal">
방참여하기
</div>
<button <button
type="button" type="button"
className="btn-close" className="btn-close"
...@@ -54,6 +57,7 @@ const JoinRoom = () => { ...@@ -54,6 +57,7 @@ const JoinRoom = () => {
></button> ></button>
</div> </div>
<div className="modal-body"> <div className="modal-body">
{error && <div className="alert alert-danger">{error}</div>}
<div className="input-group mb-3"> <div className="input-group mb-3">
<input <input
type="text" type="text"
...@@ -67,7 +71,9 @@ const JoinRoom = () => { ...@@ -67,7 +71,9 @@ const JoinRoom = () => {
/> />
</div> </div>
<div className="modal-footer"> <div className="modal-footer">
<button type="submit" className="btn btn-primary"> <button
type="submit"
className="btn btn-primary">
확인 확인
</button> </button>
</div> </div>
...@@ -77,4 +83,4 @@ const JoinRoom = () => { ...@@ -77,4 +83,4 @@ const JoinRoom = () => {
); );
}; };
export default JoinRoom; export default JoinRoom;
\ No newline at end of file
import { useEffect, useState } from 'react'; import { useEffect, useState } from "react";
import { Link } from 'react-router-dom' import { Link, useParams } from "react-router-dom";
import roomApi from '../../apis/room.api'; import roomApi from "../../apis/room.api";
import userApi from '../../apis/user.api'; import userApi from "../../apis/user.api";
import catchErrors from "../../context/catchError";
const id = localStorage.getItem("user");
const INIT_ROOM = {
roomId:"",
name: "",
profileimg: "",
member: "",
};
const RoomSingle = () => { const RoomSingle = () => {
const [roomNum, setRoomNum] = useState('') const [room, setRoom] = useState([INIT_ROOM]);
const [room, setRoom] = useState([]) const [error, setError] = useState("");
const roomId = localStorage.getItem('user'); const channelId = 'main';
const channelId = 1 const {roomId}=useParams(room.roomId);
const A = [] async function getJoinRoom(Id) {
try {
// async function getJoinRoom(Id) { const User = await userApi.getUser(Id);
// try { const RoomNumArr = User.roomNumber;
// console.log('id:',id) const Room = await roomApi.getRoom(RoomNumArr);
// const User = await userApi.getUser({id: Id}) let roomlist = [];
// console.log('User1:',User) for (let prop in Room) {
// console.log('User2:',User.roomNumber) roomlist.push({
// const RoomNumArr = User.roomNumber roomId:Room[prop].id,
// console.log('setRoomNum:',RoomNumArr) name: Room[prop].name,
// const Room = await roomApi.getRoom(RoomNumArr) profileimg: Room[prop].profileimg,
// } catch (error) { member: Room[prop].member.length,
// // catchErrors(error, setError) });
// } }
// } setRoom(roomlist);
} catch (error) {
// useEffect(() => { catchErrors(error, setError);
// getJoinRoom(id) }
// }, [id]) }
useEffect(() => {
getJoinRoom(id);
}, [id]);
const { profileimg } = room;
return ( return (
<Link <div>
to={`/room/${roomId}/${channelId}`} {room &&
className="text-decoration-none text-dark" room.map((el) => (
> <Link
<div to={`/room/${el.roomId}/${channelId}`}
className="d-flex mx-4 my-2 p-2" className="text-decoration-none text-dark"
style={{ backgroundColor: '#C4C4C4' }} >
> <div
<div style={{ width: '37px', height: '37px' }}> className="d-flex mx-4 my-2 p-2"
<img style={{ backgroundColor: "#C4C4C4" }}
src="BORA.png" >
className="rounded-circle" <div style={{ width: "37px", height: "37px" }}>
style={{ width: '37px', height: '37px' }} <img
/> src={`/roomUploads/${el.profileimg}`}
</div> className="rounded-circle"
<div style={{ width: "37px", height: "37px" }}
className="mx-3 mt-2" />
style={{ </div>
width: '250px', <div
overflow:'scroll', className="mx-3 mt-2"
whiteSpace: 'nowrap', style={{
msOverflowStyle:'none', width: "250px",
}} overflow: "scroll",
> whiteSpace: "nowrap",
데계 재미있는 수학과 데계데계데계 재미있는 수학과 msOverflowStyle: "none",
</div> }}
<div className="ms-auto mt-2"> 15/34 </div> >
</div> {el.name}
</div>
</Link> <div className="ms-auto mt-2"> {el.member}/100 </div>
) </div>
} </Link>
))}
</div>
);
};
export default RoomSingle export default RoomSingle;
import React, { useEffect } from "react";
const KakaoShareButton = () => {
useEffect(() => {
createKakaoButton();
}, []);
const ad = "이름"
const createKakaoButton = () => {
// kakao sdk script이 정상적으로 불러와졌으면 window.Kakao로 접근이 가능합니다
if (window.Kakao) {
const kakao = window.Kakao;
// 중복 initialization 방지
if (!kakao.isInitialized()) {
// 두번째 step 에서 가져온 javascript key 를 이용하여 initialize
kakao.init(process.env.REACT_APP_KAKAO_KEY);
}
kakao.Link.createDefaultButton({
container: '#kakao-link-btn',
objectType: 'text',
text:
`${ad}`,
//'기본 템플릿으로 제공되는 텍스트 템플릿은 텍스트를 최대 200자까지 표시할 수 있습니다. 텍스트 템플릿은 텍스트 영역과 하나의 기본 버튼을 가집니다. 임의의 버튼을 설정할 수도 있습니다. 여러 장의 이미지, 프로필 정보 등 보다 확장된 형태의 카카오링크는 다른 템플릿을 이용해 보낼 수 있습니다.',
link: {
mobileWebUrl:
'http://localhost:3000/room/Invite',
webUrl:
'http://localhost:3000/room/Invite',
},
});
}
};
return (
<div className="kakao-share-button">
{/* Kakao share button */}
<button
id="kakao-link-btn"
type="submit"
className="col-2 p-1 btn btn-primary"
data-bs-dismiss="modal"
style={{ width: "120px" }}
>카카오로 초대
</button>
</div>
);
};
export default KakaoShareButton;
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { Redirect } from 'react-router-dom' import { Link } from 'react-router-dom'
import userApi from '../apis/user.api' import userApi from '../apis/user.api'
import catchErrors from "../context/catchError"; import catchErrors from '../context/catchError'
import { handleLogin } from '../context/auth'; import { handleLogin } from '../context/auth'
const INIT_USER = { const INIT_USER = {
userId: '9999',
email: '', email: '',
password: '', password: '',
} }
const Login = () => { const Login = () => {
// const { loading, login, catchErrorAuth } = useAuth()
const [user, setUser] = useState(INIT_USER) const [user, setUser] = useState(INIT_USER)
const [disabled, setDisabled] = useState(true) const [disabled, setDisabled] = useState(true)
const [error, setError] = useState('') const [error, setError] = useState('')
const [success, setSuccess] = useState(false) const [success, setSuccess] = useState(false)
const [id, setId] = useState('')
useEffect(() => { useEffect(() => {
const isUser = Object.values(user).every((el) => Boolean(el)) const isUser = Object.values(user).every((el) => Boolean(el))
...@@ -27,12 +28,13 @@ const Login = () => { ...@@ -27,12 +28,13 @@ const Login = () => {
async function handleSubmit(e) { async function handleSubmit(e) {
e.preventDefault() e.preventDefault()
console.log('로그인')
try { try {
// setLoading(true); // setLoading(true);
// setError(""); // setError("");
console.log('user정보:', user)
const data = await userApi.login(user) const data = await userApi.login(user)
console.log(data) console.log(data)
setId(data.id)
handleLogin(data.id) handleLogin(data.id)
setSuccess(true) setSuccess(true)
} catch (error) { } catch (error) {
...@@ -43,63 +45,59 @@ const Login = () => { ...@@ -43,63 +45,59 @@ const Login = () => {
} }
} }
if (success) { if (success) {
alert('로그인 되었습니다') alert('로그인 되었습니다');
return <Redirect to="/user" /> window.location.href = `/user/${id}`
} }
const { email, password } = user const { email, password } = user
return ( return (
<div className="modal-content"> <div className="container">
{error && <div className="alert alert-danger">{error}</div>}
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit}>
<div className="modal-header"> <div className="m-3 d-flex justify-content-center">
<h5 className="modal-title" id="loginModalLabel"> <Link to="/">
로그인 <img src="/BORA.png" style={{ width: '160px' }} />
</h5> </Link>
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div> </div>
<div className="modal-body"> <div className="row mt-5 d-flex align-items-center">
<div> <h2 style={{ textAlign: 'center' }}>로그인</h2>
<label>아이디</label> {error && <div className="alert alert-danger">{error}</div>}
<input <div className="form-group">
className="form-control" <div className="mt-5">
id="email" <label>아이디</label>
type="text" <input
name="email" className="form-control"
placeholder="아이디를 입력하세요" id="email"
value={email} type="text"
onChange={handleChange} name="email"
/> placeholder="아이디를 입력하세요"
value={email}
onChange={handleChange}
/>
</div>
<div className="mt-3">
<label>비밀번호</label>
<input
className="form-control"
id="password"
type="password"
name="password"
placeholder="비밀번호를 입력하세요"
value={password}
onChange={handleChange}
/>
</div>
</div> </div>
<div> <div className="mt-4 d-flex justify-content-center">
<label>비밀번호</label> <button
<input type="submit"
className="form-control" className="btn btn-primary"
id="loginPassword" disabled={disabled}
type="password" >
name="password" 로그인
placeholder="비밀번호를 입력하세요" </button>
value={password}
onChange={handleChange}
/>
</div> </div>
</div> </div>
<div className="modal-footer">
<button
type="submit"
className="btn btn-primary"
disabled={disabled}
data-bs-dismiss="modal"
>
로그인
</button>
</div>
</form> </form>
</div> </div>
) )
......
import userApi from "../../apis/user.api"; import userApi from "../../apis/user.api";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import catchErrors from "../../context/catchError";
const userprofile = localStorage.getItem("user"); const userprofile = localStorage.getItem("user");
const INIT_PROFILE = { const INIT_PROFILE = {
...@@ -11,12 +12,15 @@ const INIT_PROFILE = { ...@@ -11,12 +12,15 @@ const INIT_PROFILE = {
const Info = () => { const Info = () => {
const [profile, setProfile] = useState(INIT_PROFILE); const [profile, setProfile] = useState(INIT_PROFILE);
const [error, setError]= useState("");
async function getProfile(userID) { async function getProfile(userID) {
try { try {
const data = await userApi.getUser(userID); const data = await userApi.getUser(userID);
setProfile(data); setProfile(data);
} catch (error) {} } catch (error) {
catchErrors(error, setError);
}
} }
useEffect(() => { useEffect(() => {
getProfile(userprofile); getProfile(userprofile);
......
import { Link, useParams } from "react-router-dom"; import { Link, useParams } from "react-router-dom";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import userApi from "../../apis/user.api"; import userApi from "../../apis/user.api";
import catchErrors from "../../context/catchError";
const userprofile = localStorage.getItem("user"); const userprofile = localStorage.getItem("user");
const INIT_PROFILE = { const INIT_PROFILE = {
...@@ -16,12 +17,15 @@ const InfoUpdate = () => { ...@@ -16,12 +17,15 @@ const InfoUpdate = () => {
const [profile, setProfile] = useState(INIT_PROFILE); const [profile, setProfile] = useState(INIT_PROFILE);
const [error,setError]=useState("");
async function getProfile(userID) { async function getProfile(userID) {
try { try {
const data = await userApi.getUser(userID); const data = await userApi.getUser(userID);
setProfile(data); setProfile(data);
} catch (error) {} } catch (error) {
catchErrors(error, setError);
}
} }
useEffect(() => { useEffect(() => {
...@@ -30,6 +34,7 @@ const InfoUpdate = () => { ...@@ -30,6 +34,7 @@ const InfoUpdate = () => {
const handleChange = async (event) => { const handleChange = async (event) => {
const { files } = event.target; const { files } = event.target;
console.log('files:',files)
let formData = new FormData(); let formData = new FormData();
formData.append("img", files[0]); formData.append("img", files[0]);
formData.append("id", userprofile); formData.append("id", userprofile);
...@@ -39,7 +44,9 @@ const InfoUpdate = () => { ...@@ -39,7 +44,9 @@ const InfoUpdate = () => {
setProfile({...profile, img:res}) setProfile({...profile, img:res})
}else{ }else{
setProfile() setProfile()
} } catch (error) {} } } catch (error) {
catchErrors(error, setError);
}
}; };
const changeinfo = async (event) => { const changeinfo = async (event) => {
......
import { Link, useParams } from "react-router-dom"; import { Link, useParams } from "react-router-dom";
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import userApi from "../../apis/user.api"; import userApi from "../../apis/user.api";
import catchErrors from "../../context/catchError";
const userprofile = localStorage.getItem("user"); const userprofile = localStorage.getItem("user");
const INIT_PROFILE = { const INIT_PROFILE = {
...@@ -11,14 +11,18 @@ const INIT_PROFILE = { ...@@ -11,14 +11,18 @@ const INIT_PROFILE = {
const Profile = () => { const Profile = () => {
const [profile, setProfile] = useState(INIT_PROFILE); const [profile, setProfile] = useState(INIT_PROFILE);
const [error,setError]= useState("");
async function getProfile(userID) { async function getProfile(userID) {
try { try {
const data = await userApi.getUser(userID); const data = await userApi.getUser(userID);
console.log(data)
setProfile(data.img) setProfile(data.img)
} catch (error) {} } catch (error) {
catchErrors(error, setError);
}
} }
console.log(profile)
useEffect(() => { useEffect(() => {
getProfile(userprofile); getProfile(userprofile);
}, [userprofile]); }, [userprofile]);
......
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import React, { useState } from 'react'; import React, { useState } from 'react';
import LeftHamburger from './LeftHamburger';
import RightHamburger from './RightHamburger'; import RightHamburger from './RightHamburger';
const ChannelList = () => { const ChannelList = () => {
const id = localStorage.getItem('user');
return ( return (
<div> <div>
<nav className="navbar navbar-light d-flex justify-content-between"> <nav className="navbar navbar-light ">
<LeftHamburger /> <div className="col-2"></div>
<div> <div>
<Link to="/user"> <Link to={`/user/${id}`}>
<img src="/BORA.png" style={{ width: '160px' }} /> <img src="/BORA.png" style={{ width: '160px' }} />
</Link> </Link>
</div> </div>
......
const ChannelSingle = () => { import { Link, Route, Switch, useParams } from "react-router-dom";
return (
<div className="overflow-auto" style={{ height: '610px' }}>
<div className="mb-3">
<div className="m-3 p-1 row" style={{ backgroundColor: '#E0CEE8' }}>
<img
className="col-auto mt-2"
src="/fullSpeaker.png"
width="25px"
height="25px"
/>
<h5 className="col mt-2">회의</h5>
</div>
<ul className="mx-5" style={{ color: '#76D079' }}>
<li>
<p style={{ color: 'black' }}>CHERRY</p>
</li>
<li>
<p style={{ color: 'black' }}>JAEYEON</p>
</li>
<li>
<p style={{ color: 'black' }}>SEOYEON</p>
</li>
<li>
<p style={{ color: 'black' }}>JIWEON</p>
</li>
<li>
<p style={{ color: 'black' }}>BYOUNGYUN</p>
</li>
</ul>
</div>
<div className="mb-3">
<div className="m-3 p-1 row" style={{ backgroundColor: '#E0CEE8' }}>
<img
className="col-auto mt-2"
src="/emptySpeaker.png"
width="25px"
height="25px"
/>
<h5 className="col mt-2">사담</h5>
</div>
<ul className="mx-5" style={{ color: '#76D079' }}>
<li>
<p style={{ color: 'black' }}>CHERRY</p>
</li>
<li>
<p style={{ color: 'black' }}>JAEYEON</p>
</li>
<li>
<p style={{ color: 'black' }}>SEOYEON</p>
</li>
<li>
<p style={{ color: 'black' }}>JIWEON</p>
</li>
<li>
<p style={{ color: 'black' }}>BYOUNGYUN</p>
</li>
</ul>
</div>
<div className="mb-3"> const ChannelSingle = (props) => {
<div className="m-3 p-1 row" style={{ backgroundColor: '#E0CEE8' }}> const { roomId } = useParams();
<img console.log("props", props.channel);
className="col-auto mt-2" return (
src="/emptySpeaker.png" <div>
width="25px" <div className="overflow-auto" style={{ height: "610px" }}>
height="25px" {props.channel.map((el) => (
/> <div className="mb-3">
<h5 className="col mt-2">일반</h5> <Link to={`${roomId}/${el.channelName}`}>
</div> <div
<ul className="mx-5" style={{ color: '#76D079' }}> className="m-3 p-1 row"
<li> style={{ backgroundColor: "#E0CEE8" }}
<p style={{ color: 'black' }}>CHERRY</p> >
</li> <img
<li> className="col-auto mt-2"
<p style={{ color: 'black' }}>JAEYEON</p> src="/fullSpeaker.png"
</li> width="25px"
<li> height="25px"
<p style={{ color: 'black' }}>SEOYEON</p> />
</li> <h5 className="col mt-2" style={{ color: "black" }}>
<li> {el.channelName}
<p style={{ color: 'black' }}>JIWEON</p> </h5>
</li> </div>{" "}
<li> </Link>
<p style={{ color: 'black' }}>BYOUNGYUN</p>
</li>
</ul>
</div>
<div className="mb-3"> {el.joinName &&
<div className="m-3 p-1 row" style={{ backgroundColor: '#E0CEE8' }}> el.joinName.map((e) => (
<img <div>
className="col-auto mt-2" <ul className="mx-5" style={{ color: "#76D079" }}>
src="/emptySpeaker.png" <li>
width="25px" <p style={{ color: "black" }}>{e}</p>
height="25px" </li>
/> </ul>
<h5 className="col mt-2">공지</h5> </div>
</div> ))}
<ul className="mx-5" style={{ color: '#76D079' }}> </div>
<li> ))}
<p style={{ color: 'black' }}>CHERRY</p>
</li>
<li>
<p style={{ color: 'black' }}>JAEYEON</p>
</li>
<li>
<p style={{ color: 'black' }}>SEOYEON</p>
</li>
<li>
<p style={{ color: 'black' }}>JIWEON</p>
</li>
<li>
<p style={{ color: 'black' }}>BYOUNGYUN</p>
</li>
</ul>
</div> </div>
</div> </div>
) );
} };
export default ChannelSingle export default ChannelSingle;
import ScreenSelect from './ScreenSelect' import ScreenSelect from './ScreenSelect'
import video_btn from '../../images/videobtn.png'
import speaker_btn from '../../images/speakerbtn.png'
import mic_btn from '../../images/micbtn.png'
import videooff_btn from '../../images/videooffbtn.png'
import speakeroff_btn from '../../images/speakeroffbtn.png'
import micoff_btn from '../../images/micoffbtn.png'
import React, { useState } from 'react'; import React, { useState } from 'react';
const Controller = () => { const Controller = () => {
const [mic, setMic] = useState("true") const [mic, setMic] = useState(true)
const [speaker, setSpeaker] = useState("true") const [speaker, setSpeaker] = useState(true)
const [video, setVideo] = useState("true") const [video, setVideo] = useState(true)
const micOn = (() => setMic(false)); const micOn = (() => setMic(false));
const micOff = (() => setMic(true)); const micOff = (() => setMic(true));
...@@ -29,22 +23,22 @@ const Controller = () => { ...@@ -29,22 +23,22 @@ const Controller = () => {
{mic ? <div className="col d-flex justify-content-center"> {mic ? <div className="col d-flex justify-content-center">
<button type="button" className="btn" onClick={micOn}> <button type="button" className="btn" onClick={micOn}>
<img src={micoff_btn} width="45" height="40" /> <img src="/micoffbtn.png" width="45" height="40" />
</button> </button>
</div> </div>
: <div className="col d-flex justify-content-center"> : <div className="col d-flex justify-content-center">
<button type="button" className="btn" onClick={micOff}> <button type="button" className="btn" onClick={micOff}>
<img src={mic_btn} width="45" height="40" /> <img src="/micbtn.png" width="45" height="40" />
</button> </button>
</div> </div>
} }
{speaker ? <div className="col d-flex justify-content-center"> {speaker ? <div className="col d-flex justify-content-center">
<button type="button" className="btn" onClick={speakerOn}> <button type="button" className="btn" onClick={speakerOn}>
<img src={speakeroff_btn} width="45" /> <img src="/speakeroffbtn.png" width="45" />
</button> </button>
</div> : <div className="col d-flex justify-content-center"> </div> : <div className="col d-flex justify-content-center">
<button type="button" className="btn" onClick={speakerOff}> <button type="button" className="btn" onClick={speakerOff}>
<img src={speaker_btn} width="45" /> <img src="/speakerbtn.png" width="45" />
</button> </button>
</div> </div>
} }
...@@ -57,12 +51,12 @@ const Controller = () => { ...@@ -57,12 +51,12 @@ const Controller = () => {
onClick="location.href='ScreenSelect.js'" onClick="location.href='ScreenSelect.js'"
onClick={videoOn} onClick={videoOn}
> >
<img src={videooff_btn} width="45" /> <img src="/videooffbtn.png" width="45" />
</button> </button>
</div> : </div> :
<div className="col d-flex justify-content-center"> <div className="col d-flex justify-content-center">
<button type="button" className="btn" onClick={videoOff}> <button type="button" className="btn" onClick={videoOff}>
<img src={video_btn} width="45" /> <img src="/videobtn.png" width="45" />
</button> </button>
</div>} </div>}
</div> </div>
......
import { useEffect, useState } from "react";
import catchErrors from "../../context/catchError";
import { useParams } from "react-router-dom";
import roomApi from "../../apis/room.api";
const INIT_ROOM = {
id: "",
name: "",
profileimg: "",
};
const InitRoom = () => {
const { roomId } = useParams();
const [room, setRoom] = useState(INIT_ROOM);
const [error, setError] = useState("");
async function getRoom(roomId) {
console.log(roomId)
try {
const data = await roomApi.getRoom([roomId]);
setRoom(data[0]);
} catch (error) {
catchErrors(error, setError);
}
}
console.log(room)
useEffect(() => {
console.log('roomId확인', roomId)
getRoom(roomId);
}, [roomId]);
return (
<div>
<div style={{ backgroundColor: "#262626", width: "auto", height: "2px" }} />
<form className="flex-row align-items-center justify-content-center m-5">
<div className="d-flex justify-content-center">
<img
src={`/roomUploads/${room.profileimg}`}
className="rounded-circle"
style={{
width: "250px",
height: "250px",
}}
/>
</div>
<div className="d-flex justify-content-center mt-3">
<div>
<div className="row">
<h6 className="col" style={{ text: 'center' }}> 방이름 </h6>
<h4 className="col"> {room.name} </h4>
</div>
<div className="row">
<h6 className="col"> 방코드 </h6>
<h4 className="col"> {room.id} </h4>
</div>
</div>
</div>
</form>
</div>
);
};
export default InitRoom;
import backward from "../../images/backward.png";
import ChannelSingle from "./ChannelSingle";
const LeftHamberger = () => {
function roomIdCopy() {
const t = document.querySelector("#roomId").innerText;
console.log(t);
navigator.clipboard.writeText(t);
document.execCommand("copy");
}
return (
<div>
<div>
<button
className="navbar-toggler"
type="button"
data-bs-toggle="offcanvas"
data-bs-target="#left-hamburger"
aria-controls="left-hamburger"
aria-expanded="false"
aria-label="Toggle navigation"
style={{ border: "#f4c1f2" }}
>
<span className="navbar-toggler-icon"></span>
</button>
</div>
<div
className="offcanvas offcanvas-start"
style={{ width: "330px" }}
tabIndex="-1"
id="left-hamburger"
aria-labelledby="hamburgerLabel"
>
<div className="offcanvas-header">
<p
className="col-6 offcanvas-title"
id="offcanvasExampleLabel"
style={{
fontWeight: "bold",
fontSize: "15px",
width: "150px",
color: "#000000",
}}
>
/오프라인 사용자
</p>
<h6 className="mt-2" id="roomId">
{" "}
#ASV2AE985{" "}
</h6>
<button
type="button"
className="btn-close text-reset"
data-bs-dismiss="offcanvas"
aria-label="Close"
></button>
</div>
<div className="overflow-auto" style={{ height: "610px" }}>
<div className="mb-3">
<div className="m-3 p-1 row" style={{ backgroundColor: "#E0CEE8" }}>
<h5 className="col mt-2">온라인 사용자</h5>
</div>
<ul className="mx-5" style={{ color: "#76D079" }}>
<li>
<p style={{ color: "black" }}>CHERRY</p>
</li>
<li>
<p style={{ color: "black" }}>JAEYEON</p>
</li>
<li>
<p style={{ color: "black" }}>SEOYEON</p>
</li>
<li>
<p style={{ color: "black" }}>JIWEON</p>
</li>
<li>
<p style={{ color: "black" }}>BYOUNGYUN</p>
</li>
</ul>
</div>
<div className="mb-3">
<div className="m-3 p-1 row" style={{ backgroundColor: "#E0CEE8" }}>
<h5 className="col mt-2">오프라인 사용자</h5>
</div>
<ul className="mx-5">
<li>CHERRY</li>
<li>JAEYEON</li>
<li>SEOYEON</li>
<li>JIWEON</li>
<li>BYOUNGYUN</li>
</ul>
</div>
</div>
<div>
<div className="d-flex flex-row-reverse">
<button
type="button"
className="m-3 rounded"
data-bs-toggle="modal"
data-bs-target="#inviteRoom"
style={{
height: "30px",
fontWeight: "bold",
backgroundColor: "#E0CEE8",
color: "black",
border: "1px #D64D61",
}}
>
초대
</button>
<div
className="modal fade"
id="inviteRoom"
tabIndex="-1"
aria-labelledby="exitRoomLabel"
aria-hidden="true"
>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body d-flex justify-content-center">
어떤 방식으로 초대하시겠습니까?
</div>
<div className="row mb-3">
<div className="d-flex justify-content-evenly">
<button
type="submit"
className="col-2 p-1 btn btn-primary"
style={{ width: "120px" }}
>
카카오로 초대
</button>
{/*
<button
type="submit"
className="col-2 p-1 btn btn-primary"
data-bs-toggle="modal"
data-bs-target="#copyRoomId"
onClick={roomIdCopy}
style={{ width: "120px" }}
>
방 Id 복사
</button> */}
<button
type="submit"
className="col-2 p-1 btn btn-primary"
data-bs-dismiss="modal"
style={{ width: "120px" }}
onClick={roomIdCopy}
>
Id 복사
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default LeftHamberger;
import { useState } from "react"; import { useState, useEffect } from "react";
import ChannelSingle from './ChannelSingle' import { useParams } from "react-router-dom";
import ChannelSingle from "./ChannelSingle";
import Rightimg from "../../images/RightHamburgerImg.png";
import RoomApi from "../../apis/room.api";
import roomApi from "../../apis/room.api";
import catchErrors from "../../context/catchError";
const RightHamberger = () => { const INIT_CHANNEL = {
const [admin, setAdmin] = useState('true') channelName: "",
return ( joinName: [],
<div> };
<div>
<button const INIT_ROOM = {
className="navbar-toggler" name: "",
type="button" };
data-bs-toggle="offcanvas" const RightHamburger = () => {
data-bs-target="#right-hamburger" const [channel, setChannel] = useState([INIT_CHANNEL]);
aria-controls="right-hamburger" const [room, setRoom] = useState([INIT_ROOM]);
aria-expanded="false" const { roomId } = useParams();
aria-label="Toggle navigation" const [error, setError] = useState("");
style={{ border: '#f4c1f2' }}
> async function getroom(Id) {
<span className="navbar-toggler-icon"></span> try {
</button> const Room = await roomApi.getRoom([Id]);
</div> setRoom({...room, name:Room[0].name})
} catch (error) {
catchErrors(error, setError);
}
}
async function getChannel(roomId) {
// console.log('roomId', roomId)
const ID = roomId;
try {
const data = await roomApi.getRoom([ID]);
const Channel = data[0].channel;
// console.log('방데이터:', Channel)
const channelList = [];
for (const prop in Channel) {
// Channel의 항목(prop)으로 작업을 실행합니다
for (const key in Channel[prop]) {
// console.log(key)
// console.log(prop)
// console.log(Channel[prop][key])
channelList.push({
channelName: key,
joinName: Channel[prop][key],
});
}
}
setChannel(channelList);
} catch (error) {
catchErrors(error, setError);
}
}
// console.log(channel)
useEffect(() => {
getChannel(roomId);
getroom(roomId)
}, [roomId]);
function roomIdCopy() {
const t = document.querySelector("#roomId").innerText;
console.log(t);
navigator.clipboard.writeText(t);
document.execCommand("copy");
}
return (
<div>
<div>
<button
className="navbar-toggler"
type="button"
data-bs-toggle="offcanvas"
data-bs-target="#right-hamburger"
aria-controls="right-hamburger"
aria-expanded="false"
aria-label="Toggle navigation"
style={{ border: "#f4c1f2" }}
>
<img src={Rightimg} width="50px" height="30px" />
</button>
</div>
<div
className="offcanvas offcanvas-end"
style={{ width: "330px" }}
tabIndex="-1"
id="right-hamburger"
aria-labelledby="hamburgerLabel"
>
<div className="offcanvas-header">
<p
className="col-6 offcanvas-title"
id="offcanvasExampleLabel"
style={{
fontWeight: "bold",
fontSize: "15px",
overflow: "hidden",
whiteSpace: "nowrap",
width: "150px",
color: "#000000",
}}
>
{room.name}
</p>
<h6 className="mt-2" id="roomId">
{" "}
{`${roomId}`}{" "}
</h6>
<button
type="button"
className="btn-close text-reset"
data-bs-dismiss="offcanvas"
aria-label="Close"
></button>
</div>
<ChannelSingle channel={channel} />
<div>
<div className="d-flex flex-row-reverse">
<button
type="button"
className="m-3 rounded"
data-bs-toggle="modal"
data-bs-target="#inviteRoom"
style={{
height: "30px",
fontWeight: "bold",
backgroundColor: "#E0CEE8",
color: "black",
border: "1px #D64D61",
}}
>
초대
</button>
<div <div
className="offcanvas offcanvas-end" className="modal fade"
style={{ width: '330px' }} id="inviteRoom"
tabIndex="-1" tabIndex="-1"
id="right-hamburger" aria-labelledby="exitRoomLabel"
aria-labelledby="hamburgerLabel" aria-hidden="true"
> >
<div className="offcanvas-header"> <div className="modal-dialog">
<p <div className="modal-content">
className="col-6 offcanvas-title" <div className="modal-header">
id="offcanvasExampleLabel"
style={{
fontWeight: 'bold',
fontSize: '15px',
overflow: 'hidden',
whiteSpace: 'nowrap',
width: '150px',
color: '#000000',
}}
>
데계데계데계데계데계데계데계데계데계데계 재밌는 수학과
</p>
<h6 className="mt-2" id="roomId" > #ASV2AE985 </h6>
<button <button
type="button" type="button"
className="btn-close text-reset" className="btn-close"
data-bs-dismiss="offcanvas" data-bs-dismiss="modal"
aria-label="Close" aria-label="Close"
></button> ></button>
</div> </div>
<div className="modal-body d-flex justify-content-center">
<ChannelSingle /> 어떤 방식으로 초대하시겠습니까?
<div> </div>
<div className="d-flex flex-row-reverse"> <div className="row mb-3">
<button <div className="d-flex justify-content-evenly">
type="button" <button
className="m-3 rounded text-white" type="submit"
data-bs-toggle="modal" className="col-2 p-1 btn btn-primary"
data-bs-target="#exitRoom" style={{ width: "120px" }}
style={{ >
height: '30px', 카카오로 초대
fontWeight: 'bold', </button>
backgroundColor: '#d86da6', {/*
color: 'black',
border: '1px #d86da6',
}}
>
퇴장
</button>
{admin ? <button
type="button"
className="m-3 rounded"
style={{
height: '30px',
fontWeight: 'bold',
backgroundColor: '#E0CEE8',
color: 'black',
border: '1px #D64D61',
}}
>
설정
</button> : null}
<div
className="modal fade"
id="exitRoom"
tabIndex="-1"
aria-labelledby="exitRoomLabel"
aria-hidden="true"
>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body d-flex justify-content-center">
이방에서 퇴장하시겠습니까?
</div>
<div className="row mb-3">
<div className="d-flex justify-content-evenly">
{/* <Link to="/user"> */}
<button <button
type="submit" type="submit"
className="col-2 p-1 btn btn-primary" className="col-2 p-1 btn btn-primary"
data-bs-dismiss="modal" data-bs-toggle="modal"
data-bs-target="#copyRoomId"
onClick={roomIdCopy}
style={{ width: "120px" }}
> >
방 Id 복사
</button> </button> */}
{/* </Link> */} <button
<button type="submit"
type="submit" className="col-2 p-1 btn btn-primary"
className="col-2 p-1 btn btn-primary" data-bs-dismiss="modal"
data-bs-dismiss="modal" style={{ width: "120px" }}
> onClick={roomIdCopy}
아니요 >
</button> Id 복사
</div> </button>
</div>
</div>
</div>
</div>
</div> </div>
</div>
</div> </div>
</div>
</div> </div>
</div > <div>
) <div>
<button
type="button"
className="m-3 rounded text-white"
data-bs-toggle="modal"
data-bs-target="#exitRoom"
style={{
height: "30px",
fontWeight: "bold",
backgroundColor: "#d86da6",
color: "black",
border: "1px #d86da6",
}}
>
퇴장
</button>
{/* {admin ? (
<button
type="button"
className="m-3 rounded"
style={{
height: "30px",
fontWeight: "bold",
backgroundColor: "#E0CEE8",
color: "black",
border: "1px #D64D61",
}}
>
설정
</button>
) : null} */}
} <div
className="modal fade"
id="exitRoom"
tabIndex="-1"
aria-labelledby="exitRoomLabel"
aria-hidden="true"
>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div className="modal-body d-flex justify-content-center">
이방에서 퇴장하시겠습니까?
</div>
<div className="row mb-3">
<div className="d-flex justify-content-evenly">
{/* <Link to="/user/:id"> */}
<button
type="submit"
className="col-2 p-1 btn btn-primary"
data-bs-dismiss="modal"
>
</button>
{/* </Link> */}
<button
type="submit"
className="col-2 p-1 btn btn-primary"
data-bs-dismiss="modal"
>
아니요
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default RightHamberger export default RightHamburger;
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment