From 5c03a13b8e3fe36860286acbbe41ead53024a018 Mon Sep 17 00:00:00 2001 From: sagar Date: Fri, 25 Oct 2024 19:42:10 +0530 Subject: [PATCH 1/4] fix:Build the file name based on the timestamp and revert the old code. There's an issue where a hard refresh is needed after deployment. --- packages/student-app/craco.config.js | 11 +++ packages/teacher-app/src/bootstrap.js | 23 ++--- packages/teacher-app/src/service-worker.js | 85 ++++++++++------- .../src/serviceWorkerRegistration.js | 93 +++++++++++++------ 4 files changed, 135 insertions(+), 77 deletions(-) diff --git a/packages/student-app/craco.config.js b/packages/student-app/craco.config.js index 5c25484d..79777a39 100644 --- a/packages/student-app/craco.config.js +++ b/packages/student-app/craco.config.js @@ -1,5 +1,6 @@ const cracoModuleFederation = require("craco-module-federation"); const ExternalTemplateRemotesPlugin = require("external-remotes-plugin"); +const path = require("path"); module.exports = { devServer: { @@ -7,6 +8,16 @@ module.exports = { }, webpack: { plugins: [new ExternalTemplateRemotesPlugin()], + configure: (webpackConfig) => { + const timestamp = new Date().getTime(); + webpackConfig.output = { + ...webpackConfig.output, + filename: `static/js/[name].[hash]-${timestamp}.js`, + chunkFilename: `static/js/[name].[hash]-${timestamp}.chunk.js`, + path: path.resolve(__dirname, "build"), + }; + return webpackConfig; + }, }, plugins: [ { diff --git a/packages/teacher-app/src/bootstrap.js b/packages/teacher-app/src/bootstrap.js index 7930d7a0..5e5847c9 100644 --- a/packages/teacher-app/src/bootstrap.js +++ b/packages/teacher-app/src/bootstrap.js @@ -12,21 +12,12 @@ ReactDOM.render( document.getElementById("root") ); -// Register service worker -serviceWorkerRegistration.register({ - onUpdate: registration => { - // Notify user about new updates - if (window.confirm("New version available! Would you like to update?")) { - if (registration && registration.waiting) { - registration.waiting.postMessage({ type: "SKIP_WAITING" }); - registration.waiting.addEventListener("statechange", (e) => { - if (e.target.state === "activated") { - window.location.reload(); - } - }); - } - } - } -}); +// If you want your app to work offline and load faster, you can change +// unregister() to register() below. Note this comes with some pitfalls. +// Learn more about service workers: https://cra.link/PWA +serviceWorkerRegistration.unregister(); +// If you want to start measuring performance in your app, pass a function +// to log results (for example: reportWebVitals(console.log)) +// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals(); diff --git a/packages/teacher-app/src/service-worker.js b/packages/teacher-app/src/service-worker.js index 5389c5cb..a0d2c5e6 100644 --- a/packages/teacher-app/src/service-worker.js +++ b/packages/teacher-app/src/service-worker.js @@ -1,58 +1,73 @@ /* eslint-disable no-restricted-globals */ + +// This service worker can be customized! +// See https://developers.google.com/web/tools/workbox/modules +// for the list of available Workbox modules, or add any other +// code you'd like. +// You can also remove this file if you'd prefer not to use a +// service worker, and the Workbox build step will be skipped. + import { clientsClaim } from "workbox-core"; import { ExpirationPlugin } from "workbox-expiration"; import { precacheAndRoute, createHandlerBoundToURL } from "workbox-precaching"; import { registerRoute } from "workbox-routing"; import { StaleWhileRevalidate } from "workbox-strategies"; -// Import Workbox from CDN -importScripts("https://storage.googleapis.com/workbox-cdn/releases/6.1.5/workbox-sw.js"); - -// Claim clients immediately clientsClaim(); -// Listen for messages from the client to skip waiting -self.addEventListener("message", (event) => { - if (event.data && event.data.type === "SKIP_WAITING") { - self.skipWaiting(); - } -}); - -// Precache all of the assets generated by your build process +// Precache all of the assets generated by your build process. +// Their URLs are injected into the manifest variable below. +// This variable must be present somewhere in your service worker file, +// even if you decide not to use precaching. See https://cra.link/PWA precacheAndRoute(self.__WB_MANIFEST); -// Use StaleWhileRevalidate strategy for navigation requests to ensure fresh content +// Set up App Shell-style routing, so that all navigation requests +// are fulfilled with your index.html shell. Learn more at +// https://developers.google.com/web/fundamentals/architecture/app-shell +const fileExtensionRegexp = new RegExp("/[^/?]+\\.[^/]+$"); registerRoute( - ({ request }) => request.mode === "navigate", - new StaleWhileRevalidate({ - cacheName: "pages-cache", - plugins: [ - new ExpirationPlugin({ maxEntries: 50 }), - ], - }) + // Return false to exempt requests from being fulfilled by index.html. + ({ request, url }) => { + // If this isn't a navigation, skip. + if (request.mode !== "navigate") { + return false; + } // If this is a URL that starts with /_, skip. + + if (url.pathname.startsWith("/_")) { + return false; + } // If this looks like a URL for a resource, because it contains // a file extension, skip. + + if (url.pathname.match(fileExtensionRegexp)) { + return false; + } // Return true to signal that we want to use the handler. + + return true; + }, + createHandlerBoundToURL(process.env.PUBLIC_URL + "/index.html") ); -// Use StaleWhileRevalidate strategy for images and other assets +// An example runtime caching route for requests that aren't handled by the +// precache, in this case same-origin .png requests like those from in public/ registerRoute( - ({ request }) => request.destination === "image", + // Add in any other file extensions or routing criteria as needed. + ({ url }) => + url.origin === self.location.origin && url.pathname.endsWith(".png"), // Customize this strategy as needed, e.g., by changing to CacheFirst. new StaleWhileRevalidate({ - cacheName: "images-cache", + cacheName: "images", plugins: [ + // Ensure that once this runtime cache reaches a maximum size the + // least-recently used images are removed. new ExpirationPlugin({ maxEntries: 50 }), ], }) ); -// Do not cache API calls, they should always go to the network -// No route registered for API calls +// This allows the web app to trigger skipWaiting via +// registration.waiting.postMessage({type: 'SKIP_WAITING'}) +self.addEventListener("message", (event) => { + if (event.data && event.data.type === "SKIP_WAITING") { + self.skipWaiting(); + } +}); -// Fallback for other requests -registerRoute( - ({ request }) => request.destination !== "image" && request.mode !== "navigate" && !request.url.includes('/mw/'), - new StaleWhileRevalidate({ - cacheName: "default-cache", - plugins: [ - new ExpirationPlugin({ maxEntries: 50 }), - ], - }) -); +// Any other custom service worker logic can go here. diff --git a/packages/teacher-app/src/serviceWorkerRegistration.js b/packages/teacher-app/src/serviceWorkerRegistration.js index 23552d84..fd0e8c5a 100644 --- a/packages/teacher-app/src/serviceWorkerRegistration.js +++ b/packages/teacher-app/src/serviceWorkerRegistration.js @@ -1,30 +1,53 @@ +// This optional code is used to register a service worker. +// register() is not called by default. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on subsequent visits to a page, after all the +// existing tabs open on the page have been closed, since previously cached +// resources are updated in the background. + +// To learn more about the benefits of this model and instructions on how to +// opt-in, read https://cra.link/PWA + const isLocalhost = Boolean( - window.location.hostname === 'localhost' || - window.location.hostname === '[::1]' || - window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ - ) + window.location.hostname === "localhost" || + // [::1] is the IPv6 localhost address. + window.location.hostname === "[::1]" || + // 127.0.0.0/8 are considered localhost for IPv4. + window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ + ) ); export function register(config) { - if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) { + // The URL constructor is available in all browsers that support SW. const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebook/create-react-app/issues/2374 return; } - window.addEventListener('load', () => { + window.addEventListener("load", () => { const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; if (isLocalhost) { + // This is running on localhost. Let's check if a service worker still exists or not. checkValidServiceWorker(swUrl, config); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. navigator.serviceWorker.ready.then(() => { console.log( - 'This web app is being served cache-first by a service worker. ' + - 'To learn more, visit https://cra.link/PWA' + "This web app is being served cache-first by a service " + + "worker. To learn more, visit https://cra.link/PWA" ); }); } else { + // Is not localhost. Just register service worker registerValidSW(swUrl, config); } }); @@ -34,26 +57,34 @@ export function register(config) { function registerValidSW(swUrl, config) { navigator.serviceWorker .register(swUrl) - .then(registration => { + .then((registration) => { registration.onupdatefound = () => { const installingWorker = registration.installing; if (installingWorker == null) { return; } installingWorker.onstatechange = () => { - if (installingWorker.state === 'installed') { + if (installingWorker.state === "installed") { if (navigator.serviceWorker.controller) { + // At this point, the updated precached content has been fetched, + // but the previous service worker will still serve the older + // content until all client tabs are closed. console.log( - 'New content is available and will be used when all ' + - 'tabs for this page are closed. See https://cra.link/PWA.' + "New content is available and will be used when all " + + "tabs for this page are closed. See https://cra.link/PWA." ); + // Execute callback if (config && config.onUpdate) { config.onUpdate(registration); } } else { - console.log('Content is cached for offline use.'); + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log("Content is cached for offline use."); + // Execute callback if (config && config.onSuccess) { config.onSuccess(registration); } @@ -62,39 +93,49 @@ function registerValidSW(swUrl, config) { }; }; }) - .catch(error => { - console.error('Error during service worker registration:', error); + .catch((error) => { + console.error("Error during service worker registration:", error); }); } function checkValidServiceWorker(swUrl, config) { - fetch(swUrl) - .then(response => { - const contentType = response.headers.get('content-type'); + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl, { + headers: { "Service-Worker": "script" }, + }) + .then((response) => { + // Ensure service worker exists, and that we really are getting a JS file. + const contentType = response.headers.get("content-type"); if ( response.status === 404 || - (contentType != null && contentType.indexOf('javascript') === -1) + (contentType != null && contentType.indexOf("javascript") === -1) ) { - navigator.serviceWorker.ready.then(registration => { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then((registration) => { registration.unregister().then(() => { window.location.reload(); }); }); } else { + // Service worker found. Proceed as normal. registerValidSW(swUrl, config); } }) .catch(() => { console.log( - 'No internet connection found. App is running in offline mode.' + "No internet connection found. App is running in offline mode." ); }); } export function unregister() { - if ('serviceWorker' in navigator) { - navigator.serviceWorker.ready.then(registration => { - registration.unregister(); - }); + if ("serviceWorker" in navigator) { + navigator.serviceWorker.ready + .then((registration) => { + registration.unregister(); + }) + .catch((error) => { + console.error(error.message); + }); } } From f8ec60d75c902d47db408c7c99264ca7bd6e332f Mon Sep 17 00:00:00 2001 From: deepali chavhan Date: Sat, 23 Nov 2024 12:49:18 +0530 Subject: [PATCH 2/4] fix: issues fixes in student and techer filter and csv upload --- .../admin/src/api/filterStudentDetails.jsx | 21 +++++-- packages/admin/src/api/teacherBulkAPI.jsx | 11 ++-- .../admin/src/assets/images/FinalStudent.csv | 4 +- packages/admin/src/components/DownloadCsv.jsx | 60 +++++++++---------- .../admin/src/components/FilterTableData.jsx | 3 +- .../admin/src/components/StudentFilters.jsx | 29 +++++---- .../admin/src/components/StudentListView.jsx | 31 ++++------ packages/admin/src/components/TeacherCSV.jsx | 4 +- 8 files changed, 87 insertions(+), 76 deletions(-) diff --git a/packages/admin/src/api/filterStudentDetails.jsx b/packages/admin/src/api/filterStudentDetails.jsx index 9adc1dd5..1cb94b5f 100644 --- a/packages/admin/src/api/filterStudentDetails.jsx +++ b/packages/admin/src/api/filterStudentDetails.jsx @@ -9,7 +9,9 @@ export const fetchStates = async (token) => { { state: "" }, // Fetch all states { headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" }} ); - return response.data.data.map(item => item.state); + return response.data.data.map(item => ({ + label: `${item.state}` + })); } catch (error) { console.error("Error fetching states:", error); throw error; @@ -24,7 +26,9 @@ export const fetchDistricts = async (token, state = "") => { { state }, // Send selected state as payload { headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" }} ); - return response.data.data.map(item => item.district); + return response.data.data.map(item => ({ + label: `${item.district}` + })); } catch (error) { console.error("Error fetching districts:", error); throw error; @@ -39,7 +43,9 @@ export const fetchBlocks = async (token, state = "", district = "") => { { state, district }, // Send both state and district as payload { headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" }} ); - return response.data.data.map(item => item.block); + return response.data.data.map(item => ({ + label: `${item.block}` + })); } catch (error) { console.error("Error fetching blocks:", error); throw error; @@ -54,7 +60,10 @@ export const fetchSchools = async (token, state = "", district = "", block = "") { state, district, block }, // Send state, district, and block as payload { headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" }} ); - return response.data.data.map(item => item.name); + return response.data.data.map(item => ({ + label: `${item.name}`, + udiseCode: `${item.udiseCode}` + })); } catch (error) { console.error("Error fetching schools:", error); throw error; @@ -69,7 +78,9 @@ export const fetchClasses = async (token, schoolName = "") => { { schoolName }, // Send selected schoolName as payload { headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" }} ); - return response.data.data.map(item => item.name); + return response.data.data.map(item => ({ + label: `${item.name}` + })); } catch (error) { console.error("Error fetching classes:", error); throw error; diff --git a/packages/admin/src/api/teacherBulkAPI.jsx b/packages/admin/src/api/teacherBulkAPI.jsx index 4c8239dc..818b3d3e 100644 --- a/packages/admin/src/api/teacherBulkAPI.jsx +++ b/packages/admin/src/api/teacherBulkAPI.jsx @@ -19,9 +19,9 @@ const teacherBulkAPI = async (teacher) => { headers: headers, }) .then((res) => { - const names = res.data.errors.map((error) => error.name).filter(Boolean); - if (res.data.errors && res.data.errors.length > 0) { - const firstError = res.data.errors[0]; + const names = res?.data?.data?.errors.map((error) => error.name).filter(Boolean); + if (res?.data?.data?.errors && res?.data?.data?.errors.length > 0) { + const firstError = res?.data?.data?.errors[0]; if (firstError.teacherRes && firstError.teacherRes.errorMessage) { const errorMessage = firstError.teacherRes.errorMessage; localStorage.setItem("errorMessage", errorMessage); @@ -32,9 +32,10 @@ const teacherBulkAPI = async (teacher) => { console.log("No errors in the response data."); } - localStorage.setItem("bulkErrors", res.data.errors.length - 1); + const errorCount = res?.data?.data?.errors?.length ?? 0; + localStorage.setItem("bulkErrors", errorCount > 0 ? errorCount - 1 : 0); localStorage.setItem("bulkErrorsNames", names); - localStorage.setItem("successCount", res.data.successCount); + localStorage.setItem("successCount", res?.data?.data?.successCount); if (res.status === 201) { result = true; } else { diff --git a/packages/admin/src/assets/images/FinalStudent.csv b/packages/admin/src/assets/images/FinalStudent.csv index 587253fa..2a67bcdc 100644 --- a/packages/admin/src/assets/images/FinalStudent.csv +++ b/packages/admin/src/assets/images/FinalStudent.csv @@ -1,2 +1,2 @@ -name,username,email,mobile,gender,dateOfBirth,board,password,status,className,religion,school_udise,caste,annual_income,mother_education,father_education,mother_occupation,father_occupation,No_of_siblings,promotion -Test,retesttekdiwb600112121884,,9999999999,Female ,1990-01-03,West Bengal,NA ,TRUE,Class 7,Hindu,12345678,General,668,,,,,,, +name,username,email,mobile,gender,dateOfBirth,board,password,status,className,religion,school_udise,caste,annual_income,mother_education,father_education,mother_occupation,father_occupation,No_of_siblings,promotion,state,district,block +Test,retesttekdiwb600112121884,,9999999999,Female ,1990-01-03,West Bengal,NA ,TRUE,Class 7,Hindu,12345678,General,668,,,,,,,maharastra,pune,kothrud diff --git a/packages/admin/src/components/DownloadCsv.jsx b/packages/admin/src/components/DownloadCsv.jsx index 59e35adc..283abd16 100644 --- a/packages/admin/src/components/DownloadCsv.jsx +++ b/packages/admin/src/components/DownloadCsv.jsx @@ -97,19 +97,19 @@ const DownloadCsv = ({ open, handleClose }) => { // Update districts based on selected state useEffect(() => { const loadDistricts = async () => { - if (!dropdownValues.stateDropdown) return; // Check for selected state + if (!dropdownValues.stateDropdown?.label) return; // Check for selected state try { const token = sessionStorage.getItem("token"); const districts = await fetchDistricts( token, - dropdownValues.stateDropdown + dropdownValues.stateDropdown?.label ); setDistrictOptions(districts); - const blocks = await fetchBlocks(token, dropdownValues.stateDropdown); + const blocks = await fetchBlocks(token, dropdownValues.stateDropdown?.label); setBlockOptions(blocks); - const schools = await fetchSchools(token, dropdownValues.stateDropdown); + const schools = await fetchSchools(token, dropdownValues.stateDropdown?.label); setSchoolOptions(schools); } catch (error) { console.error("Error loading districts:", error); @@ -121,14 +121,14 @@ const DownloadCsv = ({ open, handleClose }) => { // Update blocks based on selected district useEffect(() => { const loadBlocks = async () => { - if (!dropdownValues.districtDropdown) return; // Check for selected district + if (!dropdownValues.districtDropdown?.label) return; // Check for selected district try { const token = sessionStorage.getItem("token"); const blocks = await fetchBlocks( token, - dropdownValues.stateDropdown, - dropdownValues.districtDropdown + dropdownValues.stateDropdown?.label, + dropdownValues.districtDropdown?.label ); setBlockOptions(blocks); } catch (error) { @@ -145,9 +145,9 @@ const DownloadCsv = ({ open, handleClose }) => { const token = sessionStorage.getItem("token"); const schools = await fetchSchools( token, - dropdownValues.stateDropdown, - dropdownValues.districtDropdown, - dropdownValues.blockDropdown + dropdownValues.stateDropdown?.label, + dropdownValues.districtDropdown?.label, + dropdownValues.blockDropdown?.label ); setSchoolOptions(schools); } catch (error) { @@ -184,11 +184,11 @@ const DownloadCsv = ({ open, handleClose }) => { // Ensure at least one dropdown value is selected before allowing download if ( - !dropdownValues.stateDropdown && - !dropdownValues.districtDropdown && - !dropdownValues.blockDropdown && - !dropdownValues.schoolNameDropdown && - !dropdownValues.classNameDropdown + !dropdownValues.stateDropdown?.label && + !dropdownValues.districtDropdown?.label && + !dropdownValues.blockDropdown?.label && + !dropdownValues.schoolNameDropdown?.label && + !dropdownValues.classNameDropdown?.label ) { alert("Please select at least one filter before downloading."); return false; @@ -199,20 +199,20 @@ const DownloadCsv = ({ open, handleClose }) => { filters: {}, }; - if (dropdownValues.stateDropdown) { - payload.filters.state = { eq: dropdownValues.stateDropdown }; + if (dropdownValues.stateDropdown?.label) { + payload.filters.state = { eq: dropdownValues.stateDropdown?.label }; } - if (dropdownValues.districtDropdown) { - payload.filters.district = { eq: dropdownValues.districtDropdown }; + if (dropdownValues.districtDropdown?.label) { + payload.filters.district = { eq: dropdownValues.districtDropdown?.label }; } - if (dropdownValues.blockDropdown) { - payload.filters.block = { eq: dropdownValues.blockDropdown }; + if (dropdownValues.blockDropdown?.label) { + payload.filters.block = { eq: dropdownValues.blockDropdown?.label }; } - if (dropdownValues.schoolNameDropdown) { - payload.filters.schoolName = { eq: dropdownValues.schoolNameDropdown }; + if (dropdownValues.schoolNameDropdown?.label) { + payload.filters.schoolName = { eq: dropdownValues.schoolNameDropdown?.label }; } - if (dropdownValues.classNameDropdown) { - payload.filters.class = { eq: dropdownValues.classNameDropdown }; + if (dropdownValues.classNameDropdown?.label) { + payload.filters.class = { eq: dropdownValues.classNameDropdown?.label }; } try { @@ -292,11 +292,11 @@ const DownloadCsv = ({ open, handleClose }) => { }; const isDownloadDisabled = - !dropdownValues.stateDropdown && - !dropdownValues.districtDropdown && - !dropdownValues.blockDropdown && - !dropdownValues.schoolNameDropdown && - !dropdownValues.classNameDropdown; + !dropdownValues.stateDropdown?.label && + !dropdownValues.districtDropdown?.label && + !dropdownValues.blockDropdown?.label && + !dropdownValues.schoolNameDropdown?.label && + !dropdownValues.classNameDropdown?.label; const handleChange = (event, value, name) => { const dropdownOrder = [ diff --git a/packages/admin/src/components/FilterTableData.jsx b/packages/admin/src/components/FilterTableData.jsx index deac4832..d4cf65fb 100644 --- a/packages/admin/src/components/FilterTableData.jsx +++ b/packages/admin/src/components/FilterTableData.jsx @@ -75,7 +75,7 @@ const FilterTableData = ({ open, handleClose, rowData, onApplyFilter }) => { option.label} + getOptionLabel={(option) => option.label || ""} value={filterOption} onChange={(event, value) => setFilterOption(value)} sx={{ width: "100%", marginBottom: 2 }} @@ -88,6 +88,7 @@ const FilterTableData = ({ open, handleClose, rowData, onApplyFilter }) => { option.label || ""} value={selectedFilterValue} onChange={(event, value) => setSelectedFilterValue(value)} disabled={!filterOption} // Disable until a filter option is selected diff --git a/packages/admin/src/components/StudentFilters.jsx b/packages/admin/src/components/StudentFilters.jsx index eb77b7a4..e4924a2d 100644 --- a/packages/admin/src/components/StudentFilters.jsx +++ b/packages/admin/src/components/StudentFilters.jsx @@ -74,19 +74,19 @@ const StudentFilters = ({ handleFiltersChange }) => { useEffect(() => { const loadDistricts = async () => { - if (!dropdownValues.stateDropdown) return; + if (!dropdownValues.stateDropdown.label) return; try { const token = sessionStorage.getItem("token"); const districts = await fetchDistricts( token, - dropdownValues.stateDropdown + dropdownValues.stateDropdown.label ); setDistrictOptions(districts); - const blocks = await fetchBlocks(token, dropdownValues.stateDropdown); + const blocks = await fetchBlocks(token, dropdownValues.stateDropdown.label); setBlockOptions(blocks); - const schools = await fetchSchools(token, dropdownValues.stateDropdown); + const schools = await fetchSchools(token, dropdownValues.stateDropdown.label); setSchoolOptions(schools); } catch (error) { console.error("Error loading districts:", error); @@ -98,14 +98,14 @@ const StudentFilters = ({ handleFiltersChange }) => { // Update blocks based on selected district useEffect(() => { const loadBlocks = async () => { - if (!dropdownValues.districtDropdown) return; + if (!dropdownValues.districtDropdown.label) return; try { const token = sessionStorage.getItem("token"); const blocks = await fetchBlocks( token, - dropdownValues.stateDropdown, - dropdownValues.districtDropdown + dropdownValues.stateDropdown.label, + dropdownValues.districtDropdown.label ); setBlockOptions(blocks); } catch (error) { @@ -122,9 +122,9 @@ const StudentFilters = ({ handleFiltersChange }) => { const token = sessionStorage.getItem("token"); const schools = await fetchSchools( token, - dropdownValues.stateDropdown, - dropdownValues.districtDropdown, - dropdownValues.blockDropdown + dropdownValues.stateDropdown.label, + dropdownValues.districtDropdown.label, + dropdownValues.blockDropdown.label ); setSchoolOptions(schools); } catch (error) { @@ -137,12 +137,12 @@ const StudentFilters = ({ handleFiltersChange }) => { // Fetch classes based on selected school useEffect(() => { const loadClasses = async () => { - if (!dropdownValues.schoolNameDropdown) return; + if (!dropdownValues.schoolNameDropdown.label) return; try { const token = sessionStorage.getItem("token"); const classes = await fetchClasses( token, - dropdownValues.schoolNameDropdown + dropdownValues.schoolNameDropdown.label ); setClassOptions(classes); } catch (error) { @@ -186,6 +186,7 @@ const StudentFilters = ({ handleFiltersChange }) => { option.label || ""} value={dropdownValues.stateDropdown} onChange={(event, value) => handleChange(event, value, "stateDropdown") @@ -207,6 +208,7 @@ const StudentFilters = ({ handleFiltersChange }) => { option.label || ""} value={dropdownValues.districtDropdown} onChange={(event, value) => handleChange(event, value, "districtDropdown") @@ -228,6 +230,7 @@ const StudentFilters = ({ handleFiltersChange }) => { option.label || ""} value={dropdownValues.blockDropdown} onChange={(event, value) => handleChange(event, value, "blockDropdown") @@ -249,6 +252,7 @@ const StudentFilters = ({ handleFiltersChange }) => { `${option.label} (${option.udiseCode})`} value={dropdownValues.schoolNameDropdown} onChange={(event, value) => handleChange(event, value, "schoolNameDropdown") @@ -270,6 +274,7 @@ const StudentFilters = ({ handleFiltersChange }) => { option.label || ""} value={dropdownValues.classNameDropdown} onChange={(event, value) => handleChange(event, value, "classNameDropdown") diff --git a/packages/admin/src/components/StudentListView.jsx b/packages/admin/src/components/StudentListView.jsx index cedfcbfa..36eaa70a 100644 --- a/packages/admin/src/components/StudentListView.jsx +++ b/packages/admin/src/components/StudentListView.jsx @@ -117,7 +117,6 @@ function StudentListView() { // /> // ); // Replace with your desired label // const handleClick = async () => { - // console.log("Record has been removed"); // }; // return
{label}
; @@ -142,10 +141,13 @@ function StudentListView() { ); }, }, - { field: "name" }, + { field: "name" , editable: true, }, { field: "dateOfBirth", width: 150 }, { field: "board", width: 150 }, - { field: "schoolName", width: 250 }, + { field: "schoolName", + width: 250 , + editable: true + }, { field: "schoolUdise", filter: true, @@ -155,7 +157,7 @@ function StudentListView() { }, }, { field: "email" }, - { field: "username" }, + { field: "username", editable: true, }, { field: "mobile" }, { field: "gender" }, @@ -181,7 +183,6 @@ function StudentListView() { if (person == null || person == "") { alert("Please enter a valid Udise"); } else { - console.log(person); const result = await studentUdiseAPI(person); if (result) { @@ -190,7 +191,6 @@ function StudentListView() { const { password, ...rest } = item; return rest; }); - console.log(filteredData); // Convert the data to CSV format using PapaParse const csvData = Papa.unparse(filteredData); @@ -212,7 +212,6 @@ function StudentListView() { }; const cellClickedListener = useCallback((event) => { - console.log("cellClicked", event); }, []); const onBtnExportFields = async () => { @@ -221,13 +220,10 @@ function StudentListView() { if (person == null || person == "") { alert("Please enter a valid Udise"); } else { - console.log(person); const result = await studentUsernamePasswordAPI(person); if (result) { const filteredData = result.data.data; - console.log(filteredData); - const selectedFieldsData = filteredData.map((row) => ({ Name: row.name, UserName: row.username, @@ -259,8 +255,6 @@ function StudentListView() { if (username == null || username == "") { alert("Please enter a valid username"); } else { - console.log(username); - // Find the row corresponding to the entered username in the rowData array const student = rowData.find((student) => student.username === username); @@ -300,11 +294,11 @@ function StudentListView() { } = dropdownValues; const newFilters = {}; - if (state) newFilters.state = { eq: state }; - if (district) newFilters.district = { eq: district }; - if (block) newFilters.block = { eq: block }; - if (schoolName) newFilters.schoolName = { eq: schoolName }; - if (className) newFilters.class = { eq: className }; + if (state) newFilters.state = { eq: state.label }; + if (district) newFilters.district = { eq: district.label }; + if (block) newFilters.block = { eq: block.label }; + if (schoolName) newFilters.schoolName = { eq: schoolName.udiseCode }; + if (className) newFilters.class = { eq: className.label }; setFilters(newFilters); }; @@ -326,8 +320,6 @@ function StudentListView() { filters: filters || {}, // Pass filters object, empty if no filters selected }; - console.log("API Request Data:", requestData); // For debugging - const response = await axios.post(studentSearch, requestData, { headers, }); @@ -354,7 +346,6 @@ function StudentListView() { const closeDownloadStudentDetailsModal = () => { setisDownloadStudentDetails(false); }; - console.log("row data", rowData); return (
Date: Sat, 23 Nov 2024 17:12:11 +0530 Subject: [PATCH 3/4] fix: issues fixes in student and teacher component --- packages/admin/src/api/studentBulkAPI.jsx | 18 +++++++++--------- .../admin/src/assets/images/FinalSchool.csv | 2 +- .../admin/src/assets/images/FinalStudent.csv | 4 ++-- .../admin/src/assets/images/FinalTeacher.csv | 2 +- packages/admin/src/components/DownloadCsv.jsx | 5 +++-- .../admin/src/components/StudentListView.jsx | 2 +- 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/packages/admin/src/api/studentBulkAPI.jsx b/packages/admin/src/api/studentBulkAPI.jsx index d6075351..77f343bc 100644 --- a/packages/admin/src/api/studentBulkAPI.jsx +++ b/packages/admin/src/api/studentBulkAPI.jsx @@ -21,13 +21,13 @@ const studentBulkAPI = async (student) => { .then((res) => { // Extract student information and store it in localStorage - const responses = res.data.responses; + const responses = res?.data?.data?.responses; responses.forEach(response => { - const studentId = response.studentId; - const message = response.message; - const username = response.username; - const schoolUdise = response.schoolUdise; + const studentId = response?.studentId; + const message = response?.message; + const username = response?.username; + const schoolUdise = response?.schoolUdise; const studentData = { studentId, @@ -41,17 +41,17 @@ const studentBulkAPI = async (student) => { }); - localStorage.setItem("successCount", res.data.successCount); - localStorage.setItem("errorCount", res.data.errors.length); + localStorage.setItem("successCount", res?.data?.data?.successCount); + localStorage.setItem("errorCount", res?.data?.data?.errors?.length); - if (res.status === 201) { + if (res?.status === 201) { result = true; } else { result = false; } }) .catch(function (error) { - console.log(error.response.data.error); + console.log(error?.response?.data?.error); let err = 0; return err; }); diff --git a/packages/admin/src/assets/images/FinalSchool.csv b/packages/admin/src/assets/images/FinalSchool.csv index a30be4a3..4d3b2869 100644 --- a/packages/admin/src/assets/images/FinalSchool.csv +++ b/packages/admin/src/assets/images/FinalSchool.csv @@ -1,2 +1,2 @@ School UDISE code,School Name,Location,School Management,School Composition,Board,Medium of Instruction,Head Master,Headmaster Type,Headmaster Mobile,Number of teachers sanctioned -Upper Primary,Number of teachers sanctioned -Secondary,Library Functional,Computer Lab functional,Number of functional computers,Number of Boys toilet,Number of Girls toilet,Smart Board functional in Class 6,Smart Board functional in Class 7,Smart Board functional in Class 8,Smart Board functional in Class 9,Smart Board functional in Class 10,State,District,Block,Adequate Rooms For EveryClass,Drinking Water Supply,Separate Toilet For Girls And Boys,Whether Toilet Being Used,Playground Available,Boundary Wall Fence,Electric Fittings Are Insulated,Building Is Resistant To Earthquake Fire Flood Other Calamity,Building Is Free From Inflammable And Toxic Materials,Roof And Walls Are In Good Condition -234234234,New Park School,Urban,Others,Boys,Odisha,English,dummy,FullTime,8805852647,1,5,Yes,Yes,1,1,1,Yes,Yes,Yes,Yes,Yes,Maharashtra,Pune,Pune,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE +6969696969,New Park School,Urban,Others,Boys,Odisha,English,dummy,FullTime,8805852647,1,5,Yes,Yes,1,1,1,Yes,Yes,Yes,Yes,Yes,Maharashtra,Pune,Pune,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE diff --git a/packages/admin/src/assets/images/FinalStudent.csv b/packages/admin/src/assets/images/FinalStudent.csv index 2a67bcdc..21f605fa 100644 --- a/packages/admin/src/assets/images/FinalStudent.csv +++ b/packages/admin/src/assets/images/FinalStudent.csv @@ -1,2 +1,2 @@ -name,username,email,mobile,gender,dateOfBirth,board,password,status,className,religion,school_udise,caste,annual_income,mother_education,father_education,mother_occupation,father_occupation,No_of_siblings,promotion,state,district,block -Test,retesttekdiwb600112121884,,9999999999,Female ,1990-01-03,West Bengal,NA ,TRUE,Class 7,Hindu,12345678,General,668,,,,,,,maharastra,pune,kothrud +name,username,email,mobile,gender,dateOfBirth,board,password,status,className,religion,school_udise,caste,annual_income,mother_education,father_education,mother_occupation,father_occupation,No_of_siblings,promotion,state,district,block,promotion +Ankushkumar Maherwal,696969696969,,9999999999,Male,1991-11-02,West Bengal,696969696969 ,True,Class 7,Hindu,12345678,General,668,,,,,,,Maharashtra,Pune,Pune,, diff --git a/packages/admin/src/assets/images/FinalTeacher.csv b/packages/admin/src/assets/images/FinalTeacher.csv index 34aa5ac8..4635f745 100644 --- a/packages/admin/src/assets/images/FinalTeacher.csv +++ b/packages/admin/src/assets/images/FinalTeacher.csv @@ -1,2 +1,2 @@ Name,Email Id,Mobile,Gender,DoB,board,Status,Classes taught,School Udise,Educational Qualification,Current role,Nature of appointment,Appointed Postname,Total Experience in teaching,Total experience as Head Teacher,Core subject taught,Attended In service teacher training,Last training attended (Topic),Last training attended (Year),Trained in use of computer & digital teaching -xyzabcd teacher xyz,,1234567890,female,1992-05-12,Maharashtra,true,Secondary,123456789,BA,teacher,NA,teacher,5,5,Science,no,,,yes +Ankushkumar Maherwal,,9878767678,Male,1992-05-12,Maharashtra,True,Secondary,123456789,Graduation,Teacher,Regular,TGTCBZ,2_5yrs,2_5yrs,Science,,,, diff --git a/packages/admin/src/components/DownloadCsv.jsx b/packages/admin/src/components/DownloadCsv.jsx index 283abd16..7fe83b65 100644 --- a/packages/admin/src/components/DownloadCsv.jsx +++ b/packages/admin/src/components/DownloadCsv.jsx @@ -164,7 +164,7 @@ const DownloadCsv = ({ open, handleClose }) => { const token = sessionStorage.getItem("token"); const classes = await fetchClasses( token, - dropdownValues.schoolNameDropdown + dropdownValues?.schoolNameDropdown?.label ); console.log("classes", classes); setClassOptions(classes); @@ -209,7 +209,7 @@ const DownloadCsv = ({ open, handleClose }) => { payload.filters.block = { eq: dropdownValues.blockDropdown?.label }; } if (dropdownValues.schoolNameDropdown?.label) { - payload.filters.schoolName = { eq: dropdownValues.schoolNameDropdown?.label }; + payload.filters.udiseCode = { eq: dropdownValues?.schoolNameDropdown?.udiseCode }; } if (dropdownValues.classNameDropdown?.label) { payload.filters.class = { eq: dropdownValues.classNameDropdown?.label }; @@ -452,6 +452,7 @@ const DownloadCsv = ({ open, handleClose }) => { `${option?.label} (${option?.udiseCode})`} value={dropdownValues.schoolNameDropdown} // Manage this state accordingly onChange={(event, value) => handleChange(event, value, "schoolNameDropdown") diff --git a/packages/admin/src/components/StudentListView.jsx b/packages/admin/src/components/StudentListView.jsx index 36eaa70a..ff6fee82 100644 --- a/packages/admin/src/components/StudentListView.jsx +++ b/packages/admin/src/components/StudentListView.jsx @@ -297,7 +297,7 @@ function StudentListView() { if (state) newFilters.state = { eq: state.label }; if (district) newFilters.district = { eq: district.label }; if (block) newFilters.block = { eq: block.label }; - if (schoolName) newFilters.schoolName = { eq: schoolName.udiseCode }; + if (schoolName) newFilters.udiseCode = { eq: schoolName?.udiseCode }; if (className) newFilters.class = { eq: className.label }; setFilters(newFilters); From fd16065b7b4e7779b7e45d8b82f3a3cff932b317 Mon Sep 17 00:00:00 2001 From: deepali chavhan Date: Sat, 23 Nov 2024 17:28:28 +0530 Subject: [PATCH 4/4] fix: data updated for csv --- packages/admin/src/assets/images/FinalSchool.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/admin/src/assets/images/FinalSchool.csv b/packages/admin/src/assets/images/FinalSchool.csv index 4d3b2869..255904d2 100644 --- a/packages/admin/src/assets/images/FinalSchool.csv +++ b/packages/admin/src/assets/images/FinalSchool.csv @@ -1,2 +1,2 @@ School UDISE code,School Name,Location,School Management,School Composition,Board,Medium of Instruction,Head Master,Headmaster Type,Headmaster Mobile,Number of teachers sanctioned -Upper Primary,Number of teachers sanctioned -Secondary,Library Functional,Computer Lab functional,Number of functional computers,Number of Boys toilet,Number of Girls toilet,Smart Board functional in Class 6,Smart Board functional in Class 7,Smart Board functional in Class 8,Smart Board functional in Class 9,Smart Board functional in Class 10,State,District,Block,Adequate Rooms For EveryClass,Drinking Water Supply,Separate Toilet For Girls And Boys,Whether Toilet Being Used,Playground Available,Boundary Wall Fence,Electric Fittings Are Insulated,Building Is Resistant To Earthquake Fire Flood Other Calamity,Building Is Free From Inflammable And Toxic Materials,Roof And Walls Are In Good Condition -6969696969,New Park School,Urban,Others,Boys,Odisha,English,dummy,FullTime,8805852647,1,5,Yes,Yes,1,1,1,Yes,Yes,Yes,Yes,Yes,Maharashtra,Pune,Pune,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE,TRUE +6969696969,New Park School,Urban,Others,Boys,Odisha,English,dummy,FullTime,8805852647,1,5,Yes,Yes,1,1,1,Yes,Yes,Yes,Yes,Yes,Maharashtra,Pune,Pune,True,True,True,True,True,True,True,True,True,True