Skip to content

Commit 1874c0d

Browse files
committed
Merge branch 'origin/maintenance'
2 parents ee5f70b + 223c7ea commit 1874c0d

File tree

2 files changed

+23
-323
lines changed

2 files changed

+23
-323
lines changed

pages/index.tsx

Lines changed: 15 additions & 322 deletions
Original file line numberDiff line numberDiff line change
@@ -1,326 +1,19 @@
1-
import Options from "../components/Options";
2-
import Display from "../components/Display";
3-
import Overlay from "../components/Overlay";
4-
import ReactDOM from 'react-dom/client';
5-
import React, {useState, useEffect, useRef} from "react";
6-
import {ThemeProvider,createTheme} from "@mui/material/styles";
7-
import TextField from '@mui/material/TextField';
8-
import Fab from "@mui/material/Fab";
9-
import Card from "@mui/material/Card";
10-
import Button from "@mui/material/Button";
11-
import {DarkModeSharp, LightModeRounded, HelpOutlineRounded, MailOutlineRounded} from "@mui/icons-material";
12-
// import {students as STUDENTS, rollToYear} from "../components/student_data_getter.tsx";
13-
import TreeCard from "../components/treeSCard";
14-
import SCard from "../components/SCard";
15-
import {Student as StudentType, Query as QueryType, Options as OptType} from "../components/commontypes";
16-
import GuestFooter from "../components/Treefooter";
17-
18-
//start shared search worker
19-
if (!(typeof window === "undefined") && window.Worker) {//only on the client, TODO: find better method - do when dealing w/ SSG
20-
var searcher = new Worker(new URL("../components/data_worker", import.meta.url));
21-
}
22-
23-
const isIFrame = (typeof window !== "undefined") && (window.top === window.self);
1+
import { Card } from "@mui/material";
242

