Files
natreex 7f34421212 Add error handling, enhance syncing, and refactor deletion logic
- Introduce new error messages for syncing and book deletion in `en.json`.
- Update `DeleteBook` to support local-only deletion and synced book management.
- Refine offline/online behavior with `deleteLocalToo` checkbox and update related state handling.
- Extend repository and IPC methods to handle optional IDs for updates.
- Add `SyncQueueContext` for queueing offline changes and improving synchronization workflows.
- Enhance refined text generation logic in `DraftCompanion` and `GhostWriter` components.
- Replace PUT with PATCH for world updates to align with API expectations.
- Streamline `AlertBox` by integrating dynamic translation keys for deletion prompts.
2026-01-10 15:50:03 -05:00

106 lines
3.8 KiB
TypeScript

import {useEffect, useState} from 'react';
import {createPortal} from 'react-dom';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faCheck, faExclamationTriangle, faInfoCircle, faTimes} from '@fortawesome/free-solid-svg-icons';
import ConfirmButton from "@/components/form/ConfirmButton";
import CancelButton from "@/components/form/CancelButton";
export type AlertType = 'alert' | 'danger' | 'informatif' | 'success';
interface AlertBoxProps {
title: string;
message: string;
type: AlertType;
confirmText?: string;
cancelText?: string;
onConfirm: () => Promise<void>;
onCancel: () => void;
children?: React.ReactNode;
}
export default function AlertBox(
{
title,
message,
type,
confirmText = 'Confirmer',
cancelText = 'Annuler',
onConfirm,
onCancel,
children
}: AlertBoxProps) {
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
return () => setMounted(false);
}, []);
function getAlertConfig(alertType: AlertType) {
switch (alertType) {
case 'alert':
return {
background: 'bg-warning',
borderColor: 'border-warning/30',
icon: faExclamationTriangle,
iconBg: 'bg-warning/10'
};
case 'danger':
return {
background: 'bg-error',
borderColor: 'border-error/30',
icon: faTimes,
iconBg: 'bg-error/10'
};
case 'informatif':
return {
background: 'bg-info',
borderColor: 'border-info/30',
icon: faInfoCircle,
iconBg: 'bg-info/10'
};
case 'success':
default:
return {
background: 'bg-success',
borderColor: 'border-success/30',
icon: faCheck,
iconBg: 'bg-success/10'
};
}
}
const alertSettings = getAlertConfig(type);
const alertContent = (
<div
className="fixed inset-0 z-[9999] flex items-center justify-center p-4 bg-black/60 backdrop-blur-md animate-fadeIn">
<div
className="relative w-full max-w-md rounded-2xl bg-tertiary shadow-2xl border border-secondary/50 overflow-hidden">
<div className={`${alertSettings.background} px-6 py-4 shadow-lg`}>
<div className="flex items-center gap-4">
<div
className={`w-12 h-12 rounded-xl ${alertSettings.iconBg} flex items-center justify-center`}>
<FontAwesomeIcon icon={alertSettings.icon} className="w-6 h-6 text-white"/>
</div>
<h3 className="text-xl font-bold text-white tracking-wide">{title}</h3>
</div>
</div>
<div className="p-6 bg-dark-background/30">
<p className="text-text-primary whitespace-pre-line leading-relaxed">{message}</p>
{children}
<div className="flex justify-end gap-3 mt-6">
<CancelButton callBackFunction={onCancel} text={cancelText}/>
<ConfirmButton text={confirmText} buttonType={type} callBackFunction={onConfirm}/>
</div>
</div>
</div>
</div>
);
if (!mounted) return null;
return createPortal(alertContent, document.body);
}