From 0517ad94ecf896de50ad86453c497b2a419d346a Mon Sep 17 00:00:00 2001 From: Fouz97 Date: Wed, 30 Oct 2024 09:27:39 +0700 Subject: [PATCH 01/19] FIX :: Route --- src/App.jsx | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index d7df8046..4d3f57fe 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -178,7 +178,6 @@ const App = () => { } /> - . { } /> + }> + + + } + /> - }> - - - } - /> {/* for error handler */} }/> @@ -206,8 +205,7 @@ const App = () => { - ) - ; + ); }; export default App; From 96f51154ad022c864c9b767ca1cc25e95fe3c842 Mon Sep 17 00:00:00 2001 From: Fouz97 Date: Sun, 3 Nov 2024 13:04:22 +0700 Subject: [PATCH 02/19] FIX :: Class Management Integrating --- src/context/ClassContext.jsx | 36 ++++--- src/pages/Class/ClassDashboard.jsx | 83 ++++++++++------ .../libs/components/ClassFilterButton.jsx | 98 +++++++++++++++++++ .../components/ClassList/ClassColumns.jsx | 6 +- .../libs/components/modals/ClassDetail.jsx | 17 ++-- .../components/modals/ClassDetailContent.jsx | 4 +- .../libs/components/modals/CreateClass.jsx | 2 +- .../libs/components/modals/UpdateClass.jsx | 34 +++++-- src/pages/Class/libs/components/utils.js | 8 ++ 9 files changed, 220 insertions(+), 68 deletions(-) create mode 100644 src/pages/Class/libs/components/ClassFilterButton.jsx diff --git a/src/context/ClassContext.jsx b/src/context/ClassContext.jsx index d922e9a9..4c6bef19 100644 --- a/src/context/ClassContext.jsx +++ b/src/context/ClassContext.jsx @@ -1,10 +1,11 @@ -import {createContext, useState, useCallback} from "react"; -import {ClassApi} from "@/utils/axios/ApiService"; +import { createContext, useState, useCallback } from "react"; +import { ClassApi } from "@/utils/axios/ApiService"; export const ClassContext = createContext(); -export const ClassProvider = ( {children} ) => { +export const ClassProvider = ({ children }) => { const [classData, setClassData] = useState([]); + const [originalClassData, setOriginalClassData] = useState([]); const [isModalLoading, setIsModalLoading] = useState(false); const [isTableLoading, setIsTableLoading] = useState(false); const [tableErrorMessage, setTableErrorMessage] = useState(""); @@ -13,13 +14,19 @@ export const ClassProvider = ( {children} ) => { const [currentPage, setCurrentPage] = useState(1); const [rowsPerPage, setRowPerPage] = useState(5); const [isRefreshPage, setIsRefreshPage] = useState(false); + const [totalData, setTotalData] = useState(0); + const [totalPages, setTotalPages] = useState(0); const getAllClasses = useCallback(async () => { try { setIsTableLoading(true); const response = await ClassApi.getClasses(rowsPerPage, currentPage); - const classList = response.data; + const classList = response.data.data; + const total = response.data.total; setClassData(classList); + setOriginalClassData(classList); + setTotalData(total); + setTotalPages(Math.ceil(total / rowsPerPage)); } catch (error) { setTableErrorMessage(error.response.message); } finally { @@ -27,17 +34,13 @@ export const ClassProvider = ( {children} ) => { } }, [rowsPerPage, currentPage]); - const getClassByUUID = useCallback(async (uuid) => { - try { - setIsModalLoading(true); - const response = await ClassApi.getClassById(uuid); - return response.data; - } catch (error) { - setTableErrorMessage(error.response.message); - } finally { - setIsModalLoading(false); + const filterClassData = (filterValues) => { + if (filterValues.length === 0) { + setClassData(originalClassData); + } else { + setClassData(originalClassData.filter((cls) => filterValues.includes(cls.majors.uuid))); } - }, []); + }; return ( { isRefreshPage, setIsRefreshPage, getAllClasses, + totalData, + setTotalData, + totalPages, + setTotalPages, + filterClassData, }} > {children} diff --git a/src/pages/Class/ClassDashboard.jsx b/src/pages/Class/ClassDashboard.jsx index c6b1dac8..c0737d70 100644 --- a/src/pages/Class/ClassDashboard.jsx +++ b/src/pages/Class/ClassDashboard.jsx @@ -1,17 +1,18 @@ -import {useContext} from "react"; -import {Select, Input} from "antd"; +import { useContext, useState } from "react"; +import { Select, Input, Flex } from "antd"; import CreateClass from "./libs/components/modals/CreateClass.jsx"; import UpdateClass from "@/pages/Class/libs/components/modals/UpdateClass.jsx"; -import {ToastContainer} from "react-toastify"; -import {Header} from "@/components/Dashboard/Header"; -import {ClassContext} from "@/context/ClassContext"; +import { ToastContainer } from "react-toastify"; +import { Header } from "@/components/Dashboard/Header"; +import { ClassContext } from "@/context/ClassContext"; import ClassTable from "./libs/components/ClassList/ClassTable.jsx"; import Button from "@/components/Dashboard/Button"; -import {PlusCircleOutlined} from "@ant-design/icons"; +import { PlusCircleOutlined } from "@ant-design/icons"; import ClassDetail from "@/pages/Class/libs/components/modals/ClassDetail.jsx"; -import {debounce} from "lodash"; -import {ClassApi} from "@/utils/axios/ApiService.js"; -import {mappedClassData} from "@/pages/Class/libs/components/utils.js"; +import { debounce } from "lodash"; +import { ClassApi } from "@/utils/axios/ApiService.js"; +import { mappedClassData } from "@/pages/Class/libs/components/utils.js"; +import ClassFilterButton from "@/pages/Class/libs/components/ClassFilterButton.jsx"; const { Search } = Input; @@ -24,7 +25,11 @@ const ClassDashboard = () => { setIsTableLoading, setVisibleModal, setIsRefreshPage, + setRowPerPage, + filterClassData, } = useContext(ClassContext); + const [filterValues, setFilterValues] = useState([]); + const rowPerMenu = [ { value: "5", label: "5" }, { value: "10", label: "10" }, @@ -33,16 +38,16 @@ const ClassDashboard = () => { { value: "50", label: "50" }, ]; - const handleSearchChange = debounce(async ( value ) => { + const handleSearchChange = debounce(async (value) => { setTableErrorMessage(""); if (value === "") { - setIsRefreshPage(( previous ) => !previous); + setIsRefreshPage((previous) => !previous); } else { try { setIsTableLoading(true); const getClass = await ClassApi.searchClass(value); const classes = getClass.data; - const mappedClasses = classes.map(( cls, idx ) => { + const mappedClasses = classes.map((cls, idx) => { return mappedClassData(cls, idx + 1); }); setIsTableLoading(false); @@ -56,9 +61,14 @@ const ClassDashboard = () => { } }, 300); + const handleFilterChange = (values) => { + setFilterValues(values); + filterClassData(values); + }; + return (
-
+
{ {/*for desktop view*/}
- handleSearchChange(value)} - onChange={( e ) => handleSearchChange(e.target.value)} - enterButton - /> + gap="middle" + > + handleSearchChange(value)} + onChange={(e) => handleSearchChange(e.target.value)} + enterButton + /> + +
Show - setRowPerPage(value)} + /> Entries
@@ -107,12 +127,12 @@ const ClassDashboard = () => { handleSearchChange(value)} - onChange={( e ) => handleSearchChange(e.target.value)} + onSearch={(value) => handleSearchChange(value)} + onChange={(e) => handleSearchChange(e.target.value)} enterButton />
); diff --git a/src/pages/Class/libs/components/ClassFilterButton.jsx b/src/pages/Class/libs/components/ClassFilterButton.jsx new file mode 100644 index 00000000..d1c6b59f --- /dev/null +++ b/src/pages/Class/libs/components/ClassFilterButton.jsx @@ -0,0 +1,98 @@ +import { useState, useEffect, useRef } from "react"; +import { Button, Checkbox } from "antd"; +import { CaretDownFilled } from "@ant-design/icons"; +import { fetchMajorsFilter } from "@/pages/Class/libs/components/utils.js"; + +const ClassFilterButton = ({ onFilterChange }) => { + const [checkedItems, setCheckedItems] = useState([]); + const [options, setOptions] = useState([]); + const menuRef = useRef(null); + + useEffect(() => { + const getMajors = async () => { + const majors = await fetchMajorsFilter(); + const options = majors.map((major) => ({ + label: major.label, + value: major.value, + })); + setOptions(options); + }; + + getMajors(); + }, []); + + const handleCheckboxChange = (checkedValues) => { + setCheckedItems(checkedValues); + if (checkedValues.length === 0) { + onFilterChange([]); + } else { + onFilterChange(checkedValues); + } + }; + + const handleClickOutside = (event) => { + if (menuRef.current && !menuRef.current.contains(event.target)) { + menuRef.current.style.display = "none"; + } + }; + + useEffect(() => { + document.addEventListener("mousedown", handleClickOutside); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, []); + + const menu = ( + + ); + + return ( +
+ +
+ {menu} +
+
+ ); +}; + +export default ClassFilterButton; \ No newline at end of file diff --git a/src/pages/Class/libs/components/ClassList/ClassColumns.jsx b/src/pages/Class/libs/components/ClassList/ClassColumns.jsx index 82d88be1..cd059191 100644 --- a/src/pages/Class/libs/components/ClassList/ClassColumns.jsx +++ b/src/pages/Class/libs/components/ClassList/ClassColumns.jsx @@ -18,14 +18,14 @@ export const ClassColumns = ( handleModal, handleDeleteSchool ) => [ }, { title: "Majority", - dataIndex: "major", - key: "major", + dataIndex: ["majors", "major_name"], + key: "majors.major_name", }, { title: "Action", dataIndex: "actions", key: "actions", - render: (_, record) => ( + render: ( _, record ) => ( { const { setVisibleModal, visibleModal, selectedClassUUID } = useContext(ClassContext); const [classData, setClassData] = useState({}); @@ -39,13 +38,13 @@ const ClassDetail = () => { { title: 'Email', dataIndex: 'email', key: 'email' }, ]; - const dataSource = [ - { key: '1', no: '1', nip_nisn: '1234567890', name: 'John Doe', email: 'john.doe@example.com' }, - { key: '2', no: '2', nip_nisn: '2345678901', name: 'Jane Smith', email: 'jane.smith@example.com' }, - { key: '3', no: '3', nip_nisn: '3456789012', name: 'Alice Johnson', email: 'alice.johnson@example.com' }, - { key: '4', no: '4', nip_nisn: '4567890123', name: 'Bob Brown', email: 'bob.brown@example.com' }, - { key: '5', no: '5', nip_nisn: '5678901234', name: 'Charlie Davis', email: 'charlie.davis@example.com' }, - ]; + const dataSource = classData.users?.map((user, index) => ({ + key: user.uuid, + no: index + 1, + nip_nisn: user.nip_nisn, + name: user.name, + email: user.email, + })) || []; return ( { footer={null} centered loading={isDetailLoading} - style={modalStyle} + style={modalStyle} > diff --git a/src/pages/Class/libs/components/modals/ClassDetailContent.jsx b/src/pages/Class/libs/components/modals/ClassDetailContent.jsx index d4e7329b..ccc5c586 100644 --- a/src/pages/Class/libs/components/modals/ClassDetailContent.jsx +++ b/src/pages/Class/libs/components/modals/ClassDetailContent.jsx @@ -4,11 +4,11 @@ const ClassDetailContent = ({ classData, columns, dataSource }) => (

Major Code :

-

Hardcode

+

{classData.major?.major_name}

Major Name :

-

Hardcode

+

{classData.major?.major_code}

List Student :

diff --git a/src/pages/Class/libs/components/modals/CreateClass.jsx b/src/pages/Class/libs/components/modals/CreateClass.jsx index 52558b64..de45ac6c 100644 --- a/src/pages/Class/libs/components/modals/CreateClass.jsx +++ b/src/pages/Class/libs/components/modals/CreateClass.jsx @@ -85,7 +85,7 @@ const CreateClass = () => { if (field.name === "className") { formDataObj.append("class_name", field.value); } else if (field.name === "majority") { - formDataObj.append("major", field.value); + formDataObj.append("major_id", field.value); } else { formDataObj.append(field.name, field.value); } diff --git a/src/pages/Class/libs/components/modals/UpdateClass.jsx b/src/pages/Class/libs/components/modals/UpdateClass.jsx index 69a580da..8794273f 100644 --- a/src/pages/Class/libs/components/modals/UpdateClass.jsx +++ b/src/pages/Class/libs/components/modals/UpdateClass.jsx @@ -1,8 +1,8 @@ -import {Modal, Form, Input, Select} from "antd"; -import {useContext, useEffect, useState} from "react"; -import {ClassContext} from "@/context/ClassContext"; -import {fetchClassData, fetchMajors} from "@/pages/Class/libs/components/utils.js"; -import {ClassApi} from "@/utils/axios/ApiService.js"; +import { Modal, Form, Input, Select } from "antd"; +import { useContext, useEffect, useState } from "react"; +import { ClassContext } from "@/context/ClassContext"; +import { fetchClassData, fetchMajors } from "@/pages/Class/libs/components/utils.js"; +import { ClassApi } from "@/utils/axios/ApiService.js"; const UpdateClass = () => { const { @@ -22,7 +22,21 @@ const UpdateClass = () => { fetchClassData(selectedClassUUID, form, setLoading); }, [selectedClassUUID, form]); - const handleUpdateClass = async ( values ) => { + useEffect(() => { + if (selectedClassUUID) { + const fetchData = async () => { + const classD = await ClassApi.getClassById(selectedClassUUID); + form.setFieldsValue({ + className: classD.class_name, + majority: classD.major?.major_name, + classCode: classD.class_code, + }); + }; + fetchData(); + } + }, [selectedClassUUID, form]); + + const handleUpdateClass = async (values) => { closeAllModal(); try { setIsTableLoading(true); @@ -34,7 +48,7 @@ const UpdateClass = () => { const response = await ClassApi.updateClassById(selectedClassUUID, classData); const updatedClass = response.data; - const updatedClassData = classData.map(( cls ) => + const updatedClassData = classData.map((cls) => cls.uuid === selectedClassUUID ? updatedClass : cls ); setClassData(updatedClassData); @@ -115,14 +129,14 @@ const UpdateClass = () => { label="Class Code" rules={[{ required: true, message: "Please enter class code" }]} > - + - + { rules={[{ required: true, message: "Please select majority" }]} > } - status={isNIPWrong ? "error" : ""} - /> -
+ ); + }; -
-
- -
- - - + return ( + + {errorMessage && showErrorMessage(errorMessage)} + + +

Forgot Password

+

+ Enter your NIP/NISN and we’ll send you an OTP Code to the linked email + account to reset your password! +

+
+ +
({ + error: , + success: <>, + })} + > + + } + /> + + + +

+ Remember your password?{" "} + + Login + +

+
); }; diff --git a/src/pages/Class/ClassDashboard.jsx b/src/pages/Class/ClassDashboard.jsx index c0737d70..dfac0018 100644 --- a/src/pages/Class/ClassDashboard.jsx +++ b/src/pages/Class/ClassDashboard.jsx @@ -70,19 +70,19 @@ const ClassDashboard = () => {
- +
@@ -166,4 +166,4 @@ const ClassDashboard = () => { ); }; -export default ClassDashboard; \ No newline at end of file +export default ClassDashboard; diff --git a/src/pages/Internship/libs/components/DetailInternship/DetailInternship.jsx b/src/pages/Internship/libs/components/DetailInternship/DetailInternship.jsx index 6157f7e7..2a014c1e 100644 --- a/src/pages/Internship/libs/components/DetailInternship/DetailInternship.jsx +++ b/src/pages/Internship/libs/components/DetailInternship/DetailInternship.jsx @@ -5,18 +5,28 @@ import { Divider, Space, ArrowLeftOutlined, - DownOutlined, SettingOutlined, } from "@/components/components"; import SchooltechLogo from "@/assets/img/school-tech-logo.svg"; -import { useContext, useNavigate, useEffect, useState } from "@/hooks/hooks"; +import { + useContext, + useNavigate, + useEffect, + useState, + useOutletContext, + useCallback, + useBreakpoints, +} from "@/hooks/hooks"; import { InternshipRoute } from "@/enums/enums"; import { InternshipContext } from "@/context/contexts"; +import { CoordinatorLabel, DescriptionCollapse } from "./components/components"; const DetailInternship = () => { const navigate = useNavigate(); const { internshipCards, selectedInternship } = useContext(InternshipContext); const [internshipCard, setInternshipCard] = useState([]); + const { setlimitSubPagesChars, setSubPages } = useOutletContext(); + const { isMobile, isTablet, isDesktop } = useBreakpoints(); const description = "Program Internship di PT Sembrani Siber Solusiindo memberikan kesempatan bagi peserta untuk mendapatkan pengalaman kerja nyata di bidang teknologi dan desain. Program ini dimulai dengan orientasi perusahaan yang memperkenalkan struktur organisasi, visi, misi, serta tim yang terlibat. Selanjutnya, peserta akan mengikuti pelatihan teknis sesuai dengan bidangnya, seperti UI/UX atau pengembangan perangkat lunak, dan langsung terlibat dalam proyek-proyek nyata yang sedang berjalan. Setiap peserta didampingi oleh mentor yang memberikan bimbingan dan evaluasi secara berkala. Selain itu, peserta juga mengikuti rapat evaluasi mingguan untuk melaporkan progres dan mendiskusikan tantangan yang dihadapi. Program ini juga menekankan pengembangan soft skill, termasuk komunikasi, kerja tim, dan problem solving. Di akhir program, peserta diwajibkan mempresentasikan hasil kerjanya dan akan menerima umpan balik serta sertifikat kelulusan jika memenuhi kriteria."; @@ -29,6 +39,18 @@ const DetailInternship = () => { navigate(InternshipRoute.INTERNSHIP); }; + const setLimitHeaderChars = useCallback(() => { + if (isMobile) { + setlimitSubPagesChars(5); + } + if (isTablet) { + setlimitSubPagesChars(20); + } + if (isDesktop) { + setlimitSubPagesChars(0); + } + }, [setlimitSubPagesChars, isMobile, isTablet, isDesktop]); + useEffect(() => { const findInternshipCard = internshipCards.find( (card) => card.id === selectedInternship @@ -36,13 +58,31 @@ const DetailInternship = () => { setInternshipCard(findInternshipCard); }, [internshipCards, selectedInternship]); + useEffect(() => { + setLimitHeaderChars(); + }, [setLimitHeaderChars]); + + useEffect(() => { + //! it can be duplicate sub pages because render is run twice + setSubPages((prev) => [ + ...prev, + { + title: "Detail Intern SchoolTech", + path: "program-management/internship", + }, + ]); + //! ========end======== + }, [setSubPages]); + return ( {/* title */} -

Detail Internship Program

+

+ Detail Internship Program +

{/* logo section */} @@ -50,8 +90,12 @@ const DetailInternship = () => { schooltech logo -

{internshipCard.title}

-
SchoolTech Indonesia
+

+ {internshipCard.title} +

+
+ Duration ({internshipCard.startDate} - {internshipCard.endDate}) +
{/* divider */} @@ -60,13 +104,7 @@ const DetailInternship = () => { {/* description */} - -

Deskripsi:

- -
-

- {description} -

+ {/* divider */}
@@ -113,30 +151,9 @@ const DetailInternship = () => {
{/* coordinator */} - +

Coordinator:

- - - Sendy Joan Kevin M.M.T, P.hd - | - - Akuntansi - - - - Sendy Joan Kevin M.M.T, P.hd - | - - Bisnis - - - +
{/* divider */} @@ -149,6 +166,7 @@ const DetailInternship = () => { icon={} iconPosition="start" onClick={handleClickActivity} + className="w-full sm:w-1/2 min-920:w-1/4" />
diff --git a/src/pages/Internship/libs/components/DetailInternship/components/CoordinatorLabel/CoordinatorLabel.jsx b/src/pages/Internship/libs/components/DetailInternship/components/CoordinatorLabel/CoordinatorLabel.jsx new file mode 100644 index 00000000..c90982a5 --- /dev/null +++ b/src/pages/Internship/libs/components/DetailInternship/components/CoordinatorLabel/CoordinatorLabel.jsx @@ -0,0 +1,25 @@ +import { Flex, Typography } from "@/components/components"; + +const { Text } = Typography; + +const CoordinatorLabel = () => { + return ( + + {/* name */} + + + Sendy johan + + + | + {/* major */} + + + Akuntansi + + + + ); +}; + +export { CoordinatorLabel }; diff --git a/src/pages/Internship/libs/components/DetailInternship/components/DescriptionCollapse/DescriptionCollapse.jsx b/src/pages/Internship/libs/components/DetailInternship/components/DescriptionCollapse/DescriptionCollapse.jsx new file mode 100644 index 00000000..d4a0520f --- /dev/null +++ b/src/pages/Internship/libs/components/DetailInternship/components/DescriptionCollapse/DescriptionCollapse.jsx @@ -0,0 +1,47 @@ +import { Collapse, DownOutlined, LeftOutlined } from "@/components/components"; + +const DescriptionCollapse = ({ description }) => { + const label = ( +

+ Deskripsi +

+ ); + + const children = ( +

+ {description} +

+ ); + + const styles = { + header: { + padding: 0, + }, + body: { + padding: 0, + }, + }; + + const items = [ + { + key: "1", + label, + children, + styles, + }, + ]; + + return ( + + panelProps.isActive ? : + } + bordered={false} + className="" + /> + ); +}; + +export { DescriptionCollapse }; diff --git a/src/pages/Internship/libs/components/DetailInternship/components/components.js b/src/pages/Internship/libs/components/DetailInternship/components/components.js new file mode 100644 index 00000000..da167496 --- /dev/null +++ b/src/pages/Internship/libs/components/DetailInternship/components/components.js @@ -0,0 +1,2 @@ +export { CoordinatorLabel } from "./CoordinatorLabel/CoordinatorLabel"; +export { DescriptionCollapse } from "./DescriptionCollapse/DescriptionCollapse"; diff --git a/src/pages/Internship/libs/components/ListInternship/ListInternship.jsx b/src/pages/Internship/libs/components/ListInternship/ListInternship.jsx index 5041fb44..98666363 100644 --- a/src/pages/Internship/libs/components/ListInternship/ListInternship.jsx +++ b/src/pages/Internship/libs/components/ListInternship/ListInternship.jsx @@ -6,7 +6,14 @@ import { PlusCircleOutlined, CustomButton, } from "@/components/components"; -import { useState, useContext, useEffect } from "@/hooks/hooks"; +import { + useState, + useContext, + useEffect, + useOutletContext, + useBreakpoints, + useCallback, +} from "@/hooks/hooks"; import { EmptyInternship, InternshipCard, @@ -21,13 +28,15 @@ const ListInternship = () => { const { setVisibleModal, internshipCards } = useContext(InternshipContext); const [isInternshipEmpty, setIntershipEmpty] = useState(false); const [isNotFound, setIsNotFound] = useState(false); + const { setlimitSubPagesChars, setSubPages } = useOutletContext(); + const { isMobileMin, isMobile, isTablet, isDesktop } = useBreakpoints(); const rowPerMenu = [ - { value: "5", label: "5" }, - { value: "10", label: "10" }, - { value: "15", label: "15" }, + { value: "4", label: "4" }, + { value: "8", label: "8" }, + { value: "12", label: "12" }, + { value: "16", label: "16" }, { value: "20", label: "20" }, - { value: "50", label: "50" }, ]; const [searchInternshipCards, setSearchInternshipCards] = @@ -66,31 +75,50 @@ const ListInternship = () => { }); }; + const setLimitHeaderChars = useCallback(() => { + if (isMobileMin) { + setlimitSubPagesChars(3); + } + if (isMobile) { + setlimitSubPagesChars(10); + } + if (isTablet) { + setlimitSubPagesChars(18); + } + if (isDesktop) { + setlimitSubPagesChars(0); + } + }, [setlimitSubPagesChars, isMobile, isTablet, isDesktop, isMobileMin]); + useEffect(() => { if (internshipCards.length <= 0) { setIntershipEmpty(true); } }, [internshipCards]); + useEffect(() => { + setLimitHeaderChars(); + setSubPages([ + { title: "Program Management", path: "program-management/internship" }, + ]); + }, [setLimitHeaderChars, setSubPages]); + return ( <> - - - handleSearchChange(value)} - onChange={(e) => handleSearchChange(e.target.value)} - enterButton - /> -

- List Program{" "} - - ({searchInternshipCards.length}) - -

-
- +

List Program

+ + handleSearchChange(value)} + onChange={(e) => handleSearchChange(e.target.value)} + enterButton + /> {!isInternshipEmpty && ( { icon={} iconPosition="end" onClick={handleCreateInternship} + className="w-full sm:w-auto" /> )}
Show + -
    - - - - - - - - - - - - - - - - - - - - + + + + + - - - + + + + - - - + + - - )} - /> +
+ + + + + + + ); }; diff --git a/src/pages/Opportunity/libs/components/UpdateOpportunity/UpdateOpportunity.jsx b/src/pages/Opportunity/libs/components/UpdateOpportunity/UpdateOpportunity.jsx index 63e28397..f61731a5 100644 --- a/src/pages/Opportunity/libs/components/UpdateOpportunity/UpdateOpportunity.jsx +++ b/src/pages/Opportunity/libs/components/UpdateOpportunity/UpdateOpportunity.jsx @@ -1,19 +1,17 @@ import { useOpportunityContext } from "@/context/OpportunityContext"; -import { Cross } from "@/pages/User/libs/utils/customIcon"; import { handleClose } from "@/pages/User/libs/utils/utils"; import { Button, Flex, Form, + InfoCircleFilled, Input, Modal, Select, } from "@/components/components"; -import Title from "antd/es/typography/Title"; import { useCallback, useEffect, useState } from "@/hooks/hooks"; import { MENTOR_LIST } from "../../utils/dummyData"; import { QuillEditor } from "@/components/components"; -import { InfoCircleFilled } from "@ant-design/icons"; import { OpportunityApi } from "@/utils/axios/ApiService"; // ====================================== @@ -24,8 +22,13 @@ import { OpportunityApi } from "@/utils/axios/ApiService"; // 2. Handling the unshowed data payload {mentor, description} const UpdateOpportunity = ({ opportunityData }) => { - const { isModalOpen, setIsModalOpen, setModalType, setSelectedOpportunity } = - useOpportunityContext(); + const { + isModalOpen, + setIsModalOpen, + setModalType, + selectedOpportunity, + setSelectedOpportunity, + } = useOpportunityContext(); const [form] = Form.useForm(); @@ -55,12 +58,10 @@ const UpdateOpportunity = ({ opportunityData }) => { useEffect(() => { const fetchOpportunityData = async () => { try { - const response = await OpportunityApi.getOpportunityById( + const opportunity = await OpportunityApi.getOpportunityById( opportunityData.id ); - if (response) { - const opportunity = response; - + if (opportunity) { form.setFieldsValue({ id: opportunity.opportunity_id, code: opportunity.code, @@ -71,6 +72,7 @@ const UpdateOpportunity = ({ opportunityData }) => { school_id: opportunity.school_id, }); } + setSelectedOpportunity(opportunity); } catch (error) { return error; // console.error("Failed to fetch opportunity data:", error); @@ -80,7 +82,7 @@ const UpdateOpportunity = ({ opportunityData }) => { if (opportunityData.id) { fetchOpportunityData(); } - }, [form, opportunityData.id]); + }, [form, opportunityData.id, setSelectedOpportunity]); const handleModal = useCallback( (type, opportunity) => { @@ -164,139 +166,131 @@ const UpdateOpportunity = ({ opportunityData }) => { return ( ( -
- - - Edit Opportunity - - + + -
    - - - - - - - - - - - - - - - - - - - - + + + + + - - - + + + + - - - + + form.setFieldsValue({ description: content }) + } + /> + - - )} - /> +
+ + + + + + +
); }; diff --git a/src/pages/School/SchoolDashboard.jsx b/src/pages/School/SchoolDashboard.jsx index 959d0562..c1362c4e 100644 --- a/src/pages/School/SchoolDashboard.jsx +++ b/src/pages/School/SchoolDashboard.jsx @@ -60,7 +60,7 @@ const SchoolDashboard = () => { return (
-
+
{ iconPosition="end" />
{ footer={ <> @@ -560,7 +559,9 @@ const MentorDashboard = () => { <> @@ -568,7 +569,7 @@ const MentorDashboard = () => { } >
- +

Delete Mentor Data

diff --git a/src/utils/axios/api/Auth.js b/src/utils/axios/api/Auth.js index 9b5f7c84..50a1edea 100644 --- a/src/utils/axios/api/Auth.js +++ b/src/utils/axios/api/Auth.js @@ -19,7 +19,7 @@ class Auth { ); return response.data; } catch (error) { - throw { response: error.response.data }; + throw { response: error.response }; } } diff --git a/tailwind.config.js b/tailwind.config.js index 7ddc4685..6a4c75a9 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -3,6 +3,14 @@ export default { content: ["./index.html", "./src/**/*.{js,jsx,ts,tsx}"], theme: { extend: { + screens: { + "min-300": "300px", + "min-360": "360px", + "min-400": "400px", + "min-460": "460px", + "min-840": "840px", + "min-920": "920px", + }, fontFamily: { nunito: ["Nunito"], }, @@ -41,6 +49,7 @@ export default { colorSplit: "#0000000F", // antd color gray3: "#f5f5f5", + blue9: "#002c8c", }, spacing: { 4.5: "1.125rem", diff --git a/yarn.lock b/yarn.lock index 86b4c654..376f3825 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1449,6 +1449,11 @@ crypto2@2.0.0: node-rsa "0.4.2" util.promisify "1.0.0" +css-mediaquery@^0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/css-mediaquery/-/css-mediaquery-0.1.2.tgz" + integrity sha512-COtn4EROW5dBGlE/4PiKnh6rZpAPxDeFLaEEwt4i10jpDMFt2EhQGS79QmmrO+iKCHv0PU/HrOWEhijFd1x99Q== + cssesc@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" @@ -2433,6 +2438,11 @@ http-errors@~1.6.2, http-errors@~1.6.3, http-errors@1.6.3: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" +hyphenate-style-name@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz" + integrity sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw== + iconv-lite@0.4.23: version "0.4.23" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz" @@ -2987,6 +2997,13 @@ lusca@1.6.1: dependencies: tsscmp "^1.0.5" +matchmediaquery@^0.4.2: + version "0.4.2" + resolved "https://registry.npmjs.org/matchmediaquery/-/matchmediaquery-0.4.2.tgz" + integrity sha512-wrZpoT50ehYOudhDjt/YvUJc6eUzcdFPdmbizfgvswCKNHD1/OBOHYJpHie+HXpu6bSkEGieFMYk6VuutaiRfA== + dependencies: + css-mediaquery "^0.1.2" + media-typer@0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" @@ -3445,7 +3462,7 @@ prop-types-extra@^1.1.0: react-is "^16.3.2" warning "^4.0.0" -prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.8.1: +prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -3953,6 +3970,16 @@ react-refresh@^0.14.2: resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz" integrity sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA== +react-responsive@^10.0.0: + version "10.0.0" + resolved "https://registry.npmjs.org/react-responsive/-/react-responsive-10.0.0.tgz" + integrity sha512-N6/UiRLGQyGUqrarhBZmrSmHi2FXSD++N5VbSKsBBvWfG0ZV7asvUBluSv5lSzdMyEVjzZ6Y8DL4OHABiztDOg== + dependencies: + hyphenate-style-name "^1.0.0" + matchmediaquery "^0.4.2" + prop-types "^15.6.1" + shallow-equal "^3.1.0" + react-router-dom@^6.23.1: version "6.23.1" resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.23.1.tgz" @@ -4308,6 +4335,11 @@ sha-1@0.1.1: resolved "https://registry.npmjs.org/sha-1/-/sha-1-0.1.1.tgz" integrity sha512-dexizf3hB7d4Jq6Cd0d/NYQiqgEqIfZIpuMfwPfvSb6h06DZKmHyUe55jYwpHC12R42wpqXO6ouhiBpRzIcD/g== +shallow-equal@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/shallow-equal/-/shallow-equal-3.1.0.tgz" + integrity sha512-pfVOw8QZIXpMbhBWvzBISicvToTiM5WBF1EeAUZDDSb5Dt29yl4AYbyywbJFSEsRUMr7gJaxqCdr4L3tQf9wVg== + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" From 35e04ab9b5e813443fba0258f3b8264bec133cd2 Mon Sep 17 00:00:00 2001 From: Fouz97 Date: Wed, 13 Nov 2024 08:14:13 +0700 Subject: [PATCH 04/19] FIX :: Class Management Integrating --- src/pages/Class/ClassDashboard.jsx | 85 ++++++++++--------- .../components/modals/ClassDetailContent.jsx | 4 +- .../libs/components/modals/UpdateClass.jsx | 51 ++++++----- 3 files changed, 77 insertions(+), 63 deletions(-) diff --git a/src/pages/Class/ClassDashboard.jsx b/src/pages/Class/ClassDashboard.jsx index dfac0018..2421fa41 100644 --- a/src/pages/Class/ClassDashboard.jsx +++ b/src/pages/Class/ClassDashboard.jsx @@ -1,17 +1,17 @@ -import { useContext, useState } from "react"; -import { Select, Input, Flex } from "antd"; +import {useContext, useState} from "react"; +import {Select, Input, Flex} from "antd"; import CreateClass from "./libs/components/modals/CreateClass.jsx"; import UpdateClass from "@/pages/Class/libs/components/modals/UpdateClass.jsx"; -import { ToastContainer } from "react-toastify"; -import { Header } from "@/components/Dashboard/Header"; -import { ClassContext } from "@/context/ClassContext"; +import {ToastContainer} from "react-toastify"; +import {Header} from "@/components/Dashboard/Header"; +import {ClassContext} from "@/context/ClassContext"; import ClassTable from "./libs/components/ClassList/ClassTable.jsx"; import Button from "@/components/Dashboard/Button"; -import { PlusCircleOutlined } from "@ant-design/icons"; +import {PlusCircleOutlined} from "@ant-design/icons"; import ClassDetail from "@/pages/Class/libs/components/modals/ClassDetail.jsx"; -import { debounce } from "lodash"; -import { ClassApi } from "@/utils/axios/ApiService.js"; -import { mappedClassData } from "@/pages/Class/libs/components/utils.js"; +import {debounce} from "lodash"; +import {ClassApi} from "@/utils/axios/ApiService.js"; +import {mappedClassData} from "@/pages/Class/libs/components/utils.js"; import ClassFilterButton from "@/pages/Class/libs/components/ClassFilterButton.jsx"; const { Search } = Input; @@ -38,16 +38,16 @@ const ClassDashboard = () => { { value: "50", label: "50" }, ]; - const handleSearchChange = debounce(async (value) => { + const handleSearchChange = debounce(async ( value ) => { setTableErrorMessage(""); if (value === "") { - setIsRefreshPage((previous) => !previous); + setIsRefreshPage(( previous ) => !previous); } else { try { setIsTableLoading(true); const getClass = await ClassApi.searchClass(value); const classes = getClass.data; - const mappedClasses = classes.map((cls, idx) => { + const mappedClasses = classes.map(( cls, idx ) => { return mappedClassData(cls, idx + 1); }); setIsTableLoading(false); @@ -61,28 +61,33 @@ const ClassDashboard = () => { } }, 300); - const handleFilterChange = (values) => { + const handleFilterChange = ( values ) => { setFilterValues(values); filterClassData(values); }; return (

-
+
- +
@@ -95,14 +100,14 @@ const ClassDashboard = () => { > handleSearchChange(value)} - onChange={(e) => handleSearchChange(e.target.value)} + onSearch={( value ) => handleSearchChange(value)} + onChange={( e ) => handleSearchChange(e.target.value)} enterButton /> - +
@@ -127,12 +132,12 @@ const ClassDashboard = () => { handleSearchChange(value)} - onChange={(e) => handleSearchChange(e.target.value)} + onSearch={( value ) => handleSearchChange(value)} + onChange={( e ) => handleSearchChange(e.target.value)} enterButton />
- +
{visibleModal === 1 ? ( - + ) : visibleModal === 2 ? ( - + ) : visibleModal === 3 ? ( - + ) : null}
); diff --git a/src/pages/Class/libs/components/modals/ClassDetailContent.jsx b/src/pages/Class/libs/components/modals/ClassDetailContent.jsx index ccc5c586..20e93b3b 100644 --- a/src/pages/Class/libs/components/modals/ClassDetailContent.jsx +++ b/src/pages/Class/libs/components/modals/ClassDetailContent.jsx @@ -4,11 +4,11 @@ const ClassDetailContent = ({ classData, columns, dataSource }) => (

Major Code :

-

{classData.major?.major_name}

+

{classData.majors?.major_name}

Major Name :

-

{classData.major?.major_code}

+

{classData.majors?.major_code}

List Student :

diff --git a/src/pages/Class/libs/components/modals/UpdateClass.jsx b/src/pages/Class/libs/components/modals/UpdateClass.jsx index 8794273f..082a4159 100644 --- a/src/pages/Class/libs/components/modals/UpdateClass.jsx +++ b/src/pages/Class/libs/components/modals/UpdateClass.jsx @@ -1,8 +1,8 @@ -import { Modal, Form, Input, Select } from "antd"; -import { useContext, useEffect, useState } from "react"; -import { ClassContext } from "@/context/ClassContext"; -import { fetchClassData, fetchMajors } from "@/pages/Class/libs/components/utils.js"; -import { ClassApi } from "@/utils/axios/ApiService.js"; +import {Modal, Form, Input, Select} from "antd"; +import {useContext, useEffect, useState} from "react"; +import {ClassContext} from "@/context/ClassContext"; +import {fetchClassData, fetchMajors} from "@/pages/Class/libs/components/utils.js"; +import {ClassApi} from "@/utils/axios/ApiService.js"; const UpdateClass = () => { const { @@ -11,6 +11,7 @@ const UpdateClass = () => { setIsTableLoading, selectedClassUUID, setClassData, + getAllClasses, } = useContext(ClassContext); const [form] = Form.useForm(); @@ -28,7 +29,7 @@ const UpdateClass = () => { const classD = await ClassApi.getClassById(selectedClassUUID); form.setFieldsValue({ className: classD.class_name, - majority: classD.major?.major_name, + majority: classD.majors?.major_name, classCode: classD.class_code, }); }; @@ -36,30 +37,38 @@ const UpdateClass = () => { } }, [selectedClassUUID, form]); - const handleUpdateClass = async (values) => { + const handleUpdateClass = async ( values ) => { closeAllModal(); try { setIsTableLoading(true); const classData = { class_name: values.className, - major: values.majority, + major_id: values.majority, class_code: values.classCode, }; const response = await ClassApi.updateClassById(selectedClassUUID, classData); - const updatedClass = response.data; - const updatedClassData = classData.map((cls) => - cls.uuid === selectedClassUUID ? updatedClass : cls + const { success, message, data: updatedClass } = response; + + if (success) { + setClassData((prevClassData) => + prevClassData.map((cls) => + cls.uuid === selectedClassUUID ? { ...cls, ...updatedClass } : cls + ) ); - setClassData(updatedClassData); - Modal.success({ - title: "Update Class Data", - content: "Data updated successfully!", - centered: true, - }); + getAllClasses(); + + Modal.success({ + title: "Update Class Data", + content: message || "Data updated successfully!", + centered: true, + }); + } else { + throw new Error(message || "An error occurred while updating the class."); + } } catch (error) { - const errorMessage = error.response?.data?.message || "An error occurred while updating the class."; + const errorMessage = error.response?.data?.message || error.message || "An error occurred while updating the class."; Modal.error({ title: "Update Class Data", content: errorMessage, @@ -129,14 +138,14 @@ const UpdateClass = () => { label="Class Code" rules={[{ required: true, message: "Please enter class code" }]} > - + - + { rules={[{ required: true, message: "Please select majority" }]} > setRowPerPage(value)} - /> - Entries -
-
- - {/*for mobile view*/} -
- handleSearchChange(value)} - onChange={( e ) => handleSearchChange(e.target.value)} - enterButton - /> -
- - ); + {/*for mobile view*/} +
+ handleSearchChange(value)} + onChange={(e) => handleSearchChange(e.target.value)} + enterButton + /> + } + type="primary" + label="Create Class" + iconPosition="end" + className="py-5 px-5 w-full" + onClick={() => setVisibleModal(1)} + /> +
+ Show + { className="py-5 px-5 w-full" onClick={() => setVisibleModal(1)} /> -
+ Show - } - /> - {field.errorMessage && ( - {field.errorMessage} - )} -
- ); - })} - - - ); + const {visibleModal, setVisibleModal, setIsTableLoading, setIsRefreshPage} = + useContext(SchoolContext); + + const schoolValidations = { + schoolNameValidations, + schoolAddressValidations, + phoneNumberValidations, + startMemberValidations, + endMemberValidations, + }; + + const {formData, setFormData} = useSchoolForm({schoolValidations}); + const [isButtonDisabled, setIsButtonDisabled] = useState(true); + + const handleChangeTime = (dateString, dateName) => { + setFormData((prevForm) => { + const newDate = prevForm.map((field) => { + const {errorMessage, isError} = validationInput( + field.validations, + dateString, + dateName + ); + return field.name == dateName + ? {...field, isError, value: dateString, errorMessage} + : field; + }); + + setIsButtonDisabled(!isFormValid(formData, newDate)); + return newDate; + }); + }; + + const handleChange = (e) => { + let {name, value} = e.target; + + setFormData((prevForm) => { + const newFormData = prevForm.map((field) => { + const {errorMessage, isError} = validationInput( + field.validations, + value, + name + ); + + const newValue = + name === "phone_number" ? formatPhoneNumber(value) : value; + + return field.name == name + ? {...field, value: newValue, errorMessage, isError} + : field; + }); + + setIsButtonDisabled(!isFormValid(formData, newFormData)); + return newFormData; + }); + }; + + const handleCreateSchool = async () => { + closeAllModal(); + try { + setIsTableLoading(true); + const newSchoolData = formData.reduce((acc, field) => { + const {value, name} = field; + const newValue = + field.name === "phone_number" + ? formatPhoneNumberNoSimbol(value) + : value; + acc[name] = newValue; + return acc; + }, {}); + await SchoolApi.createSchool(newSchoolData); + Modal.success({ + title: "Create School Data", + content: "Data added successfully!", + centered: true, + onOk: closeAllModal, + }); + } catch (error) { + const response = error.response; + Modal.error({ + title: "Create School Data", + content: response.message, + centered: true, + onOk: closeAllModal, + }); + } finally { + setIsTableLoading(false); + setIsRefreshPage((prev) => !prev); + } + }; + + const handleSubmit = (e) => { + e.preventDefault(); + Modal.info({ + title: "Create School", + content: "Are you sure the data correct?", + okCancel: true, + onOk: handleCreateSchool, + centered: true, + }); + }; + + const handleClose = (e) => { + e.preventDefault(); + Modal.warning({ + title: "Create School", + content: "Are you sure you want to exit? The data will not be saved.", + okCancel: true, + centered: true, + onOk: closeAllModal, + width: 500, + }); + }; + + const closeAllModal = () => { + setVisibleModal(0); + Modal.destroyAll(); + }; + + return ( + +
+ {formData.map((field, i) => { + return field.type == "date" ? ( + + + + handleChangeTime(dateString, field.name) + } + required + /> + {field.errorMessage && ( + {field.errorMessage} + )} + + ) : ( +
+

+ * {field.label} +

+ + } + /> + {field.errorMessage && ( + {field.errorMessage} + )} +
+ ); + })} +
+
+ ); }; -export { CreateSchool }; +export {CreateSchool}; diff --git a/yarn.lock b/yarn.lock index e8244230..0e8eb8ae 100644 --- a/yarn.lock +++ b/yarn.lock @@ -380,10 +380,10 @@ resolved "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz" integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg== -"@esbuild/linux-x64@0.21.5": +"@esbuild/win32-x64@0.21.5": version "0.21.5" - resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz" - integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== + resolved "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" @@ -510,21 +510,6 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@mapbox/node-pre-gyp@^1.0.0": - version "1.0.11" - resolved "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz" - integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ== - dependencies: - detect-libc "^2.0.0" - https-proxy-agent "^5.0.0" - make-dir "^3.1.0" - node-fetch "^2.6.7" - nopt "^5.0.0" - npmlog "^5.0.1" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.11" - "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -672,15 +657,10 @@ uncontrollable "^8.0.1" warning "^4.0.3" -"@rollup/rollup-linux-x64-gnu@4.24.0": +"@rollup/rollup-win32-x64-msvc@4.24.0": version "4.24.0" - resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz" - integrity sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A== - -"@rollup/rollup-linux-x64-musl@4.24.0": - version "4.24.0" - resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz" - integrity sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ== + resolved "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz" + integrity sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw== "@swc/helpers@^0.5.0": version "0.5.13" @@ -792,11 +772,6 @@ resolved "https://registry.npmjs.org/@wojtekmaj/react-hooks/-/react-hooks-1.21.0.tgz" integrity sha512-lxZgdVbnFROsaNa3y6nqYFwoajnC5kN41+UdbnTyRyc1O7l30/nH4kgslPQjTPBYxBq+PRT4lYg3fFYVdipD2Q== -abbrev@1: - version "1.1.1" - resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - accepts@~1.3.5: version "1.3.8" resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" @@ -815,13 +790,6 @@ acorn-jsx@^5.3.2: resolved "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz" integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== -agent-base@6: - version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - ajv@^6.12.4: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" @@ -962,19 +930,6 @@ app-root-path@2.1.0: resolved "https://registry.npmjs.org/app-root-path/-/app-root-path-2.1.0.tgz" integrity sha512-z5BqVjscbjmJBybKlICogJR2jCr2q/Ixu7Pvui5D4y97i7FLsJlvEG9XOR/KJRlkxxZz7UaaS2TMwQh1dRJ2dA== -"aproba@^1.0.3 || ^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - -are-we-there-yet@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz" - integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - arg@^5.0.2: version "5.0.2" resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz" @@ -1270,15 +1225,6 @@ caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001663: resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001666.tgz" integrity sha512-gD14ICmoV5ZZM1OdzPWmpx+q4GyefaK06zi8hmfHV5xe4/2nOQX3+Dw5o+fSqOws2xVwL9j+anOPFwHzdEdV4g== -canvas@^2.11.2: - version "2.11.2" - resolved "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz" - integrity sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw== - dependencies: - "@mapbox/node-pre-gyp" "^1.0.0" - nan "^2.17.0" - simple-get "^3.0.3" - chalk@^2.4.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" @@ -1329,11 +1275,6 @@ chokidar@^4.0.0: optionalDependencies: fsevents "~2.3.2" -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - classnames@^2.2.1, classnames@^2.2.3, classnames@^2.2.5, classnames@^2.2.6, classnames@^2.3.1, classnames@^2.3.2, classnames@^2.5.1, classnames@2.x: version "2.5.1" resolved "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz" @@ -1373,11 +1314,6 @@ color-name@1.1.3: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== -color-support@^1.1.2: - version "1.1.3" - resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" @@ -1434,11 +1370,6 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -console-control-strings@^1.0.0, console-control-strings@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== - content-disposition@0.5.2: version "0.5.2" resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz" @@ -1626,7 +1557,7 @@ dayjs@^1.11.11, dayjs@^1.11.13, "dayjs@>= 1.x": resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz" integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== -debug@^4.1.0, debug@^4.3.1, debug@^4.3.2, debug@4: +debug@^4.1.0, debug@^4.3.1, debug@^4.3.2: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -1640,13 +1571,6 @@ debug@2.6.9: dependencies: ms "2.0.0" -decompress-response@^4.2.0: - version "4.2.1" - resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz" - integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== - dependencies: - mimic-response "^2.0.0" - deep-equal@^1.0.1: version "1.1.2" resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.2.tgz" @@ -1687,11 +1611,6 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - depd@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" @@ -1707,11 +1626,6 @@ destroy@~1.0.4: resolved "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz" integrity sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg== -detect-libc@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz" - integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== - didyoumean@^1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz" @@ -2326,13 +2240,6 @@ fresh@0.5.2: resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" @@ -2358,21 +2265,6 @@ functions-have-names@^1.2.3: resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== -gauge@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz" - integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.2" - console-control-strings "^1.0.0" - has-unicode "^2.0.1" - object-assign "^4.1.1" - signal-exit "^3.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.2" - gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" @@ -2519,11 +2411,6 @@ has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: dependencies: has-symbols "^1.0.3" -has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - hase@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/hase/-/hase-2.0.0.tgz" @@ -2556,14 +2443,6 @@ http-errors@~1.6.2, http-errors@~1.6.3, http-errors@1.6.3: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - hyphenate-style-name@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz" @@ -3133,13 +3012,6 @@ make-cancellable-promise@^1.3.1: resolved "https://registry.npmjs.org/make-cancellable-promise/-/make-cancellable-promise-1.3.2.tgz" integrity sha512-GCXh3bq/WuMbS+Ky4JBPW1hYTOU+znU+Q5m9Pu+pI8EoUqIHk9+tviOKC6/qhHh8C4/As3tzJ69IF32kdz85ww== -make-dir@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - make-event-props@^1.6.0: version "1.6.2" resolved "https://registry.npmjs.org/make-event-props/-/make-event-props-1.6.2.tgz" @@ -3207,11 +3079,6 @@ mime@1.4.1: resolved "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz" integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== -mimic-response@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz" - integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== - minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" @@ -3226,36 +3093,11 @@ minimatch@^9.0.4: dependencies: brace-expansion "^2.0.1" -minipass@^3.0.0: - version "3.3.6" - resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - "minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: version "7.1.2" resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== -minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== - -minizlib@^2.1.1: - version "2.1.2" - resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mkdirp@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - "moment@>= 2.x", moment@2.22.2: version "2.22.2" resolved "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz" @@ -3291,11 +3133,6 @@ mz@^2.7.0: object-assign "^4.0.1" thenify-all "^1.0.0" -nan@^2.17.0: - version "2.22.0" - resolved "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz" - integrity sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw== - nanoid@^3.3.7: version "3.3.7" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz" @@ -3316,13 +3153,6 @@ nocache@2.0.0: resolved "https://registry.npmjs.org/nocache/-/nocache-2.0.0.tgz" integrity sha512-YdKcy2x0dDwOh+8BEuHvA+mnOKAhmMQDgKBOCUGaLpewdmsRYguYZSom3yA+/OrE61O/q+NMQANnun65xpI1Hw== -node-fetch@^2.6.7: - version "2.7.0" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - node-releases@^2.0.18: version "2.0.18" resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz" @@ -3340,13 +3170,6 @@ node-statsd@0.1.1: resolved "https://registry.npmjs.org/node-statsd/-/node-statsd-0.1.1.tgz" integrity sha512-QDf6R8VXF56QVe1boek8an/Rb3rSNaxoFWb7Elpsv2m1+Noua1yy0F1FpKpK5VluF8oymWM4w764A4KsYL4pDg== -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" @@ -3357,16 +3180,6 @@ normalize-range@^0.1.2: resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== -npmlog@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz" - integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== - dependencies: - are-we-there-yet "^2.0.0" - console-control-strings "^1.1.0" - gauge "^3.0.0" - set-blocking "^2.0.0" - object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" @@ -3458,7 +3271,7 @@ on-headers@~1.0.1: resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== -once@^1.3.0, once@^1.3.1: +once@^1.3.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -4294,15 +4107,6 @@ readable-stream@^3.0.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - "readable-stream@1.x >=1.1.9": version "1.1.14" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz" @@ -4522,16 +4326,11 @@ semver@^5.6.0: resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.0.0, semver@^6.3.1: +semver@^6.3.1: version "6.3.1" resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.5: - version "7.6.3" - resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz" - integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== - send@0.16.2: version "0.16.2" resolved "https://registry.npmjs.org/send/-/send-0.16.2.tgz" @@ -4561,11 +4360,6 @@ serve-static@1.13.2: parseurl "~1.3.2" send "0.16.2" -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - set-function-length@^1.2.1: version "1.2.2" resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz" @@ -4625,30 +4419,11 @@ side-channel@^1.0.4, side-channel@^1.0.6: get-intrinsic "^1.2.4" object-inspect "^1.13.1" -signal-exit@^3.0.0: - version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - signal-exit@^4.0.1: version "4.1.0" resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^3.0.3: - version "3.1.1" - resolved "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz" - integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA== - dependencies: - decompress-response "^4.2.0" - once "^1.3.1" - simple-concat "^1.0.0" - source-map-js@^1.2.1, "source-map-js@>=0.6.2 <2.0.0": version "1.2.1" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz" @@ -4709,15 +4484,6 @@ string-convert@^0.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -"string-width@^1.0.2 || 2 || 3 || 4": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^4.1.0: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" @@ -4727,15 +4493,6 @@ string-width@^4.1.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" @@ -4955,18 +4712,6 @@ tailwindcss@^3.4.10: resolve "^1.22.2" sucrase "^3.32.0" -tar@^6.1.11: - version "6.2.1" - resolved "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz" - integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^5.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - text-table@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" @@ -5018,11 +4763,6 @@ toggle-selection@^1.0.6: resolved "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz" integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - ts-interface-checker@^0.1.9: version "0.1.13" resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz" @@ -5223,19 +4963,6 @@ warning@^4.0.0, warning@^4.0.3: dependencies: loose-envify "^1.0.0" -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" @@ -5293,13 +5020,6 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -wide-align@^1.1.2: - version "1.1.5" - resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - word-wrap@^1.2.5: version "1.2.5" resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz" @@ -5340,11 +5060,6 @@ yallist@^3.0.2: resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - yaml@^1.10.0: version "1.10.2" resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" From 0ed775f7981c145b0a890b872bed2831e1924534 Mon Sep 17 00:00:00 2001 From: Fouz7 Date: Fri, 29 Nov 2024 09:10:32 +0700 Subject: [PATCH 11/19] Refactor :: Class Management --- src/hooks/class/useClass.js | 2 +- src/pages/Class/ClassDashboard.jsx | 4 ++-- src/pages/Class/libs/components/ClassList/ClassHeader.jsx | 2 ++ src/pages/Class/libs/components/modals/CreateClass.jsx | 3 +-- src/pages/Class/libs/components/modals/UpdateClass.jsx | 3 +-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hooks/class/useClass.js b/src/hooks/class/useClass.js index 7e7178ac..e7535b48 100644 --- a/src/hooks/class/useClass.js +++ b/src/hooks/class/useClass.js @@ -1,5 +1,5 @@ import { useCallback, useState } from "react"; -import { ClassApi } from "@/utils/axios/ApiService.js"; +import { ClassApi } from "@/utils/utils"; import { mappedClassData } from "@/utils/utils"; const useClass = () => { diff --git a/src/pages/Class/ClassDashboard.jsx b/src/pages/Class/ClassDashboard.jsx index cc36a54b..71ae017f 100644 --- a/src/pages/Class/ClassDashboard.jsx +++ b/src/pages/Class/ClassDashboard.jsx @@ -8,7 +8,7 @@ import { CreateClass, UpdateClass } from "./libs/components"; -import { ModalEnum } from "@/enums/enums"; +import { ModalEnum, AppRoute } from "@/enums/enums"; const ClassDashboard = () => { const { visibleModal } = useContext(ClassContext); @@ -31,7 +31,7 @@ const ClassDashboard = () => {
diff --git a/src/pages/Class/libs/components/ClassList/ClassHeader.jsx b/src/pages/Class/libs/components/ClassList/ClassHeader.jsx index b4b94316..802c9e56 100644 --- a/src/pages/Class/libs/components/ClassList/ClassHeader.jsx +++ b/src/pages/Class/libs/components/ClassList/ClassHeader.jsx @@ -16,6 +16,7 @@ const ClassHeader = () => { setIsRefreshPage, filterClassData, setRowPerPage, + setTotalData, } = useContext(ClassContext); const [filterValues, setFilterValues] = useState([]); @@ -43,6 +44,7 @@ const ClassHeader = () => { setIsTableLoading(false); setCurrentPage(1); setClassData(mappedClasses); + setTotalData(getClass.data.total); } catch (error) { const response = error.response; setIsTableLoading(false); diff --git a/src/pages/Class/libs/components/modals/CreateClass.jsx b/src/pages/Class/libs/components/modals/CreateClass.jsx index f2182dfa..c478fe66 100644 --- a/src/pages/Class/libs/components/modals/CreateClass.jsx +++ b/src/pages/Class/libs/components/modals/CreateClass.jsx @@ -3,8 +3,7 @@ import {useContext, useEffect, useState} from "@/hooks/hooks"; import {ClassContext} from "@/context/contexts"; import {GlobalModal} from "@/components/components"; import {validationInput} from "@/pages/School/libs/utils"; -import {ClassApi} from "@/utils/utils"; -import {fetchMajors} from "@/utils/utils"; +import {fetchMajors, ClassApi} from "@/utils/utils"; const CreateClass = () => { const { diff --git a/src/pages/Class/libs/components/modals/UpdateClass.jsx b/src/pages/Class/libs/components/modals/UpdateClass.jsx index 26e09334..7707bdb3 100644 --- a/src/pages/Class/libs/components/modals/UpdateClass.jsx +++ b/src/pages/Class/libs/components/modals/UpdateClass.jsx @@ -1,8 +1,7 @@ import {Modal, Form, Input, Select} from "@/components/components"; import {useContext, useEffect, useState} from "@/hooks/hooks"; import {ClassContext} from "@/context/ClassContext"; -import {fetchClassData, fetchMajors} from "@/utils/utils"; -import {ClassApi} from "@/utils/utils"; +import {fetchClassData, fetchMajors, ClassApi} from "@/utils/utils"; const UpdateClass = () => { const { From 33e3d0064d69f228d2165d0c30aa2d8234dffdb9 Mon Sep 17 00:00:00 2001 From: Fouz7 Date: Mon, 2 Dec 2024 09:47:09 +0700 Subject: [PATCH 12/19] Refactor :: Class Management --- src/hooks/class/useClass.js | 3 +-- .../{modals => ClassDetail}/ClassDetail.jsx | 2 +- .../components/ClassDetailContent.jsx | 2 +- .../components/ClassDetail/components/index.js | 1 + .../{ClassList => ClassHeader}/ClassHeader.jsx | 2 +- .../components/ClassFilterButton.jsx | 4 ++-- .../components/ClassHeader/components/index.js | 1 + .../libs/components/ClassList/components/index.js | 1 - src/pages/Class/libs/components/ClassList/index.js | 5 ----- .../{ClassList => ClassTable}/ClassTable.jsx | 2 +- .../components}/ClassColumns.jsx | 0 .../components}/ClassPagination.jsx | 0 .../libs/components/ClassTable/components/index.js | 2 ++ .../{modals => CreateClass}/CreateClass.jsx | 0 .../{modals => UpdateClass}/UpdateClass.jsx | 2 +- src/pages/Class/libs/components/index.js | 14 +++++++------- .../libs/components/modals/components/index.js | 1 - src/utils/class/index.js | 2 +- 18 files changed, 20 insertions(+), 24 deletions(-) rename src/pages/Class/libs/components/{modals => ClassDetail}/ClassDetail.jsx (97%) rename src/pages/Class/libs/components/{modals => ClassDetail}/components/ClassDetailContent.jsx (99%) create mode 100644 src/pages/Class/libs/components/ClassDetail/components/index.js rename src/pages/Class/libs/components/{ClassList => ClassHeader}/ClassHeader.jsx (98%) rename src/pages/Class/libs/components/{ClassList => ClassHeader}/components/ClassFilterButton.jsx (96%) create mode 100644 src/pages/Class/libs/components/ClassHeader/components/index.js delete mode 100644 src/pages/Class/libs/components/ClassList/components/index.js delete mode 100644 src/pages/Class/libs/components/ClassList/index.js rename src/pages/Class/libs/components/{ClassList => ClassTable}/ClassTable.jsx (97%) rename src/pages/Class/libs/components/{ClassList => ClassTable/components}/ClassColumns.jsx (100%) rename src/pages/Class/libs/components/{ClassList => ClassTable/components}/ClassPagination.jsx (100%) create mode 100644 src/pages/Class/libs/components/ClassTable/components/index.js rename src/pages/Class/libs/components/{modals => CreateClass}/CreateClass.jsx (100%) rename src/pages/Class/libs/components/{modals => UpdateClass}/UpdateClass.jsx (98%) delete mode 100644 src/pages/Class/libs/components/modals/components/index.js diff --git a/src/hooks/class/useClass.js b/src/hooks/class/useClass.js index e7535b48..b4da8ad5 100644 --- a/src/hooks/class/useClass.js +++ b/src/hooks/class/useClass.js @@ -1,6 +1,5 @@ import { useCallback, useState } from "react"; -import { ClassApi } from "@/utils/utils"; -import { mappedClassData } from "@/utils/utils"; +import { ClassApi, mappedClassData } from "@/utils/utils"; const useClass = () => { const [classData, setClassData] = useState([]); diff --git a/src/pages/Class/libs/components/modals/ClassDetail.jsx b/src/pages/Class/libs/components/ClassDetail/ClassDetail.jsx similarity index 97% rename from src/pages/Class/libs/components/modals/ClassDetail.jsx rename to src/pages/Class/libs/components/ClassDetail/ClassDetail.jsx index a3b724ea..86e3d87b 100644 --- a/src/pages/Class/libs/components/modals/ClassDetail.jsx +++ b/src/pages/Class/libs/components/ClassDetail/ClassDetail.jsx @@ -1,4 +1,4 @@ -import { Modal } from "antd"; +import { Modal } from "@/components/components"; import { ClassContext } from "@/context/contexts"; import { useCallback, useContext, useEffect, useState } from "@/hooks/hooks"; import { ClassApi } from "@/utils/utils"; diff --git a/src/pages/Class/libs/components/modals/components/ClassDetailContent.jsx b/src/pages/Class/libs/components/ClassDetail/components/ClassDetailContent.jsx similarity index 99% rename from src/pages/Class/libs/components/modals/components/ClassDetailContent.jsx rename to src/pages/Class/libs/components/ClassDetail/components/ClassDetailContent.jsx index 2ea9dcc7..99afe051 100644 --- a/src/pages/Class/libs/components/modals/components/ClassDetailContent.jsx +++ b/src/pages/Class/libs/components/ClassDetail/components/ClassDetailContent.jsx @@ -1,4 +1,4 @@ -import { Card, Descriptions, Table, Flex } from "@/components/components.js"; +import { Card, Descriptions, Table, Flex } from "@/components/components"; const ClassDetailContent = ({ classData, columns, dataSource }) => ( diff --git a/src/pages/Class/libs/components/ClassDetail/components/index.js b/src/pages/Class/libs/components/ClassDetail/components/index.js new file mode 100644 index 00000000..08e73969 --- /dev/null +++ b/src/pages/Class/libs/components/ClassDetail/components/index.js @@ -0,0 +1 @@ +export { ClassDetailContent } from "./ClassDetailContent.jsx"; \ No newline at end of file diff --git a/src/pages/Class/libs/components/ClassList/ClassHeader.jsx b/src/pages/Class/libs/components/ClassHeader/ClassHeader.jsx similarity index 98% rename from src/pages/Class/libs/components/ClassList/ClassHeader.jsx rename to src/pages/Class/libs/components/ClassHeader/ClassHeader.jsx index 802c9e56..20fec0b4 100644 --- a/src/pages/Class/libs/components/ClassList/ClassHeader.jsx +++ b/src/pages/Class/libs/components/ClassHeader/ClassHeader.jsx @@ -1,6 +1,6 @@ import { useContext, useState } from "@/hooks/hooks"; import { Flex, Select, Input, PlusCircleOutlined, CustomButton } from "@/components/components"; -import { ClassFilterButton } from "./components"; +import { ClassFilterButton } from "@/pages/Class/libs/components/ClassHeader/components"; import {debounce, ClassApi, mappedClassData} from "@/utils/utils"; import { ClassContext } from "@/context/contexts"; diff --git a/src/pages/Class/libs/components/ClassList/components/ClassFilterButton.jsx b/src/pages/Class/libs/components/ClassHeader/components/ClassFilterButton.jsx similarity index 96% rename from src/pages/Class/libs/components/ClassList/components/ClassFilterButton.jsx rename to src/pages/Class/libs/components/ClassHeader/components/ClassFilterButton.jsx index ef864c8e..e875bcaf 100644 --- a/src/pages/Class/libs/components/ClassList/components/ClassFilterButton.jsx +++ b/src/pages/Class/libs/components/ClassHeader/components/ClassFilterButton.jsx @@ -1,5 +1,5 @@ -import {useState, useEffect, useRef} from "@/hooks/hooks.js"; -import {Button, Checkbox, CaretDownFilled} from "@/components/components.js"; +import {useState, useEffect, useRef} from "@/hooks/hooks"; +import {Button, Checkbox, CaretDownFilled} from "@/components/components"; import {fetchMajorsFilter} from "@/utils/utils"; const ClassFilterButton = ( { onFilterChange } ) => { diff --git a/src/pages/Class/libs/components/ClassHeader/components/index.js b/src/pages/Class/libs/components/ClassHeader/components/index.js new file mode 100644 index 00000000..c169cf45 --- /dev/null +++ b/src/pages/Class/libs/components/ClassHeader/components/index.js @@ -0,0 +1 @@ +export {ClassFilterButton} from "./ClassFilterButton.jsx" \ No newline at end of file diff --git a/src/pages/Class/libs/components/ClassList/components/index.js b/src/pages/Class/libs/components/ClassList/components/index.js deleted file mode 100644 index 0508e9ba..00000000 --- a/src/pages/Class/libs/components/ClassList/components/index.js +++ /dev/null @@ -1 +0,0 @@ -export {ClassFilterButton} from "./ClassFilterButton" \ No newline at end of file diff --git a/src/pages/Class/libs/components/ClassList/index.js b/src/pages/Class/libs/components/ClassList/index.js deleted file mode 100644 index 28e342ba..00000000 --- a/src/pages/Class/libs/components/ClassList/index.js +++ /dev/null @@ -1,5 +0,0 @@ -export {ClassColumns} from "./ClassColumns" -export {ClassHeader} from "./ClassHeader" -export {ClassTable} from "./ClassTable" -export {ClassPagination} from "./ClassPagination" -export {ClassFilterButton} from "./components" diff --git a/src/pages/Class/libs/components/ClassList/ClassTable.jsx b/src/pages/Class/libs/components/ClassTable/ClassTable.jsx similarity index 97% rename from src/pages/Class/libs/components/ClassList/ClassTable.jsx rename to src/pages/Class/libs/components/ClassTable/ClassTable.jsx index fccae35f..78ec0cd5 100644 --- a/src/pages/Class/libs/components/ClassList/ClassTable.jsx +++ b/src/pages/Class/libs/components/ClassTable/ClassTable.jsx @@ -2,7 +2,7 @@ import {ClassContext} from '@/context/contexts'; import {useContext, useEffect} from '@/hooks/hooks'; import {Table, Modal, Flex} from '@/components/components'; import {ClassApi} from '@/utils/utils'; -import {ClassColumns, ClassPagination} from "./index"; +import {ClassColumns, ClassPagination} from "./components"; const ClassTable = () => { const { diff --git a/src/pages/Class/libs/components/ClassList/ClassColumns.jsx b/src/pages/Class/libs/components/ClassTable/components/ClassColumns.jsx similarity index 100% rename from src/pages/Class/libs/components/ClassList/ClassColumns.jsx rename to src/pages/Class/libs/components/ClassTable/components/ClassColumns.jsx diff --git a/src/pages/Class/libs/components/ClassList/ClassPagination.jsx b/src/pages/Class/libs/components/ClassTable/components/ClassPagination.jsx similarity index 100% rename from src/pages/Class/libs/components/ClassList/ClassPagination.jsx rename to src/pages/Class/libs/components/ClassTable/components/ClassPagination.jsx diff --git a/src/pages/Class/libs/components/ClassTable/components/index.js b/src/pages/Class/libs/components/ClassTable/components/index.js new file mode 100644 index 00000000..c7ec48c8 --- /dev/null +++ b/src/pages/Class/libs/components/ClassTable/components/index.js @@ -0,0 +1,2 @@ +export {ClassPagination} from "./ClassPagination.jsx" +export {ClassColumns} from "./ClassColumns.jsx" \ No newline at end of file diff --git a/src/pages/Class/libs/components/modals/CreateClass.jsx b/src/pages/Class/libs/components/CreateClass/CreateClass.jsx similarity index 100% rename from src/pages/Class/libs/components/modals/CreateClass.jsx rename to src/pages/Class/libs/components/CreateClass/CreateClass.jsx diff --git a/src/pages/Class/libs/components/modals/UpdateClass.jsx b/src/pages/Class/libs/components/UpdateClass/UpdateClass.jsx similarity index 98% rename from src/pages/Class/libs/components/modals/UpdateClass.jsx rename to src/pages/Class/libs/components/UpdateClass/UpdateClass.jsx index 7707bdb3..4769ca0f 100644 --- a/src/pages/Class/libs/components/modals/UpdateClass.jsx +++ b/src/pages/Class/libs/components/UpdateClass/UpdateClass.jsx @@ -1,6 +1,6 @@ import {Modal, Form, Input, Select} from "@/components/components"; import {useContext, useEffect, useState} from "@/hooks/hooks"; -import {ClassContext} from "@/context/ClassContext"; +import {ClassContext} from "@/context/contexts"; import {fetchClassData, fetchMajors, ClassApi} from "@/utils/utils"; const UpdateClass = () => { diff --git a/src/pages/Class/libs/components/index.js b/src/pages/Class/libs/components/index.js index f71dd426..7eb9e5bb 100644 --- a/src/pages/Class/libs/components/index.js +++ b/src/pages/Class/libs/components/index.js @@ -1,7 +1,7 @@ -export {CreateClass} from "./modals/CreateClass" -export {ClassDetail} from "./modals/ClassDetail" -export {UpdateClass} from "./modals/UpdateClass" -export {ClassColumns} from "./ClassList/ClassColumns" -export {ClassHeader} from "./ClassList/ClassHeader" -export {ClassTable} from "./ClassList/ClassTable" -export {ClassPagination} from "./ClassList/ClassPagination" +export {CreateClass} from "./CreateClass/CreateClass.jsx" +export {ClassDetail} from "./ClassDetail/ClassDetail.jsx" +export {UpdateClass} from "./UpdateClass/UpdateClass.jsx" +export {ClassColumns} from "./ClassTable/components/ClassColumns.jsx" +export {ClassHeader} from "./ClassHeader/ClassHeader.jsx" +export {ClassTable} from "./ClassTable/ClassTable.jsx" +export {ClassPagination} from "./ClassTable/components/ClassPagination.jsx" diff --git a/src/pages/Class/libs/components/modals/components/index.js b/src/pages/Class/libs/components/modals/components/index.js deleted file mode 100644 index ee26ebe1..00000000 --- a/src/pages/Class/libs/components/modals/components/index.js +++ /dev/null @@ -1 +0,0 @@ -export { ClassDetailContent } from "./ClassDetailContent"; \ No newline at end of file diff --git a/src/utils/class/index.js b/src/utils/class/index.js index 13fab795..0215bfea 100644 --- a/src/utils/class/index.js +++ b/src/utils/class/index.js @@ -53,7 +53,7 @@ export const fetchClassData = async ( selectedClassUUID, form, setIsFormLoading }; -export const validationInput = ( rule, value ) => { +export const classValidationInput = ( rule, value ) => { let errorMessage = null; if (rule.required && value === "") { errorMessage = rule.required.message; From c48beb10ba3b17cd16f743e91a80eda066f62238 Mon Sep 17 00:00:00 2001 From: Fouz7 Date: Mon, 2 Dec 2024 10:23:36 +0700 Subject: [PATCH 13/19] Refactor :: Class Management --- src/hooks/class/useClass.js | 22 ++++++++++++++++------ src/hooks/class/useData.js | 27 +++++++++++++++------------ 2 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/hooks/class/useClass.js b/src/hooks/class/useClass.js index b4da8ad5..0f43be0b 100644 --- a/src/hooks/class/useClass.js +++ b/src/hooks/class/useClass.js @@ -1,20 +1,29 @@ -import { useCallback, useState } from "react"; +import { useCallback, useState } from "@/hooks/hooks"; import { ClassApi, mappedClassData } from "@/utils/utils"; +import { useData } from "./useData"; const useClass = () => { - const [classData, setClassData] = useState([]); + const { + classData, + setClassData, + filterValues, + setFilterValues, + isModalLoading, + setIsModalLoading, + isTableLoading, + setIsTableLoading, + ...allState + } = useData(); + const [originalClassData, setOriginalClassData] = useState([]); - const [isModalLoading, setIsModalLoading] = useState(false); const [tableErrorMessage, setTableErrorMessage] = useState(""); const [visibleModal, setVisibleModal] = useState(0); const [selectedClassUUID, setSelectedClassUUID] = useState(null); const [currentPage, setCurrentPage] = useState(1); const [rowPerPage, setRowPerPage] = useState(5); const [isRefreshPage, setIsRefreshPage] = useState(false); - const [isTableLoading, setIsTableLoading] = useState(false); const [totalData, setTotalData] = useState(0); const [totalPages, setTotalPages] = useState(0); - const [filterValues, setFilterValues] = useState([]); const getAllClasses = useCallback(async () => { setTableErrorMessage(false); @@ -76,7 +85,8 @@ const useClass = () => { totalPages, setTotalPages, getAllClasses, - filterClassData + filterClassData, + ...allState }; }; diff --git a/src/hooks/class/useData.js b/src/hooks/class/useData.js index 772ec59f..68a31271 100644 --- a/src/hooks/class/useData.js +++ b/src/hooks/class/useData.js @@ -1,18 +1,21 @@ -import { useState } from "../hooks"; -import { useLoading } from "./useLoading"; -import { useModal } from "./useModal"; -import { usePagination } from "./usePagination"; +import {useState} from "../hooks"; +import {useLoading} from "./useLoading"; +import {useModal} from "./useModal"; +import {usePagination} from "./usePagination"; const useData = () => { const [classData, setClassData] = useState([]); + const [filterValues, setFilterValues] = useState({}); - return { - classData, - setClassData, - ...useLoading(), - ...usePagination(), - ...useModal(), - }; + return { + classData, + setClassData, + filterValues, + setFilterValues, + ...useLoading(), + ...usePagination(), + ...useModal(), + }; }; -export { useData }; +export {useData}; From 617a6b71139d432fdb43033c6b1a79ee9574f945 Mon Sep 17 00:00:00 2001 From: Fouz7 Date: Tue, 3 Dec 2024 02:13:12 +0700 Subject: [PATCH 14/19] Refactor :: Class Management --- src/hooks/class/useClass.js | 25 ++++--------- src/hooks/class/useData.js | 21 ----------- src/hooks/class/useLoading.js | 15 -------- src/hooks/class/useModal.js | 10 ----- src/hooks/class/usePagination.js | 21 ----------- .../libs/components/ClassTable/ClassTable.jsx | 37 +++++++------------ 6 files changed, 22 insertions(+), 107 deletions(-) delete mode 100644 src/hooks/class/useData.js delete mode 100644 src/hooks/class/useLoading.js delete mode 100644 src/hooks/class/useModal.js delete mode 100644 src/hooks/class/usePagination.js diff --git a/src/hooks/class/useClass.js b/src/hooks/class/useClass.js index 0f43be0b..e7535b48 100644 --- a/src/hooks/class/useClass.js +++ b/src/hooks/class/useClass.js @@ -1,29 +1,21 @@ -import { useCallback, useState } from "@/hooks/hooks"; -import { ClassApi, mappedClassData } from "@/utils/utils"; -import { useData } from "./useData"; +import { useCallback, useState } from "react"; +import { ClassApi } from "@/utils/utils"; +import { mappedClassData } from "@/utils/utils"; const useClass = () => { - const { - classData, - setClassData, - filterValues, - setFilterValues, - isModalLoading, - setIsModalLoading, - isTableLoading, - setIsTableLoading, - ...allState - } = useData(); - + const [classData, setClassData] = useState([]); const [originalClassData, setOriginalClassData] = useState([]); + const [isModalLoading, setIsModalLoading] = useState(false); const [tableErrorMessage, setTableErrorMessage] = useState(""); const [visibleModal, setVisibleModal] = useState(0); const [selectedClassUUID, setSelectedClassUUID] = useState(null); const [currentPage, setCurrentPage] = useState(1); const [rowPerPage, setRowPerPage] = useState(5); const [isRefreshPage, setIsRefreshPage] = useState(false); + const [isTableLoading, setIsTableLoading] = useState(false); const [totalData, setTotalData] = useState(0); const [totalPages, setTotalPages] = useState(0); + const [filterValues, setFilterValues] = useState([]); const getAllClasses = useCallback(async () => { setTableErrorMessage(false); @@ -85,8 +77,7 @@ const useClass = () => { totalPages, setTotalPages, getAllClasses, - filterClassData, - ...allState + filterClassData }; }; diff --git a/src/hooks/class/useData.js b/src/hooks/class/useData.js deleted file mode 100644 index 68a31271..00000000 --- a/src/hooks/class/useData.js +++ /dev/null @@ -1,21 +0,0 @@ -import {useState} from "../hooks"; -import {useLoading} from "./useLoading"; -import {useModal} from "./useModal"; -import {usePagination} from "./usePagination"; - -const useData = () => { - const [classData, setClassData] = useState([]); - const [filterValues, setFilterValues] = useState({}); - - return { - classData, - setClassData, - filterValues, - setFilterValues, - ...useLoading(), - ...usePagination(), - ...useModal(), - }; -}; - -export {useData}; diff --git a/src/hooks/class/useLoading.js b/src/hooks/class/useLoading.js deleted file mode 100644 index 9ba67016..00000000 --- a/src/hooks/class/useLoading.js +++ /dev/null @@ -1,15 +0,0 @@ -import { useState } from "@/hooks/hooks"; - -const useLoading = () => { - const [isModalLoading, setIsModalLoading] = useState(false); - const [isTableLoading, setIsTableLoading] = useState(false); - - return { - isModalLoading, - setIsModalLoading, - isTableLoading, - setIsTableLoading, - }; -}; - -export { useLoading }; diff --git a/src/hooks/class/useModal.js b/src/hooks/class/useModal.js deleted file mode 100644 index 42e348b8..00000000 --- a/src/hooks/class/useModal.js +++ /dev/null @@ -1,10 +0,0 @@ -import { useState } from "@/hooks/hooks"; - -const useModal = () => { - const [visibleModal, setVisibleModal] = useState(0); - const [selectedClassUUID, setSelectedClassUUID] = useState(null); - - return { visibleModal, setVisibleModal, selectedClassUUID, setSelectedClassUUID }; -}; - -export { useModal }; diff --git a/src/hooks/class/usePagination.js b/src/hooks/class/usePagination.js deleted file mode 100644 index bb969916..00000000 --- a/src/hooks/class/usePagination.js +++ /dev/null @@ -1,21 +0,0 @@ -import { useState } from "@/hooks/hooks"; - -const usePagination = () => { - const [currentPage, setCurrentPage] = useState(1); - const [rowsPerPage, setRowPerPage] = useState(5); - const [totalData, setTotalData] = useState(0); - const [totalPages, setTotalPages] = useState(0); - - return { - currentPage, - setCurrentPage, - rowsPerPage, - setRowPerPage, - totalData, - setTotalData, - totalPages, - setTotalPages, - }; -}; - -export { usePagination }; diff --git a/src/pages/Class/libs/components/ClassTable/ClassTable.jsx b/src/pages/Class/libs/components/ClassTable/ClassTable.jsx index 78ec0cd5..d1190ac3 100644 --- a/src/pages/Class/libs/components/ClassTable/ClassTable.jsx +++ b/src/pages/Class/libs/components/ClassTable/ClassTable.jsx @@ -1,8 +1,8 @@ -import {ClassContext} from '@/context/contexts'; -import {useContext, useEffect} from '@/hooks/hooks'; -import {Table, Modal, Flex} from '@/components/components'; -import {ClassApi} from '@/utils/utils'; -import {ClassColumns, ClassPagination} from "./components"; +import { useContext, useEffect } from "@/hooks/hooks"; +import { ClassContext } from '@/context/contexts'; +import { Table, Modal, Flex } from '@/components/components'; +import { ClassApi } from '@/utils/utils'; +import { ClassColumns, ClassPagination } from "./components"; const ClassTable = () => { const { @@ -16,25 +16,16 @@ const ClassTable = () => { isRefreshPage, setIsRefreshPage, getAllClasses, + rowPerPage, + currentPage, + filterValues, } = useContext(ClassContext); - const fetchClasses = async ( getAllClasses ) => { - try { - await getAllClasses(); - } catch (error) { - Modal.error({ - title: 'Error fetching class data', - content: 'Failed to fetch class data', - centered: true, - }); - } - }; - useEffect(() => { - fetchClasses(getAllClasses); - }, [getAllClasses, isRefreshPage]); + getAllClasses(); + }, [getAllClasses, isRefreshPage, rowPerPage, currentPage, filterValues]); - const handleDeleteClass = async ( row ) => { + const handleDeleteClass = async (row) => { try { setIsTableLoading(true); await ClassApi.deleteClassById(row.uuid); @@ -52,11 +43,11 @@ const ClassTable = () => { } finally { setIsTableLoading(false); setCurrentPage(1); - setIsRefreshPage(( prev ) => !prev); + setIsRefreshPage((prev) => !prev); } }; - const handleModal = ( val, classItem = {} ) => { + const handleModal = (val, classItem = {}) => { const uuid = classItem.uuid ? classItem.uuid : null; setSelectedClassUUID(uuid); setVisibleModal(val); @@ -82,4 +73,4 @@ const ClassTable = () => { ); }; -export {ClassTable}; \ No newline at end of file +export { ClassTable }; \ No newline at end of file From 0d0c8d8cc9e000692390531a169ba28f6d95eb4b Mon Sep 17 00:00:00 2001 From: Fouz7 Date: Tue, 3 Dec 2024 03:06:00 +0700 Subject: [PATCH 15/19] Refactor :: Class Management --- src/hooks/class/useClass.js | 91 ++++++++++++-------------------- src/hooks/class/useData.js | 55 +++++++++++++++++++ src/hooks/class/useLoading.js | 15 ++++++ src/hooks/class/useModal.js | 10 ++++ src/hooks/class/usePagination.js | 38 +++++++++++++ 5 files changed, 153 insertions(+), 56 deletions(-) create mode 100644 src/hooks/class/useData.js create mode 100644 src/hooks/class/useLoading.js create mode 100644 src/hooks/class/useModal.js create mode 100644 src/hooks/class/usePagination.js diff --git a/src/hooks/class/useClass.js b/src/hooks/class/useClass.js index e7535b48..1893220a 100644 --- a/src/hooks/class/useClass.js +++ b/src/hooks/class/useClass.js @@ -1,66 +1,46 @@ -import { useCallback, useState } from "react"; -import { ClassApi } from "@/utils/utils"; -import { mappedClassData } from "@/utils/utils"; +import { useData } from "./useData"; const useClass = () => { - const [classData, setClassData] = useState([]); - const [originalClassData, setOriginalClassData] = useState([]); - const [isModalLoading, setIsModalLoading] = useState(false); - const [tableErrorMessage, setTableErrorMessage] = useState(""); - const [visibleModal, setVisibleModal] = useState(0); - const [selectedClassUUID, setSelectedClassUUID] = useState(null); - const [currentPage, setCurrentPage] = useState(1); - const [rowPerPage, setRowPerPage] = useState(5); - const [isRefreshPage, setIsRefreshPage] = useState(false); - const [isTableLoading, setIsTableLoading] = useState(false); - const [totalData, setTotalData] = useState(0); - const [totalPages, setTotalPages] = useState(0); - const [filterValues, setFilterValues] = useState([]); - - const getAllClasses = useCallback(async () => { - setTableErrorMessage(false); - setIsTableLoading(true); - - try { - const response = await ClassApi.getClasses(rowPerPage, currentPage, true, "", filterValues); - if (response.success) { - const { data, total } = response.data; - const mappedClasses = data.map((cls, idx) => - mappedClassData(cls, idx + 1 + (currentPage - 1) * rowPerPage) - ); - setClassData(mappedClasses); - setOriginalClassData(mappedClasses); - setTotalData(total); - setTotalPages(Math.ceil(total / rowPerPage)); - } else { - setClassData([]); - } - } catch (error) { - setTableErrorMessage('Error fetching class data'); - } finally { - setIsTableLoading(false); - } - }, [rowPerPage, currentPage, filterValues]); - - const handleSetRowPerPage = (value) => { - setRowPerPage(value); - setCurrentPage(1); - setIsRefreshPage((prev) => !prev); - }; - - const filterClassData = (filterValues) => { - setFilterValues(filterValues); - setIsRefreshPage((prev) => !prev); - }; + const { + classData, + setClassData, + originalClassData, + tableErrorMessage, + setTableErrorMessage, + getAllClasses, + isModalLoading, + setIsModalLoading, + isTableLoading, + setIsTableLoading, + visibleModal, + setVisibleModal, + selectedClassUUID, + setSelectedClassUUID, + currentPage, + setCurrentPage, + rowPerPage, + setRowPerPage, + isRefreshPage, + setIsRefreshPage, + totalData, + setTotalData, + totalPages, + setTotalPages, + filterValues, + filterClassData + } = useData(); return { classData, setClassData, + originalClassData, + tableErrorMessage, + setTableErrorMessage, + getAllClasses, isModalLoading, setIsModalLoading, isTableLoading, setIsTableLoading, - tableErrorMessage, visibleModal, setVisibleModal, selectedClassUUID, @@ -68,15 +48,14 @@ const useClass = () => { currentPage, setCurrentPage, rowPerPage, - setRowPerPage: handleSetRowPerPage, + setRowPerPage, isRefreshPage, - setTableErrorMessage, setIsRefreshPage, totalData, setTotalData, totalPages, setTotalPages, - getAllClasses, + filterValues, filterClassData }; }; diff --git a/src/hooks/class/useData.js b/src/hooks/class/useData.js new file mode 100644 index 00000000..b2ed3679 --- /dev/null +++ b/src/hooks/class/useData.js @@ -0,0 +1,55 @@ +import { useState, useCallback } from "react"; +import { ClassApi } from "@/utils/utils"; +import { mappedClassData } from "@/utils/utils"; +import { useLoading } from "./useLoading"; +import { useModal } from "./useModal"; +import { usePagination } from "./usePagination"; + +const useData = () => { + const [classData, setClassData] = useState([]); + const [originalClassData, setOriginalClassData] = useState([]); + const [tableErrorMessage, setTableErrorMessage] = useState(""); + + const loadingState = useLoading(); + const modalState = useModal(); + const paginationState = usePagination(); + + const getAllClasses = useCallback(async () => { + setTableErrorMessage(false); + loadingState.setIsTableLoading(true); + + try { + const response = await ClassApi.getClasses(paginationState.rowPerPage, paginationState.currentPage, true, "", paginationState.filterValues); + if (response.success) { + const { data, total } = response.data; + const mappedClasses = data.map((cls, idx) => + mappedClassData(cls, idx + 1 + (paginationState.currentPage - 1) * paginationState.rowPerPage) + ); + setClassData(mappedClasses); + setOriginalClassData(mappedClasses); + paginationState.setTotalData(total); + paginationState.setTotalPages(Math.ceil(total / paginationState.rowPerPage)); + } else { + setClassData([]); + } + } catch (error) { + setTableErrorMessage('Error fetching class data'); + } finally { + loadingState.setIsTableLoading(false); + } + }, [paginationState.rowPerPage, paginationState.currentPage, paginationState.filterValues]); + + return { + classData, + setClassData, + originalClassData, + tableErrorMessage, + setTableErrorMessage, + getAllClasses, + ...loadingState, + ...modalState, + ...paginationState + }; +}; + +export { useData }; \ No newline at end of file diff --git a/src/hooks/class/useLoading.js b/src/hooks/class/useLoading.js new file mode 100644 index 00000000..9ba67016 --- /dev/null +++ b/src/hooks/class/useLoading.js @@ -0,0 +1,15 @@ +import { useState } from "@/hooks/hooks"; + +const useLoading = () => { + const [isModalLoading, setIsModalLoading] = useState(false); + const [isTableLoading, setIsTableLoading] = useState(false); + + return { + isModalLoading, + setIsModalLoading, + isTableLoading, + setIsTableLoading, + }; +}; + +export { useLoading }; diff --git a/src/hooks/class/useModal.js b/src/hooks/class/useModal.js new file mode 100644 index 00000000..42e348b8 --- /dev/null +++ b/src/hooks/class/useModal.js @@ -0,0 +1,10 @@ +import { useState } from "@/hooks/hooks"; + +const useModal = () => { + const [visibleModal, setVisibleModal] = useState(0); + const [selectedClassUUID, setSelectedClassUUID] = useState(null); + + return { visibleModal, setVisibleModal, selectedClassUUID, setSelectedClassUUID }; +}; + +export { useModal }; diff --git a/src/hooks/class/usePagination.js b/src/hooks/class/usePagination.js new file mode 100644 index 00000000..fd1e07c3 --- /dev/null +++ b/src/hooks/class/usePagination.js @@ -0,0 +1,38 @@ +import { useState } from "react"; + +const usePagination = () => { + const [currentPage, setCurrentPage] = useState(1); + const [rowPerPage, setRowPerPage] = useState(5); + const [isRefreshPage, setIsRefreshPage] = useState(false); + const [totalData, setTotalData] = useState(0); + const [totalPages, setTotalPages] = useState(0); + const [filterValues, setFilterValues] = useState([]); + + const handleSetRowPerPage = (value) => { + setRowPerPage(value); + setCurrentPage(1); + setIsRefreshPage((prev) => !prev); + }; + + const filterClassData = (filterValues) => { + setFilterValues(filterValues); + setIsRefreshPage((prev) => !prev); + }; + + return { + currentPage, + setCurrentPage, + rowPerPage, + setRowPerPage: handleSetRowPerPage, + isRefreshPage, + setIsRefreshPage, + totalData, + setTotalData, + totalPages, + setTotalPages, + filterValues, + filterClassData + }; +}; + +export { usePagination }; \ No newline at end of file From ecc138b24b3ba0181cff5777c03bc97c12feeeb8 Mon Sep 17 00:00:00 2001 From: Fouz7 Date: Tue, 3 Dec 2024 03:07:42 +0700 Subject: [PATCH 16/19] Refactor :: Class Management --- src/hooks/class/useData.js | 2 +- src/hooks/class/usePagination.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/class/useData.js b/src/hooks/class/useData.js index b2ed3679..cb2da001 100644 --- a/src/hooks/class/useData.js +++ b/src/hooks/class/useData.js @@ -1,4 +1,4 @@ -import { useState, useCallback } from "react"; +import { useState, useCallback } from "@/hooks/hooks"; import { ClassApi } from "@/utils/utils"; import { mappedClassData } from "@/utils/utils"; import { useLoading } from "./useLoading"; diff --git a/src/hooks/class/usePagination.js b/src/hooks/class/usePagination.js index fd1e07c3..740eb918 100644 --- a/src/hooks/class/usePagination.js +++ b/src/hooks/class/usePagination.js @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState } from "@/hooks/hooks"; const usePagination = () => { const [currentPage, setCurrentPage] = useState(1); From cd3b544999c5bfc3f3e1e46667484e5b7748bef0 Mon Sep 17 00:00:00 2001 From: Fouz7 Date: Tue, 3 Dec 2024 03:10:34 +0700 Subject: [PATCH 17/19] Refactor :: Class Management --- src/hooks/class/useClass.js | 58 ++----------------------------------- 1 file changed, 2 insertions(+), 56 deletions(-) diff --git a/src/hooks/class/useClass.js b/src/hooks/class/useClass.js index 1893220a..ee23f633 100644 --- a/src/hooks/class/useClass.js +++ b/src/hooks/class/useClass.js @@ -1,63 +1,9 @@ import { useData } from "./useData"; const useClass = () => { - const { - classData, - setClassData, - originalClassData, - tableErrorMessage, - setTableErrorMessage, - getAllClasses, - isModalLoading, - setIsModalLoading, - isTableLoading, - setIsTableLoading, - visibleModal, - setVisibleModal, - selectedClassUUID, - setSelectedClassUUID, - currentPage, - setCurrentPage, - rowPerPage, - setRowPerPage, - isRefreshPage, - setIsRefreshPage, - totalData, - setTotalData, - totalPages, - setTotalPages, - filterValues, - filterClassData - } = useData(); + const allState = useData(); - return { - classData, - setClassData, - originalClassData, - tableErrorMessage, - setTableErrorMessage, - getAllClasses, - isModalLoading, - setIsModalLoading, - isTableLoading, - setIsTableLoading, - visibleModal, - setVisibleModal, - selectedClassUUID, - setSelectedClassUUID, - currentPage, - setCurrentPage, - rowPerPage, - setRowPerPage, - isRefreshPage, - setIsRefreshPage, - totalData, - setTotalData, - totalPages, - setTotalPages, - filterValues, - filterClassData - }; + return { ...allState }; }; export { useClass }; \ No newline at end of file From c37fff00eaf6faf04f826c3089e46fa61072e474 Mon Sep 17 00:00:00 2001 From: Fouz7 Date: Tue, 3 Dec 2024 08:18:45 +0700 Subject: [PATCH 18/19] Refactor :: Class Management --- src/components/components.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/components.js b/src/components/components.js index 27aa6fe6..147f8ef9 100644 --- a/src/components/components.js +++ b/src/components/components.js @@ -105,6 +105,9 @@ export { ExclamationCircleFilled, } from "@ant-design/icons"; + +export {ActionButtons} from "@/components/Button/ActionButtons.jsx"; +export {GlobalModal} from "./Modal/modal.jsx"; export {ToastContainer, toast} from "react-toastify"; export {SelectMultiple} from "./ProgramManagement/components"; export {Link, Navigate} from "react-router-dom"; From b6c19b7ffe473f60ee1837b2ca34a4fef4af47f0 Mon Sep 17 00:00:00 2001 From: Fouz7 Date: Tue, 3 Dec 2024 08:25:01 +0700 Subject: [PATCH 19/19] Refactor :: Class Management --- src/pages/Class/libs/components/ClassHeader/ClassHeader.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Class/libs/components/ClassHeader/ClassHeader.jsx b/src/pages/Class/libs/components/ClassHeader/ClassHeader.jsx index 20fec0b4..802c9e56 100644 --- a/src/pages/Class/libs/components/ClassHeader/ClassHeader.jsx +++ b/src/pages/Class/libs/components/ClassHeader/ClassHeader.jsx @@ -1,6 +1,6 @@ import { useContext, useState } from "@/hooks/hooks"; import { Flex, Select, Input, PlusCircleOutlined, CustomButton } from "@/components/components"; -import { ClassFilterButton } from "@/pages/Class/libs/components/ClassHeader/components"; +import { ClassFilterButton } from "./components"; import {debounce, ClassApi, mappedClassData} from "@/utils/utils"; import { ClassContext } from "@/context/contexts";