'use client'; import { useState } from 'react'; import { useRouter } from 'next/navigation'; import Link from 'next/link'; import BulkImportProgress from '@/components/BulkImportProgress'; import ImportLayout from '@/components/layout/ImportLayout'; import Button from '@/components/ui/Button'; import { Textarea } from '@/components/ui/Input'; interface ImportResult { url: string; status: 'imported' | 'skipped' | 'error'; reason?: string; title?: string; author?: string; error?: string; storyId?: string; } interface BulkImportResponse { results: ImportResult[]; summary: { total: number; imported: number; skipped: number; errors: number; }; combinedStory?: { title: string; author: string; content: string; summary?: string; sourceUrl: string; tags?: string[]; }; } export default function BulkImportPage() { const router = useRouter(); const [urls, setUrls] = useState(''); const [combineIntoOne, setCombineIntoOne] = useState(false); const [isLoading, setIsLoading] = useState(false); const [results, setResults] = useState(null); const [error, setError] = useState(null); const [sessionId, setSessionId] = useState(null); const [showProgress, setShowProgress] = useState(false); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!urls.trim()) { setError('Please enter at least one URL'); return; } setIsLoading(true); setError(null); setResults(null); try { // Parse URLs from textarea (one per line) const urlList = urls .split('\n') .map(url => url.trim()) .filter(url => url.length > 0); if (urlList.length === 0) { setError('Please enter at least one valid URL'); setIsLoading(false); return; } if (urlList.length > 200) { setError('Maximum 200 URLs allowed per bulk import'); setIsLoading(false); return; } // Generate session ID for progress tracking const newSessionId = `bulk-import-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; setSessionId(newSessionId); setShowProgress(true); // Get auth token for server-side API calls const token = localStorage.getItem('auth-token'); const response = await fetch('/scrape/bulk', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': token ? `Bearer ${token}` : '', }, body: JSON.stringify({ urls: urlList, combineIntoOne, sessionId: newSessionId }), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || 'Failed to start bulk import'); } const startData = await response.json(); console.log('Bulk import started:', startData); // The progress component will handle the rest via SSE } catch (err) { console.error('Bulk import error:', err); setError(err instanceof Error ? err.message : 'Failed to import stories'); } finally { setIsLoading(false); } }; const handleReset = () => { setUrls(''); setCombineIntoOne(false); setResults(null); setError(null); setSessionId(null); setShowProgress(false); }; const handleProgressComplete = (data?: any) => { // Progress component will handle this when the operation completes setShowProgress(false); setIsLoading(false); // Handle completion data if (data) { if (data.combinedStory && combineIntoOne) { // For combine mode, redirect to import page with the combined content localStorage.setItem('pendingStory', JSON.stringify(data.combinedStory)); router.push('/import?from=bulk-combine'); return; } else if (data.results && data.summary) { // For individual mode, show the results setResults({ results: data.results, summary: data.summary }); return; } } // Fallback: just hide progress and let user know it completed console.log('Import completed successfully'); }; const handleProgressError = (errorMessage: string) => { setError(errorMessage); setIsLoading(false); setShowProgress(false); }; const getStatusColor = (status: string) => { switch (status) { case 'imported': return 'text-green-700 bg-green-50 border-green-200'; case 'skipped': return 'text-yellow-700 bg-yellow-50 border-yellow-200'; case 'error': return 'text-red-700 bg-red-50 border-red-200'; default: return 'text-gray-700 bg-gray-50 border-gray-200'; } }; const getStatusIcon = (status: string) => { switch (status) { case 'imported': return '✓'; case 'skipped': return '⚠'; case 'error': return '✗'; default: return ''; } }; return ( {!results ? ( // Import Form

Enter one URL per line. Maximum 200 URLs per import.