justforsake

This commit is contained in:
Pradeeppon01 2024-06-15 14:27:06 +05:30
parent 33147c8b0e
commit 95108241f2
5 changed files with 396 additions and 14 deletions

4
.env
View File

@ -1,4 +1,4 @@
# VITE_REACT_APP_BACKEND_URL="https://sandbox.exampaper.vidh.ai" # VITE_REACT_APP_BACKEND_URL="https://sandbox.exampaper.vidh.ai"
# VITE_REACT_APP_BACKEND_URL="http://localhost:9999" VITE_REACT_APP_BACKEND_URL="http://localhost:9999"
METABASE_BASE_URL="http://metabase.usln.in/public/question/d8774923-09bb-4cd9-903b-559d417e12cf" 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="https://api.exampaper.vidh.ai"

View File

@ -15,6 +15,7 @@ import Statistics from "./Components/Statistics";
import AnomolyAttendencePage from "./Components/AnomolyAttendencePage"; import AnomolyAttendencePage from "./Components/AnomolyAttendencePage";
import AttendenceAdditionalRecord from "./Components/AttendenceAdditionalRecord"; import AttendenceAdditionalRecord from "./Components/AttendenceAdditionalRecord";
import AttendenceAdditionalRecordCorrection from "./Components/AttendenceAdditionalRecordCorrection"; import AttendenceAdditionalRecordCorrection from "./Components/AttendenceAdditionalRecordCorrection";
import QueryExecutor from "./Components/QueryExecutor";
function App() { function App() {
return ( return (
@ -22,6 +23,7 @@ function App() {
<BrowserRouter> <BrowserRouter>
<Routes> <Routes>
<Route path="/" element={<Home />}></Route> <Route path="/" element={<Home />}></Route>
<Route path="/sqlPlayground" element={<QueryExecutor/>}></Route>
<Route <Route
path="/anomoly/attendence/reassigned" path="/anomoly/attendence/reassigned"
element={<AnomolyReassigned />} element={<AnomolyReassigned />}

View File

@ -106,17 +106,34 @@ const PartACorrection = () => {
const examDateInputRef = useRef(null); const examDateInputRef = useRef(null);
const studentNameInputRef = useRef(null); const studentNameInputRef = useRef(null);
const bookletInputRef = useRef(null); const bookletInputRef = useRef(null);
const registerNumberInputRef = useRef(null);
// Handle the Enter key press in the register number input // Handle the Enter key press in the register number input
const handleRegisterNumberKeyDown = (e) => { const handleRegisterNumberKeyDown = (e) => {
console.log("Handle register number key down ....")
if (e.key === 'Enter') { if (e.key === 'Enter') {
console.log("Entering subject code field ...")
// Focus on the subject code input // Focus on the subject code input
registerNumberInputRef.current.unfocus()
const subjectCodeInput = subjectCodeInputRef.current; const subjectCodeInput = subjectCodeInputRef.current;
console.log("Subject code input :: ",subjectCodeInput)
subjectCodeInput.focus(); subjectCodeInput.focus();
subjectCodeInput.select(); subjectCodeInput.select();
} }
}; };
const handleBookletSerialNoKeyDown = (e) =>{
console.log("Handdle booklet serial no key down.....")
if(e.key === 'Enter'){
console.log("Entering register number field...")
const registerNumberInputField = registerNumberInputRef.current
console.log("Register number input :: ",registerNumberInputField)
registerNumberInputField.focus()
// const ele = document.getElementById("corrected-register-number-input")
// console.log("ELE : ",ele)
// ele.focus()
}
}
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -460,6 +477,7 @@ const PartACorrection = () => {
}; };
const updatePartAanomoly = async (e) => { const updatePartAanomoly = async (e) => {
subjectCodeInputRef.current.blur()
setIsLoading(true); setIsLoading(true);
setMetaBaseRegnoLink(null); setMetaBaseRegnoLink(null);
setMetaBaseSubjectLinkWithTitle(null); setMetaBaseSubjectLinkWithTitle(null);
@ -768,7 +786,7 @@ const PartACorrection = () => {
/> />
</Box> </Box>
</Box> */} </Box> */}
{showSubjectTitleInput && ( {/* {showSubjectTitleInput && (
<Box className="d-flex flex-column align-items-start gap-2 py-2"> <Box className="d-flex flex-column align-items-start gap-2 py-2">
<label for="corrected-register-number-input"> <label for="corrected-register-number-input">
Corrected Subject Title: Corrected Subject Title:
@ -785,10 +803,10 @@ const PartACorrection = () => {
/> />
</Box> </Box>
</Box> </Box>
)} )} */}
{showAdditionalStudentInputs && ( {showAdditionalStudentInputs && (
<> <>
<Box className="d-flex flex-column align-items-start gap-2 py-2"> {/* <Box className="d-flex flex-column align-items-start gap-2 py-2">
<label for="corrected-register-number-input"> <label for="corrected-register-number-input">
Corrected Exam Centre Code: Corrected Exam Centre Code:
</label> </label>
@ -806,8 +824,8 @@ const PartACorrection = () => {
}} }}
/> />
</Box> </Box>
</Box> </Box> */}
<Box className="d-flex flex-column align-items-start gap-2 py-2"> {/* <Box className="d-flex flex-column align-items-start gap-2 py-2">
<label for="corrected-register-number-input"> <label for="corrected-register-number-input">
Corrected Exam Date: Corrected Exam Date:
</label> </label>
@ -824,8 +842,8 @@ const PartACorrection = () => {
placeholder="(DD-MM-YYYY)" placeholder="(DD-MM-YYYY)"
/> />
</Box> </Box>
</Box> </Box> */}
<Box className="d-flex flex-column align-items-start gap-2 py-2"> {/* <Box className="d-flex flex-column align-items-start gap-2 py-2">
<label for="corrected-register-number-input"> <label for="corrected-register-number-input">
Corrected Student Name: Corrected Student Name:
</label> </label>
@ -841,7 +859,7 @@ const PartACorrection = () => {
}} }}
/> />
</Box> </Box>
</Box> </Box> */}
{batchType === "old" && ( {batchType === "old" && (
<Box className="d-flex flex-column align-items-start gap-2 py-2"> <Box className="d-flex flex-column align-items-start gap-2 py-2">
<label for="corrected-register-number-input"> <label for="corrected-register-number-input">
@ -854,6 +872,7 @@ const PartACorrection = () => {
value={correctedSerialNo} value={correctedSerialNo}
inputRef={bookletInputRef} inputRef={bookletInputRef}
autoComplete="off" autoComplete="off"
onKeyDown={handleBookletSerialNoKeyDown}
onChange={(e) => { onChange={(e) => {
setCorrectedSerialNo(e.target.value); setCorrectedSerialNo(e.target.value);
}} }}
@ -874,6 +893,7 @@ const PartACorrection = () => {
id="corrected-register-number-input" id="corrected-register-number-input"
className="w-100" className="w-100"
value={correctedRegisterNo} value={correctedRegisterNo}
inputRef={registerNumberInputRef}
autoComplete="off" autoComplete="off"
onKeyDown={handleRegisterNumberKeyDown} // Attach the keydown handler onKeyDown={handleRegisterNumberKeyDown} // Attach the keydown handler
onChange={(e) => { onChange={(e) => {
@ -980,7 +1000,7 @@ const PartACorrection = () => {
/> />
</Box> </Box>
</Box> */} </Box> */}
{showSubjectTitleInput && ( {/* {showSubjectTitleInput && (
<Box className="d-flex flex-column align-items-start gap-2 py-2"> <Box className="d-flex flex-column align-items-start gap-2 py-2">
<label for="corrected-register-number-input"> <label for="corrected-register-number-input">
Corrected Subject Title: Corrected Subject Title:
@ -997,10 +1017,10 @@ const PartACorrection = () => {
/> />
</Box> </Box>
</Box> </Box>
)} )} */}
{showAdditionalStudentInputs && ( {showAdditionalStudentInputs && (
<> <>
<Box className="d-flex flex-column align-items-start gap-2 py-2"> {/* <Box className="d-flex flex-column align-items-start gap-2 py-2">
<label for="corrected-register-number-input"> <label for="corrected-register-number-input">
Corrected Exam Centre Code: Corrected Exam Centre Code:
</label> </label>
@ -1050,7 +1070,7 @@ const PartACorrection = () => {
}} }}
/> />
</Box> </Box>
</Box> </Box> */}
<Box className="d-flex flex-column align-items-start gap-2 py-2"> <Box className="d-flex flex-column align-items-start gap-2 py-2">
<label for="corrected-register-number-input"> <label for="corrected-register-number-input">
Corrected Booklet Serial No: Corrected Booklet Serial No:
@ -1060,6 +1080,7 @@ const PartACorrection = () => {
id="corrected-register-number-input" id="corrected-register-number-input"
className="w-100" className="w-100"
value={correctedSerialNo} value={correctedSerialNo}
onKeyDown={handleBookletSerialNoKeyDown}
autoComplete="off" autoComplete="off"
onChange={(e) => { onChange={(e) => {
setCorrectedSerialNo(e.target.value); setCorrectedSerialNo(e.target.value);
@ -1081,6 +1102,8 @@ const PartACorrection = () => {
className="w-100" className="w-100"
value={correctedRegisterNo} value={correctedRegisterNo}
autoComplete="off" autoComplete="off"
inputRef={registerNumberInputRef}
onKeyDown={handleRegisterNumberKeyDown}
onChange={(e) => { onChange={(e) => {
setCorrectedRegisterNo(e.target.value); setCorrectedRegisterNo(e.target.value);
}} }}

View File

@ -0,0 +1,339 @@
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 { useSelector, useDispatch } from "react-redux";
import {
updatePartAanomolyData,
updateSystemNo,
} from "../redux/actions/actions";
import SimpleDialog from "./SimpleDialog";
import SystemNumberDialog from "./SystemNumberDialog";
import ValidationContainer from "./ValidationContainer";
const { Header, Content, Footer, Sider } = Layout;
const QueryExecutor = () => {
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 [limit, setLimit] = useState("");
const recordsPerPage = 5;
const {
token: { colorBgContainer, borderRadiusLG },
} = theme.useToken();
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;
}
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);
const totalPageCount = Math.ceil(data.results.length / recordsPerPage);
setTotalPages(totalPageCount);
setCurrentPage(1);
setResponseData(data.results.slice(0, recordsPerPage));
} else {
toast.error(data.message);
}
} catch (error) {
console.error("Error:", error);
}
};
useEffect(() => {
if (totalData.length > 0) {
const startIndex = (currentPage - 1) * recordsPerPage;
const endIndex = startIndex + recordsPerPage;
setResponseData(totalData.slice(startIndex, endIndex));
}
}, [currentPage, totalData]);
const getTableData = () => {
if (responseData.length === 0) return null;
const keys = Object.keys(totalData[0]);
return (
<div className="w-100">
<div className="text-left d-flex justify-content-between align-items-center">
<h5>
<strong>Total Results </strong> : {totalData.length}
</h5>
{totalData.length > 0 && (
<div id="footer-container">
<div
id="footer-main"
className="d-flex justify-content-center p-3 align-items-center"
>
<div className="d-flex justify-content-center align-items-center p-1">
<strong>{currentPage}</strong>/<strong>{totalPages}</strong>
</div>
<div className="d-flex gap-3">
<button
className="btn text-light bg-primary rounded p-2 mx-3"
onClick={() =>
setCurrentPage((prev) => Math.max(prev - 1, 1))
}
>
Previous
</button>
<button
className="btn text-light bg-primary rounded p-2"
onClick={() =>
setCurrentPage((prev) => Math.min(prev + 1, totalPages))
}
>
Next
</button>
</div>
</div>
</div>
)}
</div>
<div className="my-2 overflow-auto">
<table>
<thead>
<tr>
<th>sno</th>
<th>Record Info</th>
<th>Image</th>
</tr>
</thead>
<tbody>
{responseData.map((value, index) => {
const sno = totalData.indexOf(value) + 1;
let recordInfo = "";
let imageInfo = "";
keys.forEach((header) => {
if (header !== imageColumn) {
recordInfo += `<p><strong>${header}</strong>: ${value[header]}</p>`;
} else {
imageInfo = (
<td key={header}>
<img
src={`https://docs.exampaper.vidh.ai/${value[header]}`}
width="900px"
height="auto"
alt={header}
/>
</td>
);
}
});
return (
<tr key={index}>
<td>{sno}</td>
<td>
<div
className="d-flex flex-column p-2"
dangerouslySetInnerHTML={{ __html: recordInfo }}
></div>
</td>
{imageInfo}
</tr>
);
})}
</tbody>
</table>
</div>
</div>
);
};
return (
<Layout
style={{
minHeight: "100vh",
}}
>
<ToastContainer />
<Layout>
<Header
style={{
padding: 0,
background: colorBgContainer,
}}
>
<Box className="d-flex justify-content-between h-100 py-1 px-2">
<Button
className="bg-primary p-1 text-light"
onClick={() => {
navigate(-1);
}}
>
<ArrowBackIcon />
</Button>
<Box className="d-flex justify-content-between gap-2">
{/* <Button
className="bg-primary p-1 text-light"
onClick={() => {
navigate("/anomoly/reassigned/stats");
}}
>
<QueryStatsIcon />
</Button> */}
<Box className="d-flex justify-content-between gap-md-4 gap-1 align-items-center">
<Button
className="bg-primary p-1 text-light rounded h-100"
onClick={() => {
navigate("/");
}}
>
<HomeIcon />
</Button>
</Box>
</Box>
</Box>
</Header>
<Content
style={{
margin: "16px 16px",
}}
>
<div className="mx-3">
<div className="my-3 d-flex flex-md-row flex-column">
<div className="w-100 w-md-75">
<textarea
className="w-100 p-3 h5"
id="text-area-input"
placeholder="Enter your query ...."
rows="5"
value={query}
onChange={(e) => setQuery(e.target.value)}
></textarea>
</div>
<div className="d-none d-md-block w-25">
<div className="w-100 d-flex flex-column gap-2 mx-2">
<input
className="rounded p-2 h6"
type="text"
placeholder="Limit"
id="limit-input"
autoComplete="off"
value={limit}
onChange={(e) => setLimit(e.target.value)}
/>
<input
className="input rounded p-2 h6"
type="text"
placeholder="Image column name"
id="image-column-input"
autoComplete="off"
value={imageColumn}
onChange={(e) => setImageColumn(e.target.value)}
/>
<button
className="btn bg-primary text-light"
id="submit-btn"
onClick={fetchQueryValue}
>
Submit
</button>
</div>
</div>
<div className="d-block d-md-none w-100">
<div className="w-100 d-flex flex-column gap-2 mx-2">
<input
className="rounded p-2 h6"
type="text"
placeholder="Limit"
id="limit-input"
autoComplete="off"
value={limit}
onChange={(e) => setLimit(e.target.value)}
/>
<input
className="input rounded p-2 h6"
type="text"
placeholder="Image column name"
id="image-column-input"
autoComplete="off"
value={imageColumn}
onChange={(e) => setImageColumn(e.target.value)}
/>
<button
className="btn bg-primary text-light"
id="submit-btn"
onClick={fetchQueryValue}
>
Submit
</button>
</div>
</div>
</div>
<div
id="results-container"
className="d-flex w-100 justify-content-center"
>
{getTableData()}
</div>
</div>
</Content>
<Footer
style={{
textAlign: "center",
}}
>
exampaper.vidh.ai ©{new Date().getFullYear()}
</Footer>
</Layout>
{isLoading && <LoadingContainer loadingText={"Loading"} />}
</Layout>
);
};
export default QueryExecutor;

View File

@ -66,3 +66,21 @@ button:focus-visible {
background-color: #f9f9f9; background-color: #f9f9f9;
} }
} }
table {
border-collapse: collapse;
border: 1px solid black !important;
width: 100%;
}
p {
margin: 0 !important;
padding: 0 !important;
}
th,
td {
padding: 5px;
border: 1px solid black !important;
text-align: left;
}