Files
office_translator/frontend/src/app/(app)/settings/page.tsx
2026-03-07 11:42:58 +01:00

395 lines
18 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"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>
);
}