refactor: remove unused code and migrate legacy API
Backend cleanup: - Remove ocr_service_original.py (legacy OCR service, replaced by ocr_service.py) - Remove preprocessor.py (unused, functionality absorbed by layout_preprocessing_service.py) - Remove pdf_font_manager.py (unused, never referenced by any service) Frontend cleanup: - Remove MarkdownPreview.tsx (unused component) - Remove ResultsTable.tsx (unused, replaced by TaskHistoryPage) - Remove services/api.ts (legacy API client, migrated to apiV2) - Remove types/api.ts (legacy types, migrated to apiV2.ts) API migration: - Add export rules CRUD methods to apiClientV2 - Update SettingsPage.tsx to use apiClientV2 - Update Layout.tsx to use only apiClientV2 for logout This reduces ~1,500 lines of redundant code and unifies the API client. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import { Outlet, NavLink, useNavigate } from 'react-router-dom'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useAuthStore } from '@/store/authStore'
|
||||
import { apiClient } from '@/services/api'
|
||||
import { apiClientV2 } from '@/services/apiV2'
|
||||
import {
|
||||
Upload,
|
||||
@@ -29,12 +28,7 @@ export default function Layout() {
|
||||
|
||||
const handleLogout = async () => {
|
||||
try {
|
||||
// Use V2 API if authenticated with V2
|
||||
if (apiClientV2.isAuthenticated()) {
|
||||
await apiClientV2.logout()
|
||||
} else {
|
||||
apiClient.logout()
|
||||
}
|
||||
await apiClientV2.logout()
|
||||
} catch (error) {
|
||||
console.error('Logout error:', error)
|
||||
} finally {
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
|
||||
interface MarkdownPreviewProps {
|
||||
title?: string
|
||||
content: string
|
||||
className?: string
|
||||
}
|
||||
|
||||
export default function MarkdownPreview({ title, content, className }: MarkdownPreviewProps) {
|
||||
return (
|
||||
<Card className={className}>
|
||||
{title && (
|
||||
<CardHeader>
|
||||
<CardTitle>{title}</CardTitle>
|
||||
</CardHeader>
|
||||
)}
|
||||
<CardContent>
|
||||
<div className="prose prose-sm max-w-none dark:prose-invert">
|
||||
<pre className="whitespace-pre-wrap break-words bg-muted p-4 rounded-md overflow-auto max-h-[600px]">
|
||||
{content}
|
||||
</pre>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import type { FileResult } from '@/types/apiV2'
|
||||
|
||||
interface ResultsTableProps {
|
||||
files: FileResult[]
|
||||
onViewResult?: (fileId: number) => void
|
||||
onDownloadPDF?: (fileId: number) => void
|
||||
}
|
||||
|
||||
export default function ResultsTable({ files, onViewResult, onDownloadPDF }: ResultsTableProps) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const getStatusBadge = (status: FileResult['status']) => {
|
||||
switch (status) {
|
||||
case 'completed':
|
||||
return <Badge variant="success">{t('processing.completed')}</Badge>
|
||||
case 'processing':
|
||||
return <Badge variant="default">{t('processing.processing')}</Badge>
|
||||
case 'failed':
|
||||
return <Badge variant="destructive">{t('processing.failed')}</Badge>
|
||||
default:
|
||||
return <Badge variant="secondary">{t('processing.pending')}</Badge>
|
||||
}
|
||||
}
|
||||
|
||||
const formatTime = (seconds?: number) => {
|
||||
if (!seconds) return 'N/A'
|
||||
return `${seconds.toFixed(2)}s`
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="rounded-md border">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>{t('results.filename')}</TableHead>
|
||||
<TableHead>{t('results.status')}</TableHead>
|
||||
<TableHead>{t('results.processingTime')}</TableHead>
|
||||
<TableHead className="text-right">{t('results.actions')}</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{files.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={4} className="text-center text-muted-foreground">
|
||||
{t('results.noResults')}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
files.map((file) => (
|
||||
<TableRow key={file.id}>
|
||||
<TableCell className="font-medium">{file.filename}</TableCell>
|
||||
<TableCell>{getStatusBadge(file.status)}</TableCell>
|
||||
<TableCell>{formatTime(file.processing_time)}</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<div className="flex justify-end gap-2">
|
||||
{file.status === 'completed' && (
|
||||
<>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => onViewResult?.(file.id)}
|
||||
>
|
||||
{t('results.viewMarkdown')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => onDownloadPDF?.(file.id)}
|
||||
>
|
||||
{t('results.downloadPDF')}
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{file.status === 'failed' && file.error && (
|
||||
<span className="text-sm text-destructive">{file.error}</span>
|
||||
)}
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user