starsnatched commited on
Commit
c4aea9f
·
1 Parent(s): 95aeb25

Remove frontend codebase including components, styles, and configuration files

Browse files
frontend/.gitignore DELETED
@@ -1,24 +0,0 @@
1
- # Logs
2
- logs
3
- *.log
4
- npm-debug.log*
5
- yarn-debug.log*
6
- yarn-error.log*
7
- pnpm-debug.log*
8
- lerna-debug.log*
9
-
10
- node_modules
11
- dist
12
- dist-ssr
13
- *.local
14
-
15
- # Editor directories and files
16
- .vscode/*
17
- !.vscode/extensions.json
18
- .idea
19
- .DS_Store
20
- *.suo
21
- *.ntvs*
22
- *.njsproj
23
- *.sln
24
- *.sw?
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/README.md DELETED
@@ -1,12 +0,0 @@
1
- # React + Vite
2
-
3
- This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4
-
5
- Currently, two official plugins are available:
6
-
7
- - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) for Fast Refresh
8
- - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9
-
10
- ## Expanding the ESLint configuration
11
-
12
- If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/eslint.config.js DELETED
@@ -1,33 +0,0 @@
1
- import js from '@eslint/js'
2
- import globals from 'globals'
3
- import reactHooks from 'eslint-plugin-react-hooks'
4
- import reactRefresh from 'eslint-plugin-react-refresh'
5
-
6
- export default [
7
- { ignores: ['dist'] },
8
- {
9
- files: ['**/*.{js,jsx}'],
10
- languageOptions: {
11
- ecmaVersion: 2020,
12
- globals: globals.browser,
13
- parserOptions: {
14
- ecmaVersion: 'latest',
15
- ecmaFeatures: { jsx: true },
16
- sourceType: 'module',
17
- },
18
- },
19
- plugins: {
20
- 'react-hooks': reactHooks,
21
- 'react-refresh': reactRefresh,
22
- },
23
- rules: {
24
- ...js.configs.recommended.rules,
25
- ...reactHooks.configs.recommended.rules,
26
- 'no-unused-vars': ['error', { varsIgnorePattern: '^[A-Z_]' }],
27
- 'react-refresh/only-export-components': [
28
- 'warn',
29
- { allowConstantExport: true },
30
- ],
31
- },
32
- },
33
- ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/index.html DELETED
@@ -1,19 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
- <link rel="preconnect" href="https://fonts.googleapis.com" />
7
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
8
- <link
9
- href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap"
10
- rel="stylesheet"
11
- />
12
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
13
- <title>LLM Chat</title>
14
- </head>
15
- <body>
16
- <div id="root"></div>
17
- <script type="module" src="/src/main.jsx"></script>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/package-lock.json DELETED
The diff for this file is too large to render. See raw diff
 
