Make update consent for research possible

This commit is contained in:
outisa
2026-10-07 21:39:43 +03:00
parent c6f7c8edeb
commit 8410871a06
7 changed files with 141 additions and 5 deletions
+20
View File
@@ -2,6 +2,26 @@ const usersRouter = require('express').Router()
const db = require('../models/index')
const { checkLogin, checkInstructor } = require('../middleware')
usersRouter.put('/consent/:studentNumber', checkLogin, async (req, res) => {
const { research_consent } = req.body
const { studentNumber } = req.params
try {
const user = await db.User.findOne({
where: { student_number: studentNumber },
})
if (!user) {
return res.status(400).json({ error: 'user does not exist' })
}
const updatedUser = await user.update({ research_consent })
const refreshedUser = await updatedUser.reload()
res.status(200).json({ user: refreshedUser })
} catch (error) {
console.log(error)
res.status(500).json({ error: 'Something is wrong... try reloading the page' })
}
})
usersRouter.put('/:studentNumber', checkLogin, async (req, res) => {
const { email } = req.body
const { studentNumber } = req.params
@@ -0,0 +1,15 @@
'use strict'
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.addColumn('users', 'research_consent', {
type: Sequelize.BOOLEAN,
defaultValue: false,
allowNull: false,
})
},
// eslint-disable-next-line no-unused-vars
down: async (queryInterface, Sequelize) => {
await queryInterface.removeColumn('users', 'research_consent')
},
}
+4
View File
@@ -23,6 +23,10 @@ module.exports = (sequelize, Sequelize) => {
type: Sequelize.BOOLEAN,
defaultValue: false,
},
research_consent: {
type: Sequelize.BOOLEAN,
defaultValue: false,
},
},
{
underscored: true,
@@ -1,15 +1,26 @@
import { withRouter } from '../utils/withRouter'
import React from 'react'
import React, { useState } from 'react'
import { Link } from 'react-router-dom'
import { connect } from 'react-redux'
import { connect, useDispatch } from 'react-redux'
import registrationActions from '../reducers/actions/registrationActions'
import { setError } from '../reducers/actions/notificationActions'
import { updateConsent } from '../reducers/actions/userActions'
import peerReviewService from '../services/peerReview'
import Typography from '@mui/material/Typography'
import { Input, Card, CardContent, Select, MenuItem } from '@mui/material'
import {
Input,
Card,
CardContent,
Select,
MenuItem,
RadioGroup,
Radio,
FormControl,
FormControlLabel,
Button,
} from '@mui/material'
import CourseMaterial from './common/CourseMaterial'
import SortableTopicList from './SortableTopicList'
@@ -67,6 +78,59 @@ class PeerReviewInfo extends React.Component {
}
}
const ResearchConsent = ({ student }) => {
const [consent, setConsent] = useState(student.research_consent)
const dispatch = useDispatch()
const handleUpdate = () => {
dispatch(updateConsent(consent, student))
}
return (
<div>
<Typography variant="h2">Tutkimuslupa</Typography>
<Typography style={{ width: '60%' }}>
Yliopiston tehtäviin kuuluvat opetuksen lisäksi myös tutkimuksen teko. Te opiskelijat olette
tärkeä osa prosessia, ilman teitä laadukasta yliopisto-opetuksen tutkimusta on vaikea tehdä.
Olemme tekemässä Helsingin yliopistossa tutkimusta generatiivisen tekoälyn käytöstä
opintojen aikana. Mikäli osallistut tutkimukseen, vastauksesi kysymyksiin voidaan yhdistää
arvosana- ja kurssisuoritustietoihisi, mutta sinua tai ryhmääsi ei voida tunnistaa
julkaistusta tutkimuksesta. Lisätietoja voi kysyä Matti Luukkaiselta (vastuuopettaja) tai
Outi Savolaiselta (opettaja).
</Typography>
<br />
<Typography style={{ width: '60%' }}>
Vertaisarviossa tai tuntikirjanpidossa antamasi vastaukset tekoälynkäytöstä eivät vaikuta
arvosanaasi tai kohteluusi kurssilla.
</Typography>
<FormControl>
<RadioGroup
name="research-consent-group"
value={consent ? 'consentGiven' : 'denied'}
onChange={() => setConsent(!consent)}
>
<FormControlLabel
value={'consentGiven'}
control={<Radio />}
label="Osallistun oppimiseen liittyvään tutkimukseen."
/>
<FormControlLabel
value={'denied'}
control={<Radio />}
label="En osallistu oppimiseen liittyvään tutkimukseen."
/>
</RadioGroup>
<Button
style={{ marginRight: '10px', height: '40px', width: 250 }}
color="inherit"
variant="outlined"
onClick={handleUpdate}
>
Tallenna valintasi
</Button>
</FormControl>
</div>
)
}
const GroupDetails = ({ groupDetails }) => {
return (
<div>
@@ -187,6 +251,7 @@ class RegistrationDetailsPage extends React.Component {
projectRegistrationConf,
peerReviewOpen,
peerReviewRound,
user,
} = this.props
if (groupDetails) {
@@ -198,6 +263,7 @@ class RegistrationDetailsPage extends React.Component {
peerReviewRound={peerReviewRound}
groupDetails={groupDetails}
/>
<ResearchConsent student={user} />
</div>
)
}
@@ -249,6 +315,7 @@ const mapStateToProps = (state) => {
peerReviewRound: state.registrationManagement.peerReviewRound,
peerReviewConf: state.registrationManagement.peerReviewConf,
projectRegistrationConf: state.registrationManagement.projectRegistrationConf,
user: state.login.user.user,
}
}
@@ -7,6 +7,18 @@ const updateIsInstructor = (user, isInstructor) => ({
instructor: isInstructor,
})
export const updateConsent = (consent, user) => {
return async (dispatch) => {
const { user: updatedUser } = await userService.updateUserConsent(consent, user)
dispatch({
type: 'UPDATE_CONSENT',
payload: {
research_consent: updatedUser.research_consent,
},
})
}
}
export const loginUser = (userCredentials) => {
return async (dispatch) => {
const { user, token } = await loginService.login(userCredentials)
+5
View File
@@ -17,6 +17,11 @@ const loginReducer = (state = initialState, action) => {
...state,
user: null,
}
case 'UPDATE_CONSENT':
return {
...state,
research_consent: action.payload,
}
case 'UPDATE_USERNAME':
return {
...state,
+14 -1
View File
@@ -20,6 +20,19 @@ const update = async (user) => {
return response.data
}
const updateUserConsent = async (consent, user) => {
const config = {
headers: { Authorization: 'bearer ' + getUserToken() },
}
const studentNumber = user.student_number
const response = await axios.put(
url + '/consent/' + studentNumber,
{ research_consent: consent },
config,
)
return response.data
}
const checkInstructor = async (token) => {
const config = {
headers: { Authorization: 'bearer ' + token },
@@ -28,4 +41,4 @@ const checkInstructor = async (token) => {
return response.data
}
export default { get, update, checkInstructor }
export default { get, update, checkInstructor, updateUserConsent }