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/pages/_dashboard/renderDashboard/default/events/Organizer.js b/frontend/src/pages/_dashboard/renderDashboard/default/events/Organizer.js index a3dc38afb..cf5b256bc 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/default/events/Organizer.js +++ b/frontend/src/pages/_dashboard/renderDashboard/default/events/Organizer.js @@ -16,8 +16,7 @@ import * as UserActions from 'redux/user/actions' import CreateEventCard from './CreateEventCard' import TextInput from '../../../../../components/inputs/TextInput' - - +import { debugGroup } from 'utils/debuggingTools' //TODO: make this to use theme colors and make prettier const useStyles = makeStyles({ @@ -66,49 +65,48 @@ export default () => { var date = new Date() const isodate = date.toISOString() - const [searchTerm, setSearchTerm] = React.useState('') + const [searchTerm, setSearchTerm] = useState('') const [searchResults, setSearchResults] = useState(organizerEvents) const [name, setName] = useState('') const [error, setError] = useState() const [loading, setLoading] = useState(false) const hasError = Boolean(error) - - const isOrganizer = useSelector(AuthSelectors.idTokenData)?.roles?.some(r => - ["Organiser", "AssistantOrganiser", "SuperAdmin"].includes(r) + ['Organiser', 'AssistantOrganiser', 'SuperAdmin'].includes(r), ) - - useEffect(() => { - if (hasError) { - if (name.length < 5) { - setError(t('Name_must_five_')) - } else if (name.length >= 50) { - setError(t('Name_must_under_')) - } else if (name === "default") { - setError(t('Name_not_default_')) - } else { - setError() - } - } - }, [name, hasError, t]) - - const checkName = useCallback(() => { - if (name.length < 5) { - setError(t('Name_must_five_')) - return false - } else if (name.length >= 50) { - setError(t('Name_must_under_')) - return false - } else if (name === "default") { - setError(t('Name_not_default_')) - return false - } - return true - }, [name.length, t]) - - console.log("organizerEvents", organizerEvents) + // useEffect(() => { + // if (hasError) { + // if (name.length < 5) { + // setError(t('Name_must_five_')) + // } else if (name.length >= 50) { + // setError(t('Name_must_under_')) + // } else if (name === 'default') { + // setError(t('Name_not_default_')) + // } else { + // setError() + // } + // } + // }, [name, hasError, t]) + + // const checkName = useCallback(() => { + // if (name.length < 5) { + // setError(t('Name_must_five_')) + // return false + // } else if (name.length >= 50) { + // setError(t('Name_must_under_')) + // return false + // } else if (name === 'default') { + // setError(t('Name_not_default_')) + // return false + // } + // return true + // }, [name.length, t]) + + console.log('organizerEvents', organizerEvents) + + //TODO implement pagination to improve performance of organize tab useEffect(() => { const results = organizerEvents.filter( @@ -119,108 +117,100 @@ export default () => { setSearchResults(results) }, [organizerEvents, searchTerm]) - //TODO: super slow on superadmin. fix the rendering - return (organizerEvents.length === 0 || !isOrganizer) ? - ( - ( - <> - - - - - - - - - ) - ) - : - ( - <> - - - - - - - - - - - + return organizerEvents.length === 0 || !isOrganizer ? ( + <> + + + + + + + + ) : ( + <> + + + + + - - - {searchResults.map(event => ( - -
- {event.published && event.approved ? ( - - Published! - - ) : null} - {event.published && !event.approved ? ( - - Waiting approval - - ) : null} - {!event.published ? ( - - Not published - - ) : null} -
- - - dispatch(push('/events/' + event.slug)) - } - > - {t('See_more_')} - , - , - ]} - /> - -
- ))} + + -
- - ) - - -} \ No newline at end of file +
+ + + {searchResults.map(event => ( + +
+ {event.published && event.approved ? ( + + Published! + + ) : null} + {event.published && !event.approved ? ( + + Waiting approval + + ) : null} + {!event.published ? ( + + Not published + + ) : null} +
+ + + dispatch( + push('/events/' + event.slug), + ) + } + > + {t('See_more_')} + , + , + ]} + /> +
+ ))} +
+
+ + ) +} diff --git a/frontend/src/pages/_dashboard/renderDashboard/default/events/Participant.js b/frontend/src/pages/_dashboard/renderDashboard/default/events/Participant.js index 001ac223b..314b1fb6d 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/default/events/Participant.js +++ b/frontend/src/pages/_dashboard/renderDashboard/default/events/Participant.js @@ -14,13 +14,10 @@ import Button from 'components/generic/Button' import PageWrapper from 'components/layouts/PageWrapper' import Container from 'components/generic/Container' - import * as AuthSelectors from 'redux/auth/selectors' import * as DashboardSelectors from 'redux/dashboard/selectors' import * as UserActions from 'redux/user/actions' - - export default () => { const userId = useSelector(AuthSelectors.getUserId) const activeEvents = useSelector(DashboardSelectors.activeEvents) @@ -28,11 +25,9 @@ export default () => { const [registrations, loading, error] = useRegistrationsByUser(userId) //useSelector(UserSelectors.registrations) - - - console.log("activeEvents", activeEvents) - console.log("pastEvents", pastEvents) - console.log("registrations", registrations) + console.log('activeEvents', activeEvents) + console.log('pastEvents', pastEvents) + console.log('registrations', registrations) const dispatch = useDispatch() const { t } = useTranslation() @@ -40,7 +35,6 @@ export default () => { const isodate = date.toISOString() function renderEvents() { - return ( <> { - - {registrations.length === 0 && ( - - {t('Looks_like_register_')} - - )} + {Array.isArray(registrations) && + registrations.length === 0 && ( + + {t('Looks_like_register_')} + + )} {registrations?.map(registration => ( @@ -64,45 +58,63 @@ export default () => { { - dispatch(UserActions.setAccessRight('participant'))//TODO: make this a schema - dispatch(push(`/dashboard/event/${event?.slug}`)) - } - } + dispatch( + UserActions.setAccessRight( + 'participant', + ), + ) //TODO: make this a schema + dispatch( + push( + `/dashboard/event/${event?.slug}`, + ), + ) + }} /> ))}
- -

Upcoming Events

+

Upcoming Events

- {activeEvents?.filter(event => - registrations?.map(e => e.event?.slug).indexOf(event?.slug) === -1 - ) + {activeEvents + ?.filter( + event => + registrations + ?.map(e => e.event?.slug) + .indexOf(event?.slug) === -1, + ) .map(event => { const canApply = isodate < event.registrationEndTime && isodate > event.registrationStartTime const eventStarted = isodate > event.startTime - console.log("button render", event.slug, canApply && !event.galleryOpen, event.galleryOpen && eventStarted) + console.log( + 'button render', + event.slug, + canApply && !event.galleryOpen, + event.galleryOpen && eventStarted, + ) return ( - dispatch(push('/events/' + event.slug)) - } - > - {t('See_more_')} - - ), + , canApply && ( ), - event.galleryOpen && eventStarted && ( - - ), - - - - - - + event.galleryOpen && + eventStarted && ( + + ), ]} - />) - } - ) - } + /> + ) + })} - + -

Past Events

+

Past Events

