Skip to content

Commit b90a1e5

Browse files
committed
Added Intro Evals Slideshow
1 parent c4979aa commit b90a1e5

File tree

10 files changed

+345
-8
lines changed

10 files changed

+345
-8
lines changed

Diff for: package-lock.json

+16
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+5-3
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
"@axa-fr/react-oidc": "^6.14.4",
77
"@emotion/react": "^11.11.1",
88
"@emotion/styled": "^11.11.0",
9+
"@fortawesome/free-solid-svg-icons": "^6.4.2",
10+
"@fortawesome/react-fontawesome": "^0.2.0",
911
"@mui/icons-material": "^5.14.9",
1012
"@mui/joy": "^5.0.0-beta.9",
1113
"@mui/material": "^5.14.12",
12-
"@fortawesome/free-solid-svg-icons": "^6.4.2",
13-
"@fortawesome/react-fontawesome": "^0.2.0",
1414
"@testing-library/jest-dom": "^5.16.5",
1515
"@testing-library/react": "^14.0.0",
1616
"@testing-library/user-event": "^14.4.3",
@@ -26,8 +26,9 @@
2626
"react-router": "^6.8.1",
2727
"react-router-dom": "^6.16.0",
2828
"react-scripts": "^5.0.1",
29-
"reactstrap": "^9.2.0",
3029
"react-toastify": "^9.1.3",
30+
"reactstrap": "^9.2.0",
31+
"reveal.js": "^4.6.1",
3132
"typescript": "^4"
3233
},
3334
"scripts": {
@@ -55,6 +56,7 @@
5556
]
5657
},
5758
"devDependencies": {
59+
"@types/reveal.js": "^4.4.3",
5860
"sass": "^1.58.1",
5961
"typescript-eslint-language-service": "^5.0.5"
6062
},

Diff for: src/API/Types.ts

+32
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,35 @@ export interface UserInfo {
1010
username: string,
1111
fullName: string,
1212
}
13+
14+
export interface DirectorshipAttendanceRecord {
15+
approved: boolean,
16+
committe: DirectorshipType,
17+
frosh: number[],
18+
members: string[],
19+
timestamp: Date
20+
}
21+
22+
export interface SeminarAttendanceRecord {
23+
approved: boolean,
24+
name: string,
25+
frosh: number[],
26+
members: string[],
27+
timestamp: Date,
28+
}
29+
30+
export interface IntroEvalsSummary {
31+
name: string,
32+
uid: string | null,
33+
seminars: number,
34+
directorships: number,
35+
missed_hms: number,
36+
signatures: number,
37+
max_signatures: number,
38+
}
39+
40+
export interface IntroEvalsForm {
41+
uid: string,
42+
social_events: string | null,
43+
comments: string | null,
44+
}

Diff for: src/App.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
import React from 'react'
22
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'
33
import Home from './pages/Home'
4-
import AttendanceHistory from './pages/AttendanceHistory'
4+
import AttendanceHistory from './pages/Attendance/AttendanceHistory'
55
import SubmitDirectorship from './pages/SubmitDirectorship'
66
import PageContainer from './containers/PageContainer'
77
import 'csh-material-bootstrap/dist/csh-material-bootstrap.css'
88
import NotFound from './pages/NotFound'
9-
import { request } from 'http'
109
import SubmitSeminar from './pages/SubmitSeminar'
10+
import IntroEvalsSlideshow from './pages/Slideshow/IntroEvalsSlideshow'
1111

1212
type Props = {
1313
rerouteHomeOn404?: boolean
1414
}
1515

