Skip to content

Commit bfb442a

Browse files
committed
fix: online status check
1 parent d632fac commit bfb442a

File tree

3 files changed

+111
-6
lines changed

3 files changed

+111
-6
lines changed

chat-ui/src/components/ChatInterface.css

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,4 +739,49 @@
739739
.input-area {
740740
padding: 0.8rem;
741741
}
742+
}
743+
744+
.status-online {
745+
background-color: #4caf50; /* Green for online */
746+
animation: none; /* No animation for stable connection */
747+
}
748+
749+
.status-offline {
750+
background-color: #f44336; /* Red for offline */
751+
animation: none; /* No animation for stable disconnection */
752+
}
753+
754+
.status-checking {
755+
background-color: #ffc107; /* Yellow/amber for checking */
756+
animation: pulse 1.5s infinite; /* Pulsing animation while checking */
757+
}
758+
759+
/* Add to your existing keyframes or add if missing */
760+
@keyframes pulse {
761+
0% { opacity: 0.3; }
762+
50% { opacity: 1; }
763+
100% { opacity: 0.3; }
764+
}
765+
766+
/* Disabled input area styling */
767+
.input-field:disabled {
768+
background-color: var(--gray-100);
769+
cursor: not-allowed;
770+
opacity: 0.8;
771+
}
772+
773+
/* Connection status message */
774+
.status-message {
775+
font-size: 0.75rem;
776+
font-style: italic;
777+
padding: 0.5rem;
778+
text-align: center;
779+
background-color: var(--gray-100);
780+
border-radius: 4px;
781+
margin: 0.5rem 1.5rem;
782+
}
783+
784+
.status-message.offline {
785+
background-color: rgba(244, 67, 54, 0.1);
786+
color: #f44336;
742787
}

chat-ui/src/components/ChatInterface.js

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const ChatInterface = () => {
2323
const [awaitingConfirmation, setAwaitingConfirmation] = useState(false);
2424
const [pendingTransaction, setPendingTransaction] = useState(null);
2525
const [showInfo, setShowInfo] = useState(false);
26+
const [backendStatus, setBackendStatus] = useState('checking'); // 'online', 'offline', or 'checking'
2627
const messagesEndRef = useRef(null);
2728
const inputRef = useRef(null);
2829

@@ -39,6 +40,44 @@ const ChatInterface = () => {
3940
inputRef.current?.focus();
4041
}, []);
4142

43+
// Check backend connection status periodically
44+
useEffect(() => {
45+
const checkBackendStatus = async () => {
46+
try {
47+
const controller = new AbortController();
48+
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5 second timeout
49+
50+
// Use the ping endpoint to check if the backend is available
51+
const response = await fetch(`${BACKEND_ROUTE}ping`, {
52+
method: 'GET',
53+
signal: controller.signal
54+
});
55+
56+
clearTimeout(timeoutId);
57+
58+
if (response.ok) {
59+
setBackendStatus('online');
60+
console.log('Backend connection: Online');
61+
} else {
62+
setBackendStatus('offline');
63+
console.log('Backend connection: Offline (Response not OK)');
64+
}
65+
} catch (error) {
66+
console.error('Backend connection error:', error);
67+
setBackendStatus('offline');
68+
}
69+
};
70+
71+
// Initial check
72+
checkBackendStatus();
73+
74+
// Set up periodic checking (every 30 seconds)
75+
const intervalId = setInterval(checkBackendStatus, 30000);
76+
77+
// Cleanup
78+
return () => clearInterval(intervalId);
79+
}, []);
80+
4281
const handleSendMessage = async (text) => {
4382
try {
4483
const response = await fetch(BACKEND_ROUTE, {
@@ -55,6 +94,9 @@ const ChatInterface = () => {
5594

5695
const data = await response.json();
5796

97+
// If message sent successfully, update backend status to online
98+
setBackendStatus('online');
99+
58100
// Check if response contains a transaction preview
59101
if (data.response.includes('Transaction Preview:')) {
60102
setAwaitingConfirmation(true);
@@ -66,7 +108,9 @@ const ChatInterface = () => {
66108
return data.response;
67109
} catch (error) {
68110
console.error('Error:', error);
69-
return 'Sorry, there was an error processing your request. Please try again.';
111+
// If error occurred, update backend status to offline
112+
setBackendStatus('offline');
113+
return 'Sorry, I\'m having trouble connecting to my backend. Please check your connection and try again.';
70114
}
71115
};
72116

@@ -311,8 +355,14 @@ const ChatInterface = () => {
311355
<div>
312356
<h2>Agent Pugo Hilion</h2>
313357
<div className="status-indicator">
314-
<span className="status-dot"></span>
315-
<span>Online</span>
358+
<span className={`status-dot ${
359+
backendStatus === 'online' ? 'status-online' :
360+
backendStatus === 'offline' ? 'status-offline' : 'status-checking'
361+
}`}></span>
362+
<span>{
363+
backendStatus === 'online' ? 'Online' :
364+
backendStatus === 'offline' ? 'Offline' : 'Connecting...'
365+
}</span>
316366
</div>
317367
</div>
318368
</div>
@@ -528,12 +578,12 @@ const ChatInterface = () => {
528578
: "Type your message... (Markdown supported)"}
529579
className="input-field"
530580
rows="1"
531-
disabled={isLoading}
581+
disabled={isLoading || backendStatus === 'offline'}
532582
/>
533583
<button
534584
type="submit"
535-
disabled={isLoading || !inputText.trim()}
536-
className={`send-button ${isLoading || !inputText.trim() ? 'disabled' : ''}`}
585+
disabled={isLoading || !inputText.trim() || backendStatus === 'offline'}
586+
className={`send-button ${isLoading || !inputText.trim() || backendStatus === 'offline' ? 'disabled' : ''}`}
537587
aria-label="Send message"
538588
>
539589
<Send size={18} />

src/flare_ai_social/api/routes/chat.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,16 @@ async def chat(message: ChatMessage) -> dict[str, str]: # pyright: ignore [repo
9090
self.logger.exception("message_handling_failed", error=str(e))
9191
raise HTTPException(status_code=500, detail=str(e)) from e
9292

93+
@self._router.get("/ping")
94+
async def ping() -> dict[str, str]: # pyright: ignore [reportUnusedFunction]
95+
"""
96+
Simple ping endpoint to check if the service is up.
97+
98+
Returns:
99+
dict[str, str]: Status message
100+
"""
101+
return {"status": "ok"}
102+
93103
@property
94104
def router(self) -> APIRouter:
95105
"""Get the FastAPI router with registered routes."""

0 commit comments

Comments
 (0)