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

Feat/get teams #68

Merged
merged 13 commits into from
Apr 25, 2024
11 changes: 11 additions & 0 deletions app/(api)/_actions/logic/ingestCSV.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
'use server';

import { CreateManyTeams } from '@datalib/teams/createTeams';
import csvAlgorithm from '@utils/csv-ingestion/csvAlgorithm';

export default async function ingestCSV() {
const parsedData = await (await csvAlgorithm()).json();

const res = await (await CreateManyTeams(parsedData.body)).json();
return { ok: res.ok, error: res.error };
}
28 changes: 28 additions & 0 deletions app/(api)/_actions/logic/uploadFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use server';
import fs from 'fs';

export default async function uploadFile(formData: FormData) {
const file = formData.get('file') as File;
const data = await file.arrayBuffer();
return new Promise((resolve, rejects) => {
fs.writeFile(
'app/(api)/_data/2024_data.csv',
Buffer.from(data),
(error) => {
if (error) {
rejects({
ok: false,
body: null,
error: error?.message,
});
} else {
resolve({
ok: true,
body: `Successfully uploaded.`,
error: null,
});
}
}
);
});
}
5 changes: 5 additions & 0 deletions app/(api)/_data/2024_data.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
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,...
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

blah blah blah
",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
3,997 changes: 3,997 additions & 0 deletions app/(api)/_data/test_projects_2023.csv

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/(api)/_data/tracks.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
"type": "tech"
},
{
"name": "Best .Tech Domain Name",
"name": "Best Use of .Tech Domain Name",
"weights": [0.35, 0.25, 0.05, 0.25, 0.1],
"type": "tech"
},
Expand Down
3 changes: 1 addition & 2 deletions app/(api)/_schema/Team.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ const Team = {
},
tracks: {
bsonType: 'array',
minItems: 4,
maxItems: 5,
maxItems: 4,
items: {
enum: tracks.map((track) => track.name),
description: 'track must be one of the valid tracks',
Expand Down
85 changes: 85 additions & 0 deletions app/(api)/_utils/csv-ingestion/csvAlgorithm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import * as fs from 'fs';
import csv from 'csv-parser';
import { NextResponse } from 'next/server';
import trackData from '../../_data/tracks.json' assert { type: 'json' };

const validTracks: string[] = trackData
.map((track: track) => track.name)
.filter((t) => t !== 'Best Hack for Social Good');

interface parsedRecord {
name: string;
number: number;
tracks: string[];
}

interface track {
name: string;
}

function sortTracks(track1: string, track2: string, chosentracks: string) {
const tracksInOrder: string[] = [track1, track2];
if (chosentracks.length < 2) {
return tracksInOrder;
} else {
const otherTracks = chosentracks
.split(',')
.map((track: string) => track.trim())
.filter(
(track: string) =>
validTracks.includes(track) && !tracksInOrder.includes(track)
);

tracksInOrder.push(...otherTracks);

return tracksInOrder;
}
}

export default async function csvAlgorithm() {
const csvFilePath = 'app/(api)/_data/2024_data.csv';

try {
const parsePromise = new Promise<parsedRecord[]>((resolve, reject) => {
const output: parsedRecord[] = [];

fs.createReadStream(csvFilePath)
.pipe(csv())
.on('data', (data) => {
if (data['Table Number'] !== '') {
const track1 =
data[
'From The Tracks You Have Selected (Upto 4 Tracks) Please Choose The Top 2 Prize Tracks.'
].trim();
const track2 =
data[
'Choose The Second Prize Track From Your Top 2 Prize Tracks.'
].trim();

const tracksInOrder: string[] = sortTracks(
track1,
track2,
data['Opt-In Prizes']
);

output.push({
name: data['Project Title'],
number: parseInt(data['Table Number']),
tracks: tracksInOrder,
});
}
})
.on('end', () => {
resolve(output);
})
.on('error', (error) => reject(error));
});

const results = await parsePromise;

return NextResponse.json({ ok: true, body: results, error: null });
} catch (e) {
const error = e as Error;
return NextResponse.json({ ok: false, body: null, error: error.message });
}
}
6 changes: 6 additions & 0 deletions app/(pages)/judges/admin/csv/csv.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.form{
display: flex;
flex-direction: column;
padding: 16px 0px;
gap: 8px;
}
41 changes: 41 additions & 0 deletions app/(pages)/judges/admin/csv/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use client';
import ingestCSV from '@actions/logic/ingestCSV';
import React, { useState } from 'react';
import uploadFile from '@actions/logic/uploadFile';
import styles from './csv.module.scss';

export default function CsvIngestion() {
const [pending, setPending] = useState(false);
const [response, setResponse] = useState('');
const [uploadRes, setUploadRes] = useState('');

const handleIngestion = async () => {
setPending(true);
const res = await ingestCSV();
setResponse(JSON.stringify(res));
setPending(false);
};

const handleUpload = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const res = await uploadFile(formData);
setUploadRes(JSON.stringify(res));
};

return (
<div>
<div>
<h4>Upload CSV:</h4>
<form onSubmit={handleUpload} className={styles.form}>
<input type="file" accept=".csv" name="file" id="file" />
<button type="submit">Upload</button>
<p>{uploadRes}</p>
</form>
<h4>Create Teams:</h4>
<button onClick={handleIngestion}>Start CSV Ingestion</button>
<p>{pending ? 'creating teams...' : response}</p>
</div>
</div>
);
}
22 changes: 21 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
"@mui/material": "^5.15.4",
"bcryptjs": "^2.4.3",
"crypto": "^1.0.1",
"csv-parse": "^5.5.5",
"csv-parser": "^3.0.0",
"font-awesome-icons": "^1.6.0",
"js-cookie": "^3.0.5",
"jsonwebtoken": "^9.0.2",
Expand Down