Add IUCN Red List API v4 support and token validation. Updates API status display to include v4 token status and version information.
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/e2f8696a-1efd-4683-88a6-bfae91274fad.jpg
This commit is contained in:
@ -6,12 +6,12 @@ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/comp
|
|||||||
|
|
||||||
interface ApiStatusProps {
|
interface ApiStatusProps {
|
||||||
citesToken: string | null;
|
citesToken: string | null;
|
||||||
|
iucnToken?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ApiStatus({ citesToken }: ApiStatusProps) {
|
export default function ApiStatus({ citesToken, iucnToken }: ApiStatusProps) {
|
||||||
const [iucnStatus, setIucnStatus] = useState<'checking' | 'connected' | 'error'>('checking');
|
const [iucnStatus, setIucnStatus] = useState<'checking' | 'connected' | 'error'>('checking');
|
||||||
const [citesStatus, setCitesStatus] = useState<'checking' | 'connected' | 'error'>('checking');
|
const [citesStatus, setCitesStatus] = useState<'checking' | 'connected' | 'error'>('checking');
|
||||||
const [iucnApiVersion, setIucnApiVersion] = useState<string | null>(null);
|
|
||||||
|
|
||||||
// Check CITES API status
|
// Check CITES API status
|
||||||
const {
|
const {
|
||||||
@ -54,10 +54,8 @@ export default function ApiStatus({ citesToken }: ApiStatusProps) {
|
|||||||
setIucnStatus('checking');
|
setIucnStatus('checking');
|
||||||
} else if (iucnApiData?.connected) {
|
} else if (iucnApiData?.connected) {
|
||||||
setIucnStatus('connected');
|
setIucnStatus('connected');
|
||||||
setIucnApiVersion((iucnApiData as any)?.apiVersion || 'v3'); // Use v3 as default if not specified
|
|
||||||
} else {
|
} else {
|
||||||
setIucnStatus('error');
|
setIucnStatus('error');
|
||||||
setIucnApiVersion(null);
|
|
||||||
}
|
}
|
||||||
}, [isIucnLoading, iucnApiData]);
|
}, [isIucnLoading, iucnApiData]);
|
||||||
|
|
||||||
@ -77,7 +75,9 @@ export default function ApiStatus({ citesToken }: ApiStatusProps) {
|
|||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent side="bottom" className="max-w-md">
|
<TooltipContent side="bottom" className="max-w-md">
|
||||||
{citesStatus === 'connected'
|
{citesStatus === 'connected'
|
||||||
? 'CITES+ API is connected and working'
|
? citesToken
|
||||||
|
? `CITES+ API is connected and working (Token: ${citesToken.substring(0, 6)}...)`
|
||||||
|
: 'CITES+ API is connected and working'
|
||||||
: citesStatus === 'checking'
|
: citesStatus === 'checking'
|
||||||
? 'Checking CITES+ API connection...'
|
? 'Checking CITES+ API connection...'
|
||||||
: citesApiData?.message || 'CITES+ API is not connected. Click "API Token" and add your CITES+ API token.'}
|
: citesApiData?.message || 'CITES+ API is not connected. Click "API Token" and add your CITES+ API token.'}
|
||||||
@ -93,20 +93,22 @@ export default function ApiStatus({ citesToken }: ApiStatusProps) {
|
|||||||
variant={iucnStatus === 'connected' ? 'default' : 'destructive'}
|
variant={iucnStatus === 'connected' ? 'default' : 'destructive'}
|
||||||
className="text-xs px-2 py-0.5"
|
className="text-xs px-2 py-0.5"
|
||||||
>
|
>
|
||||||
IUCN API: {iucnStatus === 'checking'
|
IUCN API v4: {iucnStatus === 'checking'
|
||||||
? 'Checking...'
|
? 'Checking...'
|
||||||
: iucnStatus === 'connected'
|
: iucnStatus === 'connected'
|
||||||
? `Connected (${iucnApiVersion})`
|
? 'Connected'
|
||||||
: 'Not Connected'}
|
: 'Not Connected'}
|
||||||
</Badge>
|
</Badge>
|
||||||
</div>
|
</div>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent side="bottom" className="max-w-md">
|
<TooltipContent side="bottom" className="max-w-md">
|
||||||
{iucnStatus === 'connected'
|
{iucnStatus === 'connected'
|
||||||
? `IUCN Red List API ${iucnApiVersion} is connected and working`
|
? iucnToken
|
||||||
|
? `IUCN Red List API v4 is connected and working (Token: ${iucnToken.substring(0, 6)}...)`
|
||||||
|
: 'IUCN Red List API v4 is connected and working'
|
||||||
: iucnStatus === 'checking'
|
: iucnStatus === 'checking'
|
||||||
? 'Checking IUCN Red List API connection...'
|
? 'Checking IUCN Red List API v4 connection...'
|
||||||
: iucnApiData?.message || 'IUCN Red List API connection issue. To use IUCN API features, click "API Token" and add your API key on the IUCN tab.'}
|
: iucnApiData?.message || 'IUCN Red List API v4 connection issue. To use IUCN API features, click "API Token" and add your API token.'}
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
|
@ -8,9 +8,6 @@ import { fromZodError } from "zod-validation-error";
|
|||||||
|
|
||||||
const CITES_BASE_URL = "https://api.speciesplus.net/api/v1";
|
const CITES_BASE_URL = "https://api.speciesplus.net/api/v1";
|
||||||
|
|
||||||
// IUCN API V4 only
|
|
||||||
const IUCN_API_BASE_URL = "https://apiv4.iucnredlist.org/api/v4";
|
|
||||||
|
|
||||||
export async function registerRoutes(app: Express): Promise<Server> {
|
export async function registerRoutes(app: Express): Promise<Server> {
|
||||||
// API Token routes
|
// API Token routes
|
||||||
app.post("/api/token", async (req: Request, res: Response) => {
|
app.post("/api/token", async (req: Request, res: Response) => {
|
||||||
@ -35,17 +32,17 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// If IUCN token is provided, try to validate it but don't fail if invalid
|
// If IUCN token is provided, try to validate it
|
||||||
if (tokenData.iucnToken) {
|
if (tokenData.iucnToken) {
|
||||||
try {
|
try {
|
||||||
await axios.get(`${IUCN_V4_BASE_URL}/version`, {
|
await axios.get("https://apiv4.iucnredlist.org/api/v4/version", {
|
||||||
headers: {
|
headers: {
|
||||||
"Authorization": `Bearer ${tokenData.iucnToken}`
|
"Authorization": `Bearer ${tokenData.iucnToken}`
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
iucnValid = true;
|
iucnValid = true;
|
||||||
} catch (iucnError) {
|
} catch (iucnError) {
|
||||||
warnings.push("The IUCN v4 token could not be validated. The system will fall back to IUCN v3 API.");
|
warnings.push("The IUCN v4 token could not be validated. Please check your token and try again.");
|
||||||
// Don't store the invalid token
|
// Don't store the invalid token
|
||||||
tokenData.iucnToken = null;
|
tokenData.iucnToken = null;
|
||||||
}
|
}
|
||||||
@ -60,7 +57,7 @@ export async function registerRoutes(app: Express): Promise<Server> {
|
|||||||
success: true,
|
success: true,
|
||||||
token: savedToken,
|
token: savedToken,
|
||||||
warnings,
|
warnings,
|
||||||
message: "CITES API token validated and saved. The IUCN token validation failed - the system will use IUCN v3 API instead."
|
message: "CITES API token validated and saved. The IUCN v4 token validation failed."
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user