From d20df652a5efd702777b1aec3e8860ad4672fd8a Mon Sep 17 00:00:00 2001 From: IceTeaXXD <13521024@std.stei.itb.ac.id> Date: Thu, 16 Nov 2023 19:36:50 +0700 Subject: [PATCH] chore: reformat code --- src/App.tsx | 18 +-- src/api/axios.tsx | 6 +- src/components/Acceptance/Acceptance.tsx | 2 +- src/components/Assignment/AssignmentCards.tsx | 32 +++-- .../Assignment/DeleteAssignmentDialog.tsx | 2 +- .../Assignment/EditAssignmentModal.tsx | 3 +- src/components/Assignment/Submission.tsx | 116 ++++++++++-------- .../Dashboard/UniversityDashboard.tsx | 23 ++-- src/components/Home/Home.tsx | 18 +-- src/components/Home/UniversityHome.tsx | 18 +-- src/components/Login/Login.tsx | 69 ++++++----- src/components/Register/RegisterOrg.tsx | 76 ++++++++---- .../Register/RegisterUniversity.tsx | 69 ++++++++--- src/components/Report/Report.tsx | 65 +++++----- src/hooks/axiosPrivate.tsx | 33 +++-- src/hooks/useRefreshToken.tsx | 2 - src/utils/RequireAuth.tsx | 2 +- src/utils/auth.tsx | 1 - 18 files changed, 329 insertions(+), 226 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 89a31b4..f971b6c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react-hooks/exhaustive-deps */ import "./App.css" import { BrowserRouter as Router, Routes, Route } from "react-router-dom" import { ChakraProvider, extendTheme } from "@chakra-ui/react" @@ -43,7 +44,7 @@ function App() { const getInfo = async () => { try { - refresh(); + refresh() const response = await handleGetInfo() setUserInfo({ user_id: response?.data.user_id, @@ -55,15 +56,13 @@ function App() { console.log(error) } } - useEffect(() => { - - }) + useEffect(() => {}) useEffect(() => { getInfo() }, [userInfo.role]) const activeLabelStyles = { transform: "scale(0.85) translateY(-24px)" - }; + } const theme = extendTheme({ components: { Form: { @@ -75,9 +74,10 @@ function App() { ...activeLabelStyles } }, - "input:not(:placeholder-shown) + label, .chakra-select__wrapper + label, textarea:not(:placeholder-shown) ~ label": { - ...activeLabelStyles - }, + "input:not(:placeholder-shown) + label, .chakra-select__wrapper + label, textarea:not(:placeholder-shown) ~ label": + { + ...activeLabelStyles + }, label: { top: 0, left: 0, @@ -95,7 +95,7 @@ function App() { } } } - }); + }) return ( <ChakraProvider theme={theme}> <Router> diff --git a/src/api/axios.tsx b/src/api/axios.tsx index 66f88f3..625e785 100644 --- a/src/api/axios.tsx +++ b/src/api/axios.tsx @@ -1,10 +1,10 @@ import axios from "axios" export default axios.create({ - baseURL: "http://localhost:5001" + baseURL: process.env.REACT_APP_API_URL }) export const axiosPrivate = axios.create({ - baseURL: "http://localhost:5001", - headers: { "Content-Type": "application/json" }, + baseURL: process.env.REACT_APP_API_URL, + headers: { "Content-Type": "application/json" } }) diff --git a/src/components/Acceptance/Acceptance.tsx b/src/components/Acceptance/Acceptance.tsx index 46491ed..d483def 100644 --- a/src/components/Acceptance/Acceptance.tsx +++ b/src/components/Acceptance/Acceptance.tsx @@ -200,7 +200,7 @@ const Acceptance = () => { return ( <Box p="12"> - <Heading size="sm" as="h1" mb="6" fontSize={{base:30, md:36, lg:48}}> + <Heading size="sm" as="h1" mb="6" fontSize={{ base: 30, md: 36, lg: 48 }}> Scholarship Acceptance </Heading> <Stack> diff --git a/src/components/Assignment/AssignmentCards.tsx b/src/components/Assignment/AssignmentCards.tsx index d60c50e..5c71f62 100644 --- a/src/components/Assignment/AssignmentCards.tsx +++ b/src/components/Assignment/AssignmentCards.tsx @@ -15,7 +15,6 @@ import { FiEdit } from "react-icons/fi" import { Link } from "react-router-dom" import { DeleteAssignmentDialog } from "./DeleteAssignmentDialog" import { EditAssignmentModal } from "./EditAssignmentModal" -import axios from "axios" import useAxiosPrivate from "../../hooks/axiosPrivate" export interface AssignmentCardsProps { @@ -40,11 +39,12 @@ export const AssignmentCards = ({ // use fetch student const useFetchStudent = (sid: any) => { const [students, setStudents] = useState([]) - const STUDENT_URL = process.env.REACT_APP_API_URL + '/api/scholarship/user/' + sid + const STUDENT_URL = + process.env.REACT_APP_API_URL + "/api/scholarship/user/" + sid const fetchStudent = async () => { try { - const response = await axiosInstance.get(STUDENT_URL); - setStudents(response.data.data.scholarships); + const response = await axiosInstance.get(STUDENT_URL) + setStudents(response.data.data.scholarships) } catch (err: any) { console.log(err) } @@ -54,7 +54,12 @@ export const AssignmentCards = ({ //use fetch file const useFetchFile = (sid: any, aid: any) => { const [submissionFile, setSubmissionFile] = useState([]) - const FILE_URL = process.env.REACT_APP_API_URL + "/api/files/scholarship/" + sid + "/assignment/" + aid + const FILE_URL = + process.env.REACT_APP_API_URL + + "/api/files/scholarship/" + + sid + + "/assignment/" + + aid const fetchFile = async () => { try { @@ -68,23 +73,26 @@ export const AssignmentCards = ({ return { submissionFile, fetchFile } } const axiosInstance = useAxiosPrivate() - const { submissionFile, fetchFile } = useFetchFile(scholarship_id, assignment_id); - const { students, fetchStudent } = useFetchStudent(scholarship_id); + const { submissionFile, fetchFile } = useFetchFile( + scholarship_id, + assignment_id + ) + const { students, fetchStudent } = useFetchStudent(scholarship_id) const [applicants, setApplicants] = useState(students.length) const [submissions, setSubmissions] = useState(submissionFile.length) useEffect(() => { const fetchData = async () => { - await fetchFile(); + await fetchFile() setSubmissions(submissionFile.length) } - fetchData(); - }, [submissionFile.length]); + fetchData() + }, [submissionFile.length]) useEffect(() => { const fetchData = async () => { - await fetchStudent(); + await fetchStudent() setApplicants(students.length) } - fetchData(); + fetchData() }, [students.length]) // TODO: SET THE APPLICANTS AND SUBMSISSIONS @MATTHEW MAHENDRA const [isOpenEditAssignment, setIsOpenEditAssignment] = useState(false) diff --git a/src/components/Assignment/DeleteAssignmentDialog.tsx b/src/components/Assignment/DeleteAssignmentDialog.tsx index 986e2b7..8ed632f 100644 --- a/src/components/Assignment/DeleteAssignmentDialog.tsx +++ b/src/components/Assignment/DeleteAssignmentDialog.tsx @@ -26,7 +26,7 @@ export const DeleteAssignmentDialog: React.FC<DeleteAlertDialogProps> = ({ assignment_id, onDeleteSuccess }) => { - const axiosInstance = useAxiosPrivate(); + const axiosInstance = useAxiosPrivate() const toast = useToast() async function DeleteAssignment() { try { diff --git a/src/components/Assignment/EditAssignmentModal.tsx b/src/components/Assignment/EditAssignmentModal.tsx index 978a25d..830164e 100644 --- a/src/components/Assignment/EditAssignmentModal.tsx +++ b/src/components/Assignment/EditAssignmentModal.tsx @@ -17,7 +17,6 @@ import { Textarea, useToast } from "@chakra-ui/react" -import axios from "axios" import { Form, Formik, Field } from "formik" import { FiEdit } from "react-icons/fi" import useAxiosPrivate from "../../hooks/axiosPrivate" @@ -36,7 +35,7 @@ export const EditAssignmentModal: React.FC<EditAssignmentModalProps> = ({ assignment_id, onEditSuccess }) => { - const axiosInstance = useAxiosPrivate(); + const axiosInstance = useAxiosPrivate() const toast = useToast() const [assignmentName, setAssignmentName] = React.useState("") const [assignmentDescription, setAssignmentDescription] = React.useState("") diff --git a/src/components/Assignment/Submission.tsx b/src/components/Assignment/Submission.tsx index 5466c8e..1e98cfe 100644 --- a/src/components/Assignment/Submission.tsx +++ b/src/components/Assignment/Submission.tsx @@ -1,78 +1,94 @@ -import { Box, Text } from "@chakra-ui/react"; -import axios from "axios"; -import React, { useEffect, useState } from "react"; -import { useParams } from "react-router-dom"; -import useAxiosPrivate from "../../hooks/axiosPrivate"; +/* eslint-disable react-hooks/exhaustive-deps */ +import { Box, Text } from "@chakra-ui/react" +import axios from "axios" +import { useEffect, useState } from "react" +import { useParams } from "react-router-dom" +import useAxiosPrivate from "../../hooks/axiosPrivate" interface FileDetails { - file_id: number; - file_path: string; - user_id_student: number; + file_id: number + file_path: string + user_id_student: number } interface UserDetails { - userId: number; - name: string; - email: string; + userId: number + name: string + email: string } export const Submissions = () => { - const axiosInstance = useAxiosPrivate(); + const axiosInstance = useAxiosPrivate() const useFetchFile = (sid: any, aid: any) => { - const [submissionFile, setSubmissionFile] = useState<FileDetails[]>([]); - const [userDetailsArray, setUserDetailsArray] = useState<UserDetails[]>([]); + const [submissionFile, setSubmissionFile] = useState<FileDetails[]>([]) + const [userDetailsArray, setUserDetailsArray] = useState<UserDetails[]>([]) - const FILE_URL = process.env.REACT_APP_API_URL + `/api/files/scholarship/${sid}/assignment/${aid}`; + const FILE_URL = + process.env.REACT_APP_API_URL + + `/api/files/scholarship/${sid}/assignment/${aid}` const fetchFile = async () => { try { - const response = await axiosInstance.get(FILE_URL); - console.log(response.data.data.files); - setSubmissionFile(response.data.data.files); + const response = await axiosInstance.get(FILE_URL) + console.log(response.data.data.files) + setSubmissionFile(response.data.data.files) - const userDetailsPromises = response.data.data.files.map(async (file: FileDetails) => { - try { - const userInfo = await axios.get( - process.env.REACT_APP_API_URL + `/api/user/` + file.user_id_student - ); - return { - userId: file.user_id_student, - name: userInfo.data.data.user.name, - email: userInfo.data.data.user.email, - }; - } catch (error: any) { - console.error( - `Error fetching user details for user_id_student ${file.user_id_student}:`, - error.message - ); - return null; + const userDetailsPromises = response.data.data.files.map( + async (file: FileDetails) => { + try { + const userInfo = await axios.get( + process.env.REACT_APP_API_URL + + `/api/user/` + + file.user_id_student + ) + return { + userId: file.user_id_student, + name: userInfo.data.data.user.name, + email: userInfo.data.data.user.email + } + } catch (error: any) { + console.error( + `Error fetching user details for user_id_student ${file.user_id_student}:`, + error.message + ) + return null + } } - }); + ) - const userDetailsArray = await Promise.all(userDetailsPromises); - setUserDetailsArray(userDetailsArray.filter((user) => user !== null) as UserDetails[]); + const userDetailsArray = await Promise.all(userDetailsPromises) + setUserDetailsArray( + userDetailsArray.filter((user) => user !== null) as UserDetails[] + ) } catch (error) { - setSubmissionFile([]); + setSubmissionFile([]) } - }; + } - return { submissionFile, userDetailsArray, fetchFile }; - }; - const { scholarshipid, assignmentid } = useParams(); + return { submissionFile, userDetailsArray, fetchFile } + } + const { scholarshipid, assignmentid } = useParams() const { submissionFile, userDetailsArray, fetchFile } = useFetchFile( scholarshipid, assignmentid - ); + ) useEffect(() => { - fetchFile(); - }, [scholarshipid, assignmentid]); + fetchFile() + }, [scholarshipid, assignmentid]) return ( <div> {submissionFile.map((file, index) => ( - <Box key={index} marginBottom="4" width="100%" borderWidth="1px" borderRadius="lg" overflow="hidden"> + <Box + key={index} + marginBottom="4" + width="100%" + borderWidth="1px" + borderRadius="lg" + overflow="hidden" + > <iframe title={`Google Drive Viewer ${index}`} src={file.file_path} @@ -81,12 +97,14 @@ export const Submissions = () => { ></iframe> {userDetailsArray[index] && ( <Box p="4"> - <Text fontWeight="bold" marginBottom="2">Name: {userDetailsArray[index].name}</Text> + <Text fontWeight="bold" marginBottom="2"> + Name: {userDetailsArray[index].name} + </Text> <Text>Email: {userDetailsArray[index].email}</Text> </Box> )} </Box> ))} </div> - ); -}; + ) +} diff --git a/src/components/Dashboard/UniversityDashboard.tsx b/src/components/Dashboard/UniversityDashboard.tsx index 44b1635..915095a 100644 --- a/src/components/Dashboard/UniversityDashboard.tsx +++ b/src/components/Dashboard/UniversityDashboard.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react-hooks/exhaustive-deps */ import { InfoIcon } from "@chakra-ui/icons" import { Heading, @@ -16,38 +17,40 @@ import { handleGetInfo } from "../../utils/auth" export const UniversityDashboard = () => { const axiosInstance = useAxiosPrivate() - const [userInfo, setUserInfo] = useState({ + const [UserInfo, setUserInfo] = useState({ user_id: 0, name: "", email: "", role: "" - }); + }) const [studentCount, setStudentCount] = useState() useEffect(() => { const getInfo = async () => { try { - const response = await handleGetInfo(); + const response = await handleGetInfo() setUserInfo({ user_id: response?.data.user_id, name: response?.data.name, email: response?.data.email, role: response?.data.roles - }); + }) const students = await axiosInstance.get( - process.env.REACT_APP_API_URL + "/api/university/stats/" + response?.data.user_id - ); + process.env.REACT_APP_API_URL + + "/api/university/stats/" + + response?.data.user_id + ) setStudentCount(students.data.data.data[0].applicant_count) } catch (error) { - console.error("Error in useEffect:", error); + console.error("Error in useEffect:", error) } - }; + } - getInfo(); - }, []); + getInfo() + }, []) return ( <> diff --git a/src/components/Home/Home.tsx b/src/components/Home/Home.tsx index 0e91ab4..3dc61df 100644 --- a/src/components/Home/Home.tsx +++ b/src/components/Home/Home.tsx @@ -1,4 +1,12 @@ -import { Flex, Box, SimpleGrid, Heading, Text, useColorModeValue, useColorMode } from "@chakra-ui/react" +import { + Flex, + Box, + SimpleGrid, + Heading, + Text, + useColorModeValue, + useColorMode +} from "@chakra-ui/react" import { ArrowForwardIcon } from "@chakra-ui/icons" import { Link } from "react-router-dom" @@ -33,9 +41,7 @@ const Home = () => { alignItems="center" justifyContent="center" > - <Link - to={`/scholarships`} - > + <Link to={`/scholarships`}> <ArrowForwardIcon w={6} h={6} mr={2} /> View Scholarships </Link> </Box> @@ -70,9 +76,7 @@ const Home = () => { alignItems="center" justifyContent="center" > - <Link - to={`/dashboard`} - > + <Link to={`/dashboard`}> <ArrowForwardIcon w={6} h={6} mr={2} /> View Dashboard </Link> </Box> diff --git a/src/components/Home/UniversityHome.tsx b/src/components/Home/UniversityHome.tsx index c942a84..7060551 100644 --- a/src/components/Home/UniversityHome.tsx +++ b/src/components/Home/UniversityHome.tsx @@ -1,4 +1,12 @@ -import { Flex, Box, SimpleGrid, Heading, Text, useColorModeValue, useColorMode } from "@chakra-ui/react" +import { + Flex, + Box, + SimpleGrid, + Heading, + Text, + useColorModeValue, + useColorMode +} from "@chakra-ui/react" import { ArrowForwardIcon } from "@chakra-ui/icons" import { Link } from "react-router-dom" @@ -33,9 +41,7 @@ const UniversityHome = () => { alignItems="center" justifyContent="center" > - <Link - to={`/report`} - > + <Link to={`/report`}> <ArrowForwardIcon w={6} h={6} mr={2} /> View Students </Link> </Box> @@ -48,9 +54,7 @@ const UniversityHome = () => { alignItems="center" justifyContent="center" > - <Link - to={`/dashboard`} - > + <Link to={`/dashboard`}> <ArrowForwardIcon w={6} h={6} mr={2} /> View Dashboard </Link> </Box> diff --git a/src/components/Login/Login.tsx b/src/components/Login/Login.tsx index 353f242..9223db3 100644 --- a/src/components/Login/Login.tsx +++ b/src/components/Login/Login.tsx @@ -1,6 +1,6 @@ -import { useState } from "react"; -import Cookies from "js-cookie"; -import { motion } from "framer-motion"; +import { useState } from "react" +import Cookies from "js-cookie" +import { motion } from "framer-motion" import { Flex, @@ -9,7 +9,6 @@ import { Button, FormControl, FormLabel, - Switch, useColorMode, useColorModeValue, Box, @@ -17,35 +16,35 @@ import { IconButton, InputGroup, InputRightElement -} from "@chakra-ui/react"; -import { Link, useNavigate } from "react-router-dom"; -import { FaSun, FaMoon } from "react-icons/fa"; -import { ViewIcon, ViewOffIcon } from "@chakra-ui/icons"; -import { handleLogin } from "../../utils/auth"; +} from "@chakra-ui/react" +import { Link, useNavigate } from "react-router-dom" +import { FaSun, FaMoon } from "react-icons/fa" +import { ViewIcon, ViewOffIcon } from "@chakra-ui/icons" +import { handleLogin } from "../../utils/auth" const Login = () => { // const {handleLogin} = useAuth() - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); - const [errMsg, setErrMsg] = useState(""); + const [email, setEmail] = useState("") + const [password, setPassword] = useState("") + const [errMsg, setErrMsg] = useState("") const [showPassword, setShowPassword] = useState(false) - const { colorMode, toggleColorMode } = useColorMode(); - const formBackground = useColorModeValue("white", "gray.800"); - const buttonColor = useColorModeValue("gray.800", "white"); - const navigate = useNavigate(); + const { colorMode, toggleColorMode } = useColorMode() + const formBackground = useColorModeValue("white", "gray.800") + const buttonColor = useColorModeValue("gray.800", "white") + const navigate = useNavigate() async function handleSubmit(e: any) { - e.preventDefault(); + e.preventDefault() try { - const res = await handleLogin(email, password); - Cookies.set("accToken", res?.accToken); + const res = await handleLogin(email, password) + Cookies.set("accToken", res?.accToken) if (res && res.status === "success") { - navigate("/"); + navigate("/") } else { - setErrMsg(res?.message || "Credentials not match"); + setErrMsg(res?.message || "Credentials not match") } } catch (err: any) { - console.log(err); + console.log(err) } } @@ -53,7 +52,11 @@ const Login = () => { setShowPassword(!showPassword) } return ( - <motion.div initial={{ opacity: 0, y: -50 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }}> + <motion.div + initial={{ opacity: 0, y: -50 }} + animate={{ opacity: 1, y: 0 }} + transition={{ duration: 0.5 }} + > <Flex h="100vh"> {/* IMAGE */} <Box @@ -115,7 +118,9 @@ const Login = () => { <FormLabel bg={formBackground}>Password</FormLabel> <InputRightElement> <IconButton - aria-label={showPassword ? "Hide password" : "Show password"} + aria-label={ + showPassword ? "Hide password" : "Show password" + } icon={showPassword ? <ViewOffIcon /> : <ViewIcon />} onClick={handlePasswordVisibility} variant="ghost" @@ -145,14 +150,22 @@ const Login = () => { </Box> <FormControl> <FormLabel> - Don't have an account? <Link to="/register-org"> <u>Register Organization</u></Link> or <Link to="/register-uni"><u>Register University</u></Link> + Don't have an account?{" "} + <Link to="/register-org"> + {" "} + <u>Register Organization</u> + </Link>{" "} + or{" "} + <Link to="/register-uni"> + <u>Register University</u> + </Link> </FormLabel> </FormControl> </Box> </Flex> </Flex> </motion.div> - ); -}; + ) +} -export default Login; +export default Login diff --git a/src/components/Register/RegisterOrg.tsx b/src/components/Register/RegisterOrg.tsx index 6686b91..f0ebbe4 100644 --- a/src/components/Register/RegisterOrg.tsx +++ b/src/components/Register/RegisterOrg.tsx @@ -1,5 +1,5 @@ import { useState } from "react" -import { motion } from "framer-motion"; +import { motion } from "framer-motion" import { Flex, Heading, @@ -16,27 +16,24 @@ import { Image, FormErrorMessage, Alert, - AlertIcon, + AlertIcon } from "@chakra-ui/react" import { ViewIcon, ViewOffIcon, WarningIcon } from "@chakra-ui/icons" import { Link } from "react-router-dom" -import axios from "../../api/axios" -import { redirect } from "react-router-dom" -import { FaSun, FaMoon } from "react-icons/fa"; -import useAxiosPrivate from "../../hooks/axiosPrivate"; +import { FaSun, FaMoon } from "react-icons/fa" +import useAxiosPrivate from "../../hooks/axiosPrivate" const EMAIL_REGEX = /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/ const PWD_REGEX = /^(?=.*\d).{8,}$/ const REGISTER_URL = "/api/organization" // const navigate = useNavigate(); const RegisterOrg = () => { - const axiosInstance = useAxiosPrivate(); + const axiosInstance = useAxiosPrivate() const [showPassword, setShowPassword] = useState(false) const { colorMode, toggleColorMode } = useColorMode() - const [showSuccessMessage, setShowSuccessMessage] = useState(false); + const [showSuccessMessage, setShowSuccessMessage] = useState(false) const formBackground = useColorModeValue("white", "gray.800") const buttonColor = useColorModeValue("gray.800", "white") - const textColor = useColorModeValue("gray.800", "white") // NAMA const [name, setName] = useState("") @@ -105,7 +102,7 @@ const RegisterOrg = () => { headers: { "X-API-KEY": "kunciT", "Content-Type": "application/json" } } ) - setShowSuccessMessage(true); + setShowSuccessMessage(true) setName("") setEmail("") setPassword("") @@ -127,7 +124,11 @@ const RegisterOrg = () => { setShowPassword(!showPassword) } return ( - <motion.div initial={{ opacity: 0, y: -50 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }}> + <motion.div + initial={{ opacity: 0, y: -50 }} + animate={{ opacity: 1, y: 0 }} + transition={{ duration: 0.5 }} + > <Flex h="100vh"> {/* FORM */} <Flex @@ -164,7 +165,13 @@ const RegisterOrg = () => { /> <FormLabel bg={formBackground}>Name </FormLabel> </FormControl> - <FormControl variant="floating" id="email" isRequired isInvalid={!validEmail} mb={6}> + <FormControl + variant="floating" + id="email" + isRequired + isInvalid={!validEmail} + mb={6} + > <Input placeholder=" " type="email" @@ -178,7 +185,13 @@ const RegisterOrg = () => { {!validEmail && "Invalid Email"} </FormErrorMessage> </FormControl> - <FormControl variant="floating" id="password" isRequired isInvalid={!validPwd} mb={6}> + <FormControl + variant="floating" + id="password" + isRequired + isInvalid={!validPwd} + mb={6} + > <InputGroup> <Input placeholder=" " @@ -199,10 +212,17 @@ const RegisterOrg = () => { </InputRightElement> </InputGroup> <FormErrorMessage> - Password must contain at least one digit and be a minimum of 8 characters long + Password must contain at least one digit and be a minimum of 8 + characters long </FormErrorMessage> </FormControl> - <FormControl variant="floating" id="passwordConfirmation" isRequired isInvalid={!validMatch} mb={6}> + <FormControl + variant="floating" + id="passwordConfirmation" + isRequired + isInvalid={!validMatch} + mb={6} + > <InputGroup> <Input placeholder=" " @@ -222,9 +242,7 @@ const RegisterOrg = () => { /> </InputRightElement> </InputGroup> - <FormErrorMessage> - Password do not match - </FormErrorMessage> + <FormErrorMessage>Password do not match</FormErrorMessage> </FormControl> <FormControl variant="floating" id="name" isRequired mb={6}> <Input @@ -236,7 +254,12 @@ const RegisterOrg = () => { /> <FormLabel bg={formBackground}>Address </FormLabel> </FormControl> - <FormControl variant="floating" id="organizationDescription" isRequired mb={6}> + <FormControl + variant="floating" + id="organizationDescription" + isRequired + mb={6} + > <Input placeholder=" " type="text" @@ -246,7 +269,12 @@ const RegisterOrg = () => { /> <FormLabel bg={formBackground}>Description </FormLabel> </FormControl> - <FormControl variant="floating" id="organizationDescription" isRequired mb={6}> + <FormControl + variant="floating" + id="organizationDescription" + isRequired + mb={6} + > <Input placeholder=" " type="text" @@ -256,7 +284,13 @@ const RegisterOrg = () => { /> <FormLabel bg={formBackground}>Refferal Code </FormLabel> </FormControl> - <Button bg={buttonColor} color={formBackground} _hover={{ bg: "gray.600", color: "gray.200" }} mb={8} onClick={handleSubmit}> + <Button + bg={buttonColor} + color={formBackground} + _hover={{ bg: "gray.600", color: "gray.200" }} + mb={8} + onClick={handleSubmit} + > Register </Button> <Box position="absolute" top="2" left="2"> diff --git a/src/components/Register/RegisterUniversity.tsx b/src/components/Register/RegisterUniversity.tsx index b352d10..4b7b3cf 100644 --- a/src/components/Register/RegisterUniversity.tsx +++ b/src/components/Register/RegisterUniversity.tsx @@ -1,5 +1,5 @@ import { useState } from "react" -import { motion } from "framer-motion"; +import { motion } from "framer-motion" import { Flex, Heading, @@ -16,14 +16,12 @@ import { Image, FormErrorMessage, Alert, - AlertIcon, + AlertIcon } from "@chakra-ui/react" import { ViewIcon, ViewOffIcon, WarningIcon } from "@chakra-ui/icons" import { Link } from "react-router-dom" -import axios from "../../api/axios" -import { redirect } from "react-router-dom" -import { FaSun, FaMoon } from "react-icons/fa"; -import useAxiosPrivate from "../../hooks/axiosPrivate"; +import { FaSun, FaMoon } from "react-icons/fa" +import useAxiosPrivate from "../../hooks/axiosPrivate" const EMAIL_REGEX = /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/ const PWD_REGEX = /^(?=.*\d).{8,}$/ @@ -33,10 +31,9 @@ const RegisterUni = () => { const axiosInstance = useAxiosPrivate() const [showPassword, setShowPassword] = useState(false) const { colorMode, toggleColorMode } = useColorMode() - const [showSuccessMessage, setShowSuccessMessage] = useState(false); + const [showSuccessMessage, setShowSuccessMessage] = useState(false) const formBackground = useColorModeValue("white", "gray.800") const buttonColor = useColorModeValue("gray.800", "white") - const textColor = useColorModeValue("gray.800", "white") // NAMA const [name, setName] = useState("") @@ -94,13 +91,13 @@ const RegisterUni = () => { email: email, password: password, address: address, - universityDescription: universityDescription, + universityDescription: universityDescription }, { headers: { "X-API-KEY": "kunciT", "Content-Type": "application/json" } } ) - setShowSuccessMessage(true); + setShowSuccessMessage(true) setName("") setEmail("") setPassword("") @@ -121,7 +118,11 @@ const RegisterUni = () => { setShowPassword(!showPassword) } return ( - <motion.div initial={{ opacity: 0, y: -50 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.5 }}> + <motion.div + initial={{ opacity: 0, y: -50 }} + animate={{ opacity: 1, y: 0 }} + transition={{ duration: 0.5 }} + > <Flex h="100vh"> {/* FORM */} <Flex @@ -158,7 +159,13 @@ const RegisterUni = () => { /> <FormLabel bg={formBackground}>Name </FormLabel> </FormControl> - <FormControl variant="floating" id="email" isRequired isInvalid={!validEmail} mb={6}> + <FormControl + variant="floating" + id="email" + isRequired + isInvalid={!validEmail} + mb={6} + > <Input placeholder=" " type="email" @@ -172,7 +179,13 @@ const RegisterUni = () => { {!validEmail && "Invalid Email"} </FormErrorMessage> </FormControl> - <FormControl variant="floating" id="password" isRequired isInvalid={!validPwd} mb={6}> + <FormControl + variant="floating" + id="password" + isRequired + isInvalid={!validPwd} + mb={6} + > <InputGroup> <Input placeholder=" " @@ -193,10 +206,17 @@ const RegisterUni = () => { </InputRightElement> </InputGroup> <FormErrorMessage> - Password must contain at least one digit and be a minimum of 8 characters long + Password must contain at least one digit and be a minimum of 8 + characters long </FormErrorMessage> </FormControl> - <FormControl variant="floating" id="passwordConfirmation" isRequired isInvalid={!validMatch} mb={6}> + <FormControl + variant="floating" + id="passwordConfirmation" + isRequired + isInvalid={!validMatch} + mb={6} + > <InputGroup> <Input placeholder=" " @@ -216,9 +236,7 @@ const RegisterUni = () => { /> </InputRightElement> </InputGroup> - <FormErrorMessage> - Password do not match - </FormErrorMessage> + <FormErrorMessage>Password do not match</FormErrorMessage> </FormControl> <FormControl variant="floating" id="name" isRequired mb={6}> <Input @@ -230,7 +248,12 @@ const RegisterUni = () => { /> <FormLabel bg={formBackground}>Address </FormLabel> </FormControl> - <FormControl variant="floating" id="universityDescription" isRequired mb={6}> + <FormControl + variant="floating" + id="universityDescription" + isRequired + mb={6} + > <Input placeholder=" " type="text" @@ -240,7 +263,13 @@ const RegisterUni = () => { /> <FormLabel bg={formBackground}>Description </FormLabel> </FormControl> - <Button bg={buttonColor} color={formBackground} _hover={{ bg: "gray.600", color: "gray.200" }} mb={8} onClick={handleSubmit}> + <Button + bg={buttonColor} + color={formBackground} + _hover={{ bg: "gray.600", color: "gray.200" }} + mb={8} + onClick={handleSubmit} + > Register </Button> <Box position="absolute" top="2" left="2"> diff --git a/src/components/Report/Report.tsx b/src/components/Report/Report.tsx index 7188b4c..4c51a81 100644 --- a/src/components/Report/Report.tsx +++ b/src/components/Report/Report.tsx @@ -22,7 +22,6 @@ import { HStack, Icon } from "@chakra-ui/react" -import axios from "axios" import React, { useState, useEffect } from "react" import { ArrowBackIcon, @@ -31,67 +30,67 @@ import { Search2Icon } from "@chakra-ui/icons" import { FaFilter } from "react-icons/fa" -import { debounce, get } from "lodash" +import { debounce } from "lodash" import useAxiosPrivate from "../../hooks/axiosPrivate" import { handleGetInfo } from "../../utils/auth" const Report: React.FC = () => { - const [userInfo, setUserInfo] = useState({ + const [UserInfo, setUserInfo] = useState({ user_id: 0, name: "", email: "", role: "" - }); + }) const axiosInstance = useAxiosPrivate() - const [userId, setUserId] = useState(0); - const [students, setStudents] = useState([]); - const [currentPage, setCurrentPage] = useState(1); - const [itemsPerPage, setItemsPerPage] = useState(5); - const [search, setSearch] = useState(""); - const [numberOfPages, setNumberOfPages] = useState(0); - const MAX_PAGE_BUTTONS = 3; + const [userId, setUserId] = useState(0) + const [students, setStudents] = useState([]) + const [currentPage, setCurrentPage] = useState(1) + const [itemsPerPage, setItemsPerPage] = useState(5) + const [search, setSearch] = useState("") + const [numberOfPages, setNumberOfPages] = useState(0) + const MAX_PAGE_BUTTONS = 3 const fetchStudents = async () => { const url = new URL( process.env.REACT_APP_API_URL + "/api/university/stats/" + userId - ); - const params = new URLSearchParams(); - params.append("name", search); - params.append("itemsperpage", String(itemsPerPage)); - params.append("currentPage", String(currentPage)); - console.log(params.toString()); - url.search = params.toString(); - const response = await axiosInstance.get(url.toString()); - const students = await response.data; - setNumberOfPages(Math.ceil(students.data.total / itemsPerPage || 100)); - setStudents(students.data.data); - }; - - const debounceFetch = debounce(fetchStudents, 500); + ) + const params = new URLSearchParams() + params.append("name", search) + params.append("itemsperpage", String(itemsPerPage)) + params.append("currentPage", String(currentPage)) + console.log(params.toString()) + url.search = params.toString() + const response = await axiosInstance.get(url.toString()) + const students = await response.data + setNumberOfPages(Math.ceil(students.data.total / itemsPerPage || 100)) + setStudents(students.data.data) + } + + const debounceFetch = debounce(fetchStudents, 500) useEffect(() => { const getInfoAndFetchStudents = async () => { - const response = await handleGetInfo(); + const response = await handleGetInfo() setUserInfo({ user_id: response?.data.user_id, name: response?.data.name, email: response?.data.email, role: response?.data.roles - }); + }) if (userId === 0 && response?.data.user_id !== 0) { - setUserId(response?.data.user_id); + setUserId(response?.data.user_id) } - debounceFetch(); - }; + debounceFetch() + } - getInfoAndFetchStudents(); - }, [search, itemsPerPage, currentPage, userId]); + getInfoAndFetchStudents() + }, [search, itemsPerPage, currentPage, userId]) useEffect(() => { - setCurrentPage(1); + setCurrentPage(1) }, [itemsPerPage]) const startPage = diff --git a/src/hooks/axiosPrivate.tsx b/src/hooks/axiosPrivate.tsx index 4509255..1890db1 100644 --- a/src/hooks/axiosPrivate.tsx +++ b/src/hooks/axiosPrivate.tsx @@ -1,34 +1,29 @@ /* eslint-disable react-hooks/exhaustive-deps */ -import { axiosPrivate } from "../api/axios"; -import { useEffect } from "react"; -import useRefreshToken from "./useRefreshToken"; -import Cookies from "js-cookie"; +import { axiosPrivate } from "../api/axios" +import { useEffect } from "react" +import useRefreshToken from "./useRefreshToken" const useAxiosPrivate = () => { - const refresh = useRefreshToken(); + const refresh = useRefreshToken() useEffect(() => { const requestIntercept = axiosPrivate.interceptors.request.use( async (config) => { try { - // Ensure that the access token is up-to-date before making the request - await refresh(); - - // Set the new access token in the request headers - // config.headers["Authorization"] = `Bearer ${newAccessToken}`; - return config; + await refresh() + return config } catch (error) { - return Promise.reject(error); + return Promise.reject(error) } }, (error) => Promise.reject(error) - ); + ) return () => { - axiosPrivate.interceptors.request.eject(requestIntercept); - }; - }, [refresh]); + axiosPrivate.interceptors.request.eject(requestIntercept) + } + }, [refresh]) - return axiosPrivate; -}; + return axiosPrivate +} -export default useAxiosPrivate; +export default useAxiosPrivate diff --git a/src/hooks/useRefreshToken.tsx b/src/hooks/useRefreshToken.tsx index 57464b1..6961f51 100644 --- a/src/hooks/useRefreshToken.tsx +++ b/src/hooks/useRefreshToken.tsx @@ -1,5 +1,4 @@ import axios from "../api/axios" -import Cookies from "js-cookie" const useRefreshToken = () => { const refresh = async () => { @@ -9,7 +8,6 @@ const useRefreshToken = () => { ) return response.data } catch (error) { - // console.error("An error occurred while refreshing the token:", error) throw error } } diff --git a/src/utils/RequireAuth.tsx b/src/utils/RequireAuth.tsx index eb6ca37..4f224a8 100644 --- a/src/utils/RequireAuth.tsx +++ b/src/utils/RequireAuth.tsx @@ -1,5 +1,5 @@ import { useLocation, Outlet, useNavigate } from "react-router-dom" -import { useState, useEffect } from "react" +import { useState } from "react" import useRefreshToken from "../hooks/useRefreshToken" import { handleGetInfo } from "./auth" diff --git a/src/utils/auth.tsx b/src/utils/auth.tsx index c80ee97..b473177 100644 --- a/src/utils/auth.tsx +++ b/src/utils/auth.tsx @@ -58,4 +58,3 @@ async function handleGetInfo() { } } export { handleLogin, handleLogout, handleGetInfo } - -- GitLab