Skip to content

Commit 9c3619a

Browse files
committed
wip
1 parent 2fe8155 commit 9c3619a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1567
-1145
lines changed

webapp/chat-app/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
"version": "0.1.0",
44
"private": true,
55
"dependencies": {
6+
"mermaid": "^10.0.0",
7+
"qrcode-generator": "^1.4.4",
68
"@fortawesome/free-solid-svg-icons": "^6.7.1",
79
"@fortawesome/react-fontawesome": "^0.2.2",
810
"@reduxjs/toolkit": "^1.9.7",
911
"@testing-library/jest-dom": "^5.17.0",
1012
"@testing-library/react": "^13.4.0",
1113
"@testing-library/user-event": "^13.5.0",
1214
"dompurify": "^3.2.1",
15+
"prismjs": "^1.29.0",
1316
"react": "^18.3.1",
1417
"react-dom": "^18.3.1",
1518
"react-redux": "^8.1.3",
@@ -22,6 +25,7 @@
2225
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
2326
"@types/dompurify": "^3.2.0",
2427
"@types/node": "^18.0.0",
28+
"@types/prismjs": "^1.26.3",
2529
"@types/react": "^18.2.37",
2630
"@types/react-dom": "^18.2.15",
2731
"@types/react-redux": "^7.1.34",
@@ -69,4 +73,4 @@
6973
"last 1 safari version"
7074
]
7175
}
72-
}
76+
}

webapp/chat-app/src/App.css

Lines changed: 94 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,105 @@
11
.App {
2-
text-align: center;
3-
height: 100vh;
4-
display: flex;
5-
flex-direction: column;
2+
text-align: center;
3+
height: 100vh;
4+
display: flex;
5+
flex-direction: column;
66
}
77

8+
.App-main {
9+
flex: 1;
10+
display: flex;
11+
flex-direction: column;
12+
padding: 1rem;
13+
overflow: auto;
14+
}
15+
16+
.App-header {
17+
padding: 1rem;
18+
display: flex;
19+
flex-direction: column;
20+
align-items: center;
21+
justify-content: center;
22+
}
23+
24+
825
.App-logo {
9-
height: 40vmin;
10-
pointer-events: none;
26+
height: 40vmin;
27+
pointer-events: none;
1128
}
1229

1330
@media (prefers-reduced-motion: no-preference) {
14-
.App-logo {
15-
animation: App-logo-spin infinite 20s linear;
16-
}
31+
.App-logo {
32+
animation: App-logo-spin infinite 20s linear;
33+
}
1734
}
1835

1936
.App-header {
20-
padding: 1rem;
21-
display: flex;
22-
flex-direction: column;
23-
align-items: center;
24-
justify-content: center;
37+
padding: 1rem;
38+
display: flex;
39+
flex-direction: column;
40+
align-items: center;
41+
justify-content: center;
42+
}
43+
44+
45+
.tab-button {
46+
padding: 0.5rem 1rem;
47+
border: none;
48+
background: none;
49+
cursor: pointer;
50+
position: relative;
51+
font-weight: bold;
52+
color: #007bff;
53+
transition: all 0.2s ease-in-out;
54+
}
55+
56+
.tab-button:hover {
57+
background: #f2f2f7;
58+
}
59+
60+
.tab-content {
61+
flex: 1;
62+
overflow: auto;
63+
display: none; /* Hide by default */
64+
flex-direction: column;
65+
padding: 1rem;
66+
animation: fadeIn 0.3s ease-in-out;
67+
}
68+
69+
.tab-content.active {
70+
display: flex;
71+
}
72+
73+
@keyframes fadeIn {
74+
from {
75+
opacity: 0;
76+
}
77+
to {
78+
opacity: 1;
79+
}
80+
}
81+
82+
.cmd-button {
83+
display: inline-block;
84+
padding: 8px 15px;
85+
font-size: 14px;
86+
cursor: pointer;
87+
text-align: center;
88+
text-decoration: none;
89+
outline: none;
90+
color: #fff;
91+
background-color: #4CAF50;
92+
border: none;
93+
border-radius: 5px;
94+
box-shadow: 0 9px #999;
95+
}
96+
97+
.cmd-button:hover {
98+
background-color: #3e8e41;
99+
}
100+
101+
.cmd-button:active {
102+
background-color: #3e8e41;
103+
box-shadow: 0 5px #666;
104+
transform: translateY(4px);
25105
}

webapp/chat-app/src/App.test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ console.log('Starting App component tests...');
66

