{timelineBlocks}
{plannedEvents.map(plannedEvent => {
diff --git a/src/components/SearchAndFilter/SearchAndFilter.jsx b/src/components/SearchAndFilter/SearchAndFilter.jsx
deleted file mode 100644
index 040aaca..0000000
--- a/src/components/SearchAndFilter/SearchAndFilter.jsx
+++ /dev/null
@@ -1,51 +0,0 @@
-import { Input, Select, Flex } from '@chakra-ui/react';
-import PropTypes from 'prop-types';
-const subjectsOptions = ['life skills', 'science', 'technology', 'engineering', 'math', 'college readiness'];
-const eventOptions = ['guest speaker', 'study-trip', 'workshop', 'other'];
-const yearOptions = ['junior', 'senior', 'both'];
-const seasonOptions = ['fall', 'spring', 'summer'];
-
-const SearchAndFilter = ({ onSearch, onChange }) => {
- return (
-
-
-
-
-
-
-
-
-
- );
-};
-
-SearchAndFilter.propTypes = {
- onSearch: PropTypes.func.isRequired,
- onChange: PropTypes.func.isRequired,
- };
-
- export default SearchAndFilter;
diff --git a/src/components/StatTable/MoreInfoModal.jsx b/src/components/StatTable/MoreInfoModal.jsx
new file mode 100644
index 0000000..fd02f4f
--- /dev/null
+++ b/src/components/StatTable/MoreInfoModal.jsx
@@ -0,0 +1,43 @@
+import PropTypes from 'prop-types';
+import {
+ Text,
+ Image,
+ Modal,
+ ModalOverlay,
+ ModalContent,
+ ModalBody,
+ ModalCloseButton,
+ Heading,
+} from '@chakra-ui/react';
+import { InfoOutlineIcon } from '@chakra-ui/icons';
+
+const MoreInfoModal = ({ isOpen, onClose }) => {
+ return (
+ <>
+
+
+
+
+
+
+
+ More Info
+
+ The event Dr. Jong-Levinger is tagged as Science and Engineering.
+
+ So it will appear once under Science, and once under Engineering.
+
+ But the final Total is still 1.
+
+
+
+ >
+ );
+};
+
+MoreInfoModal.propTypes = {
+ isOpen: PropTypes.bool.isRequired,
+ onClose: PropTypes.func.isRequired,
+};
+
+export default MoreInfoModal;
diff --git a/src/components/StatTable/StatTable.css b/src/components/StatTable/StatTable.css
index a3f220d..667a8e5 100644
--- a/src/components/StatTable/StatTable.css
+++ b/src/components/StatTable/StatTable.css
@@ -21,7 +21,7 @@
}
.table-container th {
- background-color: #0e509c;
+ background-color: #243268;
color: white;
padding: 15px;
text-align: center;
@@ -34,12 +34,12 @@
}
.table-container tbody tr:last-child td:not(:first-child) {
- background-color: #f0f8ff;
+ font-weight: 700;
color: blue;
}
.table-container tbody tr:not(:last-child) td:last-child {
- background-color: #f0f8ff;
+ font-weight: 700;
color: blue;
}
diff --git a/src/components/StatTable/StatTable.jsx b/src/components/StatTable/StatTable.jsx
index 12d4837..35f7878 100644
--- a/src/components/StatTable/StatTable.jsx
+++ b/src/components/StatTable/StatTable.jsx
@@ -1,13 +1,18 @@
-import { useState, useEffect } from 'react';
+import { useState, useEffect, useRef } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { NPOBackend } from '../../utils/auth_utils';
-import { Box, Select } from '@chakra-ui/react';
+import { Box, Select, Text, IconButton, useDisclosure, Heading, Flex } from '@chakra-ui/react';
+import { InfoOutlineIcon } from '@chakra-ui/icons';
import './StatTable.css';
+import MoreInfoModal from './MoreInfoModal';
const StatTable = ({ season, allSeasons }) => {
const [stats, setStats] = useState([]);
const [selectedSeason, setSelectedSeason] = useState(season);
+ const [tableWidth, setTableWidth] = useState(0);
+ const tableRef = useRef(null);
+ const { isOpen: isOpenMoreInfo, onOpen: onOpenMoreInfio, onClose: onCloseMoreInfo } = useDisclosure();
useEffect(() => {
const fetchStats = async () => {
@@ -17,6 +22,9 @@ const StatTable = ({ season, allSeasons }) => {
const response = await NPOBackend.get(`/published-schedule/stats?season=${curSeason.toLowerCase()}&year=${curYear}`);
const data = response.data;
setStats(data);
+ if (tableRef.current) {
+ setTableWidth(tableRef.current.offsetWidth);
+ }
} catch (error) {
console.error('Error fetching statistics:', error);
}
@@ -46,21 +54,26 @@ const StatTable = ({ season, allSeasons }) => {
const transformedStats = transformData();
return (
-
+
-
+
+
+ Event Breakdown
+
+
+
@@ -87,6 +100,14 @@ const StatTable = ({ season, allSeasons }) => {
+
+
+ * Totals reflect the actual number of events. However, individual events
+ may appear within the table more than once if it is tagged with more than one subject
+ } onClick={onOpenMoreInfio}/>
+
+
+
);
};
diff --git a/src/pages/Accounts/Accounts.jsx b/src/pages/Accounts/Accounts.jsx
index 4b0cdbd..4d7ddc3 100644
--- a/src/pages/Accounts/Accounts.jsx
+++ b/src/pages/Accounts/Accounts.jsx
@@ -27,26 +27,23 @@ const Accounts = () => {
- Admins
Students
+ Admins
-
- {hasAdminPendingAccounts ? (
- <>
-
-
- Pending
-
-
-
- >
- ) : (
- <>>
+
+ {hasStudentPendingAccounts && (
+
+
+ Pending
+
+
+
)}
@@ -66,27 +63,24 @@ const Accounts = () => {
variant="filled"
bgColor="blackAlpha.200"
h="30px"
- onChange={e => setApprovedAdminKeyword(e.target.value)}
+ onChange={e => setApprovedStudentKeyword(e.target.value)}
/>
-
+
- {hasStudentPendingAccounts ? (
+ {hasAdminPendingAccounts && (
Pending
- ) : (
- <>>
)}
@@ -106,12 +100,12 @@ const Accounts = () => {
variant="filled"
bgColor="blackAlpha.200"
h="30px"
- onChange={e => setApprovedStudentKeyword(e.target.value)}
+ onChange={e => setApprovedAdminKeyword(e.target.value)}
/>
-
+
diff --git a/src/pages/PublishedSchedule/PublishedSchedule.jsx b/src/pages/PublishedSchedule/PublishedSchedule.jsx
index 41b5155..6027091 100644
--- a/src/pages/PublishedSchedule/PublishedSchedule.jsx
+++ b/src/pages/PublishedSchedule/PublishedSchedule.jsx
@@ -3,7 +3,11 @@ import PublishedScheduleTable from '../../components/Events/PublishedScheduleTab
import AUTH_ROLES from '../../utils/auth_config.js';
import { useAuthContext } from '../../common/AuthContext.jsx';
import { useEffect, useState } from 'react';
-import { Box, Select, Text } from '@chakra-ui/react';
+import { Box, HStack, IconButton, Input, InputGroup, InputLeftElement, Select, Spacer, Text, useDisclosure } from '@chakra-ui/react';
+import { AddIcon, CloseIcon, SearchIcon } from '@chakra-ui/icons';
+import AddDayModal from './AddDayModal.jsx';
+import StatModal from './StatisticsModal.jsx';
+import { IoStatsChart } from 'react-icons/io5';
const { ADMIN_ROLE, USER_ROLE } = AUTH_ROLES.AUTH_ROLES;
const PublishedSchedule = () => {
@@ -14,6 +18,12 @@ const PublishedSchedule = () => {
const [seasonHover, setSeasonHover] = useState(false);
const [dataShouldRevalidate, setShouldDataRevalidate] = useState(false);
+ const [allEvents, setAllEvents] = useState([]);
+ const [eventData, setEventData] = useState([]);
+ const [searchedDate, setSearchedDate] = useState('');
+
+ const { isOpen: isOpenDay, onOpen: onOpenDay, onClose: onCloseDay } = useDisclosure();
+ const { isOpen: isOpenStats, onOpen: onOpenStats, onClose: onCloseStats } = useDisclosure();
const getTodaySeason = () => {
let today = new Date();
@@ -52,60 +62,157 @@ const PublishedSchedule = () => {
setAllSeasons(data);
};
+ const renderTable = async () => {
+ if (selectedSeason.length) {
+ const [seasonType, seasonYear] = selectedSeason.split(' ');
+ const { data } = await NPOBackend.get(
+ `/published-schedule/season?season=${seasonType}&year=${seasonYear}`,
+ );
+ setAllEvents(data);
+ if (!searchedDate.length) {
+ setEventData(data);
+ }
+ }
+ };
+
+ useEffect(() => {
+ renderTable();
+ }, [selectedSeason]);
+
useEffect(() => {
if (selectedSeason === '') {
setSelectedSeason(curSeason);
}
renderSeasons();
+ renderTable();
}, []);
useEffect(() => {
if (dataShouldRevalidate) {
renderSeasons();
+ renderTable();
setShouldDataRevalidate(false);
}
- }, [dataShouldRevalidate, renderSeasons])
+ }, [dataShouldRevalidate, renderSeasons, renderTable]);
+
+ useEffect(() => {
+ if (searchedDate) {
+ const searchedData = allEvents.filter(item => item.day.eventDate === searchedDate);
+ setEventData(searchedData);
+ } else {
+ setEventData(allEvents);
+ }
+ }, [searchedDate])
//update chakra table container accordingly
return (
- {selectedSeason != '' ? (
-
- {selectedSeason}
-
- ) : (
-
- {curSeason}
-
- )}
-
-
- {/* tables for each season */}
- {selectedSeason != '' ? (
-
- ) : (
-
- )}
+ {currentUser.type === ADMIN_ROLE &&
+ <>
+ }
+ >
+ Stats
+
+
+ }
+ >
+ Create
+
+ >
+ }
+
+
+
+ { selectedSeason && allSeasons &&
+
+ }
+
+
+
+
+ {selectedSeason}
+
+
+
+
+
+
+
+
+ {searchedDate.length ?
+ }
+ onClick={() => setSearchedDate('')}
+ color="gray.600"
+ ml="0.5rem"
+ /> :
+
+ }
+
+ setSearchedDate(e.target.value)}
+ />
+
+
+
+
);
};