Showing
7 changed files
with
134 additions
and
24 deletions
... | @@ -12,6 +12,7 @@ | ... | @@ -12,6 +12,7 @@ |
12 | "@testing-library/react": "^13.2.0", | 12 | "@testing-library/react": "^13.2.0", |
13 | "@testing-library/user-event": "^13.5.0", | 13 | "@testing-library/user-event": "^13.5.0", |
14 | "axios": "^0.27.2", | 14 | "axios": "^0.27.2", |
15 | + "dateformat": "^5.0.3", | ||
15 | "react": "^18.1.0", | 16 | "react": "^18.1.0", |
16 | "react-dom": "^18.1.0", | 17 | "react-dom": "^18.1.0", |
17 | "react-icons": "^4.4.0", | 18 | "react-icons": "^4.4.0", |
... | @@ -5959,6 +5960,14 @@ | ... | @@ -5959,6 +5960,14 @@ |
5959 | "node": ">=10" | 5960 | "node": ">=10" |
5960 | } | 5961 | } |
5961 | }, | 5962 | }, |
5963 | + "node_modules/dateformat": { | ||
5964 | + "version": "5.0.3", | ||
5965 | + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-5.0.3.tgz", | ||
5966 | + "integrity": "sha512-Kvr6HmPXUMerlLcLF+Pwq3K7apHpYmGDVqrxcDasBg86UcKeTSNWbEzU8bwdXnxnR44FtMhJAxI4Bov6Y/KUfA==", | ||
5967 | + "engines": { | ||
5968 | + "node": ">=12.20" | ||
5969 | + } | ||
5970 | + }, | ||
5962 | "node_modules/debug": { | 5971 | "node_modules/debug": { |
5963 | "version": "4.3.4", | 5972 | "version": "4.3.4", |
5964 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", | 5973 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", |
... | @@ -20639,6 +20648,11 @@ | ... | @@ -20639,6 +20648,11 @@ |
20639 | "whatwg-url": "^8.0.0" | 20648 | "whatwg-url": "^8.0.0" |
20640 | } | 20649 | } |
20641 | }, | 20650 | }, |
20651 | + "dateformat": { | ||
20652 | + "version": "5.0.3", | ||
20653 | + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-5.0.3.tgz", | ||
20654 | + "integrity": "sha512-Kvr6HmPXUMerlLcLF+Pwq3K7apHpYmGDVqrxcDasBg86UcKeTSNWbEzU8bwdXnxnR44FtMhJAxI4Bov6Y/KUfA==" | ||
20655 | + }, | ||
20642 | "debug": { | 20656 | "debug": { |
20643 | "version": "4.3.4", | 20657 | "version": "4.3.4", |
20644 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", | 20658 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", | ... | ... |
... | @@ -7,6 +7,7 @@ | ... | @@ -7,6 +7,7 @@ |
7 | "@testing-library/react": "^13.2.0", | 7 | "@testing-library/react": "^13.2.0", |
8 | "@testing-library/user-event": "^13.5.0", | 8 | "@testing-library/user-event": "^13.5.0", |
9 | "axios": "^0.27.2", | 9 | "axios": "^0.27.2", |
10 | + "dateformat": "^5.0.3", | ||
10 | "react": "^18.1.0", | 11 | "react": "^18.1.0", |
11 | "react-dom": "^18.1.0", | 12 | "react-dom": "^18.1.0", |
12 | "react-icons": "^4.4.0", | 13 | "react-icons": "^4.4.0", | ... | ... |
1 | +import dateFormat from "dateformat"; | ||
2 | +import { useEffect, useState } from "react"; | ||
3 | +import authService from "../service/auth"; | ||
1 | import "../styles/layout.scss"; | 4 | import "../styles/layout.scss"; |
2 | 5 | ||
3 | function Tweet({ writer, createdAt, text }) { | 6 | function Tweet({ writer, createdAt, text }) { |
7 | + const [username, setUsername] = useState(""); | ||
8 | + const dateTime = dateFormat(createdAt); | ||
9 | + | ||
10 | + useEffect(() => { | ||
11 | + async function fetchUsername() { | ||
12 | + const user = await authService.handleGetUser(writer); | ||
13 | + setUsername(user); | ||
14 | + } | ||
15 | + fetchUsername(); | ||
16 | + }, [username, setUsername]); | ||
17 | + | ||
4 | return ( | 18 | return ( |
5 | <div className="tweetBox"> | 19 | <div className="tweetBox"> |
6 | <p>{text}</p> | 20 | <p>{text}</p> |
7 | <small> | 21 | <small> |
8 | - <b>{writer}</b> {createdAt} | 22 | + <b>{username}</b> |
9 | </small> | 23 | </small> |
24 | + <small>{dateTime}</small> | ||
10 | </div> | 25 | </div> |
11 | ); | 26 | ); |
12 | } | 27 | } | ... | ... |
1 | +import { useEffect, useState } from "react"; | ||
2 | +import postsService from "../service/posts"; | ||
1 | // components | 3 | // components |
2 | import Tweet from "../components/Tweet"; | 4 | import Tweet from "../components/Tweet"; |
3 | import Topbar from "../components/Topbar"; | 5 | import Topbar from "../components/Topbar"; |
4 | import Bottombar from "../components/Bottombar"; | 6 | import Bottombar from "../components/Bottombar"; |
5 | 7 | ||
6 | function Tweets() { | 8 | function Tweets() { |
7 | - const posts = [ | 9 | + const [posts, setPosts] = useState([]); |
8 | - { | 10 | + const [text, setText] = useState(""); |
9 | - user: "tom", | 11 | + |
10 | - text: "test post", | 12 | + const onRefresh = async () => { |
11 | - createdAt: "2022-02-11", | 13 | + const posts = await postsService.getAllPosts(); |
12 | - }, | 14 | + setPosts(posts); |
13 | - { | 15 | + }; |
14 | - user: "jasmine", | 16 | + |
15 | - text: "test post #2", | 17 | + const onTextInput = (e) => { |
16 | - createdAt: "2022-03-03", | 18 | + setText(e.target.value); |
17 | - }, | 19 | + }; |
18 | - ]; | 20 | + const handlePost = (e) => { |
21 | + e.preventDefault(); | ||
22 | + postsService.addPost(text); | ||
23 | + setText(""); | ||
24 | + }; | ||
25 | + | ||
26 | + useEffect(() => { | ||
27 | + async function fetchData() { | ||
28 | + const posts = await postsService.getAllPosts(); | ||
29 | + setPosts(posts); | ||
30 | + } | ||
31 | + fetchData(); | ||
32 | + }, []); | ||
19 | 33 | ||
20 | return ( | 34 | return ( |
21 | <div> | 35 | <div> |
22 | <Topbar /> | 36 | <Topbar /> |
23 | 37 | ||
24 | <div className="mainBox"> | 38 | <div className="mainBox"> |
25 | - <h2>Social Network</h2> | 39 | + <h2> |
40 | + Social Network <button onClick={() => onRefresh()}>refresh</button> | ||
41 | + </h2> | ||
42 | + | ||
26 | <br /> | 43 | <br /> |
27 | - {posts.map((data, index) => ( | 44 | + |
28 | - <Tweet | 45 | + <form className="" onSubmit={(e) => handlePost(e)}> |
29 | - key={index} | 46 | + <label htmlFor="text"> |
30 | - writer={data.user} | 47 | + <input |
31 | - text={data.text} | 48 | + placeholder="How's the weather?" |
32 | - createdAt={data.createdAt} | 49 | + onChange={(e) => onTextInput(e)} |
33 | - /> | 50 | + value={text} |
34 | - ))} | 51 | + type="text" |
52 | + id="text" | ||
53 | + /> | ||
54 | + </label> | ||
55 | + <label className="submitBtn" htmlFor="submit"> | ||
56 | + <input value="Post" type="submit" id="submit" /> | ||
57 | + </label> | ||
58 | + </form> | ||
59 | + | ||
60 | + <br /> | ||
61 | + | ||
62 | + {!posts | ||
63 | + ? "" | ||
64 | + : posts.map((post, index) => ( | ||
65 | + <Tweet | ||
66 | + key={index} | ||
67 | + text={post.text} | ||
68 | + writer={post.user} | ||
69 | + createdAt={post.createdAt} | ||
70 | + /> | ||
71 | + ))} | ||
35 | </div> | 72 | </div> |
36 | 73 | ||
37 | <Bottombar /> | 74 | <Bottombar /> | ... | ... |
... | @@ -61,10 +61,22 @@ const handleUserEdit = async ({ username, country, city, email }) => { | ... | @@ -61,10 +61,22 @@ const handleUserEdit = async ({ username, country, city, email }) => { |
61 | } | 61 | } |
62 | }; | 62 | }; |
63 | 63 | ||
64 | +const handleGetUser = async (userId) => { | ||
65 | + try { | ||
66 | + const response = await axios.post("http://localhost:8080/api/users/self", { | ||
67 | + userId, | ||
68 | + }); | ||
69 | + return response.data.username; | ||
70 | + } catch (err) { | ||
71 | + console.log(err); | ||
72 | + } | ||
73 | +}; | ||
74 | + | ||
64 | const authService = { | 75 | const authService = { |
65 | handleSignup, | 76 | handleSignup, |
66 | handleLogin, | 77 | handleLogin, |
67 | handleUserEdit, | 78 | handleUserEdit, |
79 | + handleGetUser, | ||
68 | }; | 80 | }; |
69 | 81 | ||
70 | export default authService; | 82 | export default authService; | ... | ... |
client/src/service/posts.js
0 → 100644
1 | +const axios = require("axios").default; | ||
2 | + | ||
3 | +const getAllPosts = async () => { | ||
4 | + try { | ||
5 | + const response = await axios.get("http://localhost:8080/api/posts"); | ||
6 | + return response.data; | ||
7 | + } catch (err) { | ||
8 | + console.log(err); | ||
9 | + } | ||
10 | +}; | ||
11 | + | ||
12 | +const addPost = async (text) => { | ||
13 | + const token = JSON.parse(sessionStorage.getItem("user-token")).token; | ||
14 | + try { | ||
15 | + const response = await axios.post("http://localhost:8080/api/posts/add", { | ||
16 | + text, | ||
17 | + token, | ||
18 | + }); | ||
19 | + } catch (err) { | ||
20 | + console.log(err); | ||
21 | + } | ||
22 | +}; | ||
23 | + | ||
24 | +const postsService = { | ||
25 | + getAllPosts, | ||
26 | + addPost, | ||
27 | +}; | ||
28 | + | ||
29 | +export default postsService; |
... | @@ -19,6 +19,7 @@ html { | ... | @@ -19,6 +19,7 @@ html { |
19 | align-items: center; | 19 | align-items: center; |
20 | min-height: 82vh; | 20 | min-height: 82vh; |
21 | margin-top: 13vh; | 21 | margin-top: 13vh; |
22 | + margin-bottom: 10vh; | ||
22 | padding-left: 1rem; | 23 | padding-left: 1rem; |
23 | padding-right: 1rem; | 24 | padding-right: 1rem; |
24 | font-size: 2rem; | 25 | font-size: 2rem; |
... | @@ -98,16 +99,17 @@ hr { | ... | @@ -98,16 +99,17 @@ hr { |
98 | display: flex; | 99 | display: flex; |
99 | justify-content: center; | 100 | justify-content: center; |
100 | flex-direction: column; | 101 | flex-direction: column; |
101 | - width: 60%; | 102 | + width: 55%; |
102 | border: solid gray 2px; | 103 | border: solid gray 2px; |
103 | border-radius: 4px; | 104 | border-radius: 4px; |
104 | margin-bottom: 1rem; | 105 | margin-bottom: 1rem; |
105 | - padding: 0.2rem; | 106 | + padding: 0.2rem 0.4rem; |
106 | small { | 107 | small { |
107 | font-size: 1.5rem; | 108 | font-size: 1.5rem; |
108 | margin-top: 0.3rem; | 109 | margin-top: 0.3rem; |
109 | b { | 110 | b { |
110 | font-size: 1.6rem; | 111 | font-size: 1.6rem; |
112 | + margin-right: 0.5rem; | ||
111 | } | 113 | } |
112 | } | 114 | } |
113 | } | 115 | } | ... | ... |
-
Please register or login to post a comment