feature: add actions for edit and delete
This commit is contained in:
		| @@ -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
									
								
							
							
						
						
									
										65
									
								
								src/api/mongo/actions.jsx
									
									
									
									
									
										Normal 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; | ||||
|   } | ||||
| } | ||||
| @@ -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,25 +23,25 @@ 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> | ||||
|  | ||||
|         <Box sx={{ py: 2 }}> | ||||
|             <TextField | ||||
|                 fullWidth | ||||
|                 label="Name" | ||||
| @@ -56,7 +50,6 @@ export default function AddOrEditAdminForm({ onAdd, initialData, onCancel }) { | ||||
|                 onChange={handleChange} | ||||
|                 margin="normal" | ||||
|             /> | ||||
|  | ||||
|             <TextField | ||||
|                 fullWidth | ||||
|                 label="Description" | ||||
| @@ -65,10 +58,9 @@ export default function AddOrEditAdminForm({ onAdd, initialData, onCancel }) { | ||||
|                 onChange={handleChange} | ||||
|                 margin="normal" | ||||
|             /> | ||||
|  | ||||
|             <TextField | ||||
|                     select | ||||
|                 fullWidth | ||||
|                 select | ||||
|                 label="Status" | ||||
|                 name="status" | ||||
|                 value={formData.status} | ||||
| @@ -78,16 +70,11 @@ export default function AddOrEditAdminForm({ onAdd, initialData, onCancel }) { | ||||
|                 <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 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> | ||||
|             </Paper> | ||||
|  | ||||
|         </Box> | ||||
|     ); | ||||
| } | ||||
| @@ -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 => { | ||||
|         let isMounted = true; | ||||
|  | ||||
|         getExternalData() | ||||
|             .then(data => { | ||||
|                 if (isMounted) { | ||||
|                     const safeData = Array.isArray(data) ? data : []; | ||||
|                     setRows(safeData); | ||||
|         }).catch(error => { | ||||
|                 } | ||||
|             }) | ||||
|             .catch(error => { | ||||
|                 console.error('Error loading data:', error); | ||||
|             setRows([]); | ||||
|                 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> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Rodolfo Ruiz
					Rodolfo Ruiz