update admin service
This commit is contained in:
parent
5478b58e2e
commit
1c0c2ba39c
|
|
@ -30,7 +30,7 @@ const fetchData= async (search, sort, page, limit) => {
|
|||
|
||||
const getSectionById = async (id) => {
|
||||
try {
|
||||
const response = await axios.get(`${API_URL}/${id}`, config);
|
||||
const response = await axiosInstance.get(`/${id}`);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error(`Error fetching section with ID ${id}:`, error);
|
||||
|
|
@ -40,7 +40,7 @@ const getSectionById = async (id) => {
|
|||
|
||||
const createData = async (sectionData) => {
|
||||
try {
|
||||
const response = await axios.post(`${API_URL}/section`, sectionData, config);
|
||||
const response = await axiosInstance.post(`/section`, sectionData);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error('Error adding section:', error);
|
||||
|
|
@ -50,7 +50,7 @@ const createData = async (sectionData) => {
|
|||
|
||||
const updateData = async (id, sectionData) => {
|
||||
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;
|
||||
} catch (error) {
|
||||
console.error(`Error updating section with ID ${id}:`, error);
|
||||
|
|
@ -60,7 +60,7 @@ const updateData = async (id, sectionData) => {
|
|||
|
||||
const deleteData = async (id) => {
|
||||
try {
|
||||
const response = await axios.delete(`${API_URL}/section/delete/${id}`, config);
|
||||
const response = await axiosInstance.delete(`/section/delete/${id}`);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error(`Error deleting section with ID ${id}:`, error);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ const useStudents = () => {
|
|||
const [students, setStudents] = useState([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState(null);
|
||||
const [fileImport, setFileImport] = useState(null);
|
||||
|
||||
const [selectedStudent, setSelectedStudent] = useState(null);
|
||||
const [formData, setFormData] = useState({
|
||||
|
|
@ -30,14 +31,13 @@ const useStudents = () => {
|
|||
});
|
||||
}
|
||||
|
||||
const resetImportFile = () => {setFileImport(null)}
|
||||
|
||||
const createStudent = async (data) => {
|
||||
try {
|
||||
const newStudent ={
|
||||
NAME_USERS: data.fullName,
|
||||
EMAIL: data.email,
|
||||
NISN: data.nisn,
|
||||
PASSWORD: data.pass,
|
||||
CONFIRM_PASSWORD: data.confirm_pass,
|
||||
};
|
||||
const createdStudent = await studentService.createData(newStudent);
|
||||
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 formData = new FormData();
|
||||
formData.append('NAME_USERS', data.fullName);
|
||||
|
|
@ -94,6 +114,10 @@ const useStudents = () => {
|
|||
setFormData({ ...formData, [e.target.name]: e.target.value });
|
||||
};
|
||||
|
||||
const handleFileChange = (e) => {
|
||||
setFileImport(e.target.files[0]);
|
||||
};
|
||||
|
||||
const handleShow = (data) => {
|
||||
setSelectedStudent(data);
|
||||
setFormData({
|
||||
|
|
@ -151,6 +175,24 @@ const useStudents = () => {
|
|||
}, [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 {
|
||||
students,
|
||||
loading,
|
||||
|
|
@ -182,7 +224,12 @@ const useStudents = () => {
|
|||
page,
|
||||
handlePageChange,
|
||||
handleLimitsChange,
|
||||
handleSerachChange
|
||||
handleSerachChange,
|
||||
handleFileChange,
|
||||
handleDownloadTemplate,
|
||||
importRegister,
|
||||
fileImport,
|
||||
resetImportFile
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,5 @@
|
|||
import axios from 'axios';
|
||||
import { API_URL } from '../../../../utils/Constant';
|
||||
import axiosInstance from '../../../../utils/axiosInstance';
|
||||
|
||||
const config = {
|
||||
headers: {
|
||||
Authorization: localStorage.getItem('token')
|
||||
}
|
||||
};
|
||||
|
||||
const fetchData= async (search, sort, page, limit) => {
|
||||
try {
|
||||
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) => {
|
||||
try {
|
||||
const response = await axios.get(`${API_URL}/${id}`, config);
|
||||
const response = await axiosInstance.get(`/student/${id}`);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error(`Error fetching student with ID ${id}:`, error);
|
||||
|
|
@ -30,7 +22,7 @@ const getStudentById = async (id) => {
|
|||
|
||||
const createData = async (studentData) => {
|
||||
try {
|
||||
const response = await axios.post(`${API_URL}/register/student`, studentData, config);
|
||||
const response = await axiosInstance.post(`/admin/register/student`, studentData);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
console.error('Error adding student:', error);
|
||||
|
|
@ -40,7 +32,7 @@ const createData = async (studentData) => {
|
|||
|
||||
const updateData = async (id, studentData) => {
|
||||
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;
|
||||
} catch (error) {
|
||||
console.error(`Error updating student with ID ${id}:`, error);
|
||||
|
|
@ -50,7 +42,7 @@ const updateData = async (id, studentData) => {
|
|||
|
||||
const deleteData = async (id) => {
|
||||
try {
|
||||
const response = await axios.delete(`${API_URL}/user/delete/${id}`, config);
|
||||
const response = await axiosInstance.delete(`/user/delete/${id}`);
|
||||
return response.data;
|
||||
} catch (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{
|
||||
fetchData,
|
||||
getStudentById,
|
||||
createData,
|
||||
updateData,
|
||||
deleteData
|
||||
deleteData,
|
||||
getTemplate,
|
||||
registerImport
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,7 +35,12 @@ const ManageStudents = () => {
|
|||
setSearch,
|
||||
handlePageChange,
|
||||
handleLimitsChange,
|
||||
handleSerachChange
|
||||
handleSerachChange,
|
||||
handleFileChange,
|
||||
handleDownloadTemplate,
|
||||
importRegister,
|
||||
fileImport,
|
||||
resetImportFile
|
||||
} = useStudents();
|
||||
|
||||
const handleCreate = async (e) => {
|
||||
|
|
@ -44,6 +49,12 @@ const ManageStudents = () => {
|
|||
await createStudent(formData);
|
||||
};
|
||||
|
||||
const handleImport = async (e) => {
|
||||
handleShowLoader('Created', '', true)
|
||||
e.preventDefault();
|
||||
await importRegister();
|
||||
};
|
||||
|
||||
const handleUpdate = async (e) => {
|
||||
handleClose();
|
||||
handleShowLoader('Updated', '', true)
|
||||
|
|
@ -60,6 +71,34 @@ const ManageStudents = () => {
|
|||
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) {
|
||||
<>{error}</>
|
||||
}
|
||||
|
|
@ -67,7 +106,7 @@ const ManageStudents = () => {
|
|||
return (
|
||||
<div className='admin-students'>
|
||||
<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}>
|
||||
<Row className='mb-45'>
|
||||
<Col xs={12}>
|
||||
|
|
@ -177,58 +216,43 @@ const ManageStudents = () => {
|
|||
</div>
|
||||
</Tab.Pane>
|
||||
<Tab.Pane eventKey="create">
|
||||
<div className="cards">
|
||||
<div className="cards mb-4">
|
||||
<div className="cards-title">
|
||||
<h4>Add Student Data</h4>
|
||||
</div>
|
||||
<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}>
|
||||
<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.Label>Role<sup className='text-red fw-bold'>*</sup></Form.Label>
|
||||
<InputGroup className="mb-2 input-group-icon disabled">
|
||||
|
|
@ -310,7 +334,7 @@ const ManageStudents = () => {
|
|||
/>
|
||||
</InputGroup>
|
||||
</Form.Group>
|
||||
</Row>
|
||||
</Row> */}
|
||||
<div className="d-flex justify-content-end">
|
||||
<Button variant="outline-blue" type="reset" className='ms-auto py-2 rounded-35'
|
||||
onClick={resetForm}
|
||||
|
|
@ -326,6 +350,49 @@ const ManageStudents = () => {
|
|||
</Form>
|
||||
</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.Content>
|
||||
</Col>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import axios from 'axios';
|
||||
import { API_URL } from '../../../../utils/Constant';
|
||||
import axiosInstance from '../../../../utils/axiosInstance';
|
||||
|
||||
const config = {
|
||||
headers: {
|
||||
|
|
@ -9,7 +8,7 @@ const config = {
|
|||
|
||||
const fetchProfile = async () => {
|
||||
try {
|
||||
const response = await axios.get(`${API_URL}/getMe`, config);
|
||||
const response = await axiosInstance.get(`/getMe`, config);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
|
@ -17,16 +16,8 @@ const fetchProfile = async () => {
|
|||
};
|
||||
|
||||
const updateProfile = async (id, formData) => {
|
||||
|
||||
const cfg = {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
Authorization: localStorage.getItem('token')
|
||||
},
|
||||
};
|
||||
|
||||
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;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
|
@ -34,14 +25,8 @@ const updateProfile = async (id, formData) => {
|
|||
};
|
||||
|
||||
const updatePassword = async (userId, passwordData) => {
|
||||
const cfg = {
|
||||
headers: {
|
||||
Authorization: localStorage.getItem('token'),
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
};
|
||||
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;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user