Add components for Act management and integrate Electron setup
This commit is contained in:
91
components/Modal.tsx
Normal file
91
components/Modal.tsx
Normal file
@@ -0,0 +1,91 @@
|
||||
import React, {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);
|
||||
}
|
||||
Reference in New Issue
Block a user