diff --git a/.gitignore b/.gitignore
index 37f0f70..88c6cac 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-summerizer.py
\ No newline at end of file
+summerizer.py
+node_modules
diff --git a/src/components/Modals/ApiKeyCreationModal.js b/src/components/Modals/ApiKeyCreationModal.js
new file mode 100644
index 0000000..b901452
--- /dev/null
+++ b/src/components/Modals/ApiKeyCreationModal.js
@@ -0,0 +1,164 @@
+import React, { useState } from 'react';
+import { useCreateApiKey } from '../../utils/queries/apikey-queries';
+
+const AVAILABLE_ROLES = ['guest', 'creator', 'admin'];
+
+const ApiKeyCreationModal = ({ isOpen, onClose }) => {
+ const [name, setName] = useState('');
+ const [roles, setRoles] = useState(['guest']);
+ const [generatedKey, setGeneratedKey] = useState(null);
+ const createApiKeyMutation = useCreateApiKey();
+
+ const handleAddRole = () => {
+ const availableRoles = AVAILABLE_ROLES.filter(role => !roles.includes(role));
+ if (availableRoles.length > 0) {
+ setRoles([...roles, availableRoles[0]]);
+ }
+ };
+
+ const handleRoleChange = (index, value) => {
+ if (roles.includes(value) && roles.findIndex(r => r === value) !== index) {
+ return;
+ }
+ const newRoles = [...roles];
+ newRoles[index] = value;
+ setRoles(newRoles);
+ };
+
+ const handleRemoveRole = (index) => {
+ const newRoles = roles.filter((_, i) => i !== index);
+ setRoles(newRoles);
+ };
+
+ const handleGenerate = async () => {
+ if (!name.trim()) {
+ alert('API key name is required');
+ return;
+ }
+ try {
+ const result = await createApiKeyMutation.mutateAsync({
+ name: name.trim(),
+ roles: roles
+ });
+ setGeneratedKey(result);
+ } catch (error) {
+ console.error('failed to create api key', error);
+ alert('failed to create api key');
+ }
+ };
+
+ const handleCopy = () => {
+ navigator.clipboard.writeText(generatedKey)
+ .then(() => alert('API key copied to clipboard'))
+ .catch(err => console.error('failed to copy api key:', err));
+ };
+
+ const getRemainingRoles = (currentIndex) => {
+ return AVAILABLE_ROLES.filter(role =>
+ !roles.find((r, i) => r === role && i !== currentIndex)
+ );
+ };
+
+ if (!isOpen) return null;
+
+ return (
+
+
+
+
+
+ {!generatedKey ? (
+
+
+
+
+ setName(e.target.value)}
+ />
+
+
+
+
+ {roles.map((role, index) => (
+
+
+
+
+
+
+
+
+
+
+ ))}
+
+
+
+ ) : (
+
+
+ Please copy your API key immediately! It will only be displayed once!
+
+
+
+
+ )}
+
+
+
+
+ );
+};
+
+export default ApiKeyCreationModal;
\ No newline at end of file
diff --git a/src/components/Modals/ApiKeyRevokeModal.js b/src/components/Modals/ApiKeyRevokeModal.js
new file mode 100644
index 0000000..32f7d89
--- /dev/null
+++ b/src/components/Modals/ApiKeyRevokeModal.js
@@ -0,0 +1,63 @@
+import React, { useState } from 'react';
+import { useRevokeApiKey } from '../../utils/queries/apikey-queries';
+
+const ApiKeyRevokeModal = ({ isOpen, onClose }) => {
+ const [apiKey, setApiKey] = useState('');
+ const revokeApiKeyMutation = useRevokeApiKey();
+
+ const handleRevoke = async () => {
+ if (!apiKey.trim()) {
+ alert('Please enter an API key');
+ return;
+ }
+
+ try {
+ await revokeApiKeyMutation.mutateAsync(apiKey);
+ alert('API key revoked successfully');
+ onClose();
+ } catch (error) {
+ console.error('Failed to revoke API key:', error);
+ alert('Failed to revoke API key');
+ }
+ };
+
+ if (!isOpen) return null;
+
+ return (
+
+
+
+
+
+
+
+
+ setApiKey(e.target.value)}
+ />
+
+
+
+
+
+
+ );
+};
+
+export default ApiKeyRevokeModal;
\ No newline at end of file
diff --git a/src/components/Navigations/MainNavigation.js b/src/components/Navigations/MainNavigation.js
index b8ff456..9922cb6 100644
--- a/src/components/Navigations/MainNavigation.js
+++ b/src/components/Navigations/MainNavigation.js
@@ -4,11 +4,16 @@ import { AuthContext } from "../../AuthProvider";
import "bulma/css/bulma.min.css";
import {useConfig} from "../../ConfigProvider";
import "./MainNavigation.css";
+import ApiKeyCreationModal from "../Modals/ApiKeyCreationModal";
+import ApiKeyRevokeModal from "../Modals/ApiKeyRevokeModal";
const MainNavigation = () => {
const { user, login, logout } = useContext(AuthContext);
const config = useConfig();
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
+ const [isApiKeyModalOpen, setIsApiKeyModalOpen] = useState(false);
+ const [isRevokeModalOpen, setIsRevokeModalOpen] = useState(false);
+
if (config===undefined) {
return Loading ...
;
}
@@ -88,102 +93,124 @@ const MainNavigation = () => {
};
return (
-