diff --git a/src/index.ts b/src/index.ts index 5de9802b..7df81146 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import 'reflect-metadata'; +const path = require('path'); import * as express from 'express'; import * as dotenv from 'dotenv'; import { createConnection } from 'typeorm'; @@ -16,6 +17,7 @@ import { cohortRoutes, matchMakingRoutes, battlesRoutes, + versusRoutes, } from './routes'; import { connection } from './util/typeorm-connection'; import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions'; @@ -31,7 +33,8 @@ const main = async () => { const app = express(); globalMiddleware(app); - + app.use(express.static(path.join(__dirname, '../', 'public'))); + app; app.use('/admin', adminRoutes); app.use('/auth', authRoutes); app.use('/canon', CheckJwt(), canonRoutes); @@ -41,6 +44,7 @@ const main = async () => { app.use('/payment', CheckJwt(), UpdateStripeRecords(), stripeRoutes); app.use('/matchmaking', CheckJwt(), matchMakingRoutes); app.use('/battlesRoutes', CheckJwt(), battlesRoutes); + app.use('/versusRoutes', CheckJwt(), versusRoutes); app.use('/storyRoutes', CheckJwt(), storyRoutes); app.use('/illustrationRoutes', CheckJwt(), illustrationRoutes); diff --git a/src/routes/battles/battles.routes.ts b/src/routes/battles/battles.routes.ts index ca12dfef..4b6e6c10 100644 --- a/src/routes/battles/battles.routes.ts +++ b/src/routes/battles/battles.routes.ts @@ -10,52 +10,237 @@ import { connection } from '../../util/typeorm-connection'; const battlesRoutes = Router(); battlesRoutes.get('/battles', Only(Child), async (req, res) => { + // try { + // const { id, cohort, username, avatar, stories, illustrations } = req.user as Child; + // //first get matchid so we know who this child is up against + // const match = await returnMatch(id, cohort.week); + // let thisMatch = { + // matchId: match.id, + // week: cohort.week, + // team: { + // student: { + // studentId: id, + // username: username, + // avatar: avatar, + // story: {}, + // illustration: {}, + // }, + // teammate: {}, + // }, + // }; + // let teammate = null; + // if (!match) { + // res.json(401).json({ + // message: `Match for Student ID ${id}, for week ${cohort.week} not found`, + // }); + // } else { + // { + // match.team1_child1_id === id + // ? (teammate = match.team1_child2_id) + // : match.team1_child2_id === id + // ? (teammate = match.team1_child1_id) + // : match.team2_child1_id === id + // ? (teammate = match.team2_child2_id) + // : (teammate = match.team2_child1_id); + // } + // console.log(`student: ${thisMatch.team.student.studentId}, teammate: ${teammate}`); + // const [story] = stories.filter((el) => el.week === cohort.week); + // const [illustration] = illustrations.filter((el) => el.week === cohort.week); + // thisMatch.team.student = { + // ...thisMatch.team.student, + // // replacing story and illustration objects as empty strings to avoid sending base64 04/2020 + // story: story, + // illustration: illustration, + // }; + // thisMatch.team.teammate = await getCustomRepository( + // MatchInfoRepository, + // connection() + // ).findStudentInfo(teammate, cohort.week); + // // thisMatch.team.teammate = await getCustomRepository(MatchInfoRepository,) + // // previous syntax structure commented out below 3.12.20 + // // new syntax structure (yet to be tested) 3.18.20 + // } + // return res.status(200).json({ + // thisMatch, + // }); + // } catch (err) { + // console.log(err.toString()); + // return res.status(500).json({ message: err.toString() }); + // } + // }); + try { const { id, cohort, username, avatar, stories, illustrations } = req.user as Child; //first get matchid so we know who this child is up against const match = await returnMatch(id, cohort.week); + console.log(`MATCH loc18`, match); + + // populate home team object(s) + let student = null; + let teammate = null; - let thisMatch = { + let homeTeam = { matchId: match.id, week: cohort.week, - team: { - student: { - studentId: id, - username: username, - avatar: avatar, - story: {}, - illustration: {} - }, - teammate: {} + student: { + studentId: id, + username: username, + avatar: avatar, + story: {}, + storyPoints: null, + illustration: {}, + illustrationPoints: null, }, + teammate: {}, + }; + console.log('homeTeam', homeTeam); + + // populate away team object(s) + let opponentA = null; + let opponentB = null; + + let awayTeam = { + matchId: match.id, + week: cohort.week, + opponentA: {}, + opponentB: {}, }; - let teammate = null + if (!match) { res.json(401).json({ message: `Match for Student ID ${id}, for week ${cohort.week} not found`, }); } else { - - { - match.team1_child1_id === id ? teammate = match.team1_child2_id : - match.team1_child2_id === id ? teammate = match.team1_child1_id : - match.team2_child1_id === id ? teammate = match.team2_child2_id : teammate = match.team2_child1_id + { + if (match.team1_child1_id === id) { + teammate = match.team1_child2_id; + opponentA = match.team2_child1_id; + opponentB = match.team2_child2_id; + } else if (match.team1_child2_id === id) { + teammate = match.team1_child1_id; + opponentA = match.team2_child1_id; + opponentB = match.team2_child2_id; + } else if (match.team2_child1_id === id) { + teammate = match.team2_child2_id; + opponentA = match.team1_child1_id; + opponentB = match.team1_child2_id; + } else { + teammate = match.team2_child1_id; + opponentA = match.team1_child1_id; + opponentB = match.team1_child2_id; + } } - console.log(`student: ${thisMatch.team.student.studentId}, teammate: ${teammate}`) - const [ story ] = stories.filter(el => el.week === cohort.week) - const [ illustration ] = illustrations.filter(el => el.week === cohort.week) - thisMatch.team.student = { ...thisMatch.team.student, story: story, illustration: illustration} - thisMatch.team.teammate = await getCustomRepository(MatchInfoRepository, connection()).findStudentInfo(teammate, cohort.week) + console.log(`student: ${homeTeam.student.studentId}, teammate: ${teammate}`); + console.log('teammate', homeTeam.teammate); + // find CCS and point values + const [story] = stories.filter((el) => el.week === cohort.week); + homeTeam.student.story = story; + const [illustration] = illustrations.filter((el) => el.week === cohort.week); + homeTeam.student.illustration = illustration; + + homeTeam.teammate = await getCustomRepository( + MatchInfoRepository, + connection() + ).findStudentInfo(teammate, cohort.week); + // thisMatch.team.teammate = await getCustomRepository(MatchInfoRepository,) // previous syntax structure commented out below 3.12.20 // new syntax structure (yet to be tested) 3.18.20 - } - return res.status(200).json({ - thisMatch, - }); + awayTeam.opponentA = await getCustomRepository( + MatchInfoRepository, + connection() + ).findStudentInfo(opponentA, cohort.week); + + awayTeam.opponentB = await getCustomRepository( + MatchInfoRepository, + connection() + ).findStudentInfo(opponentB, cohort.week); + } + ////////////////////////////////////////////////// + const myTeam = [ + { + me: { + id, + storyPoints: homeTeam.student.story.points, + illustrationPoints: homeTeam.student.illustration.points, + }, + }, + { + teammate: { + id: homeTeam.teammate.studentId, + storyPoints: homeTeam.teammate.story.points, + illustrationPoints: homeTeam.teammate.illustration.points, + }, + }, + ]; + + const team2 = [ + { + opponentA: { + id: awayTeam.opponentA.studentId, + storyPoints: awayTeam.opponentA.story.points, + illustrationPoints: awayTeam.opponentA.illustration.points, + }, + }, + { + opponentB: { + id: awayTeam.opponentB.studentId, + storyPoints: awayTeam.opponentB.story.points, + illustrationPoints: awayTeam.opponentB.illustration.points, + }, + }, + ]; + console.log('myTeam', myTeam); + console.log('team2', team2); + const higherMyteam = decideHigher(myTeam[0].me, myTeam[1].teammate); + // array of arrays returned by decideHighter [[storypoint high, storypoint low], [illustrationpoint high, illustrationpoint low]] + console.log('higherMytem', higherMyteam); + + const higherTeam2 = decideHigher(team2[0].opponentA, team2[1].opponentB); + console.log('higherTeam2', higherTeam2); + + //storyHigh = [higherMyteam in Story, higherTeam2 in Story, total points] + const storyHigh = [higherMyteam[0][0], higherTeam2[0][0]]; + storyHigh.push(higherMyteam[0][0].storyPoints + higherTeam2[0][0].storyPoints); + console.log('storyHigh', storyHigh); + + //storyLow = [LowerMyteam in Story, LowerTeam2 in Story, total points] + const storyLow = [higherMyteam[0][1], higherTeam2[0][1]]; + storyLow.push(higherMyteam[0][1].storyPoints + higherTeam2[0][1].storyPoints); + console.log('storyLow', storyLow); + + //illustrationHigh = [higherMyteam in illustration, higherTeam2 in illustration, total points] + const illustrationHigh = [higherMyteam[1][0], higherTeam2[1][0]]; + illustrationHigh.push( + higherMyteam[1][0].illustrationPoints + higherTeam2[1][0].illustrationPoints + ); + console.log('illustrationHigh', illustrationHigh); + + //illustrationLow = [lowerMyteam in illustration, lowerTeam2 in illustration, total points] + const illustrationLow = [higherMyteam[1][1], higherTeam2[1][1]]; + illustrationLow.push( + higherMyteam[1][1].illustrationPoints + higherTeam2[1][1].illustrationPoints + ); + console.log('illustrationLow', illustrationLow); + + const thisBattle = { + storyHigh, + storyLow, + illustrationHigh, + illustrationLow, + }; + + console.log('thisBattle', thisBattle); + + const thisMatch = { + team: homeTeam, + otherTeam: awayTeam, + }; + + return res.status(200).json({ thisMatch, thisBattle }); } catch (err) { console.log(err.toString()); return res.status(500).json({ message: err.toString() }); @@ -64,45 +249,48 @@ battlesRoutes.get('/battles', Only(Child), async (req, res) => { battlesRoutes.put('/battles', Only(Child), async (req, res) => { try { - const { id, progress } = req.user as Child; - if (progress.teamReview === true) { + console.log('progress.teamReview', progress.teamReview); return res.status(400).json({ - message: `Cannot submit points twice` - }) + message: `Cannot submit points twice`, + }); } + const { stories, illustrations } = req.body; - const { stories, illustrations } = req.body - try { - await Promise.all(stories.map(el => { - getRepository(Stories, connection()) - .findOne({ id: el.id }) - .then( async (res) => { - await getRepository(Stories, connection()) - .update({ id: el.id}, { points: res.points + el.points}) + await Promise.all( + stories.map((el) => { + getRepository(Stories, connection()) + .findOne({ id: el.id }) + .then(async (res) => { + await getRepository(Stories, connection()).update( + { id: el.id }, + { points: res.points + el.points } + ); + }); }) - })) - } catch(err) { - res.status(400).json({ message: `Story failed`}) + ); + } catch (err) { + res.status(400).json({ message: `Story failed` }); } - try { - await Promise.all(illustrations.map(el => { - getRepository(Illustrations, connection()) - .findOne({ id: el.id }) - .then( async (res) => { - await getRepository(Illustrations, connection()) - .update({ id: el.id}, { points: res.points + el.points}) + await Promise.all( + illustrations.map((el) => { + getRepository(Illustrations, connection()) + .findOne({ id: el.id }) + .then(async (res) => { + await getRepository(Illustrations, connection()).update( + { id: el.id }, + { points: res.points + el.points } + ); + }); }) - })) - } catch(err) { - res.status(400).json({ message: 'Illustration failed' }) + ); + } catch (err) { + res.status(400).json({ message: 'Illustration failed' }); } - await getRepository(Child, connection()).update({ id }, { progress: { teamReview: true } }); - res.status(200).json({ message: 'success' }); } catch (err) { res.status(500).json({ message: err.toString() }); @@ -111,6 +299,17 @@ battlesRoutes.put('/battles', Only(Child), async (req, res) => { export { battlesRoutes }; +function decideHigher(studentA, studentB) { + const high = []; + if (studentA.storyPoints > studentB.storyPoints) high.push([studentA, studentB]); + else high.push([studentB, studentA]); + + if (studentA.illustrationPoints > studentB.illustrationPoints) high.push([studentA, studentB]); + else high.push([studentB, studentA]); + + return high; +} + async function returnMatch(id: number, week: number) { const match = await getRepository(Matches, connection()).findOne({ where: [{ team1_child1_id: id, week: week }], diff --git a/src/routes/index.ts b/src/routes/index.ts index f067f099..1752cb46 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,6 +1,6 @@ export * from './admin/admin.routes'; export * from './auth/auth.routes'; -export * from './battles/battles.routes' +export * from './battles/battles.routes'; export * from './canon/canon.routes'; export * from './child/child.routes'; export * from './cohort/cohort.routes'; @@ -9,3 +9,4 @@ export * from './stripe/stripe.routes'; export * from './story/story.routes'; export * from './illustration/illustration.routes'; export * from './matchmaking/matchmaking.routes'; +export * from './versus/versus.Routes'; \ No newline at end of file diff --git a/src/routes/matchmaking/matchmaking.routes.ts b/src/routes/matchmaking/matchmaking.routes.ts index 04014b90..42c3d3d1 100644 --- a/src/routes/matchmaking/matchmaking.routes.ts +++ b/src/routes/matchmaking/matchmaking.routes.ts @@ -29,11 +29,13 @@ matchMakingRoutes.get('/:week', Only(Admin), async (req, res) => { }); } catch (err) { console.log(err.toString()); - return res.status(500).json({ err: err.toString(), message: 'Could not fetch submissions' }); + return res + .status(500) + .json({ err: err.toString(), message: 'Could not fetch submissions' }); } let submissionObject = {}; - + for (const story of stories) { try { const [childusMinimus] = await getRepository(Child, connection()).find({ @@ -43,29 +45,31 @@ matchMakingRoutes.get('/:week', Only(Admin), async (req, res) => { const pictureCheck = await getRepository(Illustrations, connection()).find({ where: { id: childusMinimus.id, week: req.params.week }, }); - console.log(`PICTURE CHECK - id: ${story.childId}`, `length: ${pictureCheck.length}`); + console.log( + `PICTURE CHECK - id: ${story.childId}`, + `length: ${pictureCheck.length}` + ); // if picture is present, perform DS matchmaking - if (pictureCheck.length){ - submissionObject = { - - ...submissionObject, - [story.childId]: { - flesch_reading_ease: story.flesch_reading_ease, - smog_index: story.smog_index, - flesch_kincaid: story.flesch_kincaid_grade, - coleman_liau_index: story.coleman_liau_index, - automated_readability_index: story.automated_readability_index, - dale_chall_readability_score: story.dale_chall_readability_score, - difficult_words: story.difficult_words, - linsear_write_formula: story.linsear_write_formula, - gunning_fog: story.gunning_fog, - doc_length: story.doc_length, - quote_count: story.quote_count, - grade: childusMinimus.grade, - }, - }; - } + if (pictureCheck.length) { + submissionObject = { + ...submissionObject, + [story.childId]: { + flesch_reading_ease: story.flesch_reading_ease, + smog_index: story.smog_index, + flesch_kincaid: story.flesch_kincaid_grade, + coleman_liau_index: story.coleman_liau_index, + automated_readability_index: story.automated_readability_index, + dale_chall_readability_score: story.dale_chall_readability_score, + difficult_words: story.difficult_words, + linsear_write_formula: story.linsear_write_formula, + gunning_fog: story.gunning_fog, + doc_length: story.doc_length, + quote_count: story.quote_count, + grade: childusMinimus.grade, + }, + }; + } } catch (err) { console.log(err.toString()); return res.status(500).json({ @@ -89,7 +93,7 @@ matchMakingRoutes.get('/:week', Only(Admin), async (req, res) => { try { for (let [key, value] of Object.entries(competition)) { const existingMatch = await checkTeams(value); - if (existingMatch[0] && existingMatch[1] && existingMatch[2] && existingMatch[3]) { + if (existingMatch[0]) { await persistMatch(value, thisWeek); } else { console.log('matches pre-existing'); @@ -188,7 +192,7 @@ async function checkTeams(value) { } catch (err) { console.log(err.toString()); } - console.log(`CHECK TEAMS`, existingMatch) + console.log(`CHECK TEAMS`, existingMatch); return existingMatch; } diff --git a/src/routes/versus/assignRole.ts b/src/routes/versus/assignRole.ts new file mode 100644 index 00000000..58f7a30c --- /dev/null +++ b/src/routes/versus/assignRole.ts @@ -0,0 +1,15 @@ +function assignRole(higherTeam, team) { + if (higherTeam[0][0].role === 'student' && higherTeam[1][0].role === 'student') { + team.student.storyRole = 'storyHigh'; + team.teammate.storyRole = 'storyLow'; + team.student.illustrationRole = 'illustrationHigh'; + team.teammate.illustrationRole = 'illustrationLow'; + } else { + team.student.storyRole = 'storyLow'; + team.teammate.storyRole = 'storyHigh'; + team.student.illustrationRole = 'illustrationLow'; + team.teammate.illustrationRole = 'illustrationHigh'; + } +} + +export { assignRole }; diff --git a/src/routes/versus/child.imageParse.ts b/src/routes/versus/child.imageParse.ts new file mode 100644 index 00000000..6dd95691 --- /dev/null +++ b/src/routes/versus/child.imageParse.ts @@ -0,0 +1,51 @@ +const fs = require('fs'); +const path = require('path'); + +const storyParse = (person, stories) => { + const { page1, page2, page3 } = stories; + const stories1 = { + page1, + page2, + page3, + }; + // console.log('stories1', stories); + const myStories = { + page1: '', + page2: '', + page3: '', + }; + + for (let key in stories1) { + if (stories1[key]) { + const contents = stories1[key].split(',')[1]; + // const contents = stories[key]; + fs.writeFile( + path.join(__dirname, '../../../', 'public', `story_${person}_${key}.jpg`), + contents, + 'base64', + (err) => { + if (err) throw err; + console.log(`public/story_${person}_${key}.jpg file saved`); + } + ); + myStories[key] = `story_${person}_${key}.jpg`; + } + } + return myStories; +}; + +const illustrationParse = (person, image) => { + const contents = image.split(',')[1]; + + fs.writeFile( + path.join(__dirname, '../../../', 'public', `${person}_illustration.jpg`), + contents, + 'base64', + (err) => { + if (err) throw err; + console.log(`public/{person}_illustration.jpg file saved`); + } + ); + return `${person}_illustration.jpg`; +}; +export { storyParse, illustrationParse }; diff --git a/src/routes/versus/createStudent.ts b/src/routes/versus/createStudent.ts new file mode 100644 index 00000000..434363cd --- /dev/null +++ b/src/routes/versus/createStudent.ts @@ -0,0 +1,10 @@ +function createStudent(team, story, illustration) { + team.student.story = story.story; + team.student.storyPoints = story.points; + team.student.illustration = illustration.illustration; + team.student.illustrationPoints = illustration.points; + team.student.role = 'student'; + return team.student; +} + +export { createStudent }; diff --git a/src/routes/versus/createTeam.ts b/src/routes/versus/createTeam.ts new file mode 100644 index 00000000..c8044a22 --- /dev/null +++ b/src/routes/versus/createTeam.ts @@ -0,0 +1,36 @@ +function createTeam(team, member) { + if (getObjectClass(team) === 'awayTeam' && getObjectClass(member) === 'opponentA') { + return { + ...team.student, + ...member, + role: getObjectClass(member), + }; + } else if (getObjectClass(team) === 'awayTeam' && getObjectClass(member) === 'opponentB') { + return { + ...team.teammate, + ...member, + role: getObjectClass(member), + }; + } else { + return { + ...team['member'], + ...member, + role: propName(team, member), + }; + } +} + +function getObjectClass(obj) { + if (typeof obj != 'object' || obj === null) return false; + else return /(\w+)\(/.exec(obj.constructor.toString())[1]; +} + +function propName(prop, value) { + for (var i in prop) { + if (prop[i] == value) { + return i; + } + } + return false; +} +export { createTeam }; diff --git a/src/routes/versus/custom.ts b/src/routes/versus/custom.ts new file mode 100644 index 00000000..189dfdaf --- /dev/null +++ b/src/routes/versus/custom.ts @@ -0,0 +1,68 @@ +import { EntityRepository, EntityManager } from 'typeorm'; + +import { Child, Stories, Illustrations } from '../../database/entity'; + +@EntityRepository() +export class MatchInfoRepository { + constructor(private manager: EntityManager) {} + + async findStudentInfo(studentId: number, week: number) { + const thisStudent = this.manager.findOne(Child, { + where: { id: studentId }, + }); + const thisStory = this.manager.findOne(Stories, { + where: { childId: studentId, week: week }, + }); + const thisIllustration = this.manager.findOne(Illustrations, { + where: { childId: studentId, week: week }, + }); + //line 13-21 should run concurrently and all the promises should be resolved in line 23 + const [child, story, illustration] = await Promise.all([ + thisStudent, + thisStory, + thisIllustration, + ]); + + return { + studentId: studentId, + username: child.username, + avatar: child.avatar, + // replacing story and illustration objects as empty strings to avoid sending base64 4/13/2020 + story: story.story, + storyPoints: story.points, + illustration: illustration.illustration, + illustrationPoints: illustration.points, + }; + } + async updatePoints( + storyId: number, + storyPoints: number, + drawingId: number, + drawingPoints: number + ) { + // console logs below were left due to a merge conflict from put-battles-fixed branch + // const story = await this.manager.findOne(Stories, { where: { id: storyId } }) + // const drawing = await this.manager.findOne(Illustrations, { where: { id: drawingId } }) + + // console.log('story points', story.points) + // console.log('drawing points', drawing.points) + + const storyPromise = this.manager.findOne(Stories, { where: { id: storyId } }); + const drawingPromise = this.manager.findOne(Illustrations, { where: { id: drawingId } }); + const [story, drawing] = await Promise.all([storyPromise, drawingPromise]); + + // replaced () => points + storyPoints with story.points + storyPoints 4.1.20 + const storyUpdate = this.manager.update( + Stories, + { where: { id: storyId } }, + { points: story.points + storyPoints } + ); + const illustrationUpdate = this.manager.update( + Illustrations, + { where: { id: drawingId } }, + { points: drawing.points + drawingPoints } + ); + + return await Promise.all([storyUpdate, illustrationUpdate]); + } +} diff --git a/src/routes/versus/matchVersusPlayers.ts b/src/routes/versus/matchVersusPlayers.ts new file mode 100644 index 00000000..d1ed1471 --- /dev/null +++ b/src/routes/versus/matchVersusPlayers.ts @@ -0,0 +1,31 @@ +function matchVersusPlayers(teamA, teamB) { + if (teamA.student.subjecRole === teamB.student.storyRole) { + teamA.student.storyOpponent = teamB.student; + teamA.teammate.storyOpponent = teamB.teammate; + teamA.student.storyTotal = teamA.student.storyPoints + teamB.student.storyPoints; + teamA.teammate.storyTotal = teamA.teammate.storyPoints + teamB.teammate.storyPoints; + } else { + teamA.student.storyOpponent = teamB.teammate; + teamA.teammate.storyOpponent = teamB.student; + teamA.student.storyTotal = teamA.student.storyPoints + teamB.teammate.storyPoints; + teamA.teammate.storyTotal = teamA.teammate.storyPoints + teamB.student.storyPoints; + } + + if (teamA.student.illustrationRole === teamB.student.illustrationRole) { + teamA.student.illustrationOpponent = teamB.student; + teamA.teammate.illustrationOpponent = teamB.teammate; + teamA.student.illustrationTotal = + teamA.student.illustrationPoints + teamB.student.illustrationPoints; + teamA.teammate.illustrationTotal = + teamA.teammate.illustrationPoints + teamB.teammate.illustrationPoints; + } else { + teamA.student.illustrationOpponent = teamB.teammate; + teamA.teammate.illustrationOpponent = teamB.student; + teamA.student.illustrationTotal = + teamA.student.illustrationPoints + teamB.teammate.illustrationPoints; + teamA.teammate.illustrationTotal = + teamA.teammate.illustrationPoints + teamB.student.illustrationPoints; + } +} + +export { matchVersusPlayers }; diff --git a/src/routes/versus/team.class.ts b/src/routes/versus/team.class.ts new file mode 100644 index 00000000..f1986ba6 --- /dev/null +++ b/src/routes/versus/team.class.ts @@ -0,0 +1,69 @@ +interface Team { + matchId: Number; + week: Number; + student: student; + teammate: student; +} + +interface student { + studentId: number; + username: string; + avatar: string; + story: story; + storyPoints: number; + illustration: string; + illustrationPoints: string | any; + role?: string; + storyRole?: string; + illustrationRole?: string; + storyOpponent?: student; + illustrationOpponent?: student; + storyTotal?: number; + illustrationTotal?: number; +} + +interface story { + page1: String; + page2?: String; + page3?: String; +} + +class Team { + constructor(matchId: Number, cohortWeek: Number) { + this.matchId = matchId; + this.student = { + studentId: null, + username: null, + avatar: null, + story: null, + storyPoints: null, + illustration: null, + illustrationPoints: null, + role: null, + storyRole: null, + illustrationRole: null, + storyOpponent: null, + illustrationOpponent: null, + storyTotal: null, + illustrationTotal: null, + }; + this.teammate = { + studentId: null, + username: null, + avatar: null, + story: null, + storyPoints: null, + illustration: null, + illustrationPoints: null, + role: null, + storyRole: null, + illustrationRole: null, + storyOpponent: null, + illustrationOpponent: null, + storyTotal: null, + illustrationTotal: null, + }; + } +} + +export { Team }; diff --git a/src/routes/versus/team.type.ts b/src/routes/versus/team.type.ts new file mode 100644 index 00000000..f2ce6dd4 --- /dev/null +++ b/src/routes/versus/team.type.ts @@ -0,0 +1,35 @@ +interface Team { + matchId: Number; + week: Number; + student: student; + teammate: student; +} + +interface student { + studentId: Number; + username: String; + avatar: String; + story: story; + storyPoints: Number; + illustration: Object; + illustrationPoints: String; + role: String; + storyRole: String; + illustrationRole: illustration; + storyOpponent: Object; + illustrationOpponent: Object; + storyTotal?: Number; + illustrationTotal?: Number; +} + +interface story { + page1: String; + page2?: String; + page3?: String; +} + +interface illustration { + illustration: String; +} + +export { Team }; diff --git a/src/routes/versus/versus.Routes.ts b/src/routes/versus/versus.Routes.ts new file mode 100644 index 00000000..5c1969a6 --- /dev/null +++ b/src/routes/versus/versus.Routes.ts @@ -0,0 +1,126 @@ +import { Router } from 'express'; +import { getCustomRepository } from 'typeorm'; +import { Team } from './team.class'; +import { Child } from '../../database/entity'; +import { MatchInfoRepository } from './custom'; +import { Only } from '../../middleware/only/only.middleware'; +import { connection } from '../../util/typeorm-connection'; +import e = require('express'); +import { decideHigher, returnMatch } from './versusRoutes.functions'; +import { assignRole } from './assignRole'; +import { matchVersusPlayers } from './matchVersusPlayers'; +import { createTeam } from './createTeam'; +import { createStudent } from './createStudent'; + +const versusRoutes = Router(); + +versusRoutes.get('/versus', Only(Child), async (req, res) => { + try { + const { id, cohort, username, avatar, stories, illustrations } = req.user as Child; + //first get matchid so we know who this child is up against + + const match = await returnMatch(id, cohort.week); + // populate home team object(s) + + // homeTeam created + const homeTeam = new Team(match.id, cohort.week); + homeTeam.student.studentId = id; + homeTeam.student.username = username; + homeTeam.student.avatar = avatar; + let student_id = null; + let teammate_id = null; + + //awayTeam created + const awayTeam = new Team(match.id, cohort.week); + let opponentA_id = null; + let opponentB_id = null; + + if (!match) { + res.json(401).json({ + message: `Match for Student ID ${id}, for week ${cohort.week} not found`, + }); + } else { + { + if (match.team1_child1_id === id) { + teammate_id = match.team1_child2_id; + opponentA_id = match.team2_child1_id; + opponentB_id = match.team2_child2_id; + } else if (match.team1_child2_id === id) { + teammate_id = match.team1_child1_id; + opponentA_id = match.team2_child1_id; + opponentB_id = match.team2_child2_id; + } else if (match.team2_child1_id === id) { + teammate_id = match.team2_child2_id; + opponentA_id = match.team1_child1_id; + opponentB_id = match.team1_child2_id; + } else { + student_id = match.team2_child2_id; + teammate_id = match.team2_child1_id; + opponentA_id = match.team1_child1_id; + opponentB_id = match.team1_child2_id; + } + } + + const [story] = stories.filter((el) => el.week === cohort.week); + const [illustration] = illustrations.filter((el) => el.week === cohort.week); + + // creation for homeTeam student + homeTeam.student = createStudent(homeTeam, story, illustration); + + const teammate = await getCustomRepository( + MatchInfoRepository, + connection() + ).findStudentInfo(teammate_id, cohort.week); + + // creation for homeTeam teammate + homeTeam.teammate = createTeam(homeTeam, teammate); + + const opponentA = await getCustomRepository( + MatchInfoRepository, + connection() + ).findStudentInfo(opponentA_id, cohort.week); + + // creation for awayTeam student + awayTeam.student = createTeam(awayTeam, opponentA); + + const opponentB = await getCustomRepository( + MatchInfoRepository, + connection() + ).findStudentInfo(opponentB_id, cohort.week); + + // creation for awayTeam teammate + awayTeam.teammate = createTeam(awayTeam, opponentB); + } + // createTeam(awayTeam, opponentB); + // who is higher in story and illustration points between student and teammate in homeTeam? + // array of array returned by decideHighter [[storypoint high, storypoint low], [illustrationpoint high, illustrationpoint low]] + const higherMyteam = decideHigher(homeTeam.student, homeTeam.teammate); + // assign storyRole and illustrationRole to student and teammate in homeTeam + assignRole(higherMyteam, homeTeam); + + // who is higher in story and illustration points between opponentA and opponentB in awayTeam? + const higherTeam2 = decideHigher(awayTeam.student, awayTeam.teammate); + // assign storyRole and illustrationRole to opponentA and opponentB in awayTeam + assignRole(higherTeam2, awayTeam); + + // matching players for student and teammate with players in opponent team + matchVersusPlayers(homeTeam, awayTeam); + + const thisBattle = { + battleInfo: { + student: { + ...homeTeam.student, + }, + teammate: { + ...homeTeam.teammate, + }, + }, + }; + + return res.status(200).json(thisBattle); + } catch (err) { + return res.status(500).json({ message: err.toString() }); + } +}); + +export { versusRoutes }; diff --git a/src/routes/versus/versusImage.ts b/src/routes/versus/versusImage.ts new file mode 100644 index 00000000..8755c975 --- /dev/null +++ b/src/routes/versus/versusImage.ts @@ -0,0 +1,261 @@ +import { Router } from 'express'; + +import { getRepository } from 'typeorm'; +import { sign } from 'jsonwebtoken'; + +import { Parent, Child, Stories } from '../../database/entity'; +import { Only } from '../../middleware'; +import { connection } from '../../util/typeorm-connection'; +import { storyParse, illustrationParse } from './child.imageParse'; + +import { Cohort } from '../../database/entity/Cohort'; + +const childRoutes = Router(); + +childRoutes.get('/me', Only(Child), async (req, res) => { + try { + const { parent, ...me1 } = req.user as Child; + + // const myStory = me1.stories[0]; + // console.log('myStory', myStory); + // let myStoryPages = null; + + // if (me1.stories[0]) myStoryPages = storyParse(me1.stories[0].story); + + // let myIllustration = null; + + // if (me1.illustrations[0]) + // myIllustration = illustrationParse(me1.illustrations[0].illustration); + // console.log('myStoryPages', illustrationParse(myIllustration)); + const me = { + ...me1, + stories: [ + { + ...me1.stories[0], + story: me1.stories[0] && storyParse(me1.stories[0].story), + }, + ], + illustrations: [ + { + ...me1.illustrations[0], + illustration: + me1.illustrations[0] && + illustrationParse(me1.illustrations[0].illustration), + }, + ], + }; + res.json({ me }); + } catch (err) { + res.status(500).json({ + message: 'Hmm... That did not work, please try again later.', + }); + } +}); + +childRoutes.get('/preferences', Only(Child), async (req, res) => { + try { + const { preferences } = req.user as Child; + res.json({ preferences }); + } catch (err) { + res.status(500).json({ + message: 'Hmm... That did not work, please try again later.', + }); + } +}); + +childRoutes.get('/cohort', Only(Child), async (req, res) => { + try { + const { cohort } = req.user as Child; + res.json({ cohort }); + } catch (err) { + res.status(500).json({ + message: 'Hmm... That did not work, please try again later.', + }); + } +}); + +childRoutes.get('/progress', Only(Child), async (req, res) => { + try { + const { progress } = req.user as Child; + console.log(progress); + res.json({ progress }); + } catch (err) { + console.log(err.toString()); + res.status(500).json({ + message: 'Hmm... That did not work, please try again later.', + }); + } +}); + +childRoutes.post('/progress', Only(Child), async (req, res) => { + try { + const child = req.user as Child; + const { progress } = await getRepository(Child, connection()).save({ + ...child, + progress: { + ...child.progress, + ...req.progressUpdate, + }, + }); + res.json({ progress }); + } catch (err) { + res.status(500).json({ + message: 'Hmm... That did not work, please try again later.', + }); + } +}); + +childRoutes.get('/parent', Only(Child), async (req, res) => { + try { + const { + parent: { password, ...parent }, + } = req.user as Child; + + res.json({ parent }); + } catch (err) { + res.status(500).json({ + message: 'Hmm... That did not work, please try again later.', + }); + } +}); + +childRoutes.post('/:id/login', Only(Parent), async (req, res) => { + try { + const children = (req.user as Parent).children; + const child = children.find((child) => child.id === Number(req.params.id)); + if (!child) throw new Error('404'); + + const token = sign( + { parentID: req.user.id, childID: child.id, subscription: child.subscription }, + process.env.SECRET_SIGNATURE || 'secret' + ); + + res.json({ token }); + } catch (err) { + switch (err.toString()) { + case 'Error: 404': + res.status(404).json({ message: 'Child not found!' }); + break; + default: + res.status(500).json({ + message: 'Hmm... That did not work, please try again later.', + }); + break; + } + } +}); + +childRoutes.get('/list', Only(Parent), async (req, res) => { + try { + const children = (req.user as Parent).children; + children.sort((a, b) => a.id - b.id); + res.json({ children }); + } catch (err) { + res.status(500).json({ + message: 'Hmm... That did not work, please try again later.', + }); + } +}); + +childRoutes.post('/list', Only(Parent), async (req, res) => { + try { + const cohort = await getRepository(Cohort, connection()).findOne({ order: { id: 'DESC' } }); + if (!cohort) throw new Error('No Cohort'); + + const { parent, ...child } = await getRepository(Child, connection()).save({ + ...req.childUpdate, + cohort, + parent: req.user, + }); + + res.status(201).json({ child }); + } catch (err) { + if (err.toString() === 'Error: No Cohort') + res.status(500).json({ + message: 'Please contact an Admin to setup a Cohort for your Child.', + }); + res.status(500).json({ + message: 'Hmm... That did not work, please try again later.', + }); + } +}); + +childRoutes.get('/list/:id', Only(Parent), async (req, res) => { + try { + const children = (req.user as Parent).children; + const child = children.find((child) => child.id === Number(req.params.id)); + + if (!child) throw new Error('404'); + res.json({ child }); + } catch (err) { + switch (err.toString()) { + case 'Error: 404': + res.status(404).json({ message: 'Child not found!' }); + break; + default: + res.status(500).json({ + message: 'Hmm... That did not work, please try again later.', + }); + break; + } + } +}); + +childRoutes.put('/list/:id', Only(Parent), async (req, res) => { + 1; + try { + const children = (req.user as Parent).children; + const childToUpdate = children.find((child) => child.id === Number(req.params.id)); + if (!childToUpdate) throw new Error('404'); + + const child = { ...childToUpdate, ...req.childUpdate }; + try { + const { affected } = await getRepository(Child, connection()).update( + req.params.id, + child + ); + } catch (err) { + console.log(err.toString()); + res.status(500).json({ err: err.toString(), message: 'Could not update child' }); + } + + res.json({ child }); + } catch (err) { + switch (err.toString()) { + case 'Error: 404': + res.status(404).json({ message: 'Could Not Update - Child not found!' }); + break; + default: + res.status(500).json({ + message: 'Hmm... That did not work, please try again later.', + }); + break; + } + } +}); + +childRoutes.delete('/list/:id', Only(Parent), async (req, res) => { + try { + const children = (req.user as Parent).children; + const childToDelete = children.find((child) => child.id === Number(req.params.id)); + if (!childToDelete) throw new Error('404'); + + const { affected } = await getRepository(Child, connection()).delete(childToDelete); + if (!affected) throw new Error(); + + res.json({ message: `Successfully deleted ${req.params.id}` }); + } catch (err) { + switch (err.toString()) { + case 'Error: 404': + res.status(404).json({ message: 'Could Not Delete - Child not found!' }); + break; + default: + res.status(500).json({ + message: 'Hmm... That did not work, please try again later.', + }); + break; + } + } +}); + +export { childRoutes }; diff --git a/src/routes/versus/versusRoutes.functions.ts b/src/routes/versus/versusRoutes.functions.ts new file mode 100644 index 00000000..e68ce646 --- /dev/null +++ b/src/routes/versus/versusRoutes.functions.ts @@ -0,0 +1,44 @@ +import { Matches } from '../../database/entity'; +import { getRepository } from 'typeorm'; +import { connection } from '../../util/typeorm-connection'; + +function decideHigher(studentA, studentB) { + const high = []; + if (studentA.storyPoints > studentB.storyPoints) high.push([studentA, studentB]); + else high.push([studentB, studentA]); + + if (studentA.illustrationPoints > studentB.illustrationPoints) high.push([studentA, studentB]); + else high.push([studentB, studentA]); + + return high; +} + +async function returnMatch(id: number, week: number) { + const match = await getRepository(Matches, connection()).findOne({ + where: [{ team1_child1_id: id, week: week }], + }); + + return match ? match : r2(id, week); +} + +async function r2(id: number, week: number) { + const match = await getRepository(Matches, connection()).findOne({ + where: [{ team1_child2_id: id, week: week }], + }); + return match ? match : r3(id, week); +} +async function r3(id: number, week: number) { + const match = await getRepository(Matches, connection()).findOne({ + where: [{ team2_child1_id: id, week: week }], + }); + console.log(match); + return match ? match : r4(id, week); +} +async function r4(id: number, week: number) { + const match = await getRepository(Matches, connection()).findOne({ + where: [{ team2_child2_id: id, week: week }], + }); + console.log(match); + return match ? match : null; +} +export { decideHigher, returnMatch };