Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into phoebe/change-search
Browse files Browse the repository at this point in the history
  • Loading branch information
dpang314 committed Oct 28, 2023
2 parents da6b587 + 8ae71cf commit 44b8f0f
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 133 deletions.
3 changes: 0 additions & 3 deletions src/contexts/DashboardContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ const DashboardContext = React.createContext({
url: "",
isAddUser: false,
setIsAddUser: () => {},
setSemester: () => {},
semesters: new Set(),
setSemesters: () => {},
});

export default DashboardContext;
49 changes: 48 additions & 1 deletion src/pages/api/get_users.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,54 @@ import requestWrapper from "../../server/utils/middleware";

async function handler(req, res) {
const { query } = req.query;
const users = await User.find({$or: [{email: {$regex: new RegExp(query, 'i')}}, {firstName: {$regex: new RegExp(query, 'i')}}, {phoneNumber: {$regex: new RegExp(query, 'i')}}]}).populate("tenures").sort({ firstName: 1, lastName: 1 });
const users = await User.aggregate([
{
$lookup: {
from: "tenures",
as: "tenures",
localField: "tenures",
foreignField: "_id",
},
},
{
$match: {
$and: [
{ "tenures.semester": { $in: [req.query.semester] } },
{ "tenures.year": { $in: [Number(req.query.year)] } },
{
$or: [
{ email: { $regex: new RegExp(query, "i") } },
{ firstName: { $regex: new RegExp(query, "i") } },
{ phoneNumber: { $regex: new RegExp(query, "i") } },
],
},

req.query.role == "All" ? {} : { "tenures.role": { $in: [req.query.role] } },
req.query.department == "All" ? {} : { "tenures.department": { $in: [req.query.department] } },
],
},
},
{
$project: {
id: "$_id",
_id: 0,
firstName: "$firstName",
lastName: "$lastName",
email: "$email",
phoneNumber: "$phoneNumber",
access: "$access",
preference: "$preference",
tenures: {
$arrayToObject: {
$map: {
input: "$tenures",
in: { k: req.query.semester + " " + req.query.year, v: "$$this" },
},
},
},
},
},
]);
res.status(200).json({ users });
}

Expand Down
81 changes: 73 additions & 8 deletions src/screens/AdminDashboard/AdminDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { sortTenures } from "../../server/utils/memberFunctions";
import DashboardContext from "../../contexts/DashboardContext";
import Router from "next/router";
import { signOut } from "next-auth/react";
import fields from "../../server/utils/fields";

