diff --git a/backend/common/services/sendgrid.js b/backend/common/services/sendgrid.js
index 1f76afa29..604ce21ac 100644
--- a/backend/common/services/sendgrid.js
+++ b/backend/common/services/sendgrid.js
@@ -164,7 +164,10 @@ const SendgridService = {
header_image_url = event.coverImage.url
}
let msg
- if (event.eventType === EventTypes.physical.id) {
+ if (
+ event.eventType === EventTypes.physical.id ||
+ event.eventType === EventTypes.hybrid.id
+ ) {
msg = SendgridService.buildTemplateMessage(
user.email,
global.gConfig.SENDGRID_GENERIC_TEMPLATE,
diff --git a/backend/migrations/28-add-gavel-login-to-registrations.js b/backend/migrations/28-add-gavel-login-to-registrations.js
new file mode 100644
index 000000000..fcb757f75
--- /dev/null
+++ b/backend/migrations/28-add-gavel-login-to-registrations.js
@@ -0,0 +1,26 @@
+const mongoose = require('mongoose')
+const Promise = require('bluebird')
+
+module.exports = {
+ index: 28,
+ name: '28-add-gavel-login-to-registrations',
+ description: 'Add gavel login link to registrations',
+ run: async () => {
+ const addGavelLogin = await mongoose.model('Registration').updateMany(
+ { gavelLogin: { $exists: false } },
+ {
+ $set: {
+ gavelLogin: '',
+ },
+ },
+ )
+
+ console.log(
+ 'Done adding gavel login link to registrations',
+ addGavelLogin.n,
+ addGavelLogin.nModified,
+ )
+
+ return Promise.resolve()
+ },
+}
diff --git a/backend/migrations/index.js b/backend/migrations/index.js
index 771df796c..9eb493d56 100644
--- a/backend/migrations/index.js
+++ b/backend/migrations/index.js
@@ -31,6 +31,7 @@ const migrations = [
require('./25-add-emailConfig-to-event'),
require('./26-fix-empty-senderEmail-in-event'),
require('./27-add-experimental-flag-to-events'),
+ require('./28-add-gavel-login-to-registrations'),
]
const run = async () => {
diff --git a/backend/modules/event/controller.js b/backend/modules/event/controller.js
index 88f17f2c5..cc924d480 100644
--- a/backend/modules/event/controller.js
+++ b/backend/modules/event/controller.js
@@ -42,6 +42,15 @@ controller.isEventOnline = id => {
})
}
+controller.isEventHybrid = id => {
+ Event.findById(id).then(event => {
+ if (event.eventType === 'hybrid') {
+ return true
+ }
+ return false
+ })
+}
+
controller.getUnapprovedEvents = () => {
return Event.find({ approved: false })
}
diff --git a/backend/modules/event/graphql.js b/backend/modules/event/graphql.js
index 67eb99c50..f4c6bcf2f 100644
--- a/backend/modules/event/graphql.js
+++ b/backend/modules/event/graphql.js
@@ -714,7 +714,10 @@ const Resolvers = {
)
},
_eventLocationFormatted: parent => {
- if (parent.eventType === 'physical') {
+ if (
+ parent.eventType === 'physical' ||
+ parent.eventType === 'hybrid'
+ ) {
return `${parent.eventLocation.city}, ${parent.eventLocation.country}`
}
return 'Online'
diff --git a/backend/modules/event/model.js b/backend/modules/event/model.js
index 2dd6a5108..a072f21e8 100644
--- a/backend/modules/event/model.js
+++ b/backend/modules/event/model.js
@@ -105,9 +105,12 @@ const EventSchema = new mongoose.Schema({
type: AddressSchema.mongoose,
required: [
function () {
- return this.eventType === EventTypes.physical.id
+ return (
+ this.eventType === EventTypes.physical.id ||
+ this.eventType === EventTypes.hybrid.id
+ )
},
- `is required for physical events`,
+ `is required for physical or hydrid events`,
],
},
tracksEnabled: false,
@@ -326,7 +329,7 @@ const EventSchema = new mongoose.Schema({
},
senderName: {
type: String,
- default: '',
+ default: 'Junction team',
trim: true,
maxLength: 100,
},
diff --git a/backend/modules/project/controller.js b/backend/modules/project/controller.js
index 8aed6abe9..703df6431 100644
--- a/backend/modules/project/controller.js
+++ b/backend/modules/project/controller.js
@@ -1,3 +1,4 @@
+const _ = require('lodash')
const yup = require('yup')
const bcrypt = require('bcrypt')
const Promise = require('bluebird')
@@ -5,7 +6,6 @@ const { ProjectSchema } = require('@hackjunction/shared')
const Project = require('./model')
const { ForbiddenError } = require('../../common/errors/errors')
const TeamController = require('../team/controller')
-const upload = require('../../misc/gridfs').upload
const controller = {}
@@ -60,9 +60,7 @@ controller.createProjectForEventAndTeam = async (event, team, data) => {
controller.updateProjectForEventAndTeam = async (event, team, data) => {
const schema = yup.object().shape(ProjectSchema(event))
- console.log('data :>> ', data)
const validatedData = await schema.validate(data, { stripUnknown: true })
- console.log('validatedData :>> ', validatedData)
const projects = await controller.getProjectsByEventAndTeam(
event._id,
team._id,
@@ -75,11 +73,11 @@ controller.updateProjectForEventAndTeam = async (event, team, data) => {
controller.generateChallengeLink = async (event, challengeSlug) => {
const hashed = await bcrypt.hash(challengeSlug, global.gConfig.HASH_SALT)
- // console.log('inhere challenge :>> ')
return {
hash: hashed,
- link: `${global.gConfig.FRONTEND_URL}/projects/${event.slug
- }/challenge/${encodeURIComponent(hashed)}`,
+ link: `${global.gConfig.FRONTEND_URL}/projects/${
+ event.slug
+ }/challenge/${encodeURIComponent(hashed)}`,
}
}
@@ -88,8 +86,9 @@ controller.generateTrackLink = async (event, trackSlug) => {
// console.log('inhere track :>> ')
return {
hash: hashed,
- link: `${global.gConfig.FRONTEND_URL}/projects/${event.slug
- }/tracks/${encodeURIComponent(hashed)}`,
+ link: `${global.gConfig.FRONTEND_URL}/projects/${
+ event.slug
+ }/tracks/${encodeURIComponent(hashed)}`,
}
}
@@ -175,7 +174,14 @@ controller.validateToken = async (event, token) => {
if (Challengematches.length === 0 && Trackmatches === 0) {
throw new ForbiddenError('Invalid token')
}
- return true
+ console.log('Matches :>> ', Challengematches, Trackmatches)
+ if (
+ (Array.isArray(Challengematches) && Challengematches.length > 0) ||
+ (Array.isArray(Trackmatches) && Trackmatches.length > 0)
+ ) {
+ return true
+ }
+ return false
}
controller.getFinalProjects = async event => {
@@ -211,3 +217,43 @@ controller.getFinalists = event => {
return Project.find({ _id: { $in: event.finalists } })
}
module.exports = controller
+
+controller.getDataForPartnerReviewing = async (event, user) => {
+ const data = {}
+ const teams = await TeamController.getAllTeamsForEvent(event._id)
+ const projects = await controller.getProjectPreviewsByEvent(event._id)
+ const projectsWithExistingTeamsAndFinal = _.filter(projects, project => {
+ if (project.status === 'final') {
+ const teamFound = _.find(teams, team => {
+ return `${team._id}` === `${project.team}`
+ })
+ if (teamFound) {
+ return project
+ }
+ }
+ })
+
+ if (event.scoreCriteriaSettings.reviewAnyChallenge) {
+ data.projects = projectsWithExistingTeamsAndFinal
+ } else {
+ const challengeOrg = _.find(
+ event.recruiters,
+ recruiter => recruiter.recruiterId === user.sub,
+ )
+ if (challengeOrg) {
+ const challengeData = _.find(
+ event.challenges,
+ challenge => challenge.partner === challengeOrg.organization,
+ )
+ const projectsFilteredByChallenge = _.filter(
+ projectsWithExistingTeamsAndFinal,
+ project => _.includes(project.challenges, challengeData.slug),
+ )
+ data.projects = projectsFilteredByChallenge
+ data.challenge = challengeData
+ } else {
+ data.projects = []
+ }
+ }
+ return data
+}
diff --git a/backend/modules/project/model.js b/backend/modules/project/model.js
index 4b89337ad..53754c608 100644
--- a/backend/modules/project/model.js
+++ b/backend/modules/project/model.js
@@ -125,7 +125,7 @@ ProjectSchema.post('save', async function (doc, next) {
*/
case ReviewingMethods.gavelPeerReview.id: {
GavelController.ensureGavelProject(doc)
- console.log("saved as gavel project")
+ console.log('saved as gavel project')
break
}
default: {
diff --git a/backend/modules/project/routes.js b/backend/modules/project/routes.js
index 8a6c1d9c9..ca8a9b860 100644
--- a/backend/modules/project/routes.js
+++ b/backend/modules/project/routes.js
@@ -1,5 +1,4 @@
const express = require('express')
-
const router = express.Router()
const asyncHandler = require('express-async-handler')
@@ -12,6 +11,7 @@ const {
canSubmitProject,
isEventOrganiser,
getEventFromParams,
+ isEventPartner,
} = require('../../common/middleware/events')
router.route('/id/:projectId').get(
@@ -36,6 +36,22 @@ router
}),
)
+router
+ .route('/:slug/partner-review')
+ /** Get projects for partner review, only if their status is final, have a team and based on challenges */
+ .get(
+ hasToken,
+ isEventPartner,
+ getEventFromParams,
+ asyncHandler(async (req, res) => {
+ const data = await ProjectController.getDataForPartnerReviewing(
+ req.event,
+ req.user,
+ )
+ return res.status(200).json(data)
+ }),
+ )
+
router
.route('/:slug/validate')
/** Validate project before submission on UI, non-blocking (doesn't prevent saving to db) */
diff --git a/backend/modules/project_score/controller.js b/backend/modules/project_score/controller.js
index 438843085..07aa8029a 100644
--- a/backend/modules/project_score/controller.js
+++ b/backend/modules/project_score/controller.js
@@ -1,3 +1,4 @@
+const _ = require('lodash')
const Event = require('../event/model')
const Project = require('../project/model')
const { ProjectScore } = require('./model')
@@ -25,7 +26,6 @@ controller.addProjectScore = async score => {
}
projectScore.averageScore = averageScore
}
- console.log('ProjectScore from controller', projectScore)
return projectScore.save()
}
@@ -54,7 +54,6 @@ controller.updateProjectScore = async (id, updatedProjectScore) => {
}
projectScore.averageScore = averageScore
}
- console.log('updated project with token score', projectScore)
await projectScore.save()
return projectScore
}
@@ -71,7 +70,7 @@ controller.getScoresByEventAndTeamId = (eventId, teamId) => {
})
}
-controller.getScoreByProjectId = (
+controller.getScoreByProjectId = async (
projectId,
challenge = null,
track = null,
@@ -88,6 +87,18 @@ controller.getScoreByProjectId = (
return ProjectScore.find(query)
}
+controller.getScoreForProjectByReviewerId = async (projectId, reviewerId) => {
+ const testProjectScore = await controller.getScoreByProjectId(projectId)
+ if (testProjectScore && testProjectScore.length > 0) {
+ testProjectScore[0].reviewers.forEach(reviewer => {})
+ const scoreFromReviewer = _.find(
+ testProjectScore[0].reviewers,
+ reviewerScore => reviewerScore.userId === reviewerId,
+ )
+ return scoreFromReviewer
+ }
+}
+
controller.getPublicScores = async eventId => {
return ProjectScore.find({ event: eventId })
.populate({ path: 'event', select: 'name' })
@@ -101,11 +112,8 @@ const limitDecimals = (number, decimalPlaces) => {
const averageScoreCalculation = (reviewers, globalScore) => {
const allScores = reviewers.map(review => review.score)
- console.log('All scores from reviewers', allScores)
allScores.push(globalScore)
- console.log('All scores with global score', allScores)
let scoreCount = allScores.length
- console.log('Score count', scoreCount)
const scoreSum = allScores.reduce((acc, current) => {
if (current && current > 0) {
@@ -116,15 +124,10 @@ const averageScoreCalculation = (reviewers, globalScore) => {
}
}, 0)
- console.log('Score sum', scoreSum)
- console.log('Score count after', scoreCount)
let finalScore = scoreSum / scoreCount
if (!Number.isInteger(finalScore)) {
finalScore = limitDecimals(finalScore, 2)
- console.log('Not an integer')
}
- console.log('Score to submit', finalScore)
- console.log('Score type', typeof finalScore)
return finalScore
}
@@ -139,39 +142,6 @@ controller.updateProjectScoreWithReviewers = async (
projectScore.track = updatedProjectScore.track
projectScore.challenge = updatedProjectScore.challenge
projectScore.reviewers = updatedProjectScore.reviewers
- console.log(
- 'Updated project score from controller BEFORE save',
- projectScore,
- )
-
- // const allScores = projectScore.reviewers.map(review => review.score)
- // console.log('All scores from reviewers', allScores)
- // allScores.push(projectScore.score)
- // console.log('All scores with global score', allScores)
- // let scoreCount = allScores.length
- // console.log('Score count', scoreCount)
-
- // const scoreSum = allScores.reduce((acc, current) => {
- // if (current && current > 0) {
- // return acc + current
- // } else {
- // scoreCount = scoreCount - 1
- // return acc
- // }
- // }, 0)
- // function limitDecimals(number, decimalPlaces) {
- // const multiplier = Math.pow(10, decimalPlaces)
- // return Math.floor(number * multiplier) / multiplier
- // }
- // console.log('Score sum', scoreSum)
- // console.log('Score count after', scoreCount)
- // let finalScore = scoreSum / scoreCount
- // if (!Number.isInteger(finalScore)) {
- // finalScore = limitDecimals(finalScore, 2)
- // console.log('Not an integer')
- // }
- // console.log('Score to submit', finalScore)
- // console.log('Score type', typeof finalScore)
projectScore.averageScore = projectScore.score
@@ -191,10 +161,6 @@ controller.updateProjectScoreWithReviewers = async (
// projectScore.averageScore = projectScore.score +
await projectScore.save()
- console.log(
- 'Updated project score from controller AFTER save',
- projectScore,
- )
return projectScore
}
diff --git a/backend/modules/project_score/routes.js b/backend/modules/project_score/routes.js
index 20d04aa88..25b0635ce 100644
--- a/backend/modules/project_score/routes.js
+++ b/backend/modules/project_score/routes.js
@@ -14,7 +14,6 @@ const {
isEventPartner,
isOrganiserOrCanSubmitProject,
} = require('../../common/middleware/events')
-const { registrationAccepted } = require('../email-task/types')
const addProjectScore = asyncHandler(async (req, res) => {
console.log('addProjectScore is running')
@@ -127,7 +126,6 @@ router.get(
getScoreByProjectId,
)
-
router.post('/event/:slug', hasToken, isEventOrganiser, addProjectScore)
router.put('/event/:slug/:id', hasToken, isEventOrganiser, updateProjectScore)
diff --git a/backend/modules/recruitment/controller.js b/backend/modules/recruitment/controller.js
index 1ee843222..36e79963c 100644
--- a/backend/modules/recruitment/controller.js
+++ b/backend/modules/recruitment/controller.js
@@ -33,7 +33,6 @@ controller.queryProfiles = async (query = {}, user) => {
}
console.log(34)
} else if (query.filters && query.filters.length) {
-
const whereFields = query.filters.map(filter => {
//console.log("query.filter", filter.value)
const formatted = MongoUtils.ensureObjectId(filter.value)
@@ -116,7 +115,7 @@ controller.queryProfiles = async (query = {}, user) => {
//console.log(110)
}
// userQuery.$and = userQuery.$and.concat([matcher])
- console.log('userquery', JSON.stringify(userQuery), "pag", pagination,)
+ console.log('userquery', JSON.stringify(userQuery), 'pag', pagination)
//console.log("query", userQuery, "pag", pagination, "reg", JSON.stringify(userQuery.registrations))
return UserController.queryProfiles({
query: userQuery,
@@ -127,7 +126,7 @@ controller.queryProfiles = async (query = {}, user) => {
return controller.createRecruitmentProfile(profile, false)
}),
).then(profiles => {
-
+ console.log('profiles', profiles)
return { data: profiles, count: results.count }
})
})
diff --git a/backend/modules/registration/controller.js b/backend/modules/registration/controller.js
index b58191082..1f7ac5d0b 100644
--- a/backend/modules/registration/controller.js
+++ b/backend/modules/registration/controller.js
@@ -15,7 +15,7 @@ const Registration = require('./model')
const { NotFoundError, ForbiddenError } = require('../../common/errors/errors')
const RegistrationHelpers = require('./helpers')
const EmailTaskController = require('../email-task/controller')
-const { checklistItemsOnline, checklistItemsPhysical } = require('./checklists')
+// const { checklistItemsOnline, checklistItemsPhysical } = require('./checklists')
const STATUSES = RegistrationStatuses.asObject
const TRAVEL_GRANT_STATUSES = RegistrationTravelGrantStatuses.asObject
@@ -28,56 +28,49 @@ controller.getUserRegistrations = user => {
}
controller.createRegistration = async (user, event, data) => {
- console.log("user", user)
const answers = await RegistrationHelpers.registrationFromUser(data)
const registration = new Registration({
event: event._id.toString(),
user: user.sub,
answers,
})
- if (event.eventType === 'online') {
- registration.checklist = {
- items: checklistItemsOnline(),
- }
- } else {
- registration.checklist = {
- items: checklistItemsPhysical(),
- }
- }
+ // if (event.eventType === 'online') {
+ // registration.checklist = {
+ // items: checklistItemsOnline(),
+ // }
+ // } else {
+ // registration.checklist = {
+ // items: checklistItemsPhysical(),
+ // }
+ // }
registration.status = RegistrationStatuses.asObject.incomplete.id
- console.log("createRegistration", registration)
+ console.log('createRegistration', registration)
return registration.save()
- /* .catch(function (err) {
- console.log(err.name, err.errors)
- }) */
}
controller.createPartnerRegistration = async (user, event, data) => {
- console.log("user", user)
+ console.log('user', user)
const answers = await RegistrationHelpers.registrationFromUser(data)
const registration = new Registration({
event: event._id.toString(),
user: user,
answers,
})
- if (event.eventType === 'online') {
- registration.checklist = {
- items: checklistItemsOnline(),
- }
- } else {
- registration.checklist = {
- items: checklistItemsPhysical(),
- }
- }
+ // if (event.eventType === 'online') {
+ // registration.checklist = {
+ // items: checklistItemsOnline(),
+ // }
+ // } else {
+ // registration.checklist = {
+ // items: checklistItemsPhysical(),
+ // }
+ // }
registration.status = RegistrationStatuses.asObject.incomplete.id
- console.log("createRegistration", registration)
+ console.log('create registration for partner', registration)
return registration.save()
- /* .catch(function (err) {
- console.log(err.name, err.errors)
- }) */
}
-controller.getRegistration = (userId, eventId) => {
+controller.getRegistration = async (userId, eventId) => {
return Registration.findOne({
event: eventId,
user: userId,
@@ -99,7 +92,6 @@ controller.updateRegistration = (user, event, data) => {
await RegistrationHelpers.validateAnswers(data, event)
// answers are valid
if (answers) {
-
return Registration.updateAllowed(registration, { answers })
}
return false
@@ -120,15 +112,20 @@ controller.finishRegistration = (user, event, data) => {
registration.status ===
RegistrationStatuses.asObject.incomplete.id
) {
- if (event.eventType === EventTypes.physical.id) {
- registration.status =
- RegistrationStatuses.asObject.pending.id
- }
+ registration.status =
+ RegistrationStatuses.asObject.pending.id
+ // if (
+ // event.eventType === EventTypes.physical.id ||
+ // event.eventType === EventTypes.hybrid.id
+ // ) {
+ // registration.status =
+ // RegistrationStatuses.asObject.pending.id
+ // }
// TODO we most likely don't want to do this here? Get desired state from event?
- if (event.eventType === EventTypes.online.id) {
- registration.status =
- RegistrationStatuses.asObject.checkedIn.id
- }
+ // if (event.eventType === EventTypes.online.id) {
+ // registration.status =
+ // RegistrationStatuses.asObject.checkedIn.id
+ // }
}
return Registration.updateAllowed(registration, { answers })
}
@@ -460,7 +457,7 @@ controller.rejectPendingTravelGrants = eventId => {
controller.getFullRegistration = (eventId, registrationId) => {
const query =
mongoose.Types.ObjectId.isValid(registrationId) &&
- registrationId.indexOf('|') === -1
+ registrationId.indexOf('|') === -1
? { _id: registrationId }
: { user: registrationId }
return Registration.findOne(query)
@@ -525,4 +522,42 @@ controller.rejectSoftRejected = async eventId => {
return rejected
}
+controller.addGavelLoginToRegistrations = async (eventId, gavelData) => {
+ console.log('Gavel data received', gavelData, typeof gavelData)
+ gavelData.forEach(gavel => {
+ if (
+ typeof gavel.registration !== 'string' ||
+ typeof gavel.link !== 'string'
+ ) {
+ throw new Error('Gavel data is invalid')
+ }
+ })
+ let updateCount = 0
+ const registrations = await Registration.find({
+ event: eventId,
+ status: RegistrationStatuses.asObject.checkedIn.id,
+ })
+ console.log('Registrations found', registrations.length)
+ console.log('Registrations data', registrations)
+ const registrationCount = registrations.length
+
+ gavelData.forEach(gavel => {
+ const registration = registrations.find(
+ r => r._id.toString() === gavel.registration,
+ )
+ if (registration) {
+ registration.gavelLogin = gavel.link
+ updateCount++
+ console.log('Registration full data', registration)
+ registration.save()
+ }
+ })
+
+ console.log(
+ 'Modified counts, updated/total',
+ updateCount,
+ registrationCount,
+ )
+}
+
module.exports = controller
diff --git a/backend/modules/registration/helpers.js b/backend/modules/registration/helpers.js
index e8f5647fa..ae8c9a48f 100644
--- a/backend/modules/registration/helpers.js
+++ b/backend/modules/registration/helpers.js
@@ -56,7 +56,6 @@ const RegistrationHelpers = {
.validate(data, { stripUknown: true })
.catch(e => {
// TODO proper log
- console.log('error in validateAnswers', e)
return minSchema
.validate(data, { stripUknown: true })
.catch(ee => {
@@ -89,12 +88,8 @@ const RegistrationHelpers = {
})
const schema = yup.object().shape(validationSchema)
- console.log('users', d)
- const data = schema.validate(d, { stripUknown: true }).catch(e => {
- console.log('RFU', e)
- })
- console.log('got data', data)
+ const data = schema.validate(d, { stripUknown: true }).catch(e => {})
return data
},
buildAggregation: (eventId, userId, qp) => {
diff --git a/backend/modules/registration/model.js b/backend/modules/registration/model.js
index 3ae3e9c50..d753645de 100644
--- a/backend/modules/registration/model.js
+++ b/backend/modules/registration/model.js
@@ -79,6 +79,9 @@ const RegistrationSchema = new mongoose.Schema({
travelGrantAmount: {
type: Number,
},
+ gavelLogin: {
+ type: String,
+ },
})
/* Only allow a single registration per event per user */
diff --git a/backend/modules/registration/routes.js b/backend/modules/registration/routes.js
index ef0367778..5706d9e93 100644
--- a/backend/modules/registration/routes.js
+++ b/backend/modules/registration/routes.js
@@ -32,15 +32,13 @@ const getRegistration = asyncHandler(async (req, res) => {
})
const createRegistration = asyncHandler(async (req, res) => {
- console.log("creating registration with data:",
- "user: ", req.user,
- "event ", req.event,
- "data ", req.body)
+ console.log('creating registration from routes')
const registration = await RegistrationController.createRegistration(
req.user,
req.event,
req.body,
)
+ console.log('registration complete')
return res.status(201).json(registration)
})
@@ -217,31 +215,39 @@ const bulkRejectRegistrations = asyncHandler(async (req, res) => {
})
const addPartnerToRegistrated = asyncHandler(async (req, res) => {
-
- console.log("addPartnerToRegistrated", req.body)
+ console.log('addPartnerToRegistrated', req.body)
//TODO: should check if the user is registered already first
try {
- const hasRegistration = await RegistrationController.getRegistration(req.body.userId, req.event._id)
+ const hasRegistration = await RegistrationController.getRegistration(
+ req.body.userId,
+ req.event._id,
+ )
return res.status(200).json(hasRegistration)
} catch (e) {
- console.log("hasRegistration", e)
- const registration = await RegistrationController.createPartnerRegistration(
- req.body.userId, //switch to actual user
- req.event, //slug
- req.body.profile, /*data: {
+ console.log('hasRegistration', e)
+ const registration =
+ await RegistrationController.createPartnerRegistration(
+ req.body.userId, //switch to actual user
+ req.event, //slug
+ req.body.profile /*data: {
firstName: 'seppo',
lastName: 'pykälä',
email: 'samu.rotko@gmail.com'
- }*/
- )
+ }*/,
+ )
return res.status(200).json(registration)
}
+})
+const addGavelLoginToRegistrations = asyncHandler(async (req, res) => {
+ console.log('Event id', req.event._id)
+ console.log('From routes, for gavel login', req.body)
+ await RegistrationController.addGavelLoginToRegistrations(
+ req.event._id.toString(),
+ req.body,
+ )
-
-
-
-
+ return res.status(200).json([])
})
router.route('/').get(hasToken, getUserRegistrations)
@@ -388,4 +394,13 @@ router
addPartnerToRegistrated,
)
+router
+ .route('/:slug/gavel')
+ .post(
+ hasToken,
+ hasPermission(Auth.Permissions.MANAGE_EVENT),
+ isEventOrganiser,
+ addGavelLoginToRegistrations,
+ )
+
module.exports = router
diff --git a/frontend/src/components/UserMenu/index.js b/frontend/src/components/UserMenu/index.js
index 39b83b167..945ba4595 100644
--- a/frontend/src/components/UserMenu/index.js
+++ b/frontend/src/components/UserMenu/index.js
@@ -2,12 +2,7 @@ import React, { useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { push } from 'connected-react-router'
import { makeStyles } from '@material-ui/core/styles'
-import {
- Box,
- ListItem,
- ListItemText,
- Grid,
-} from '@material-ui/core'
+import { Box, ListItem, ListItemText, Grid } from '@material-ui/core'
import * as AuthSelectors from 'redux/auth/selectors'
import JunctionTheme from 'junctionTheme.js'
import Button from 'components/generic/Button'
@@ -45,17 +40,12 @@ export default () => {
const idTokenPayload = useSelector(AuthSelectors.getIdTokenPayload)
const userId = idTokenPayload?.sub
- const [profile] = useMyProfilePreview()
const dispatch = useDispatch()
const classes = useStyles()
-
-
if (!userId) {
return (
-
-
-
-
)
}
-
-
return (
-
-
+
-
-
-
+
-
+
)
-}
\ No newline at end of file
+}
diff --git a/frontend/src/components/UserMenu/userMenu_deprecated/index.js b/frontend/src/components/UserMenu/userMenu_deprecated/index.js
deleted file mode 100644
index f6a9d70ca..000000000
--- a/frontend/src/components/UserMenu/userMenu_deprecated/index.js
+++ /dev/null
@@ -1,260 +0,0 @@
-//old usermenu
-
-
-import React, { useState } from 'react'
-import { useDispatch, useSelector } from 'react-redux'
-import { push } from 'connected-react-router'
-import { makeStyles } from '@material-ui/core/styles'
-import {
- Popover,
- Avatar,
- Box,
- ListItem,
- ListItemText,
- Divider,
- Grid,
-} from '@material-ui/core'
-import * as AuthSelectors from 'redux/auth/selectors'
-import MenuIcon from '@material-ui/icons/Menu'
-import JunctionTheme from 'junctionTheme.js'
-import LanguageMenu from 'components/LanguageMenu'
-import { useMyProfilePreview } from 'graphql/queries/userProfile'
-
-import { useTranslation } from 'react-i18next'
-
-const useStyles = makeStyles(theme => ({
- menuDot: {
- width: '8px',
- height: '8px',
- margin: '2px',
- borderRadius: '2px',
- backgroundColor: 'rgba(0,0,0,0.3)',
- },
- avatar: {
- marginLeft: '16px',
- },
- hamburger: {
- transition: theme.transitions.create(['transform'], {
- duration: theme.transitions.duration.short,
- }),
- },
- hamburgerOpen: {
- transform: 'rotate(-90deg)',
- },
- hamburgerClosed: {
- transform: 'rotate(0)',
- },
- tableBottom: {
- borderBottom: 'none',
- },
- popover: {
- borderRadius: '15px',
- },
- menuBox: {
- width: '220px',
- borderRadius: '15px',
- },
-}))
-
-export default () => {
- const { t } = useTranslation()
-
- const idTokenPayload = useSelector(AuthSelectors.getIdTokenPayload)
- const userId = idTokenPayload?.sub
- const [profile] = useMyProfilePreview()
- const dispatch = useDispatch()
- const hasSuperAdmin = useSelector(AuthSelectors.hasSuperAdmin)
- const hasRecruiterAccess = useSelector(AuthSelectors.hasRecruiterAccess)
- const classes = useStyles()
- const [anchorEl, setAnchorEl] = useState(null)
- const color = JunctionTheme.palette
-
- const handleMenuOpen = e => {
- setAnchorEl(e.currentTarget)
- }
-
- const handleMenuClose = () => {
- setAnchorEl(null)
- }
-
- if (!userId) {
- return (
-
-
-
-
-
-
-
-
- dispatch(push('/login'))}
- />
-
-
-
-
-
-
-
-
-
-
-
-
- )
- }
-
- const renderEventItems = () => {
- const items = []
- TODO: Add links to event dashboard here for ongoing events
- return null
- }
-
- const renderOtherItems = () => {
- const items = []
-
- if (hasOrganiserAccess) {
- items.push({
- label: 'Create Event',
- onClick: () => dispatch(push('/organise')),
- })
- }
-
- if (hasRecruiterAccess) {
- items.push({
- label: 'Recruitment',
- onClick: () => dispatch(push('/recruitment')),
- })
- }
-
- if (hasSuperAdmin) {
- items.push({
- label: 'Admin',
- onClick: () => dispatch(push('/admin')),
- })
- }
- Grid Item isn't neccessary here, but put it in for consistency
- if (items.length > 0) {
- return (
- <>
- {items.map(({ label, onClick }) => (
-
-
-
-
-
- ))}
- >
- )
- }
-
- return null
- }
-
- return (
-
-
-
-
-
-
-
-
-
- dispatch(push('/account'))}
- />
-
-
-
- dispatch(push('/logout'))}
- >
-
-
-
-
-
-
- dispatch(push('/account/profile'))
- }
- />
-
-
- {renderEventItems()}
- {renderOtherItems()}
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/frontend/src/components/generic/PageHeader/index.js b/frontend/src/components/generic/PageHeader/index.js
index 2565a39df..c7a7e8ad7 100644
--- a/frontend/src/components/generic/PageHeader/index.js
+++ b/frontend/src/components/generic/PageHeader/index.js
@@ -1,20 +1,12 @@
import React from 'react'
-import { makeStyles } from '@material-ui/core/styles'
-import { Box, Typography } from '@material-ui/core'
-
-// const useStyles = makeStyles(theme => ({
-// subheading: {
-// marginTop: theme.spacing(1),
-// marginLeft: theme.spacing(0.5),
-// fontFamily: 'Lato',
-// },
-// }))
+import { Link, Typography } from '@material-ui/core'
const PageHeader = ({
heading,
subheading = null,
details = null,
+ link = null,
alignment = 'center',
}) => {
const styling = {
@@ -23,9 +15,7 @@ const PageHeader = ({
right: 'tw-items-end tw-text-right',
}
- // const classes = useStyles()
return (
- //
{details}
-
- {/*
- {heading}
-
- {subheading && (
-
- {subheading}
-
- )} */}
+ Open in new tab
+
+ )}
+
- //
)
}
diff --git a/frontend/src/components/generic/RadioScore/index.js b/frontend/src/components/generic/RadioScore/index.js
index 06bf6a6b8..a26e4eb52 100644
--- a/frontend/src/components/generic/RadioScore/index.js
+++ b/frontend/src/components/generic/RadioScore/index.js
@@ -58,19 +58,27 @@ export default ({ category, label, onSelectionChange, value = null }) => {
checkedIcon={
+ className={`tw-w-5 tw-h-5 tw-rounded-full tw-flex tw-justify-center tw-items-center tw-text-sm tw-font-bold tw-text-white ${classes.bgPrimary}`}
+ >
+ {score}
+
}
icon={
index < selectedIndex ? (
+ className={`tw-w-5 tw-h-5 tw-rounded-full tw-flex tw-justify-center tw-items-center tw-text-sm tw-text-gray-400 ${classes.bgPrimary}`}
+ >
+ {score}
+
) : (
-
+
+ {score}
+
)
}
/>
diff --git a/frontend/src/components/inputs/MarkdownInput/index.js b/frontend/src/components/inputs/MarkdownInput/index.js
index 092032b84..14ea89df4 100644
--- a/frontend/src/components/inputs/MarkdownInput/index.js
+++ b/frontend/src/components/inputs/MarkdownInput/index.js
@@ -20,7 +20,7 @@ const useStyles = makeStyles(theme => ({
},
}))
-export default ({ name, value, placeholder, onChange, onBlur }) => {
+export default ({ name, value, placeholder, onChange, onBlur, maxLength }) => {
const classes = useStyles()
const [isPreview, setIsPreview] = useState(false)
@@ -58,6 +58,7 @@ export default ({ name, value, placeholder, onChange, onBlur }) => {
value={value}
onChange={onChange}
onBlur={onBlur}
+ maxLength={maxLength}
/>
)}
diff --git a/frontend/src/components/inputs/Select/index.js b/frontend/src/components/inputs/Select/index.js
index 563efe335..139f7c8eb 100644
--- a/frontend/src/components/inputs/Select/index.js
+++ b/frontend/src/components/inputs/Select/index.js
@@ -243,7 +243,7 @@ SingleValue.propTypes = {
/**
* Props passed to the wrapping element for the group.
*/
- innerProps: PropTypes.any.isRequired,
+ innerProps: PropTypes.any,
selectProps: PropTypes.object.isRequired,
}
@@ -436,6 +436,9 @@ export default function IntegrationReactSelect({
})
.filter(item => !!item)
} else {
+ if (Array.isArray(value)) {
+ value = value[0]
+ }
return _options.find(o => o.value === value)
}
}, [_options, isMulti, value])
diff --git a/frontend/src/components/inputs/TextAreaInput/index.js b/frontend/src/components/inputs/TextAreaInput/index.js
index 75fa9c790..120595496 100644
--- a/frontend/src/components/inputs/TextAreaInput/index.js
+++ b/frontend/src/components/inputs/TextAreaInput/index.js
@@ -1,9 +1,8 @@
-import React, { useCallback } from 'react'
+import React, { useCallback, useState } from 'react'
import { TextField } from '@material-ui/core'
-import { makeStyles, useTheme, withStyles } from '@material-ui/core/styles'
+import { makeStyles } from '@material-ui/core/styles'
-// const theme = useTheme()
const useTextField = makeStyles(theme => ({
root: {
'& .MuiFilledInput-root': {
@@ -11,10 +10,14 @@ const useTextField = makeStyles(theme => ({
border: `2px solid #e2e8f0`,
borderRadius: '6px',
},
- // backgroundColor: '#f8f8f8',
},
}))
+const errorLengthBase = {
+ error: false,
+ helperText: '',
+}
+
const TextAreaInput = React.memo(
({
disabled,
@@ -28,36 +31,78 @@ const TextAreaInput = React.memo(
autoFocus,
minRows = 10,
maxRows = 100,
+ maxLength,
}) => {
+ const [errorLength, setErrorLength] = useState(errorLengthBase)
+
const classes = useTextField()
const handleChange = useCallback(
e => {
+ if (maxLength) {
+ if (e.target.value.length > maxLength) {
+ setErrorLength({
+ error: true,
+ helperText: `${e.target.value.length}/${maxLength}`,
+ })
+ } else {
+ setErrorLength(errorLengthBase)
+ }
+ }
onChange(e.target.value)
},
[onChange],
)
- return (
-
- )
+ let textFieldFormat
+
+ if (maxLength) {
+ textFieldFormat = (
+
+ )
+ } else {
+ textFieldFormat = (
+
+ )
+ }
+
+ return textFieldFormat
},
)
diff --git a/frontend/src/components/modals/EditProjectModal/index.js b/frontend/src/components/modals/EditProjectModal/index.js
index 749eb13ee..26a4700c6 100644
--- a/frontend/src/components/modals/EditProjectModal/index.js
+++ b/frontend/src/components/modals/EditProjectModal/index.js
@@ -32,12 +32,17 @@ import EventsService from 'services/events'
import { Formik, Form, Field, ErrorMessage } from 'formik'
import Button from 'components/generic/Button'
+import { projectURLgenerator } from 'utils/dataModifiers'
export default ({ project, onClose = () => {}, onEdited = () => {} }) => {
const dispatch = useDispatch()
const idToken = useSelector(AuthSelectors.getIdToken)
const event = useSelector(OrganiserSelectors.event)
const teams = useSelector(OrganiserSelectors.teams)
+ let projectURL
+ if (project) {
+ projectURL = projectURLgenerator(event.slug, project._id)
+ }
const [finalistChecked, setFinalistChecked] = useState(false)
const [projectScores, setProjectScores] = useState([
{
@@ -84,6 +89,7 @@ export default ({ project, onClose = () => {}, onEdited = () => {} }) => {
{
-
return (