Files
DeveloperandClaude Opus 4.6 3347a256b2 Initial commit: accountbook project
- Node.js backend server
- Frontend application
- Backup script
- Project specification

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 11:24:10 +08:00

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;
}