feat: Footer - live health-check polling Brain API every 60s with status indicator

#25
Files changed (1) hide show
  1. landing/src/components/Footer.tsx +51 -13
landing/src/components/Footer.tsx CHANGED
@@ -1,6 +1,40 @@
 
1
  import './Footer.css'
2
 
 
 
3
  export default function Footer() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  return (
5
  <footer className="footer">
6
  <div className="container footer__inner">
@@ -20,8 +54,8 @@ export default function Footer() {
20
  </div>
21
  <p>Fair routes. Happy drivers. Explainable by default.</p>
22
  <div className="footer__status">
23
- <span className="footer__status-dot" />
24
- All systems operational
25
  </div>
26
  </div>
27
 
@@ -30,32 +64,36 @@ export default function Footer() {
30
  <div className="footer__col-title">Product</div>
31
  <a href="#features">Features</a>
32
  <a href="#pricing">Pricing</a>
33
- <a href="#api">API Reference</a>
34
  <a href="#demo">Live Demo</a>
35
  </div>
36
  <div className="footer__col">
37
  <div className="footer__col-title">Developers</div>
38
- <a href="#">Getting Started</a>
39
- <a href="#">Endpoints</a>
40
- <a href="#">SDKs</a>
41
- <a href="#">Changelog</a>
42
  </div>
43
  <div className="footer__col">
44
  <div className="footer__col-title">Company</div>
45
- <a href="#">About</a>
46
- <a href="#">Blog</a>
47
- <a href="#">Privacy</a>
48
- <a href="#">Terms</a>
49
  </div>
50
  </div>
51
  </div>
52
 
53
  <div className="footer__bottom">
54
  <div className="container">
55
- <span>© 2026 FairRelay. Built for fair logistics.</span>
56
- <span>Made with 💜 for drivers everywhere</span>
57
  </div>
58
  </div>
 
 
 
 
59
  </footer>
60
  )
61
  }
 
1
+ import { useState, useEffect } from 'react'
2
  import './Footer.css'
3
 
4
+ const API_URL = import.meta.env.VITE_API_URL || 'https://fairrelay-backend.onrender.com'
5
+
6
  export default function Footer() {
7
+ const [status, setStatus] = useState<'checking' | 'operational' | 'degraded' | 'down'>('checking')
8
+
9
+ useEffect(() => {
10
+ const checkHealth = async () => {
11
+ try {
12
+ const res = await fetch(`${API_URL}/health`, { signal: AbortSignal.timeout(5000) })
13
+ if (res.ok) {
14
+ const data = await res.json()
15
+ setStatus(data.status === 'healthy' ? 'operational' : 'degraded')
16
+ } else {
17
+ setStatus('degraded')
18
+ }
19
+ } catch {
20
+ setStatus('down')
21
+ }
22
+ }
23
+
24
+ checkHealth()
25
+ const interval = setInterval(checkHealth, 60000) // Poll every 60s
26
+ return () => clearInterval(interval)
27
+ }, [])
28
+
29
+ const statusConfig = {
30
+ checking: { color: '#3b82f6', text: 'Checking status…', pulse: true },
31
+ operational: { color: '#10b981', text: 'All systems operational', pulse: false },
32
+ degraded: { color: '#f59e0b', text: 'Degraded performance', pulse: true },
33
+ down: { color: '#ef4444', text: 'Service warming up', pulse: true },
34
+ }
35
+
36
+ const s = statusConfig[status]
37
+
38
  return (
39
  <footer className="footer">
40
  <div className="container footer__inner">
 
54
  </div>
55
  <p>Fair routes. Happy drivers. Explainable by default.</p>
56
  <div className="footer__status">
57
+ <span className="footer__status-dot" style={{ background: s.color, boxShadow: s.pulse ? `0 0 8px ${s.color}` : 'none', animation: s.pulse ? 'pulse 2s infinite' : 'none' }} />
58
+ {s.text}
59
  </div>
60
  </div>
61
 
 
64
  <div className="footer__col-title">Product</div>
65
  <a href="#features">Features</a>
66
  <a href="#pricing">Pricing</a>
67
+ <a href={`${API_URL}/docs`} target="_blank" rel="noopener">API Reference</a>
68
  <a href="#demo">Live Demo</a>
69
  </div>
70
  <div className="footer__col">
71
  <div className="footer__col-title">Developers</div>
72
+ <a href={`${API_URL}/docs`} target="_blank" rel="noopener">Getting Started</a>
73
+ <a href={`${API_URL}/redoc`} target="_blank" rel="noopener">Endpoint Reference ↗</a>
74
+ <a href="https://github.com/MUTHUKUMARAN-K-1/FairRelay" target="_blank" rel="noopener">GitHub ↗</a>
75
+ <a href={`${API_URL}/health`} target="_blank" rel="noopener">Status Page ↗</a>
76
  </div>
77
  <div className="footer__col">
78
  <div className="footer__col-title">Company</div>
79
+ <a href="https://logisticsnow.in" target="_blank" rel="noopener">LogisticsNow ↗</a>
80
+ <a href="https://company.lorri.in" target="_blank" rel="noopener">LoRRI Platform ↗</a>
81
+ <a href="mailto:muthukumaran@logisticsnow.in">Contact</a>
82
+ <a href="#">Privacy Policy</a>
83
  </div>
84
  </div>
85
  </div>
86
 
87
  <div className="footer__bottom">
88
  <div className="container">
89
+ <span>© 2026 FairRelay by LogisticsNow Pvt. Ltd. Built for fair logistics.</span>
90
+ <span>Integrated with <a href="https://logisticsnow.in" target="_blank" rel="noopener" style={{ color: '#f97316' }}>LoRRI</a> · Made with 💜 for 15M+ drivers</span>
91
  </div>
92
  </div>
93
+
94
+ <style>{`
95
+ @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
96
+ `}</style>
97
  </footer>
98
  )
99
  }