/** * Component: Setup Wizard Download Client Step * Documentation: documentation/setup-wizard.md */ 'use client'; import { useState } from 'react'; import { Button } from '@/components/ui/Button'; import { Input } from '@/components/ui/Input'; interface DownloadClientStepProps { downloadClient: 'qbittorrent' | 'sabnzbd'; downloadClientUrl: string; downloadClientUsername: string; downloadClientPassword: string; disableSSLVerify: boolean; remotePathMappingEnabled: boolean; remotePath: string; localPath: string; onUpdate: (field: string, value: any) => void; onNext: () => void; onBack: () => void; } export function DownloadClientStep({ downloadClient, downloadClientUrl, downloadClientUsername, downloadClientPassword, disableSSLVerify, remotePathMappingEnabled, remotePath, localPath, onUpdate, onNext, onBack, }: DownloadClientStepProps) { const [testing, setTesting] = useState(false); const [testResult, setTestResult] = useState<{ success: boolean; message: string; version?: string; } | null>(null); const testConnection = async () => { setTesting(true); setTestResult(null); try { const response = await fetch('/api/setup/test-download-client', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ type: downloadClient, url: downloadClientUrl, username: downloadClientUsername, password: downloadClientPassword, disableSSLVerify, remotePathMappingEnabled, remotePath, localPath, }), }); const data = await response.json(); if (response.ok && data.success) { setTestResult({ success: true, message: `Connected successfully! ${data.version ? `Version: ${data.version}` : ''}`, version: data.version, }); } else { setTestResult({ success: false, message: data.error || 'Connection failed', }); } } catch (error) { setTestResult({ success: false, message: error instanceof Error ? error.message : 'Connection test failed', }); } finally { setTesting(false); } }; const handleNext = () => { if (!testResult?.success) { setTestResult({ success: false, message: 'Please test the connection before proceeding', }); return; } onNext(); }; // SABnzbd only requires URL and API key (no username) const isFormValid = downloadClient === 'sabnzbd' ? downloadClientUrl && downloadClientPassword // Password field stores API key for SABnzbd : downloadClientUrl && downloadClientUsername && downloadClientPassword; return (
Choose your download client: qBittorrent for torrents or SABnzbd for Usenet/NZB downloads.
The URL where your download client is running (include port)
Find this in SABnzbd under Config → General → API Key
Enable this if you're using a self-signed certificate or getting SSL errors. ⚠️ Only use on trusted private networks.
Use this when {downloadClient === 'qbittorrent' ? 'qBittorrent' : 'SABnzbd'} runs on a different machine or uses different mount points (e.g., remote seedbox, Docker containers)
Example: Remote /remote/mnt/d/done → Local /downloads
{/* Conditional Fields */} {remotePathMappingEnabled && (The path prefix as reported by {downloadClient === 'qbittorrent' ? 'qBittorrent' : 'SABnzbd'}
The actual path where files are accessible
{testResult.message}
{downloadClient === 'qbittorrent' ? 'qBittorrent Setup' : 'SABnzbd Setup'}
{downloadClient === 'qbittorrent' ? 'Make sure Web UI is enabled in qBittorrent settings (Tools → Options → Web UI)' : 'Make sure SABnzbd is running and the API key is configured (Config → General → API Key)'}