|
| 1 | +import React, { useState } from 'react'; |
| 2 | + |
| 3 | +export default function ExportUsersPage() { |
| 4 | + const [error, setError] = useState<string | null>(null); |
| 5 | + |
| 6 | + const convertToCSV = (data: any[]) => { |
| 7 | + if (data.length === 0) return ''; |
| 8 | + |
| 9 | + const headers = Object.keys(data[0]).join(',') + '\n'; |
| 10 | + const rows = data |
| 11 | + .map((row) => |
| 12 | + Object.values(row) |
| 13 | + .map((value) => `"${value}"`) |
| 14 | + .join(',') |
| 15 | + ) |
| 16 | + .join('\n'); |
| 17 | + |
| 18 | + return headers + rows; |
| 19 | + }; |
| 20 | + |
| 21 | + const handleDownload = async () => { |
| 22 | + try { |
| 23 | + setError(null); |
| 24 | + const response = await fetch('/api/users'); |
| 25 | + |
| 26 | + if (!response.ok) { |
| 27 | + throw new Error(`Failed to fetch CSV: ${response.statusText}`); |
| 28 | + } |
| 29 | + |
| 30 | + const data = await response.json(); |
| 31 | + const csvData = convertToCSV(data); |
| 32 | + const blob = new Blob([csvData], { type: 'text/csv' }); |
| 33 | + const url = URL.createObjectURL(blob); |
| 34 | + const link = document.createElement('a'); |
| 35 | + link.href = url; |
| 36 | + link.download = 'users.csv'; |
| 37 | + document.body.appendChild(link); |
| 38 | + link.click(); |
| 39 | + document.body.removeChild(link); |
| 40 | + URL.revokeObjectURL(url); |
| 41 | + } catch (err) { |
| 42 | + console.error('Error downloading CSV:', err); |
| 43 | + setError('Failed to export users. Please try again.'); |
| 44 | + } |
| 45 | + }; |
| 46 | + |
| 47 | + return ( |
| 48 | + <div style={{ textAlign: 'center' }}> |
| 49 | + <button |
| 50 | + onClick={handleDownload} |
| 51 | + style={{ |
| 52 | + display: 'flex', |
| 53 | + alignItems: 'center', |
| 54 | + justifyContent: 'center', |
| 55 | + height: '46.36px', |
| 56 | + padding: '11.273px 15.031px', |
| 57 | + gap: '16px', |
| 58 | + backgroundColor: '#0468C1', |
| 59 | + color: '#FFFFFF', |
| 60 | + fontFamily: 'Poppins, sans-serif', |
| 61 | + fontSize: '16px', |
| 62 | + fontWeight: 600, |
| 63 | + border: '1px solid #D2D2D2', |
| 64 | + borderRadius: '7px', |
| 65 | + cursor: 'pointer', |
| 66 | + transition: 'background 0.2s ease-in-out, transform 0.1s', |
| 67 | + }} |
| 68 | + onMouseOver={(e) => (e.currentTarget.style.backgroundColor = '#0358A3')} |
| 69 | + onMouseOut={(e) => (e.currentTarget.style.backgroundColor = '#0468C1')} |
| 70 | + onMouseDown={(e) => (e.currentTarget.style.transform = 'scale(0.95)')} |
| 71 | + onMouseUp={(e) => (e.currentTarget.style.transform = 'scale(1)')} |
| 72 | + > |
| 73 | + <svg |
| 74 | + xmlns="http://www.w3.org/2000/svg" |
| 75 | + width="26" |
| 76 | + height="25" |
| 77 | + viewBox="0 0 26 25" |
| 78 | + fill="white" |
| 79 | + > |
| 80 | + <path |
| 81 | + fillRule="evenodd" |
| 82 | + clipRule="evenodd" |
| 83 | + d="M3.7443 14.583C4.3196 14.583 4.78597 15.0494 4.78597 15.6247V19.7913C4.78597 20.0676 4.89572 20.3326 5.09107 20.5279C5.28642 20.7233 5.55137 20.833 5.82764 20.833H20.411C20.6872 20.833 20.9522 20.7233 21.1475 20.5279C21.3429 20.3326 21.4526 20.0676 21.4526 19.7913V15.6247C21.4526 15.0494 21.919 14.583 22.4943 14.583C23.0696 14.583 23.536 15.0494 23.536 15.6247V19.7913C23.536 20.6201 23.2067 21.415 22.6207 22.001C22.0346 22.5871 21.2398 22.9163 20.411 22.9163H5.82764C4.99883 22.9163 4.20398 22.5871 3.61793 22.001C3.03188 21.415 2.70264 20.6201 2.70264 19.7913V15.6247C2.70264 15.0494 3.16901 14.583 3.7443 14.583Z" |
| 84 | + fill="white" |
| 85 | + /> |
| 86 | + <path |
| 87 | + fillRule="evenodd" |
| 88 | + clipRule="evenodd" |
| 89 | + d="M7.17448 9.6801C7.58128 9.2733 8.24082 9.2733 8.64762 9.6801L13.1194 14.1519L17.5911 9.6801C17.9979 9.2733 18.6575 9.2733 19.0643 9.6801C19.4711 10.0869 19.4711 10.7464 19.0643 11.1532L13.856 16.3616C13.4492 16.7684 12.7896 16.7684 12.3828 16.3616L7.17448 11.1532C6.76769 10.7464 6.76769 10.0869 7.17448 9.6801Z" |
| 90 | + fill="white" |
| 91 | + /> |
| 92 | + <path |
| 93 | + fillRule="evenodd" |
| 94 | + clipRule="evenodd" |
| 95 | + d="M13.1193 2.08301C13.6946 2.08301 14.161 2.54938 14.161 3.12467V15.6247C14.161 16.2 13.6946 16.6663 13.1193 16.6663C12.544 16.6663 12.0776 16.2 12.0776 15.6247V3.12467C12.0776 2.54938 12.544 2.08301 13.1193 2.08301Z" |
| 96 | + fill="white" |
| 97 | + /> |
| 98 | + </svg> |
| 99 | + |
| 100 | + {/* Export Text */} |
| 101 | + <span style={{ lineHeight: 'normal' }}>Export</span> |
| 102 | + </button> |
| 103 | + {error && ( |
| 104 | + <p style={{ color: 'red', marginTop: '10px', fontSize: '14px' }}> |
| 105 | + {error} |
| 106 | + </p> |
| 107 | + )} |
| 108 | + </div> |
| 109 | + ); |
| 110 | +} |
0 commit comments