'use client'; import React, { useState, useEffect, useCallback } from 'react'; import Link from 'next/link'; import { useAuth } from '@/contexts/AuthContext'; import { useRouter } from 'next/navigation'; import AppImage from '@/components/ui/AppImage'; interface ImportedPost { id: string; wp_id: number; wp_slug: string; title: string; author_name: string; category: string | null; featured_image: string | null; featured_image_alt: string | null; wp_published_at: string | null; imported_at: string; status: string; } interface ImportLog { id: string; started_at: string; completed_at: string | null; total_fetched: number; total_imported: number; total_skipped: number; total_errors: number; status: string; error_message: string | null; } interface ImportResult { success?: boolean; error?: string; totalFetched?: number; totalImported?: number; totalErrors?: number; pagesProcessed?: number; } export default function WPImportPage() { const { user, loading } = useAuth(); const router = useRouter(); const [posts, setPosts] = useState([]); const [logs, setLogs] = useState([]); const [isImporting, setIsImporting] = useState(false); const [importResult, setImportResult] = useState(null); const [loadingData, setLoadingData] = useState(true); const [deletingId, setDeletingId] = useState(null); const [maxPages, setMaxPages] = useState(5); const [searchQuery, setSearchQuery] = useState(''); const [activeTab, setActiveTab] = useState<'posts' | 'logs'>('posts'); useEffect(() => { if (!loading && !user) { router.replace('/login?next=' + encodeURIComponent(window.location.pathname)); } }, [user, loading, router]); const fetchData = useCallback(async () => { try { const res = await fetch('/api/wp-import'); if (res.ok) { const data = await res.json(); setPosts(data?.posts || []); setLogs(data?.logs || []); } } catch { // silent } finally { setLoadingData(false); } }, []); useEffect(() => { if (user) fetchData(); }, [user, fetchData]); const handleImport = async () => { setIsImporting(true); setImportResult(null); try { const res = await fetch('/api/wp-import', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ maxPages }), }); const data = await res.json(); setImportResult(data); if (data?.success) { await fetchData(); } } catch (err: any) { setImportResult({ error: err?.message || 'Import failed' }); } finally { setIsImporting(false); } }; const handleDelete = async (id: string) => { setDeletingId(id); try { const res = await fetch('/api/wp-import', { method: 'DELETE', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id }), }); if (res.ok) { setPosts((prev) => prev.filter((p) => p.id !== id)); } } catch { // silent } finally { setDeletingId(null); } }; const filteredPosts = posts.filter((p) => !searchQuery || p.title?.toLowerCase().includes(searchQuery.toLowerCase()) || p.author_name?.toLowerCase().includes(searchQuery.toLowerCase()) || p.category?.toLowerCase().includes(searchQuery.toLowerCase()) ); const formatDate = (dateStr: string | null) => { if (!dateStr) return '—'; return new Date(dateStr).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' }); }; if (loading || (!user && !loading)) { return (
); } return (
{/* Page Header */}
Home / Admin / WP Import

WordPress Post Importer

Import posts from{' '} avbeat.com {' '} via WordPress REST API

{posts.length} posts imported
{/* Import Controls */}

Run Import

{/* Import Progress / Result */} {isImporting && (

Import in progress

Fetching posts from avbeat.com and saving to database...

)} {importResult && !isImporting && (
{importResult.error ? (

Import failed

{importResult.error}

) : (

Import completed successfully

{[ { label: 'Fetched', value: importResult.totalFetched, color: 'text-[#cccccc]' }, { label: 'Imported', value: importResult.totalImported, color: 'text-green-400' }, { label: 'Pages', value: importResult.pagesProcessed, color: 'text-[#3b82f6]' }, { label: 'Errors', value: importResult.totalErrors, color: importResult.totalErrors ? 'text-red-400' : 'text-[#555]' }, ].map((stat) => (

{stat.value ?? 0}

{stat.label}

))}
)}
)}
{/* Tabs */}
{(['posts', 'logs'] as const).map((tab) => ( ))}
{/* Posts Tab */} {activeTab === 'posts' && (
{/* Search */}
setSearchQuery(e.target.value)} className="w-full bg-[#111] border border-[#252525] text-[#cccccc] text-sm rounded pl-9 pr-4 py-2 focus:outline-none focus:border-[#3b82f6] placeholder-[#444]" />
{loadingData ? (
) : filteredPosts.length === 0 ? (

{searchQuery ? 'No posts match your search' : 'No posts imported yet. Run an import to get started.'}

) : (
{filteredPosts.map((post) => (
{/* Thumbnail */} {post.featured_image ? (
) : (
)} {/* Content */}

{post.title}

{post.category && ( {post.category} )} {post.author_name} Published {formatDate(post.wp_published_at)} Imported {formatDate(post.imported_at)}
))}
)}
)} {/* Logs Tab */} {activeTab === 'logs' && (
{loadingData ? (
) : logs.length === 0 ? (

No import history yet.

) : (
{logs.map((log) => (
{log.status === 'completed' ? ( ) : log.status === 'failed' ? ( ) : ( )} {log.status}
{formatDate(log.started_at)}
{log.status !== 'running' && (
{[ { label: 'Fetched', value: log.total_fetched }, { label: 'Imported', value: log.total_imported }, { label: 'Skipped', value: log.total_skipped }, { label: 'Errors', value: log.total_errors }, ].map((stat) => (

{stat.value}

{stat.label}

))}
)} {log.error_message && (

{log.error_message}

)}
))}
)}
)}
); }