1616
const App: React.FC<Props> = ({ rerouteHomeOn404 = null }) => {
17+
1718
return (
1819
<Router>
1920
<PageContainer>
@@ -23,6 +24,7 @@ const App: React.FC<Props> = ({ rerouteHomeOn404 = null }) => {
2324
<Route path='/attendance/history' element={<AttendanceHistory />} />
2425
<Route path='/directorship/submit' element={<SubmitDirectorship />} />
2526
<Route path='/seminar/submit' element={<SubmitSeminar />} />
27+
<Route path='/slideshow/intro' element={<IntroEvalsSlideshow />} />
2628
<Route path='*' element={rerouteHomeOn404 ?? true ? <Home /> : <NotFound />} />
2729
</Routes>
2830
</PageContainer>

Diff for: src/containers/PageContainer.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ type Props = {
77
}
88

99
export const PageContainer: React.FC<Props> = ({ children }) => {
10+
1011
return (
1112
<div style={{ marginTop: '90px' }}>
12-
<Container className="main" fluid>
13-
<NavBar />
13+
<Container className="main" fluid={!window.location.href.includes("slideshow")}>
14+
{!window.location.href.includes("slideshow") && <NavBar />}
1415
<Container>{children}</Container>
1516
</Container>
1617
</div>
1718
)
1819
}
1920

20-
export default PageContainer
21+
export default PageContainer

Diff for: src/pages/Slideshow/BatchSlide.tsx

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { useState } from "react";
2+
import { Button, Col, Container, Row } from "reactstrap"
3+
4+
const BatchSlide = (props: {
5+
name: string,
6+
names: string[],
7+
onPassFail: (passed: boolean) => void
8+
}) => {
9+
10+
const [passed, setPassed] = useState<string | null>(null);
11+
12+
return (
13+
<section data-transition="slide" className="vw-100">
14+
<Container className="d-flex flex-column vh-100 px-0 w-100">
15+
<Row>
16+
<Col className="text-center">
17+
<h2>{props.name}</h2>
18+
</Col>
19+
</Row>
20+
<Row>
21+
{
22+
props.names.map((f, i) =>
23+
<Col key={i} className="py-0 m-0 col-2">
24+
<p className="batch-name py-1 m-0">{f}</p>
25+
</Col>
26+
)
27+
}
28+
</Row>
29+
{
30+
passed == null ?
31+
<Row className="text-center m-3 py-3 align-self-center">
32+
<Button
33+
className="mr-3 shadow-none border-success border rounded pf-button"
34+
onClick={_ => {
35+
props.onPassFail(true);
36+
setPassed("Passed");
37+
}}
38+
>
39+
<h1 className="text-success px-5">Pass</h1>
40+
</Button>
41+
<Button
42+
className="mr-3 shadow-none disband-gray border rounded pf-button"
43+
onClick={_ => setPassed("Disbanded")}
44+
>
45+
<h1 className="px-5 disband-gray">Disband</h1>
46+
</Button>
47+
<Button
48+
className="mr-3 shadow-none border-danger border rounded pf-button"
49+
onClick={_ => {
50+
props.onPassFail(false);
51+
setPassed("failed");
52+
}}
53+
>
54+
<h1 className="text-danger px-5">Fail</h1>
55+
</Button>
56+
</Row>
57+
:
58+
<h3 className={`py-3 my-3 ${passed === "Success" ? "text-success" : (passed == "Failed" ? "text-danger" : "")}`}>{passed}</h3>
59+
}
60+
</Container>
61+
</section>
62+
)
63+
}
64+
65+
export default BatchSlide

Diff for: src/pages/Slideshow/IntroEvalsSlideshow.tsx

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { useEffect, useReducer, useState } from "react"
2+
import Reveal from "reveal.js";
3+
import Slide from "./Slide"
4+
import 'reveal.js/dist/reset.css'
5+
import 'reveal.js/dist/reveal.css'
6+
import 'reveal.js/dist/theme/white.css'
7+
import './index.css'
8+
import { IntroEvalsSummary } from "../../API/Types";
9+
import { getJSON, toastError } from "../../API/API";
10+
import { Container } from "reactstrap";
11+
import BatchSlide from "./BatchSlide";
12+
13+
const IntroEvalsSlideshow = () => {
14+
15+
const initSlides = () => {
16+
let slides = new Reveal({
17+
backgroundTransition: 'slide',
18+
transition: 'slide'
19+
});
20+
slides.initialize();
21+
}
22+
23+
const [frosh, setFrosh] = useState<IntroEvalsSummary[]>([]);
24+
25+
useEffect(() => {
26+
getJSON<IntroEvalsSummary[]>("/api/evals/intro")
27+
.then(setFrosh).then(initSlides)
28+
.catch(toastError("Unable to fetch Intro Evals data"));
29+
}, [])
30+
31+
interface Batch {
32+
name: string,
33+
names: string[],
34+
}
35+
36+
const batches: Batch[] = [];
37+
38+
return (
39+
<div className="reveal vh-100 vw-100">
40+
<div className="slides w-100" data-transition="slide">
41+
<section data-transition="slide" className="vw-100">
42+
<Container className="d-flex flex-column vh-100 px-0 d-xl-flex w-100">
43+
<h2>Intro Evals Slideshow</h2>
44+
{/* placeholder, because slideshow doesn't work unless at least one slide is present from the beginning*/}
45+
</Container>
46+
</section>
47+
{
48+
batches.map((b, i) =>
49+
<BatchSlide key={i} name={b.name} names={b.names} onPassFail={(pass) => setFrosh(frosh.filter(f => !b.names.includes(f.name)))} />
50+
)
51+
}
52+
53+
{
54+
frosh.sort((a, b) => a.name.localeCompare(b.name)).map((f, i) =>
55+
<Slide
56+
key={i}
57+
uid={f.uid}
58+
name={f.name}
59+
packet={Math.trunc(100 * f.signatures / f.max_signatures)}
60+
hm_absences={f.missed_hms}
61+
directorships={f.directorships}
62+
seminars={f.seminars} />)
63+
}
64+
</div>
65+
</div>
66+
67+
)
68+
}
69+
70+
export default IntroEvalsSlideshow

Diff for: src/pages/Slideshow/NumberBox.tsx

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Card, CardText, Container, Row } from "reactstrap"
2+
3+
const NumberBox = (props: { text: string, subtext: string, success: boolean }) => {
4+
5+
return (
6+
<Card className={`bg-transparent shadow-none ${props.success ? "border-success" : "border-danger"} p-3 rounded number-box h-100`}>
7+
<Container className="h-100 d-flex flex-column">
8+
<Row className="d-block justify-content-center">
9+
<h1 className="number-box-text">{props.text}</h1>
10+
</Row>
11+
<Row className="d-inline number-box-subtext">
12+
<p>{props.subtext}</p>
13+
</Row>
14+
</Container>
15+
</Card>
16+
)
17+
}
18+
19+
export default NumberBox

0 commit comments

Comments
 (0)