77
test('renders learn react link', () => {
88
console.log('Testing: Rendering App component');
9-
render(<App />);
9+
render(<App/>);
1010
console.log('Testing: Searching for "learn react" text');
11-
const linkElement = screen.getByText(/learn react/i);
11+
const linkElement = screen.getByText(/learn react/i);
1212
console.log('Testing: Verifying element is in document');
13-
expect(linkElement).toBeInTheDocument();
13+
expect(linkElement).toBeInTheDocument();
1414
console.log('Test completed successfully');
1515
});
1616
afterAll(() => {

webapp/chat-app/src/App.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
import React from 'react';
22
import {Provider} from 'react-redux';
33
import {store} from './store';
4+
import CodeHighlighter from './components/CodeHighlighter';
5+
import MermaidDiagram from './components/MermaidDiagram';
46
import websocket from './services/websocket';
57
import {GlobalStyles} from './styles/GlobalStyles';
68
import ChatInterface from './components/ChatInterface';
79
import ThemeProvider from './themes/ThemeProvider';
810
import {Menu} from "./components/Menu/Menu";
911
import {Modal} from "./components/Modal/Modal";
12+
import Prism from 'prismjs';
13+
import 'prismjs/components/prism-javascript';
14+
import 'prismjs/components/prism-css';
15+
import 'prismjs/components/prism-markup';
16+
import 'prismjs/plugins/toolbar/prism-toolbar';
17+
import 'prismjs/plugins/copy-to-clipboard/prism-copy-to-clipboard';
18+
import 'prismjs/plugins/line-numbers/prism-line-numbers';
19+
import 'prismjs/plugins/match-braces/prism-match-braces';
20+
import 'prismjs/plugins/show-language/prism-show-language';
21+
import mermaid from 'mermaid';
22+
import QRCode from 'qrcode-generator';
1023

1124
const App: React.FC = () => {
1225
console.log('[App] Component rendering');
@@ -19,6 +32,14 @@ const App: React.FC = () => {
1932
});
2033
React.useEffect(() => {
2134
console.log('[App] Component mounted');
35+
Prism.highlightAll();
36+
Prism.highlightAll();
37+
mermaid.run();
38+
// Example of generating a QR code
39+
const qr = QRCode(0, 'L');
40+
qr.addData('https://example.com');
41+
qr.make();
42+
console.log(qr.createImgTag());
2243
return () => {
2344
console.log('[App] Component unmounting');
2445
};
@@ -42,6 +63,8 @@ const App: React.FC = () => {
4263
websocket={websocket}
4364
isConnected={isConnected}
4465
/>
66+
<CodeHighlighter code={`const hello = "world";`}/>
67+
<MermaidDiagram chart={`graph TD; A-->B; A-->C; B-->D; C-->D;`}/>
4568
<Modal/>
4669
</div>
4770
</>

webapp/chat-app/src/components/Chat/index.tsx

Lines changed: 67 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,83 @@
11
import React, {useEffect} from 'react';
2-
import styled, {DefaultTheme} from 'styled-components';
2+
import styled from 'styled-components';
33
import {Message} from '../../types';
44
import {logger} from '../../utils/logger';
5+
import Tabs from '../Tabs';
6+
import MessageList from '../MessageList';
7+
import InputArea from '../InputArea';
58

69
const ChatContainer = styled.div`
7-
display: flex;
8-
flex-direction: column;
9-
height: 100%;
10+
display: flex;
11+
flex-direction: column;
12+
height: 100%;
1013
`;
1114

12-
const MessageList = styled.div`
13-
flex: 1;
14-
overflow-y: auto;
15-
padding: 1rem;
16-
`;
17-
18-
const InputArea = styled.div<{ theme: DefaultTheme }>`
19-
padding: 1rem;
20-
border-top: 1px solid ${(props: { theme: DefaultTheme }) => props.theme.colors.border};
15+
const TabContent = styled.div`
16+
flex: 1;
17+
display: flex;
18+
flex-direction: column;
19+
overflow: hidden;
2120
`;
2221

2322
interface ChatProps {
24-
messages: Message[];
25-
onSendMessage: (content: string) => void;
23+
messages: Message[];
24+
onSendMessage: (content: string) => void;
2625
}
2726

28-
const Chat: React.FC<ChatProps> = ({ messages, onSendMessage }) => {
29-
// Log component mount and updates
30-
useEffect(() => {
31-
logger.component('Chat', 'Component mounted');
32-
logger.component('Chat', 'Initial messages:', messages);
33-
return () => {
34-
logger.component('Chat', 'Component unmounting');
35-
};
36-
}, []);
37-
// Log when messages change
38-
useEffect(() => {
39-
console.log('[Chat] Messages updated:', messages);
40-
}, [messages]);
41-
// Wrap onSendMessage to add logging
42-
const handleSendMessage = (content: string) => {
43-
console.log('[Chat] Sending message:', content);
44-
onSendMessage(content);
45-
};
46-
// Log render
47-
console.log('[Chat] Rendering with', messages.length, 'messages');
27+
const Chat: React.FC<ChatProps> = ({messages, onSendMessage}) => {
28+
const [activeTab, setActiveTab] = React.useState('chat');
29+
const tabs = [
30+
{id: 'chat', label: 'Chat'},
31+
{id: 'files', label: 'Files'},
32+
{id: 'settings', label: 'Settings'}
33+
];
34+
35+
// Log component mount and updates
36+
useEffect(() => {
37+
logger.component('Chat', 'Component mounted');
38+
logger.component('Chat', 'Initial messages:', messages);
39+
return () => {
40+
logger.component('Chat', 'Component unmounting');
41+
};
42+
}, []);
43+
// Save active tab to localStorage when it changes
44+
useEffect(() => {
45+
logger.component('Chat', 'Saved active tab:', activeTab);
46+
}, [activeTab]);
47+
48+
49+
useEffect(() => {
50+
console.log('[Chat] Messages updated:', messages);
51+
}, [messages]);
52+
53+
console.log('[Chat] Rendering with', messages.length, 'messages');
4854

49-
return (
50-
<ChatContainer>
51-
<MessageList>
52-
{/* Message components will go here */}
53-
</MessageList>
54-
<InputArea>
55-
{/* Input component will go here */}
56-
</InputArea>
57-
</ChatContainer>
58-
);
55+
return (
56+
<ChatContainer>
57+
<Tabs tabs={tabs} activeTab={activeTab} onTabChange={setActiveTab}>
58+
<TabContent>
59+
{activeTab === 'chat' && (
60+
<>
61+
<MessageList messages={messages}/>
62+
<InputArea onSendMessage={onSendMessage}/>
63+
</>
64+
)}
65+
{activeTab === 'files' && (
66+
<div className="tab-content" data-tab="files">
67+
<h2>Files</h2>
68+
<p>Browse and manage your chat files here.</p>
69+
</div>
70+
)}
71+
{activeTab === 'settings' && (
72+
<div className="tab-content" data-tab="settings">
73+
<h2>Settings</h2>
74+
<p>Configure your chat preferences here.</p>
75+
</div>
76+
)}
77+
</TabContent>
78+
</Tabs>
79+
</ChatContainer>
80+
);
5981
};
6082
// Add display name for better debugging
6183
Chat.displayName = 'Chat';

webapp/chat-app/src/components/ChatInterface.tsx

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,33 @@ const ChatInterface: React.FC<ChatInterfaceProps> = ({
4040

4141
const handleMessage = (data: WebSocketMessage) => {
4242
console.log('[ChatInterface] Received message:', data);
43-
// If data is an object with raw data property, use that instead
44-
const messageData = typeof data === 'object' ? data.data : data;
45-
if (!messageData || typeof messageData !== 'string') {
43+
// Handle HTML messages differently
44+
if (data.isHtml) {
45+
console.debug('[ChatInterface] Processing HTML message');
46+
dispatch(addMessage({
47+
id: `${Date.now()}`,
48+
content: data.data,
49+
type: 'response',
50+
timestamp: data.timestamp,
51+
isHtml: true,
52+
rawHtml: data.data,
53+
version: '1.0',
54+
sanitized: false
55+
}));
56+
return;
57+
}
58+
// Handle regular messages
59+
if (!data.data || typeof data.data !== 'string') {
4660
console.warn('[ChatInterface] Invalid message format received:', data);
4761
return;
4862
}
63+
// Ignore connect messages
64+
if (data.data.includes('"type":"connect"')) {
65+
console.debug('[ChatInterface] Ignoring connect message');
66+
return;
67+
}
4968

50-
const [id, version, content] = messageData.split(',');
69+
const [id, version, content] = data.data.split(',');
5170
const timestamp = Date.now();
5271
const messageObject = {
5372
id: `${id}-${timestamp}`,

0 commit comments

Comments
 (0)