Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tyler/won added CardGrid support for 2 and 3 column grids #90

Merged
merged 9 commits into from
Mar 10, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -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].
Expand Down Expand Up @@ -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
Expand All @@ -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])
}
Expand Down Expand Up @@ -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
}
id String @id @default(auto()) @map("_id") @db.ObjectId
approved Approval @default(PENDING)
uid String @unique @db.ObjectId
chapterId String @db.ObjectId
}
20 changes: 20 additions & 0 deletions src/app/private/[uid]/chapter-leader/edit-profile/layout.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<HeaderContainer
header="Profile"
headerIcon={faUser}
showHorizontalLine={true}
>
{children}
</HeaderContainer>
);
};

export default EditProfileLayout;
3 changes: 3 additions & 0 deletions src/app/private/[uid]/chapter-leader/edit-profile/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { EditProfileForm } from "@components/user";

export default EditProfileForm;
31 changes: 31 additions & 0 deletions src/app/private/[uid]/chapter-leader/home/@joinChapter/page.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<UserJoinRequest
chapters={chapters}
joinRequest={joinRequest}
uid={params.uid}
/>
);
};

export default UserJoinChapterPage;
42 changes: 42 additions & 0 deletions src/app/private/[uid]/chapter-leader/home/layout.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<HeaderContainer
header="Home"
headerIcon={faHouse}
showHorizontalLine={false}
>
<TabButtons
queries={[
{ segment: "home", name: "My Chapter" },
{ segment: "home/resources", name: "resources" },
]}
/>
{children}
</HeaderContainer>
);
} else {
return joinChapter;
}
};

export default Layout;
55 changes: 55 additions & 0 deletions src/app/private/[uid]/chapter-leader/home/page.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div className="mt-6 flex flex-col gap-y-6">
<div className="font-merriweather text-2xl font-bold text-[#000022]">
{chapter.chapterName}
</div>
<DisplayChapterInfo
location={chapter.location}
noMembers={
chapter.students.filter((user) => user.role == "USER").length
}
dateCreated={chapter.dateCreated}
/>
<CardGrid
title={
<div className="font-merriweather text-xl font-bold">
Executive Board
</div>
}
tiles={chapter.students
.filter((user) => user.role == "CHAPTER_LEADER")
.map((user) => (
<UserTile key={user.id} student={user} link="" />
))}
/>
</div>
);
};

export default UserHomePage;
53 changes: 53 additions & 0 deletions src/app/private/[uid]/chapter-leader/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"use client";

import Sidebar, { ISideBar } from "@components/Sidebar";
import { CollapsableSidebarContainer } from "@components/container";
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/users`,
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 (
<CollapsableSidebarContainer buttons={buttons}>
{children}
</CollapsableSidebarContainer>
);
};

export default UserLayout;
34 changes: 34 additions & 0 deletions src/app/private/[uid]/chapter-leader/pending/PendingHomePage.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<>
<h1 className="font-merriweather pb-8 text-3xl">
{`Pending (${users.length})`}
</h1>
{users.length > 0 ? (
<CardGrid
tiles={users.map((user, index) => {
return (
<PendingCard key={index} name={user.name ?? ""} uid={user.id} />
);
})}
/>
) : (
<h1 className="text-2xl font-light">
{"This chapter has no members."}
</h1>
)}
</>
);
};

export default PendingHomePage;
20 changes: 20 additions & 0 deletions src/app/private/[uid]/chapter-leader/pending/layout.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<HeaderContainer
showHorizontalLine
header="Members"
headerIcon={faUserGroup}
>
{props.children}
</HeaderContainer>
);
};

export default Layout;
34 changes: 34 additions & 0 deletions src/app/private/[uid]/chapter-leader/pending/page.tsx
Original file line number Diff line number Diff line change
@@ -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({
wkim10 marked this conversation as resolved.
Show resolved Hide resolved
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 <PendingHomePage users={users} />;
};

export default PendingPage;
Loading