@@ -161,38 +172,43 @@ export default () => { - dispatch(push('/events/' + event.slug)) - } - > - {t('See_more_')} - - ), - + , event.galleryOpen && eventStarted && ( ), ]} - />) - } - ) - } + /> + ) + })} - + , ]} - />) + /> + ) })} - + ) } @@ -94,12 +110,7 @@ export default () => { return ( ( - - {renderEvents()} - - ) - } + render={() => {renderEvents()}} /> ) -} \ No newline at end of file +} diff --git a/frontend/src/pages/_dashboard/renderDashboard/generalPages/default/Blocks/ReviewingPeriodBlock.js b/frontend/src/pages/_dashboard/renderDashboard/generalPages/default/Blocks/ReviewingPeriodBlock.js index b9ebd44d2..461b73462 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/generalPages/default/Blocks/ReviewingPeriodBlock.js +++ b/frontend/src/pages/_dashboard/renderDashboard/generalPages/default/Blocks/ReviewingPeriodBlock.js @@ -21,23 +21,30 @@ export default () => { dispatch(DashboardActions.updateAnnotator(event.slug)) } }, [event, dispatch]) - if (event.reviewMethod === 'manualReview' && EventHelpers.isVotingOpen(event, moment)) return ( - - - Reviewing period - Reviewing period is open! - - Reviewing ends {moment(event.reviewingEndTime).fromNow()} - - - Sit back and relax while we review your project! - - - - + if ( + event.reviewMethod === 'gavelPeerReview' && + EventHelpers.isReviewingOpen(event, moment) ) + return ( + + + Reviewing period + + Reviewing period is open! + + + Reviewing ends{' '} + {moment(event.reviewingEndTime).fromNow()} + + + Sit back and relax while your project is reviewed! + + + + + ) - if (!EventHelpers.isVotingOpen(event, moment)) return null + if (!EventHelpers.isReviewingOpen(event, moment)) return null return ( @@ -55,7 +62,9 @@ export default () => { + + )} ) } diff --git a/frontend/src/pages/_dashboard/renderDashboard/organiser/participants/index.js b/frontend/src/pages/_dashboard/renderDashboard/organiser/participants/index.js index fd2e2ff59..d22c0fc85 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/organiser/participants/index.js +++ b/frontend/src/pages/_dashboard/renderDashboard/organiser/participants/index.js @@ -8,7 +8,7 @@ import PageHeader from 'components/generic/PageHeader' import DefaultTab from './default' import TeamsTab from './teams' import AssignedTab from './assigned' -import TravelTab from './travel' +// import TravelTab from './travel' import AdminTab from './admin' export default () => { diff --git a/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/by-challenge/index.js b/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/by-challenge/index.js index 53d2edbd0..1d327c177 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/by-challenge/index.js +++ b/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/by-challenge/index.js @@ -18,9 +18,24 @@ import * as OrganiserSelectors from 'redux/organiser/selectors' export default () => { const event = useSelector(OrganiserSelectors.event) const projects = useSelector(OrganiserSelectors.projects) + const teams = useSelector(OrganiserSelectors.teams) const getProjectsForChallenge = slug => { - return projects.filter(project => { + const projectsWithTeam = projects + .map(project => { + const teamFound = teams.find(team => { + console.log(team._id, project.team) + return team._id === project.team + }) + if (teamFound) { + project.teamCode = teamFound.code + } else { + project.teamCode = 'No team' + } + return project + }) + .filter(project => project.teamCode !== 'No team') + return projectsWithTeam.filter(project => { return project.challenges && project.challenges.indexOf(slug) !== -1 }) } diff --git a/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/by-track/index.js b/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/by-track/index.js index 29238b6fc..051d4fc99 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/by-track/index.js +++ b/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/by-track/index.js @@ -17,9 +17,24 @@ import TrackLink from './TrackLink' export default () => { const event = useSelector(OrganiserSelectors.event) const projects = useSelector(OrganiserSelectors.projects) + const teams = useSelector(OrganiserSelectors.teams) const getProjectsForTrack = slug => { - return projects.filter(project => project.track === slug) + const projectsWithTeam = projects + .map(project => { + const teamFound = teams.find(team => { + console.log(team._id, project.team) + return team._id === project.team + }) + if (teamFound) { + project.teamCode = teamFound.code + } else { + project.teamCode = 'No team' + } + return project + }) + .filter(project => project.teamCode !== 'No team') + return projectsWithTeam.filter(project => project.track === slug) } return ( diff --git a/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/finalist-selection/index.js b/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/finalist-selection/index.js index fc8066909..67c764476 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/finalist-selection/index.js +++ b/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/finalist-selection/index.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import { Grid, @@ -45,18 +45,18 @@ export default () => { const idToken = useSelector(AuthSelectors.getIdToken) const [loading, setLoading] = useState(false) - const [checked, setChecked] = React.useState([]) - const [left, setLeft] = React.useState([]) - const [filteredLeft, setFilteredLeft] = React.useState([]) + const [checked, setChecked] = useState([]) + const [left, setLeft] = useState([]) + const [filteredLeft, setFilteredLeft] = useState([]) - const [right, setRight] = React.useState([]) - const [filter, setFilter] = React.useState('') + const [right, setRight] = useState([]) + const [filter, setFilter] = useState('') const debouncedFilter = useDebounce(filter, 300) const leftChecked = intersection(checked, left) const rightChecked = intersection(checked, right) - React.useEffect(() => { + useEffect(() => { const newLeft = projects ?.filter(project => !event?.finalists?.includes(project._id)) @@ -70,7 +70,7 @@ export default () => { ) }, [projects, event]) - React.useEffect(() => { + useEffect(() => { if (debouncedFilter) { const availableProjects = projects.filter(p => left.includes(p._id)) setFilteredLeft( diff --git a/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/index.js b/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/index.js index 7d87972b8..ce2be0e7f 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/index.js +++ b/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/index.js @@ -11,8 +11,8 @@ import PageHeader from 'components/generic/PageHeader' import DefaultTab from './default' import ChallengesTab from './by-challenge' import TracksTab from './by-track' -import GavelTab from './gavel' -import AnnotatorsTab from './annotators' +// import GavelTab from './gavel' +// import AnnotatorsTab from './annotators' import WinnersTab from './winners' import FinalistSelectionTab from './finalist-selection' import VotingTokensTab from './votingTokens' @@ -51,19 +51,19 @@ export default () => { }) } - data.push({ - path: '/gavel', - key: 'gavel', - label: 'Gavel voting', - component: GavelTab, - }) + // data.push({ + // path: '/gavel', + // key: 'gavel', + // label: 'Gavel voting', + // component: GavelTab, + // }) - data.push({ - path: '/annotators', - key: 'annotators', - label: 'Gavel annotators', - component: AnnotatorsTab, - }) + // data.push({ + // path: '/annotators', + // key: 'annotators', + // label: 'Gavel annotators', + // component: AnnotatorsTab, + // }) if ( event?.overallReviewMethod === diff --git a/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/winners/index.js b/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/winners/index.js index b160d164d..1b777b90a 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/winners/index.js +++ b/frontend/src/pages/_dashboard/renderDashboard/organiser/projects/winners/index.js @@ -16,6 +16,7 @@ import EventsService from 'services/events' import WinnerVoteService from 'services/winnerVote' import VotingTokenService from 'services/votingToken' +import { debugGroup } from 'utils/debuggingTools' export default () => { const event = useSelector(OrganiserSelectors.event) @@ -86,15 +87,13 @@ export default () => { return ( <> - {total}
Participant votes: {scoreFromUsers}
Token votes: {scoreFromTokenVoters} - ) } - console.log('resus are', results) + debugGroup('Results', results) return ( diff --git a/frontend/src/pages/_dashboard/renderDashboard/participant/index.js b/frontend/src/pages/_dashboard/renderDashboard/participant/index.js index 0e2b74838..16a5c73cb 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/participant/index.js +++ b/frontend/src/pages/_dashboard/renderDashboard/participant/index.js @@ -78,13 +78,6 @@ export default ({ useEffect(() => { setAlerts(originalAlerts) setAlertCount(originalAlertCount) - console.log( - 'set alerts', - alerts, - originalAlerts, - alertCount, - originalAlertCount, - ) }, [originalAlerts, originalAlertCount]) return ( @@ -121,14 +114,6 @@ export default ({ return DefaultPage({ alerts }) }, }, - { - key: 'map', - path: '/map', - exact: false, - icon: , - label: 'Map', - component: MapPage, - }, { key: 'finals', path: '/finalist-voting', @@ -195,11 +180,11 @@ export default ({ key: 'challenges', path: '/challenges', exact: true, + hidden: !shownPages.challengesEnabled, icon: , label: 'Challenges', component: ChallengesIndex, }, - { key: 'calendar', path: '/calendar', @@ -210,6 +195,15 @@ export default ({ component: CalendarPage, }, // Experimental + { + key: 'map', + hidden: !shownPages.experimental, + path: '/map', + exact: false, + icon: , + label: 'Map', + component: MapPage, + }, { key: 'chat', hidden: !shownPages.experimental, diff --git a/frontend/src/pages/_dashboard/renderDashboard/participant/project/ProjectsList.js b/frontend/src/pages/_dashboard/renderDashboard/participant/project/ProjectsList.js index f1bf146a9..dced7d63b 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/participant/project/ProjectsList.js +++ b/frontend/src/pages/_dashboard/renderDashboard/participant/project/ProjectsList.js @@ -4,19 +4,13 @@ import { Paper, Typography, Chip, Box, Grid } from '@material-ui/core' import * as DashboardSelectors from 'redux/dashboard/selectors' -import ProjectScoreModal from 'components/modals/ProjectScoreModal' import Button from 'components/generic/Button' export default props => { const event = useSelector(DashboardSelectors.event) const projects = useSelector(DashboardSelectors.projects) - const projectScores = useSelector(DashboardSelectors.projectScores) - const projectSelectedCallback = props.projectSelectedCallback - const [selectedProjectScore, setSelectedProjectStore] = useState(null) - const [projectScoreModalOpen, setProjectScoreModalOpen] = useState(false) - const [challengeAndTrackSlugState, setChallengeAndTrackSlugState] = useState({}) @@ -35,42 +29,6 @@ export default props => { } setChallengeAndTrackSlugState(challengeAndTrackSlugToNameMap) }, [event]) - - useEffect(() => { - if (projectScoreModalOpen) { - setSelectedProjectStore( - projectScores.find(s => s._id === selectedProjectScore._id), - ) - } - }, [projectScoreModalOpen, projectScores, selectedProjectScore]) - - // const showProjectScore = project => { - // const score = projectScores.find( - // score => score.project._id === project._id, - // ) - // setSelectedProjectStore(score) - // setProjectScoreModalOpen(true) - // } - - // Checks whether there are more unique challenges that the competitor has not submitted - // a solution to yet. - // const canAddMoreSubmissions = () => { - // if (event && event.challenges && projects) { - // const challengesWithSubmittedProjects = [].concat.apply( - // [], - // projects.map(project => project.challenges), - // ) - // return ( - // event.challenges.filter( - // challenge => - // challengesWithSubmittedProjects.indexOf( - // challenge.slug, - // ) < 0, - // ).length > 0 - // ) - // } - // return false - // } const ProjectCard = props => { const project = props.project return ( @@ -114,13 +72,6 @@ export default props => { > Edit Submission - {/**/} @@ -167,11 +118,11 @@ export default props => { ) } - setProjectScoreModalOpen(false)} - /> + /> */} ) } diff --git a/frontend/src/pages/_dashboard/renderDashboard/participant/project/SubmissionForm.js b/frontend/src/pages/_dashboard/renderDashboard/participant/project/SubmissionForm.js index 361c55602..bf9b45239 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/participant/project/SubmissionForm.js +++ b/frontend/src/pages/_dashboard/renderDashboard/participant/project/SubmissionForm.js @@ -12,14 +12,13 @@ import * as DashboardActions from 'redux/dashboard/actions' import * as SnackbarActions from 'redux/snackbar/actions' import * as AuthSelectors from 'redux/auth/selectors' import { makeStyles } from '@material-ui/core/styles' -import { useTranslation } from 'react-i18next' import SubmissionFormCustomInput from 'components/inputs/SubmissionFormCustomInput' import BottomBar from 'components/inputs/BottomBar' import NameField from 'components/projects/ProjectSubmissionFields/NameField' import _ from 'lodash' import StatusField from 'components/projects/ProjectSubmissionFields/StatusField' import ProjectFieldsComponents from 'constants/projectFields' -import { debugGroup } from 'utils/debuggingTools' +import { projectURLgenerator } from 'utils/dataModifiers' const useStyles = makeStyles(theme => ({ uppercase: { 'text-transform': 'uppercase' }, @@ -27,22 +26,19 @@ const useStyles = makeStyles(theme => ({ // TODO make the form labels and hints customizable const SubmissionForm = props => { - debugGroup('SubmissionForm >>', props) const id = props.id + const projectURL = projectURLgenerator(props?.eventSlug, id) const handleProjectSelected = props.handleProjectSelected const classes = useStyles() const dispatch = useDispatch() const event = useSelector(DashboardSelectors.event) const idTokenData = useSelector(AuthSelectors.idTokenData) - const idToken = useSelector(AuthSelectors.getIdToken) - const { t } = useTranslation() const projects = useSelector(DashboardSelectors.projects) const projectLoading = useSelector(DashboardSelectors.projectsLoading) const [project, setProject] = useState(null) const [projectStatus, setProjectStatus] = useState('') useEffect(() => { - debugGroup('useEffect in submissionForm', [project, id]) if (projects && projects.length > 0 && id) { const foundProject = projects.find(p => p._id === id) setProject(foundProject) @@ -94,7 +90,10 @@ const SubmissionForm = props => { }, [event]) const locationEnabled = useMemo(() => { - return event.eventType === EventTypes.physical.id + return ( + event.eventType === EventTypes.physical.id || + event.eventType === EventTypes.hybrid.id + ) }, [event]) const valuesFormatter = values => { @@ -104,6 +103,7 @@ const SubmissionForm = props => { event.submissionFormQuestions.forEach(section => { const sec = section.name section.questions.forEach(question => { + const label = question?.label const que = question.name const value = values[que] const custom = { @@ -111,11 +111,11 @@ const SubmissionForm = props => { key: que, value: value, } + if (label) custom['label'] = label formData['submissionFormAnswers'].push(custom) }) }) } - console.log('formData after formatting:>> ', formData) return formData } @@ -166,10 +166,27 @@ const SubmissionForm = props => { > {projectStatus} - - Remember to update the project status to final if you - want this project to be graded! - + {projectStatus !== 'final' ? ( + + Remember to update the project status to final if + you want this project to be graded! + + ) : ( + projectURL && ( + <> + + Your project's public URL is: + + + {projectURL} + + + ) + )} @@ -276,7 +293,6 @@ const SubmissionForm = props => { ) } } catch (error) { - console.error('An error occurred:', error) dispatch( SnackbarActions.error('Oops, something went wrong...', { autoHideDuration: 10000, diff --git a/frontend/src/pages/_dashboard/renderDashboard/participant/project/index.js b/frontend/src/pages/_dashboard/renderDashboard/participant/project/index.js index 437d42134..1edf7859e 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/participant/project/index.js +++ b/frontend/src/pages/_dashboard/renderDashboard/participant/project/index.js @@ -223,6 +223,7 @@ export default () => { )} diff --git a/frontend/src/pages/_dashboard/renderDashboard/participant/reviewing/CompareProjects.js b/frontend/src/pages/_dashboard/renderDashboard/participant/reviewing/CompareProjects.js index cdd023b84..afcdffc31 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/participant/reviewing/CompareProjects.js +++ b/frontend/src/pages/_dashboard/renderDashboard/participant/reviewing/CompareProjects.js @@ -102,7 +102,8 @@ export default ({ annotator, prevId, nextId, isFirstChoice }) => { { { { const dispatch = useDispatch() const team = useSelector(DashboardSelectors.team) const event = useSelector(DashboardSelectors.event) + const registration = useSelector(DashboardSelectors.registration) const annotator = useSelector(DashboardSelectors.annotator) const annotatorError = useSelector(DashboardSelectors.annotatorError) const annotatorLoading = useSelector(DashboardSelectors.annotatorLoading) @@ -40,32 +44,169 @@ export default () => { ) } - if (!annotator) { - return + if (registration?.gavelLogin) { + return ( +
+ + + { + if (completed) { + return ( + { + if (!completed) { + return ( + <> + + The reviewing + period is open! + Time left:{' '} + { + formatted.hours + } + : + { + formatted.minutes + } + : + { + formatted.seconds + } + + + Once you click + "Start + reviewing", a + new tab will + open on your + browser were you + can start + reviewing the + projects. + + +

+ Copy this link + if for some + reason the + button doesn't + work: + { + registration?.gavelLogin + } +

+ + ) + } else { + return ( + + The reviewing period + is over! Thanks for + participating! + + ) + } + }} + /> + ) + } else { + return ( + <> + + The reviewing period begins in{' '} + {formatted.hours}: + {formatted.minutes}: + {formatted.seconds} + + + Come back here then! + + + ) + } + }} + /> +
+
+ ) } - if (!annotator.active) { - return - } + return - if (!annotator.prev && annotator.next) { - return - } + // if (!annotator) { + // return + // } - if (annotator.prev && annotator.next) { - return ( - - ) - } + // if (!annotator.active) { + // return + // } + + // if (!annotator.prev && annotator.next) { + // return + // } + + // if (annotator.prev && annotator.next) { + // return ( + // + // ) + // } - return + // return } - console.log("annotator", annotator, annotatorError) + // console.log("annotator", annotator, annotatorError) return ( {renderContent()} diff --git a/frontend/src/pages/_dashboard/renderDashboard/participant/team/teams/index.js b/frontend/src/pages/_dashboard/renderDashboard/participant/team/teams/index.js index a409ebfc9..822652da4 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/participant/team/teams/index.js +++ b/frontend/src/pages/_dashboard/renderDashboard/participant/team/teams/index.js @@ -21,7 +21,7 @@ export default () => { const dispatch = useDispatch() const event = useSelector(DashboardSelectors.event) const { slug } = event - + //TODO create pagination component const teams = useSelector(DashboardSelectors.teams) const hasTeam = useSelector(DashboardSelectors.hasTeam) const [selected, setSelected] = useState(false) @@ -90,8 +90,6 @@ export default () => { }, [currentPage]) const renderPagination = () => { - console.log('props', currentPage, totalResults, totalPages) - return ( ({ sidebarTop: { padding: theme.spacing(3), @@ -45,7 +46,13 @@ const useStyles = makeStyles(theme => ({ }, })) -export default ({ event, originalAlertCount, originalAlerts, shownPages }) => { +export default ({ + event, + originalAlertCount, + originalAlerts, + shownPages, + lockedPages, +}) => { const classes = useStyles() const { t } = useTranslation() const match = useRouteMatch() @@ -53,11 +60,6 @@ export default ({ event, originalAlertCount, originalAlerts, shownPages }) => { const [alertCount, setAlertCount] = useState(originalAlertCount) const [alerts, setAlerts] = useState(originalAlerts) - // const event = useSelector(DashboardSelectors.event) - - console.log('props', originalAlertCount, originalAlerts, shownPages) - console.log(originalAlertCount, alertCount) - return ( { component: () => { setAlertCount(0) if (shownPages?.experimental) { - return

Test

+ return

Experimental enabled

} return DefaultPage({ alerts }) }, }, - { - key: 'map', - path: '/map', - exact: false, - icon: , - label: 'Map', - component: MapPage, - }, { key: 'Review', - path: '/Review', - hidden: !shownPages?.reviewingByScoreCriteria, + path: '/review', + // hidden: !shownPages?.reviewingByScoreCriteria, + locked: lockedPages.reviewing, + lockedDescription: 'Reviewing closed', exact: false, icon: , label: 'Review', @@ -119,7 +115,7 @@ export default ({ event, originalAlertCount, originalAlerts, shownPages }) => { }, }, { - key: 'calendar', + key: 'meetings', path: '/calendar', exact: true, hidden: !shownPages?.meetings, @@ -127,6 +123,15 @@ export default ({ event, originalAlertCount, originalAlerts, shownPages }) => { label: 'Meetings', component: CalendarPage, }, + { + key: 'hackerpack', + path: '/hackerpack', + exact: true, + icon: , + hidden: !shownPages?.hackerPack, + label: t('Hackerpack_'), + component: HackerpackPage, + }, { key: 'recruitment', path: '/recruitment', @@ -134,17 +139,18 @@ export default ({ event, originalAlertCount, originalAlerts, shownPages }) => { icon: , label: 'Recruitment', component: RecruitmentPage, + locked: true, + lockedDescription: 'Currently unavailable', }, //Experimental { - key: 'hackerpack', - path: '/hackerpack', - exact: true, - icon: , - hidden: - !shownPages?.experimental && !shownPages?.hackerPack, - label: t('Hackerpack_'), - component: HackerpackPage, + key: 'map', + path: '/map', + exact: false, + icon: , + hidden: !shownPages?.experimental, + label: 'Map', + component: MapPage, }, { key: 'challenges', diff --git a/frontend/src/pages/_dashboard/renderDashboard/partner/partnerrecruitment/default/SearchResults/index.js b/frontend/src/pages/_dashboard/renderDashboard/partner/partnerrecruitment/default/SearchResults/index.js index 2e1a0a813..6450ed5ba 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/partner/partnerrecruitment/default/SearchResults/index.js +++ b/frontend/src/pages/_dashboard/renderDashboard/partner/partnerrecruitment/default/SearchResults/index.js @@ -2,7 +2,7 @@ import React, { useEffect } from 'react' import Empty from 'components/generic/Empty' import ResultCard from './ResultCard' import { useDispatch, useSelector } from 'react-redux' -import { useRouteMatch } from 'react-router' +// import { useRouteMatch } from 'react-router' import { Grid, Box, Typography, CircularProgress } from '@material-ui/core' import * as RecruitmentSelectors from 'redux/recruitment/selectors' @@ -11,10 +11,11 @@ import * as DashboardActions from 'redux/dashboard/actions' import { useTranslation } from 'react-i18next' import Pagination from './Pagination' import LoadingCard from './LoadingCard' +import { debugGroup } from 'utils/debuggingTools' export default ({ items, organisation }) => { const dispatch = useDispatch() - const match = useRouteMatch() + // const match = useRouteMatch() const searchResults = items ?? useSelector(RecruitmentSelectors.searchResults) const searchResultsCount = useSelector( @@ -26,9 +27,15 @@ export default ({ items, organisation }) => { const page = useSelector(RecruitmentSelectors.page) const paginationEnabled = !items const isFavorited = !!items - const { slug } = match.params + // const { slug } = match.params const { t } = useTranslation() + debugGroup('RecruitmentSearchResults', [ + useSelector(RecruitmentSelectors.searchResults), + searchResults, + searchResultsCount, + ]) + useEffect(() => { //dispatch(DashboardActions.updateEvent(slug)) dispatch(RecruitmentActions.updateSearchResults()) @@ -50,7 +57,7 @@ export default ({ items, organisation }) => { xs={12} sm={6} md={4} - //lg={3} + //lg={3} >
@@ -84,7 +91,7 @@ export default ({ items, organisation }) => { xs={12} sm={6} md={4} - //lg={3} + //lg={3} > diff --git a/frontend/src/pages/_dashboard/renderDashboard/partner/partnerrecruitment/default/index.js b/frontend/src/pages/_dashboard/renderDashboard/partner/partnerrecruitment/default/index.js index a28120fe8..484d08108 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/partner/partnerrecruitment/default/index.js +++ b/frontend/src/pages/_dashboard/renderDashboard/partner/partnerrecruitment/default/index.js @@ -1,8 +1,6 @@ - - import React, { useEffect, useState } from 'react' -import { makeStyles } from '@material-ui/core/styles' +// import { makeStyles } from '@material-ui/core/styles' import { Box } from '@material-ui/core' import { useSelector, useDispatch } from 'react-redux' @@ -20,25 +18,26 @@ import * as AuthSelectors from 'redux/auth/selectors' import ToggleFavorites from './ToggleFavorites' import { useTranslation } from 'react-i18next' import { useToggle } from 'hooks/customHooks' +import { debugGroup } from 'utils/debuggingTools' -const useStyles = makeStyles(theme => ({ - root: { - flex: 1, - backgroundColor: theme.palette.background.default, - padding: theme.spacing(3), - }, -})) +// const useStyles = makeStyles(theme => ({ +// root: { +// flex: 1, +// backgroundColor: theme.palette.background.default, +// padding: theme.spacing(3), +// }, +// })) export default () => { const { t } = useTranslation() - const classes = useStyles() + // const classes = useStyles() const dispatch = useDispatch() const idTokenData = useSelector(AuthSelectors.idTokenData) const favorites = useSelector(RecruitmentSelectors.favorites) - const event = useSelector(DashboardSelectors.event)._id + const eventId = useSelector(DashboardSelectors.event)._id const recEvents = useSelector(UserSelectors.userProfileRecruiterEvents) - const [recruiterOrganisation, SetRecruiterOrganisation] = useState("") + const [recruiterOrganisation, SetRecruiterOrganisation] = useState('') const [showFavorites, toggleFavorites] = useToggle(false) useEffect(() => { @@ -55,14 +54,14 @@ export default () => { //dispatch(RecruitmentActions.updateEvents()) const organisation = recEvents.find(e => { - return e.eventId === event + return e.eventId === eventId }).organisation SetRecruiterOrganisation(organisation) dispatch(RecruitmentActions.updateActionHistory(organisation)) }, [dispatch]) - + debugGroup('Recruitment', [recruiterOrganisation, recEvents]) return ( <> @@ -74,20 +73,24 @@ export default () => { justifyContent="flex-end" mb={2} > - -
+ {showFavorites ? ( - + ) : ( <> - + )} @@ -96,5 +99,3 @@ export default () => { ) } - - diff --git a/frontend/src/pages/_dashboard/renderDashboard/partner/partnerrecruitment/index.js b/frontend/src/pages/_dashboard/renderDashboard/partner/partnerrecruitment/index.js index 89ce8d54c..b679e9c9a 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/partner/partnerrecruitment/index.js +++ b/frontend/src/pages/_dashboard/renderDashboard/partner/partnerrecruitment/index.js @@ -1,7 +1,13 @@ import React, { useEffect, useLayoutEffect } from 'react' import { useRouteMatch } from 'react-router' import { useDispatch } from 'react-redux' -import { Switch, Route, Redirect, useLocation, useParams } from 'react-router-dom' +import { + Switch, + Route, + Redirect, + useLocation, + useParams, +} from 'react-router-dom' import PageWrapper from 'components/layouts/PageWrapper' import * as RecruitmentActions from 'redux/recruitment/actions' @@ -9,15 +15,14 @@ import * as RecruitmentActions from 'redux/recruitment/actions' import GlobalNavBar from 'components/navbars/GlobalNavBar' import SearchPage from './default' -import AdminPage from './admin' +// import AdminPage from './admin' import DetailPage from './id' export default () => { - const dispatch = useDispatch() - const location = useLocation() + // const dispatch = useDispatch() + // const location = useLocation() const match = useRouteMatch() - //console.log(match.url) return ( @@ -29,47 +34,16 @@ export default () => { path={`${match.url}/:id`} component={DetailPage} /> + {/* */} ) } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // import React, { useEffect, useRef } from 'react' // import FormControl from '@material-ui/core/FormControl' // import FormGroup from '@material-ui/core/FormGroup' @@ -82,9 +56,6 @@ export default () => { // export default () => { - - - // return ( // <> // {/* button for DEV to swithc between participant / partner view */} @@ -101,4 +72,4 @@ export default () => { // // // ) -// } \ No newline at end of file +// } diff --git a/frontend/src/pages/_dashboard/renderDashboard/partner/projects/index.js b/frontend/src/pages/_dashboard/renderDashboard/partner/projects/index.js index 63cb6f63f..ea246726b 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/partner/projects/index.js +++ b/frontend/src/pages/_dashboard/renderDashboard/partner/projects/index.js @@ -7,7 +7,6 @@ import PageHeader from 'components/generic/PageHeader' import ProjectsGrid from 'components/projects/ProjectsGrid' import ProjectsService from 'services/projects' -import Filter from 'components/Team/Filter' import _ from 'lodash' import ProjectDetail from 'components/projects/ProjectDetail' @@ -17,7 +16,6 @@ import ProjectScoresService from 'services/projectScores' import EvaluationForm from 'pages/_projects/slug/view/projectId/EvaluationForm' import Empty from 'components/generic/Empty' import * as SnackbarActions from 'redux/snackbar/actions' -import ScoreForm from 'pages/_projects/slug/view/projectId/ScoreForm' const projectScoreBase = { project: '', @@ -37,16 +35,12 @@ export default ({ event }) => { const idToken = useSelector(AuthSelectors.getIdToken) const userId = useSelector(AuthSelectors.getUserId) const userProfile = useSelector(userSelectors.userProfile) - const allFilterLabel = 'All projects' const dispatch = useDispatch() const { slug } = event const [data, setData] = useState({}) const [projects, setProjects] = useState([]) - const [draftsProjects, setDraftsProjects] = useState([]) - const [finalProjects, setFinalProjects] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(false) - const [filter, setFilter] = useState(allFilterLabel) const [selected, setSelected] = useState(null) const [scoreExists, setScoreExists] = useState(false) @@ -55,10 +49,7 @@ export default ({ event }) => { const resetProjectData = () => { setSelected(null) setScoreExists(false) - } - - const onFilterChange = filter => { - setFilter(filter) + setProjectScore(projectScoreBase) } if (event.scoreCriteriaSettings === undefined) { @@ -68,46 +59,21 @@ export default ({ event }) => { const fetchProjects = useCallback(async () => { setLoading(true) try { - const dataOt = await ProjectsService.getProjectsByEvent(slug) - const partnerData = _.find( - event.recruiters, - recruiter => recruiter.recruiterId === userId, + const dataOt = await ProjectsService.getProjectsByEventAsPartner( + idToken, + slug, ) - let challengeOrg - let filteredProjects = [] const data = { event, - } - if (event.scoreCriteriaSettings.reviewAnyChallenge) { - data.projects = dataOt - } else if (partnerData) { - challengeOrg = _.find( - event.challenges, - challenge => challenge.partner === partnerData.organization, - ) - if (challengeOrg) { - data.challenge = challengeOrg - filteredProjects = _.filter(dataOt, project => - _.includes(project.challenges, challengeOrg.slug), - ) - if (filteredProjects.length > 0) { - data.projects = filteredProjects - } - } + ...dataOt, } setData(data) - setDraftsProjects( - data.projects.filter(project => project.status === 'draft'), - ) - setFinalProjects( - data.projects.filter(project => project.status === 'final'), - ) setProjects(data.projects) } catch (err) { - console.log("err", err) setError(true) + } finally { + setLoading(false) } - setLoading(false) }, [slug, idToken, projectScore]) const handleSubmit = async (values, { setSubmitting, resetForm }) => { @@ -153,7 +119,6 @@ export default ({ event }) => { submissionValues, ) } else { - console.log("no score") await ProjectScoresService.addScoreByEventSlugAndProjectIdAndPartnerAccount( idToken, event.slug, @@ -182,6 +147,7 @@ export default ({ event }) => { return null } + //TODO perform this on the backend useEffect(() => { if (idToken && selected && event) { ProjectScoresService.getScoreByEventSlugAndProjectIdAndPartnerAccount( @@ -189,7 +155,6 @@ export default ({ event }) => { event.slug, selected._id, ).then(score => { - console.log('Score', score) if (score[0]) { const reviewerData = _.find( score[0].reviewers, @@ -221,17 +186,6 @@ export default ({ event }) => { } }, [event, idToken, selected]) - const projectsToRender = filter => { - switch (filter) { - case 'draft': - return draftsProjects - case 'final': - return finalProjects - default: - return projects - } - } - const renderProjects = inputData => { return ( <> @@ -241,31 +195,25 @@ export default ({ event }) => { heading={inputData?.challenge.name} subheading={`By ${inputData?.challenge.partner}`} alignment="left" - details={`${inputData?.projects.length} project${inputData?.projects.length > 1 || + details={`${inputData?.projects.length} project${ + inputData?.projects.length > 1 || inputData?.projects.length < 1 - ? 's' - : '' - }`} + ? 's' + : '' + }`} /> )} - @@ -284,22 +232,15 @@ export default ({ event }) => { {idToken ? ( {scoreCriteriaBase && - scoreCriteriaBase.length > 0 ? ( - - ) : ( - - )} + scoreCriteriaBase.length > 0 && ( + + )} ) : null} diff --git a/frontend/src/pages/_events/slug/context.js b/frontend/src/pages/_events/slug/context.js index 4a978bbf0..74b2c024b 100644 --- a/frontend/src/pages/_events/slug/context.js +++ b/frontend/src/pages/_events/slug/context.js @@ -194,7 +194,6 @@ export const EventDetailProvider = ({ children }) => { }) const createRegistration = useCallback( formData => { - console.log('creatin regigiigi', idToken, slug, formData) return RegistrationsService.createRegistration( idToken, slug, diff --git a/frontend/src/pages/_events/slug/register/RegistrationSection/index.js b/frontend/src/pages/_events/slug/register/RegistrationSection/index.js index 3e0fce984..ee7a9a479 100644 --- a/frontend/src/pages/_events/slug/register/RegistrationSection/index.js +++ b/frontend/src/pages/_events/slug/register/RegistrationSection/index.js @@ -107,7 +107,7 @@ export default props => {
diff --git a/frontend/src/pages/_events/slug/register/index.js b/frontend/src/pages/_events/slug/register/index.js index fcac225e1..ab8da2982 100644 --- a/frontend/src/pages/_events/slug/register/index.js +++ b/frontend/src/pages/_events/slug/register/index.js @@ -279,8 +279,10 @@ export default RequiresPermission(() => { const sec = section.name section.questions.forEach(question => { const que = question.name + const label = question?.label || 'custom question' const value = formData[sec][que] const custom = { + label: label, section: sec, key: que, value: value + '', diff --git a/frontend/src/pages/_projects/slug/challenge/token/index.js b/frontend/src/pages/_projects/slug/challenge/token/index.js index e715d8fcb..2e4440fc6 100644 --- a/frontend/src/pages/_projects/slug/challenge/token/index.js +++ b/frontend/src/pages/_projects/slug/challenge/token/index.js @@ -7,7 +7,6 @@ import PageWrapper from 'components/layouts/PageWrapper' import Container from 'components/generic/Container' import PageHeader from 'components/generic/PageHeader' import ProjectsGrid from 'components/projects/ProjectsGrid' -import { makeStyles } from '@material-ui/core/styles' import ProjectsService from 'services/projects' import Filter from 'components/Team/Filter' @@ -17,12 +16,8 @@ import _ from 'lodash' export default ({ event }) => { const baseFilter = { value: 'final', label: 'Final projects' } const match = useRouteMatch() - console.log('match', match) - console.log('match URL', match.url) const dispatch = useDispatch() const { slug } = event - const { reviewMethod } = event - console.log('event data', event) const { token } = match.params const [data, setData] = useState({}) const [projects, setProjects] = useState([]) @@ -111,7 +106,8 @@ export default ({ event }) => { onSelect={project => dispatch(push(`${match.url}/view/${project._id}`)) } - showScore={reviewMethod === 'manualReview'} + showScore={true} + showReviewers={true} token={token} /> diff --git a/frontend/src/pages/_projects/slug/view/projectId/EvaluationForm.js b/frontend/src/pages/_projects/slug/view/projectId/EvaluationForm.js index 069a2974d..d0af0a652 100644 --- a/frontend/src/pages/_projects/slug/view/projectId/EvaluationForm.js +++ b/frontend/src/pages/_projects/slug/view/projectId/EvaluationForm.js @@ -1,6 +1,5 @@ -import React, { useState } from 'react' -import { Formik, Form, Field, ErrorMessage } from 'formik' -import Button from 'components/generic/Button' +import React from 'react' +import { Formik, Form, Field } from 'formik' import { Box, Typography } from '@material-ui/core' import RadioScore from 'components/generic/RadioScore' import TextAreaInput from 'components/inputs/TextAreaInput' @@ -8,15 +7,7 @@ import FormControl from 'components/inputs/FormControl' import BottomBar from 'components/inputs/BottomBar' import _ from 'lodash' -const EvaluationForm = ({ - event, - project, - submit = () => {}, - score, - scoreCriteria, -}) => { - console.log('Score from eval form', score) - +const EvaluationForm = ({ submit = () => {}, score, scoreCriteria }) => { const allScoresSet = evalScores => { const scoreList = evalScores.map(value => { return value?.score ? value.score : null @@ -26,16 +17,13 @@ const EvaluationForm = ({ const calculateScore = (criterias, decimalPlaces) => { const multiplier = Math.pow(10, decimalPlaces) - console.log('Multiplier', multiplier) const scoreAverage = criterias.reduce((acc, curr) => { if (!curr.score) return acc return curr.score + acc }, 0) / criterias.length - console.log('Score average before format', scoreAverage) const scoreAverageFormatted = Math.floor(scoreAverage * multiplier) / multiplier - console.log('Score average', scoreAverageFormatted) return scoreAverageFormatted } @@ -54,23 +42,14 @@ const EvaluationForm = ({ score.scoreCriteria = scoreFiltered } - // if (score.scoreCriteria.map) { - return ( <> {formikProps => { - console.log('formikProps from EvaluationForm', formikProps) return (
@@ -93,10 +72,6 @@ const EvaluationForm = ({ { criteria, label }, index, ) => { - console.log( - 'Field value at evaluationForm', - field.value, - ) return ( form.setFieldTouched(field.name) } + minRows={2} + maxLength={500} /> )} diff --git a/frontend/src/pages/_projects/slug/view/projectId/index.js b/frontend/src/pages/_projects/slug/view/projectId/index.js index c6060cba3..75ebee171 100644 --- a/frontend/src/pages/_projects/slug/view/projectId/index.js +++ b/frontend/src/pages/_projects/slug/view/projectId/index.js @@ -1,77 +1,22 @@ import React, { useState, useEffect, useCallback } from 'react' import { goBack } from 'connected-react-router' -import { useDispatch, useSelector } from 'react-redux' +import { useDispatch } from 'react-redux' import { useRouteMatch } from 'react-router' import PageWrapper from 'components/layouts/PageWrapper' import ProjectDetail from 'components/projects/ProjectDetail' import ShareProject from 'components/projects/ProjectDetail/ShareProject' -import ScoreForm from './ScoreForm' -import Container from 'components/generic/Container' -import * as AuthSelectors from 'redux/auth/selectors' -import * as UserSelectors from 'redux/user/selectors' import moment from 'moment-timezone' import { EventHelpers } from '@hackjunction/shared' - -import * as SnackbarActions from 'redux/snackbar/actions' - import ProjectsService from 'services/projects' -import ProjectScoresService from 'services/projectScores' -import { set } from 'object-path' -import EvaluationForm from './EvaluationForm' import _ from 'lodash' export default ({ event, showFullTeam }) => { - const scoreCriteriaBase = event.scoreCriteriaSettings?.scoreCriteria const dispatch = useDispatch() - const userId = useSelector(AuthSelectors.getUserId) const match = useRouteMatch() - const { projectId, token } = match.params - const { slug } = event - const [scoreExists, setScoreExists] = useState(false) + const { projectId } = match.params const [project, setProject] = useState() const [loading, setLoading] = useState(true) const [error, setError] = useState(false) - const [validToken, setValidToken] = useState(false) - - useEffect(() => { - if (token && project && event) { - ProjectsService.validateToken(slug, token).then(v => { - if (v) setValidToken(v) - }) - } - }, [event, project, slug, token]) - - const [projectScore, setProjectScore] = useState({ - project: '', - event: '', - status: 'submitted', - score: 0, - maxScore: 10, - message: '', - scoreCriteria: [], - reviewers: [], - }) - - useEffect(() => { - if (token && project && event) { - ProjectScoresService.getScoreByEventSlugAndProjectIdAndPartnerToken( - token, - event.slug, - project._id, - ).then(score => { - console.log('Score', score) - if (score[0]) { - setProjectScore(score[0]) - setScoreExists(true) - } else { - setProjectScore({ - ...projectScore, - scoreCriteria: scoreCriteriaBase, - }) - } - }) - } - }, [event, token, project]) const fetchProject = useCallback(async () => { setLoading(true) @@ -79,7 +24,6 @@ export default ({ event, showFullTeam }) => { const project = await ProjectsService.getPublicProjectById( projectId, ) - console.log('Project details', project) setProject(project) } catch (err) { setError(true) @@ -88,45 +32,6 @@ export default ({ event, showFullTeam }) => { } }, [projectId]) - const handleSubmit = async (values, { setSubmitting, resetForm }) => { - values.project = project._id - values.event = event._id - console.log('values', values) - try { - if (userId) { - _.includes(values.reviewers, userId) - ? console.log('User already in reviewers list') - : values.reviewers.push(userId) - } - if (scoreExists) { - await ProjectScoresService.updateScoreByEventSlugAndPartnerToken( - token, - event.slug, - values, - ) - setProjectScore(values) - } else { - await ProjectScoresService.addScoreByEventSlugAndPartnerToken( - token, - event.slug, - values, - ) - setProjectScore(values) - } - - dispatch(SnackbarActions.success(`Score saved.`)) - resetForm() - } catch (e) { - dispatch( - SnackbarActions.error( - `Score could not be saved. Error: ${e.message}`, - ), - ) - } finally { - setSubmitting(false) - } - } - const onBack = useCallback(() => { dispatch(goBack()) }, [dispatch]) @@ -143,26 +48,7 @@ export default ({ event, showFullTeam }) => { showFullTeam={showFullTeam} showTableLocation={!EventHelpers.isEventOver(event, moment)} /> - {validToken ? ( - - {scoreCriteriaBase && scoreCriteriaBase.length > 0 ? ( - - ) : ( - - )} - - ) : null} + ) diff --git a/frontend/src/redux/dashboard/actions.js b/frontend/src/redux/dashboard/actions.js index 4fef90bf9..4e693d0d9 100644 --- a/frontend/src/redux/dashboard/actions.js +++ b/frontend/src/redux/dashboard/actions.js @@ -480,15 +480,11 @@ export const updateProjects = slug => async (dispatch, getState) => { export const createProject = (slug, data) => async (dispatch, getState) => { try { const idToken = AuthSelectors.getIdToken(getState()) - const fileData = await fileAttachmentFinder(data, idToken) + // const fileData = await fileAttachmentFinder(data, idToken) - if (fileData) { - await ProjectsService.createProjectForEventAndTeam( - idToken, - slug, - fileData, - ) - } + // if (fileData) { + // } + await ProjectsService.createProjectForEventAndTeam(idToken, slug, data) const projects = await ProjectsService.getProjectsForEventAndTeam( idToken, slug, @@ -656,15 +652,11 @@ export const deleteFileForProject = fileId => async (dispatch, getState) => { export const editProject = (slug, data) => async (dispatch, getState) => { try { const idToken = AuthSelectors.getIdToken(getState()) - const fileData = await fileAttachmentFinder(data, idToken) + // const fileData = await fileAttachmentFinder(data, idToken) - if (fileData) { - await ProjectsService.updateProjectForEventAndTeam( - idToken, - slug, - fileData, - ) - } + // if (fileData) { + // } + await ProjectsService.updateProjectForEventAndTeam(idToken, slug, data) const projects = await ProjectsService.getProjectsForEventAndTeam( idToken, slug, diff --git a/frontend/src/redux/dashboard/reducer.js b/frontend/src/redux/dashboard/reducer.js index 4d8f0e4ff..6fe5db813 100644 --- a/frontend/src/redux/dashboard/reducer.js +++ b/frontend/src/redux/dashboard/reducer.js @@ -51,12 +51,12 @@ const initialState = { error: false, updated: 0, }, - project_scores: { - data: [], - loading: true, - error: false, - updated: 0, - }, + // project_scores: { + // data: [], + // loading: true, + // error: false, + // updated: 0, + // }, } const updateEventHandler = buildHandler('event') @@ -66,7 +66,7 @@ const eventRecruitersHandler = buildHandler('recruiters', 'userId') const updateTeamHandler = buildHandler('team') const updateProjectsHandler = buildHandler('projects', '_id') const updateAnnotatorHandler = buildHandler('annotator') -const updateProjectScoresHandler = buildHandler('project_scores') +// const updateProjectScoresHandler = buildHandler('project_scores') const updateTeamsHandler = buildHandler('teams') const updateSelectedTeamHandler = buildHandler('selected_team') // const updateSeletecUserHandler = buildHandler('selected_candidate') @@ -95,9 +95,9 @@ export default function reducer(state = initialState, action) { case ActionTypes.UPDATE_ANNOTATOR: { return updateAnnotatorHandler(state, action) } - case ActionTypes.UPDATE_PROJECT_SCORES: { - return updateProjectScoresHandler(state, action) - } + // case ActionTypes.UPDATE_PROJECT_SCORES: { + // // return updateProjectScoresHandler(state, action) + // } case ActionTypes.EDIT_REGISTRATION: { return editRegistration(state, action.payload) } diff --git a/frontend/src/redux/dashboard/selectors.js b/frontend/src/redux/dashboard/selectors.js index b79c6cb05..78bd16784 100644 --- a/frontend/src/redux/dashboard/selectors.js +++ b/frontend/src/redux/dashboard/selectors.js @@ -58,12 +58,12 @@ export const annotatorLoading = state => state.dashboard.annotator.loading export const annotatorError = state => state.dashboard.annotator.error export const annotatorUpdated = state => state.dashboard.annotator.updated -export const projectScores = state => state.dashboard.project_scores.data -export const projectScoresLoading = state => - state.dashboard.project_scores.loading -export const projectScoresError = state => state.dashboard.project_scores.error -export const projectScoresUpdated = state => - state.dashboard.project_scores.updated +// export const projectScores = state => state.dashboard.project_scores.data +// export const projectScoresLoading = state => +// state.dashboard.project_scores.loading +// export const projectScoresError = state => state.dashboard.project_scores.error +// export const projectScoresUpdated = state => +// state.dashboard.project_scores.updated export const annotatorVoteCount = createSelector(annotator, annotator => { if (!annotator) return 0 @@ -146,7 +146,7 @@ export const isTeamValid = createSelector(team, team => { export const lockedPages = createSelector(event, event => { return { submissions: !EventHelpers.isSubmissionsOpen(event, moment), - reviewing: EventHelpers.isVotingPast(event, moment), + reviewing: !EventHelpers.isReviewingOpen(event, moment), team: EventHelpers.isSubmissionsPast(event, moment), finalistVoting: !EventHelpers.isFinalistVotingOpen(event, moment), } @@ -161,7 +161,8 @@ export const shownPages = createSelector( return { submissions: registration?.status === STATUSES.checkedIn.id, eventID: - event?.eventType === EventTypes.physical.id && + (event?.eventType === EventTypes.physical.id || + event?.eventType === EventTypes.hybrid.id) && [ STATUSES.confirmed.id, STATUSES.confirmedToHub.id, @@ -177,12 +178,14 @@ export const shownPages = createSelector( registration?.status === STATUSES.checkedIn.id && event?.overallReviewMethod !== 'noOverallWinner', hackerPack: + (event?.hackerpacksEnabled ?? false) && [ STATUSES.checkedIn.id, STATUSES.confirmed.id, STATUSES.confirmedToHub.id, ].indexOf(registration?.status) !== -1, meetings: EventHelpers.areMeetingsEnabled(event), + challengesEnabled: event?.challengesEnabled, reviewingByScoreCriteria: event?.reviewMethod === ReviewingMethods.manualReview.id, //Experimental diff --git a/frontend/src/routes.js b/frontend/src/routes.js index 9979dc7c2..cb8465f48 100644 --- a/frontend/src/routes.js +++ b/frontend/src/routes.js @@ -18,14 +18,18 @@ import RequiresRole from 'hocs/RequiresRole' /** Lazy-load the access-restricted pages */ const DashboardRouter = lazy(() => import('./pages/_dashboard')) -const OrganiserRouter = lazy(() => import('./pages/_dashboard/renderDashboard/organiser/router')) +const OrganiserRouter = lazy(() => + import('./pages/_dashboard/renderDashboard/organiser/router'), +) const AccountRouter = lazy(() => import('./pages/_account')) //TODO: switch the recruitment view and router -const RecruitmentRouter = lazy(() => import('./pages/_dashboard/renderDashboard/partner/partnerrecruitment'))//import('./pages/_recruitment'))// +const RecruitmentRouter = lazy(() => + import('./pages/_dashboard/renderDashboard/partner/partnerrecruitment'), +) //import('./pages/_recruitment'))// const ProjectsRouter = lazy(() => import('./pages/_projects')) const AdminRouter = lazy(() => import('./pages/_admin')) const SandboxRouter = lazy(() => import('./pages/_sandbox')) -const FilesRouter = lazy(() => import('./pages/_sandbox/files')) +// const FilesRouter = lazy(() => import('./pages/_sandbox/files')) const routes = [ { @@ -76,7 +80,8 @@ const routes = [ ]),*/ exact: false, }, - {//default after login + { + //default after login path: '/dashboard', component: RequiresPermission(DashboardRouter), exact: false, diff --git a/frontend/src/services/projects.js b/frontend/src/services/projects.js index 4ca7541be..552061bc2 100644 --- a/frontend/src/services/projects.js +++ b/frontend/src/services/projects.js @@ -13,6 +13,10 @@ ProjectsService.getProjectsByEvent = eventSlug => { return _axios.get(`/projects/${eventSlug}`) } +ProjectsService.getProjectsByEventAsPartner = (idToken, eventSlug) => { + return _axios.get(`/projects/${eventSlug}/partner-review`, config(idToken)) +} + ProjectsService.getPublicProjectById = projectId => { return _axios.get(`/projects/id/${projectId}`) } diff --git a/frontend/src/services/registrations.js b/frontend/src/services/registrations.js index fc612675d..36f0f019a 100644 --- a/frontend/src/services/registrations.js +++ b/frontend/src/services/registrations.js @@ -215,11 +215,12 @@ RegistrationsService.adminNotifyAcceptedTravelGrants = (idToken, slug) => { ) } -RegistrationsService.addPartnerToRegistrated = (idToken, - user, - slug, - data) => { +RegistrationsService.addPartnerToRegistrated = (idToken, user, slug, data) => { return _axios.post(`${BASE_ROUTE}/${slug}/partner`, user, config(idToken)) } +RegistrationsService.addGavelLoginToRegistrations = (idToken, slug, data) => { + return _axios.post(`${BASE_ROUTE}/${slug}/gavel`, data, config(idToken)) +} + export default RegistrationsService diff --git a/frontend/src/utils/dataModifiers.js b/frontend/src/utils/dataModifiers.js index bb7fa0713..da7eee689 100644 --- a/frontend/src/utils/dataModifiers.js +++ b/frontend/src/utils/dataModifiers.js @@ -18,3 +18,13 @@ export const removeNumbers = (str, replace = '') => { export const generateSlug = (str, replaceNumValue = '') => { return getSlug(removeNumbers(str, replaceNumValue)) } + +export const projectURLgenerator = (eventSlug, projectId) => { + //Utility to generate public project URL, with the shape /projects/:eventSlug/view/:projectId + const originURL = window.location.origin + let projectURL + if (!!projectId && !!eventSlug && !!originURL) { + projectURL = `${originURL}/projects/${eventSlug}/view/${projectId}` + } + return projectURL +} diff --git a/shared/constants/event-types.js b/shared/constants/event-types.js index 5959aeefc..c00aa9d0e 100644 --- a/shared/constants/event-types.js +++ b/shared/constants/event-types.js @@ -7,6 +7,10 @@ const EventTypes = { id: 'online', label: 'Online event', }, + hybrid: { + id: 'hybrid', + label: 'Hybrid event', + }, } module.exports = EventTypes diff --git a/shared/constants/project-schema.js b/shared/constants/project-schema.js index 70466d731..755e3a7cd 100644 --- a/shared/constants/project-schema.js +++ b/shared/constants/project-schema.js @@ -35,6 +35,7 @@ const ProjectSchema = { yup .object() .shape({ + label: yup.string(), section: yup.string(), key: yup.string(), value: yup.string(), @@ -96,7 +97,10 @@ const buildProjectSchema = event => { ) } - if (event.eventType === EventTypes.physical.id) { + if ( + event.eventType === EventTypes.physical.id || + event.eventType === EventTypes.hybrid.id + ) { schema.location = yup.string().max(100).label('Table location') } diff --git a/shared/constants/registration-fields-custom.js b/shared/constants/registration-fields-custom.js index 31b49b10c..5df7b3c34 100644 --- a/shared/constants/registration-fields-custom.js +++ b/shared/constants/registration-fields-custom.js @@ -23,6 +23,17 @@ const RegistrationFieldsCustom = { return required ? base.required() : base }, }, + link: { + id: 'link', + validationSchema: (required, question) => { + const base = yup + .string() + .min(required ? 1 : 0) + .max(300) + .label(question.label) + return required ? base.required() : base + }, + }, boolean: { id: 'boolean', validationSchema: (required, question) => { diff --git a/shared/helpers/events.js b/shared/helpers/events.js index e30fea153..855e6345b 100644 --- a/shared/helpers/events.js +++ b/shared/helpers/events.js @@ -52,7 +52,7 @@ const EventHelpers = { if (!event) return false return !nowIsBefore(event.submissionsEndTime, moment) }, - isVotingOpen: (event, moment) => { + isReviewingOpen: (event, moment) => { if (!event) return false return nowIsBetween( event.reviewingStartTime, @@ -67,7 +67,7 @@ const EventHelpers = { event.finalsActive ) }, - isVotingPast: (event, moment) => { + isReviewingPast: (event, moment) => { if (!event) return true return !nowIsBefore(event.reviewingEndTime, moment) }, @@ -112,6 +112,10 @@ const EventHelpers = { if (!event) return true return event.meetingsEnabled }, + areChallengesEnabled: event => { + if (!event) return false + return event.challengesEnabled + }, } module.exports = EventHelpers diff --git a/shared/schemas/Challenge.js b/shared/schemas/Challenge.js index ab17e3311..ee6bdd2e2 100644 --- a/shared/schemas/Challenge.js +++ b/shared/schemas/Challenge.js @@ -11,7 +11,7 @@ const ChallengeSchema = new mongoose.Schema({ name: { type: String, required: true, - length: 100, + length: 50, }, partner: { type: String, diff --git a/shared/schemas/CustomAnswer.js b/shared/schemas/CustomAnswer.js index 6ad309f95..7fac85246 100644 --- a/shared/schemas/CustomAnswer.js +++ b/shared/schemas/CustomAnswer.js @@ -2,6 +2,9 @@ const mongoose = require('mongoose') const { GraphQLObjectType, GraphQLString } = require('graphql') const mongooseSchema = new mongoose.Schema({ + label: { + type: String, + }, section: { type: String, }, @@ -16,6 +19,9 @@ const mongooseSchema = new mongoose.Schema({ const graphqlSchema = new GraphQLObjectType({ name: 'CustomAnswer', fields: () => ({ + label: { + type: GraphQLString, + }, section: { type: GraphQLString, },