Skip to content

Commit 7c6b8e4

Browse files
Nlw concluded
1 parent 198c700 commit 7c6b8e4

File tree

11 files changed

+455
-35
lines changed

11 files changed

+455
-35
lines changed

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
"serve": "vite preview"
88
},
99
"dependencies": {
10+
"axios": "^0.24.0",
1011
"react": "^17.0.0",
1112
"react-dom": "^17.0.0",
1213
"react-icons": "^4.3.1",
13-
"sass": "^1.43.4"
14+
"sass": "^1.43.4",
15+
"socket.io-client": "^4.3.2"
1416
},
1517
"devDependencies": {
1618
"@types/react": "^17.0.0",

src/App.module.scss

+12
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,16 @@
77
grid-template-columns: 1fr 453px;
88
column-gap: 120px;
99
position: relative;
10+
}
11+
12+
.contentSigned::before {
13+
content: '';
14+
height: 100vh;
15+
width: 420px;
16+
background: url('./assets/background.svg') no-repeat;
17+
background-size: cover;
18+
position: absolute;
19+
right: -200px;
20+
top: 0;
21+
1022
}

src/App.tsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1+
import { useContext } from 'react';
12
import styles from './App.module.scss';
23
import { LoginBox } from './components/LoginBox';
34
import { MessageList } from './components/MessageList';
5+
import { SendMessageForm } from './components/SendMessageForm';
6+
import { AuthContext } from './contexts/auth';
47

58
export function App() {
9+
const { user } = useContext(AuthContext);
610

711
return (
8-
<main className={styles.contentWrapper}>
12+
<main className={`${styles.contentWrapper} ${!!user ? styles.contentSigned : ''}`}>
913
<MessageList />
10-
<LoginBox />
14+
{ !!user ? <SendMessageForm /> : <LoginBox /> }
1115
</main>
1216
)
1317
}

src/components/LoginBox/index.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1+
import { useContext } from 'react';
12
import { VscGithubInverted } from 'react-icons/vsc';
2-
3+
import { AuthContext } from '../../contexts/auth';
34
import styles from './styles.module.scss';
45

