diff --git a/.env b/.env index 68a1d6f..3c38fb2 100644 --- a/.env +++ b/.env @@ -2,5 +2,5 @@ METABASE_BASE_URL="http://metabase.usln.in/public/question/d8774923-09bb-4cd9-903b-559d417e12cf" VITE_REACT_APP_BACKEND_URL="http://localhost:9999" -#VITE_REACT_APP_BACKEND_URL="https://api.dev.exampaper.usln.in" +# VITE_REACT_APP_BACKEND_URL="https://api.dev.exampaper.usln.in" #VITE_REACT_APP_BACKEND_URL="https://api.exampaper.usln.in" diff --git a/src/App.css b/src/App.css index 1ae4484..1e6d588 100644 --- a/src/App.css +++ b/src/App.css @@ -53,6 +53,7 @@ /* Notification Styles */ .notification { position: fixed; + font-size: 19px; top: 20px; right: 20px; padding: 15px; @@ -242,3 +243,16 @@ button{ background: blue; color: white; } + + +@font-face { + font-family: 'Bamini'; + src: url('./assets/fonts/Bamini_0.TTF') format('truetype'); + font-weight: normal; + font-style: normal; +} + +/* Apply the font */ +.font-bamini { + font-family: 'Bamini', sans-serif; +} \ No newline at end of file diff --git a/src/App.jsx b/src/App.jsx index e3b06bd..c68c509 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -39,6 +39,8 @@ import DataInsertion from "./Components/DataInsertion"; import DataInsertionCsvViewer from "./Components/DataInsertionCsvViewer"; import Login from "./Components/Login"; import HomeSections from "./Components/HomeSections"; +import CertificateTextVerification from "./Components/CertificateTextVerification"; +import AttendenceNotShadedCorrection from "./Components/AttendenceNotShadedCorrection"; function App() { return ( @@ -46,9 +48,15 @@ function App() { }> - }> - }> - }> + } + > + } + > + }> } @@ -65,14 +73,26 @@ function App() { path="/sections/:year/sqlPlayground/edit" element={} > - }> + } + > } > - }> - }> - }> + } + > + } + > + } + > } @@ -101,7 +121,10 @@ function App() { path="/sections/:year/anomoly/attendence/additionalSheet" element={} > - }> + } + > } @@ -114,11 +137,18 @@ function App() { path="/sections/:year/anomoly/attendence" element={} > - }> + } + > } /> + } + /> } @@ -127,18 +157,32 @@ function App() { path="/sections/:year/anomoly/reassigned/stats/:exam_centre_code" element={} > - }> + } + > + } + > + {/* } > */} - }> + } + > } > - }> + } + > }> diff --git a/src/Components/AnomolyPartC.jsx b/src/Components/AnomolyPartC.jsx index ddb71f1..74ed681 100644 --- a/src/Components/AnomolyPartC.jsx +++ b/src/Components/AnomolyPartC.jsx @@ -26,10 +26,13 @@ import FormControl from "@mui/material/FormControl"; import Select from "@mui/material/Select"; import { useSearchParams } from "react-router-dom"; import { updatePartCDegreeType } from "../redux/actions/actions"; +import { useParams } from "react-router-dom"; const { Content, Header } = Layout; function AnomalyPartC() { + const { year } = useParams() + const [searchParams, setSearchParams] = useSearchParams(); const [isLoading, setIsLoading] = useState(false); const [isLoading2, setIsLoading2] = useState(false); @@ -41,7 +44,7 @@ function AnomalyPartC() { const [totalPages, setTotalPages] = useState(1); const [showSystemNoContainer, setShowSystemNoContainer] = useState(false); const [selectedIndex, setSelectedIndex] = useState(null); - const [selectedDegreeType, setSelectedDegreeType] = useState(null); + const [selectedDegreeType, setSelectedDegreeType] = useState("0"); const [dataFetched, setDataFetched] = useState([]); const [counter, setCounter] = useState(0); const degreeTypes = [ @@ -56,7 +59,7 @@ function AnomalyPartC() { if (reduxDegreeType) { setSelectedDegreeType(reduxDegreeType); } else { - setSelectedDegreeType("2"); + setSelectedDegreeType("0"); } }, [reduxDegreeType]); @@ -140,6 +143,7 @@ function AnomalyPartC() { const payload = { systemRecords, sysNo: reduxSystemNo, + year, }; try { fetch( @@ -170,7 +174,7 @@ function AnomalyPartC() { const response = await fetch( `${ import.meta.env.VITE_REACT_APP_BACKEND_URL - }/getpartcEv?degreeType=${selectedDegreeType}`, + }/getpartcEv?degreeType=${selectedDegreeType}&year=${year}`, { method: "GET", headers: { @@ -203,6 +207,7 @@ function AnomalyPartC() { error_reason: errorReason, sysno: reduxSystemNo, degreeType: selectedDegreeType, + year: year }), headers: { "Content-Type": "application/json", @@ -368,7 +373,12 @@ function AnomalyPartC() { {item.error && ( - Code: {item.error} + Error Code: {item.error} + + )} + {item.error_reason && ( + + Error Reason: {item.error_reason} )} {item["count(*)"] && ( diff --git a/src/Components/AttendenceNotShadedCorrection.jsx b/src/Components/AttendenceNotShadedCorrection.jsx new file mode 100644 index 0000000..2320a81 --- /dev/null +++ b/src/Components/AttendenceNotShadedCorrection.jsx @@ -0,0 +1,8 @@ +const AttendenceNotShadedCorrection = () =>{ + return( +
Hl
+ ) +} + + +export default AttendenceNotShadedCorrection \ No newline at end of file diff --git a/src/Components/CertificateTextVerification.jsx b/src/Components/CertificateTextVerification.jsx new file mode 100644 index 0000000..32009a5 --- /dev/null +++ b/src/Components/CertificateTextVerification.jsx @@ -0,0 +1,242 @@ +import AntdesignLayout from "./AntdesignLayout"; +import { Box, Button } from "@mui/material"; +import { useState, useEffect, useRef } from "react"; +import { useParams } from "react-router-dom"; +import { Bamini_base64 } from "../assets/fonts/Bamini"; + +const CertificateTextVerification = () => { + const [certificateData, setCertificateData] = useState([]); + const [registerNumber, setRegisterNumber] = useState(null) + const { year } = useParams(); + const certificateDataRef = useRef(null); + + const [currentPage, setCurrentPage] = useState(1); // Track current page + const itemsPerPage = 30; // Number of items per page + + // Fetch certificate data + const fetchCertificateTextVerificationData = async () => { + try { + const payload = { + year, + registerNumber + }; + const certificateDataResponse = await fetch( + `${ + import.meta.env.VITE_REACT_APP_BACKEND_URL + }/fetchCertificateTextVerification`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(payload), + } + ); + const responseData = await certificateDataResponse.json(); + console.log("response data certificateDataResponse ==== ", responseData); + if (responseData?.status === "success") { + console.log("response status success ..."); + setCertificateData(responseData?.data); + } + } catch (error) { + throw new Error(error); + } + }; + + // Download HTML function + const downloadHTML = () => { + const content = certificateDataRef.current.outerHTML; + + // Base64 encoded font data (replace with your actual base64 string) + const base64Font = Bamini_base64; // Replace with the actual base64 string or import it + + // Create the HTML template that includes the embedded font and table styles + const htmlContent = ` + + + + + +
+ ${content} +
+ + + `; + + // Create a Blob object with the HTML content + const blob = new Blob([htmlContent], { type: "text/html" }); + + // Create a download link + const link = document.createElement("a"); + link.href = URL.createObjectURL(blob); + link.download = "certificate_data.html"; // The name of the downloaded file + + // Trigger the download + link.click(); + }; + + // Handle pagination + const totalItems = certificateData.length; + const totalPages = Math.ceil(totalItems / itemsPerPage); + const indexOfLastItem = currentPage * itemsPerPage; + const indexOfFirstItem = indexOfLastItem - itemsPerPage; + const currentData = certificateData.slice(indexOfFirstItem, indexOfLastItem); + + const paginate = (pageNumber) => setCurrentPage(pageNumber); + + useEffect(() => { + fetchCertificateTextVerificationData(); + }, []); + + return ( + + +
Certificate Tamil Text Verification
+
+ + { + setRegisterNumber(e.target.value) + }} + /> + + + + {certificateData.length > 0 && ( + <> + + + + + + + + + + + + + {currentData.map((data, index) => ( + + + + + + + + ))} + +
Register NumberTamil NameTamil DegreeTamil ClassTamil Month Year
{data?.register_number}{data?.tamil_name}{data?.tamil_degree}{data?.tamil_class_name}{data?.tamil_month_year}
+ + + + {/* Pagination Controls (Will not be included in download) */} +
+ + + {[...Array(totalPages)].map((_, index) => ( + + ))} + + +
+
+ + + + + + + + + + + + + {certificateData.map((data, index) => ( + + + + + + + + ))} + +
Register NumberTamil NameTamil DegreeTamil ClassTamil Month Year
{data?.register_number}{data?.tamil_name}{data?.tamil_degree}{data?.tamil_class_name}{data?.tamil_month_year}
+
+ + )} +
+ ); +}; + +export default CertificateTextVerification; diff --git a/src/Components/ConvocationCertificateTemplate.jsx b/src/Components/ConvocationCertificateTemplate.jsx new file mode 100644 index 0000000..244cdcb --- /dev/null +++ b/src/Components/ConvocationCertificateTemplate.jsx @@ -0,0 +1,11 @@ +const ConvocationCertificateTemplate = () => { + return ( + <> +
+ +
+ + ); +}; + +export default ConvocationCertificateTemplate; diff --git a/src/Components/CustomQueryExecutorCard.jsx b/src/Components/CustomQueryExecutorCard.jsx index 7cf5b8b..c8d2d8a 100644 --- a/src/Components/CustomQueryExecutorCard.jsx +++ b/src/Components/CustomQueryExecutorCard.jsx @@ -13,8 +13,7 @@ import PlayGroundEditContainer from "./PlayGroundEditContainer"; import saveRotatedImage from "./Utilities/PartCPlaygroundUtilities"; import markAsPartc from "./Utilities/PartAPlaygroundUtilities"; import { updateAttendenceBlank } from "./Utilities/AttendencePlaygroundUtilities"; - - +import Notification from "./Notification"; const CustomQueryExecutorCard = ({ data, @@ -26,15 +25,20 @@ const CustomQueryExecutorCard = ({ degreeType, type, tableName, - year + year, }) => { // console.log("ERROR ============= ",error) // console.log("ERROR REASON ============== ",error_reason) // console.log("REDUX SYSTEM NO ================== ",reduxSystemNo) const navigate = useNavigate(); - console.log("year in custom query executer card ====== ",year) - const imageDomain = (year === "april2024" ? "https://docs.exampaper.vidh.ai" : (year === "november2024" ? 'https://images.exampaper.usln.in' : 'https://docs.exampaper.vidh.ai')) - console.log('imageDomain ===== ',imageDomain) + console.log("year in custom query executer card ====== ", year); + const imageDomain = + year === "april2024" + ? "https://docs.exampaper.vidh.ai" + : year === "november2024" + ? "https://images.exampaper.usln.in" + : "https://docs.exampaper.vidh.ai"; + console.log("imageDomain ===== ", imageDomain); const [dataValue, setDataValue] = useState({}); const [isLoading, setIsLoading] = useState(false); // console.log("data in query executor Card : ", data); @@ -46,6 +50,7 @@ const CustomQueryExecutorCard = ({ const imageEleRef = useRef(); const [showEditContainer, setShowEditContainer] = useState(false); const [editorType, setEditorType] = useState(null); + const [notification, setNotification] = useState(null); console.log("data =================== ", data); // console.log("image column ====== ", s3_image_column); @@ -65,6 +70,10 @@ const CustomQueryExecutorCard = ({ } }, [data]); + const showNotification = (message, type) => { + setNotification({ message, type }); + }; + const updatePartAInstructions = async () => { console.log("update instrunction"); const payload = { @@ -168,7 +177,7 @@ const CustomQueryExecutorCard = ({ console.log("update front"); const payload = { data, - year + year, }; try { setIsLoading(true); @@ -192,7 +201,7 @@ const CustomQueryExecutorCard = ({ // toast.success("Record Marked as Frontpage ! ...."); } else { toast.error("Something Went Wrong !..."); - setIsLoading(false) + setIsLoading(false); throw new Error(responseData?.message); } } catch (error) { @@ -203,7 +212,7 @@ const CustomQueryExecutorCard = ({ const updateBack = async () => { const payload = { data, - year + year, }; try { setIsLoading(true); @@ -259,7 +268,7 @@ const CustomQueryExecutorCard = ({ const updateEvCover = async () => { const payload = { data, - year + year, }; try { setIsLoading(true); @@ -292,7 +301,7 @@ const CustomQueryExecutorCard = ({ const markAsPart_A = async () => { const payload = { data, - year + year, }; try { setIsLoading(true); @@ -325,7 +334,7 @@ const CustomQueryExecutorCard = ({ const markAsDummy = async () => { const payload = { data, - year + year, }; try { setIsLoading(true); @@ -348,7 +357,7 @@ const CustomQueryExecutorCard = ({ console.log("Updation successfull ...."); // toast.success("Record Marked As Ev !..."); } else { - setIsLoading(false) + setIsLoading(false); toast.error("Something Went Wrong !..."); throw new Error(responseData?.message); } @@ -365,10 +374,47 @@ const CustomQueryExecutorCard = ({ // setEditorType(type) }; - - const updateAttendenceBlankAction = () =>{ - updateAttendenceBlank(setIsLoading,data,setShowEditContainer) - } + const verifyRecord = async () => { + const payload = { + data, + year, + }; + try { + setIsLoading(true); + const response = await fetch( + `${import.meta.env.VITE_REACT_APP_BACKEND_URL}/verifyRecord`, + { + 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); + + console.log("Verification successfull ...."); + showNotification("Record Verified Successfully ..", "success"); + // toast.success("Record Marked As Ev !..."); + } else { + setIsLoading(false); + showNotification("Something Went Wrong ..", "error"); + throw new Error(responseData?.message); + } + } catch (error) { + setIsLoading(false); + showNotification("Something Went Wrong ..", "error"); + throw new Error(error); + } + }; + + const updateAttendenceBlankAction = () => { + updateAttendenceBlank(setIsLoading, data, setShowEditContainer); + }; const buttonActions = { PartC: [ @@ -376,8 +422,9 @@ const CustomQueryExecutorCard = ({ { btnLabel: "Mark As Back", action: updateBack }, { btnLabel: "Mark As Ev", action: updateEvCover }, { btnLabel: "Mark As Dummy", action: markAsDummy }, - {btnLabel: "Mark As Part-A", action: markAsPart_A}, + { btnLabel: "Mark As Part-A", action: markAsPart_A }, { btnLabel: "Edit", action: showContainerAction }, + { btnLabel: "Verify", action: verifyRecord }, ], PartA: [ { btnLabel: "Mark As Front", action: updatePartAFront }, @@ -388,15 +435,11 @@ const CustomQueryExecutorCard = ({ { btnLabel: "Edit", action: showContainerAction }, ], Attendence: [ - { btnLabel: "Mark As Blank", action:updateAttendenceBlankAction }, + { btnLabel: "Mark As Blank", action: updateAttendenceBlankAction }, { btnLabel: "Edit", action: showContainerAction }, - ] + ], }; - - - - useEffect(() => { setDataValue(data); setKeys(Object.keys(data)); @@ -474,7 +517,7 @@ const CustomQueryExecutorCard = ({ return ( - + @@ -585,12 +628,19 @@ const CustomQueryExecutorCard = ({ ))} + {notification && ( + setNotification(null)} + /> + )} {isLoading && } {showEditContainer && ( { title: "Part A OCR Anomoly - Old Dummy", url: `/sections/${year}/anomoly/partA?type=old`, }, - // { - // title: "Part C", - // url: `/sections/${year}/anomoly/partC`, - // }, + { + title: "Part C", + url: `/sections/${year}/anomoly/partC`, + }, // { // title:"Verification", // url:"/verification" @@ -59,7 +59,13 @@ const HomeSections = () => { { title:"PlayGrounds", url:`/sections/${year}/Playgrounds` - },// { + } + // }, { + // title:"Attendence Not Shaded Solver", + // url:`/sections/${year}/attendenceNotShadedCorrection` + // } + + // { // title:"Revaluation", // url:"/revaluation" // }, diff --git a/src/Components/QrCodeCardEditor.jsx b/src/Components/QrCodeCardEditor.jsx index 963d231..f4db617 100644 --- a/src/Components/QrCodeCardEditor.jsx +++ b/src/Components/QrCodeCardEditor.jsx @@ -15,10 +15,13 @@ import RotateRightIcon from "@mui/icons-material/RotateRight"; import { updatePartCErrorData, updateSystemNo } from "../redux/actions/actions"; import { updatePartCErrorList } from "../redux/actions/actions"; import { DiscFullTwoTone } from "@mui/icons-material"; +import { useParams } from "react-router-dom"; const QrcodeCardEditor = () => { + const {year} = useParams() const [searchParams, setSearchParams] = useSearchParams(); - + const table = year === "april2024" ? "ocr_scanned_part_c_v1" : year === "november2024" ? "ocr_scanned_part_c_v2" : "ocr_scanned_part_c_v1" + const [evQrcode, setEvQrcode] = useState(null); const [imageName, setImageName] = useState(null); const [isLoading, setIsLoading] = useState(false); @@ -28,7 +31,6 @@ const QrcodeCardEditor = () => { const [rotationResults, setRotationResults] = useState([]); const [rotateAngle, setRotateAngle] = useState(0); const evErrorsList = useSelector((state) => state?.partCErrorList); - const table = searchParams.get("table"); const image_name = searchParams.get("image_name"); const paramsError = searchParams.get("error"); const paramsErrorReason = searchParams.get("error_reason"); diff --git a/src/Components/QueryCardEditor.jsx b/src/Components/QueryCardEditor.jsx index 286c273..f0ad670 100644 --- a/src/Components/QueryCardEditor.jsx +++ b/src/Components/QueryCardEditor.jsx @@ -15,8 +15,10 @@ import RotateRightIcon from "@mui/icons-material/RotateRight"; import { updatePartCErrorData, updateSystemNo } from "../redux/actions/actions"; import { updatePartCErrorList } from "../redux/actions/actions"; import { DiscFullTwoTone } from "@mui/icons-material"; +import { useParams } from "react-router-dom"; const QueryCardEditor = () => { + const {year} = useParams() const [searchParams, setSearchParams] = useSearchParams(); const [barcode, setBarcode] = useState(); const [qrcode, setQrcode] = useState(); @@ -30,7 +32,8 @@ const QueryCardEditor = () => { const [rotationResults, setRotationResults] = useState([]); const [rotateAngle, setRotateAngle] = useState(0); const evErrorsList = useSelector((state) => state?.partCErrorList); - const table = searchParams.get("table"); + const table = year === "april2024" ? "ocr_scanned_part_c_v1" : year === "november2024" ? "ocr_scanned_part_c_v2" : "ocr_scanned_part_c_v1" + const imageDomain = (year === "april2024" ? "https://docs.exampaper.vidh.ai" : (year === "november2024" ? 'https://images.exampaper.usln.in' : 'https://docs.exampaper.vidh.ai')) const image_name = searchParams.get("image_name"); const paramsError = searchParams.get("error"); const paramsErrorReason = searchParams.get("error_reason"); @@ -107,6 +110,7 @@ const QueryCardEditor = () => { } }; fetchData(); + marksInputRef.current.focus() }, []); useEffect(() => { @@ -134,6 +138,7 @@ const QueryCardEditor = () => { marks, imageName, rotateAngle, + year }; const response = await fetch( `${import.meta.env.VITE_REACT_APP_BACKEND_URL}/editPartCdata`, @@ -171,7 +176,7 @@ const QueryCardEditor = () => { if (newRecords.length > 0) { console.log("Has to navigte 12 ....."); localStorage.setItem("marks_manual_data", JSON.stringify(newRecords)); - const newUrl = `/sqlPlayground/edit?image_name=${newRecords[currentIndex]?.image_name}&table=ocr_scanned_part_c_v1&error=${paramsError}&error_reason=${paramsErrorReason}°reeType=${paramsDegreeType}&sysNo=${paramsSysNo}`; + const newUrl = `/sections/${year}/sqlPlayground/edit?image_name=${newRecords[currentIndex]?.image_name}&error=${paramsError}&error_reason=${paramsErrorReason}°reeType=${paramsDegreeType}&sysNo=${paramsSysNo}`; console.log("new url ==== ", newUrl); window.location.href = newUrl; } else { @@ -242,7 +247,7 @@ const QueryCardEditor = () => { console.log("new index ===== ", newIndex); if (newRecords.length > 0) { console.log("Has to navigte 12 ....."); - const newUrl = `/sqlPlayground/edit?image_name=${evErrorsData[newIndex]?.image_name}&table=ocr_scanned_part_c_v1&error=${paramsError}&error_reason=${paramsErrorReason}°reeType=${paramsDegreeType}&sysNo=${paramsSysNo}`; + const newUrl = `/sections/${year}/sqlPlayground/edit?image_name=${evErrorsData[newIndex]?.image_name}&table=ocr_scanned_part_c_v1&error=${paramsError}&error_reason=${paramsErrorReason}°reeType=${paramsDegreeType}&sysNo=${paramsSysNo}`; console.log("new url ==== ", newUrl); window.location.href = newUrl; } @@ -273,9 +278,18 @@ const QueryCardEditor = () => { return ( - + + + + + + - {imageName &&
ID : {imageName}
} + {/* {imageName &&
ID : {imageName}
} {paramsError && (
Error Code : {paramsError}
)} @@ -285,7 +299,8 @@ const QueryCardEditor = () => { ) : (
Degree Type : PG
) - ) : null} + ) : null} */} +
COVER CODE : {recordData?.new_cover_barcode}
{
- - - - -
{isLoading && } {showDialog && ( diff --git a/src/Components/QueryExecutorCard.jsx b/src/Components/QueryExecutorCard.jsx index a451c56..17163d0 100644 --- a/src/Components/QueryExecutorCard.jsx +++ b/src/Components/QueryExecutorCard.jsx @@ -6,15 +6,19 @@ import { useState, useEffect } from "react"; import { ToastContainer, toast } from "react-toastify"; import LoadingContainer from "./LoadingContainer"; import { useNavigate } from "react-router-dom"; +import { useParams } from "react-router-dom"; + const QueryExecutorCard = ({ data, s3_image_column, query, error, error_reason, reduxSystemNo,degreeType }) => { + const { year } = useParams() + const imageDomain = (year === "april2024" ? "https://docs.exampaper.vidh.ai" : (year === "november2024" ? 'https://images.exampaper.usln.in' : 'https://docs.exampaper.vidh.ai')) // 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); + console.log("data in query executor Card : ", data); const [keys, setKeys] = useState([]); const [values, setValues] = useState([]); // console.log("image column ====== ", s3_image_column); @@ -175,7 +179,7 @@ const QueryExecutorCard = ({ data, s3_image_column, query, error, error_reason, <> @@ -207,7 +211,7 @@ const QueryExecutorCard = ({ data, s3_image_column, query, error, error_reason, )}