feat: add toast when endpoints are failing

This commit is contained in:
Rodolfo Ruiz
2025-07-03 17:23:09 -06:00
parent 2849ee2e6b
commit eb49416000
6 changed files with 91 additions and 48 deletions

View File

@@ -1,65 +1,44 @@
const API_BASE_URL = 'http://portainer.white-enciso.pro:4001/api/v1/MongoSample';
export async function getExternalData() {
try {
const response = await fetch(`${API_BASE_URL}/GetAll`);
if (!response.ok) throw new Error('Failed to fetch external data');
const data = await response.json();
return data;
} catch (error) {
console.error('Error fetching external data:', error);
return [];
}
const response = await fetch(`${API_BASE_URL}/GetAll`);
if (!response.ok) throw new Error('Failed to fetch external data');
const data = await response.json();
return data;
}
export async function createExternalData(data) {
try {
const response = await fetch(`${API_BASE_URL}/Create`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
if (!response.ok) throw new Error('Failed to create external data');
const result = await response.json();
return result;
} catch (error) {
console.error('Error creating external data:', error);
throw error;
}
const response = await fetch(`${API_BASE_URL}/Create`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
});
if (!response.ok) throw new Error('Failed to create external data');
return await response.json();
}
export async function updateExternalData(data) {
const response = await fetch(`${API_BASE_URL}/Update`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
body: JSON.stringify(data),
});
if (!response.ok) {
throw new Error('Failed to update item');
}
if (!response.ok) throw new Error('Failed to update item');
return await response.json();
}
export async function deleteExternalData(_Id) {
try {
const response = await fetch(`${API_BASE_URL}/Delete`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ _Id }),
});
if (!response.ok) throw new Error('Failed to delete external data');
return await response.json();
} catch (error) {
console.error('Error deleting external data:', error);
throw error;
}
const response = await fetch(`${API_BASE_URL}/Delete`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ _Id }),
});
if (!response.ok) throw new Error('Failed to delete external data');
return await response.json();
}

12
src/hooks/useApiToast.jsx Normal file
View File

@@ -0,0 +1,12 @@
import { useSnackbar } from 'notistack';
export default function useApiToast() {
const { enqueueSnackbar } = useSnackbar();
const handleError = (error, defaultMessage = 'API error') => {
console.error(error);
enqueueSnackbar(error.message || defaultMessage, { variant: 'error' });
};
return { handleError };
}

View File

@@ -1,6 +1,6 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { SnackbarProvider } from 'notistack';
import { ThemeProvider } from '@mui/material/styles';
import theme from './theme';
import './index.css'
@@ -9,7 +9,14 @@ import App from './App.jsx'
createRoot(document.getElementById('root')).render(
<StrictMode>
<ThemeProvider theme={theme}>
<App />
<SnackbarProvider maxSnack={3}
autoHideDuration={5000}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}>
<App />
</SnackbarProvider>
</ThemeProvider>
</StrictMode>,
)

View File

@@ -6,6 +6,7 @@ import EditRoundedIcon from '@mui/icons-material/EditRounded';
import DeleteRoundedIcon from '@mui/icons-material/DeleteRounded';
import AddOrEditAdminForm from './AddOrEditAdminForm';
import { getExternalData, deleteExternalData } from '../../api/mongo/actions';
import useApiToast from '../../hooks/useApiToast';
const columnsBase = [
{ field: 'name', headerName: 'Name', flex: 2 },
@@ -39,6 +40,7 @@ export default function Admin() {
const [editingData, setEditingData] = useState(null);
const [confirmOpen, setConfirmOpen] = useState(false);
const [rowToDelete, setRowToDelete] = useState(null);
const { handleError } = useApiToast();
useEffect(() => {
let isMounted = true;
@@ -75,6 +77,7 @@ export default function Admin() {
setRows(safeData);
} catch (error) {
console.error('Error loading data:', error);
handleError(error, 'Failed to load data');
setRows([]);
}
};