- Node.js backend server - Frontend application - Backup script - Project specification Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
62 lines
2.2 KiB
JavaScript
62 lines
2.2 KiB
JavaScript
import { createContext, useCallback, useContext, useMemo, useState } from 'react';
|
|
import { Icon } from './icons';
|
|
|
|
const ConfirmContext = createContext(null);
|
|
|
|
export function ConfirmProvider({ children }) {
|
|
const [dialog, setDialog] = useState(null);
|
|
|
|
const confirm = useCallback((options) => {
|
|
return new Promise((resolve) => {
|
|
setDialog({
|
|
title: options.title || '请确认操作',
|
|
description: options.description || '',
|
|
confirmText: options.confirmText || '确认',
|
|
cancelText: options.cancelText || '取消',
|
|
tone: options.tone || 'danger',
|
|
resolve,
|
|
});
|
|
});
|
|
}, []);
|
|
|
|
const close = useCallback((result) => {
|
|
setDialog((current) => {
|
|
current?.resolve(result);
|
|
return null;
|
|
});
|
|
}, []);
|
|
|
|
const value = useMemo(() => ({ confirm }), [confirm]);
|
|
|
|
return (
|
|
<ConfirmContext.Provider value={value}>
|
|
{children}
|
|
{dialog ? (
|
|
<div className="modal-overlay modal-overlay--center" onClick={() => close(false)}>
|
|
<div className="confirm-card" onClick={(event) => event.stopPropagation()} role="dialog" aria-modal="true" aria-labelledby="confirm-title">
|
|
<div className={`confirm-card__icon confirm-card__icon--${dialog.tone}`}>
|
|
<Icon name={dialog.tone === 'danger' ? 'trash' : 'info'} size={18} />
|
|
</div>
|
|
<div className="confirm-card__body">
|
|
<h2 id="confirm-title">{dialog.title}</h2>
|
|
{dialog.description ? <p>{dialog.description}</p> : null}
|
|
</div>
|
|
<div className="confirm-card__actions">
|
|
<button type="button" className="btn btn-secondary" onClick={() => close(false)}>{dialog.cancelText}</button>
|
|
<button type="button" className={`btn ${dialog.tone === 'danger' ? 'btn-danger' : 'btn-primary'}`} onClick={() => close(true)}>{dialog.confirmText}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
) : null}
|
|
</ConfirmContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useConfirm() {
|
|
const context = useContext(ConfirmContext);
|
|
if (!context) {
|
|
throw new Error('useConfirm must be used within ConfirmProvider');
|
|
}
|
|
return context;
|
|
}
|