'use client'; import React, { useState, useEffect } from "react"; import Header from "../dashboard/components/Header"; import Wrapper from "@/components/Wrapper"; import { Settings, Key, Loader2 } from 'lucide-react'; import { toast } from '@/hooks/use-toast'; import { RootState } from "@/store/store"; import { useSelector } from "react-redux"; import { handleSaveLLMConfig } from "@/utils/storeHelpers"; import { useRouter } from "next/navigation"; import { Select, SelectContent, SelectItem, SelectTrigger } from "@/components/ui/select"; const PROVIDER_CONFIGS: Record = { openai: { title: "OpenAI API Key", description: "Required for using OpenAI services", placeholder: "Enter your OpenAI API key", }, google: { title: "Google API Key", description: "Required for using Google services", placeholder: "Enter your Google API key", }, ollama: { title: "Ollama API Key", description: "Required for using Ollama services", placeholder: "Choose a model", } }; interface ProviderConfig { title: string; description: string; placeholder: string; } const SettingsPage = () => { const router = useRouter(); const userConfigState = useSelector((state: RootState) => state.userConfig); const [llmConfig, setLlmConfig] = useState(userConfigState.llm_config); const canChangeKeys = userConfigState.can_change_keys; const [ollamaModels, setOllamaModels] = useState<{ label: string; value: string; description: string; size: string; icon: string; }[]>([]); const [downloadingModel, setDownloadingModel] = useState({ name: '', size: null, downloaded: null, status: '', done: false, }); const [isLoading, setIsLoading] = useState(false); const api_key_changed = (apiKey: string) => { if (llmConfig.LLM === 'openai') { setLlmConfig({ ...llmConfig, OPENAI_API_KEY: apiKey }); } else if (llmConfig.LLM === 'google') { setLlmConfig({ ...llmConfig, GOOGLE_API_KEY: apiKey }); } else if (llmConfig.LLM === 'ollama') { setLlmConfig({ ...llmConfig, PEXELS_API_KEY: apiKey }); } } const handleSaveConfig = async () => { if (llmConfig.LLM === 'ollama') { try { setIsLoading(true); await pullOllamaModels(); toast({ title: 'Success', description: 'Model downloaded successfully', }); } catch (error) { console.error('Error pulling model:', error); toast({ title: 'Error', description: 'Failed to download model. Please try again.', variant: 'destructive', }); setIsLoading(false); return; } } try { await handleSaveLLMConfig(llmConfig); toast({ title: 'Success', description: 'Configuration saved successfully', }); setIsLoading(false); router.back(); } catch (error) { console.error('Error:', error); toast({ title: 'Error', description: 'Failed to save configuration', variant: 'destructive', }); setIsLoading(false); } }; const changeProvider = (provider: string) => { setLlmConfig({ ...llmConfig, LLM: provider }); if (provider === 'ollama') { fetchOllamaModels(); } } const pullOllamaModels = async (): Promise => { return new Promise((resolve, reject) => { const interval = setInterval(async () => { try { const response = await fetch(`/api/v1/ppt/ollama/pull-model?name=${llmConfig.OLLAMA_MODEL}`); if (response.status === 200) { const data = await response.json(); if (data.done) { clearInterval(interval); setDownloadingModel(data); resolve(); } else { setDownloadingModel(data); } } else { clearInterval(interval); reject(new Error('Model pulling failed')); } } catch (error) { console.log('Error fetching ollama models:', error); clearInterval(interval); reject(error); } }, 1000); }); } const fetchOllamaModels = async () => { try { const response = await fetch('/api/v1/ppt/ollama/list-supported-models'); const data = await response.json(); setOllamaModels(data.models); } catch (error) { console.error('Error fetching ollama models:', error); } } useEffect(() => { if (!canChangeKeys) { router.push("/dashboard"); } if (userConfigState.llm_config.LLM === 'ollama') { fetchOllamaModels(); } }, [userConfigState.llm_config.LLM]); if (!canChangeKeys) { return null; } return (
{/* Settings Header */}

Settings

{/* API Configuration Section */}

API Configuration

{/* Provider Selection */}
{Object.keys(PROVIDER_CONFIGS).map((provider) => ( ))}
{/* API Key Input */} {llmConfig.LLM !== 'ollama' && (
api_key_changed(e.target.value)} className="flex-1 px-4 py-2.5 border border-gray-300 outline-none rounded-lg focus:ring-2 focus:ring-blue-500/20 focus:border-blue-500 transition-colors" placeholder={PROVIDER_CONFIGS[llmConfig.LLM!].placeholder} />

{PROVIDER_CONFIGS[llmConfig.LLM!].description}

)} {/* Ollama Configuration */} {llmConfig.LLM === 'ollama' && (
{ollamaModels.length > 0 ? ( ) : (
)}
{ollamaModels.length === 0 && (

Loading available models...

)}
api_key_changed(e.target.value)} />

Required for using Ollama services with image generation

{downloadingModel.status && downloadingModel.status !== 'pulled' && (
{downloadingModel.status}
)}
)}
); }; export default SettingsPage;