395 lines
18 KiB
TypeScript
395 lines
18 KiB
TypeScript
"use client";
|
||
|
||
import { useState, useEffect } from "react";
|
||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||
import { Button } from "@/components/ui/button";
|
||
import { Label } from "@/components/ui/label";
|
||
import { Badge } from "@/components/ui/badge";
|
||
import { useTranslationStore } from "@/lib/store";
|
||
import { languages } from "@/lib/api";
|
||
import { Save, Loader2, Settings, Globe, Trash2, ArrowRight, Shield, Zap, Database } from "lucide-react";
|
||
import {
|
||
Select,
|
||
SelectContent,
|
||
SelectItem,
|
||
SelectTrigger,
|
||
SelectValue,
|
||
} from "@/components/ui/select";
|
||
import Link from "next/link";
|
||
|
||
export default function GeneralSettingsPage() {
|
||
const { settings, updateSettings } = useTranslationStore();
|
||
const [isSaving, setIsSaving] = useState(false);
|
||
const [isClearing, setIsClearing] = useState(false);
|
||
const [defaultLanguage, setDefaultLanguage] = useState(settings.defaultTargetLanguage);
|
||
|
||
useEffect(() => {
|
||
setDefaultLanguage(settings.defaultTargetLanguage);
|
||
}, [settings.defaultTargetLanguage]);
|
||
|
||
const handleSave = async () => {
|
||
setIsSaving(true);
|
||
try {
|
||
updateSettings({ defaultTargetLanguage: defaultLanguage });
|
||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||
} finally {
|
||
setIsSaving(false);
|
||
}
|
||
};
|
||
|
||
const handleClearCache = async () => {
|
||
setIsClearing(true);
|
||
try {
|
||
// Clear localStorage
|
||
localStorage.removeItem('translation-settings');
|
||
// Clear sessionStorage
|
||
sessionStorage.clear();
|
||
// Clear any cached files/blobs
|
||
if ('caches' in window) {
|
||
const cacheNames = await caches.keys();
|
||
await Promise.all(cacheNames.map(name => caches.delete(name)));
|
||
}
|
||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||
// Reload to reset state
|
||
window.location.reload();
|
||
} catch (error) {
|
||
console.error('Error clearing cache:', error);
|
||
setIsClearing(false);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<div className="min-h-screen bg-gradient-to-b from-surface via-surface-elevated to-background">
|
||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||
{/* Header */}
|
||
<div className="mb-8">
|
||
<Badge variant="outline" className="mb-4 border-primary/30 text-primary bg-primary/10">
|
||
<Settings className="h-3 w-3 mr-1" />
|
||
Settings
|
||
</Badge>
|
||
<h1 className="text-4xl font-bold text-white mb-2">
|
||
General Settings
|
||
</h1>
|
||
<p className="text-lg text-text-secondary">
|
||
Configure general application settings and preferences
|
||
</p>
|
||
</div>
|
||
|
||
{/* Quick Actions */}
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
|
||
<Card variant="elevated" className="group hover:scale-105 transition-all duration-300 animate-fade-in-up">
|
||
<Link href="/settings/services" className="block">
|
||
<CardContent className="p-6">
|
||
<div className="flex items-center gap-4 mb-4">
|
||
<div className="p-3 rounded-xl bg-primary/20 group-hover:bg-primary/30 transition-colors duration-300">
|
||
<Zap className="h-6 w-6 text-primary" />
|
||
</div>
|
||
<div>
|
||
<h3 className="text-lg font-semibold text-white group-hover:text-primary transition-colors duration-300">
|
||
Translation Services
|
||
</h3>
|
||
<p className="text-sm text-text-tertiary">Configure providers</p>
|
||
</div>
|
||
</div>
|
||
<div className="flex items-center text-primary">
|
||
<span className="text-sm font-medium">Manage providers</span>
|
||
<ArrowRight className="h-4 w-4 ml-2 transition-transform duration-200 group-hover:translate-x-1" />
|
||
</div>
|
||
</CardContent>
|
||
</Link>
|
||
</Card>
|
||
|
||
<Card variant="elevated" className="group hover:scale-105 transition-all duration-300 animate-fade-in-up animation-delay-100">
|
||
<Link href="/settings/context" className="block">
|
||
<CardContent className="p-6">
|
||
<div className="flex items-center gap-4 mb-4">
|
||
<div className="p-3 rounded-xl bg-accent/20 group-hover:bg-accent/30 transition-colors duration-300">
|
||
<Globe className="h-6 w-6 text-accent" />
|
||
</div>
|
||
<div>
|
||
<h3 className="text-lg font-semibold text-white group-hover:text-accent transition-colors duration-300">
|
||
Context & Glossary
|
||
</h3>
|
||
<p className="text-sm text-text-tertiary">Domain-specific settings</p>
|
||
</div>
|
||
</div>
|
||
<div className="flex items-center text-accent">
|
||
<span className="text-sm font-medium">Configure context</span>
|
||
<ArrowRight className="h-4 w-4 ml-2 transition-transform duration-200 group-hover:translate-x-1" />
|
||
</div>
|
||
</CardContent>
|
||
</Link>
|
||
</Card>
|
||
|
||
<Card variant="elevated" className="group hover:scale-105 transition-all duration-300 animate-fade-in-up animation-delay-200">
|
||
<CardContent className="p-6">
|
||
<div className="flex items-center gap-4 mb-4">
|
||
<div className="p-3 rounded-xl bg-success/20 group-hover:bg-success/30 transition-colors duration-300">
|
||
<Shield className="h-6 w-6 text-success" />
|
||
</div>
|
||
<div>
|
||
<h3 className="text-lg font-semibold text-white group-hover:text-success transition-colors duration-300">
|
||
Privacy & Security
|
||
</h3>
|
||
<p className="text-sm text-text-tertiary">Data protection</p>
|
||
</div>
|
||
</div>
|
||
<div className="flex items-center text-success">
|
||
<span className="text-sm font-medium">Coming soon</span>
|
||
<ArrowRight className="h-4 w-4 ml-2 transition-transform duration-200 group-hover:translate-x-1" />
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
|
||
{/* Application Settings */}
|
||
<Card variant="elevated" className="mb-8 animate-fade-in-up animation-delay-300">
|
||
<CardHeader>
|
||
<div className="flex items-center gap-3">
|
||
<div className="p-2 rounded-lg bg-primary/20">
|
||
<Settings className="h-5 w-5 text-primary" />
|
||
</div>
|
||
<div>
|
||
<CardTitle className="text-white">Application Settings</CardTitle>
|
||
<CardDescription>
|
||
General configuration options
|
||
</CardDescription>
|
||
</div>
|
||
</div>
|
||
</CardHeader>
|
||
<CardContent className="space-y-6">
|
||
<div className="space-y-3">
|
||
<Label htmlFor="default-language" className="text-text-secondary font-medium">
|
||
Default Target Language
|
||
</Label>
|
||
<Select value={defaultLanguage} onValueChange={setDefaultLanguage}>
|
||
<SelectTrigger className="bg-surface border-border-subtle text-white focus:border-primary focus:ring-primary/20">
|
||
<SelectValue placeholder="Select default language" />
|
||
</SelectTrigger>
|
||
<SelectContent className="bg-surface-elevated border-border-subtle max-h-[300px]">
|
||
{languages.map((lang) => (
|
||
<SelectItem
|
||
key={lang.code}
|
||
value={lang.code}
|
||
className="text-white hover:bg-surface-hover focus:bg-primary/20 focus:text-primary"
|
||
>
|
||
<span className="flex items-center gap-2">
|
||
<span>{lang.flag}</span>
|
||
<span>{lang.name}</span>
|
||
</span>
|
||
</SelectItem>
|
||
))}
|
||
</SelectContent>
|
||
</Select>
|
||
<p className="text-sm text-text-tertiary">
|
||
This language will be pre-selected when translating documents
|
||
</p>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
{/* Supported Formats */}
|
||
<Card variant="elevated" className="mb-8 animate-fade-in-up animation-delay-400">
|
||
<CardHeader>
|
||
<div className="flex items-center gap-3">
|
||
<div className="p-2 rounded-lg bg-accent/20">
|
||
<Globe className="h-5 w-5 text-accent" />
|
||
</div>
|
||
<div>
|
||
<CardTitle className="text-white">Supported Formats</CardTitle>
|
||
<CardDescription>
|
||
Document types that can be translated
|
||
</CardDescription>
|
||
</div>
|
||
</div>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||
<Card variant="glass" className="group hover:scale-105 transition-all duration-300">
|
||
<CardContent className="p-6 text-center">
|
||
<div className="text-4xl mb-3 group-hover:scale-110 transition-transform duration-300">📊</div>
|
||
<h3 className="font-semibold text-white mb-2">Excel</h3>
|
||
<p className="text-sm text-text-tertiary mb-4">.xlsx, .xls</p>
|
||
<div className="flex flex-wrap gap-2 justify-center">
|
||
<Badge variant="outline" className="border-success/50 text-success bg-success/10 text-xs">
|
||
Formulas
|
||
</Badge>
|
||
<Badge variant="outline" className="border-primary/50 text-primary bg-primary/10 text-xs">
|
||
Styles
|
||
</Badge>
|
||
<Badge variant="outline" className="border-accent/50 text-accent bg-accent/10 text-xs">
|
||
Images
|
||
</Badge>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
<Card variant="glass" className="group hover:scale-105 transition-all duration-300">
|
||
<CardContent className="p-6 text-center">
|
||
<div className="text-4xl mb-3 group-hover:scale-110 transition-transform duration-300">📝</div>
|
||
<h3 className="font-semibold text-white mb-2">Word</h3>
|
||
<p className="text-sm text-text-tertiary mb-4">.docx, .doc</p>
|
||
<div className="flex flex-wrap gap-2 justify-center">
|
||
<Badge variant="outline" className="border-success/50 text-success bg-success/10 text-xs">
|
||
Headers
|
||
</Badge>
|
||
<Badge variant="outline" className="border-primary/50 text-primary bg-primary/10 text-xs">
|
||
Tables
|
||
</Badge>
|
||
<Badge variant="outline" className="border-accent/50 text-accent bg-accent/10 text-xs">
|
||
Images
|
||
</Badge>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
<Card variant="glass" className="group hover:scale-105 transition-all duration-300">
|
||
<CardContent className="p-6 text-center">
|
||
<div className="text-4xl mb-3 group-hover:scale-110 transition-transform duration-300">📽️</div>
|
||
<h3 className="font-semibold text-white mb-2">PowerPoint</h3>
|
||
<p className="text-sm text-text-tertiary mb-4">.pptx, .ppt</p>
|
||
<div className="flex flex-wrap gap-2 justify-center">
|
||
<Badge variant="outline" className="border-success/50 text-success bg-success/10 text-xs">
|
||
Slides
|
||
</Badge>
|
||
<Badge variant="outline" className="border-primary/50 text-primary bg-primary/10 text-xs">
|
||
Notes
|
||
</Badge>
|
||
<Badge variant="outline" className="border-accent/50 text-accent bg-accent/10 text-xs">
|
||
Images
|
||
</Badge>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
{/* System Information */}
|
||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
|
||
<Card variant="elevated" className="animate-fade-in-up animation-delay-500">
|
||
<CardHeader>
|
||
<div className="flex items-center gap-3">
|
||
<div className="p-2 rounded-lg bg-success/20">
|
||
<Database className="h-5 w-5 text-success" />
|
||
</div>
|
||
<div>
|
||
<CardTitle className="text-white">API Information</CardTitle>
|
||
<CardDescription>
|
||
Backend server connection details
|
||
</CardDescription>
|
||
</div>
|
||
</div>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<div className="space-y-3">
|
||
<div className="flex items-center justify-between p-3 rounded-lg bg-surface/50 hover:bg-surface transition-colors duration-200">
|
||
<span className="text-text-tertiary">API Endpoint</span>
|
||
<code className="text-primary text-sm font-mono bg-surface px-2 py-1 rounded">http://localhost:8000</code>
|
||
</div>
|
||
<div className="flex items-center justify-between p-3 rounded-lg bg-surface/50 hover:bg-surface transition-colors duration-200">
|
||
<span className="text-text-tertiary">Health Check</span>
|
||
<code className="text-primary text-sm font-mono bg-surface px-2 py-1 rounded">/health</code>
|
||
</div>
|
||
<div className="flex items-center justify-between p-3 rounded-lg bg-surface/50 hover:bg-surface transition-colors duration-200">
|
||
<span className="text-text-tertiary">Translate Endpoint</span>
|
||
<code className="text-primary text-sm font-mono bg-surface px-2 py-1 rounded">/translate</code>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
|
||
<Card variant="elevated" className="animate-fade-in-up animation-delay-600">
|
||
<CardHeader>
|
||
<div className="flex items-center gap-3">
|
||
<div className="p-2 rounded-lg bg-warning/20">
|
||
<Shield className="h-5 w-5 text-warning" />
|
||
</div>
|
||
<div>
|
||
<CardTitle className="text-white">System Status</CardTitle>
|
||
<CardDescription>
|
||
Application health and performance
|
||
</CardDescription>
|
||
</div>
|
||
</div>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<div className="space-y-3">
|
||
<div className="flex items-center justify-between p-3 rounded-lg bg-surface/50">
|
||
<span className="text-text-tertiary">Connection Status</span>
|
||
<Badge variant="outline" className="border-success/50 text-success bg-success/10">
|
||
<div className="w-2 h-2 bg-success rounded-full mr-2 animate-pulse"></div>
|
||
Connected
|
||
</Badge>
|
||
</div>
|
||
<div className="flex items-center justify-between p-3 rounded-lg bg-surface/50">
|
||
<span className="text-text-tertiary">Last Sync</span>
|
||
<span className="text-sm text-text-secondary">Just now</span>
|
||
</div>
|
||
<div className="flex items-center justify-between p-3 rounded-lg bg-surface/50">
|
||
<span className="text-text-tertiary">Version</span>
|
||
<span className="text-sm text-text-secondary">v2.0.0</span>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
|
||
{/* Action Buttons */}
|
||
<div className="flex flex-col sm:flex-row gap-4 justify-between items-start sm:items-center animate-fade-in-up animation-delay-700">
|
||
<div className="space-y-2">
|
||
<p className="text-sm text-text-tertiary">
|
||
Need help with settings? Check our documentation.
|
||
</p>
|
||
<Button variant="glass" size="sm" className="group">
|
||
<Settings className="h-4 w-4 mr-2 transition-transform duration-200 group-hover:rotate-90" />
|
||
View Documentation
|
||
<ArrowRight className="h-4 w-4 ml-2 transition-transform duration-200 group-hover:translate-x-1" />
|
||
</Button>
|
||
</div>
|
||
|
||
<div className="flex gap-3">
|
||
<Button
|
||
onClick={handleClearCache}
|
||
disabled={isClearing}
|
||
variant="outline"
|
||
size="lg"
|
||
className="border-destructive/50 text-destructive hover:bg-destructive/10 hover:border-destructive group"
|
||
>
|
||
{isClearing ? (
|
||
<>
|
||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||
Clearing...
|
||
</>
|
||
) : (
|
||
<>
|
||
<Trash2 className="mr-2 h-4 w-4 transition-transform duration-200 group-hover:scale-110" />
|
||
Clear Cache
|
||
</>
|
||
)}
|
||
</Button>
|
||
<Button
|
||
onClick={handleSave}
|
||
disabled={isSaving}
|
||
size="lg"
|
||
className="bg-gradient-to-r from-primary to-accent hover:from-primary/90 hover:to-accent/90 text-white group"
|
||
>
|
||
{isSaving ? (
|
||
<>
|
||
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
||
Saving...
|
||
</>
|
||
) : (
|
||
<>
|
||
<Save className="mr-2 h-4 w-4 transition-transform duration-200 group-hover:scale-110" />
|
||
Save Settings
|
||
</>
|
||
)}
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|