Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
a1622d3
#1 feat : 회원가입 페이지 UI 구현
judahhh Mar 15, 2023
24a24ae
Merge pull request #2 from 2023-SejongCreative/feature/1
judahhh Mar 15, 2023
250facd
refactor : 반복되는 코드 수정
judahhh Mar 19, 2023
3b9ff3e
#3 feat : 로그인 페이지 UI 구현
judahhh Mar 19, 2023
674513f
Merge pull request #4 from 2023-SejongCreative/feature/3
judahhh Mar 19, 2023
a1c8a28
build : axios 설치
judahhh Mar 20, 2023
3f3a5a1
feat : json server로 가짜 서버 생성
judahhh Mar 20, 2023
f5c33ff
build : 프록시 설정하기 위해 http-proxy-middleware 설치
judahhh Mar 22, 2023
652c7d2
chore : 서버 ip 주소 받아 프록시 설정
judahhh Mar 22, 2023
b11e98d
feat : 기본 경로를 Login컴포넌트에서 Home컴포넌트로 변경
judahhh Mar 22, 2023
ffd34df
feat : 메인 페이지 폴더 추가
judahhh Mar 22, 2023
b09186e
feat : axios interceptor 적용한 파일 추가
judahhh Mar 22, 2023
f5a824d
feat : 로그인 분기 처리
judahhh Mar 24, 2023
d286a73
feat : 사용자가 입력한 로그인 정보 서버에 post
judahhh Mar 27, 2023
3171533
feat : 사용자가 입력한 회원가입 정보 서버에 post 전송
judahhh Mar 27, 2023
21421cd
chore : material icon 설치
judahhh Mar 28, 2023
0f05392
feat : axios interceptor 파일 적용
judahhh Mar 28, 2023
2f001f8
#3 feat : 로그인 통신 기능 구현(jwt미완)
judahhh Mar 28, 2023
e16442a
#3 style : 로그인 버튼 아래 회원가입하러 가는 버튼 스타일 추가
judahhh Mar 28, 2023
4f38496
#1 feat : 회원가입 통신기능 구현 및 유효성 검사
judahhh Mar 28, 2023
f698cc0
#1 style : 회원가입 버튼 아래 로그인 페이지로 가는 버튼 스타일 추가
judahhh Mar 28, 2023
ceb6e64
chore : 서버 ip 주소 변경
judahhh Mar 28, 2023
7d1d751
feat : json server 더미 데이터에 user data 추가
judahhh Mar 29, 2023
aa2627a
feat : 테스트 서버 ip 주소 변경
judahhh Mar 29, 2023
5e48e1a
#3 feat : 로그인 성공시 jwt localStorage에 저장
judahhh Mar 29, 2023
0029d5f
feat : console 찍는 코드 삭제
judahhh Mar 29, 2023
02343cd
feat : axios 인터셉터 파일 생성
judahhh Apr 4, 2023
ce95f0c
feat : home 페이지 헤더 및 사이드 바 구현
judahhh Apr 4, 2023
94d5e9d
chore : redux toolkit 설치
judahhh Apr 4, 2023
5515740
feat : 회원가입 유효성 검사 기능 추가
judahhh Apr 4, 2023
0677d7b
feat : 로그인 성공했을 경우 jwt 로컬스토리지에 저장 및 로그인 연장 기능 구현
judahhh Apr 4, 2023
42bd24d
feat : 페이지 새로고침 됐을 경우 access 토큰 만료여부를 체크하는 함수를 다시 호출하도록 구현
judahhh Apr 4, 2023
7dd3a14
chore : redux toolkit 설치
judahhh Apr 4, 2023
7baed56
feat : refresh token 만료됐을 경우 로컬스토리지에서 토큰 삭제 후 자동 로그아웃 처리
judahhh Apr 5, 2023
43bf69c
refactor : 회원가입 폼 입력 시 실행되는 함수를 따로 두지 않고 바로 useState의 set함수로 실행되도록 변경
judahhh Apr 7, 2023
ab9ee57
feat : redux-toolkit으로 사용자의 정보를 전역 store에 저장
judahhh Apr 7, 2023
f336b3c
feat : 최상위 루트 컴포넌트를 store로 묶음
judahhh Apr 7, 2023
ee22e46
refactor : 로그인 폼 입력 시 함수를 따로 두지 않고 useState의 set 함수가 바로 실행되도록 변경
judahhh Apr 7, 2023
dec1edb
feat : 홈에서 사이드바를 컴포넌트로 분리
judahhh Apr 12, 2023
f76ad91
chore : strictmode 제거
judahhh Apr 12, 2023
5d0a480
fix : 새로고침하면 axios network 에러나는 문제를 해결하기 위해 defaults.headers에 넣어줌
judahhh Apr 12, 2023
6fbad30
chore : json server로 통신 확인하기 위해 mockdata 추가
judahhh Apr 12, 2023
239322b
feat : rtk가 만료되었을 경우 401 에러 처리
judahhh Apr 12, 2023
901b06c
fix : 각 페이지별 파라미터 변수명 수정
judahhh Apr 12, 2023
216c72b
fix : 회원가입 유효성 검사 수정
judahhh Apr 12, 2023
2ab1a85
feat : 그룹 슬라이스 추가
judahhh Apr 12, 2023
d5ce8ce
feat : 그룹, 룸 만들기 기능 추가
judahhh Apr 12, 2023
33a7bf9
feat : 각 그룹을 클릭하면 그룹 별 페이지로 이동
judahhh Apr 12, 2023
5a08ec0
feat : 각 룸을 클릭하면 룸 별 페이지로 이동
judahhh Apr 12, 2023
621bdee
feat : 그룹 정보 추가, 삭제 리듀서 추가
judahhh Apr 12, 2023
88f5dc6
feat : 로컬 스토리지에 로그인 여부 추가
judahhh Apr 12, 2023
eb6ef8e
feat : 로컬 스토리지에 로그인 여부 저장
judahhh Apr 12, 2023
f8ec7e3
feat : 로그인 되어있지 않다면 로그인 페이지로 이동
judahhh Apr 12, 2023
ed205cb
style : 목록 리스트 스타일 수정
judahhh Apr 12, 2023
33e6c96
feat : 그룹 생성 후 모달창 자동 close
judahhh Apr 13, 2023
c8a70cf
feat : 로그인 후 localStorage에 이메일 저장
judahhh Apr 13, 2023
ced7b97
feat : localStorage에 있는 이메일 get
judahhh Apr 13, 2023
2d99d63
feat : 그룹에서 사용자 초대 후 모달창 자동 close
judahhh Apr 13, 2023
9f8d3d6
feat : 룸에서 사용자 초대 후 모달창 자동 close
judahhh Apr 13, 2023
c0e029c
feat : 룸 생성 완료 후 모달창 자동 close
judahhh Apr 13, 2023
4b105c4
fix : 그룹 삭제 관리자만 가능하도록 수정
judahhh Apr 13, 2023
2bedd26
feat : 그룹 목록 호출 시 이메일을 localStorage에서 get하여 api 호출
judahhh Apr 13, 2023
b3a8ee2
fix : 룸삭제 시 관리자만 삭제할 수 있도록 수정
judahhh Apr 13, 2023
a4536ae
fix : baseURL 수정
judahhh Apr 13, 2023
c929851
fix : mock data 목록 수정
judahhh Apr 13, 2023
3772008
chore : 소켓 프록시 설정
judahhh Apr 19, 2023
f015ae0
feat : 채팅 페이지 라우팅 및 파일 이동
judahhh Apr 19, 2023
ac74138
fix : 로컬스토리지 값 이름 변경
judahhh Apr 19, 2023
accb254
fix :로그인확인하는 로컬스토리지 값 이름 변경
judahhh Apr 19, 2023
d0abcdc
fix : 로그인확인하는 로컬스토리지 값 이 름 변경
judahhh Apr 19, 2023
d102c0a
fix : 채팅 페이지 컴포넌트 이름 변경
judahhh Apr 19, 2023
e4c3b67
fix : 로그아웃 후 로컬 스토리지에 로그인 여부 false 로 변경
judahhh Apr 19, 2023
74d490e
style : 채팅 페이지 퍼블리싱
judahhh Apr 19, 2023
231fab2
feat : 페이지가 렌더링 될 때 채팅 목록 불러오기
judahhh Apr 21, 2023
e063a35
feat : 채팅 리스트 목록으로 나열
judahhh Apr 21, 2023
bd3d25c
feat : chatPage와 chatDetail 페이지 분리
judahhh Apr 21, 2023
8fcd2ab
fix : 페이지 url 변경
judahhh Apr 21, 2023
34aa4db
fix : 채팅 리스트를 chatListArea에서 불러오도록 수정
judahhh Apr 21, 2023
35622c5
feat : 채팅방 생성 모달창에서 초대할 사람 5명까지 수정 및 서버로 채팅방 정보 전송
judahhh Apr 21, 2023
4bfabc0
fix : 채팅리스트 불러오는 부분 삭제
judahhh Apr 21, 2023
5d93b5d
feat : 채팅방 생성 기능 추가
judahhh Apr 23, 2023
fec52e9
feat : 채팅방 안에서 친구 초대, 채팅방 나가기 기능 추가
judahhh Apr 23, 2023
0fa4e65
fix : 채팅방 소켓 연결 connect, subscribe, send 함수 api 수정
judahhh Apr 24, 2023
9bc0727
feat : 채팅방 생성, 삭제, 채팅방에 사용자 초대, 채팅방 목록 조회 기능 추가
judahhh May 1, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions db.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"groups": [
{ "manager": 1, "group_name": "창의학기제", "group_id": 6 },
{ "manager": 1, "group_name": "캡스톤", "group_id": 10 },
{ "manager": 1, "group_name": "동아리", "group_id": 13 },
{ "manager": 1, "group_name": "회사", "group_id": 15 },
{ "manager": 1, "group_name": "그룹5", "group_id": 17 }
],
"rooms": [
{ "group_id": 6, "room_id": 1, "room_name": "룸1" },
{ "group_id": 6, "room_id": 2, "room_name": "룸2" },
{ "group_id": 10, "room_id": 3, "room_name": "룸3" },
{ "group_id": 10, "room_id": 4, "room_name": "룸4" },
{ "group_id": 10, "room_id": 5, "room_name": "룸5" }
]
}
11,084 changes: 6,022 additions & 5,062 deletions package-lock.json

