"use client"; import styles from "./settings.module.css"; import { Suspense, useEffect, useState } from "react"; import { useToast } from "@/components/ui/use-toast" import { useUserConfig, ModelOptions } from "../common/auth"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardFooter, CardHeader, } from "@/components/ui/card"; import { DropdownMenu, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu" import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table" import { ArrowRight, ChatCircleText, Key, Palette, SpeakerHigh, UserCircle, FileMagnifyingGlass, Trash, Copy, PlusCircle } from "@phosphor-icons/react"; import NavMenu from "../components/navMenu/navMenu"; import SidePanel from "../components/sidePanel/chatHistorySidePanel"; import Loading from "../components/loading/loading"; interface DropdownComponentProps { items: ModelOptions[]; selected: number; callbackFunc: (value: string) => Promise; } const DropdownComponent: React.FC = ({ items, selected, callbackFunc }) => { const [position, setPosition] = useState(selected?.toString() ?? "0"); return !!selected && (
{ setPosition(value); await callbackFunc(value); }} > {items.map((item) => ( {item.name} ))}
); } interface TokenObject { token: string; name: string; } export const useApiKeys = () => { const [apiKeys, setApiKeys] = useState([]); const { toast } = useToast(); const generateAPIKey = async () => { try { const response = await fetch(`/auth/token`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, }); const tokenObj = await response.json(); setApiKeys(prevKeys => [...prevKeys, tokenObj]); } catch (error) { console.error('Error generating API key:', error); } }; const copyAPIKey = async (token: string) => { try { await navigator.clipboard.writeText(token); toast({ title: "🔑 API Key", description: "Copied to clipboard", }); } catch (error) { console.error('Error copying API key:', error); } }; const deleteAPIKey = async (token: string) => { try { const response = await fetch(`/auth/token?token=${token}`, { method: 'DELETE' }); if (response.ok) { setApiKeys(prevKeys => prevKeys.filter(key => key.token !== token)); } } catch (error) { console.error('Error deleting API key:', error); } }; const listApiKeys = async () => { try { const response = await fetch(`/auth/token`); const tokens = await response.json(); if (tokens?.length > 0) { setApiKeys(tokens); } } catch (error) { console.error('Error listing API keys:', error); } }; useEffect(() => { listApiKeys(); }, []); return { apiKeys, generateAPIKey, copyAPIKey, deleteAPIKey, }; }; export default function SettingsView() { const [title, setTitle] = useState("Settings"); const [isMobileWidth, setIsMobileWidth] = useState(false); const { apiKeys, generateAPIKey, copyAPIKey, deleteAPIKey } = useApiKeys(); const userConfig = useUserConfig(true); const cardClassName = "w-1/3 grid grid-flow-column border border-gray-300 shadow-md rounded-lg"; const { toast } = useToast(); useEffect(() => { setIsMobileWidth(window.innerWidth < 786); const handleResize = () => setIsMobileWidth(window.innerWidth < 786); window.addEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize); }, []); const updateModel = (name: string) => async (id: string) => { try { const response = await fetch(`/api/model/${name}?id=` + id, { method: 'POST', headers: { 'Content-Type': 'application/json', } }); if (response.ok) { const result = await response.json(); toast({ description: `${name} model updated succesfully`, }); } else { toast({ description: `Failed to update ${name} model`, variant: "destructive", }); } } catch (error) { console.error('Error updating search model:', error); toast({ description: `An error occured while updating the ${name} model`, variant: "destructive", }); } }; if (!userConfig) return ; return (
{title}
}>
Profile
Name
Content
Files Manage your synced files Github Set repositories to index Notion Sync your Notion pages
Features
Chat Search Paint Voice
Clients
API Keys

Access Khoj from your Desktop App, Obsidian plugin, and more.

Name Token Actions {apiKeys.map((key) => ( {key.name} {`${key.token.slice(0, 4)}...${key.token.slice(-4)}`} ))}
); }