/** * Component: Setup Wizard Paths 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 PathsStepProps { downloadDir: string; mediaDir: string; metadataTaggingEnabled: boolean; plexFormatCoercionEnabled: boolean; chapterMergingEnabled: boolean; pathsTested: boolean; onUpdate: (field: string, value: any) => void; onNext: () => void; onBack: () => void; } export function PathsStep({ downloadDir, mediaDir, metadataTaggingEnabled, plexFormatCoercionEnabled, chapterMergingEnabled, pathsTested, onUpdate, onNext, onBack, }: PathsStepProps) { const [testing, setTesting] = useState(false); const [testResult, setTestResult] = useState<{ success: boolean; message: string; downloadDirValid?: boolean; mediaDirValid?: boolean; } | null>( pathsTested ? { success: true, message: 'Paths validated previously.', downloadDirValid: true, mediaDirValid: true } : null ); const testPaths = async () => { setTesting(true); setTestResult(null); try { const response = await fetch('/api/setup/test-paths', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ downloadDir, mediaDir, }), }); const data = await response.json(); if (response.ok && data.success) { setTestResult({ success: true, message: data.message || 'Directories are ready and writable!', downloadDirValid: data.downloadDirValid, mediaDirValid: data.mediaDirValid, }); onUpdate('pathsTested', true); } else { setTestResult({ success: false, message: data.error || 'Path validation failed', downloadDirValid: data.downloadDirValid, mediaDirValid: data.mediaDirValid, }); onUpdate('pathsTested', false); } } catch (error) { setTestResult({ success: false, message: error instanceof Error ? error.message : 'Path validation failed', }); onUpdate('pathsTested', false); } finally { setTesting(false); } }; const handleNext = () => { if (!testResult?.success) { setTestResult({ success: false, message: 'Please validate the paths before proceeding', }); return; } onNext(); }; return (
Set up the directories for downloads and your media library.
Where torrent files will be downloaded (will be created if it doesn't exist)
{testResult && typeof testResult.downloadDirValid !== 'undefined' && (Where organized audiobooks will be stored (will be created if it doesn't exist)
{testResult && typeof testResult.mediaDirValid !== 'undefined' && (Automatically write correct title, author, and narrator metadata to m4b and mp3 files during file organization. This significantly improves Plex matching accuracy for audiobooks with missing or incorrect metadata. Recommended: enabled.
Rename .mp4 audiobook files (and single-file .m4a) to .m4b before Plex scans. No re-encoding.
Automatically merge multi-file chapter downloads into a single M4B audiobook with chapter markers. Improves playback experience and library organization.
{testResult.message}
About directory structure
Audiobooks will be organized as: Media Directory / Author / Title / files. Directories will be created automatically if they don't exist. Validation ensures the parent mount is accessible and writable.