Large diffs are not rendered by default.

18 changes: 17 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,27 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6",
"@mui/icons-material": "^5.11.11",
"@mui/material": "^5.11.12",
"@reduxjs/toolkit": "^1.9.3",
"@stomp/stompjs": "^7.0.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.3.4",
"http-proxy-middleware": "^2.0.6",
"openvidu-browser": "^2.26.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.8.0",
"react-redux": "^8.0.5",
"react-router-dom": "^6.9.0",
"react-scripts": "5.0.1",
"sockjs-client": "^1.6.1",
"styled-components": "^5.3.9",
"swr": "^2.1.0",
"web-vitals": "^2.1.4"
},
"scripts": {
Expand All @@ -34,5 +49,6 @@
"last 1 firefox version",
"last 1 safari version"
]
}
},
"proxy": "http://172.16.95.104:8080"
}
22 changes: 22 additions & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,28 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<!-- Bootstrap -->
<!-- <script
src="https://code.jquery.com/jquery-3.3.1.min.js"
integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
crossorigin="anonymous"
></script>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous"
/>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"
></script> -->
<!-- <link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"
/> -->
<!-- Bootstrap -->
<title>React App</title>
</head>
<body>
Expand Down
66 changes: 64 additions & 2 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,69 @@
import "./App.css";
import { api } from "./api/Interceptors";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from "./pages/home/Index";
import Login from "./pages/login/Index";
import Register from "./pages/register/Index";
import Group from "./pages/group/Group";
import Room from "./pages/room/Room";
import ChatPage from "./pages/chat/ChatPage";
import ChatDetail from "./pages/chat/ChatDetail";
import VideoPage from "./pages/videochat/VideoPage";
// import { useSelector } from "react-redux";