const Search = styled("div")(({ theme }) => ({
position: "relative",
Expand Down Expand Up @@ -89,18 +90,32 @@ const StyledSelect = styled(Select)(() => ({
}));

function AdminDashboardPage({ url }) {
const [semesters, setSemesters] = useState([]);
const [semester, setSemester] = useState("");
const [semester, setSemester] = useState("Fall 2023");
const [department, setDepartment] = useState("All");
const [showUploadModal, setShowUploadModal] = useState(false);
const [fileBlob, setFileBlob] = useState(null);
const [filter, setFilter] = useState("");
const [isAddUser, setIsAddUser] = useState(false);
const [newMembers, setNewMembers] = useState(null);
const [role, setRole] = useState("All");

const semesters = fields.semesterOptions;
const roles = fields.roles;

const departments = fields.departments;

const changeSemesterHandler = (event) => {
setSemester(event.target.value);
};

const changeDepartmentHandler = (event) => {
setDepartment(event.target.value);
};

const changeRoleHandler = (event) => {
setRole(event.target.value);
};

const bulkUpload = async () => {
const res = await sendRequest(urls.api.bulkUpload, "POST", fileBlob, { "Content-Type": "text/csv" }, false);
setNewMembers(res.members);
Expand Down Expand Up @@ -196,19 +211,69 @@ function AdminDashboardPage({ url }) {
);
})}
</StyledSelect>
<StyledSelect
value={department}
onChange={changeDepartmentHandler}
MenuProps={{
PaperProps: {
sx: {
"& .MuiMenuItem-root.Mui-selected": {
backgroundColor: "#0069ca1a",
color: "#78adff",
},
"& .MuiMenuItem-root.Mui-selected:hover": {
backgroundColor: "#0069ca23",
},
},
},
}}>
{Array.from(departments)
.sort()
.map((department) => {
return (
<MenuItem key={department} value={department} style={{ justifyContent: "center", fontFamily: "Poppins" }}>
{department.toUpperCase()}
</MenuItem>
);
})}
</StyledSelect>
<StyledSelect
value={role}
onChange={changeRoleHandler}
MenuProps={{
PaperProps: {
sx: {
"& .MuiMenuItem-root.Mui-selected": {
backgroundColor: "#0069ca1a",
color: "#78adff",
},
"& .MuiMenuItem-root.Mui-selected:hover": {
backgroundColor: "#0069ca23",
},
},
},
}}>
{Array.from(roles)
.sort()
.map((role) => {
return (
<MenuItem key={role} value={role} style={{ justifyContent: "center", fontFamily: "Poppins" }}>
{role.toUpperCase()}
</MenuItem>
);
})}
</StyledSelect>
<LogoutIcon style={{ width: "2rem", height: "2rem", cursor: "pointer" }} onClick={() => signOut()} />
</Box>
</Box>
<div style={{ height: "78vh", width: "90vw" }}>
<DashboardContext.Provider value={{ url, isAddUser, setIsAddUser, setSemester, semesters, setSemesters }}>
<DashboardContext.Provider value={{ url, isAddUser, setIsAddUser }}>
<UserTable
filter={filter}
currentSemester={semester}
newMembers={newMembers}
clearNewMembers={() => setNewMembers(null)}
semesters={semesters}
setSemester={setSemester}
setSemesters={setSemesters}
filter={filter}
roleFilter={role}
departmentFilter={department}
/>
</DashboardContext.Provider>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import DashboardContext from "../../../../../contexts/DashboardContext";
import TableContext from "../../../../../contexts/TableContext";
import EditMemberField from "./EditMemberField/EditMemberField";
import { emailTester, phoneTester } from "../../../../../server/utils/regex";
import Image from "next/image";

const Label = ({ label }) => {
return (
Expand All @@ -30,7 +31,7 @@ const Label = ({ label }) => {

export default function EditMemberModal({ row, isVisible, closeModal, currentSemester }: EditMemberModalProps) {
const { userList, setUserList } = useContext(TableContext);
const { isAddUser, semesters, setSemesters } = useContext(DashboardContext);
const { isAddUser } = useContext(DashboardContext);
const scrollRef = useRef(null);
const [confirmModal, setConfirmModal] = useState(0);
const [isNewTenure, setIsNewTenure] = useState(false);
Expand Down Expand Up @@ -196,12 +197,6 @@ export default function EditMemberModal({ row, isVisible, closeModal, currentSem
});
}
setUserList(users);

if (!semesters.has(semesterYear)) {
const newSemesters = new Set(semesters);
newSemesters.add(semesterYear);
setSemesters(newSemesters);
}
}
};

Expand Down Expand Up @@ -387,7 +382,7 @@ export default function EditMemberModal({ row, isVisible, closeModal, currentSem
</Button>
)}
<div className={style.saveButton} onClick={updateHandler}>
<img src="/Save.png" height={20} width={20} alt="Save Icon" />
<Image src="/Save.png" height={20} width={20} alt="Save Icon" />
SAVE
</div>
</div>
Expand Down
107 changes: 49 additions & 58 deletions src/screens/AdminDashboard/UserTable/PaginationTable/Row/Row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,9 @@ import { TableRow, TableCell } from "@mui/material";
import ChatBubbleOutlineRoundedIcon from "@mui/icons-material/ChatBubbleOutlineRounded";
import DashboardContext from "../../../../../contexts/DashboardContext";

const Image = React.memo(({ src }) => (
<img
src={src}
alt="User Picture"
style={{
pointerEvents: "auto",
width: "6rem",
height: "6rem",
objectFit: "cover",
borderRadius: "50%",
}}
/>
));

Image.displayName = "Image";

function Row({ row, currentSemester, onClick }: RowProps) {
const { id, firstName, lastName, email, phoneNumber, image, emailVerified } = row;
const { department, role, project, status, notes } = row.tenures[currentSemester];
const { department, role, project, status, notes } = !!row.tenures[currentSemester] && row.tenures[currentSemester];
const { url } = useContext(DashboardContext);

const cellStyle = {
Expand All @@ -35,47 +19,54 @@ function Row({ row, currentSemester, onClick }: RowProps) {
};

return (
<TableRow hover role="checkbox" tabIndex={-1} key={`${id}${currentSemester}TR`} onClick={onClick}>
<TableCell
key={`member_${id}${currentSemester}`}
align="left"
style={{
...cellStyle,
display: "flex",
alignItems: "center",
columnGap: "1.5rem",
}}>
<Image key={`image_${id}${currentSemester}`} src={image ? url + id : "/Avatar.png"} />
<div>
<p className={styles.rowMemberName}>{`${firstName} ${lastName}${emailVerified ? "" : "*"}`}</p>
<p className={styles.rowEmail}>{email}</p>
<p className={styles.rowPhoneNumber}>{phoneNumber}</p>
</div>
</TableCell>
<TableCell key={`department_${id}`} align="center" style={cellStyle}>
<div className={styles.orangeHighlight}>
<p>{department}</p>
</div>
</TableCell>
<TableCell key={`role_${id}`} align="center" style={cellStyle}>
<div className={styles.orangeHighlight}>
<p>{role}</p>
</div>
</TableCell>
<TableCell key={`project_${id}`} align="center" style={cellStyle}>
<div className={styles.orangeHighlight}>
<p>{project}</p>
</div>
</TableCell>
<TableCell key={`status_${id}`} align="center" style={cellStyle}>
<div className={status === "Active" ? styles.greenHighlight : styles.redHighlight}>
<p>{status}</p>
</div>
</TableCell>
<TableCell key={`notes_${id}`} align="center" style={{ ...cellStyle, borderRight: "none" }}>
{notes ? <ChatBubbleOutlineRoundedIcon style={{ color: "#657788" }} /> : null}
</TableCell>
</TableRow>
<>
{!!row.tenures[currentSemester] && (
<TableRow hover role="checkbox" tabIndex={-1} key={`${id}${currentSemester}TR`} onClick={onClick}>
<TableCell
key={`member_${id}${currentSemester}`}
align="left"
style={{
...cellStyle,
display: "flex",
alignItems: "center",
columnGap: "1.5rem",
}}>
{
// eslint-disable-next-line @next/next/no-img-element
}
<img key={`image_${id}${currentSemester}`} src={image ? url + id : "/Avatar.png"} height={50} width={50} />
<div>
<p className={styles.rowMemberName}>{`${firstName} ${lastName}${emailVerified ? "" : "*"}`}</p>
<p className={styles.rowEmail}>{email}</p>
<p className={styles.rowPhoneNumber}>{phoneNumber}</p>
</div>
</TableCell>
<TableCell key={`department_${id}`} align="center" style={cellStyle}>
<div className={styles.orangeHighlight}>
<p>{department}</p>
</div>
</TableCell>
<TableCell key={`role_${id}`} align="center" style={cellStyle}>
<div className={styles.orangeHighlight}>
<p>{role}</p>
</div>
</TableCell>
<TableCell key={`project_${id}`} align="center" style={cellStyle}>
<div className={styles.orangeHighlight}>
<p>{project}</p>
</div>
</TableCell>
<TableCell key={`status_${id}`} align="center" style={cellStyle}>
<div className={status === "Active" ? styles.greenHighlight : styles.redHighlight}>
<p>{status}</p>
</div>
</TableCell>
<TableCell key={`notes_${id}`} align="center" style={{ ...cellStyle, borderRight: "none" }}>
{notes ? <ChatBubbleOutlineRoundedIcon style={{ color: "#657788" }} /> : null}
</TableCell>
</TableRow>
)}
</>
);
}

Expand Down
Loading

0 comments on commit 44b8f0f

Please sign in to comment.