Skip to content

Commit bf85a16

Browse files
authored
Merge pull request #68 from HackDavis/feat/getTeams
Feat/get teams
2 parents a065af5 + f498968 commit bf85a16

File tree

11 files changed

+4198
-4
lines changed

11 files changed

+4198
-4
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use server';
2+
3+
import { CreateManyTeams } from '@datalib/teams/createTeams';
4+
import csvAlgorithm from '@utils/csv-ingestion/csvAlgorithm';
5+
6+
export default async function ingestCSV() {
7+
const parsedData = await (await csvAlgorithm()).json();
8+
9+
const res = await (await CreateManyTeams(parsedData.body)).json();
10+
return { ok: res.ok, error: res.error };
11+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use server';
2+
import fs from 'fs';
3+
4+
export default async function uploadFile(formData: FormData) {
5+
const file = formData.get('file') as File;
6+
const data = await file.arrayBuffer();
7+
return new Promise((resolve, rejects) => {
8+
fs.writeFile(
9+
'app/(api)/_data/2024_data.csv',
10+
Buffer.from(data),
11+
(error) => {
12+
if (error) {
13+
rejects({
14+
ok: false,
15+
body: null,
16+
error: error?.message,
17+
});
18+
} else {
19+
resolve({
20+
ok: true,
21+
body: `Successfully uploaded.`,
22+
error: null,
23+
});
24+
}
25+
}
26+
);
27+
});
28+
}

app/(api)/_data/2024_data.csv

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Project Title,Table Number,Submission Url,Project Status,Judging Status,Highest Step Completed,Project Created At,About The Project,"""Try it out"" Links",Video Demo Link,Opt-In Prizes,Built With,Submitter First Name,Submitter Last Name,Submitter Email,Notes,Technical Focus,Design Focus,From The Tracks You Have Selected (Upto 4 Tracks) Please Choose The Top 2 Prize Tracks.,Choose The Second Prize Track From Your Top 2 Prize Tracks.,Team Colleges/Universities,Additional Team Member Count,Team Member 1 First Name,Team Member 1 Last Name,Team Member 1 Email,...
2+
dummy,10,https://hackdavis-2024.devpost.com/submissions/509367-dummy,Submitted (Gallery/Visible),Pending,Submit,04/24/2024 16:46:12,"What's next for dummy
3+
4+
blah blah blah
5+
",http://www.hackdavis.io,,"Best Beginner Hack, Most Technically Challenging Hack, Best Use of .Tech Domain Name",java,Anjali,Jain,anjjain@ucdavis.edu,,10,1,Best Beginner Hack,Most Technically Challenging Hack,University of California - Davis,0

app/(api)/_data/test_projects_2023.csv

Lines changed: 3997 additions & 0 deletions
Large diffs are not rendered by default.

app/(api)/_data/tracks.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100
"type": "tech"
101101
},
102102
{
103-
"name": "Best .Tech Domain Name",
103+
"name": "Best Use of .Tech Domain Name",
104104
"weights": [0.35, 0.25, 0.05, 0.25, 0.1],
105105
"type": "tech"
106106
},

app/(api)/_schema/Team.mjs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ const Team = {
1919
},
2020
tracks: {
2121
bsonType: 'array',
22-
minItems: 4,
23-
maxItems: 5,
22+
maxItems: 4,
2423
items: {
2524
enum: tracks.map((track) => track.name),
2625
description: 'track must be one of the valid tracks',
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import * as fs from 'fs';
2+
import csv from 'csv-parser';
3+
import { NextResponse } from 'next/server';
4+
import trackData from '../../_data/tracks.json' assert { type: 'json' };
5+
6+
const validTracks: string[] = trackData
7+
.map((track: track) => track.name)
8+
.filter((t) => t !== 'Best Hack for Social Good');
9+
10+
interface parsedRecord {
11+
name: string;
12+
number: number;
13+
tracks: string[];
14+
}
15+
16+
interface track {
17+
name: string;
18+
}
19+
20+
function sortTracks(track1: string, track2: string, chosentracks: string) {
21+
const tracksInOrder: string[] = [track1, track2];
22+
if (chosentracks.length < 2) {
23+
return tracksInOrder;
24+
} else {
25+
const otherTracks = chosentracks
26+
.split(',')
27+
.map((track: string) => track.trim())
28+
.filter(
29+
(track: string) =>
30+
validTracks.includes(track) && !tracksInOrder.includes(track)
31+
);
32+
33+
tracksInOrder.push(...otherTracks);
34+
35+
return tracksInOrder;
36+
}
37+
}
38+
39+
export default async function csvAlgorithm() {
40+
const csvFilePath = 'app/(api)/_data/2024_data.csv';
41+
42+
try {
43+
const parsePromise = new Promise<parsedRecord[]>((resolve, reject) => {
44+
const output: parsedRecord[] = [];
45+
46+
fs.createReadStream(csvFilePath)
47+
.pipe(csv())
48+
.on('data', (data) => {
49+
if (data['Table Number'] !== '') {
50+
const track1 =
51+
data[
52+
'From The Tracks You Have Selected (Upto 4 Tracks) Please Choose The Top 2 Prize Tracks.'
53+
].trim();
54+
const track2 =
55+
data[
56+
'Choose The Second Prize Track From Your Top 2 Prize Tracks.'
57+
].trim();
58+
59+
const tracksInOrder: string[] = sortTracks(
60+
track1,
61+
track2,
62+
data['Opt-In Prizes']
63+
);
64+
65+
output.push({
66+
name: data['Project Title'],
67+
number: parseInt(data['Table Number']),
68+
tracks: tracksInOrder,
69+
});
70+
}
71+
})
72+
.on('end', () => {
73+
resolve(output);
74+
})
75+
.on('error', (error) => reject(error));
76+
});
77+
78+
const results = await parsePromise;
79+
80+
return NextResponse.json({ ok: true, body: results, error: null });
81+
} catch (e) {
82+
const error = e as Error;
83+
return NextResponse.json({ ok: false, body: null, error: error.message });
84+
}
85+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.form{
2+
display: flex;
3+
flex-direction: column;
4+
padding: 16px 0px;
5+
gap: 8px;
6+
}

app/(pages)/judges/admin/csv/page.tsx

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use client';
2+
import ingestCSV from '@actions/logic/ingestCSV';
3+
import React, { useState } from 'react';
4+
import uploadFile from '@actions/logic/uploadFile';
5+
import styles from './csv.module.scss';
6+
7+
export default function CsvIngestion() {
8+
const [pending, setPending] = useState(false);
9+
const [response, setResponse] = useState('');
10+
const [uploadRes, setUploadRes] = useState('');
11+
12+
const handleIngestion = async () => {
13+
setPending(true);
14+
const res = await ingestCSV();
15+
setResponse(JSON.stringify(res));
16+
setPending(false);
17+
};
18+
19+
const handleUpload = async (event: React.FormEvent<HTMLFormElement>) => {
20+
event.preventDefault();
21+
const formData = new FormData(event.currentTarget);
22+
const res = await uploadFile(formData);
23+
setUploadRes(JSON.stringify(res));
24+
};
25+
26+
return (
27+
<div>
28+
<div>
29+
<h4>Upload CSV:</h4>
30+
<form onSubmit={handleUpload} className={styles.form}>
31+
<input type="file" accept=".csv" name="file" id="file" />
32+
<button type="submit">Upload</button>
33+
<p>{uploadRes}</p>
34+
</form>
35+
<h4>Create Teams:</h4>
36+
<button onClick={handleIngestion}>Start CSV Ingestion</button>
37+
<p>{pending ? 'creating teams...' : response}</p>
38+
</div>
39+
</div>
40+
);
41+
}

package-lock.json

Lines changed: 21 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
"@mui/material": "^5.15.4",
2222
"bcryptjs": "^2.4.3",
2323
"crypto": "^1.0.1",
24+
"csv-parse": "^5.5.5",
25+
"csv-parser": "^3.0.0",
2426
"font-awesome-icons": "^1.6.0",
2527
"js-cookie": "^3.0.5",
2628
"jsonwebtoken": "^9.0.2",

0 commit comments

Comments
 (0)