function App() {
return <div></div>;
// let isAuth = useSelector((state) => state.user.isAuth);
// let isAuth = localStorage.getItem("isAuth");

const onSlientRefresh = () => {
api
.post(
"/reissue",
{},
{
headers: {
access_token: localStorage.getItem("jwt_accessToken"),
refresh_token: localStorage.getItem("jwt_refreshToken"),
},
}
)
.then((response) => {
localStorage.setItem("jwt_accessToken", response.headers.access_token);
localStorage.setItem(
"jwt_refreshToken",
response.headers.refresh_token
);
localStorage.setItem("isLogined", true);
setInterval(onSlientRefresh, 1500000); //25분마다 리이슈 요청
})
.catch((err) => {
console.log(err);
});
};
// onSlientRefresh();
//performance.navigation.type===1
if (PerformanceNavigationTiming.type === "reload") {
onSlientRefresh();
}

return (
<div>
<BrowserRouter>
<Routes>
<Route path="/" element={<Home></Home>}></Route>
<Route path="/login" element={<Login></Login>}></Route>
<Route path="/register" element={<Register></Register>}></Route>
<Route path="/group/:group_id" element={<Group></Group>}></Route>
<Route path="/room/:room_id" element={<Room></Room>}></Route>
<Route path="/chat" element={<ChatPage></ChatPage>}></Route>
<Route
path="/chat/:dm_id"
element={<ChatDetail></ChatDetail>}
></Route>
<Route path="/openvidu" element={<VideoPage></VideoPage>}></Route>
</Routes>
</BrowserRouter>
</div>
);
}

