Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | import React, { useEffect, useState } from 'react'; import api from '../services/api'; // Build-time: Vite bundles the version from the frontend package.json import { version as FRONTEND_VERSION } from '../../package.json'; export default function Footer() { const [apiRequestsRemaining, setApiRequestsRemaining] = useState<number | null>(null); const [backendVersion, setBackendVersion] = useState<string | null>(null); const isDevelopment = import.meta.env.DEV; useEffect(() => { const fetchHealthData = async () => { try { const response = await api.get('/admin/health'); const data = response.data?.data; if (data?.apiRequestsRemaining !== undefined) { setApiRequestsRemaining(data.apiRequestsRemaining); } if (data?.version) { setBackendVersion(data.version); } } catch (error) { console.error('Failed to fetch health data:', error); } }; // Fetch on mount always (for BE version), then poll in dev for API quota fetchHealthData(); if (isDevelopment) { const interval = setInterval(fetchHealthData, 30000); return () => clearInterval(interval); } }, [isDevelopment]); const currentYear = new Date().getFullYear(); return ( <footer className="fixed bottom-0 left-0 right-0 bg-gray-800 text-white py-2 px-4 text-xs z-40" style={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace' }}> <div className="max-w-7xl mx-auto"> {/* Main Footer Row */} <div className="flex items-center justify-between gap-4"> {/* Left: Copyright & Versions */} <div className="flex items-center gap-3"> <span>© {currentYear} BetTrack</span> <span className="text-gray-400">•</span> <span className="text-gray-400" title="Frontend Version">FE v{FRONTEND_VERSION}</span> <span className="text-gray-400">•</span> <span className="text-gray-400" title="Backend Version">BE v{backendVersion ?? '...'}</span> </div> {/* Center: API Requests (Dev Only) */} {isDevelopment && apiRequestsRemaining !== null && ( <div className="flex items-center gap-2"> <span className="text-gray-400">API Requests:</span> <span className={`font-bold ${apiRequestsRemaining < 50 ? 'text-red-400' : apiRequestsRemaining < 100 ? 'text-yellow-400' : 'text-green-400'}`}> {apiRequestsRemaining} </span> </div> )} {/* Right: Links & Info */} <div className="flex items-center gap-3"> <a href="https://www.ncpgambling.org/" target="_blank" rel="noopener noreferrer" className="text-gray-400 hover:text-white transition-colors underline" > Responsible Gaming </a> <span className="text-gray-400">•</span> <a href="https://github.com/wford26/BetTrack" target="_blank" rel="noopener noreferrer" className="text-gray-400 hover:text-white transition-colors" > GitHub </a> </div> </div> {/* Bottom Row: Disclaimer (subtle) */} <div className="mt-1 pt-1 border-t border-gray-700"> <p className="text-center text-gray-500 text-[10px]"> BetTrack is a tracking tool only. We do not facilitate betting. Please gamble responsibly. If you or someone you know has a gambling problem, call 1-800-GAMBLER. </p> </div> </div> </footer> ); } |