/** * Component: BookDate Setup Step (Setup Wizard) * Documentation: documentation/features/bookdate-prd.md */ 'use client'; import { useState } from 'react'; interface BookDateStepProps { bookdateProvider: string; bookdateApiKey: string; bookdateModel: string; bookdateConfigured: boolean; bookdateModels: ModelOption[]; onUpdate: (field: string, value: any) => void; onNext: () => void; onSkip: () => void; onBack: () => void; } interface ModelOption { id: string; name: string; } export function BookDateStep({ bookdateProvider, bookdateApiKey, bookdateModel, bookdateConfigured, bookdateModels, onUpdate, onNext, onSkip, onBack, }: BookDateStepProps) { const [testing, setTesting] = useState(false); const [tested, setTested] = useState(bookdateConfigured); const [models, setModels] = useState(bookdateModels); const [error, setError] = useState(null); const handleTestConnection = async () => { if (!bookdateApiKey.trim()) { setError('Please enter an API key'); return; } setTesting(true); setError(null); try { const response = await fetch('/api/bookdate/test-connection', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ provider: bookdateProvider, apiKey: bookdateApiKey, }), }); const data = await response.json(); if (!response.ok) { throw new Error(data.error || 'Connection test failed'); } const fetchedModels = data.models || []; setModels(fetchedModels); setTested(true); onUpdate('bookdateConfigured', true); onUpdate('bookdateModels', fetchedModels); // Auto-select first model if none selected if (!bookdateModel && fetchedModels.length > 0) { onUpdate('bookdateModel', fetchedModels[0].id); } } catch (err) { setError(err instanceof Error ? err.message : 'Connection test failed'); setTested(false); onUpdate('bookdateConfigured', false); onUpdate('bookdateModels', []); } finally { setTesting(false); } }; const handleNext = () => { if (tested && bookdateModel) { onNext(); } else { setError('Please test connection and select a model'); } }; const canProceed = tested && bookdateModel; return (

BookDate Setup (Optional)

Configure AI-powered audiobook recommendations. You can skip this step and set it up later in Settings.

{error && (

{error}

)} {/* AI Provider Selection */}
{/* API Key Input */}
{ onUpdate('bookdateApiKey', e.target.value); setTested(false); setModels([]); onUpdate('bookdateConfigured', false); onUpdate('bookdateModels', []); }} placeholder={bookdateProvider === 'openai' ? 'sk-...' : bookdateProvider === 'gemini' ? 'AIza...' : 'sk-ant-...'} className="w-full px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500" />

Your API key is stored securely and only used for recommendations

{/* Test Connection Button */} {/* Model Selection (shown after successful test) */} {tested && models.length > 0 && (
)} {/* Info about per-user preferences */} {tested && bookdateModel && (

Note: Library scope and custom prompt preferences can be configured per-user after setup. Users can adjust these in their BookDate preferences (settings icon on the BookDate page).

)} {/* Navigation Buttons */}
); }