export default App;
91 changes: 91 additions & 0 deletions src/api/Interceptors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import axios from "axios";
import { useNavigate } from "react-router-dom";
// axios.defaults.baseURL = "http://192.168.0.63:8080";
// axios.defaults.headers.common["access_token"] =
// localStorage.getItem("jwt_accessToken");
export const api = axios.create({
proxy: {
baseURL: `http://172.16.95.104:8080`,
},

headers: {
access_token:
localStorage.getItem("jwt_accessToken") &&
localStorage.getItem("jwt_accessToken"),
refresh_token:
localStorage.getItem("jwt_accessToken") &&
localStorage.getItem("jwt_refreshToken"),
},
});

// Add a request interceptor
api.interceptors.request.use(
function (config) {
// 요청 바로 직전
// axios 설정값에 대해 작성합니다.
// console.log(config);
config.headers["access_token"] = localStorage.getItem("jwt_accessToken");
return config;
},
function (error) {
// 요청 에러 처리를 작성합니다.
return Promise.reject(error);
}
);

// Add a response interceptor
api.interceptors.response.use(
function (response) {
/*
http status가 200인 경우
응답 바로 직전에 대해 작성합니다.
.then() 으로 이어집니다.
*/
return response;
},

function (error) {
/*
http status가 200이 아닌 경우
응답 에러 처리를 작성합니다.
.catch() 으로 이어집니다.
*/
if (error.response && error.response.status === 401) {
Logout();
return new Promise(() => {}); //이행되지 않은 Promise를 반환하여 Promise Chaining 끊어주기
}
// console.log("rtk 만료되었습니다. 자동 로그아웃 됩니다.", error);
// const navigate = useNavigate();
// localStorage.removeItem("jwt_accessToken");
// localStorage.removeItem("jwt_refreshToken");
// localStorage.setItem("isAuthorized", false);
// navigate("/login");

return Promise.reject(error);
}
);

const Logout = () => {
const navigate = useNavigate();
api
.post(
"/",
{},
{
headers: {
access_token: localStorage.getItem("jwt_accessToken"),
refresh_token: localStorage.getItem("jwt_refreshToken"),
},
}
)
.then((response) => {
console.log(response);
localStorage.removeItem("jwt_accessToken");
localStorage.removeItem("jwt_refreshToken");
localStorage.setItem("isLogined", false);
alert("로그아웃 성공! 다음에 또 만나요❤️");
navigate("/login");
})
.catch((err) => console.log(err));
};
// export default api;
104 changes: 104 additions & 0 deletions src/components/ModalGroup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import React from "react";
import { useState } from "react";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import Modal from "@mui/material/Modal";
import AddIcon from "@mui/icons-material/Add";
import { api } from "../api/Interceptors";
import styled from "styled-components";
import { useNavigate } from "react-router-dom";
import { useSelector } from "react-redux";

const style = {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 400,
height: 300,
bgcolor: "background.paper",
boxShadow: 24,
borderRadius: 3,
p: 4,
};

const Wrapper = styled.div`
text-align: center;
`;
const Button = styled.button`
width: 200px;
height: 50px;
border: none;
border-radius: 10px;
background-color: #f5b66c;
font-size: 20px;
font-weight: bold;
margin: auto;
:hover {
cursor: pointer;
}
`;

const ModalGroup = (props) => {
const navigate = useNavigate();
const [open, setOpen] = useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
const [group_name, setGroup_name] = useState("");
const email = useSelector((state) => state.user.email);

const createGroupRoom = async (e) => {
e.preventDefault();
let body = {
group_name: group_name,
email: email,
};
await api
.post("/creategroup", body)
.then((response) => {
console.log(response);
let group_id = response.data;
navigate(`/group/${group_id}`);
handleClose();
window.location.reload();
})
.catch((err) => console.log(err));
};

return (
<div>
<Wrapper>
<Button onClick={handleOpen}>
+ &nbsp;Group Create
{/* <AddIcon /> */}
</Button>
</Wrapper>

<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style} onSubmit={createGroupRoom}>
<Typography id="modal-modal-title" variant="h6" component="h2">
그룹 생성
</Typography>
<form>
그룹 이름 :{" "}
<input
type="text"
label="그룹 이름"
value={group_name}
onChange={(e) => setGroup_name(e.target.value)}
/>
<p>
<input type="submit" value="생성" />
</p>
</form>
</Box>
</Modal>
</div>
);
};
export default ModalGroup;
Loading