"use client";
import { useState, useEffect } from "react";
import Link from "next/link";
import Button from "@/components/shared/Button";
export default function APIKeysPage() {
const [apiKeys, setApiKeys] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
const [deletingKeys, setDeletingKeys] = useState(new Set());
useEffect(() => {
fetchAPIKeys();
}, []);
async function fetchAPIKeys() {
try {
const response = await fetch(
"http://localhost:8080/twirp/apikeys.APIKeysService/ListAPIKeys",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
token: localStorage.getItem("token"),
}),
},
);
if (!response.ok) throw new Error("Failed to fetch API keys");
const data = await response.json();
setApiKeys(data.api_keys || []);
} catch (error) {
setError("Failed to load API keys");
console.error("Error:", error);
} finally {
setIsLoading(false);
}
}
if (isLoading) {
return (
);
}
if (error) {
return (
);
}
async function handleDeleteKey(keyId) {
if (
!confirm(
"Are you sure you want to delete this API key? This action cannot be undone.",
)
) {
return;
}
setDeletingKeys((prev) => new Set([...prev, keyId]));
try {
const response = await fetch(
`http://localhost:8080/twirp/apikeys.APIKeysService/DeleteAPIKey`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
token: localStorage.getItem("token"),
key_id: keyId,
}),
},
);
if (!response.ok) throw new Error("Failed to delete API key: ", response);
await fetchAPIKeys(); // Refresh the list
} catch (error) {
setError("Failed to delete API key");
console.error("Error:", error);
} finally {
setDeletingKeys((prev) => {
const newSet = new Set(prev);
newSet.delete(keyId);
return newSet;
});
}
}
if (!apiKeys.length) {
return (
No API keys
Create an API key to get started with programmatic access.
);
}
return (
<>
{apiKeys &&
apiKeys.map((key) => (
handleDeleteKey(key.id)}
isDeleting={deletingKeys.has(key.id)}
/>
))}
>
);
}
function APIKeyItem({ apiKey, onDelete, isDeleting }) {
return (
{apiKey.name}
Created on {new Date(apiKey.created_at).toLocaleDateString()}
{apiKey.last_used_at && (
Last used on {new Date(apiKey.last_used_at).toLocaleDateString()}
)}
);
}