Skip to content

Commit 9060bf4

Browse files
committed
fix: hero layout, dynamic api connection and settings panel
1 parent 0decea5 commit 9060bf4

4 files changed

Lines changed: 103 additions & 9 deletions

File tree

‎frontend/src/api.ts‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
import axios from 'axios'
22

3-
const api = axios.create({ baseURL: '/' })
3+
const savedUrl = localStorage.getItem('qm_api_url') || '/'
4+
const api = axios.create({ baseURL: savedUrl })
5+
6+
export function setApiUrl(url: string) {
7+
localStorage.setItem('qm_api_url', url)
8+
api.defaults.baseURL = url
9+
}
10+
11+
export function getApiUrl(): string {
12+
return localStorage.getItem('qm_api_url') || ''
13+
}
414

515
export interface QueryResponse {
616
sql: string

‎frontend/src/components/ChatWindow.tsx‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,12 @@ export default function ChatWindow({ messages, setMessages, onAnswer, injectedQu
4646
try {
4747
const response = await postQuery(q)
4848
onAnswer(response)
49-
} catch (err: unknown) {
50-
const errMsg = err instanceof Error ? err.message : String(err)
49+
} catch (err: any) {
50+
let errMsg = err instanceof Error ? err.message : String(err)
51+
if (errMsg.includes('405') || errMsg.includes('404') || errMsg.includes('Network Error')) {
52+
errMsg = "Failed to connect to the backend. If you are on GitHub Pages, click the ⚙️ Settings icon in the top right to configure your local Backend API URL (e.g., http://localhost:8000)."
53+
}
54+
5155
setMessages((prev) => [
5256
...prev,
5357
{ id: crypto.randomUUID(), type: 'error', content: errMsg, timestamp: new Date() },

‎frontend/src/components/HeroSection.tsx‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,12 @@ export default function HeroSection() {
5252
<section id="hero" style={{
5353
minHeight: '100vh',
5454
display: 'flex',
55-
alignItems: 'center',
55+
flexDirection: 'column',
56+
justifyContent: 'center',
5657
position: 'relative',
5758
overflow: 'hidden',
58-
paddingTop: 'var(--nav-height)',
59+
paddingTop: 'calc(var(--nav-height) + 40px)',
60+
paddingBottom: '40px',
5961
}}>
6062
{/* Background gradient orbs */}
6163
<div style={{
@@ -270,10 +272,9 @@ export default function HeroSection() {
270272

271273
{/* Stats bar */}
272274
<div style={{
273-
position: 'absolute',
274-
bottom: 0,
275-
left: 0,
276-
right: 0,
275+
position: 'relative',
276+
width: '100%',
277+
marginTop: '40px',
277278
}}>
278279
<div className="qm-container">
279280
<div className="qm-stats" style={{

‎frontend/src/components/Navbar.tsx‎

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
import { useState, useEffect } from 'react'
2+
import { getApiUrl, setApiUrl } from '../api'
23

34
export default function Navbar() {
45
const [scrolled, setScrolled] = useState(false)
6+
const [showSettings, setShowSettings] = useState(false)
7+
const [apiUrlInput, setApiUrlInput] = useState(getApiUrl() || 'http://localhost:8000')
8+
9+
const saveSettings = () => {
10+
setApiUrl(apiUrlInput)
11+
setShowSettings(false)
12+
}
513

614
useEffect(() => {
715
const onScroll = () => setScrolled(window.scrollY > 40)
@@ -90,6 +98,20 @@ export default function Navbar() {
9098
</a>
9199
))}
92100

101+
<button
102+
onClick={() => setShowSettings(true)}
103+
className="qm-btn-secondary"
104+
style={{
105+
padding: '8px',
106+
fontSize: '16px',
107+
background: 'transparent',
108+
border: 'none',
109+
}}
110+
title="Settings"
111+
>
112+
⚙️
113+
</button>
114+
93115
<a
94116
href="https://github.com/ridash2005/SQL-Query-Generator"
95117
target="_blank"
@@ -107,6 +129,63 @@ export default function Navbar() {
107129
GitHub
108130
</a>
109131
</div>
132+
133+
{showSettings && (
134+
<div style={{
135+
position: 'fixed',
136+
inset: 0,
137+
background: 'rgba(0,0,0,0.8)',
138+
display: 'flex',
139+
alignItems: 'center',
140+
justifyContent: 'center',
141+
zIndex: 1000,
142+
}}>
143+
<div className="qm-glass-card" style={{ width: '400px', padding: '30px' }}>
144+
<h3 style={{ marginBottom: '10px' }}>Backend Connection</h3>
145+
<p style={{ fontSize: '13px', color: 'var(--text-secondary)', marginBottom: '20px', lineHeight: 1.5 }}>
146+
GitHub Pages is a static host. To use the chat playground, you must run the FastAPI backend locally with your OpenAI API Key and data, then connect the frontend to it.
147+
</p>
148+
<div style={{ marginBottom: '20px' }}>
149+
<label style={{ display: 'block', fontSize: '12px', marginBottom: '8px', color: 'var(--text-tertiary)' }}>
150+
API Base URL
151+
</label>
152+
<input
153+
type="text"
154+
value={apiUrlInput}
155+
onChange={(e) => setApiUrlInput(e.target.value)}
156+
placeholder="http://localhost:8000"
157+
style={{
158+
width: '100%',
159+
background: 'var(--bg-tertiary)',
160+
border: '1px solid var(--border-color)',
161+
color: 'var(--text-primary)',
162+
padding: '10px 14px',
163+
borderRadius: '6px',
164+
fontFamily: 'var(--font-mono)',
165+
fontSize: '13px',
166+
boxSizing: 'border-box'
167+
}}
168+
/>
169+
</div>
170+
<div style={{ display: 'flex', gap: '10px', justifyContent: 'flex-end' }}>
171+
<button
172+
onClick={() => setShowSettings(false)}
173+
className="qm-btn-secondary"
174+
style={{ padding: '8px 16px' }}
175+
>
176+
Cancel
177+
</button>
178+
<button
179+
onClick={saveSettings}
180+
className="qm-btn-primary"
181+
style={{ padding: '8px 16px' }}
182+
>
183+
Save Settings
184+
</button>
185+
</div>
186+
</div>
187+
</div>
188+
)}
110189
</nav>
111190
)
112191
}

0 commit comments

Comments
 (0)