"use client"; import { useState, useEffect } from "react"; import { Server, Check, AlertCircle, Loader2, ExternalLink, Copy, Terminal, Cpu, HardDrive } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Badge } from "@/components/ui/badge"; import { cn } from "@/lib/utils"; interface OllamaModel { name: string; size: string; quantization: string; } const recommendedModels: OllamaModel[] = [ { name: "llama3.2:3b", size: "2 GB", quantization: "Q4_0" }, { name: "mistral:7b", size: "4.1 GB", quantization: "Q4_0" }, { name: "qwen2.5:7b", size: "4.7 GB", quantization: "Q4_K_M" }, { name: "llama3.1:8b", size: "4.7 GB", quantization: "Q4_0" }, { name: "gemma2:9b", size: "5.4 GB", quantization: "Q4_0" }, ]; export default function OllamaSetupPage() { const [endpoint, setEndpoint] = useState("http://localhost:11434"); const [selectedModel, setSelectedModel] = useState(""); const [availableModels, setAvailableModels] = useState([]); const [testing, setTesting] = useState(false); const [connectionStatus, setConnectionStatus] = useState<"idle" | "success" | "error">("idle"); const [errorMessage, setErrorMessage] = useState(""); const [copied, setCopied] = useState(null); const testConnection = async () => { setTesting(true); setConnectionStatus("idle"); setErrorMessage(""); try { // Test connection to Ollama const res = await fetch(`${endpoint}/api/tags`); if (!res.ok) throw new Error("Failed to connect to Ollama"); const data = await res.json(); const models = data.models?.map((m: any) => m.name) || []; setAvailableModels(models); setConnectionStatus("success"); // Auto-select first model if available if (models.length > 0 && !selectedModel) { setSelectedModel(models[0]); } } catch (error: any) { setConnectionStatus("error"); setErrorMessage(error.message || "Failed to connect to Ollama"); } finally { setTesting(false); } }; const copyToClipboard = (text: string, id: string) => { navigator.clipboard.writeText(text); setCopied(id); setTimeout(() => setCopied(null), 2000); }; const saveSettings = () => { // Save to localStorage or user settings const settings = { ollamaEndpoint: endpoint, ollamaModel: selectedModel }; localStorage.setItem("ollamaSettings", JSON.stringify(settings)); // Also save to user account if logged in const token = localStorage.getItem("token"); if (token) { fetch("http://localhost:8000/api/auth/settings", { method: "PUT", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, body: JSON.stringify({ ollama_endpoint: endpoint, ollama_model: selectedModel, }), }); } alert("Settings saved successfully!"); }; return (
{/* Header */}
Self-Hosted

Configure Your Ollama Server

Connect your own Ollama instance for unlimited, free translations using local AI models.

{/* What is Ollama */}

What is Ollama?

Ollama is a free, open-source tool that lets you run large language models locally on your computer. With Ollama, you can translate documents without sending data to external servers, ensuring complete privacy.

{/* Installation Guide */}

Quick Installation Guide

{/* Step 1 */}

1. Install Ollama

macOS / Linux: curl -fsSL https://ollama.ai/install.sh | sh

Windows: Download from ollama.ai/download

{/* Step 2 */}

2. Pull a Translation Model

ollama pull llama3.2:3b
{/* Step 3 */}

3. Start Ollama Server

ollama serve

On macOS/Windows with the desktop app, Ollama runs automatically in the background.

{/* Recommended Models */}

Recommended Models for Translation

{recommendedModels.map((model) => (
{model.name}
{model.size}
))}

πŸ’‘ Tip: For best results with limited RAM (8GB), use llama3.2:3b. With 16GB+ RAM, try mistral:7b or larger.

{/* Configuration */}

Configure Connection

setEndpoint(e.target.value)} placeholder="http://localhost:11434" className="bg-zinc-800 border-zinc-700 text-white" />
{/* Connection Status */} {connectionStatus === "success" && (
Connected successfully! Found {availableModels.length} model(s).
)} {connectionStatus === "error" && (
{errorMessage}
)} {/* Model Selection */} {availableModels.length > 0 && (
{availableModels.map((model) => ( ))}
)} {/* Save Button */} {connectionStatus === "success" && selectedModel && ( )}
{/* Benefits */}

Why Self-Host?

πŸ”’

Complete Privacy

Your documents never leave your computer

♾️

Unlimited Usage

No monthly limits or quotas

πŸ’°

Free Forever

No subscription or API costs

); }