restructuring
This commit is contained in:
128
frontend/src/components/layout/ImportLayout.tsx
Normal file
128
frontend/src/components/layout/ImportLayout.tsx
Normal file
@@ -0,0 +1,128 @@
|
||||
'use client';
|
||||
|
||||
import { ReactNode } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { usePathname, useSearchParams } from 'next/navigation';
|
||||
import AppLayout from './AppLayout';
|
||||
|
||||
interface ImportTab {
|
||||
id: string;
|
||||
label: string;
|
||||
href: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
interface ImportLayoutProps {
|
||||
children: ReactNode;
|
||||
title: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
const importTabs: ImportTab[] = [
|
||||
{
|
||||
id: 'manual',
|
||||
label: 'Manual Entry',
|
||||
href: '/import',
|
||||
description: 'Add a story by manually entering details'
|
||||
},
|
||||
{
|
||||
id: 'url',
|
||||
label: 'Import from URL',
|
||||
href: '/import?mode=url',
|
||||
description: 'Import a single story from a website'
|
||||
},
|
||||
{
|
||||
id: 'epub',
|
||||
label: 'Import EPUB',
|
||||
href: '/import/epub',
|
||||
description: 'Import a story from an EPUB file'
|
||||
},
|
||||
{
|
||||
id: 'bulk',
|
||||
label: 'Bulk Import',
|
||||
href: '/import/bulk',
|
||||
description: 'Import multiple stories from a list of URLs'
|
||||
}
|
||||
];
|
||||
|
||||
export default function ImportLayout({ children, title, description }: ImportLayoutProps) {
|
||||
const pathname = usePathname();
|
||||
const searchParams = useSearchParams();
|
||||
const mode = searchParams.get('mode');
|
||||
|
||||
// Determine which tab is active
|
||||
const getActiveTab = () => {
|
||||
if (pathname === '/import') {
|
||||
return mode === 'url' ? 'url' : 'manual';
|
||||
} else if (pathname === '/import/epub') {
|
||||
return 'epub';
|
||||
} else if (pathname === '/import/bulk') {
|
||||
return 'bulk';
|
||||
}
|
||||
return 'manual';
|
||||
};
|
||||
|
||||
const activeTab = getActiveTab();
|
||||
|
||||
return (
|
||||
<AppLayout>
|
||||
<div className="max-w-4xl mx-auto space-y-6">
|
||||
{/* Header */}
|
||||
<div className="text-center">
|
||||
<h1 className="text-3xl font-bold theme-header">{title}</h1>
|
||||
{description && (
|
||||
<p className="theme-text mt-2 text-lg">
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Tab Navigation */}
|
||||
<div className="theme-card theme-shadow rounded-lg overflow-hidden">
|
||||
{/* Tab Headers */}
|
||||
<div className="flex border-b theme-border overflow-x-auto">
|
||||
{importTabs.map((tab) => (
|
||||
<Link
|
||||
key={tab.id}
|
||||
href={tab.href}
|
||||
className={`flex-1 min-w-0 px-4 py-3 text-sm font-medium text-center transition-colors whitespace-nowrap ${
|
||||
activeTab === tab.id
|
||||
? 'theme-accent-bg text-white border-b-2 border-transparent'
|
||||
: 'theme-text hover:theme-accent-light hover:theme-accent-text'
|
||||
}`}
|
||||
>
|
||||
<div className="truncate">
|
||||
{tab.label}
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Tab Descriptions */}
|
||||
<div className="px-6 py-4 bg-gray-50 dark:bg-gray-800/50">
|
||||
<div className="flex items-center justify-center">
|
||||
<p className="text-sm theme-text text-center">
|
||||
{importTabs.find(tab => tab.id === activeTab)?.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Tab Content */}
|
||||
<div className="p-6">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quick Actions */}
|
||||
<div className="flex justify-center">
|
||||
<Link
|
||||
href="/library"
|
||||
className="theme-text hover:theme-accent transition-colors text-sm"
|
||||
>
|
||||
← Back to Library
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</AppLayout>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user