diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index c9af638e..3c1b2b75 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -46,7 +46,7 @@ model Session {
}
model User {
- id String @id @default(auto()) @map("_id") @db.ObjectId
+ id String @id @default(auto()) @map("_id") @db.ObjectId
// https://github.com/nextauthjs/next-auth/blob/v4/packages/next-auth/src/providers/google.ts
// Fields mappable from PrismaAdapter. We can map the value return from profle() in [...nextauth].
@@ -86,7 +86,7 @@ enum Role {
model Senior {
id String @id @default(auto()) @map("_id") @db.ObjectId
- name String
+ name String @default("")
location String
description String
StudentIDs String[] @db.ObjectId
@@ -98,13 +98,13 @@ model Senior {
}
model File {
- id String @id @default(auto()) @map("_id") @db.ObjectId
- date DateTime // will zero out the hours
- filetype String
- url String
- seniorId String @db.ObjectId
- senior Senior @relation(fields: [seniorId], references: [id], onDelete: Cascade)
- Tags String[]
+ id String @id @default(auto()) @map("_id") @db.ObjectId
+ date DateTime // will zero out the hours
+ filetype String
+ url String
+ seniorId String @db.ObjectId
+ senior Senior @relation(fields: [seniorId], references: [id], onDelete: Cascade)
+ Tags String[]
@@unique([seniorId, date])
}
@@ -134,20 +134,20 @@ model Chapter {
}
model Resource {
- id String @id @default(auto()) @map("_id") @db.ObjectId
- access Role[]
- link String
- title String
+ id String @id @default(auto()) @map("_id") @db.ObjectId
+ access Role[]
+ link String
+ title String
}
model Email {
- id String @id @default(auto()) @map("_id") @db.ObjectId
- email String @unique
+ id String @id @default(auto()) @map("_id") @db.ObjectId
+ email String @unique
}
model UserRequest {
- id String @id @default(auto()) @map("_id") @db.ObjectId
- approved Approval @default(PENDING)
- uid String @db.ObjectId @unique
- chapterId String @db.ObjectId
-}
\ No newline at end of file
+ id String @id @default(auto()) @map("_id") @db.ObjectId
+ approved Approval @default(PENDING)
+ uid String @unique @db.ObjectId
+ chapterId String @db.ObjectId
+}
diff --git a/src/app/private/[uid]/chapter-leader/edit-profile/layout.tsx b/src/app/private/[uid]/chapter-leader/edit-profile/layout.tsx
new file mode 100644
index 00000000..9946e8ba
--- /dev/null
+++ b/src/app/private/[uid]/chapter-leader/edit-profile/layout.tsx
@@ -0,0 +1,20 @@
+import { HeaderContainer } from "@components/container/index";
+import { faUser } from "@fortawesome/free-regular-svg-icons";
+
+interface IEditProfileLayout {
+ children: React.ReactNode;
+}
+
+const EditProfileLayout = ({ children }: IEditProfileLayout) => {
+ return (
+
+ {children}
+
+ );
+};
+
+export default EditProfileLayout;
diff --git a/src/app/private/[uid]/chapter-leader/edit-profile/page.tsx b/src/app/private/[uid]/chapter-leader/edit-profile/page.tsx
new file mode 100644
index 00000000..6dace489
--- /dev/null
+++ b/src/app/private/[uid]/chapter-leader/edit-profile/page.tsx
@@ -0,0 +1,3 @@
+import { EditProfileForm } from "@components/user";
+
+export default EditProfileForm;
diff --git a/src/app/private/[uid]/chapter-leader/home/@joinChapter/page.tsx b/src/app/private/[uid]/chapter-leader/home/@joinChapter/page.tsx
new file mode 100644
index 00000000..6440defe
--- /dev/null
+++ b/src/app/private/[uid]/chapter-leader/home/@joinChapter/page.tsx
@@ -0,0 +1,31 @@
+import { UserJoinRequest } from "@components/user";
+import { prisma } from "@server/db/client";
+
+interface UserHomePageParams {
+ params: {
+ uid: string;
+ };
+}
+
+const UserJoinChapterPage = async ({ params }: UserHomePageParams) => {
+ const chapters = await prisma.chapter.findMany({
+ include: {
+ students: true,
+ },
+ });
+ const joinRequest = await prisma.userRequest.findFirst({
+ where: {
+ uid: params.uid,
+ },
+ });
+
+ return (
+
+ );
+};
+
+export default UserJoinChapterPage;
diff --git a/src/app/private/[uid]/chapter-leader/home/layout.tsx b/src/app/private/[uid]/chapter-leader/home/layout.tsx
new file mode 100644
index 00000000..244e61a5
--- /dev/null
+++ b/src/app/private/[uid]/chapter-leader/home/layout.tsx
@@ -0,0 +1,42 @@
+import { prisma } from "@server/db/client";
+import TabButtons from "@components/TabButtons";
+import { HeaderContainer } from "@components/container/index";
+import { faHouse } from "@fortawesome/free-solid-svg-icons";
+
+interface LayoutProps {
+ children: React.ReactNode;
+ joinChapter: React.ReactNode;
+ params: {
+ uid: string;
+ };
+}
+
+const Layout = async ({ children, params, joinChapter }: LayoutProps) => {
+ const user = await prisma.user.findFirstOrThrow({
+ where: {
+ id: params.uid,
+ },
+ });
+
+ if (user.ChapterID != null) {
+ return (
+
+
+ {children}
+
+ );
+ } else {
+ return joinChapter;
+ }
+};
+
+export default Layout;
diff --git a/src/app/private/[uid]/chapter-leader/home/page.tsx b/src/app/private/[uid]/chapter-leader/home/page.tsx
new file mode 100644
index 00000000..e3f666f9
--- /dev/null
+++ b/src/app/private/[uid]/chapter-leader/home/page.tsx
@@ -0,0 +1,55 @@
+import { UserTile } from "@components/TileGrid";
+import DisplayChapterInfo from "@components/DisplayChapterInfo";
+import { prisma } from "@server/db/client";
+import { CardGrid } from "@components/container";
+
+interface UserHomePageParams {
+ params: {
+ uid: string;
+ };
+}
+
+const UserHomePage = async ({ params }: UserHomePageParams) => {
+ const user = await prisma.user.findFirstOrThrow({
+ where: {
+ id: params.uid,
+ },
+ });
+ const chapter = await prisma.chapter.findFirstOrThrow({
+ where: {
+ id: user.ChapterID ?? "",
+ },
+ include: {
+ students: true,
+ },
+ });
+
+ return (
+
+
+ {chapter.chapterName}
+
+
user.role == "USER").length
+ }
+ dateCreated={chapter.dateCreated}
+ />
+
+ Executive Board
+
+ }
+ tiles={chapter.students
+ .filter((user) => user.role == "CHAPTER_LEADER")
+ .map((user) => (
+
+ ))}
+ />
+
+ );
+};
+
+export default UserHomePage;
diff --git a/src/app/private/[uid]/chapter-leader/layout.tsx b/src/app/private/[uid]/chapter-leader/layout.tsx
new file mode 100644
index 00000000..56845964
--- /dev/null
+++ b/src/app/private/[uid]/chapter-leader/layout.tsx
@@ -0,0 +1,55 @@
+"use client";
+
+import Sidebar, { ISideBar } from "@components/Sidebar";
+import {
+ faHome,
+ faUser,
+ faUserGroup,
+ faUserPlus,
+} from "@fortawesome/free-solid-svg-icons";
+import React, { useContext } from "react";
+import { UserContext } from "src/context/UserProvider";
+
+interface IUserLayout {
+ children: React.ReactNode;
+}
+
+const UserLayout = ({ children }: IUserLayout) => {
+ const { user } = useContext(UserContext);
+ const buttons: ISideBar["buttons"] = React.useMemo(
+ () => [
+ {
+ name: "Home",
+ link: `/private/${user.id}/chapter-leader/home`,
+ icon: faHome,
+ },
+ {
+ name: "Members",
+ link: `/private/${user.id}/chapter-leader/members`,
+ icon: faUserGroup,
+ },
+ {
+ name: "Pending",
+ link: `/private/${user.id}/chapter-leader/pending`,
+ icon: faUserPlus,
+ },
+ {
+ name: "Profile",
+ link: `/private/${user.id}/chapter-leader/edit-profile`,
+ icon: faUser,
+ },
+ ],
+ [user.id]
+ );
+
+ return (
+
+ );
+};
+
+export default UserLayout;
diff --git a/src/app/private/[uid]/chapter-leader/members/MembersHomePage.tsx b/src/app/private/[uid]/chapter-leader/members/MembersHomePage.tsx
new file mode 100644
index 00000000..07653e89
--- /dev/null
+++ b/src/app/private/[uid]/chapter-leader/members/MembersHomePage.tsx
@@ -0,0 +1,52 @@
+"use client";
+
+import { useState } from "react";
+import { UserTile } from "@components/TileGrid";
+import { CardGrid } from "@components/container";
+import SearchBar from "@components/SearchBar";
+import { User } from "@prisma/client";
+
+type MembersHomePageProps = {
+ members: User[];
+ user: User;
+};
+
+const MembersHomePage = ({ members, user }: MembersHomePageProps) => {
+ const [filter, setFilter] = useState("");
+
+ return (
+ <>
+
+ {`Members (${members.length})`}
+
+
+
+
+ {members.length > 0 ? (
+
+ (member.firstName + " " + member.lastName)
+ .toLowerCase()
+ .includes(filter.toLowerCase())
+ )
+ .map((member, index) => {
+ return (
+
+ );
+ })}
+ />
+ ) : (
+
+ {"This chapter has no members."}
+
+ )}
+ >
+ );
+};
+
+export default MembersHomePage;
diff --git a/src/app/private/[uid]/chapter-leader/members/layout.tsx b/src/app/private/[uid]/chapter-leader/members/layout.tsx
new file mode 100644
index 00000000..b52667ac
--- /dev/null
+++ b/src/app/private/[uid]/chapter-leader/members/layout.tsx
@@ -0,0 +1,20 @@
+import { HeaderContainer } from "@components/container";
+import { faUserGroup } from "@fortawesome/free-solid-svg-icons";
+
+interface LayoutProps {
+ children?: React.ReactNode;
+}
+
+const Layout = (props: LayoutProps) => {
+ return (
+
+ {props.children}
+
+ );
+};
+
+export default Layout;
diff --git a/src/app/private/[uid]/chapter-leader/members/page.tsx b/src/app/private/[uid]/chapter-leader/members/page.tsx
new file mode 100644
index 00000000..1165f864
--- /dev/null
+++ b/src/app/private/[uid]/chapter-leader/members/page.tsx
@@ -0,0 +1,24 @@
+import React from "react";
+import { prisma } from "@server/db/client";
+import MembersHomePage from "./MembersHomePage";
+
+const MembersPage = async ({ params }: { params: { uid: string } }) => {
+ const user = await prisma.user.findFirstOrThrow({
+ where: {
+ id: params.uid,
+ },
+ });
+
+ const chapter = await prisma.chapter.findFirstOrThrow({
+ where: {
+ id: user.ChapterID ?? "",
+ },
+ include: {
+ students: true,
+ },
+ });
+
+ return ;
+};
+
+export default MembersPage;
diff --git a/src/app/private/[uid]/chapter-leader/pending/PendingHomePage.tsx b/src/app/private/[uid]/chapter-leader/pending/PendingHomePage.tsx
new file mode 100644
index 00000000..29644307
--- /dev/null
+++ b/src/app/private/[uid]/chapter-leader/pending/PendingHomePage.tsx
@@ -0,0 +1,34 @@
+"use client";
+
+import PendingCard from "@components/PendingCard";
+import { CardGrid } from "@components/container";
+import { User } from "@prisma/client";
+
+type MembersHomePageProps = {
+ users: User[];
+};
+
+const PendingHomePage = ({ users }: MembersHomePageProps) => {
+ return (
+ <>
+
+ {`Pending (${users.length})`}
+
+ {users.length > 0 ? (
+ {
+ return (
+
+ );
+ })}
+ />
+ ) : (
+
+ {"This chapter has no members."}
+
+ )}
+ >
+ );
+};
+
+export default PendingHomePage;
diff --git a/src/app/private/[uid]/chapter-leader/pending/layout.tsx b/src/app/private/[uid]/chapter-leader/pending/layout.tsx
new file mode 100644
index 00000000..b52667ac
--- /dev/null
+++ b/src/app/private/[uid]/chapter-leader/pending/layout.tsx
@@ -0,0 +1,20 @@
+import { HeaderContainer } from "@components/container";
+import { faUserGroup } from "@fortawesome/free-solid-svg-icons";
+
+interface LayoutProps {
+ children?: React.ReactNode;
+}
+
+const Layout = (props: LayoutProps) => {
+ return (
+
+ {props.children}
+
+ );
+};
+
+export default Layout;
diff --git a/src/app/private/[uid]/chapter-leader/pending/page.tsx b/src/app/private/[uid]/chapter-leader/pending/page.tsx
new file mode 100644
index 00000000..92db5f09
--- /dev/null
+++ b/src/app/private/[uid]/chapter-leader/pending/page.tsx
@@ -0,0 +1,34 @@
+import React from "react";
+import { prisma } from "@server/db/client";
+import PendingHomePage from "./PendingHomePage";
+import { User } from "@prisma/client";
+
+const PendingPage = async ({ params }: { params: { uid: string } }) => {
+ const user = await prisma.user.findFirstOrThrow({
+ where: {
+ id: params.uid,
+ },
+ });
+
+ const userRequests = await prisma.userRequest.findMany({
+ where: {
+ chapterId: user.ChapterID ?? "",
+ },
+ });
+
+ const users: User[] = [];
+
+ for (let i = 0; i < userRequests.length; i++) {
+ const user = await prisma.user.findFirstOrThrow({
+ where: {
+ id: userRequests[i]?.uid ?? "",
+ },
+ });
+
+ users.push(user);
+ }
+
+ return ;
+};
+
+export default PendingPage;
diff --git a/src/app/private/[uid]/user/layout.tsx b/src/app/private/[uid]/user/layout.tsx
index 7277efa2..4cf917fa 100644
--- a/src/app/private/[uid]/user/layout.tsx
+++ b/src/app/private/[uid]/user/layout.tsx
@@ -1,6 +1,10 @@
"use client";
+<<<<<<< HEAD
import { CollapsableSidebarContainer } from "@components/container";
+=======
+import Sidebar, { ISideBar } from "@components/Sidebar";
+>>>>>>> 9bd5bd7 (finish first draft)
import { faHome, faUsers, faUser } from "@fortawesome/free-solid-svg-icons";
import React, { useContext } from "react";
import { UserContext } from "src/context/UserProvider";
diff --git a/src/app/private/[uid]/user/seniors/SeniorsHomePage.tsx b/src/app/private/[uid]/user/seniors/SeniorsHomePage.tsx
index 304a89b7..2448f666 100644
--- a/src/app/private/[uid]/user/seniors/SeniorsHomePage.tsx
+++ b/src/app/private/[uid]/user/seniors/SeniorsHomePage.tsx
@@ -19,25 +19,33 @@ const SeniorsHomePage = ({ seniors, user }: SeniorsHomePageProps) => {
return (
<>
+
+ {`My Assigned Seniors (${seniors.length})`}
+
-
- senior.name.toLowerCase().includes(filter.toLowerCase())
- )
- .map((senior, index) => {
- return (
-
- );
- })}
- />
+ {seniors.length > 0 ? (
+
+ senior.name.toLowerCase().includes(filter.toLowerCase())
+ )
+ .map((senior, index) => {
+ return (
+
+ );
+ })}
+ />
+ ) : (
+
+ {"You haven't been assigned a Senior yet."}
+
+ )}
>
);
};
diff --git a/src/components/Sidebar.tsx b/src/components/Sidebar.tsx
index b18b4cb6..6983941f 100644
--- a/src/components/Sidebar.tsx
+++ b/src/components/Sidebar.tsx
@@ -12,8 +12,11 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { UserContext } from "src/context/UserProvider";
import Logo from "@public/icons/logo.svg";
import Image from "next/image";
+<<<<<<< HEAD
import { RoleAlias } from "@constants/RoleAlias";
import { fullName } from "@utils";
+=======
+>>>>>>> 9bd5bd7 (finish first draft)
interface Button {
name: string;
@@ -98,6 +101,7 @@ const Sidebar = (props: ISideBar) => {
<_Sidebar {...props} />
+<<<<<<< HEAD
setSidebarVisible(false)}
@@ -119,6 +123,30 @@ const Sidebar = (props: ISideBar) => {
<_Sidebar {...props} />
)}
+=======
+
+
+ {/* TODO(nickbar01234) - Render university name */}
+ {/*
+
+ Tufts University
+
*/}
+
+
+ {user.name ?? ""}
+
+
+ {user.role[0] + user.role.toLowerCase().slice(1)}
+
+
+>>>>>>> 9bd5bd7 (finish first draft)
>
);
diff --git a/src/components/TileGrid/UserTile.tsx b/src/components/TileGrid/UserTile.tsx
index 7a0a63df..f0616bc4 100644
--- a/src/components/TileGrid/UserTile.tsx
+++ b/src/components/TileGrid/UserTile.tsx
@@ -54,7 +54,7 @@ export function UserTile({
{student && student.name
? student.name + (student.admin ? " (Admin)" : "")
- : senior && senior.name
+ : senior
? senior.name
: null}
diff --git a/src/components/admin/DisplayChapter.tsx b/src/components/admin/DisplayChapter.tsx
index 02eb66ec..d8b91205 100644
--- a/src/components/admin/DisplayChapter.tsx
+++ b/src/components/admin/DisplayChapter.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react/jsx-no-duplicate-props */
"use client";
import { editRole } from "@api/user/[uid]/edit-role/route.client";