Skip to content

Commit 6aee7bb

Browse files
authored
Merge branch 'main' into db-validation-fix
2 parents ac081a8 + 35145e7 commit 6aee7bb

27 files changed

+1175
-273
lines changed

app/(api)/_actions/logic/applyDiagnosticAlpha.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import JudgeToTeam from '@typeDefs/judgeToTeam';
44
import { GetManySubmissions } from '@datalib/submissions/getSubmissions';
5-
import { CreateSubmission } from '@datalib/submissions/createSubmission';
5+
import { CreateManySubmissions } from '@datalib/submissions/createSubmission';
66
import { GetManyTeams } from '@datalib/teams/getTeam';
77
import parseAndReplace from '@utils/request/parseAndReplace';
88
import checkMatches from '@actions/logic/checkMatches';
@@ -41,16 +41,26 @@ export default async function applyDiagnosticAlpha(options: {
4141
error: `Invalid assignments for alpha ${options.alpha}.`,
4242
};
4343
}
44-
4544
for (const submission of parsedSubmissions) {
46-
const res = await CreateSubmission({
47-
judge_id: { '*convertId': { id: submission.judge_id } },
48-
team_id: { '*convertId': { id: submission.team_id } },
49-
});
50-
if (!res.ok) {
51-
return { ok: false, body: null, error: res.error };
52-
}
45+
submission.judge_id = { '*convertId': { id: submission.judge_id } };
46+
submission.team_id = { '*convertId': { id: submission.team_id } };
47+
}
48+
const res = await CreateManySubmissions(parsedSubmissions);
49+
if (!res.ok) {
50+
return {
51+
ok: false,
52+
body: null,
53+
error: `Invalid submissions. ${res.error}`,
54+
};
5355
}
56+
// for (const submission of parsedSubmissions) {
57+
// const res = await CreateSubmission({
58+
// judge_id: { '*convertId': { id: submission.judge_id } },
59+
// team_id: { '*convertId': { id: submission.team_id } },
60+
// });
61+
// if (!res.ok) {
62+
// return { ok: false, body: null, error: res.error };
63+
// }
5464

5565
return { ok: true, body: options.judgeToTeam, error: null };
5666
}

app/(api)/_actions/logic/matchTeams.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import JudgeToTeam from '@typeDefs/judgeToTeam';
44
import matchAllTeams from '@utils/matching/judgesToTeamsAlgorithm';
55
import parseAndReplace from '@utils/request/parseAndReplace';
66
import { GetManyTeams } from '@datalib/teams/getTeam';
7-
import { CreateSubmission } from '@datalib/submissions/createSubmission';
7+
import { CreateManySubmissions } from '@datalib/submissions/createSubmission';
88
import { GetManySubmissions } from '@datalib/submissions/getSubmissions';
99
import checkMatches from '@actions/logic/checkMatches';
1010

