"use client"; import { useState, useEffect, useMemo } from "react"; import { useRouter } from "next/navigation"; import { toast } from "sonner"; import { Loader2, Download, CheckCircle, X } from "lucide-react"; import { useSelector } from "react-redux"; import { RootState } from "@/store/store"; import { handleSaveLLMConfig } from "@/utils/storeHelpers"; import LLMProviderSelection from "./LLMSelection"; import { checkIfSelectedOllamaModelIsPulled, LLMConfig, pullOllamaModel, } from "@/utils/providerUtils"; // Button state interface interface ButtonState { isLoading: boolean; isDisabled: boolean; text: string; showProgress: boolean; progressPercentage?: number; status?: string; } export default function Home() { const router = useRouter(); const config = useSelector((state: RootState) => state.userConfig); const [llmConfig, setLlmConfig] = useState(config.llm_config); const [isLoading, setIsLoading] = useState(false); const [downloadingModel, setDownloadingModel] = useState<{ name: string; size: number | null; downloaded: number | null; status: string; done: boolean; } | null>(null); const [showDownloadModal, setShowDownloadModal] = useState(false); const [buttonState, setButtonState] = useState({ isLoading: false, isDisabled: false, text: "Save Configuration", showProgress: false }); const canChangeKeys = config.can_change_keys; const downloadProgress = useMemo(() => { if (downloadingModel && downloadingModel.downloaded !== null && downloadingModel.size !== null) { return Math.round((downloadingModel.downloaded / downloadingModel.size) * 100); } return 0; }, [downloadingModel?.downloaded, downloadingModel?.size]); const handleSaveConfig = async () => { try { setIsLoading(true); setButtonState(prev => ({ ...prev, isLoading: true, isDisabled: true, text: "Saving Configuration..." })); console.log("llmConfig", llmConfig); await handleSaveLLMConfig(llmConfig); if (llmConfig.LLM === "ollama" && llmConfig.OLLAMA_MODEL) { const isPulled = await checkIfSelectedOllamaModelIsPulled(llmConfig.OLLAMA_MODEL); if (!isPulled) { setShowDownloadModal(true); await handleModelDownload(); } } toast.info("Configuration saved successfully"); setIsLoading(false); setButtonState(prev => ({ ...prev, isLoading: false, isDisabled: false, text: "Save Configuration" })); router.push("/upload"); } catch (error) { toast.info("Failed to save configuration"); setIsLoading(false); setButtonState(prev => ({ ...prev, isLoading: false, isDisabled: false, text: "Save Configuration" })); } }; const handleModelDownload = async () => { try { await pullOllamaModel(llmConfig.OLLAMA_MODEL!, setDownloadingModel); } catch (error) { console.info("Error downloading model:", error); setDownloadingModel(null); setShowDownloadModal(false); } }; useEffect(() => { if (downloadingModel && downloadingModel.downloaded !== null && downloadingModel.size !== null) { const percentage = Math.round(((downloadingModel.downloaded / downloadingModel.size) * 100)); setButtonState({ isLoading: true, isDisabled: true, text: `Downloading Model (${percentage}%)`, showProgress: true, progressPercentage: percentage, status: downloadingModel.status }); } if (downloadingModel && downloadingModel.done) { setTimeout(() => { setShowDownloadModal(false); setDownloadingModel(null); toast.info("Model downloaded successfully!"); }, 2000); } }, [downloadingModel]); useEffect(() => { if (!canChangeKeys) { router.push("/upload"); } }, [canChangeKeys, router]); if (!canChangeKeys) { return null; } return (
{/* Branding Header */}
Presenton Logo

Open-source AI presentation generator

{/* Main Configuration Card */}
{/* Download Progress Modal */} {showDownloadModal && downloadingModel && (
{/* Modal Content */}
{/* Icon */}
{downloadingModel.done ? ( ) : ( )}
{/* Title */}

{downloadingModel.done ? "Download Complete!" : "Downloading Model"}

{/* Model Name */}

{llmConfig.OLLAMA_MODEL}

{/* Progress Bar */} {downloadProgress > 0 && (

{downloadProgress}% Complete

)} {/* Status */} {downloadingModel.status && (
{downloadingModel.status}
)} {/* Status Message */} {downloadingModel.status && downloadingModel.status !== "pulled" && (
{downloadingModel.status === "downloading" && "Downloading model files..."} {downloadingModel.status === "verifying" && "Verifying model integrity..."} {downloadingModel.status === "pulling" && "Pulling model from registry..."}
)} {/* Download Info */} {downloadingModel.downloaded && downloadingModel.size && (
Downloaded: {(downloadingModel.downloaded / 1024 / 1024).toFixed(1)} MB Total: {(downloadingModel.size / 1024 / 1024).toFixed(1)} MB
)}
)} {/* Fixed Bottom Button */}
); }