fix: resolve React Error #310 and refactor admin section
Some checks failed
Deploy to Production / Build and Deploy (push) Has been cancelled

- Fix React bug #33580: remove Suspense boundaries co-located with Link components
- Delete settings/loading.tsx and admin/loading.tsx (root cause of race condition)
- Convert all admin navigation from Next.js Link to anchor tags
- Move admin pages to dedicated (admin) route group
- Add AdminHeader matching main header visual design
- Add AdminSidebar with anchor-based navigation
- Add /api/admin/models route handler (replaces server actions for GET)
- Add /api/debug/client-error for server-side browser error reporting
- Add useNoteRefreshOptional() to fix crash in AdminHeader
- Hide Admin Dashboard menu for non-admin users
- Change app icons from yellow to blue (#3A7CA5) matching brand primary
- Fix admin search bar width to match main header

Made-with: Cursor
This commit is contained in:
2026-04-25 20:46:10 +02:00
parent 1d53c16cc2
commit 986d438738
49 changed files with 1277 additions and 358 deletions

View File

@@ -0,0 +1,101 @@
'use client'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { ArrowLeft, TestTube } from 'lucide-react'
import { AI_TESTER } from './ai-tester'
import { useLanguage } from '@/lib/i18n'
export default function AITestPage() {
const { t } = useLanguage()
return (
<div className="container mx-auto py-10 px-4 max-w-6xl">
<div className="flex justify-between items-center mb-8">
<div className="flex items-center gap-3">
<a href="/admin/settings">
<Button variant="outline" size="icon">
<ArrowLeft className="h-4 w-4" />
</Button>
</a>
<div>
<h1 className="text-3xl font-bold flex items-center gap-2">
<TestTube className="h-8 w-8" />
{t('admin.aiTest.title')}
</h1>
<p className="text-muted-foreground mt-1">
{t('admin.aiTest.description')}
</p>
</div>
</div>
</div>
<div className="grid gap-6 md:grid-cols-2">
{/* Tags Provider Test */}
<Card className="border-primary/20 dark:border-primary/30">
<CardHeader className="bg-primary/5 dark:bg-primary/10">
<CardTitle className="flex items-center gap-2">
<span className="text-2xl">🏷</span>
{t('admin.aiTest.tagsTestTitle')}
</CardTitle>
<CardDescription>
{t('admin.aiTest.tagsTestDescription')}
</CardDescription>
</CardHeader>
<CardContent className="pt-6">
<AI_TESTER type="tags" />
</CardContent>
</Card>
{/* Embeddings Provider Test */}
<Card className="border-green-200 dark:border-green-900">
<CardHeader className="bg-green-50/50 dark:bg-green-950/20">
<CardTitle className="flex items-center gap-2">
<span className="text-2xl">🔍</span>
{t('admin.aiTest.embeddingsTestTitle')}
</CardTitle>
<CardDescription>
{t('admin.aiTest.embeddingsTestDescription')}
</CardDescription>
</CardHeader>
<CardContent className="pt-6">
<AI_TESTER type="embeddings" />
</CardContent>
</Card>
</div>
{/* Info Section */}
<Card className="mt-6">
<CardHeader>
<CardTitle> {t('admin.aiTest.howItWorksTitle')}</CardTitle>
</CardHeader>
<CardContent className="space-y-4 text-sm">
<div>
<h4 className="font-semibold mb-2">{t('admin.aiTest.tagsGenerationTest')}</h4>
<ul className="list-disc list-inside space-y-1 text-muted-foreground">
<li>{t('admin.aiTest.tagsStep1')}</li>
<li>{t('admin.aiTest.tagsStep2')}</li>
<li>{t('admin.aiTest.tagsStep3')}</li>
<li>{t('admin.aiTest.tagsStep4')}</li>
</ul>
</div>
<div>
<h4 className="font-semibold mb-2">{t('admin.aiTest.embeddingsTestLabel')}</h4>
<ul className="list-disc list-inside space-y-1 text-muted-foreground">
<li>{t('admin.aiTest.embeddingsStep1')}</li>
<li>{t('admin.aiTest.embeddingsStep2')}</li>
<li>{t('admin.aiTest.embeddingsStep3')}</li>
<li>{t('admin.aiTest.embeddingsStep4')}</li>
</ul>
</div>
<div className="bg-amber-50 dark:bg-amber-950/20 p-4 rounded-lg border border-amber-200 dark:border-amber-900">
<p className="font-semibold text-amber-900 dark:text-amber-100">💡 {t('admin.aiTest.tipTitle')}</p>
<p className="text-amber-800 dark:text-amber-200 mt-1">
{t('admin.aiTest.tipContent')}
</p>
</div>
</CardContent>
</Card>
</div>
)
}