56
export function LoginBox() {
7+
const { signInUrl } = useContext(AuthContext);
68
return (
79
<div className={styles.loginBoxWrapper}>
810
<strong>Entre e compartilhe sua mensagem</strong>
9-
<a href="#" className={styles.signInWithGithub}>
11+
<a href={signInUrl} className={styles.signInWithGithub}>
1012
<VscGithubInverted size={24}/>
1113
Entrar com Github
1214
</a>

src/components/MessageList/index.tsx

+55-28
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,67 @@
11
import styles from "./styles.module.scss";
22
import LogoImg from '../../assets/logo.svg';
3+
import { useEffect, useState } from "react";
4+
import io from 'socket.io-client';
5+
import { api } from "../../services/api";
6+
7+
type Message = {
8+
id: string;
9+
text: string;
10+
user: {
11+
name: string;
12+
avatar_url: string;
13+
}
14+
};
15+
16+
const messagesQueue: Message[] = [];
17+
18+
const socket = io('http://localhost:3333');
19+
20+
socket.on('new_message', (newMessage: Message) => {
21+
messagesQueue.push(newMessage);
22+
})
23+
324

425
export function MessageList() {
26+
const [messages, setMessages] = useState<Message[]>([]);
27+
28+
useEffect(() => {
29+
const timer = setInterval(() => {
30+
if (messagesQueue.length > 0) {
31+
setMessages(prevState => [
32+
messagesQueue[0],
33+
prevState[0],
34+
prevState[1],
35+
].filter(Boolean));
36+
37+
messagesQueue.shift();
38+
}
39+
}, 3000);
40+
}, []);
41+
42+
useEffect(() => {
43+
api.get<Message[]>('/messages/last3').then(response => {
44+
setMessages(response.data);
45+
});
46+
}, []);
547
return (
648
<div className={styles.messageListWrapper}>
749
<img src={LogoImg} alt="Dowhile2021" />
850

951
<ul className={styles.messageList}>
10-
<li className={styles.message}>
11-
<p className={styles.messageContent}>Não vejo a hora de começar esse evento, com certeza vai ser o melhor de todos os tempos, vamooo pra cima! 🔥🔥</p>
12-
<div className={styles.messageUser}>
13-
<div className={styles.userImage}>
14-
<img src="https://github.com/rodrigosaantos.png" alt="Rodrigo Santos" />
15-
</div>
16-
<span>Rodrigo Santos</span>
17-
</div>
18-
</li>
19-
<li className={styles.message}>
20-
<p className={styles.messageContent}>Não vejo a hora de começar esse evento, com certeza vai ser o melhor de todos os tempos, vamooo pra cima! 🔥🔥</p>
21-
<div className={styles.messageUser}>
22-
<div className={styles.userImage}>
23-
<img src="https://github.com/rodrigosaantos.png" alt="Rodrigo Santos" />
24-
</div>
25-
<span>Rodrigo Santos</span>
26-
</div>
27-
</li>
28-
<li className={styles.message}>
29-
<p className={styles.messageContent}>Não vejo a hora de começar esse evento, com certeza vai ser o melhor de todos os tempos, vamooo pra cima! 🔥🔥</p>
30-
<div className={styles.messageUser}>
31-
<div className={styles.userImage}>
32-
<img src="https://github.com/rodrigosaantos.png" alt="Rodrigo Santos" />
33-
</div>
34-
<span>Rodrigo Santos</span>
35-
</div>
36-
</li>
37-
52+
{messages.map(message => {
53+
return (
54+
<li className={styles.message} key={message.id}>
55+
<p className={styles.messageContent}>{message.text}</p>
56+
<div className={styles.messageUser}>
57+
<div className={styles.userImage}>
58+
<img src={message.user.avatar_url} alt={message.user.name} />
59+
</div>
60+
<span>{message.user.name}</span>
61+
</div>
62+
</li>
63+
)
64+
})}
3865
</ul>
3966
</div>
4067
)
+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { FormEvent, useContext, useState } from 'react';
2+
import { VscGithubInverted, VscSignOut } from 'react-icons/vsc';
3+
import { AuthContext } from '../../contexts/auth';
4+
import { api } from '../../services/api';
5+
import styles from './styles.module.scss';
6+
7+
export function SendMessageForm() {
8+
const { user, signOut } = useContext(AuthContext);
9+
const [message, setMessage] = useState('');
10+
11+
async function handleSendMessage(event: FormEvent) {
12+
event.preventDefault();
13+
if (!message.trim()) {
14+
return;
15+
}
16+
await api.post('/messages', { message });
17+
18+
setMessage('');
19+
20+
}
21+
return (
22+
<div className={styles.sendMessageFormWrapper}>
23+
<button onClick={signOut} className={styles.signOutButton}>
24+
<VscSignOut size={32} />
25+
</button>
26+
27+
<header className={styles.userInformation}>
28+
<div className={styles.userImage}>
29+
<img src={user?.avatar_url} alt={user?.name} />
30+
</div>
31+
<strong className={styles.userName}>{user?.name}</strong>
32+
<span className={styles.userGithub}>
33+
<VscGithubInverted size={16}/>
34+
{user?.login}
35+
</span>
36+
</header>
37+
38+
<form onSubmit={handleSendMessage} className={styles.sendMessageForm}>
39+
<label htmlFor="message">Mensagem</label>
40+
<textarea
41+
name="message"
42+
id="message"
43+
placeholder="Qual sua expectativa para o evento?"
44+
value={message}
45+
onChange={event => setMessage(event.target.value)}
46+
/>
47+
<button type="submit">Enviar mensagem</button>
48+
</form>
49+
</div>
50+
)
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
.sendMessageFormWrapper {
2+
background: #1b1b1f;
3+
padding: 24px;
4+
align-self: center;
5+
6+
display: flex;
7+
flex-direction: column;
8+
align-items: center;
9+
text-align: center;
10+
11+
position: relative;
12+
}
13+
14+
.signOutButton {
15+
background: transparent;
16+
border: 0;
17+
color: #c4c4cc;
18+
19+
position: absolute;
20+
left: 24px;
21+
top: 24px;
22+
23+
cursor: pointer;
24+
25+
&:hover {
26+
filter: brightness(0.9);
27+
}
28+
}
29+
30+
.userInformation {
31+
display: flex;
32+
flex-direction: column;
33+
align-items: center;
34+
35+
.userImage {
36+
padding: 3px;
37+
background: linear-gradient(100deg, #ff008e 0%, #ffcd1e 100%);
38+
border-radius: 50%;
39+
line-height: 0;
40+
41+
img {
42+
width: 94px;
43+
height: 94px;
44+
border-radius: 50%;
45+
border: 6px solid #121214;
46+
}
47+
}
48+
49+
.userName {
50+
font-size: 24px;
51+
line-height: 30px;
52+
margin-top: 16px;
53+
}
54+
55+
.userGithub {
56+
display: flex;
57+
align-items: center;
58+
59+
margin-top: 8px;
60+
color: #c4c4cc;
61+
62+
svg {
63+
margin-right: 8px;
64+
}
65+
}
66+
}
67+
68+
.sendMessageForm {
69+
display: flex;
70+
flex-direction: column;
71+
align-self: stretch;
72+
margin-top: 48px;
73+
74+
background: #202024;
75+
76+
label {
77+
padding: 18px 24px;
78+
font-size: 20px;
79+
background: #29292e;
80+
font-weight: bold;
81+
text-align: left;
82+
}
83+
84+
textarea {
85+
background: transparent;
86+
border: 0;
87+
padding: 24px;
88+
resize: none;
89+
height: 160px;
90+
color: #e1e1e6;
91+
font-size: 16px;
92+
line-height: 24px;
93+
94+
&:focus {
95+
outline: 0;
96+
}
97+
98+
&::placeholder {
99+
color: #8d8d99;
100+
}
101+
}
102+
103+
button {
104+
background: #ff008e;
105+
margin: 24px;
106+
cursor: pointer;
107+
padding: 0 32px;
108+
border: 0;
109+
height: 40px;
110+
color: #fff;
111+
font-size: 14px;
112+
font-weight: bold;
113+
text-transform: uppercase;
114+
text-decoration: none;
115+
116+
display: flex;
117+
align-items: center;
118+
align-self: flex-end;
119+
justify-content: center;
120+
border-radius: 8px;
121+
122+
&:hover {
123+
filter: brightness(0.9);
124+
}
125+
}
126+
}

0 commit comments

Comments
 (0)