diff --git a/.env b/.env index 54940de..a7ae0e1 100644 --- a/.env +++ b/.env @@ -1,4 +1,5 @@ #VITE_REACT_APP_BACKEND_URL="https://sandbox.exampaper.vidh.ai" METABASE_BASE_URL="http://metabase.usln.in/public/question/d8774923-09bb-4cd9-903b-559d417e12cf" -VITE_REACT_APP_BACKEND_URL="https://api.exampaper.vidh.ai" -#VITE_REACT_APP_BACKEND_URL="http://localhost:9999" + +VITE_REACT_APP_BACKEND_URL="http://localhost:9999" +# VITE_REACT_APP_BACKEND_URL="https://api.exampaper.vidh.ai" diff --git a/src/App.jsx b/src/App.jsx index d10828e..e0e1452 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -25,6 +25,8 @@ import BarcodeScanner from "./Components/BarcodeScanner" import EvQrcode from "./Components/EvQrcode"; import QrcodeCardEditor from "./Components/QrCodeCardEditor"; import StudentResultsData from "./Components/StudentsResultsData"; +import PlayGrounds from "./Components/PlayGrounds"; +import PlayGround from "./Components/PlayGround"; function App() { return ( @@ -36,6 +38,8 @@ function App() { }> }> }> + }> + }> } diff --git a/src/Components/CustomQueryExecutorCard.jsx b/src/Components/CustomQueryExecutorCard.jsx new file mode 100644 index 0000000..5d97cef --- /dev/null +++ b/src/Components/CustomQueryExecutorCard.jsx @@ -0,0 +1,356 @@ +import { Box, Button } from "@mui/material"; +import DownloadIcon from "@mui/icons-material/Download"; +import { LazyLoadImage } from "react-lazy-load-image-component"; +import { Label, MoreHorizTwoTone, RotateRight } from "@mui/icons-material"; +import { useState, useEffect,useRef } from "react"; +import { ToastContainer, toast } from "react-toastify"; +import LoadingContainer from "./LoadingContainer"; +import { useNavigate } from "react-router-dom"; + +const CustomQueryExecutorCard = ({ + data, + s3_image_column, + query, + error, + error_reason, + reduxSystemNo, + degreeType, + type, + tableName +}) => { + // console.log("ERROR ============= ",error) + // console.log("ERROR REASON ============== ",error_reason) + // console.log("REDUX SYSTEM NO ================== ",reduxSystemNo) + const navigate = useNavigate(); + const [dataValue, setDataValue] = useState({}); + const [isLoading, setIsLoading] = useState(false); + // console.log("data in query executor Card : ", data); + const [keys, setKeys] = useState([]); + const [values, setValues] = useState([]); + const [rotateAngle, setRotateAngle] = useState(0); + const [imageName,setImageName] = useState(null) + const [tableNameData,setTableNameData] = useState(null) + const imageEleRef = useRef() + console.log("data =================== ",data) + // console.log("image column ====== ", s3_image_column); + // console.log("s3 image ======= ", data[s3_image_column]); + // console.log("Keys ==== ",keys) + // console.log("Values ===== ",values) + + useEffect(()=>{ + if(data){ + console.log("Image name ====== ",data?.image_name) + setImageName(data?.image_name) + } + if(tableName){ + setTableNameData(tableName) + } + },[data]) + + + const updateFront = () => { + console.log("update front"); + }; + + const updateBack = () => { + console.log("update back .."); + }; + + const initateProcess = () => { + console.log("inititate process.."); + }; + + const rotateLeft = () => { + console.log("rotate left ....."); + const newAngle = rotateAngle - 90 + setRotateAngle((prev) => prev - 90); + console.log("new angle ....",newAngle) + const newStyle = `rotate(${newAngle}deg)` + imageEleRef.current.style.transform = newStyle + }; + + const rotateRight = () => { + console.log("rotate right"); + const newAngle = rotateAngle + 90 + setRotateAngle((prev) => prev + 90); + const newStyle = `rotate(${newAngle}deg)` + imageEleRef.current.style.transform = newStyle + }; + + const buttonActions = { + PartC: [ + { btnLabel: "Mark As Front", action: updateFront }, + { btnLabel: "Mark As Back", action: updateBack }, + { btnLabel: "Initiate Process", action: initateProcess }, + ], + }; + + useEffect(() => { + setDataValue(data); + setKeys(Object.keys(data)); + setValues(Object.values(data)); + }, [data]); + + useEffect(() => { + console.log("Data value ===== ", dataValue); + setKeys(Object.keys(dataValue)); + setValues(Object.values(dataValue)); + }, [dataValue]); + + const mark_as_ev = async () => { + const payload = { + data, + }; + try { + setIsLoading(true); + const response = await fetch( + `${import.meta.env.VITE_REACT_APP_BACKEND_URL}/partcEvCoverMarking`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(payload), + } + ); + setIsLoading(false); + const responseData = await response.json(); + if (responseData.status === "success") { + const updatedData = { ...dataValue, is_cover: 1 }; + // console.log("Data ===== ", updatedData); + setDataValue(updatedData); + console.log("Updation successfull ...."); + toast.success("Record Marked As Ev !..."); + } else { + throw new Error(responseData?.message); + } + } catch (error) { + throw new Error(error); + } + }; + + const mark_as_dummy = async () => { + const payload = { + data, + }; + try { + setIsLoading(true); + const response = await fetch( + `${import.meta.env.VITE_REACT_APP_BACKEND_URL}/partcDummyMarking`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(payload), + } + ); + setIsLoading(false); + const responseData = await response.json(); + if (responseData.status === "success") { + console.log("Updation successfull ...."); + const updatedData = { ...dataValue, type: 102 }; + // console.log("Data ===== ", updatedData); + setDataValue(updatedData); + toast.success("Record Marked as Dummy ! ...."); + } else { + throw new Error(responseData?.message); + } + } catch (error) { + throw new Error(error); + } + }; + + + const saveRotatedImage = async () =>{ + try{ + if(rotateAngle === 0){ + return + } + const payload = { + imageName, + tableNameData, + rotateAngle, + s3_path : data[s3_image_column] + } + setIsLoading(true); + const response = await fetch( + `${import.meta.env.VITE_REACT_APP_BACKEND_URL}/saveRotatedImage`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(payload), + } + ); + setIsLoading(false); + const responseData = await response.json(); + if (responseData.status === "success") { + toast.success("Image Rotation Saved Successfully") + } + + }catch(error){ + setIsLoading(false) + throw new Error(error) + } + } + + const mark_as_backpage = async () => { + const payload = { + data, + }; + try { + setIsLoading(true); + const response = await fetch( + `${import.meta.env.VITE_REACT_APP_BACKEND_URL}/partcEvBacksideMarking`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(payload), + } + ); + setIsLoading(false); + const responseData = await response.json(); + if (responseData.status === "success") { + console.log("Updation successfull ...."); + const updatedData = { ...dataValue, is_backpage: 1 }; + // console.log("Data ===== ", updatedData); + setDataValue(updatedData); + toast.success("Record Marked as Backpage ! ...."); + } else { + throw new Error(responseData?.message); + } + } catch (error) { + throw new Error(error); + } + }; + + const rotate_and_process = async () => { + setIsLoading(true); + try { + const payload = { + data, + }; + const response = await fetch( + `${import.meta.env.VITE_REACT_APP_BACKEND_URL}/partCRotateProcess`, + { + method: "POST", + header: { + "Content-Type": "application/json", + }, + body: JSON.stringify(payload), + } + ); + const responseData = await response.json(); + setIsLoading(false); + if (responseData.status === "success") { + console.log("Response successfull ..."); + } + } catch (error) { + setIsLoading(false); + throw new Error(error); + } + }; + + return ( + + + + + {keys.map((record, index) => ( +

