feat: confirmation dialog before deleting the API key

This commit is contained in:
amhsirak
2026-02-03 11:19:46 +05:30
parent c0314982f9
commit ef56157888

View File

@@ -13,6 +13,11 @@ import {
TableRow, TableRow,
Tooltip, Tooltip,
Paper, Paper,
Dialog,
DialogTitle,
DialogContent,
DialogContentText,
DialogActions,
} from '@mui/material'; } from '@mui/material';
import { ContentCopy, Visibility, VisibilityOff, Delete } from '@mui/icons-material'; import { ContentCopy, Visibility, VisibilityOff, Delete } from '@mui/icons-material';
import styled from 'styled-components'; import styled from 'styled-components';
@@ -38,6 +43,9 @@ const ApiKeyManager = () => {
const [loading, setLoading] = useState<boolean>(true); const [loading, setLoading] = useState<boolean>(true);
const [showKey, setShowKey] = useState<boolean>(false); const [showKey, setShowKey] = useState<boolean>(false);
const [copySuccess, setCopySuccess] = useState<boolean>(false); const [copySuccess, setCopySuccess] = useState<boolean>(false);
const [confirmDeleteOpen, setConfirmDeleteOpen] = useState<boolean>(false);
const { notify } = useGlobalInfoStore(); const { notify } = useGlobalInfoStore();
useEffect(() => { useEffect(() => {
@@ -54,7 +62,6 @@ const ApiKeyManager = () => {
}; };
fetchApiKey(); fetchApiKey();
}, []); }, []);
const generateApiKey = async () => { const generateApiKey = async () => {
@@ -82,6 +89,7 @@ const ApiKeyManager = () => {
notify('error', t('apikey.notifications.delete_error', { error: error.message })); notify('error', t('apikey.notifications.delete_error', { error: error.message }));
} finally { } finally {
setLoading(false); setLoading(false);
setConfirmDeleteOpen(false);
} }
}; };
@@ -94,6 +102,18 @@ const ApiKeyManager = () => {
} }
}; };
const handleDeleteClick = () => {
setConfirmDeleteOpen(true);
};
const handleDeleteCancel = () => {
setConfirmDeleteOpen(false);
};
const handleDeleteConfirm = () => {
deleteApiKey();
};
if (loading) { if (loading) {
return ( return (
<Box <Box
@@ -114,13 +134,26 @@ const ApiKeyManager = () => {
<Container sx={{ alignSelf: 'flex-start' }}> <Container sx={{ alignSelf: 'flex-start' }}>
<Typography variant="body1" sx={{ marginBottom: '40px' }}> <Typography variant="body1" sx={{ marginBottom: '40px' }}>
Start by creating an API key below. Then, Start by creating an API key below. Then,
<a href={`${apiUrl}/api-docs/`} target="_blank" rel="noopener noreferrer" style={{ textDecoration: 'none', marginLeft: '5px', marginRight: '5px' }}> <a
href={`${apiUrl}/api-docs/`}
target="_blank"
rel="noopener noreferrer"
style={{ textDecoration: 'none', marginLeft: '5px', marginRight: '5px' }}
>
test your API test your API
</a> </a>
or read the <a href="https://docs.maxun.dev/category/api-docs" target="_blank" rel="noopener noreferrer" style={{ textDecoration: 'none' }}> or read the{' '}
<a
href="https://docs.maxun.dev/category/api-docs"
target="_blank"
rel="noopener noreferrer"
style={{ textDecoration: 'none' }}
>
API documentation API documentation
</a> for setup instructions. </a>{' '}
for setup instructions.
</Typography> </Typography>
<Typography <Typography
variant="h6" variant="h6"
gutterBottom gutterBottom
@@ -129,6 +162,7 @@ const ApiKeyManager = () => {
> >
{t('apikey.title')} {t('apikey.title')}
</Typography> </Typography>
{apiKey ? ( {apiKey ? (
<TableContainer component={Paper} sx={{ width: '100%', overflow: 'hidden' }}> <TableContainer component={Paper} sx={{ width: '100%', overflow: 'hidden' }}>
<Table sx={{ tableLayout: 'fixed', width: '100%' }}> <Table sx={{ tableLayout: 'fixed', width: '100%' }}>
@@ -137,7 +171,9 @@ const ApiKeyManager = () => {
<TableCell>{t('apikey.table.name')}</TableCell> <TableCell>{t('apikey.table.name')}</TableCell>
<TableCell>{t('apikey.table.key')}</TableCell> <TableCell>{t('apikey.table.key')}</TableCell>
{apiKeyCreatedAt && <TableCell>Created On</TableCell>} {apiKeyCreatedAt && <TableCell>Created On</TableCell>}
<TableCell align="center" sx={{ width: 160 }}>{t('apikey.table.actions')}</TableCell> <TableCell align="center" sx={{ width: 160 }}>
{t('apikey.table.actions')}
</TableCell>
</TableRow> </TableRow>
</TableHead> </TableHead>
<TableBody> <TableBody>
@@ -163,13 +199,15 @@ const ApiKeyManager = () => {
<ContentCopy /> <ContentCopy />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
<Tooltip title={showKey ? t('apikey.actions.hide') : t('apikey.actions.show')}> <Tooltip title={showKey ? t('apikey.actions.hide') : t('apikey.actions.show')}>
<IconButton onClick={() => setShowKey(!showKey)}> <IconButton onClick={() => setShowKey(!showKey)}>
{showKey ? <VisibilityOff /> : <Visibility />} {showKey ? <VisibilityOff /> : <Visibility />}
</IconButton> </IconButton>
</Tooltip> </Tooltip>
<Tooltip title={t('apikey.actions.delete')}> <Tooltip title={t('apikey.actions.delete')}>
<IconButton onClick={deleteApiKey} color="error"> <IconButton onClick={handleDeleteClick} color="error">
<Delete /> <Delete />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
@@ -181,12 +219,37 @@ const ApiKeyManager = () => {
) : ( ) : (
<> <>
<Typography>{t('apikey.no_key_message')}</Typography> <Typography>{t('apikey.no_key_message')}</Typography>
<Button onClick={generateApiKey} variant="contained" color="primary" sx={{ marginTop: '20px' }}> <Button
onClick={generateApiKey}
variant="contained"
color="primary"
sx={{ marginTop: '20px' }}
>
{t('apikey.generate_button')} {t('apikey.generate_button')}
</Button> </Button>
</> </>
)} )}
{/* Delete confirmation dialog */}
<Dialog open={confirmDeleteOpen} onClose={handleDeleteCancel}>
<DialogTitle>Delete API Key</DialogTitle>
<DialogContent>
<DialogContentText>
Are you sure you want to delete this API key? This action cannot be undone and
will immediately invalidate the key.
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={handleDeleteCancel}>
Cancel
</Button>
<Button onClick={handleDeleteConfirm} color="error" variant="contained">
Delete
</Button>
</DialogActions>
</Dialog>
</Container> </Container>
); );
} };
export default ApiKeyManager;
export default ApiKeyManager;