Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
86e1d5c
displays reported teams at the top
phlangiee Sep 7, 2025
0bebd88
made Reported Teams header smaller
phlangiee Sep 7, 2025
54ebaa2
Pulled changes from main
phlangiee Sep 8, 2025
06e1f36
Added team number and table number alongside the team number in the r…
phlangiee Sep 22, 2025
fa5db7e
test
phlangiee Sep 22, 2025
13bb3cc
Reverted test changes and combined declaration of POST variable with …
phlangiee Sep 22, 2025
3529479
Formatting (probably all of it)
phlangiee Sep 22, 2025
3373844
Added a param to post function
phlangiee Sep 22, 2025
a10fc8a
Meshed the post function with the export line (please please please w…
phlangiee Sep 22, 2025
5a88998
More formatting
phlangiee Sep 22, 2025
8df3844
Added a param to post function that complies with eslint
phlangiee Sep 22, 2025
e2e3b54
Just kidding this complies with eslint
phlangiee Sep 22, 2025
b4fcad6
More formmatting
phlangiee Sep 22, 2025
aabce0a
Just kidding this param complies with eslint
phlangiee Sep 22, 2025
bc246ab
Maybe this complies??
phlangiee Sep 22, 2025
e1a0022
Formatting (I hope this is the last one)
phlangiee Sep 22, 2025
add747d
Ok I take that back please dont give me that error
phlangiee Sep 22, 2025
6f1fc9e
Formatting (Ok this is the last one)
phlangiee Sep 22, 2025
311707e
Added sorted reports view
michelleyeoh Sep 24, 2025
4051f67
Added sorted reports view
michelleyeoh Sep 24, 2025
891fd60
Merge branch 'feat/reported-teams' of https://github.com/HackDavis/ju…
michelleyeoh Sep 24, 2025
5a13474
Updated logout post function
michelleyeoh Sep 24, 2025
60aaf41
Add NextRequest only
michelleyeoh Sep 24, 2025
8ba034a
Made params optional
michelleyeoh Sep 24, 2025
b13b96c
added promise to invite link
michelleyeoh Sep 24, 2025
230a802
Added promise to magic link reset
michelleyeoh Sep 24, 2025
2732bfc
Updated async promise in judges score
michelleyeoh Sep 24, 2025
4de53a8
updated async cookies
michelleyeoh Sep 24, 2025
91a89fd
Updated Next version
michelleyeoh Sep 24, 2025
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
3 changes: 2 additions & 1 deletion app/(api)/_actions/invite/getInviteData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export async function getInviteData() {
if (noUsers) {
return null;
} else {
const data = cookies().get('data');
const cookieStore = await cookies();
const data = cookieStore.get('data');
if (!data) return null;

const dataJson = atob(data.value);
Expand Down
5 changes: 3 additions & 2 deletions app/(api)/_actions/invite/processInvite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ export async function processInvite(slug: string) {
const data = slugComponents[0];
const sig = slugComponents[1];

cookies().set('data', data, { httpOnly: true });
cookies().set('sig', sig, { httpOnly: true });
const cookieStore = await cookies();
cookieStore.set('data', data, { httpOnly: true });
cookieStore.set('sig', sig, { httpOnly: true });

return true;
}
Expand Down
4 changes: 2 additions & 2 deletions app/(api)/_utils/authentication/authenticated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { auth } from '@/auth';
import { HttpError, NotAuthenticatedError } from '@utils/response/Errors';

export default function authenticated(
handler: (request: NextRequest, params: any) => Promise<NextResponse>
handler: (request: NextRequest, params?: any) => Promise<NextResponse>
) {
return async (request: NextRequest, params: object) => {
return async (request: NextRequest, params?: any) => {
try {
const session = await auth();
if (!session) {
Expand Down
4 changes: 2 additions & 2 deletions app/(api)/api/auth/logout/route.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
'use server';

import { NextResponse } from 'next/server';
import { NextRequest, NextResponse } from 'next/server';

import Logout from '@datalib/auth/logout';
import authenticated from '@utils/authentication/authenticated';

async function post() {
async function post(_: NextRequest) {
const res = await Logout();
return NextResponse.json({ ...res }, { status: res.ok ? 200 : 401 });
}
Expand Down
9 changes: 7 additions & 2 deletions app/(pages)/(magic-link)/invite/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ import { useRouter } from 'next/navigation';
import { processInvite } from '@actions/invite/processInvite';
import Loader from '@pages/_components/Loader/Loader';

export default function Page({ params }: { params: { slug: string } }) {
export default function Page({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const router = useRouter();
const [valid, setValid] = useState(true);

useEffect(() => {
const handleInvite = async () => {
if (await processInvite(params.slug)) {
const resolvedParams = await params;
if (await processInvite(resolvedParams.slug)) {
setValid(true);
router.push('/register');
} else {
Expand Down
9 changes: 7 additions & 2 deletions app/(pages)/(magic-link)/reset/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,18 @@ import { useRouter } from 'next/navigation';
import { processInvite } from '@actions/invite/processInvite';
import Loader from '@pages/_components/Loader/Loader';

export default function Page({ params }: { params: { slug: string } }) {
export default function Page({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const router = useRouter();
const [valid, setValid] = useState(true);

useEffect(() => {
const handleReset = async () => {
if (await processInvite(params.slug)) {
const resolvedParams = await params;
if (await processInvite(resolvedParams.slug)) {
setValid(true);
router.push('/reset-password');
} else {
Expand Down
5 changes: 3 additions & 2 deletions app/(pages)/_components/InviteOnlyRoute/InviteOnlyRoute.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ export default async function InviteOnlyRoute({
}: {
children: React.ReactNode;
}) {
const data = cookies().get('data');
const sig = cookies().get('sig');
const cookieStore = await cookies();
const data = cookieStore.get('data');
const sig = cookieStore.get('sig');

const users = await getManyUsers();
const noUsers = users.body.length === 0;
Expand Down
26 changes: 26 additions & 0 deletions app/(pages)/admin/teams/page.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,29 @@ $data-gap: 24px;
.action_header {
font-size: 1.75rem;
}

.reported_teams_container {
display: flex;
gap: 8px;
margin-top: 10px;
margin-bottom: 10px;
}

.reports_container {
display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr;
gap: 4px;

@include desktop-m {
grid-template-columns: 1fr 1fr;
}
}

.report_container {
font-size: 0.9rem;
color: black;
padding: 6px 12px;
border-radius: 8px;
background: var(--text-gray-light);
box-shadow: 0px 4px 8px 4px rgba(195, 194, 194, 0.08);
}
75 changes: 70 additions & 5 deletions app/(pages)/admin/teams/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import { useState } from 'react';
import { useTeams } from '@pages/_hooks/useTeams';
import { GoSearch } from 'react-icons/go';
import { IoAdd } from 'react-icons/io5';
import { RxCross1 } from 'react-icons/rx';
import TeamCard from '../_components/Teams/TeamCard';
import Team from '@typeDefs/team';
import User from '@typeDefs/user';
Expand All @@ -20,6 +22,7 @@ export default function Teams() {
const { loading, teams, getTeams } = useTeams();
const { data, setData } = useFormContext();
const isEditing = Boolean(data._id);
const [reportedTeamsDisplay, setReportedTeamsDisplay] = useState(false);

if (loading) {
return 'loading...';
Expand All @@ -29,6 +32,10 @@ export default function Teams() {
return teams.error;
}

function toggleReportedTeamsDisplay() {
setReportedTeamsDisplay(!reportedTeamsDisplay);
}

const teamData: TeamWithJudges[] = teams.body
.filter((team: TeamWithJudges) =>
JSON.stringify(team).toLowerCase().includes(search.toLowerCase())
Expand All @@ -44,6 +51,8 @@ export default function Teams() {
backgroundColor: '#9EE7E5',
}));

const reportedTeams = teamData.filter((team) => team.reports?.length > 0);

return (
<div className={styles.container}>
<h1 className={styles.page_title}>Team Manager</h1>
Expand All @@ -65,15 +74,71 @@ export default function Teams() {
/>
<GoSearch className={styles.search_icon} />
</div>
<div className={styles.reported_teams_container}>
<h2 className={styles.action_header}> Reported Teams</h2>
<button
onClick={toggleReportedTeamsDisplay}
style={{
fontSize: '1.25rem',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '40px',
height: '40px',
backgroundColor: reportedTeamsDisplay
? 'var(--text-error)'
: 'var(--text-gray-light)',
color: reportedTeamsDisplay ? 'white' : 'black',
borderRadius: '6px',
cursor: 'pointer',
border: 'none',
}}
>
{reportedTeamsDisplay ? <RxCross1 /> : <IoAdd />}
</button>
</div>
<div className={styles.reports_container}>
{reportedTeamsDisplay &&
reportedTeams
.sort((a, b) => (b.reports?.length || 0) - (a.reports?.length || 0))
.map((team) => (
<div className={styles.report_container} key={team._id}>
<a href={`#${team._id}`}>
<strong style={{ color: 'var(--text-error)' }}>
[{team.reports?.length}]
</strong>{' '}
Table {team.tableNumber}: {team.name} (Team {team.teamNumber})
</a>
</div>
))}
</div>
<div className={styles.data_portion}>
<div className={styles.teams_list}>
{teamData.map((team: TeamWithJudges) => (
<div className={styles.team_card_wrapper} key={team._id}>
<TeamCard team={team} onEditClick={() => setData(team)} />
</div>
))}
{teamData
.sort((a, b) => (b.reports?.length || 0) - (a.reports?.length || 0))
.map((team: TeamWithJudges) => (
<div
id={team._id}
className={styles.team_card_wrapper}
key={team._id}
>
<TeamCard team={team} onEditClick={() => setData(team)} />
</div>
))}
{teamData
.sort((a, b) => (b.reports?.length || 0) - (a.reports?.length || 0))
.map((team: TeamWithJudges) => (
<div
id={team._id}
className={styles.team_card_wrapper}
key={team._id}
>
<TeamCard team={team} onEditClick={() => setData(team)} />
</div>
))}
</div>
<div className={styles.bar_chart_container}>
<h2 className={styles.action_header}>Judge Count</h2>
<BarChart
data={chartData}
lines={[{ style: 'dashed 1px red', value: 3 }]}
Expand Down
14 changes: 9 additions & 5 deletions app/(pages)/judges/(app)/score/[team-id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { useState } from 'react';
import { useState, useEffect } from 'react';
import styles from './page.module.scss';
import ScoringForm from '@components/ScoringForm/ScoringForm';
import Loader from '@components/Loader/Loader';
Expand All @@ -13,15 +13,19 @@ import { useTeam } from '@hooks/useTeam';
import leftArrow from '@public/judges/scoring/left-arrow.svg';

interface ScoringFormProps {
params: {
params: Promise<{
'team-id': string;
};
}>;
}

export default function ScoreTeam({ params }: ScoringFormProps) {
const [showInfo, setShowInfo] = useState(false);
const { submission, loading: subLoading } = useSubmission(params['team-id']);
const { team, loading: teamLoading } = useTeam(params['team-id']);
const [teamId, setTeamId] = useState<string>('');
useEffect(() => {
params.then((p) => setTeamId(p['team-id']));
}, [params]);
const { submission, loading: subLoading } = useSubmission(teamId);
const { team, loading: teamLoading } = useTeam(teamId);
const loading = subLoading || teamLoading;

if (loading) {
Expand Down
Loading