Skip to content

Commit 325ca1b

Browse files
committed
feat: implement WebSocket hook and integrate into dashboard pages
1 parent dc01e0b commit 325ca1b

File tree

4 files changed

+526
-85
lines changed

4 files changed

+526
-85
lines changed

next.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ const nextConfig: NextConfig = {
55
};
66

77
export default nextConfig;
8+
module.exports = nextConfig;

src/app/dashboard-master/page.tsx

Lines changed: 152 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,163 @@
11
'use client'
22

3-
import React from 'react'
3+
import React, { useState, useEffect } from 'react'
44
import './app.css'
5+
import styles from '../dashboard-master/dashboard.module.css'
56
import { Cinzel } from 'next/font/google'
6-
import MainContent from './MainContent'
7-
import CampaignButtons from './CampaignButtons'
7+
import Image from 'next/image'
8+
import useWebSocket from '@/hooks/useWebSocket'
89

910
const cinzel = Cinzel({
10-
subsets: ['latin'],
11-
weight: ['700'],
11+
subsets: ['latin'],
12+
weight: ['700'],
1213
})
1314

15+
const Box = () => {
16+
const campaigns = [
17+
{ logo: '/images/rocket.png', title: 'UMA ODISSÉIA NO ESPAÇO' },
18+
{ logo: '/images/spider.png', title: 'A FLORESTA RADIOATIVA' },
19+
];
20+
21+
return (
22+
<div className={styles.boxContainer}> {}
23+
{campaigns.map(({ logo, title }, idx) => (
24+
<div key={idx} className={styles.card}> {}
25+
<div className={styles.cardHeader}> {}
26+
<Image src={logo} alt={`Logo ${idx + 1}`} width={40} height={40} />
27+
<span className={styles.cardTitle}>{title}</span> {}
28+
</div>
29+
30+
<div className={styles.cardContent}> {}
31+
<div className={styles.cardColumn}> {}
32+
<div className={styles.sectionTitle}>MESTRE</div> {}
33+
<div className={styles.sectionTitle}>JOGADORES</div> {}
34+
<div className={styles.playersGrid}> {}
35+
{[1, 2, 3, 4].map((i) => (
36+
<Image key={i} src='/images/circle.png' alt={`Jogador ${i}`} width={50} height={50} />
37+
))}
38+
</div>
39+
</div>
40+
41+
<div className={styles.cardColumn}> {}
42+
<div className={styles.sectionTitleRight}>MAPA</div> {}
43+
<Image src='/images/image.png' alt='Mapa' width={150} height={100} className={styles.mapImage} /> {}
44+
<div className={styles.mapName}>NOME DO MAPA</div> {}
45+
<div className={styles.sectionTitle}>ESTATISTICAS</div> {}
46+
47+
<div className={styles.statItem}> {}
48+
<Image src='/images/clock.png' alt='Tempo' width={25} height={25} />
49+
<span>00:00:00</span>
50+
</div>
51+
<div className={styles.divider}></div> {}
52+
<div className={styles.statItem}> {}
53+
<Image src='/images/check.png' alt='Check' width={25} height={25} />
54+
<span>SESSÕES REALIZADAS</span>
55+
</div>
56+
<div className={styles.divider}></div> {}
57+
<div className={styles.statItem}> {}
58+
<Image src='/images/calendar.png' alt='Calendário' width={25} height={25} />
59+
<span>00/00/0000</span>
60+
</div>
61+
</div>
62+
</div>
63+
</div>
64+
))}
65+
</div>
66+
);
67+
}
68+
69+
1470
const Page: React.FC = () => {
15-
return (
16-
<div className='page-container'>
17-
{/* SIDEBAR */}
18-
<div className='sidebar'>
19-
<div className='logo-container'>
20-
<img src='/images/logo1.png' alt='Logo' className='logo' />
21-
</div>
22-
</div>
23-
24-
{/* MAIN AND TOPBAR */}
25-
<div className='main-and-topbar'>
26-
<div className='topbar'>
27-
<div className='topbar-left'>
28-
<img src='/images/light-icon.png' alt='Ícone TopBar' className='topbar-icon' />
29-
</div>
30-
31-
<div className='topbar-content'>
32-
<h2 className={`${cinzel.className}`}>DASHBOARD DO MESTRE</h2>
33-
</div>
34-
35-
{/* SIDEBAR AND ADITIONAL BUTTONS */}
36-
<div className='topbar-right'>
37-
<button className='logout-button'>LOGOUT</button>
38-
<button className='avatar-button'>
39-
<img src='/images/profile.png' alt='Avatar do Usuário' className='avatar-image' />
40-
</button>
41-
</div>
42-
</div>
43-
44-
{/* CAMPAIGN BUTTONS */}
45-
<CampaignButtons />
46-
47-
{/* MAIN CONTENT */}
48-
<MainContent />
49-
</div>
50-
</div>
51-
)
71+
const session_id = 'master_session_123'; // Substitua por lógica real para obter o ID da sessão do mestre
72+
const user_id = 456; // Substitua por lógica real para obter o ID do usuário mestre
73+
74+
const wsHost = typeof window !== 'undefined' ? window.location.hostname : 'localhost';
75+
const wsPort = process.env.NEXT_PUBLIC_SESSION_PORT || '8081';
76+
const websocketUrl = `ws://${wsHost}:${wsPort}/ws/sessions/${session_id}/connect/${user_id}`;
77+
78+
const [messages, setMessages] = useState<any[]>([]); // Estado para mensagens recebidas (exemplo)
79+
80+
const { isConnected, error, sendMessage, disconnect } = useWebSocket({
81+
url: websocketUrl,
82+
onMessage: (message) => {
83+
console.log('Mensagem recebida no componente Mestre:', message);
84+
setMessages((prevMessages) => [...prevMessages, message]);
85+
},
86+
onOpen: () => {
87+
console.log('Conexão WebSocket aberta no componente Mestre.');
88+
sendMessage({ type: 'master_connected', session_id: session_id, user_id: user_id });
89+
},
90+
onClose: (event) => {
91+
console.log('Conexão WebSocket fechada no componente Mestre.', event);
92+
},
93+
onError: (event) => {
94+
console.error('Erro no WebSocket no componente Mestre:', event);
95+
}
96+
});
97+
98+
// Opcional: Efeito para desconectar ao sair da página
99+
useEffect(() => {
100+
return () => {
101+
disconnect();
102+
};
103+
}, [disconnect]);
104+
105+
106+
return (
107+
<div className='page-container'> {}
108+
{/* SIDEBAR */}
109+
<div className='sidebar'> {}
110+
<div className='logo-container'> {}
111+
{}
112+
<Image src='/images/logo1.png' alt='Logo' className='logo' width={180} height={180} /> {}
113+
</div>
114+
</div>
115+
116+
{/* MAIN AND TOPBAR */}
117+
<div className='main-and-topbar'> {}
118+
<div className='topbar'> {}
119+
<div className='topbar-left'> {}
120+
{}
121+
<Image src='/images/light-icon.png' alt='Ícone TopBar' className='topbar-icon' width={70} height={70} /> {}
122+
</div>
123+
124+
<div className='topbar-content'> {}
125+
<h2 className={`${cinzel.className}`}>DASHBOARD DO MESTRE</h2>
126+
</div>
127+
{/* Adicionar botão de logout se necessário */}
128+
{/* <button className={styles.logoutButton}>LOGOUT</button> */}
129+
</div>
130+
131+
<div className='main-content'> {}
132+
<div className={styles.contentWrapper}> {}
133+
<div className={styles.sessionActions}> {}
134+
<button className={styles.sessionButton}>CRIAR CAMPANHA</button> {}
135+
<button className={`${styles.sessionButton} ${styles.deleteButton}`}>EXCLUIR CAMPANHA</button> {/* Classes de dashboard.module.css */}
136+
137+
{/* Exibir status da conexão e mensagens (para debug/demonstração) */}
138+
<div style={{ marginTop: '1rem', color: isConnected ? 'green' : 'red' }}>
139+
Status da Conexão WebSocket: {isConnected ? 'Conectado' : 'Desconectado'}
140+
</div>
141+
{error && <div style={{ color: 'red' }}>Erro: {error.type}</div>} {/* Melhorar exibição do erro */}
142+
143+
{/* Exibir mensagens recebidas (para debug/demonstração) */}
144+
<div style={{ marginTop: '1rem', border: '1px solid #ccc', padding: '10px', maxHeight: '200px', overflowY: 'auto' }}>
145+
<h4>Mensagens Recebidas (Mestre):</h4>
146+
{messages.map((msg, index) => (
147+
<p key={index}>{JSON.stringify(msg)}</p>
148+
))}
149+
</div>
150+
151+
</div>
152+
153+
<div className={styles.boxContainer}> {}
154+
<Box />
155+
</div>
156+
</div>
157+
</div>
158+
</div>
159+
</div>
160+
)
52161
}
53162

54-
export default Page
163+
export default Page;

0 commit comments

Comments
 (0)