pmtool / src /components /ApiConnectionAlert.tsx
devarshia5's picture
Upload 487 files
d97b8f9 verified
Raw
History Blame Contribute Delete
6.75 kB
import React, { useEffect, useState } from 'react';
import { AlertCircle, X, RefreshCw, WifiOff } from 'lucide-react';
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import { checkApiConnection } from '@/lib/api';
import { API_BASE_URL } from '@/config';
import apiClient from '@/lib/api/axios-instance';
const ApiConnectionAlert = () => {
const [isApiAvailable, setIsApiAvailable] = useState<boolean | null>(null);
const [checking, setChecking] = useState(false);
const [isVisible, setIsVisible] = useState(true);
const [retryCount, setRetryCount] = useState(0);
const [fadeOut, setFadeOut] = useState(false);
const checkConnection = async () => {
setChecking(true);
try {
console.log('Checking API connection...');
const isAvailable = await checkApiConnection();
console.log('API connection check result:', isAvailable);
setIsApiAvailable(isAvailable);
if (isAvailable) {
// If connection is restored after previous failures, show success briefly then hide
if (retryCount > 0) {
setTimeout(() => {
setFadeOut(true);
setTimeout(() => setIsVisible(false), 300);
}, 3000);
}
} else {
setRetryCount(prev => prev + 1);
}
} catch (error) {
console.error('Error checking API connection:', error);
setIsApiAvailable(false);
setRetryCount(prev => prev + 1);
} finally {
setChecking(false);
}
};
useEffect(() => {
checkConnection();
// Set up automatic retry every 30 seconds if API is down
const intervalId = setInterval(() => {
if (isApiAvailable === false) {
checkConnection();
}
}, 30000);
return () => clearInterval(intervalId);
}, [isApiAvailable]);
const closeAlert = () => {
setFadeOut(true);
setTimeout(() => setIsVisible(false), 300);
};
if (isApiAvailable === true && !isVisible) {
return null;
}
return (
<>
{(isApiAvailable === false || (isApiAvailable === true && retryCount > 0)) && isVisible && (
<div
className={`fixed bottom-4 right-4 z-50 max-w-md w-full transition-all duration-300 ${
fadeOut ? 'opacity-0 translate-y-5' : 'opacity-100 translate-y-0'
}`}
>
<Alert
variant={isApiAvailable === true ? "default" : "destructive"}
className={`
relative shadow-lg border-2
${isApiAvailable === true
? "bg-green-50 border-green-200 dark:bg-green-900/20 dark:border-green-800"
: "bg-red-50 border-red-200 dark:bg-red-900/20 dark:border-red-800"}
`}
>
<Button
variant="ghost"
size="icon"
className="absolute top-2 right-2 h-6 w-6 rounded-full p-0"
onClick={closeAlert}
>
<X className="h-4 w-4" />
</Button>
{isApiAvailable === true ? (
<div className="flex items-start">
<div className="rounded-full bg-green-100 dark:bg-green-800 p-2 mr-3">
<RefreshCw className="h-4 w-4 text-green-600 dark:text-green-200" />
</div>
<div>
<AlertTitle className="text-green-700 dark:text-green-300">
API Connection Restored
</AlertTitle>
<AlertDescription className="text-green-600 dark:text-green-400">
<p className="mb-2">
Successfully connected to the API server. You can continue using the application.
</p>
</AlertDescription>
</div>
</div>
) : (
<div className="flex items-start">
<div className="rounded-full bg-red-100 dark:bg-red-800 p-2 mr-3">
<WifiOff className="h-4 w-4 text-red-600 dark:text-red-200" />
</div>
<div>
<AlertTitle className="text-red-700 dark:text-red-300">
API Connection Error
</AlertTitle>
<AlertDescription className="text-red-600 dark:text-red-400">
<p className="mb-3">
Cannot connect to the API server at <code className="px-1 py-0.5 bg-red-100 dark:bg-red-900/30 rounded">{API_BASE_URL}</code>.
Some features may not work correctly.
</p>
<div className="mb-3 space-y-1 pl-5">
<p className="font-medium text-sm">Troubleshooting steps:</p>
<ul className="list-disc pl-4 text-sm space-y-1">
<li>Ensure the API server is running</li>
<li>Check your network connection</li>
<li>Verify that ports are not blocked by a firewall</li>
<li>If you're a developer, check for CORS issues</li>
</ul>
</div>
<div className="flex justify-end gap-2 mt-2">
<Button
variant="outline"
size="sm"
onClick={closeAlert}
className="border-red-200 hover:bg-red-100 hover:text-red-800"
>
Dismiss
</Button>
<Button
size="sm"
onClick={checkConnection}
disabled={checking}
className="bg-red-600 hover:bg-red-700 text-white"
>
{checking ? (
<>
<RefreshCw className="h-3 w-3 mr-1 animate-spin" />
Checking...
</>
) : (
<>
<RefreshCw className="h-3 w-3 mr-1" />
Retry Connection
</>
)}
</Button>
</div>
</AlertDescription>
</div>
</div>
)}
</Alert>
</div>
)}
</>
);
};
export default ApiConnectionAlert;