Add foundational components and logic for migration, UI design, and input handling
- Introduced foundational UI components (`Badge`, `LockCard`, `SectionHeader`, `AvatarIcon`, etc.) for flexible layouts and consistent design. - Added migration support with the `MigrationModal` component and backend integration for exporting/importing data between Electron and Tauri. - Extended form components with `TextAreaInput`, `OrderInput`, `ToggleField`, and `ToolbarSelect` for improved input handling. - Updated `ScribeShell` with migration popup logic to prompt users for data migration. - Integrated `AlertStack` for better alert handling and notification management. - Enhanced Rust/Tauri services with migration command implementations. - Added translations and styles for new components.
This commit is contained in:
73
components/ui/StaticAlert.tsx
Normal file
73
components/ui/StaticAlert.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
'use client'
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {CheckCircle, AlertCircle, Info, AlertTriangle, X, LucideIcon} from 'lucide-react';
|
||||
|
||||
interface StaticAlertProps {
|
||||
type: 'success' | 'error' | 'info' | 'warning';
|
||||
message: string;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
const iconMap: Record<StaticAlertProps['type'], LucideIcon> = {
|
||||
success: CheckCircle,
|
||||
error: AlertCircle,
|
||||
info: Info,
|
||||
warning: AlertTriangle,
|
||||
};
|
||||
|
||||
const accentColorMap: Record<StaticAlertProps['type'], string> = {
|
||||
success: 'text-success border-l-success',
|
||||
error: 'text-error border-l-error',
|
||||
info: 'text-info border-l-info',
|
||||
warning: 'text-warning border-l-warning',
|
||||
};
|
||||
|
||||
export default function StaticAlert({type, message, onClose}: StaticAlertProps) {
|
||||
const [visible, setVisible] = useState<boolean>(false);
|
||||
const onCloseRef = React.useRef(onClose);
|
||||
|
||||
useEffect((): void => {
|
||||
onCloseRef.current = onClose;
|
||||
}, [onClose]);
|
||||
|
||||
useEffect((): (() => void) => {
|
||||
setVisible(true);
|
||||
const timer: ReturnType<typeof setTimeout> = setTimeout((): void => {
|
||||
setVisible(false);
|
||||
setTimeout((): void => onCloseRef.current(), 300);
|
||||
}, 4800);
|
||||
|
||||
return (): void => {
|
||||
clearTimeout(timer);
|
||||
};
|
||||
}, []);
|
||||
|
||||
function handleClose(): void {
|
||||
setVisible(false);
|
||||
setTimeout((): void => onCloseRef.current(), 300);
|
||||
}
|
||||
|
||||
const AlertIcon: LucideIcon = iconMap[type];
|
||||
const accentClasses: string = accentColorMap[type];
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`max-w-sm rounded-xl transition-all duration-300 ease-in-out transform ${
|
||||
visible ? 'translate-x-0 opacity-100' : 'translate-x-full opacity-0'
|
||||
} bg-darkest-background border-l-4 ${accentClasses}`}
|
||||
>
|
||||
<div className="px-4 py-3 flex items-center gap-3">
|
||||
<AlertIcon className="w-5 h-5 flex-shrink-0" strokeWidth={2}/>
|
||||
<span className="flex-grow text-text-primary text-sm font-medium">
|
||||
{typeof message === 'string' ? message : String(message ?? 'Une erreur est survenue')}
|
||||
</span>
|
||||
<button
|
||||
onClick={handleClose}
|
||||
className="text-muted hover:text-text-primary p-1 rounded-lg hover:bg-secondary transition-all duration-200 flex-shrink-0"
|
||||
>
|
||||
<X className="w-4 h-4" strokeWidth={2}/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user