Add API status indicators to display CITES and IUCN API connection status.
Replit-Commit-Author: Agent Replit-Commit-Session-Id: e931b5ab-041b-42e7-baf1-50017869cef6 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/e19c6a51-7e4c-4bb8-a6a6-46dc00f0ec99/ebd6a444-6df0-46b8-a6af-5e08a6ffae6a.jpg
This commit is contained in:
94
client/src/components/api-status.tsx
Normal file
94
client/src/components/api-status.tsx
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
import { apiClient } from "@/lib/api";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
|
||||||
|
|
||||||
|
interface ApiStatusProps {
|
||||||
|
citesToken: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ApiStatus({ citesToken }: ApiStatusProps) {
|
||||||
|
const [iucnStatus, setIucnStatus] = useState<'checking' | 'connected' | 'error'>('checking');
|
||||||
|
const [citesStatus, setCitesStatus] = useState<'checking' | 'connected' | 'error'>('checking');
|
||||||
|
|
||||||
|
// Check CITES API status based on token availability
|
||||||
|
useEffect(() => {
|
||||||
|
if (citesToken) {
|
||||||
|
setCitesStatus('connected');
|
||||||
|
} else {
|
||||||
|
setCitesStatus('error');
|
||||||
|
}
|
||||||
|
}, [citesToken]);
|
||||||
|
|
||||||
|
// Check IUCN API status by making a test request
|
||||||
|
const { isError, isSuccess, isLoading } = useQuery({
|
||||||
|
queryKey: ['api-status-check-iucn'],
|
||||||
|
queryFn: async () => {
|
||||||
|
try {
|
||||||
|
// Make a simple request to check if the IUCN API is responding
|
||||||
|
// Using a well-known species for testing
|
||||||
|
const response = await apiClient.getIucnSpeciesByName("Panthera leo");
|
||||||
|
return response;
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error("Failed to connect to IUCN API");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
retry: 1,
|
||||||
|
staleTime: 60000, // 1 minute
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isLoading) {
|
||||||
|
setIucnStatus('checking');
|
||||||
|
} else if (isError) {
|
||||||
|
setIucnStatus('error');
|
||||||
|
} else if (isSuccess) {
|
||||||
|
setIucnStatus('connected');
|
||||||
|
}
|
||||||
|
}, [isLoading, isError, isSuccess]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Badge
|
||||||
|
variant={citesStatus === 'connected' ? 'default' : 'destructive'}
|
||||||
|
className="text-xs px-2 py-0.5"
|
||||||
|
>
|
||||||
|
CITES API: {citesStatus === 'checking' ? 'Checking...' : citesStatus === 'connected' ? 'Connected' : 'Not Connected'}
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="bottom">
|
||||||
|
{citesStatus === 'connected'
|
||||||
|
? 'CITES+ API is connected and working'
|
||||||
|
: 'CITES+ API is not connected. Please add your API token.'}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
|
||||||
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<div className="flex items-center">
|
||||||
|
<Badge
|
||||||
|
variant={iucnStatus === 'connected' ? 'default' : 'destructive'}
|
||||||
|
className="text-xs px-2 py-0.5"
|
||||||
|
>
|
||||||
|
IUCN API: {iucnStatus === 'checking' ? 'Checking...' : iucnStatus === 'connected' ? 'Connected' : 'Not Connected'}
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="bottom">
|
||||||
|
{iucnStatus === 'connected'
|
||||||
|
? 'IUCN Red List API is connected and working'
|
||||||
|
: 'IUCN Red List API connection issue. Check the API key.'}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -7,6 +7,7 @@ import SearchForm from "@/components/search-form";
|
|||||||
import RecentSearches from "@/components/recent-searches";
|
import RecentSearches from "@/components/recent-searches";
|
||||||
import ResultsContainer from "@/components/results-container";
|
import ResultsContainer from "@/components/results-container";
|
||||||
import SavedSpecies from "@/components/saved-species";
|
import SavedSpecies from "@/components/saved-species";
|
||||||
|
import ApiStatus from "@/components/api-status";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
@ -85,6 +86,9 @@ export default function Home() {
|
|||||||
<path d="M12 2L5 6.5M12 2v6.5M12 2l7 4.5M5 6.5V18l3.5 2M5 6.5l7 4.5M22 9l-7.5 4.5M22 9V16M22 9l-3.5-2M5 18l7 4m0 0 7-4M19 18l-7-4.5m0 0L8.5 9"/>
|
<path d="M12 2L5 6.5M12 2v6.5M12 2l7 4.5M5 6.5V18l3.5 2M5 6.5l7 4.5M22 9l-7.5 4.5M22 9V16M22 9l-3.5-2M5 18l7 4m0 0 7-4M19 18l-7-4.5m0 0L8.5 9"/>
|
||||||
</svg>
|
</svg>
|
||||||
<h1 className="text-xl font-bold">CITES+ Species Lookup</h1>
|
<h1 className="text-xl font-bold">CITES+ Species Lookup</h1>
|
||||||
|
<div className="ml-6">
|
||||||
|
<ApiStatus citesToken={tokenData || null} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
@ -121,7 +125,7 @@ export default function Home() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<SearchForm
|
<SearchForm
|
||||||
token={tokenData}
|
token={tokenData || null}
|
||||||
onSpeciesFound={setSelectedSpecies}
|
onSpeciesFound={setSelectedSpecies}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user