mirror of
https://github.com/kikootwo/ReadMeABook.git
synced 2026-06-03 12:50:09 +00:00
5a0cce7985
Introduces granular toggles for Anna's Archive and Indexer Search as ebook sources, updates settings UI to a three-section layout, and documents the new configuration. Adds per-indexer category configuration with separate tabs for audiobooks and ebooks, updates API routes and types for new settings, and ensures legacy config migration. Indexer grouping and file organization logic now support the new category structure and ebook source toggles.
156 lines
4.8 KiB
TypeScript
156 lines
4.8 KiB
TypeScript
/**
|
|
* Component: Setup Wizard Prowlarr Step
|
|
* Documentation: documentation/setup-wizard.md
|
|
*/
|
|
|
|
'use client';
|
|
|
|
import { useState, useEffect } from 'react';
|
|
import { Button } from '@/components/ui/Button';
|
|
import { Input } from '@/components/ui/Input';
|
|
import { IndexerManagement } from '@/components/admin/indexers/IndexerManagement';
|
|
|
|
interface ProwlarrStepProps {
|
|
prowlarrUrl: string;
|
|
prowlarrApiKey: string;
|
|
onUpdate: (field: string, value: any) => void;
|
|
onNext: () => void;
|
|
onBack: () => void;
|
|
}
|
|
|
|
interface SelectedIndexer {
|
|
id: number;
|
|
name: string;
|
|
protocol: string;
|
|
priority: number;
|
|
seedingTimeMinutes?: number; // Torrents only
|
|
removeAfterProcessing?: boolean; // Usenet only
|
|
rssEnabled: boolean;
|
|
audiobookCategories: number[]; // Categories for audiobook searches
|
|
ebookCategories: number[]; // Categories for ebook searches
|
|
}
|
|
|
|
export function ProwlarrStep({
|
|
prowlarrUrl,
|
|
prowlarrApiKey,
|
|
onUpdate,
|
|
onNext,
|
|
onBack,
|
|
}: ProwlarrStepProps) {
|
|
const [configuredIndexers, setConfiguredIndexers] = useState<SelectedIndexer[]>([]);
|
|
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
|
|
|
// Sync configured indexers with parent
|
|
useEffect(() => {
|
|
onUpdate('prowlarrIndexers', configuredIndexers);
|
|
}, [configuredIndexers, onUpdate]);
|
|
|
|
const handleNext = () => {
|
|
setErrorMessage(null);
|
|
|
|
if (!prowlarrUrl || !prowlarrApiKey) {
|
|
setErrorMessage('Please enter Prowlarr URL and API key');
|
|
return;
|
|
}
|
|
|
|
if (configuredIndexers.length === 0) {
|
|
setErrorMessage('Please add at least one indexer');
|
|
return;
|
|
}
|
|
|
|
onNext();
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<div>
|
|
<h2 className="text-2xl font-bold text-gray-900 dark:text-gray-100">
|
|
Configure Prowlarr
|
|
</h2>
|
|
<p className="text-gray-600 dark:text-gray-400 mt-2">
|
|
Connect to Prowlarr to search for audiobooks across multiple indexers.
|
|
</p>
|
|
</div>
|
|
|
|
<div className="space-y-4">
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
|
Prowlarr URL
|
|
</label>
|
|
<Input
|
|
type="url"
|
|
placeholder="http://localhost:9696"
|
|
value={prowlarrUrl}
|
|
onChange={(e) => onUpdate('prowlarrUrl', e.target.value)}
|
|
/>
|
|
<p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
|
|
The URL where Prowlarr is running (include port)
|
|
</p>
|
|
</div>
|
|
|
|
<div>
|
|
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
|
API Key
|
|
</label>
|
|
<Input
|
|
type="password"
|
|
placeholder="Enter your Prowlarr API key"
|
|
value={prowlarrApiKey}
|
|
onChange={(e) => onUpdate('prowlarrApiKey', e.target.value)}
|
|
/>
|
|
<p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
|
|
Find this in Prowlarr Settings → General → Security → API Key
|
|
</p>
|
|
</div>
|
|
|
|
{errorMessage && (
|
|
<div className="rounded-lg p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800">
|
|
<div className="flex gap-3">
|
|
<svg
|
|
className="w-6 h-6 flex-shrink-0 text-red-600 dark:text-red-400"
|
|
fill="currentColor"
|
|
viewBox="0 0 20 20"
|
|
>
|
|
<path
|
|
fillRule="evenodd"
|
|
d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z"
|
|
clipRule="evenodd"
|
|
/>
|
|
</svg>
|
|
<div>
|
|
<h3 className="text-sm font-medium text-red-800 dark:text-red-200">
|
|
Error
|
|
</h3>
|
|
<p className="text-sm mt-1 text-red-700 dark:text-red-300">
|
|
{errorMessage}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* Indexer Management Component */}
|
|
<div className="border-t border-gray-200 dark:border-gray-700 pt-6">
|
|
<IndexerManagement
|
|
prowlarrUrl={prowlarrUrl}
|
|
prowlarrApiKey={prowlarrApiKey}
|
|
mode="wizard"
|
|
initialIndexers={configuredIndexers}
|
|
onIndexersChange={setConfiguredIndexers}
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Navigation Buttons */}
|
|
<div className="flex justify-between pt-6 border-t border-gray-200 dark:border-gray-700">
|
|
<Button onClick={onBack} variant="outline">
|
|
Back
|
|
</Button>
|
|
<Button onClick={handleNext} variant="primary">
|
|
Next
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|