253
export default function Home(props: Object) {
26-
27-
const [students, setStudents]:[Array<StudentType>, Function] = useState([]);
28-
const [darkMode, setDarkMode]=useState(true);
29-
//initial render doesn't have access to localStorage so start off with true
30-
const [currDisp, setCurr]:[any, Function] = useState();
31-
const [loading, setLoading] = useState(true); //loading at the start
32-
const [listOpts, setOpts]:[OptType, Function] = useState({
33-
batch:["Loading..."],
34-
hall:["Loading..."],
35-
prog:["Loading..."],
36-
dept:["Loading..."],
37-
bloodgrp:["Loading..."]
38-
});
39-
const [iFrame, setIFrame] = useState(false);
40-
const searchBar = useRef<HTMLInputElement>(null);
41-
42-
function queryHandler(event: any) {
43-
// console.log("Query result received");
44-
if (event.data[0] == "query") {
45-
setStudents(event.data[1].toSorted((a:StudentType, b:StudentType) => {
46-
try {
47-
return (Number(a.i) > Number(b.i));
48-
} catch (err) {
49-
return (a.i > b.i);
50-
}
51-
}));
52-
// setLoading(false);
53-
}
54-
}
55-
56-
function treeHandler(event: any) {
57-
// console.log("Tree result received");
58-
if (event.data[0] == "ft") {
59-
// document.body.style.overflow = "hidden"; //hotfix
60-
let [baapu, student, bacchas] = event.data[1];
61-
setCurr([
62-
<TreeCard
63-
key="open"
64-
data={student}
65-
baapu={baapu /*TreeCard'll handle undefined*/}
66-
bacchas={bacchas}
67-
displayCard={displayCard}
68-
clearOverlay={clearOverlay}
69-
/>,
70-
<div className="footer-absolute" key="footer">
71-
<GuestFooter />
72-
</div>
73-
]);
74-
}
75-
76-
}
77-
78-
function optsHandler(event: any) {
79-
if (event.data[0] == "Options") {
80-
setOpts(event.data[1]);
81-
}
82-
}
83-
84-
function errorHandler(event: any) {
85-
if (event.data === "Error") {
86-
displayElement(
87-
<Card><h1>Data could not be retrieved locally nor fetched.</h1>
88-
<h2 >Please access the website from campus or via VPN once so that student data can be downloaded and stored.</h2>
89-
<p>Check the console for more details.</p></Card>
90-
);
91-
}
92-
}
93-
94-
useEffect(() => {
95-
//on mount: set up worker handler, wait for it to initialise, and then:
96-
//1. get list options from it
97-
//2. set up the handlers for query and treecard
98-
// console.log("waiting for worker");
99-
searcher.postMessage("ready?");
100-
searcher.onmessage = null;
101-
searcher.onmessage = (event) => {
102-
if (event.data !== "Worker ready") {
103-
//error condition
104-
errorHandler({data: "Error"});
105-
} else {
106-
searcher.onmessage = (event) => {
107-
if (event.data[0] != "Options") return;
108-
setLoading(false);
109-
setTimeout(() => {
110-
if (searchBar.current) {
111-
// console.log("focusing search bar");
112-
searchBar.current.focus();
113-
}
114-
}, 0); //I don't know why but it just won't focus without a timeout
115-
setOpts(event.data[1]);
116-
searcher.onmessage = null; //remove this event handler
117-
searcher.addEventListener("message", queryHandler);
118-
searcher.addEventListener("message",treeHandler);
119-
searcher.addEventListener("message", optsHandler); //when web worker updates, it will send out options again
120-
searcher.addEventListener("message", errorHandler);
121-
122-
};
123-
searcher.postMessage("Options");
124-
}
125-
};
126-
return (() => {searcher.onmessage = null;}); //on unmount: remove all handlers
127-
},[])
128-
129-
useEffect(() => {
130-
setDarkMode(localStorage.getItem("darkmode") !== "false")
131-
},[]);
132-
//on mount: load darkmode setting
133-
134-
useEffect(() => {
135-
setIFrame(!isIFrame);
136-
}, []);
137-
//on mount: load the iframe stopper, need to do it this way so that static generation generates the page normally (isIFrame is false when building because typeof window is "undefined" then) but if the page is indeed an iframe, the app stops working
138-
//can't stop iframes the normal way (setting HTTP header to disallow them) because github pages doesn't allow you to set HTTP headers :(
139-
140-
const keydownfxn = (e: any) => {
141-
if (e.key === "/" && searchBar.current && document.activeElement != searchBar.current) {
142-
e.preventDefault();
143-
searchBar.current.focus();
144-
} else if (e.key === "Escape" && document.activeElement && document.activeElement instanceof HTMLElement) {
145-
document.activeElement.blur();
146-
}
147-
};
148-
149-
useEffect(() => {
150-
document.addEventListener("keydown", keydownfxn);
151-
return () => {document.removeEventListener("keydown", keydownfxn)}
152-
}, [])
153-
//on mount: add / button detection to move focus to search bar
154-
155-
useEffect(() => {
156-
if (darkMode) {
157-
document.body.style.backgroundColor = "#000";
158-
} else {
159-
document.body.style.backgroundColor = "#efefef";
160-
}
161-
},[darkMode]);
162-
163-
164-
const sendQuery = (query: QueryType)=> {
165-
searcher.postMessage(query);
166-
// console.log(query);
167-
// setLoading(true);
168-
// if (!workerReady) return [];
169-
170-
}
171-
172-
const clearOverlay = ()=> {
173-
setCurr(undefined);
174-
// document.body.style.overflow = "auto"; //hotfix
175-
}
176-
177-
const displayElement = (element: any) => {
178-
clearOverlay();
179-
setCurr([element]);
180-
// document.body.style.overflow = "hidden"; //hotfix
181-
}
182-
183-
const displayCard = (student: StudentType) =>{
184-
clearOverlay();
185-
// document.body.style.overflow = "hidden"; //hotfix
186-
setCurr([<SCard
187-
compact={false}
188-
data={student}
189-
key="closed"
190-
>
191-
<Button
192-
onClick={() => {displayTree(student);}}
193-
>Open Family Tree</Button>
194-
</SCard>]);
195-
}
196-
197-
const displayTree = (student: StudentType) => {
198-
clearOverlay();
199-
// if (!workerReady) return;
200-
searcher.postMessage(["ft", student]);
201-
}
202-
203-
if (!iFrame) return (
204-
<div>
205-
<ThemeProvider theme={darkMode
206-
? createTheme({
207-
palette:{
208-
mode: "dark",
209-
}
210-
})
211-
: createTheme({
212-
213-
})
214-
}>
215-
<div
216-
className="buttons"
217-
style={{
218-
zIndex:"9999"
219-
}}
220-
>
221-
<Fab
222-
onClick={()=>{
223-
setDarkMode(!darkMode);
224-
localStorage.setItem("darkmode", String(!darkMode));}}
225-
>
226-
{darkMode ?
227-
<LightModeRounded />
228-
: <DarkModeSharp />}
229-
</Fab>
230-
<Fab
231-
onClick={() => {
232-
displayElement(
233-
<Card
234-
style={{
235-
padding:"10px"
236-
}}
237-
>
238-
<h1>Setting a custom DP</h1>
239-
<p>You can customise the image shown here by placing a custom image in your iitk webhome folder called dp.jpg/dp.png such that going to http://home.iitk.ac.in/~yourusername/dp opens up that particular picture.</p>
240-
<h1>How do I update the data shown here?</h1>
241-
<p>{`The data here is scraped from the Office Automation Portal. The data there can be updated via the Login Based Services > Student Profile > PI form . If you have had a branch change, please go to the ID Cell and update your ID Card to update your branch.`}</p>
242-
<p>The changes if any will be reflected in about a week. </p>
243-
<h1>{`I can't see students' pictures/I can't access student data.`}</h1>
244-
<p>{`Access to student data is restricted to those currently on campus or connecting via VPN. Please visit the website once via either method so that the data can be stored locally. After this, you will be able to access student data from anywhere (as long as you don't wipe your cache or local files).`}</p>
245-
<h1>Credits</h1>
246-
<p>Student Search has gone through many iterations over the years. The current one was made by Deven Gangwani and Krishnansh Agrawal (both Y21).The one just before this was made by Yash Srivastav (Y15).</p>
247-
<p>Credit for Student Guide data (bacche, ammas and baapus) goes to the Counselling Service, IITK.</p>
248-
</Card>
249-
);
250-
}}
251-
>
252-
<HelpOutlineRounded />
253-
</Fab>
254-
<Fab
255-
style={{
256-
display:(students.length < 3000 && students.length > 0 ? "" : "none")
257-
}}
258-
onClick={() => {
259-
displayElement(
260-
<Card
261-
style={{
262-
padding:"10px",
263-
width:"80vw",
264-
maxWidth:"1200px",
265-
maxHeight:"1000px"
266-
}}
267-
>
268-
<p>{`Press the 'copy' button to copy all email addresses.`}</p>
269-
<div
270-
style={{
271-
height:"60vh",
272-
overflow:"auto"
273-
}}
274-
>
275-
{students.filter((el) => (el.u.length > 0)).map((el) => (el.u + "@iitk.ac.in")).join(", ")}
276-
</div>
277-
<Button
278-
variant="contained"
279-
onClick={() => {
280-
navigator.clipboard.writeText(students.filter((el) => (el.u.length > 0)).map((el) => (el.u + "@iitk.ac.in")).join(", "));
281-
}}
282-
>Copy</Button>
283-
</Card>
284-
);
285-
}}
286-
>
287-
<MailOutlineRounded />
288-
</Fab>
289-
</div>
290-
<Options
291-
sendQuery={sendQuery}
292-
listOpts={listOpts}
293-
loading={loading}
294-
ref={searchBar}
295-
/>
296-
<br/>
297-
<Display
298-
loading={loading}
299-
toShow={students}
300-
displayCard={displayCard}
301-
/>
302-
<Overlay
303-
clearOverlay={clearOverlay}
304-
>
305-
{currDisp !== undefined
306-
? currDisp
307-
: ""}
308-
</Overlay>
309-
</ThemeProvider>
310-
</div>
311-
);
312-
else return (
313-
<div style={{
314-
width: "60%",
315-
margin:"auto",
316-
color:"white"
317-
}}><h1>Please view this page at <a href="https://search.pclub.in" target="_blank">search.pclub.in</a></h1>
318-
<p>Credits:</p>
319-
<p>Deven Gangwani</p>
320-
<p>Krishnansh Agarwal</p>
321-
<p>Programming Club, IITK</p>
322-
</div>
4+
return (
5+
<Card className="options bg-grey ">
6+
<div>
7+
<h2>Temporary Service Unavailable for Maintenance</h2>
8+
<p>
9+
As per the order of DDIA, Student Search portal will be unavailable
10+
until further notice.
11+
<br />
12+
We are working with the administration to resolve the issue and will
13+
be back soon with the necessary updates. Thank you for your
14+
understanding.
15+
</p>
16+
</div>
17+
</Card>
32318
);
32419
}
325-
326-

styles/styles.css

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ a {
4444
display:flex;
4545
flex-direction:column;
4646
align-items: center;
47-
filter: drop-shadow(0px 5px 5px #777);
47+
filter: drop-shadow(1px 1px 10px #777);
4848
}
4949

5050
.row {
@@ -305,4 +305,11 @@ display:flex;
305305
align-items: center;
306306
min-height: 100vh;
307307
width: 100%;
308+
}
309+
310+
.bg-grey{
311+
margin-top: 10%;
312+
padding: 2%;
313+
background-color: #000;
314+
color: white;
308315
}

0 commit comments

Comments
 (0)