Skip to content

Commit 9184e1a

Browse files
committed
Merge branch 'dev' of https://github.com/boostcampwm-2022/web27-Wabinar into feat/#82-S
2 parents 0b5ede2 + c1944dd commit 9184e1a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+805
-320
lines changed

client/src/App.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,27 @@
11
import { useState, useEffect } from 'react';
2-
import { Routes, Route, useNavigate } from 'react-router-dom';
2+
import { Routes, Route, useNavigate, useLocation } from 'react-router-dom';
33
import { getAuth } from 'src/apis/auth';
4-
import UserContext, { User } from 'src/contexts/user';
4+
import UserContext from 'src/contexts/user';
55
import { LoadingPage, LoginPage, OAuthPage, WorkspacePage } from 'src/pages';
6+
import { User } from 'src/types/user';
67
import 'styles/reset.scss';
78

89
function App() {
10+
const [isLoaded, setIsLoaded] = useState<boolean>(false);
911
const [user, setUser] = useState<User | null>(null);
12+
1013
const navigate = useNavigate();
14+
const location = useLocation();
1115

1216
const autoLogin = async () => {
1317
const currentUser = await getAuth();
1418

15-
if (!currentUser) return;
19+
setIsLoaded(true);
20+
21+
if (!currentUser) {
22+
if (location.pathname === '/workspace') navigate('/');
23+
return;
24+
}
1625

1726
setUser(currentUser);
1827
navigate('/workspace');
@@ -22,7 +31,7 @@ function App() {
2231
autoLogin();
2332
}, []);
2433

25-
return user ? (
34+
return isLoaded ? (
2635
<UserContext.Provider value={{ user, setUser }}>
2736
<Routes>
2837
<Route path="/" element={<LoginPage />} />

client/src/apis/auth.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,15 @@ import { http } from './http';
44
import { OK, CREATED } from './http-status';
55

66
export const getAuth = async () => {
7-
const res = await http.get(`/auth`);
7+
try {
8+
const res = await http.get(`/auth`);
89

9-
if (res.status !== OK) throw new Error();
10+
if (res.status !== OK) return null;
1011

11-
return res.data;
12+
return res.data;
13+
} catch (e) {
14+
return null;
15+
}
1216
};
1317

1418
export const postAuthLogin = async ({ code }: PostLoginParams) => {

client/src/apis/workspace.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { PostJoinParams, PostParams } from 'params/workspace';
2+
import { Workspace } from 'src/types/workspace';
3+
4+
import { http } from './http';
5+
import { CREATED } from './http-status';
6+
7+
export const postWorkspace = async ({
8+
name,
9+
}: PostParams): Promise<Workspace> => {
10+
const res = await http.post(`/workspace`, { name });
11+
12+
if (res.status !== CREATED) throw new Error();
13+
14+
return res.data;
15+
};
16+
17+
export const postWorkspaceJoin = async ({
18+
code,
19+
}: PostJoinParams): Promise<Workspace> => {
20+
const res = await http.post(`/workspace/join`, { code });
21+
22+
if (res.status !== CREATED) throw new Error();
23+
24+
return res.data;
25+
};

client/src/components/SelectModal/index.tsx

Lines changed: 0 additions & 36 deletions
This file was deleted.

client/src/components/SelectModal/style.module.scss

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,12 @@
11
import { MdAdd } from '@react-icons/all-files/md/MdAdd';
2-
import React from 'react';
32

43
import style from './style.module.scss';
54

65
interface AddButtonProps {
7-
onClick: () => void;
6+
onClick: React.MouseEventHandler;
87
}
9-
108
function AddButton({ onClick }: AddButtonProps) {
11-
const onClickBtn = () => {
12-
onClick();
13-
};
14-
15-
return (
16-
<button className={style.button} onClick={onClickBtn}>
17-
<MdAdd color="white" size={20} />
18-
</button>
19-
);
9+
return <MdAdd onClick={onClick} className={style.button} size={20} />;
2010
}
2111

2212
export default AddButton;

client/src/components/WorkspaceList/index.tsx

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,62 @@
1-
import { memo, useContext, useEffect, useState } from 'react';
1+
import Selector from 'common/Selector';
2+
import WorkspaceModal from 'components/WorkspaceModal';
3+
import WorkspaceThumbnaliList from 'components/WorkspaceThumbnailList';
4+
import { memo, useEffect, useState } from 'react';
25
import { getWorkspaces } from 'src/apis/user';
3-
import UserContext from 'src/contexts/user';
6+
import { MENUS } from 'src/constants/workspace';
7+
import SetWorkspacesContext from 'src/contexts/set-workspaces';
8+
import { useUserContext } from 'src/hooks/useUserContext';
9+
import { SelectorStyle } from 'src/types/selector';
410
import { Workspace } from 'src/types/workspace';
511

612
import AddButton from './AddButton';
713
import style from './style.module.scss';
8-
import WorkspaceThumbnaliList from './WorkspaceThumbnailList';
914

10-
interface WorkspaceListProps {
11-
onSelectModalOpen: () => void;
12-
}
15+
function WorkspaceList() {
16+
const userContext = useUserContext();
1317

14-
function WorkspaceList({ onSelectModalOpen }: WorkspaceListProps) {
1518
const [workspaces, setWorkspaces] = useState<Workspace[]>([]);
16-
const userContext = useContext(UserContext);
1719

1820
const updateWorkspaces = async (userId: number) => {
1921
const { workspaces } = await getWorkspaces({ id: userId });
2022
setWorkspaces(workspaces);
2123
};
2224

2325
useEffect(() => {
24-
if (!userContext) {
26+
if (!userContext.user) {
2527
return;
2628
}
29+
2730
updateWorkspaces(userContext.user.id);
2831
}, []);
2932

33+
const [selectedMenu, setSelectedMenu] = useState<number>(0);
34+
35+
const onSelectMenu = (id: number) => {
36+
setSelectedMenu(id);
37+
};
38+
39+
const selectorStyle: SelectorStyle = {
40+
menu: style.menu,
41+
dimmed: style.dimmed,
42+
};
43+
3044
return (
31-
<div className={style.workspace__container}>
32-
<WorkspaceThumbnaliList workspaces={workspaces} />
33-
<AddButton onClick={onSelectModalOpen} />
34-
</div>
45+
<SetWorkspacesContext.Provider value={setWorkspaces}>
46+
<div className={style.workspace__container}>
47+
<WorkspaceThumbnaliList workspaces={workspaces} />
48+
<Selector
49+
TriggerElement={AddButton}
50+
options={MENUS}
51+
onChange={onSelectMenu}
52+
style={selectorStyle}
53+
/>
54+
<WorkspaceModal
55+
selectedMenu={selectedMenu}
56+
setSelectedMenu={setSelectedMenu}
57+
/>
58+
</div>
59+
</SetWorkspacesContext.Provider>
3560
);
3661
}
3762

Lines changed: 40 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
@import 'styles/color.module.scss';
22

33
.workspace__container {
4+
position: relative;
5+
46
background-color: $primary-100;
57
height: 100vh;
68
width: 78px;
@@ -10,42 +12,52 @@
1012
align-items: center;
1113
}
1214

13-
.thumbnail__list {
14-
padding: 12px;
15-
}
16-
17-
.thumbnail {
18-
width: 45px;
19-
height: 45px;
20-
21-
border: 1px solid $white;
22-
border-radius: 50%;
15+
.button {
16+
fill: $white;
2317
cursor: pointer;
24-
25-
& + & {
26-
margin-top: 12px;
27-
}
2818
}
2919

30-
/**
31-
나중에 img로 바뀌면 변경될 수 있어요.
32-
*/
33-
.thumbnail__content {
34-
width: 100%;
35-
height: 100%;
20+
.menu {
21+
position: relative;
22+
z-index: 1;
23+
top: -8px;
24+
left: 70px;
3625

3726
display: flex;
38-
justify-content: center;
27+
flex-direction: column;
3928
align-items: center;
29+
padding: 20px;
4030

31+
border-radius: 10px;
32+
box-shadow: 1px 1px 3px $gray-300;
33+
background-color: $primary-100;
34+
font-size: 14px;
4135
color: $white;
42-
}
4336

44-
.button {
45-
display: flex;
46-
justify-content: center;
47-
align-items: center;
37+
li {
38+
width: max-content;
39+
padding: 8px 15px;
40+
cursor: pointer;
4841

49-
padding: 12px;
50-
cursor: pointer;
42+
&:not(:last-of-type) {
43+
border-bottom: 1px solid $gray-200;
44+
}
45+
46+
&:first-child {
47+
padding-top: 0;
48+
}
49+
50+
&:last-child {
51+
padding-bottom: 0;
52+
}
53+
}
54+
}
55+
56+
.dimmed {
57+
position: fixed;
58+
z-index: 0;
59+
top: 0;
60+
bottom: 0;
61+
right: 0;
62+
left: 0;
5163
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import React, { useState } from 'react';
2+
import { postWorkspace, postWorkspaceJoin } from 'src/apis/workspace';
3+
import { MENU } from 'src/constants/workspace';
4+
import { useSetWorkspaces } from 'src/hooks/useSetWorkspaces';
5+
6+
import FormModal, { ModalContents } from './FormModal';
7+
8+
interface CreateModalProps {
9+
modalContents: ModalContents;
10+
onClose: () => void;
11+
setSelectedMenu: React.Dispatch<React.SetStateAction<number>>;
12+
setCode: React.Dispatch<React.SetStateAction<string>>;
13+
}
14+
15+
function CreateModal({
16+
modalContents,
17+
onClose,
18+
setSelectedMenu,
19+
setCode,
20+
}: CreateModalProps) {
21+
const setWorkspaces = useSetWorkspaces();
22+
const [inputValue, setInputValue] = useState<string>('');
23+
24+
const onSubmit = async () => {
25+
const workspace = await postWorkspace({ name: inputValue });
26+
const { code } = workspace;
27+
28+
await postWorkspaceJoin({ code });
29+
30+
setWorkspaces((workspaces) => [...workspaces, workspace]);
31+
setCode(code);
32+
setSelectedMenu(MENU.CREATE_SUCCESS);
33+
34+
return;
35+
};
36+
37+
return (
38+
<FormModal
39+
{...modalContents}
40+
onClose={onClose}
41+
onSubmit={onSubmit}
42+
inputValue={inputValue}
43+
setInputValue={setInputValue}
44+
/>
45+
);
46+
}
47+
48+
export default CreateModal;

0 commit comments

Comments
 (0)