update admin service

This commit is contained in:
Dimas Atmodjo 2024-12-05 15:32:19 +07:00
parent 5478b58e2e
commit 1c0c2ba39c
5 changed files with 208 additions and 89 deletions

View File

@ -30,7 +30,7 @@ const fetchData= async (search, sort, page, limit) => {
const getSectionById = async (id) => { const getSectionById = async (id) => {
try { try {
const response = await axios.get(`${API_URL}/${id}`, config); const response = await axiosInstance.get(`/${id}`);
return response.data; return response.data;
} catch (error) { } catch (error) {
console.error(`Error fetching section with ID ${id}:`, error); console.error(`Error fetching section with ID ${id}:`, error);
@ -40,7 +40,7 @@ const getSectionById = async (id) => {
const createData = async (sectionData) => { const createData = async (sectionData) => {
try { try {
const response = await axios.post(`${API_URL}/section`, sectionData, config); const response = await axiosInstance.post(`/section`, sectionData);
return response.data; return response.data;
} catch (error) { } catch (error) {
console.error('Error adding section:', error); console.error('Error adding section:', error);
@ -50,7 +50,7 @@ const createData = async (sectionData) => {
const updateData = async (id, sectionData) => { const updateData = async (id, sectionData) => {
try { try {
const response = await axios.put(`${API_URL}/section/update/${id}`, sectionData, config); const response = await axiosInstance.put(`/section/update/${id}`, sectionData);
return response.data; return response.data;
} catch (error) { } catch (error) {
console.error(`Error updating section with ID ${id}:`, error); console.error(`Error updating section with ID ${id}:`, error);
@ -60,7 +60,7 @@ const updateData = async (id, sectionData) => {
const deleteData = async (id) => { const deleteData = async (id) => {
try { try {
const response = await axios.delete(`${API_URL}/section/delete/${id}`, config); const response = await axiosInstance.delete(`/section/delete/${id}`);
return response.data; return response.data;
} catch (error) { } catch (error) {
console.error(`Error deleting section with ID ${id}:`, error); console.error(`Error deleting section with ID ${id}:`, error);

View File

@ -5,6 +5,7 @@ const useStudents = () => {
const [students, setStudents] = useState([]); const [students, setStudents] = useState([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [error, setError] = useState(null); const [error, setError] = useState(null);
const [fileImport, setFileImport] = useState(null);
const [selectedStudent, setSelectedStudent] = useState(null); const [selectedStudent, setSelectedStudent] = useState(null);
const [formData, setFormData] = useState({ const [formData, setFormData] = useState({
@ -30,14 +31,13 @@ const useStudents = () => {
}); });
} }
const resetImportFile = () => {setFileImport(null)}
const createStudent = async (data) => { const createStudent = async (data) => {
try { try {
const newStudent ={ const newStudent ={
NAME_USERS: data.fullName, NAME_USERS: data.fullName,
EMAIL: data.email,
NISN: data.nisn, NISN: data.nisn,
PASSWORD: data.pass,
CONFIRM_PASSWORD: data.confirm_pass,
}; };
const createdStudent = await studentService.createData(newStudent); const createdStudent = await studentService.createData(newStudent);
setStudents((prevStudents) => [...prevStudents, createdStudent.payload]); setStudents((prevStudents) => [...prevStudents, createdStudent.payload]);
@ -53,6 +53,26 @@ const useStudents = () => {
} }
}; };
const importRegister = async () => {
const fileData = new FormData();
const file = fileImport;
fileData.append('file', file);
console.log(file);
try {
const response = await studentService.registerImport(fileData);
console.log(response.data);
} catch (err) {
setError(err);
}finally{
resetForm();
setLoaderState(prev => ({
...prev,
loading: false,
successMessage: 'Your new entry has been successfully created and saved.'
}));
}
}
const editStudent = async (id, data) => { const editStudent = async (id, data) => {
const formData = new FormData(); const formData = new FormData();
formData.append('NAME_USERS', data.fullName); formData.append('NAME_USERS', data.fullName);
@ -94,6 +114,10 @@ const useStudents = () => {
setFormData({ ...formData, [e.target.name]: e.target.value }); setFormData({ ...formData, [e.target.name]: e.target.value });
}; };
const handleFileChange = (e) => {
setFileImport(e.target.files[0]);
};
const handleShow = (data) => { const handleShow = (data) => {
setSelectedStudent(data); setSelectedStudent(data);
setFormData({ setFormData({
@ -151,6 +175,24 @@ const useStudents = () => {
}, [page, limit]); }, [page, limit]);
const handleDownloadTemplate = async () => {try {
const response = await studentService.getTemplate();
const blob = new Blob([response], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const downloadUrl = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = downloadUrl;
link.download = 'template.xls';
link.click();
URL.revokeObjectURL(downloadUrl);
} catch (error) {
console.error('Error downloading file:', error);
alert('Gagal mengunduh file');
}
}
return { return {
students, students,
loading, loading,
@ -182,7 +224,12 @@ const useStudents = () => {
page, page,
handlePageChange, handlePageChange,
handleLimitsChange, handleLimitsChange,
handleSerachChange handleSerachChange,
handleFileChange,
handleDownloadTemplate,
importRegister,
fileImport,
resetImportFile
}; };
}; };

View File

@ -1,13 +1,5 @@
import axios from 'axios';
import { API_URL } from '../../../../utils/Constant';
import axiosInstance from '../../../../utils/axiosInstance'; import axiosInstance from '../../../../utils/axiosInstance';
const config = {
headers: {
Authorization: localStorage.getItem('token')
}
};
const fetchData= async (search, sort, page, limit) => { const fetchData= async (search, sort, page, limit) => {
try { try {
const response = await axiosInstance.get(`/user/student?search=${search}&sort=${sort}&page=${page}&limit=${limit}`); const response = await axiosInstance.get(`/user/student?search=${search}&sort=${sort}&page=${page}&limit=${limit}`);
@ -20,7 +12,7 @@ const fetchData= async (search, sort, page, limit) => {
const getStudentById = async (id) => { const getStudentById = async (id) => {
try { try {
const response = await axios.get(`${API_URL}/${id}`, config); const response = await axiosInstance.get(`/student/${id}`);
return response.data; return response.data;
} catch (error) { } catch (error) {
console.error(`Error fetching student with ID ${id}:`, error); console.error(`Error fetching student with ID ${id}:`, error);
@ -30,7 +22,7 @@ const getStudentById = async (id) => {
const createData = async (studentData) => { const createData = async (studentData) => {
try { try {
const response = await axios.post(`${API_URL}/register/student`, studentData, config); const response = await axiosInstance.post(`/admin/register/student`, studentData);
return response.data; return response.data;
} catch (error) { } catch (error) {
console.error('Error adding student:', error); console.error('Error adding student:', error);
@ -40,7 +32,7 @@ const createData = async (studentData) => {
const updateData = async (id, studentData) => { const updateData = async (id, studentData) => {
try { try {
const response = await axios.put(`${API_URL}/user/update/${id}`, studentData, config); const response = await axiosInstance.put(`/user/update/${id}`, studentData);
return response.data; return response.data;
} catch (error) { } catch (error) {
console.error(`Error updating student with ID ${id}:`, error); console.error(`Error updating student with ID ${id}:`, error);
@ -50,7 +42,7 @@ const updateData = async (id, studentData) => {
const deleteData = async (id) => { const deleteData = async (id) => {
try { try {
const response = await axios.delete(`${API_URL}/user/delete/${id}`, config); const response = await axiosInstance.delete(`/user/delete/${id}`);
return response.data; return response.data;
} catch (error) { } catch (error) {
console.error(`Error deleting student with ID ${id}:`, error); console.error(`Error deleting student with ID ${id}:`, error);
@ -58,10 +50,38 @@ const deleteData = async (id) => {
} }
}; };
const getTemplate = async () => {
const configs = {
headers: {
Authorization: localStorage.getItem('token')
},
responseType: 'blob',
};
try {
const response = await axiosInstance.get(`/user/sendExcelExample`, configs);
return response.data;
} catch (error) {
console.error(`Error get file:`, error);
throw error;
}
};
const registerImport = async (file) => {
try {
const response = await axiosInstance.post(`/admin/register/student/csv`, file);
return response.data;
} catch (error) {
console.error('Error adding student:', error);
throw error;
}
};
export default{ export default{
fetchData, fetchData,
getStudentById, getStudentById,
createData, createData,
updateData, updateData,
deleteData deleteData,
getTemplate,
registerImport
}; };

View File

@ -35,7 +35,12 @@ const ManageStudents = () => {
setSearch, setSearch,
handlePageChange, handlePageChange,
handleLimitsChange, handleLimitsChange,
handleSerachChange handleSerachChange,
handleFileChange,
handleDownloadTemplate,
importRegister,
fileImport,
resetImportFile
} = useStudents(); } = useStudents();
const handleCreate = async (e) => { const handleCreate = async (e) => {
@ -44,6 +49,12 @@ const ManageStudents = () => {
await createStudent(formData); await createStudent(formData);
}; };
const handleImport = async (e) => {
handleShowLoader('Created', '', true)
e.preventDefault();
await importRegister();
};
const handleUpdate = async (e) => { const handleUpdate = async (e) => {
handleClose(); handleClose();
handleShowLoader('Updated', '', true) handleShowLoader('Updated', '', true)
@ -60,6 +71,34 @@ const ManageStudents = () => {
setLoaderState(prev => ({ ...prev, handleConfirm: confirmDelete })); setLoaderState(prev => ({ ...prev, handleConfirm: confirmDelete }));
} }
const handleDragOver = (e) => {
e.preventDefault(); // Mencegah browser membuka file
e.stopPropagation();
};
const handleDrop = (e) => {
e.preventDefault();
e.stopPropagation();
const droppedFiles = e.dataTransfer.files; // Ambil file dari drag event
if (droppedFiles.length) {
// Kirim file ke input
handleFileChange({ target: { files: droppedFiles } });
}
};
const handleDragEnter = (e) => {
e.preventDefault();
e.stopPropagation();
e.target.classList.add('dragging');
};
const handleDragLeave = (e) => {
e.preventDefault();
e.stopPropagation();
e.target.classList.remove('dragging');
};
if (error) { if (error) {
<>{error}</> <>{error}</>
} }
@ -67,7 +106,7 @@ const ManageStudents = () => {
return ( return (
<div className='admin-students'> <div className='admin-students'>
<h2 className='page-title strip'>Students</h2> <h2 className='page-title strip'>Students</h2>
<p className='page-desc'>Description of students.</p> <p className='page-desc'>Easily add students to their classes and organize them efficiently.</p>
<Tab.Container id="left-tabs-example" defaultActiveKey="detail" onSelect={resetForm}> <Tab.Container id="left-tabs-example" defaultActiveKey="detail" onSelect={resetForm}>
<Row className='mb-45'> <Row className='mb-45'>
<Col xs={12}> <Col xs={12}>
@ -177,58 +216,43 @@ const ManageStudents = () => {
</div> </div>
</Tab.Pane> </Tab.Pane>
<Tab.Pane eventKey="create"> <Tab.Pane eventKey="create">
<div className="cards"> <div className="cards mb-4">
<div className="cards-title"> <div className="cards-title">
<h4>Add Student Data</h4> <h4>Add Student Data</h4>
</div> </div>
<div className="cards-body"> <div className="cards-body">
{/* <Form>
<Row className="mb-2">
<Form.Group as={Col}>
<Form.Label>Full Name</Form.Label>
<InputGroup className="mb-2 input-group-icon">
<Form.Control
name="fullName"
value={formData.fullName}
onChange={handleFormChange}
placeholder="Enter Full Name"
/>
</InputGroup>
</Form.Group>
<Form.Group as={Col}>
<Form.Label>NISN</Form.Label>
<InputGroup className="mb-2 input-group-icon">
<Form.Control
name="nisn"
value={formData.nisn}
onChange={handleFormChange}
placeholder="Enter NISN"
/>
</InputGroup>
</Form.Group>
</Row>
<Row className="mb-2">
<Form.Group as={Col}>
<Form.Label>Email Address</Form.Label>
<InputGroup className="mb-2 input-group-icon">
<Form.Control
name="email"
value={formData.email}
onChange={handleFormChange}
placeholder="Enter Email"
/>
</InputGroup>
</Form.Group>
</Row>
<div className="btn-group mt-4">
<Button className='btn-submit' type='button' onClick={handleSubmit}>
Submit
</Button>
</div>
</Form> */}
<Form onSubmit={handleCreate}> <Form onSubmit={handleCreate}>
<Row className="mb-2"> <Row className="mb-2">
<Form.Group as={Col} controlId="formGridNISN">
<Form.Label>NISN<sup className='text-red fw-bold'>*</sup></Form.Label>
<InputGroup className="mb-2 input-group-icon">
<InputGroup.Text id="basic-addon1"><i className="bi bi-123"></i></InputGroup.Text>
<Form.Control
name="nisn"
value={formData.nisn || ''}
onChange={handleFormChange}
placeholder="Enter NISN"
required
/>
</InputGroup>
</Form.Group>
<Form.Group as={Col} controlId="formGridName">
<Form.Label>Full Name<sup className='text-red fw-bold'>*</sup></Form.Label>
<InputGroup className="mb-2 input-group-icon">
<InputGroup.Text id="basic-addon1"><i className="bi bi-person"></i></InputGroup.Text>
<Form.Control
name="fullName"
value={formData.fullName || ''}
onChange={handleFormChange}
placeholder="Enter Full Name"
required
/>
</InputGroup>
</Form.Group>
</Row>
{/* <Row className="mb-2">
<Form.Group as={Col} controlId="formGridRole"> <Form.Group as={Col} controlId="formGridRole">
<Form.Label>Role<sup className='text-red fw-bold'>*</sup></Form.Label> <Form.Label>Role<sup className='text-red fw-bold'>*</sup></Form.Label>
<InputGroup className="mb-2 input-group-icon disabled"> <InputGroup className="mb-2 input-group-icon disabled">
@ -310,7 +334,7 @@ const ManageStudents = () => {
/> />
</InputGroup> </InputGroup>
</Form.Group> </Form.Group>
</Row> </Row> */}
<div className="d-flex justify-content-end"> <div className="d-flex justify-content-end">
<Button variant="outline-blue" type="reset" className='ms-auto py-2 rounded-35' <Button variant="outline-blue" type="reset" className='ms-auto py-2 rounded-35'
onClick={resetForm} onClick={resetForm}
@ -326,6 +350,49 @@ const ManageStudents = () => {
</Form> </Form>
</div> </div>
</div> </div>
<div className="cards">
<div className="cards-title d-flex justify-content-between aligb-items-center">
<h4>Add Student Data via Excel</h4>
<span className='text-blue cursor-pointer' onClick={() => {handleDownloadTemplate()}}><i className="bi bi-download me-2"></i>Download Template Excel</span>
</div>
<div className="cards-body">
<Form onSubmit={handleImport}>
<Row className="mb-2">
<Form.Control
id='fileUpload'
accept='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
type='file'
name="file"
onChange={handleFileChange}
placeholder="Masukan File"
className='d-none'
/>
<label
htmlFor="fileUpload"
className={`drop-zone rounded-3 ${fileImport ? `active` : ``}`}
onDragOver={handleDragOver}
onDrop={handleDrop}
onDragEnter={handleDragEnter}
onDragLeave={handleDragLeave}
>
<h5 className={`m-0 ${fileImport ? `text-green fs-3` : `text-grey`}`}>{fileImport ? fileImport.name : "Upload Excel file here"}</h5>
<span className={`fs-14p ${fileImport ? `text-green` : `text-grey`}`}>{fileImport ? "Your file is ready to import" : "Please make sure your Excel file follows the template."}</span>
</label>
</Row>
<div className="d-flex justify-content-end">
<Button variant="outline-blue" type="reset" className='ms-auto py-2 rounded-35'
onClick={resetImportFile}
>
reset
</Button>
<Button variant="blue" type="submit" className='ms-2 py-2 px-5 rounded-35' disabled={fileImport ? false : true}>
Import
</Button>
</div>
</Form>
</div>
</div>
</Tab.Pane> </Tab.Pane>
</Tab.Content> </Tab.Content>
</Col> </Col>

View File

@ -1,5 +1,4 @@
import axios from 'axios'; import axiosInstance from '../../../../utils/axiosInstance';
import { API_URL } from '../../../../utils/Constant';
const config = { const config = {
headers: { headers: {
@ -9,7 +8,7 @@ const config = {
const fetchProfile = async () => { const fetchProfile = async () => {
try { try {
const response = await axios.get(`${API_URL}/getMe`, config); const response = await axiosInstance.get(`/getMe`, config);
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@ -17,16 +16,8 @@ const fetchProfile = async () => {
}; };
const updateProfile = async (id, formData) => { const updateProfile = async (id, formData) => {
const cfg = {
headers: {
'Content-Type': 'multipart/form-data',
Authorization: localStorage.getItem('token')
},
};
try { try {
const response = await axios.put(`${API_URL}/user/update/${id}`, formData, cfg); const response = await axiosInstance.put(`/user/update/${id}`, formData);
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;
@ -34,14 +25,8 @@ const updateProfile = async (id, formData) => {
}; };
const updatePassword = async (userId, passwordData) => { const updatePassword = async (userId, passwordData) => {
const cfg = {
headers: {
Authorization: localStorage.getItem('token'),
'Content-Type': 'application/json',
},
};
try { try {
const response = await axios.put(`${API_URL}/user/update/password/${userId}`, passwordData, cfg); const response = await axiosInstance.put(`/user/update/password/${userId}`, passwordData);
return response.data; return response.data;
} catch (error) { } catch (error) {
throw error; throw error;