2023-08-01 10:24:57 +03:00
|
|
|
/* eslint-disable max-lines */
|
2023-09-13 14:47:12 +03:00
|
|
|
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
2023-08-01 10:24:57 +03:00
|
|
|
import { useEffect, useState } from "react";
|
2023-08-30 12:20:28 +03:00
|
|
|
import { useTranslation } from "react-i18next";
|
2023-07-26 00:12:46 +03:00
|
|
|
|
2023-08-30 12:20:28 +03:00
|
|
|
import { validateOpenAIKey } from "@/app/brains-management/[brainId]/components/BrainManagementTabs/components/SettingsTab/utils/validateOpenAIKey";
|
2023-07-26 00:12:46 +03:00
|
|
|
import { useAuthApi } from "@/lib/api/auth/useAuthApi";
|
2023-09-13 14:47:12 +03:00
|
|
|
import { USER_IDENTITY_DATA_KEY } from "@/lib/api/user/config";
|
2023-08-01 10:24:57 +03:00
|
|
|
import { useUserApi } from "@/lib/api/user/useUserApi";
|
|
|
|
import { UserIdentity } from "@/lib/api/user/user";
|
|
|
|
import { useToast } from "@/lib/hooks";
|
2023-09-18 16:12:50 +03:00
|
|
|
import { useGAnalyticsEventTracker } from "@/services/analytics/google/useGAnalyticsEventTracker";
|
|
|
|
import { useEventTracking } from "@/services/analytics/june/useEventTracking";
|
2023-07-26 00:12:46 +03:00
|
|
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
|
|
export const useApiKeyConfig = () => {
|
|
|
|
const [apiKey, setApiKey] = useState("");
|
2023-08-01 10:24:57 +03:00
|
|
|
const [openAiApiKey, setOpenAiApiKey] = useState<string | null>();
|
|
|
|
const [
|
|
|
|
changeOpenAiApiKeyRequestPending,
|
|
|
|
setChangeOpenAiApiKeyRequestPending,
|
|
|
|
] = useState(false);
|
|
|
|
const { updateUserIdentity, getUserIdentity } = useUserApi();
|
2023-07-26 00:12:46 +03:00
|
|
|
const { track } = useEventTracking();
|
|
|
|
const { createApiKey } = useAuthApi();
|
2023-08-01 10:24:57 +03:00
|
|
|
const { publish } = useToast();
|
|
|
|
const [userIdentity, setUserIdentity] = useState<UserIdentity>();
|
2023-08-30 12:20:28 +03:00
|
|
|
const { t } = useTranslation(["config"]);
|
2023-09-13 14:47:12 +03:00
|
|
|
const queryClient = useQueryClient();
|
|
|
|
const { data: userData } = useQuery({
|
|
|
|
queryKey: [USER_IDENTITY_DATA_KEY],
|
|
|
|
queryFn: getUserIdentity,
|
|
|
|
});
|
2023-09-18 16:12:50 +03:00
|
|
|
const { eventTracker: gaEventTracker } = useGAnalyticsEventTracker({
|
|
|
|
category: "QUIVR_API_KEY",
|
|
|
|
});
|
2023-08-01 10:24:57 +03:00
|
|
|
|
|
|
|
useEffect(() => {
|
2023-09-13 14:47:12 +03:00
|
|
|
if (userData !== undefined) {
|
|
|
|
setUserIdentity(userData);
|
|
|
|
}
|
|
|
|
}, [userData]);
|
2023-07-26 00:12:46 +03:00
|
|
|
|
|
|
|
const handleCreateClick = async () => {
|
|
|
|
try {
|
|
|
|
void track("CREATE_API_KEY");
|
2023-09-18 16:12:50 +03:00
|
|
|
gaEventTracker?.({ action: "CREATE_API_KEY" });
|
2023-07-26 00:12:46 +03:00
|
|
|
const createdApiKey = await createApiKey();
|
|
|
|
setApiKey(createdApiKey);
|
|
|
|
} catch (error) {
|
|
|
|
console.error("Error creating API key: ", error);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const copyToClipboard = async (text: string) => {
|
|
|
|
try {
|
|
|
|
void track("COPY_API_KEY");
|
2023-09-18 16:12:50 +03:00
|
|
|
gaEventTracker?.({ action: "COPY_API_KEY" });
|
|
|
|
|
2023-07-26 00:12:46 +03:00
|
|
|
await navigator.clipboard.writeText(text);
|
|
|
|
} catch (err) {
|
|
|
|
console.error("Failed to copy:", err);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleCopyClick = () => {
|
|
|
|
if (apiKey !== "") {
|
|
|
|
void copyToClipboard(apiKey);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-08-01 10:24:57 +03:00
|
|
|
const changeOpenAiApiKey = async () => {
|
|
|
|
try {
|
|
|
|
setChangeOpenAiApiKeyRequestPending(true);
|
2023-08-30 12:20:28 +03:00
|
|
|
|
|
|
|
if (
|
|
|
|
openAiApiKey !== undefined &&
|
|
|
|
openAiApiKey !== null &&
|
|
|
|
!(await validateOpenAIKey(
|
|
|
|
openAiApiKey,
|
|
|
|
{
|
|
|
|
badApiKeyError: t("incorrectApiKey", { ns: "config" }),
|
|
|
|
invalidApiKeyError: t("invalidApiKeyError", { ns: "config" }),
|
|
|
|
},
|
|
|
|
publish
|
|
|
|
))
|
|
|
|
) {
|
|
|
|
setChangeOpenAiApiKeyRequestPending(false);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-08-01 10:24:57 +03:00
|
|
|
await updateUserIdentity({
|
|
|
|
openai_api_key: openAiApiKey,
|
|
|
|
});
|
2023-09-13 14:47:12 +03:00
|
|
|
void queryClient.invalidateQueries({
|
|
|
|
queryKey: [USER_IDENTITY_DATA_KEY],
|
|
|
|
});
|
|
|
|
|
2023-08-01 10:24:57 +03:00
|
|
|
publish({
|
|
|
|
variant: "success",
|
|
|
|
text: "OpenAI API Key updated",
|
|
|
|
});
|
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
} finally {
|
|
|
|
setChangeOpenAiApiKeyRequestPending(false);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const removeOpenAiApiKey = async () => {
|
|
|
|
try {
|
|
|
|
setChangeOpenAiApiKeyRequestPending(true);
|
|
|
|
await updateUserIdentity({
|
|
|
|
openai_api_key: null,
|
|
|
|
});
|
|
|
|
|
|
|
|
publish({
|
|
|
|
variant: "success",
|
|
|
|
text: "OpenAI API Key removed",
|
|
|
|
});
|
|
|
|
|
2023-09-13 14:47:12 +03:00
|
|
|
void queryClient.invalidateQueries({
|
|
|
|
queryKey: [USER_IDENTITY_DATA_KEY],
|
|
|
|
});
|
2023-08-01 10:24:57 +03:00
|
|
|
} catch (error) {
|
|
|
|
console.error(error);
|
|
|
|
} finally {
|
|
|
|
setChangeOpenAiApiKeyRequestPending(false);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (userIdentity?.openai_api_key !== undefined) {
|
|
|
|
setOpenAiApiKey(userIdentity.openai_api_key);
|
|
|
|
}
|
|
|
|
}, [userIdentity]);
|
|
|
|
|
|
|
|
const hasOpenAiApiKey =
|
|
|
|
userIdentity?.openai_api_key !== null &&
|
|
|
|
userIdentity?.openai_api_key !== undefined &&
|
|
|
|
userIdentity.openai_api_key !== "";
|
|
|
|
|
2023-07-26 00:12:46 +03:00
|
|
|
return {
|
|
|
|
handleCreateClick,
|
|
|
|
apiKey,
|
|
|
|
handleCopyClick,
|
2023-08-01 10:24:57 +03:00
|
|
|
openAiApiKey,
|
|
|
|
setOpenAiApiKey,
|
|
|
|
changeOpenAiApiKey,
|
|
|
|
changeOpenAiApiKeyRequestPending,
|
|
|
|
userIdentity,
|
|
|
|
removeOpenAiApiKey,
|
|
|
|
hasOpenAiApiKey,
|
2023-07-26 00:12:46 +03:00
|
|
|
};
|
|
|
|
};
|