- Removed unnecessary React imports. - Adjusted package.json scripts for Electron integration. - Updated components to replace Next.js-specific imports with Electron-compatible alternatives. - Minor tsconfig.json changes for better compatibility.
92 lines
3.6 KiB
TypeScript
92 lines
3.6 KiB
TypeScript
import {ReactNode, useEffect, useState} from 'react';
|
|
import {createPortal} from 'react-dom';
|
|
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
|
import {faX} from "@fortawesome/free-solid-svg-icons";
|
|
|
|
interface ModalProps {
|
|
title: string;
|
|
children: ReactNode;
|
|
size: 'small' | 'medium' | 'large';
|
|
onClose: () => void;
|
|
onConfirm: () => void;
|
|
confirmText?: string;
|
|
cancelText?: string;
|
|
enableFooter?: boolean;
|
|
}
|
|
|
|
export default function Modal(
|
|
{
|
|
title,
|
|
children,
|
|
size,
|
|
onClose,
|
|
onConfirm,
|
|
confirmText = 'Confirm',
|
|
cancelText = 'Cancel',
|
|
enableFooter = true,
|
|
}: ModalProps) {
|
|
const [mounted, setMounted] = useState(false);
|
|
|
|
useEffect(() => {
|
|
setMounted(true);
|
|
return () => setMounted(false);
|
|
}, []);
|
|
|
|
function getSizeClasses(size: 'small' | 'medium' | 'large'): string {
|
|
switch (size) {
|
|
case 'small':
|
|
return 'w-1/4';
|
|
case 'medium':
|
|
return 'w-1/2';
|
|
case 'large':
|
|
return 'w-3/4';
|
|
default:
|
|
return 'w-1/2';
|
|
}
|
|
}
|
|
|
|
const modalContent = (
|
|
<div
|
|
className="fixed inset-0 z-40 flex items-center justify-center p-4 bg-black/60 backdrop-blur-md animate-fadeIn">
|
|
<div
|
|
className={`relative bg-tertiary text-text-primary rounded-2xl border border-secondary/50 shadow-2xl max-h-[90vh] overflow-hidden flex flex-col ${getSizeClasses(size)}`}>
|
|
<div
|
|
className="flex justify-between items-center bg-primary px-6 py-4 rounded-t-2xl shadow-lg border-b border-primary-dark">
|
|
<h2 className="font-['ADLaM_Display'] text-xl tracking-wide">{title}</h2>
|
|
<button
|
|
className="group text-white/80 hover:text-white p-2 rounded-lg hover:bg-white/10 transition-all hover:scale-110"
|
|
onClick={onClose}>
|
|
<FontAwesomeIcon icon={faX} className={'w-5 h-5 transition-transform group-hover:rotate-90'}/>
|
|
</button>
|
|
</div>
|
|
<div className="flex-1 overflow-auto">
|
|
{children}
|
|
</div>
|
|
{
|
|
enableFooter && (
|
|
<div
|
|
className="flex justify-end gap-3 px-6 py-4 border-t border-secondary/50 bg-dark-background/30">
|
|
<button
|
|
onClick={onClose}
|
|
className="px-5 py-2.5 rounded-lg bg-secondary/50 text-text-primary hover:bg-secondary border border-secondary/50 hover:border-primary/30 transition-all hover:shadow-md hover:scale-105"
|
|
>
|
|
{cancelText || 'Annuler'}
|
|
</button>
|
|
<button
|
|
onClick={onConfirm}
|
|
className="px-5 py-2.5 rounded-lg bg-primary text-text-primary hover:bg-primary-dark shadow-md hover:shadow-lg hover:shadow-primary/30 transition-all hover:scale-105"
|
|
>
|
|
{confirmText || 'Confirmer'}
|
|
</button>
|
|
</div>
|
|
)
|
|
}
|
|
</div>
|
|
</div>
|
|
);
|
|
|
|
if (!mounted) return null;
|
|
|
|
return createPortal(modalContent, document.body);
|
|
}
|