Vollständig lokalisierte Komponenten: - GeneralSettingsModal: Alle Tabs (General/GitHub/Auth), Settings, Messages - ConfirmationModal: Type-to-confirm Dialoge mit Fallback-Buttons - ErrorModal: Error/Success Modals mit Details Translation-Keys hinzugefügt: - de.ts & en.ts: settings.* (theme, filters, colorCoding, github, auth) - de.ts & en.ts: confirmationModal.* (typeToConfirm, placeholder) - de.ts & en.ts: errorModal.* (detailsLabel, errorDetailsLabel) Features: - useTranslation Hook mit values-Interpolation - Dynamische Button-Texte (Confirm/Cancel mit Fallback) - Mehrsprachige Fehlermeldungen und Erfolgs-Benachrichtigungen - Theme- und Language-Switching unterstützt Bestehende Lokalisierungen beibehalten: - Footer, CategorySidebar, FilterBar bereits lokalisiert
93 lines
2.8 KiB
TypeScript
93 lines
2.8 KiB
TypeScript
'use client';
|
|
|
|
import { useEffect } from 'react';
|
|
import { Button } from './ui/button';
|
|
import { AlertCircle, CheckCircle } from 'lucide-react';
|
|
import { useRegisterModal } from './modal/ModalStackProvider';
|
|
import { useTranslation } from '~/lib/i18n/useTranslation';
|
|
|
|
interface ErrorModalProps {
|
|
isOpen: boolean;
|
|
onClose: () => void;
|
|
title: string;
|
|
message: string;
|
|
details?: string;
|
|
type?: 'error' | 'success';
|
|
}
|
|
|
|
export function ErrorModal({
|
|
isOpen,
|
|
onClose,
|
|
title,
|
|
message,
|
|
details,
|
|
type = 'error'
|
|
}: ErrorModalProps) {
|
|
const { t } = useTranslation('errorModal');
|
|
const { t: tc } = useTranslation('common.actions');
|
|
useRegisterModal(isOpen, { id: 'error-modal', allowEscape: true, onClose });
|
|
// Auto-close after 10 seconds
|
|
useEffect(() => {
|
|
if (isOpen) {
|
|
const timer = setTimeout(() => {
|
|
onClose();
|
|
}, 10000);
|
|
return () => clearTimeout(timer);
|
|
}
|
|
}, [isOpen, onClose]);
|
|
|
|
if (!isOpen) return null;
|
|
|
|
return (
|
|
<div className="fixed inset-0 backdrop-blur-sm bg-black/50 flex items-center justify-center z-50 p-4">
|
|
<div className="bg-card rounded-lg shadow-xl max-w-lg w-full border border-border">
|
|
{/* Header */}
|
|
<div className="flex items-center justify-center p-6 border-b border-border">
|
|
<div className="flex items-center gap-3">
|
|
{type === 'success' ? (
|
|
<CheckCircle className="h-8 w-8 text-success" />
|
|
) : (
|
|
<AlertCircle className="h-8 w-8 text-error" />
|
|
)}
|
|
<h2 className="text-xl font-semibold text-foreground">{title}</h2>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Content */}
|
|
<div className="p-6">
|
|
<p className="text-sm text-foreground mb-4">{message}</p>
|
|
{details && (
|
|
<div className={`rounded-lg p-3 ${
|
|
type === 'success'
|
|
? 'bg-success/10 border border-success/20'
|
|
: 'bg-error/10 border border-error/20'
|
|
}`}>
|
|
<p className={`text-xs font-medium mb-1 ${
|
|
type === 'success'
|
|
? 'text-success-foreground'
|
|
: 'text-error-foreground'
|
|
}`}>
|
|
{type === 'success' ? t('detailsLabel') : t('errorDetailsLabel')}
|
|
</p>
|
|
<pre className={`text-xs whitespace-pre-wrap break-words ${
|
|
type === 'success'
|
|
? 'text-success/80'
|
|
: 'text-error/80'
|
|
}`}>
|
|
{details}
|
|
</pre>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Footer */}
|
|
<div className="flex justify-end gap-3 p-6 border-t border-border">
|
|
<Button variant="outline" onClick={onClose}>
|
|
{tc('close')}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|