Skip to content

Commit 7a46e8f

Browse files
authored
Merge branch 'feature/frontend/#33' of https://github.com/osamhack2021/Web_Handover_Handover into feature/frontend/#33
2 parents d284068 + 778999e commit 7a46e8f

7 files changed

Lines changed: 554 additions & 221 deletions

File tree

backend/InitDB.js

Lines changed: 457 additions & 193 deletions
Large diffs are not rendered by default.

frontend/components/environment/Main/Main.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import LoginPage from '_pages/LoginPage';
99
import RegisterPage from '_pages/RegisterPage';
1010
import RoutingPage from '_pages/RoutingPage';
1111
import WelcomePage from '_pages/WelcomePage';
12-
import { attemptGetUser } from '_thunks/user';
12+
import { attemptGetCurrentUser } from '_thunks/user';
1313

1414
export default function Main({ location }) {
1515
const dispatch = useDispatch();
@@ -18,7 +18,7 @@ export default function Main({ location }) {
1818
useEffect(() => {
1919
let subscribed = true;
2020

21-
dispatch(attemptGetUser())
21+
dispatch(attemptGetCurrentUser())
2222
.catch(R.identity)
2323
.then(() => subscribed && setLoading(false));
2424

frontend/components/molecules/Item/Item.js

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ import {
2222
Skeleton,
2323
Tooltip
2424
} from "@mui/material";
25-
import humanizeDuration from "humanize-duration";
2625
import R from "ramda";
2726
import React, { useEffect, useState } from "react";
2827
import { store as RNC } from "react-notifications-component";
2928
import { useDispatch, useSelector } from "react-redux";
3029
import LinkComponent from "_atoms/LinkComponent";
30+
import { dateElapsed, dateToString } from "_frontend/utils/date";
3131
import {
3232
attemptArchiveItem,
3333
attemptDeleteItem,
@@ -47,9 +47,7 @@ const borderRadius = {
4747
// Maximum number of line of the content
4848
const LINE_CLAMP = 4;
4949

50-
const content = (item, itemChildren) => {
51-
const dispatch = useDispatch();
52-
50+
const renderContent = (item, itemChildren) => {
5351
if (item == null || !item.hasOwnProperty("content")) return null;
5452

5553
if (item.type === "card") {
@@ -84,17 +82,6 @@ const content = (item, itemChildren) => {
8482
});
8583
};
8684

87-
const dateElapsed = (date) => {
88-
const created = new Date(date);
89-
const now = new Date();
90-
return `${humanizeDuration(now - created, {
91-
language: "ko",
92-
largest: 1,
93-
spacer: "",
94-
round: true,
95-
})} 전`;
96-
};
97-
9885
const statusIcon = {
9986
archived: mdiPackageDown,
10087
public: mdiEarth,
@@ -290,10 +277,7 @@ export default function Item({
290277
// don't render if visible is false
291278
if (visible == false) return null;
292279

293-
const createdDate = new Date(item.created);
294-
const createdString = `${createdDate.toLocaleDateString(
295-
"ko-KR"
296-
)} ${createdDate.toLocaleTimeString("en-GB")}`;
280+
const content = renderContent(item, itemChildren)
297281

298282
return item == null ? (
299283
<div className="item" key={itemId}>
@@ -360,10 +344,18 @@ export default function Item({
360344
<div />
361345
)}
362346
</div>
363-
<div className="item-content">{content(item, itemChildren)}</div>
347+
{content != null ? (
348+
<div className="item-content">{content}</div>
349+
) : (
350+
<div className="item-content">
351+
<Skeleton width="100%" />
352+
<Skeleton width="100%" />
353+
<Skeleton width="75%" />
354+
</div>
355+
)}
364356
</ButtonBase>
365357
<div className="item-footer">
366-
<Tooltip title={createdString} arrow>
358+
<Tooltip title={dateToString(item.created)} arrow>
367359
<div className="item-description">
368360
{`${item.owner.rank} ${item.owner.name} · ${dateElapsed(
369361
item.created

frontend/components/pages/ItemPage/ItemPage.js

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
Divider,
1919
IconButton,
2020
ListItemIcon,
21+
Skeleton,
2122
Menu,
2223
MenuItem,
2324
Stack,
@@ -41,7 +42,11 @@ import {
4142
attemptGetItemChildren,
4243
attemptPublishItem
4344
} from "_thunks/item";
44-
import { attemptAddBookmark, attemptRemoveBookmark } from "_thunks/user";
45+
import {
46+
attemptAddBookmark,
47+
attemptGetUser,
48+
attemptRemoveBookmark
49+
} from "_thunks/user";
4550
import { deepEqual } from "_utils/compare";
4651

4752
const typeString = {
@@ -85,6 +90,8 @@ export default function ItemPage() {
8590
const [isBookmarked, setBookmarked] = useState(
8691
user.bookmarks.includes(itemId)
8792
);
93+
const [itemOwner, setItemOwner] = useState(null);
94+
8895
// visibility of the component; used on delete and unauthorized items
8996
const [visible, setVisible] = useState(true);
9097

@@ -164,6 +171,10 @@ export default function ItemPage() {
164171

165172
useEffect(() => {
166173
if (item != null) {
174+
dispatch(attemptGetUser(item.owner._id)).then((user) => {
175+
setItemOwner(user);
176+
});
177+
167178
switch (item.type) {
168179
case "cabinet": // will have 0 parents because it's the root item
169180
console.log("switch: case =", item.type, pathArray);
@@ -302,9 +313,7 @@ export default function ItemPage() {
302313
badgeContent={
303314
status != null ? (
304315
<Icon size={0.75} path={statusIcon[status]} opacity={0.7} />
305-
) : (
306-
null
307-
)
316+
) : null
308317
}
309318
anchorOrigin={{
310319
vertical: "bottom",
@@ -343,6 +352,22 @@ export default function ItemPage() {
343352
<BreadCrumbs hierarchyLevel={hierarchyLevel[item.type]} />
344353
)}
345354
</Stack>
355+
{itemOwner != null ? (
356+
<Stack className="item-profile">
357+
<img
358+
className="item-profile-image"
359+
src={itemOwner.profileImageUrl || "/images/default-profile.png"}
360+
/>
361+
<div className="item-profile-name">
362+
{itemOwner.rank} {itemOwner.name}
363+
</div>
364+
</Stack>
365+
) : (
366+
<Stack className="item-profile">
367+
<Skeleton className="item-profile-image"/>
368+
<Skeleton className="item-profile-name" />
369+
</Stack>
370+
)}
346371
{item.content && <Editor content={item.content} editable={false} />}
347372
<div>
348373
<div className="outer-div">

frontend/store/thunks/user.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { updateUser } from "_actions/user";
44
import { getUser, putUser, putUserPassword } from "_api/user";
55
import { dispatchError } from "_utils/api";
66

7-
export const attemptGetUser = () => (dispatch) => {
7+
export const attemptGetCurrentUser = () => (dispatch) => {
88
try {
99
const currentUserId = JSON.parse(localStorage.getItem("user"))._id;
1010

@@ -25,6 +25,17 @@ export const attemptGetUser = () => (dispatch) => {
2525
}
2626
};
2727

28+
export const attemptGetUser = (userId) => (dispatch) => {
29+
return getUser(userId)
30+
.then((data) => {
31+
return data;
32+
})
33+
.catch(() => {
34+
// Redirect to /login if there is no user logged in
35+
dispatchError(dispatch);
36+
});
37+
};
38+
2839
export const attemptUpdateUser = (updatedUser) => (dispatch) => {
2940
const currentUserId = JSON.parse(localStorage.getItem("user"))._id;
3041

frontend/styles/item-page.scss

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,28 @@
3434
text-overflow: ellipsis;
3535
}
3636
}
37+
38+
.item-profile {
39+
align-items: center;
40+
flex-direction: row;
41+
42+
.item-profile-image {
43+
width: 24px;
44+
height: 24px;
45+
margin-right: 12px;
46+
border-radius: 50%;
47+
border: 1px solid #0005;
48+
}
49+
50+
.item-profile-name {
51+
font-size: 1.15em;
52+
font-weight: bold;
53+
text-align: start;
54+
padding-top: 3px;
55+
}
56+
57+
.item-profile-name-loading {
58+
width: 100px;
59+
}
60+
}
3761
}

frontend/utils/date.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import humanizeDuration from "humanize-duration";
2+
3+
export const dateElapsed = (dateString) => {
4+
const date = new Date(dateString);
5+
const now = new Date();
6+
return `${humanizeDuration(now - date, {
7+
language: "ko",
8+
largest: 1,
9+
spacer: "",
10+
round: true,
11+
})} 전`;
12+
};
13+
14+
export const dateToString = (dateString) => {
15+
const date = new Date(dateString);
16+
return `${date.toLocaleDateString("ko-KR")} ${date.toLocaleTimeString("en-GB")}`;
17+
};

0 commit comments

Comments
 (0)