@@ -41,14 +41,26 @@ export default async function matchTeams(
4141
const valid = checkMatches(parsedJudgeToTeam, teams.length);
4242
if (valid) {
4343
for (const submission of parsedJudgeToTeam) {
44-
const res = await CreateSubmission({
45-
judge_id: { '*convertId': { id: submission.judge_id } },
46-
team_id: { '*convertId': { id: submission.team_id } },
47-
});
48-
if (!res.ok) {
49-
console.error(res.error);
50-
}
44+
submission.judge_id = { '*convertId': { id: submission.judge_id } };
45+
submission.team_id = { '*convertId': { id: submission.team_id } };
5146
}
47+
const res = await CreateManySubmissions(parsedJudgeToTeam);
48+
if (!res.ok) {
49+
return {
50+
ok: false,
51+
body: null,
52+
error: 'Invalid submissions.',
53+
};
54+
}
55+
// for (const submission of parsedJudgeToTeam) {
56+
// const res = await CreateSubmission({
57+
// judge_id: { '*convertId': { id: submission.judge_id } },
58+
// team_id: { '*convertId': { id: submission.team_id } },
59+
// });
60+
// if (!res.ok) {
61+
// console.error(res.error);
62+
// }
63+
// }
5264
} else {
5365
return {
5466
ok: false,

app/(api)/_actions/submissions/getSubmission.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@ export async function getSubmission(judge_id: string, team_id: string) {
1616
export async function getManySubmissions(query: object = {}) {
1717
const newQuery = await parseAndReplace(query);
1818
const submissions = await GetManySubmissions(newQuery);
19-
return serializeMongoData(submissions);
19+
return JSON.parse(JSON.stringify(submissions));
2020
}

app/(api)/_datalib/submissions/createSubmission.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,80 @@ export const CreateSubmission = async (body: any) => {
6464
return { ok: false, body: null, error: error.message };
6565
}
6666
};
67+
68+
export const CreateManySubmissions = async (body: any[]) => {
69+
try {
70+
if (isBodyEmpty(body)) {
71+
throw new NoContentError();
72+
}
73+
74+
const parsedBody = await parseAndReplace(body);
75+
76+
const db = await getDatabase();
77+
78+
const submissionsToInsert = [];
79+
80+
for (const submission of parsedBody) {
81+
const { judge_id, team_id } = submission;
82+
83+
// Check if judge exists and has role 'judge'
84+
const judge = await db.collection('users').findOne({
85+
_id: judge_id,
86+
role: 'judge',
87+
});
88+
if (!judge) {
89+
throw new NotFoundError(`Judge with id: ${judge_id} not found.`);
90+
}
91+
92+
// Check if team exists
93+
const team = await db.collection('teams').findOne({
94+
_id: team_id,
95+
});
96+
if (!team) {
97+
throw new NotFoundError(`Team with id: ${team_id} not found.`);
98+
}
99+
100+
// Check for duplicate submission
101+
const existingSubmission = await db.collection('submissions').findOne({
102+
judge_id,
103+
team_id,
104+
});
105+
if (existingSubmission) {
106+
throw new DuplicateError(
107+
`Submission already exists for judge ${judge_id} and team ${team_id}`
108+
);
109+
}
110+
111+
submissionsToInsert.push({
112+
...submission,
113+
social_good: null,
114+
creativity: null,
115+
presentation: null,
116+
scores: [],
117+
comments: '',
118+
is_scored: false,
119+
queuePosition: null,
120+
});
121+
}
122+
123+
const creationStatus = await db
124+
.collection('submissions')
125+
.insertMany(submissionsToInsert);
126+
127+
const insertedSubmissions = await db
128+
.collection('submissions')
129+
.find({
130+
_id: {
131+
$in: Object.values(creationStatus.insertedIds).map(
132+
(id: any) => new ObjectId(id)
133+
),
134+
},
135+
})
136+
.toArray();
137+
138+
return { ok: true, body: insertedSubmissions, error: null, status: 201 };
139+
} catch (e) {
140+
const error = e as HttpError;
141+
return { ok: false, body: null, error: error.message };
142+
}
143+
};

app/(api)/_datalib/users/getUser.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { getDatabase } from '@utils/mongodb/mongoClient.mjs';
2+
import parseAndReplace from '@utils/request/parseAndReplace';
23
import { HttpError, NotFoundError } from '@utils/response/Errors';
34
import { ObjectId } from 'mongodb';
45

@@ -24,13 +25,15 @@ export const GetUser = async (id: string) => {
2425

2526
export const GetManyUsers = async (query: object = {}) => {
2627
try {
28+
const parsedQuery = await parseAndReplace(query);
29+
2730
const db = await getDatabase();
2831

2932
const users = await db
3033
.collection('users')
3134
.aggregate([
3235
{
33-
$match: query,
36+
$match: parsedQuery,
3437
},
3538
{
3639
$lookup: {

app/(pages)/(hackers)/(hub)/(index)/page.tsx

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,26 @@ import Contact from '@pages/(hackers)/_components/Contact/Contact';
77
import IndexHero from '@pages/(hackers)/_components/IndexHero/IndexHero';
88
import IndexHeroContentHacking from '@pages/(hackers)/_components/DOE/Hacking/IndexHeroContentHacking';
99
import IndexHeroContentJudging from '@pages/(hackers)/_components/DOE/Judging/IndexHeroContentJudging';
10-
import IndexHeroContentDone from '@pages/(hackers)/_components/IndexHero/IndexHeroContentDone';
11-
// import TimeProtectedDisplay from '@pages/_components/TimeProtectedDisplay/TimeProtectedDisplay';
1210
import ClientTimeProtectedDisplay from '@pages/_components/TimeProtectedDisplay/ClientTimeProtectedDisplay';
11+
import TableNumberCheckin from '@pages/(hackers)/_components/TableNumberCheckin/TableNumberCheckin';
12+
import TableNumberContextProvider from '@pages/_contexts/TableNumberContext';
1313

1414
export default function Page() {
1515
return (
1616
<main id="home">
17-
<IndexHero>
18-
<ClientTimeProtectedDisplay featureId="hero-hacking">
19-
<IndexHeroContentHacking />
17+
<TableNumberContextProvider>
18+
<IndexHero>
19+
<ClientTimeProtectedDisplay featureId="hero-hacking">
20+
<IndexHeroContentHacking />
21+
</ClientTimeProtectedDisplay>
22+
<ClientTimeProtectedDisplay featureId="hero-judging">
23+
<IndexHeroContentJudging />
24+
</ClientTimeProtectedDisplay>
25+
</IndexHero>
26+
<ClientTimeProtectedDisplay featureId="table-number-checkin">
27+
<TableNumberCheckin />
2028
</ClientTimeProtectedDisplay>
21-
<ClientTimeProtectedDisplay featureId="hero-judging">
22-
<IndexHeroContentJudging />
23-
</ClientTimeProtectedDisplay>
24-
<ClientTimeProtectedDisplay featureId="hero-done">
25-
<IndexHeroContentDone />
26-
</ClientTimeProtectedDisplay>
27-
</IndexHero>
28-
29+
</TableNumberContextProvider>
2930
<BeginnersSection />
3031
<Contact />
3132
<PrizeTracks />

app/(pages)/(hackers)/_components/DOE/Judging/IndexHeroContentJudging.module.scss

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -108,23 +108,6 @@
108108
flex-shrink: 0;
109109
}
110110
}
111-
112-
113-
114-
.belowClock {
115-
display: flex;
116-
flex-direction: row;
117-
align-items: center;
118-
gap: 40px;
119-
justify-content: space-between;
120-
width: 100%;
121-
122-
@include mixins.tablet-l {
123-
flex-direction: row;
124-
justify-content: center;
125-
align-items: flex-start;
126-
}
127-
}
128111

129112
.center_right {
130113
display: flex;

app/(pages)/(hackers)/_components/DOE/Judging/IndexHeroContentJudging.tsx

Lines changed: 12 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,28 @@
1+
'use client';
2+
13
import Image from 'next/image';
2-
// import Countdown from './Countdown';
3-
import styles from './IndexHeroContentJudging.module.scss';
44
import MusicPlayer from '../../IndexHero/MusicPlayer';
55
import star_icon from '@public/hackers/hero/star.svg';
6-
// import cow_tada from '@public/hackers/hero/cow_tada.svg';
76
import judge_bunny_and_ducky from '@public/hackers/hero/judge_bunny_and_ducky.svg';
8-
import Scroll from '../../IndexHero/Scroll';
97
import { LuArrowUpRight } from 'react-icons/lu';
10-
// import Map from '@pages/judges/(app)/map/_components/Map/Map';
118
import star from 'public/index/hero/star.svg';
129
import Link from 'next/link';
13-
// import TimeTracker from '../../IndexHero/TimeTracker';
14-
import Notifications from '../../IndexHero/Notifications';
1510
import JudgeBanners from '../../IndexHero/JudgeBanners';
16-
import { GoArrowRight } from 'react-icons/go';
11+
import styles from './IndexHeroContentJudging.module.scss';
1712

1813
export default function IndexHeroContentJudging() {
1914
return (
2015
<div className={styles.container}>
2116
<div className={styles.infoContainer}>
22-
<div className={styles.text}>
23-
<p className={styles.date}>
24-
APRIL 19-20
25-
<br />
26-
2025
27-
</p>
28-
<a
29-
href="https://drive.google.com/file/d/1l6fxi9jDKlleaStt4xXSgCjVg4dfQkjz/view?usp=sharing"
30-
className={styles.link}
31-
>
32-
<p className={styles.map}>VENUE MAP</p>
33-
<LuArrowUpRight size={23} />
34-
</a>
35-
</div>
36-
{/* <JudgeBanners /> */}
37-
<div className={styles.notifications}>
38-
<Notifications />
39-
</div>
17+
<p className={styles.date}>
18+
APRIL 19-20
19+
<br />
20+
2025
21+
</p>
22+
<a href="/map" className={styles.link}>
23+
<p className={styles.map}>VENUE MAP</p>
24+
<LuArrowUpRight size={23} />
25+
</a>
4026
</div>
4127

4228
<div className={styles.spacer_star_container}>
@@ -47,22 +33,6 @@ export default function IndexHeroContentJudging() {
4733
<MusicPlayer />
4834
<div className={styles.center_right}>
4935
<JudgeBanners />
50-
<div className={styles.belowClock}>
51-
<p className={styles.info}>
52-
A HACKDAVIS HUB
53-
<br />
54-
FOR EVERYONE WHO
55-
<span className={styles.monospace}>
56-
{' // creates for social good'}
57-
</span>
58-
</p>
59-
<a href="https://hackdavis-2025.devpost.com/">
60-
<button className={styles.submitButton}>
61-
<p>SUBMIT!</p>
62-
<GoArrowRight className={styles.submitArrow} />
63-
</button>
64-
</a>
65-
</div>
6636
</div>
6737
</div>
6838

@@ -73,11 +43,6 @@ export default function IndexHeroContentJudging() {
7343
<div className={styles.social_good}>{'// for social good'}</div>
7444
</div>
7545

76-
<div className={styles.spacer_star_container}>
77-
<Image src={star} alt="star" className={styles.spacer_star} />
78-
</div>
79-
<Scroll />
80-
8146
<div className={styles.group_width}>
8247
<div
8348
style={{

app/(pages)/(hackers)/_components/IndexHero/DoneJudging.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ export default function DoneJudging() {
1212
<p>CONGRATS!</p>
1313
<br />
1414
<p>
15-
Youre all done, thank you so much for your participation at
15+
You're all done, thank you so much for your participation at
1616
HackDavis 2025. Please wait until <b>Closing Ceremony</b> for
1717
judging results! In the meantime, put in your vote for{' '}
1818
<a href="/" target="_blank">
19-
Hackers Choice Award
19+
Hacker's Choice Award
2020
</a>{' '}
2121
and check out our insta <b>@hackdavis!</b>
2222
</p>

app/(pages)/(hackers)/_components/IndexHero/IndexHero.module.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
background: linear-gradient(154deg, #76DEEB 45.75%, #FCFCD1 92.58%);
99

1010
@include tablet-l {
11-
padding-bottom: 0;
11+
padding-bottom: 15%;
1212
}
1313
}
1414

0 commit comments

Comments
 (0)