Brijesh's Git Server — argus-web @ c02beda1900bfabbff84bdf336bb6120523f3250

Web Ul for argus

src/app/dashboard/api-keys/page.js (view raw)

 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
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
"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);

  useEffect(() => {
    fetchAPIKeys();
  }, []);

  async function fetchAPIKeys() {
    try {
      const response = await fetch("http://localhost:8080/api-keys", {
        headers: {
          Authorization: `Bearer ${localStorage.getItem("token")}`,
        },
      });

      if (!response.ok) throw new Error("Failed to fetch API keys");

      const data = await response.json();
      setApiKeys(data);
    } catch (error) {
      setError("Failed to load API keys");
      console.error("Error:", error);
    } finally {
      setIsLoading(false);
    }
  }

  if (isLoading) {
    return (
      <div className="flex items-center justify-center h-64">
        <div className="text-gray-500">Loading API keys...</div>
      </div>
    );
  }

  if (error) {
    return (
      <div className="rounded-lg bg-white shadow p-6">
        <div className="text-red-600">{error}</div>
      </div>
    );
  }

  async function handleRevokeKey(keyId) {
    if (
      !confirm(
        "Are you sure you want to revoke this API key? This action cannot be undone.",
      )
    ) {
      return;
    }

    try {
      const response = await fetch(`http://localhost:8080/api-keys/${keyId}`, {
        method: "DELETE",
        headers: {
          Authorization: `Bearer ${localStorage.getItem("token")}`,
        },
      });

      if (!response.ok) throw new Error("Failed to revoke API key");

      await fetchAPIKeys(); // Refresh the list
    } catch (error) {
      setError("Failed to revoke API key");
      console.error("Error:", error);
    }
  }

  if (!apiKeys) {
    return (
      <div className="rounded-lg bg-white shadow">
        <div className="px-4 py-12 my-0">
          <div className="text-center">
            <h3 className="mt-2 text-lg font-semibold text-gray-900">
              No API keys
            </h3>
            <p className="mt-1 text-sm text-gray-500">
              Create an API key to get started with programmatic access.
            </p>
            <div className="mt-6">
              <Link href="/dashboard/api-keys/new">
                <Button variant="secondary">Create API Key</Button>
              </Link>
            </div>
          </div>
        </div>
      </div>
    );
  }

  return (
    <>
      <div className="bg-white shadow rounded-lg divide-y divide-gray-200">
        {apiKeys &&
          apiKeys.map((key) => (
            <APIKeyItem
              key={key.id}
              apiKey={key}
              onRevoke={() => handleRevokeKey(key.id)}
            />
          ))}
      </div>
    </>
  );
}

function APIKeyItem({ apiKey, onRevoke }) {
  return (
    <div className="px-6 py-4">
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-4">
          <h3 className="text-lg font-medium text-gray-900 capitalize w-48 truncate">
            {apiKey.name}
          </h3>
          <div className="mt-1 text-sm text-gray-500">
            Created on {new Date(apiKey.created_at).toLocaleDateString()}
          </div>
          {apiKey.last_used_at && (
            <div className="mt-1 text-sm text-gray-500">
              Last used on {new Date(apiKey.last_used_at).toLocaleDateString()}
            </div>
          )}
        </div>
        <button
          onClick={onRevoke}
          className="text-sm text-red-600 hover:text-red-900"
        >
          Revoke
        </button>
      </div>
    </div>
  );
}