-
Notifications
You must be signed in to change notification settings - Fork 62
Expand file tree
/
Copy pathExportButton.tsx
More file actions
122 lines (107 loc) · 2.92 KB
/
ExportButton.tsx
File metadata and controls
122 lines (107 loc) · 2.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import React, { useState } from 'react';
import {
Button,
Menu,
MenuItem,
ListItemIcon,
ListItemText,
Divider,
Box,
Typography
} from '@mui/material';
import { Download, FileText, Code } from 'lucide-react';
import toast from 'react-hot-toast';
import { exportToCSV, exportToJSON, generateFilename } from '../utils/exportUtils';
interface GitHubItem {
id: number;
title: string;
state: string;
created_at: string;
pull_request?: { merged_at: string | null };
repository_url: string;
html_url: string;
user?: { login: string };
labels?: Array<{ name: string }>;
}
interface ExportButtonProps {
data: GitHubItem[];
username: string;
type: 'issues' | 'prs' | 'all';
disabled?: boolean;
}
const ExportButton: React.FC<ExportButtonProps> = ({
data,
username,
type,
disabled = false
}) => {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
const handleExport = (format: 'csv' | 'json') => {
try {
const filename = generateFilename(username, type, format);
if (format === 'csv') {
exportToCSV(data, filename);
} else {
exportToJSON(data, filename);
}
toast.success(`Successfully exported ${data.length} items as ${format.toUpperCase()}`);
} catch (error) {
toast.error('Failed to export data. Please try again.');
console.error('Export error:', error);
}
handleClose();
};
return (
<Box>
<Button
variant="outlined"
startIcon={<Download size={16} />}
onClick={handleClick}
disabled={disabled || data.length === 0}
sx={{ minWidth: 120 }}
>
Export
</Button>
<Menu
anchorEl={anchorEl}
open={open}
onClose={handleClose}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
>
<MenuItem disabled sx={{ opacity: 0.7 }}>
<Typography variant="caption" color="text.secondary">
Export {data.length} items
</Typography>
</MenuItem>
<Divider />
<MenuItem onClick={() => handleExport('csv')}>
<ListItemIcon>
<FileText size={16} />
</ListItemIcon>
<ListItemText primary="CSV Format" secondary="Spreadsheet compatible" />
</MenuItem>
<MenuItem onClick={() => handleExport('json')}>
<ListItemIcon>
<Code size={16} />
</ListItemIcon>
<ListItemText primary="JSON Format" secondary="Developer friendly" />
</MenuItem>
</Menu>
</Box>
);
};
export default ExportButton;