Skip to content

Commit e805990

Browse files
authored
Merge branch 'feature/frontend/#33' of https://github.com/osamhack2021/Web_Handover_Handover into feature/frontend/#33
2 parents 1cc874a + 4b06cad commit e805990

14 files changed

Lines changed: 294 additions & 188 deletions

File tree

backend/controllers/groupController.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ module.exports = {
1313
// Only allowed fields are Searchable
1414
for(let key of keys) {
1515
if(!valids.includes(key))
16-
throw new BusinessError(`Invalid: ${key}로는 검색할 수 없습니다!`);
16+
throw new BusinessError(`Query invalid: ${key}로는 검색할 수 없습니다!`);
1717
}
1818

1919
const result = await groupService.search(req.query);
2020

21-
if(result.length < 1) throw new NotFoundError(`NotFound: 검색결과가 없습니다.`);
21+
// if(result.length < 1) throw new NotFoundError(`NotFound: 검색결과가 없습니다.`);
2222

2323
res.status(200).send(result);
2424
} catch(err) {
@@ -33,7 +33,7 @@ module.exports = {
3333

3434
const result = await groupService.read({ _id: group_id });
3535

36-
if(result === null) throw new NotFoundError(`NotFound: 검색결과가 없습니다.`);
36+
if(result === null) throw new NotFoundError(`Group not found: 존재하지 않는 그룹입니다.`);
3737

3838
res.status(200).send(result);
3939
} catch(err) {
@@ -66,10 +66,10 @@ module.exports = {
6666
const group = await groupService.read({ _id: group_id });
6767

6868
// Invalid group_id
69-
if(group === null) throw new NotFoundError(`NotFound: 검색결과가 없습니다.`);
69+
if(group === null) throw new NotFoundError(`Group not found: 존재하지 않는 그룹입니다.`);
7070

7171
// Admin check
72-
if(!group.admins.some(admin => admin.equals(res.locals._id))) throw new ForbiddenError(`Forbidden: 그룹의 관리자만 수정할 수 있습니다.`);
72+
if(!group.admins.some(admin => admin.equals(res.locals._id))) throw new ForbiddenError(`Access denied: 그룹의 관리자만 수정할 수 있습니다.`);
7373

7474
await groupService.update(group_id, req.body);
7575

@@ -86,7 +86,7 @@ module.exports = {
8686

8787
let result = await groupService.delete(group_id);
8888

89-
if(result === null) throw new NotFoundError(`Not Found: 검색결과가 없습니다.`);
89+
if(result === null) throw new NotFoundError(`Group not found: 존재하지 않는 그룹입니다.`);
9090

9191
res.status(204).send();
9292
} catch(err) {

backend/controllers/itemController.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ module.exports = {
1616
// Only allowed fields are Searchable
1717
for(let key of keys) {
1818
if(!valids.includes(key))
19-
throw new BusinessError(`Invalid: ${key}로는 검색할 수 없습니다!`);
19+
throw new BusinessError(`Query invalid: ${key}로는 검색할 수 없습니다!`);
2020
}
2121

2222
const result = await itemService.search(req.query);
2323

24-
if(result.length < 1) throw new NotFoundError(`Not Found: 검색결과가 없습니다.`);
24+
// if(result.length < 1) throw new NotFoundError(`Not Found: 검색결과가 없습니다.`);
2525

2626
res.status(200).send(result);
2727

@@ -39,7 +39,7 @@ module.exports = {
3939
filters: `status:"modified" AND NOT accessGroups.read:"${res.locals.group}"`
4040
});
4141

42-
if(result.hits.length < 1) throw new NotFoundError(`NotFound: 검색결과가 없습니다.`);
42+
// if(result.hits.length < 1) throw new NotFoundError(`NotFound: 검색결과가 없습니다.`);
4343

4444
res.status(200).send(result.hits);
4545
} catch(err) {
@@ -54,12 +54,12 @@ module.exports = {
5454

5555
const item = await itemService.read({ _id: item_id });
5656

57-
if(item === null) throw new NotFoundError(`NotFound: 검색결과가 없습니다.`);
57+
if(item === null) throw new NotFoundError(`Item not found: 존재하지 않는 항목입니다.`);
5858

5959
// Check session's read authority
6060
const user = await userService.findOne({ serviceNumber: res.locals.serviceNumber });
6161
if(!item.accessGroups.read.some(i => i.equals(user.group)))
62-
throw new ForbiddenError(`Forbidden: 읽기 권한이 없습니다.`);
62+
throw new ForbiddenError(`Access denied: 열람 권한이 없습니다.`);
6363

6464
res.status(200).send(item);
6565
} catch(err) {
@@ -110,11 +110,11 @@ module.exports = {
110110

111111
let item = await itemService.read({ _id: item_id }, { populate: false });
112112

113-
if(item === null) throw new NotFoundError(`Not Found: 검색 결과가 없습니다.`);
113+
if(item === null) throw new NotFoundError(`Item not Found: 존재하지 않는 항목입니다.`);
114114

115115
// Check session's edit authority
116116
if(!item.accessGroups.edit.some(i => i.equals(res.locals.group)))
117-
throw new ForbiddenError(`Forbidden: 수정 권한이 없습니다.`);
117+
throw new ForbiddenError(`Access denied: 수정 권한이 없습니다.`);
118118

119119
// Append Contributor
120120
item = Object.assign(item, { contributors: [...item.contributors, res.locals._id] });
@@ -140,7 +140,7 @@ module.exports = {
140140
let item = await itemService.read({ _id: item_id }, { populate: false });
141141

142142
if(item === null)
143-
throw new NotFoundError(`Not Found: 검색 결과가 없습니다.`);
143+
throw new NotFoundError(`Item not Found: 존재하지 않는 항목입니다.`);
144144

145145
// Algolia
146146
await algolia.deleteObject(item_id);

backend/controllers/userController.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ module.exports = {
1313
// Only allowed fields are Searchable
1414
for(let key of keys) {
1515
if(!valids.includes(key))
16-
throw new BusinessError(`${key} 는 검색할 수는 없는 속성입니다.`);
16+
throw new BusinessError(`Query invalid: ${key} 는 검색할 수는 없는 속성입니다.`);
1717
}
1818

1919

2020
const projection = {
2121
_id: true, name: true, rank: true, status: true,
22-
group: true, email: true, tel: true, lastLogin: true
22+
group: true, email: true, tel: true, lastLogin: true, profileImageUrl: true, title: true
2323
};
2424

2525
try {
@@ -35,7 +35,7 @@ module.exports = {
3535
let projection = {
3636
_id: true,serviceNumber:true, name: true, rank: true, title:true,
3737
status: true, group: true, email: true, tel: true, lastLogin: true,
38-
lastLogin: true, firseLogin:true, bookmarks: true, subscriptions: true
38+
lastLogin: true, firseLogin:true, bookmarks: true, subscriptions: true, profileImageUrl: true
3939
};
4040

4141
try {
@@ -74,7 +74,7 @@ module.exports = {
7474
// Only allowed fields are Searchable
7575
for(let key of keys) {
7676
if(!valids.includes(key))
77-
throw new BusinessError(`${key} 는 User에 존재하지 않거나, 변경할 수 없는 속성입니다`);
77+
throw new BusinessError(`Query invalid: ${key} 는 User에 존재하지 않거나, 변경할 수 없는 속성입니다`);
7878
}
7979

8080
await authService.editUserAuth(res.locals._id.toString(),req.params.id);

backend/services/authService.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function decodeToken(token) {
2222

2323
return decoded;
2424
} catch (err) {
25-
throw new ForbiddenError('로그인이 필요한 서비스입니다.');
25+
throw new ForbiddenError('Access denied: 로그인이 필요한 서비스입니다.');
2626
}
2727
}
2828

@@ -94,13 +94,13 @@ module.exports = {
9494
.findOne({ serviceNumber: params.serviceNumber })
9595
.catch((err) => {
9696
if (err instanceof TypeError) {
97-
throw new AuthError('로그인에 실패했습니다.');
97+
throw new AuthError('Authentication error: 로그인에 실패했습니다.');
9898
}
99-
throw new RuntimeError('로그인에 실패했습니다.');
99+
throw new RuntimeError('Runtime error: 로그인에 실패했습니다.');
100100
});
101101

102102
if (loginUser === null || loginUser.password !== params.password) {
103-
throw new AuthError('로그인에 실패했습니다.');
103+
throw new AuthError('Authentication error: 로그인에 실패했습니다. 올바르지 않은 군번과 비밀번호입니다.');
104104
}
105105

106106
const user = jwt.sign({
@@ -124,7 +124,7 @@ module.exports = {
124124

125125
const isAd = await isAdmin(decode._id).catch((err) => { throw err; });
126126
if (!isAd) {
127-
throw new ForbiddenError('접근 권한이 존재하지 않습니다');
127+
throw new ForbiddenError('Access denied: 접근 권한이 존재하지 않습니다');
128128
}
129129
return isAd;
130130
},
@@ -135,7 +135,7 @@ module.exports = {
135135

136136
if (!isSelf(loginUserId, targetUserId)
137137
&& !results.includes(true)) {
138-
throw new ForbiddenError('접근 권한이 존재하지 않습니다');
138+
throw new ForbiddenError('Access denied: 접근 권한이 존재하지 않습니다');
139139
}
140140

141141
return true;
@@ -146,7 +146,7 @@ module.exports = {
146146
.catch((err) => { throw err; });
147147

148148
if (!results.includes(true)) {
149-
throw new ForbiddenError('접근 권한이 존재하지 않습니다');
149+
throw new ForbiddenError('Access denied: 접근 권한이 존재하지 않습니다');
150150
}
151151

152152
return true;
@@ -169,7 +169,7 @@ module.exports = {
169169
const results = await Promise.all([isGroupManager(loginUserId, targetGroupId), isAdmin(loginUserId)])
170170
.catch((err) => { throw err; });
171171
if (!results.includes(true)) {
172-
throw new ForbiddenError('접근 권한이 존재하지 않습니다');
172+
throw new ForbiddenError('Access denied: 접근 권한이 존재하지 않습니다');
173173
}
174174

175175
return true;
@@ -180,7 +180,7 @@ module.exports = {
180180
const results = await Promise.all([isItemEditor(loginUserId, targetItemId), isAdmin(loginUserId)])
181181
.catch((err) => { throw err; });
182182
if (!results.includes(true)) {
183-
throw new ForbiddenError('접근 권한이 존재하지 않습니다');
183+
throw new ForbiddenError('Access denied: 접근 권한이 존재하지 않습니다');
184184
}
185185

186186
return true;
@@ -190,7 +190,7 @@ module.exports = {
190190
const results = await Promise.all([isItemReader(loginUserId, targetItemId), isAdmin(loginUserId)])
191191
.catch((err) => { throw err; });
192192
if (!results) {
193-
throw new ForbiddenError('접근 권한이 존재하지 않습니다');
193+
throw new ForbiddenError('Access denied: 접근 권한이 존재하지 않습니다');
194194
}
195195

196196
return true;

backend/services/userService.js

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ module.exports = {
1717
const result = await User
1818
.find(params, projection)
1919
.catch(err => {
20-
throw new RuntimeError(params + '를 불러올 수 없습니다.');
20+
throw new RuntimeError("Runtime error: " + params + '를 불러올 수 없습니다.');
2121
});
2222

23-
if(result === null) throw new NotFoundError('Not Found: 검색 결과가 없습니다.');
23+
if(result === null) throw new NotFoundError('User not found: 존재하지 않는 사용자입니다.');
2424

2525
return result;
2626
},
@@ -30,10 +30,10 @@ module.exports = {
3030
const result = await User
3131
.findOne(params, projection)
3232
.catch(err => {
33-
throw new RuntimeError(params + '를 불러올 수 없습니다.');
33+
throw new RuntimeError("Runtime error: " + params + '를 불러올 수 없습니다.');
3434
});
3535

36-
if(result === null) throw new NotFoundError('Not Found: 검색 결과가 없습니다.');
36+
if(result === null) throw new NotFoundError('User not found: 존재하지 않는 사용자입니다.');
3737

3838
return result;
3939
},
@@ -46,7 +46,7 @@ module.exports = {
4646
.create(params)
4747
.catch(err => {
4848
if(err.code === 11000) {
49-
throw new BusinessError('군번이 이미 존재합니다');
49+
throw new BusinessError('Duplicate found: 이미 가입된 군번입니다.');
5050
}
5151
throw new RuntimeError(err.message);
5252
});
@@ -63,7 +63,7 @@ module.exports = {
6363
const result = await User
6464
.findOneAndUpdate({_id:id}, params, {new: true})
6565
.catch(err => {
66-
throw new RuntimeError("update를 진행할 수 없습니다.");
66+
throw new RuntimeError("Runtime error: 사용자 정보 수정에 오류가 발생했습니다.");
6767
});
6868
result.password = '';
6969

@@ -75,7 +75,7 @@ module.exports = {
7575
const result = await User
7676
.deleteOne({_id:id})
7777
.catch(err => {
78-
throw new RuntimeError("delete를 진행할 수 없습니다.");
78+
throw new RuntimeError("Runtime error: 사용자 삭제에 오류가 발생했습니다.");
7979
});
8080

8181
return true;
@@ -85,7 +85,9 @@ module.exports = {
8585

8686
const user = await User
8787
.findOne({serviceNumber:params.serviceNumber})
88-
.catch(err => { throw new RuntimeError(err.message); });
88+
.catch(err => {
89+
throw new RuntimeError("Runtime error: 알수없는 오류가 발생했습니다.");
90+
});
8991

9092
return {exist: user !== null};
9193
}

frontend/api/group.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ export const getGroupByGroupId = (id) => request.get(`/api/group/${id}`)
66
// .send(id)
77
.then(handleSuccess)
88
.catch(handleError);
9+
10+
export const searchGroupByAdmin = (adminId) => request.get(`/api/group`)
11+
.query({ admin: adminId })
12+
.then(handleSuccess)
13+
.catch(handleError);

frontend/api/user.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,8 @@ export const putUserPassword = (passwordInfo) => request.put('/api/user/password
1414
.send(passwordInfo)
1515
.then(handleSuccess)
1616
.catch(handleError);
17+
18+
export const searchUserByGroupId = (groupId) => request.get(`/api/user`)
19+
.query({ group: groupId })
20+
.then(handleSuccess)
21+
.catch(handleError);

frontend/components/molecules/GroupMember/GroupMember.js

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
import React, { useState } from 'react';
2-
import PropTypes from 'prop-types';
3-
4-
import { Menu, IconButton, MenuItem } from '@mui/material';
5-
import MoreHorizIcon from '@mui/icons-material/MoreHoriz';
1+
import MoreHorizIcon from "@mui/icons-material/MoreHoriz";
2+
import { IconButton, Menu, MenuItem } from "@mui/material";
3+
import PropTypes from "prop-types";
4+
import React, { useState } from "react";
65

76
export default function GroupMember({
8-
name = '', rank = '', division = '', title = '', profilePic = '', status = '', admin = '',
7+
name = "",
8+
rank = "",
9+
division = "",
10+
title = "",
11+
profileImageUrl = "",
12+
status = "",
13+
type = "",
914
}) {
1015
const aboveString = `${rank} ${name}`;
1116
const belowString = `${division} ${title}`;
@@ -24,30 +29,30 @@ export default function GroupMember({
2429
<div className="group-member-profile">
2530
<img
2631
className="profile-img"
27-
src={profilePic || '/images/default-profile.png'}
32+
src={profileImageUrl || "/images/default-profile.png"}
2833
alt="profile"
2934
/>
3035
<div className="profile-string">
31-
<div className="profile-string-above">
32-
{aboveString}
33-
</div>
34-
<div className="profile-string-below">
35-
{belowString}
36-
</div>
36+
<div className="profile-string-above">{aboveString}</div>
37+
<div className="profile-string-below">{belowString}</div>
3738
</div>
3839
</div>
3940
<div className="group-member-admin">
40-
{admin === 'admin' ? '관리자' : '그룹원'}
41+
{type === "admin"
42+
? "관리자"
43+
: type === "inspector"
44+
? "보안 검수자"
45+
: "그룹원"}
4146
</div>
4247
<div className="group-member-active">
43-
{status === 'active' ? '활동중' : '비활성'}
48+
{status === "active" ? "활동중" : "비활성"}
4449
</div>
4550
<div>
4651
<IconButton
4752
aria-label="more"
4853
id="long-button"
4954
aria-controls="long-menu"
50-
aria-expanded={open ? 'true' : undefined}
55+
aria-expanded={open ? "true" : undefined}
5156
aria-haspopup="true"
5257
onClick={handleClick}
5358
>
@@ -70,9 +75,9 @@ export default function GroupMember({
7075
GroupMember.propTypes = {
7176
name: PropTypes.string.isRequired,
7277
rank: PropTypes.string.isRequired,
73-
division: PropTypes.string.isRequired,
78+
division: PropTypes.string,
7479
title: PropTypes.string.isRequired,
75-
profilePic: PropTypes.string.isRequired,
80+
profileImageUrl: PropTypes.string,
7681
status: PropTypes.string.isRequired,
77-
admin: PropTypes.string.isRequired,
82+
type: PropTypes.string.isRequired,
7883
};

0 commit comments

Comments
 (0)