+ {keys[index]} : {values[index]} +

+ ))} +
+ + + {/* {query.includes("ocr_scanned_part_c_v1") && + data[s3_image_column] && ( + <> + + + + + + )} */} + {type && + buttonActions[type].map((action) => ( + + ))} + + + + Image Alt + + + + + + + +
+ {isLoading && } +
+ ); +}; + +export default CustomQueryExecutorCard; diff --git a/src/Components/Home.jsx b/src/Components/Home.jsx index 8fefbc8..447c05c 100644 --- a/src/Components/Home.jsx +++ b/src/Components/Home.jsx @@ -39,6 +39,10 @@ const Home = () => { { title:"EV Qrcode", url:"/evQrcode" + }, + { + title:"PlayGrounds", + url:"/Playgrounds" } // { // title:"Marks Verfication", diff --git a/src/Components/PlayGround.jsx b/src/Components/PlayGround.jsx new file mode 100644 index 0000000..1a9407a --- /dev/null +++ b/src/Components/PlayGround.jsx @@ -0,0 +1,374 @@ +import React, { useState, useEffect } from "react"; +import { + DesktopOutlined, + FileOutlined, + PieChartOutlined, + TeamOutlined, + UserOutlined, +} from "@ant-design/icons"; +import { Breadcrumb, Layout, Menu, Typography, theme } from "antd"; +import { ToastContainer, toast } from "react-toastify"; +import { Box, Button } from "@mui/material"; +import TextField from "@mui/material/TextField"; +import EditButton from "./EditButton"; +import { width } from "@mui/system"; +import "react-toastify/dist/ReactToastify.css"; +import { useSearchParams } from "react-router-dom"; +import LoadingContainer from "./LoadingContainer"; +import HomeIcon from "@mui/icons-material/Home"; +import ArrowBackIcon from "@mui/icons-material/ArrowBack"; +import { useNavigate } from "react-router-dom"; +import QueryStatsIcon from "@mui/icons-material/QueryStats"; +import RotateLeftIcon from "@mui/icons-material/RotateLeft"; +import RotateRightIcon from "@mui/icons-material/RotateRight"; +import { + updatePartAanomolyData, + updatePlaygroundCurrentPage, + updatePlaygroundResults, + updatePlaygroundTotalPages, + updateSystemNo, +} from "../redux/actions/actions"; + + +import CustomQueryExecutorCard from "./CustomQueryExecutorCard"; +import SimpleDialog from "./SimpleDialog"; +import SystemNumberDialog from "./SystemNumberDialog"; +import ValidationContainer from "./ValidationContainer"; +import QueryExecutorCard from "./QueryExecutorCard"; +import ArrowUpwardIcon from "@mui/icons-material/ArrowUpward"; +import QueryExecutortextArea from "./QueryExecutortextArea"; +import AntdesignLayout from "./AntdesignLayout"; +import TextInputField from "./TextInputField"; +import { render } from "react-dom"; +import { updatePlaygroundQuery } from "../redux/actions/actions"; +import { useSelector, useDispatch } from "react-redux"; +import PlayGrounds from "./PlayGrounds"; +import { useParams } from "react-router-dom"; + +const { Header, Content, Footer, Sider } = Layout; +const PlayGround = () => { + const { type } = useParams(); + console.log("Type ============= ", type); + const [tableName, setTableName] = useState(null); + const tableType = { + PartA: "ocr_scanned_part_a_v1", + PartC: "ocr_scanned_part_c_v1", + Attendence: "attendence_scanned_data", + }; + + useEffect(() => { + console.log("use effect type ==== ", type); + console.log("use effect table name ===== ", tableName); + console.log("table name ==== ", tableType[type]); + if (!tableName) { + setTableName(tableType[type]); + } + }, [type, tableName]); + + const [responseData, setResponseData] = useState([]); + const [totalData, setTotalData] = useState([]); + const [currentPage, setCurrentPage] = useState(1); + const [totalPages, setTotalPages] = useState(0); + const [imageColumn, setImageColumn] = useState(null); + const [query, setQuery] = useState(""); + const [isLoading, setIsLoading] = useState(false); + const [paginationPages, setPaginationPages] = useState(null); + const [limit, setLimit] = useState(""); + const recordsPerPage = 50; + const navigate = useNavigate(); + const dispatch = useDispatch(); + const reduxPlaygroundQuery = useSelector((state) => state?.playGroundQuery); + const reduxPlaygroundPageNo = useSelector( + (state) => state?.playGroundCurrentPage + ); + const reduxPlaygroundTotalPages = useSelector( + (state) => state?.playGroundtotalPages + ); + const reduxPlaygroundResults = useSelector( + (state) => state?.playGroundResults + ); + console.log("Redux playground query : ", reduxPlaygroundQuery); + console.log("Redux playground page no : ", reduxPlaygroundPageNo); + console.log("Redux playground total pages : ", reduxPlaygroundTotalPages); + console.log("Redux playground resutls : ", reduxPlaygroundResults); + const { + token: { colorBgContainer, borderRadiusLG }, + } = theme.useToken(); + + useEffect(() => { + if (reduxPlaygroundQuery && !query) { + setQuery(reduxPlaygroundQuery); + } + }, [reduxPlaygroundQuery]); + + useEffect(() => { + if (reduxPlaygroundPageNo != 0 && totalPages == 0) { + setTotalPages(reduxPlaygroundTotalPages); + } + }, [reduxPlaygroundTotalPages]); + + useEffect(() => { + console.log("1234 ---- useEffect") + if (totalData.length == 0 && reduxPlaygroundResults) { + console.log("Redux playground results if ..."); + console.log("reduxPlaygroundResults.type === type ",reduxPlaygroundResults.type === type) + if (reduxPlaygroundResults.type === type) { + console.log("Into if ...") + setTotalData(reduxPlaygroundResults?.data); + setImageColumn("s3_path"); + } + } + }, [reduxPlaygroundResults]); + + useEffect(() => { + if (currentPage == 0 && reduxPlaygroundPageNo !== 0) { + console.log("Updating in use effect ============================= >"); + setCurrentPage(reduxPlaygroundPageNo); + } + }, [reduxPlaygroundPageNo]); + + const fetchQueryValue = async () => { + if (query.includes("limit")) { + alert("Please specify the limit in the input field."); + return; + } + if (query.includes(";")) { + alert("Please remove the special character from the query ';'"); + return; + } + if (!limit) { + alert("Limit cannot be empty !!"); + return; + } + if ( + !query.includes("image_name") && + !query.includes("*") && + query.includes("ocr_scanned_part_c_v1") + ) { + alert( + "Selecting primary Key (image_name) or Selecting all (*) is mandatory" + ); + return; + } + if (!query.includes(tableName)) { + alert(`This playground is only for : ${tableName}`); + return; + } + setIsLoading(true); + const payload = { + query: query, + limit: limit, + }; + + try { + const response = await fetch( + `${import.meta.env.VITE_REACT_APP_BACKEND_URL}/fetchQueryValue`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(payload), + } + ); + const data = await response.json(); + setIsLoading(false); + if (data.status === "success") { + setTotalData(data.results); + var tmp = {}; + tmp.type = type; + tmp.data = data?.results; + // dispatch(updatePlaygroundResults(data?.results)); + dispatch(updatePlaygroundResults(tmp)); + const totalPageCount = Math.ceil(data?.results.length / recordsPerPage); + setTotalPages(totalPageCount); + dispatch(updatePlaygroundTotalPages(totalPages)); + setCurrentPage(1); + setResponseData(data.results.slice(0, recordsPerPage)); + } else { + toast.error(data.message); + } + } catch (error) { + console.error("Error:", error); + } + }; + + useEffect(() => { + dispatch(updatePlaygroundQuery(query)); + }, [query]); + + useEffect(() => { + if (totalData.length > 0) { + setResponseData([]); + console.log(" ===========================>>>>>>>>>>>>>>>>>>>>>>>> "); + setIsLoading(true); + setTimeout(() => { + const startIndex = (currentPage - 1) * recordsPerPage; + const endIndex = startIndex + recordsPerPage; + setResponseData(totalData.slice(startIndex, endIndex)); + setIsLoading(false); + }, 1000); + } + dispatch(updatePlaygroundCurrentPage(currentPage)); + renderPagination(); + }, [currentPage, totalData]); + + const renderPagination = () => { + const pages = []; + for (let i = 1; i <= totalPages; i++) { + pages.push( + + {i > 1 && " | "} + setCurrentPage(i)} + className={i === currentPage ? "active" : ""} + > + {i} + + + ); + } + setPaginationPages(pages); + }; + + useEffect(() => { + renderPagination(); + dispatch(updatePlaygroundTotalPages(totalPages)); + }, [currentPage, totalPages]); + + const getTableData = () => { + if (responseData.length === 0) return null; + const keys = Object.keys(totalData[0]); + + return ( +
+
+
+ Total Results : {totalData.length} +
+ {totalData.length > 0 && ( + + )} +
+
+ {responseData.map((data) => ( + + ))} +
+
+ ); + }; + + return ( + +
+
+
+ +
+
+
+ + + +
+
+ +
+
+ setLimit(e.target.value)} + /> + setImageColumn(e.target.value)} + /> + +
+
+
+
+ {getTableData()} +
+
+ {isLoading && } +
+ ); +}; + +export default PlayGround; diff --git a/src/Components/PlayGrounds.jsx b/src/Components/PlayGrounds.jsx new file mode 100644 index 0000000..a81b173 --- /dev/null +++ b/src/Components/PlayGrounds.jsx @@ -0,0 +1,34 @@ +import React from "react"; +import { Box } from "@mui/material"; +import HomepageCard from "./HomepageCard"; + +const PlayGrounds = () => { + const cards = [ + { + title: "PART - A", + url: "/Playground/PartA", + }, + { + title: "PART - C", + url: "/Playground/PartC", + }, + { + title: "ATTENDENCE", + url: "/Playground/Attendence", + }, + ]; + return ( + <> + +

Welcome to exampaper.vidh.ai

+
+ + {cards.map((card) => ( + + ))} + + + ); +}; + +export default PlayGrounds;