- 新增批量导出功能,支持text模式导出账户数据 - 添加导出弹窗,支持文本全选和文件下载 - 移动刷新按钮到全局位置,统一刷新账户和统计数据 - 在统计卡片中将已导出状态计入可用账户 - 创建自定义确认对话框替换系统confirm弹窗 - 统一按钮尺寸,修复刷新和上传按钮大小不一致 - 添加已导出状态的中文映射和样式 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			127 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| "use client";
 | |
| 
 | |
| import { useState, useEffect } from 'react';
 | |
| import { Button } from '@/components/ui/button';
 | |
| import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
 | |
| import { AlertTriangle } from 'lucide-react';
 | |
| 
 | |
| interface ConfirmDialogProps {
 | |
|   open: boolean;
 | |
|   onOpenChange: (open: boolean) => void;
 | |
|   title: string;
 | |
|   description: string;
 | |
|   confirmText?: string;
 | |
|   cancelText?: string;
 | |
|   variant?: 'default' | 'destructive';
 | |
|   onConfirm: () => void;
 | |
|   onCancel?: () => void;
 | |
| }
 | |
| 
 | |
| export function ConfirmDialog({
 | |
|   open,
 | |
|   onOpenChange,
 | |
|   title,
 | |
|   description,
 | |
|   confirmText = '确认',
 | |
|   cancelText = '取消',
 | |
|   variant = 'default',
 | |
|   onConfirm,
 | |
|   onCancel
 | |
| }: ConfirmDialogProps) {
 | |
|   const handleConfirm = () => {
 | |
|     onConfirm();
 | |
|     onOpenChange(false);
 | |
|   };
 | |
| 
 | |
|   const handleCancel = () => {
 | |
|     onCancel?.();
 | |
|     onOpenChange(false);
 | |
|   };
 | |
| 
 | |
|   return (
 | |
|     <Dialog open={open} onOpenChange={onOpenChange}>
 | |
|       <DialogContent className="sm:max-w-[425px]">
 | |
|         <DialogHeader>
 | |
|           <DialogTitle className="flex items-center gap-2">
 | |
|             {variant === 'destructive' && (
 | |
|               <AlertTriangle className="h-5 w-5 text-destructive" />
 | |
|             )}
 | |
|             {title}
 | |
|           </DialogTitle>
 | |
|           <DialogDescription>
 | |
|             {description}
 | |
|           </DialogDescription>
 | |
|         </DialogHeader>
 | |
|         <DialogFooter>
 | |
|           <Button variant="outline" onClick={handleCancel}>
 | |
|             {cancelText}
 | |
|           </Button>
 | |
|           <Button 
 | |
|             variant={variant === 'destructive' ? 'destructive' : 'default'}
 | |
|             onClick={handleConfirm}
 | |
|           >
 | |
|             {confirmText}
 | |
|           </Button>
 | |
|         </DialogFooter>
 | |
|       </DialogContent>
 | |
|     </Dialog>
 | |
|   );
 | |
| }
 | |
| 
 | |
| // Hook for easier usage
 | |
| export function useConfirmDialog() {
 | |
|   const [confirmDialog, setConfirmDialog] = useState<{
 | |
|     open: boolean;
 | |
|     title: string;
 | |
|     description: string;
 | |
|     confirmText?: string;
 | |
|     cancelText?: string;
 | |
|     variant?: 'default' | 'destructive';
 | |
|     onConfirm: () => void;
 | |
|     onCancel?: () => void;
 | |
|   }>({
 | |
|     open: false,
 | |
|     title: '',
 | |
|     description: '',
 | |
|     onConfirm: () => {}
 | |
|   });
 | |
| 
 | |
|   const showConfirm = (options: {
 | |
|     title: string;
 | |
|     description: string;
 | |
|     confirmText?: string;
 | |
|     cancelText?: string;
 | |
|     variant?: 'default' | 'destructive';
 | |
|     onConfirm: () => void;
 | |
|     onCancel?: () => void;
 | |
|   }) => {
 | |
|     setConfirmDialog({
 | |
|       ...options,
 | |
|       open: true
 | |
|     });
 | |
|   };
 | |
| 
 | |
|   const hideConfirm = () => {
 | |
|     setConfirmDialog(prev => ({ ...prev, open: false }));
 | |
|   };
 | |
| 
 | |
|   const ConfirmDialogComponent = () => (
 | |
|     <ConfirmDialog
 | |
|       open={confirmDialog.open}
 | |
|       onOpenChange={hideConfirm}
 | |
|       title={confirmDialog.title}
 | |
|       description={confirmDialog.description}
 | |
|       confirmText={confirmDialog.confirmText}
 | |
|       cancelText={confirmDialog.cancelText}
 | |
|       variant={confirmDialog.variant}
 | |
|       onConfirm={confirmDialog.onConfirm}
 | |
|       onCancel={confirmDialog.onCancel}
 | |
|     />
 | |
|   );
 | |
| 
 | |
|   return {
 | |
|     showConfirm,
 | |
|     hideConfirm,
 | |
|     ConfirmDialogComponent
 | |
|   };
 | |
| } |