feature: add actions for edit and delete

This commit is contained in:
Rodolfo Ruiz 2025-06-25 20:07:31 -06:00
parent 03022206ae
commit c9de10c46e
4 changed files with 145 additions and 84 deletions

View File

@ -1,13 +0,0 @@
export async function getExternalData() {
try {
const response = await fetch('http://portainer.white-enciso.pro:4001/api/v1/MongoSample/GetAll');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('Failed to fetch data:', error);
return [];
}
}

65
src/api/mongo/actions.jsx Normal file
View File

@ -0,0 +1,65 @@
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 [];
}
}
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;
}
}
export async function updateExternalData(data) {
const response = await fetch(`${API_BASE_URL}/Update`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
});
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;
}
}

View File

@ -1,12 +1,6 @@
import { useEffect, useState } from 'react';
import {
Box,
Button,
TextField,
Typography,
Paper,
MenuItem
} from '@mui/material';
import { useState, useEffect } from 'react';
import { Box, Button, TextField, MenuItem } from '@mui/material';
import { createExternalData, updateExternalData } from '../../api/mongo/actions';
export default function AddOrEditAdminForm({ onAdd, initialData, onCancel }) {
const [formData, setFormData] = useState({
@ -17,7 +11,7 @@ export default function AddOrEditAdminForm({ onAdd, initialData, onCancel }) {
useEffect(() => {
if (initialData) {
setFormData(initialData);
setFormData({ ...initialData });
} else {
setFormData({
name: '',
@ -29,65 +23,58 @@ export default function AddOrEditAdminForm({ onAdd, initialData, onCancel }) {
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prev) => ({
...prev,
[name]: value
}));
setFormData(prev => ({ ...prev, [name]: value }));
};
const handleSubmit = () => {
if (onAdd) {
onAdd(formData);
const handleSubmit = async () => {
try {
if (initialData) {
await updateExternalData(formData);
} else {
await createExternalData(formData);
}
if (onAdd) onAdd();
} catch (error) {
console.error('Error submitting form:', error);
}
};
return (
<Box sx={{ px: 2, py: 3 }}>
<Paper elevation={0} sx={{ bgcolor: '#f9f9f9', p: 2, borderRadius: 2 }}>
<Typography variant="h6" gutterBottom>
Item details
</Typography>
<TextField
fullWidth
label="Name"
name="name"
value={formData.name}
onChange={handleChange}
margin="normal"
/>
<Box sx={{ py: 2 }}>
<TextField
fullWidth
label="Name"
name="name"
value={formData.name}
onChange={handleChange}
margin="normal"
/>
<TextField
fullWidth
label="Description"
name="description"
value={formData.description}
onChange={handleChange}
margin="normal"
/>
<TextField
fullWidth
select
label="Status"
name="status"
value={formData.status}
onChange={handleChange}
margin="normal"
>
<MenuItem value="Active">Active</MenuItem>
<MenuItem value="Inactive">Inactive</MenuItem>
</TextField>
<Box display="flex" justifyContent="flex-end" mt={3} gap={1}>
<Button onClick={onCancel} className="button-transparent">Cancel</Button>
<Button variant="contained" onClick={handleSubmit} className="button-gold">Save</Button>
</Box>
<TextField
fullWidth
label="Description"
name="description"
value={formData.description}
onChange={handleChange}
margin="normal"
/>
<TextField
select
fullWidth
label="Status"
name="status"
value={formData.status}
onChange={handleChange}
margin="normal"
>
<MenuItem value="Active">Active</MenuItem>
<MenuItem value="Inactive">Inactive</MenuItem>
</TextField>
<Box display="flex" justifyContent="flex-end" gap={1} mt={3}>
<Button onClick={onCancel} className="button-transparent">
Cancel
</Button>
<Button variant="contained" onClick={handleSubmit} className="button-gold">
Save
</Button>
</Box>
</Paper>
</Box>
);
}

View File

@ -5,7 +5,7 @@ import { Typography, Button, Dialog, DialogTitle, DialogContent, IconButton, Box
import EditRoundedIcon from '@mui/icons-material/EditRounded';
import DeleteRoundedIcon from '@mui/icons-material/DeleteRounded';
import AddOrEditAdminForm from './AddOrEditAdminForm';
import { getExternalData } from '../../api/actions';
import { getExternalData, deleteExternalData } from '../../api/mongo/actions';
const columnsBase = [
{ field: 'name', headerName: 'Name', flex: 2 },
@ -41,13 +41,23 @@ export default function Admin() {
const [rowToDelete, setRowToDelete] = useState(null);
useEffect(() => {
getExternalData().then(data => {
const safeData = Array.isArray(data) ? data : [];
setRows(safeData);
}).catch(error => {
console.error('Error loading data:', error);
setRows([]);
});
let isMounted = true;
getExternalData()
.then(data => {
if (isMounted) {
const safeData = Array.isArray(data) ? data : [];
setRows(safeData);
}
})
.catch(error => {
console.error('Error loading data:', error);
if (isMounted) setRows([]);
});
return () => {
isMounted = false;
};
}, []);
const handleEditClick = (params) => {
@ -60,6 +70,18 @@ export default function Admin() {
setConfirmOpen(true);
};
const handleConfirmDelete = async () => {
try {
await deleteExternalData(rowToDelete._Id);
setRows((prevRows) => prevRows.filter(r => r._Id !== rowToDelete._Id));
} catch (error) {
console.error('Delete failed:', error);
} finally {
setConfirmOpen(false);
setRowToDelete(null);
}
};
const columns = [
...columnsBase,
{
@ -118,7 +140,7 @@ export default function Admin() {
</Typography>
<Box mt={2} display="flex" justifyContent="flex-end" gap={1}>
<Button onClick={() => setConfirmOpen(false)} className='button-transparent'>Cancel</Button>
<Button variant="contained" onClick={() => { }} className="button-gold">Delete</Button>
<Button variant="contained" onClick={handleConfirmDelete} className="button-gold">Delete</Button>
</Box>
</DialogContent>
</Dialog>
@ -140,4 +162,4 @@ export default function Admin() {
</Box>
</SectionContainer>
);
}
}