# All files / src/components Footer.tsx

0% Statements 0/73
0% Branches 0/1
0% Functions 0/1
0% Lines 0/73

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>
      );
    }