frontend/package.json DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "name": "frontend",
3
- "private": true,
4
- "version": "0.0.0",
5
- "type": "module",
6
- "scripts": {
7
- "dev": "vite",
8
- "build": "vite build",
9
- "lint": "eslint .",
10
- "preview": "vite preview"
11
- },
12
- "dependencies": {
13
- "prop-types": "^15.8.1",
14
- "react": "^19.1.0",
15
- "react-dom": "^19.1.0"
16
- },
17
- "devDependencies": {
18
- "@eslint/js": "^9.25.0",
19
- "@types/react": "^19.1.2",
20
- "@types/react-dom": "^19.1.2",
21
- "@vitejs/plugin-react": "^4.4.1",
22
- "eslint": "^9.25.0",
23
- "eslint-plugin-react-hooks": "^5.2.0",
24
- "eslint-plugin-react-refresh": "^0.4.19",
25
- "globals": "^16.0.0",
26
- "vite": "^6.3.5"
27
- }
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/public/vite.svg DELETED
frontend/src/App.css DELETED
@@ -1,42 +0,0 @@
1
- #root {
2
- max-width: 1280px;
3
- margin: 0 auto;
4
- padding: 2rem;
5
- text-align: center;
6
- }
7
-
8
- .logo {
9
- height: 6em;
10
- padding: 1.5em;
11
- will-change: filter;
12
- transition: filter 300ms;
13
- }
14
- .logo:hover {
15
- filter: drop-shadow(0 0 2em #646cffaa);
16
- }
17
- .logo.react:hover {
18
- filter: drop-shadow(0 0 2em #61dafbaa);
19
- }
20
-
21
- @keyframes logo-spin {
22
- from {
23
- transform: rotate(0deg);
24
- }
25
- to {
26
- transform: rotate(360deg);
27
- }
28
- }
29
-
30
- @media (prefers-reduced-motion: no-preference) {
31
- a:nth-of-type(2) .logo {
32
- animation: logo-spin infinite 20s linear;
33
- }
34
- }
35
-
36
- .card {
37
- padding: 2em;
38
- }
39
-
40
- .read-the-docs {
41
- color: #888;
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/src/App.jsx DELETED
@@ -1,8 +0,0 @@
1
- import ChatWindow from './components/ChatWindow'
2
- import './index.css'
3
-
4
- function App() {
5
- return <ChatWindow />
6
- }
7
-
8
- export default App
 
 
 
 
 
 
 
 
 
frontend/src/api.js DELETED
@@ -1,23 +0,0 @@
1
- const API_BASE = import.meta.env.VITE_API_BASE || 'http://localhost:8000';
2
-
3
- export async function fetchStream(user, session, prompt, onChunk) {
4
- const res = await fetch(`${API_BASE}/chat/stream`, {
5
- method: 'POST',
6
- headers: { 'Content-Type': 'application/json' },
7
- body: JSON.stringify({ user, session, prompt }),
8
- });
9
- const reader = res.body.getReader();
10
- const decoder = new TextDecoder();
11
- while (true) {
12
- const { value, done } = await reader.read();
13
- if (done) break;
14
- onChunk(decoder.decode(value));
15
- }
16
- }
17
-
18
- export async function fetchSessions(user) {
19
- const res = await fetch(`${API_BASE}/sessions/${encodeURIComponent(user)}`);
20
- if (!res.ok) return [];
21
- const data = await res.json();
22
- return data.sessions ?? [];
23
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/src/assets/react.svg DELETED
frontend/src/components/ChatWindow.jsx DELETED
@@ -1,63 +0,0 @@
1
- import { useEffect, useState } from 'react'
2
- import MessageList from './MessageList'
3
- import InputBar from './InputBar'
4
- import SessionList from './SessionList'
5
- import UsernameForm from './UsernameForm'
6
- import '../styles/chat.css'
7
- import { fetchStream, fetchSessions } from '../api'
8
-
9
- function ChatWindow() {
10
- const [messages, setMessages] = useState([])
11
- const [sessionName] = useState(() => crypto.randomUUID())
12
- const [sessions, setSessions] = useState([])
13
- const [username, setUsername] = useState(() =>
14
- localStorage.getItem('username') || ''
15
- )
16
-
17
- useEffect(() => {
18
- if (username) {
19
- fetchSessions(username).then(setSessions)
20
- }
21
- }, [username])
22
-
23
- const refreshSessions = () => {
24
- if (username) {
25
- fetchSessions(username).then(setSessions)
26
- }
27
- }
28
-
29
- const sendMessage = async (text) => {
30
- const userMsg = { role: 'user', content: text }
31
- setMessages((prev) => [...prev, userMsg, { role: 'assistant', content: '' }])
32
- const index = messages.length + 1
33
- await fetchStream(username, sessionName, text, (chunk) => {
34
- setMessages((prev) => {
35
- const copy = [...prev]
36
- copy[index] = { ...copy[index], content: copy[index].content + chunk }
37
- return copy
38
- })
39
- })
40
- refreshSessions()
41
- }
42
-
43
- const handleUsernameSet = (name) => {
44
- localStorage.setItem('username', name)
45
- setUsername(name)
46
- }
47
-
48
- return (
49
- <div className="chat-container">
50
- {!username ? (
51
- <UsernameForm onSet={handleUsernameSet} />
52
- ) : (
53
- <>
54
- <SessionList sessions={sessions} current={sessionName} />
55
- <MessageList messages={messages} />
56
- <InputBar onSend={sendMessage} />
57
- </>
58
- )}
59
- </div>
60
- )
61
- }
62
-
63
- export default ChatWindow
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/src/components/InputBar.jsx DELETED
@@ -1,31 +0,0 @@
1
- import { useState } from 'react'
2
- import PropTypes from 'prop-types'
3
-
4
- function InputBar({ onSend }) {
5
- const [text, setText] = useState('')
6
-
7
- const handleSubmit = (e) => {
8
- e.preventDefault()
9
- if (!text.trim()) return
10
- onSend(text)
11
- setText('')
12
- }
13
-
14
- return (
15
- <form className="input-bar" onSubmit={handleSubmit}>
16
- <input
17
- type="text"
18
- value={text}
19
- onChange={(e) => setText(e.target.value)}
20
- placeholder="Type a message..."
21
- />
22
- <button type="submit">Send</button>
23
- </form>
24
- )
25
- }
26
-
27
- InputBar.propTypes = {
28
- onSend: PropTypes.func.isRequired,
29
- }
30
-
31
- export default InputBar
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/src/components/MessageBubble.jsx DELETED
@@ -1,13 +0,0 @@
1
- import PropTypes from 'prop-types'
2
- import '../styles/chat.css'
3
-
4
- function MessageBubble({ role, content }) {
5
- return <div className={`message ${role}`}>{content}</div>
6
- }
7
-
8
- MessageBubble.propTypes = {
9
- role: PropTypes.string.isRequired,
10
- content: PropTypes.string.isRequired,
11
- }
12
-
13
- export default MessageBubble
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/src/components/MessageList.jsx DELETED
@@ -1,23 +0,0 @@
1
- import PropTypes from 'prop-types'
2
- import MessageBubble from './MessageBubble'
3
-
4
- function MessageList({ messages }) {
5
- return (
6
- <div className="message-list">
7
- {messages.map((m, i) => (
8
- <MessageBubble key={i} role={m.role} content={m.content} />
9
- ))}
10
- </div>
11
- )
12
- }
13
-
14
- MessageList.propTypes = {
15
- messages: PropTypes.arrayOf(
16
- PropTypes.shape({
17
- role: PropTypes.string.isRequired,
18
- content: PropTypes.string.isRequired,
19
- })
20
- ).isRequired,
21
- }
22
-
23
- export default MessageList
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/src/components/SessionList.jsx DELETED
@@ -1,24 +0,0 @@
1
- import PropTypes from 'prop-types'
2
- import '../styles/chat.css'
3
-
4
- function SessionList({ sessions, current }) {
5
- return (
6
- <div className="session-list">
7
- {sessions.map((name) => (
8
- <span
9
- key={name}
10
- className={`session-item ${name === current ? 'active' : ''}`}
11
- >
12
- {name}
13
- </span>
14
- ))}
15
- </div>
16
- )
17
- }
18
-
19
- SessionList.propTypes = {
20
- sessions: PropTypes.arrayOf(PropTypes.string).isRequired,
21
- current: PropTypes.string.isRequired,
22
- }
23
-
24
- export default SessionList
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/src/components/UsernameForm.jsx DELETED
@@ -1,32 +0,0 @@
1
- import { useState } from 'react'
2
- import PropTypes from 'prop-types'
3
- import '../styles/chat.css'
4
-
5
- function UsernameForm({ onSet }) {
6
- const [name, setName] = useState('')
7
-
8
- const handleSubmit = (e) => {
9
- e.preventDefault()
10
- const trimmed = name.trim()
11
- if (!trimmed) return
12
- onSet(trimmed)
13
- }
14
-
15
- return (
16
- <form className="username-form" onSubmit={handleSubmit}>
17
- <input
18
- type="text"
19
- value={name}
20
- onChange={(e) => setName(e.target.value)}
21
- placeholder="Enter your name..."
22
- />
23
- <button type="submit">Start Chatting</button>
24
- </form>
25
- )
26
- }
27
-
28
- UsernameForm.propTypes = {
29
- onSet: PropTypes.func.isRequired,
30
- }
31
-
32
- export default UsernameForm
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/src/index.css DELETED
@@ -1,47 +0,0 @@
1
- :root {
2
- --glass-bg: rgba(255, 255, 255, 0.15);
3
- --glass-border: rgba(255, 255, 255, 0.35);
4
- --blur: 16px;
5
- --radius: 20px;
6
- --glare: radial-gradient(circle at top left, rgba(255, 255, 255, 0.6), transparent);
7
- }
8
-
9
- * {
10
- box-sizing: border-box;
11
- }
12
-
13
- body {
14
- margin: 0;
15
- padding: 0;
16
- font-family: 'Inter', system-ui, Avenir, Helvetica, Arial, sans-serif;
17
- background: linear-gradient(120deg, #89f7fe 0%, #66a6ff 100%);
18
- display: flex;
19
- justify-content: center;
20
- align-items: center;
21
- min-height: 100vh;
22
- position: relative;
23
- overflow: hidden;
24
- }
25
-
26
- body::before,
27
- body::after {
28
- content: '';
29
- position: absolute;
30
- width: 300px;
31
- height: 300px;
32
- background: radial-gradient(circle at center, rgba(255, 255, 255, 0.5), transparent);
33
- filter: blur(100px);
34
- z-index: 0;
35
- mix-blend-mode: overlay;
36
- opacity: 0.6;
37
- }
38
-
39
- body::before {
40
- top: -80px;
41
- left: -80px;
42
- }
43
-
44
- body::after {
45
- bottom: -80px;
46
- right: -80px;
47
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/src/main.jsx DELETED
@@ -1,10 +0,0 @@
1
- import { StrictMode } from 'react'
2
- import { createRoot } from 'react-dom/client'
3
- import './index.css'
4
- import App from './App.jsx'
5
-
6
- createRoot(document.getElementById('root')).render(
7
- <StrictMode>
8
- <App />
9
- </StrictMode>,
10
- )
 
 
 
 
 
 
 
 
 
 
 
frontend/src/styles/chat.css DELETED
@@ -1,167 +0,0 @@
1
- .chat-container {
2
- width: 420px;
3
- max-width: 90vw;
4
- height: 600px;
5
- display: flex;
6
- flex-direction: column;
7
- background: var(--glass-bg);
8
- border: 1px solid var(--glass-border);
9
- backdrop-filter: blur(var(--blur)) saturate(180%);
10
- -webkit-backdrop-filter: blur(var(--blur)) saturate(180%);
11
- border-radius: var(--radius);
12
- padding: 1rem;
13
- box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
14
- position: relative;
15
- overflow: hidden;
16
- }
17
-
18
- .chat-container::before {
19
- content: '';
20
- position: absolute;
21
- inset: 0;
22
- background: var(--glare);
23
- mix-blend-mode: overlay;
24
- pointer-events: none;
25
- }
26
-
27
- .message-list {
28
- flex: 1;
29
- overflow-y: auto;
30
- display: flex;
31
- flex-direction: column;
32
- gap: 0.5rem;
33
- padding-right: 4px;
34
- scroll-behavior: smooth;
35
- }
36
-
37
- .session-list {
38
- display: flex;
39
- gap: 0.5rem;
40
- flex-wrap: wrap;
41
- margin-bottom: 0.5rem;
42
- z-index: 1;
43
- }
44
-
45
- .session-item {
46
- padding: 0.25rem 0.5rem;
47
- background: var(--glass-bg);
48
- border: 1px solid var(--glass-border);
49
- border-radius: var(--radius);
50
- backdrop-filter: blur(var(--blur));
51
- -webkit-backdrop-filter: blur(var(--blur));
52
- font-size: 0.75rem;
53
- transition: transform 0.2s cubic-bezier(0.22, 1, 0.36, 1);
54
- }
55
-
56
- .session-item.active {
57
- background: rgba(255, 255, 255, 0.4);
58
- font-weight: bold;
59
- }
60
-
61
- .message {
62
- width: fit-content;
63
- max-width: 80%;
64
- padding: 0.5rem 1rem;
65
- background: var(--glass-bg);
66
- border: 1px solid var(--glass-border);
67
- border-radius: var(--radius);
68
- backdrop-filter: blur(var(--blur));
69
- -webkit-backdrop-filter: blur(var(--blur));
70
- animation: jelly 0.6s cubic-bezier(0.22, 1, 0.36, 1);
71
- }
72
-
73
- .message.user {
74
- align-self: flex-end;
75
- }
76
-
77
- .input-bar {
78
- display: flex;
79
- gap: 0.5rem;
80
- margin-top: 0.5rem;
81
- }
82
-
83
- .input-bar input {
84
- flex: 1;
85
- padding: 0.5rem 1rem;
86
- border: 1px solid var(--glass-border);
87
- background: var(--glass-bg);
88
- border-radius: var(--radius);
89
- backdrop-filter: blur(var(--blur));
90
- -webkit-backdrop-filter: blur(var(--blur));
91
- color: #000;
92
- outline: none;
93
- }
94
-
95
- .input-bar button {
96
- padding: 0.5rem 1rem;
97
- border: none;
98
- border-radius: var(--radius);
99
- background: rgba(255, 255, 255, 0.6);
100
- color: #000;
101
- font-weight: bold;
102
- cursor: pointer;
103
- transition: transform 0.2s cubic-bezier(0.22, 1, 0.36, 1);
104
- }
105
-
106
- .username-form {
107
- display: flex;
108
- flex-direction: column;
109
- gap: 0.5rem;
110
- flex: 1;
111
- justify-content: center;
112
- align-items: center;
113
- }
114
-
115
- .username-form input {
116
- padding: 0.75rem 1rem;
117
- border: 1px solid var(--glass-border);
118
- background: var(--glass-bg);
119
- border-radius: var(--radius);
120
- backdrop-filter: blur(var(--blur));
121
- -webkit-backdrop-filter: blur(var(--blur));
122
- width: 100%;
123
- max-width: 200px;
124
- text-align: center;
125
- outline: none;
126
- }
127
-
128
- .username-form button {
129
- padding: 0.5rem 1.5rem;
130
- border: none;
131
- border-radius: var(--radius);
132
- background: rgba(255, 255, 255, 0.7);
133
- font-weight: bold;
134
- cursor: pointer;
135
- transition: transform 0.2s cubic-bezier(0.22, 1, 0.36, 1);
136
- }
137
-
138
- .username-form button:hover {
139
- transform: scale(1.05);
140
- }
141
-
142
- .username-form button:active {
143
- transform: scale(0.95);
144
- }
145
-
146
- .input-bar button:hover {
147
- transform: scale(1.05);
148
- }
149
-
150
- .input-bar button:active {
151
- transform: scale(0.95);
152
- }
153
-
154
- @keyframes jelly {
155
- 0% {
156
- transform: scale(0.9);
157
- }
158
- 40% {
159
- transform: scale(1.05);
160
- }
161
- 60% {
162
- transform: scale(0.97);
163
- }
164
- 100% {
165
- transform: scale(1);
166
- }
167
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
frontend/vite.config.js DELETED
@@ -1,7 +0,0 @@
1
- import { defineConfig } from 'vite'
2
- import react from '@vitejs/plugin-react'
3
-
4
- // https://vite.dev/config/
5
- export default defineConfig({
6
- plugins: [react()],
7
- })