Merge branch 'master' into tonitch/feat/notifications
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m22s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 24s

This commit is contained in:
2024-04-21 10:35:07 +02:00
70 changed files with 2770 additions and 652 deletions

View File

@ -13,6 +13,13 @@ login.guest.lastpage=Last Page
login.guest.submit=Submit
login.guest.birthday=BIRTHDAY
login.guest.confirm=CONFIRM
login.guest.browse=Browse...
login.guest.disclaimer=If you are already registered please connect to your account and use the change cursus/reregister function if not continue here.
login.guest.identityCard=Identity Card :
login.guest.attestationdisclaimer=This curriculum requires an entrance exam attestation
login.guest.formationdisclaimer=Please add your old formations with the associated degree/attestation,your case will be check by a member of the inscription service.
login.guest.managecareer=Manage your external formations
login.guest.sendRegReq=Send register request
login.cPassword=Confirm Password
login.password=Password
app.home=Home
@ -28,6 +35,7 @@ app.language=Language
app.manage.profile=Manage profile
app.studentList=Students List
app.users=Users
app.payments = Payments
request.moreInfos=More Infos
request.accept=Accept
request.refuse=Refuse
@ -53,3 +61,87 @@ Credits=Credits
InscriptionService=I.S.
faculty=Faculty
msg.notification.new=You have a new message
forum.create=Create forum
forum.create.name=New forum's name
forum.post.create.name=New post's title
firstname/name=Firstname/Name
regNo=regNo
From=From
To=To
WantedCursus=Wanted Cursus
seeprofile=See profile
acceptequiv=Accept equivalence
refuseequiv=Refuse equivalence
course=course
state=state
dljustifdoc=Download justification document
backtoreq=Back to request
dlidentitycard=Download identity card
dladmissiondoc=Download admission document
seeextcur=See external curriculums
dltaxdoc=Download tax justification document
dlresidency=Download residency justification document
enteramount=Please enter the amount to provide :
oldcursus=Old curriculums
newcursus = New curriculums
year=Year
reason=Reason :
selectedcursus=Selected curriculum :
askexemp=Ask exemption
exemp=Exempted
uploadjustifdoc=Please upload the justification document
subexemreq=Submit exemption request
addextcurr=Add external curriculum
dldoc=Download document
edit=Edit
delete=Delete
school=School
checkifnotcompleted=Check the box if you didn't complete the formation
wichyearstop=In which year did you stop (ex: 3rd year) ?
startyear=Start year
endyear=End year
giveextcurdoc=Please upload a document that proves this formation
uploadcurr=Upload curriculum
editcurr=Edit curriculum
reqtype=Request type :
inscription=register
scholarship=scholarship
exemption=exemption
unregister=unregister
curriculumch=curriculum change
filter=Filter :
approval=Approval :
teacherapproval=Teacher approval :
surreq=Are you sure that you want to accept this request ?
validate=Validate
amount=Amount
role=Role
manageextcur=Manage external curriculum
managecourse=Manage courses
manageminerval=Manage school fees
enterreason=Please enter the reason you leave
onlycursus=I only want to unregister from a specific cursus
plsselectcurs=Please select that cursus
sureunreg=Are you sure that you want to unregister ?
no=No
yes=Yes
reqsend=Your request has been send !
payment=Payment
lefttopay=left to pay
paydeposit=Pay deposit
payrest=Pay all the rest
alreadypaid=Payment : School fees have already been paid this year
askscholarship=Ask scholarship
uploaddocs=Please upload the required documents
taxjustdoc=Tax justification document :
residencydoc=Residency justification document :
reqsent=Your request has been sent to the inscription service.
backprofile=Go back to profile
procpayment=Proceed to payment of
procpaybutton=Process payment
rereg=Reregister in the next year of one of my cursus
reregsup=Register in a supplementary cursus
chcur=Change from a cursus to another
iwouldlike=I would like to :
newcurr=New curriculum
cursusprereq=The cursus you selected has some prerequisites ensure that your external curriculum data is updated in your profile

View File

@ -13,6 +13,13 @@ login.guest.lastpage=Derniere Page
login.guest.submit=Envoyer
login.guest.birthday=DATE DE NAISSANCE
login.guest.confirm=CONFIRMER
login.guest.browse=Parcourir...
login.guest.disclaimer=Si vous êtes déja inscrits dans cette université veuillez vous connecter a votre compte et utilisez les fonctions changer de cursus/réinscription sinon continuez ici.
login.guest.identityCard=Carte d'identité :
login.guest.attestationdisclaimer=Ce cursus requiert une attestation de réussite d'un examen d'entrée
login.guest.formationdisclaimer=Veuillez ajouter vos formations antérieures en y joignant les attestations/diplomes, votre dossier sera vérifié par un membre du service d'inscription.
login.guest.managecareer=Gèrer mon parcours extérieur
login.guest.sendRegReq=Envoyer la demande d'inscription
login.cPassword=Confirmer mot de passe
login.password=Mot de passe
app.home=Home
@ -28,6 +35,7 @@ app.language=Langue
app.manage.profile=Gérer le profil
app.studentList=Liste des étudiants
app.users=Utilisateurs
app.payments = Payements
request.moreInfos=Plus d'Infos
request.accept=Accepter
request.refuse=Refuser
@ -53,3 +61,87 @@ Credits=Credits
InscriptionService=S.I.
faculty=Faculté
msg.notification.new=Vous avez un nouveau message!
forum.create=Créer un forum
forum.create.name=Nom du forum
forum.post.create.name=Titre du post
firstname/name=Prénom/Nom
regNo=Matricule
From=De
To=A
WantedCursus=Cursus voulu
seeprofile=Voir le profil
acceptequiv=Accepter l'équivalence
refuseequiv=Refuser l'équivalence
course=cours
state=état
dljustifdoc=Télécharger le justificatif
backtoreq=Retour a la requête
dlidentitycard=Télécharger la carte d'identité
dladmissiondoc=Télécharger le certificat d'admission
seeextcur=Voir le parcours extérieur
dltaxdoc=Télécharger le justificatif d'impot
dlresidency=Télécharger le justificatif de résidence
enteramount=Veuillez entrer le montant alloué :
oldcursus=Anciens cursus
newcursus=Nouveaux cursus
year=Année
reason=Raison :
selectedcursus=Cursus selectionné :
askexemp=Demander une dispense
exemp=Dispensé
uploadjustifdoc=Veuillez soumettre le justificatif
subexemreq=Envoyer la demande de dispense
addextcurr=Ajouter une formation
dldoc=Télécharger le document
edit=Modifier
delete=Supprimer
school=Ecole
checkifnotcompleted=Cochez la case si vous n'avez terminé cette formation
wichyearstop=En quelle année de la formation vous êtes vous arrété (exemple: 3ème) ?
startyear=Année de début
endyear=Année de fin
giveextcurdoc=Veuillez soumettre un document attestant de ce parcours
uploadcurr=Ajouter la formation
editcurr=Modifier la formation
reqtype=Type de requête :
inscription=inscription
scholarship=bourse
exemption=dispense
unregister=désinscription
curriculumch=changement de cursus
filer=Filtre :
approval=Approbation :
teacherapproval=Approbation d'un prof :
surreq=Etes vous sur de vouloir accepter cette demande ?
validate=Valider
amount=Montant
role=Role
manageextcur=Gérer les formations
managecourse=Gérer les cours
manageminerval=Gérer le minerval
enterreason=Veuillez entrer la raison de votre départ
onlycursus=Je veux uniquement me désinscrire d'un seul cursus
plsselectcurs=Veuillez sélectionner ce cursus
sureunreg=Etes-vous sur de vouloir vous désinscrire ?
no=Non
yes=Oui
reqsend=Votre requête a été envoyée !
payment=Payement
lefttopay=restants a payer
paydeposit=Payer l'acompte
payrest=Payer le reste
alreadypaid=Payement : les frais ont déja été payés cette année
askscholarship=Demander une bourse
uploaddocs=Veuillez soumettre les documents requis
taxjustdoc=Justificatif d'impôts :
residencydoc=Justificatif de résidence :
reqsent=Votre requête a été envoyée au service d'inscription.
backprofile=Retour au profil
procpayment=Procéder au payement de
procpaybutton=Procéder au payement
rereg=Me réinscrire dans l'année supérieure
reregsup=M'inscrire dans un cursus supplémentaire
chcur=Changer d'un cursus vers un autre
iwouldlike=Je voudrais :
newcurr=Nouveau cursus
cursusprereq=Le cursus que vous avez selectionné a des prérequis assurez vous que votre dossier de parcours est a jour dans votre profil

View File

@ -30,7 +30,6 @@ window.addEventListener('hashchange', () => {
const active=ref(false)
const notification = ref(false)
const apps = ref([])
appList().then(e => apps.value = e)
@ -38,7 +37,6 @@ window.addEventListener('hashchange', () => {
<template>
<div class="container">
<div class="topBar">
<ul class="horizontal">
<li title=home>
@ -77,7 +75,6 @@ window.addEventListener('hashchange', () => {
{{i18n("app.manage.profile")}}
</a>
</div>
</div>
</a></li>
</ul>
@ -107,20 +104,19 @@ window.addEventListener('hashchange', () => {
height: 100%;
width: 100%;
display:grid;
grid-template-columns:[firstCol-start]70px[firstCol-end secondCol-start]auto[endCol];
grid-template-rows:[firstRow-start]61px[firstRow-end secondRow-start] auto [endRow];
grid-template-columns:[firstCol-start]70px[firstCol-end secondCol-start] auto [endCol];
grid-template-rows:[firstRow-start] var(--header-size) [firstRow-end secondRow-start] calc(100% - var(--header-size)) [endRow];
grid-template-areas:
"topBar topBar"
"leftBar page";
row-gap:0px;
column-gap:0px;
}
.page {
grid-area:page;
height: 100%;
width: 100%;
place-self:center;
}
.topBar{
@ -163,7 +159,7 @@ window.addEventListener('hashchange', () => {
ul.vertical{
list-style-type: none;
margin-top: 61px;
margin-top: var(--header-size);
top:0;
left:0;
padding: 25px 0 0;
@ -211,7 +207,7 @@ window.addEventListener('hashchange', () => {
left:0;
position: fixed;
height:61px;
height:var(--header-size);
width: 100%;
background-color: rgb(24, 24, 24);
}

View File

@ -0,0 +1,215 @@
<!----------------------------------------------------
File: Forums.vue
Author: Anthony Debucquoy
Scope: Extension messagerie
Description: Forum des étudiants
----------------------------------------------------->
<script setup>
import { ref, reactive } from 'vue'
import i18n from '@/i18n.js'
import { getCourses, getUserActualCourses } from '@/rest/courses.js'
import { ForumsOfCurrentCourse, getForumsOfCourse, createForum } from '@/rest/forum.js'
import { PostsOfCurrentForum, getPostsOfForum, createPost } from '@/rest/forum.js'
import { fetchedPost, fetchPost, sendAnswer } from '@/rest/forum.js'
import { getSelf } from '@/rest/Users.js'
const Role = (await getSelf()).role;
const courses = Role === 'Admin' || Role === 'Secretary' ? await reactive(getCourses()) : await reactive(getUserActualCourses());
const selectedCourse = ref();
const selectedForum = ref();
const addForumName = ref("");
const addPost = ref(false);
const addPostSubject = ref("");
const addPostContent = ref("");
</script>
<template>
<div id="app">
<div id="ForumSelector">
<select id="cours" value="" v-model="selectedCourse" @change="getForumsOfCourse(selectedCourse)">
<option v-for="course in courses" :value="course.courseID">{{course.title}}</option>
</select>
<select id="forum" value="" v-model="selectedForum" @change="getPostsOfForum(selectedForum !== 'create' ? selectedForum : null)" v-if="ForumsOfCurrentCourse != null">
<option v-for="forum in ForumsOfCurrentCourse" :value=forum.id>{{forum.name}}</option>
<option v-if="(Role === 'Admin' || Role === 'Teacher') && ForumsOfCurrentCourse != null" value="create">{{ i18n("forum.create") }}</option>
</select>
</div>
<div id="PostSelector" v-if="PostsOfCurrentForum != null">
<div @click="fetchPost(post.id)" class="postItem" v-for="post in PostsOfCurrentForum" :key="post.id">{{ post.subject }}</div>
<button v-if="Role === 'Admin' || Role === 'Teacher' " id="createPost" @click="addPost = true">+</button>
</div>
<div id="PostViewer" v-if="fetchedPost != null">
<div id="Post">
<h1>{{ fetchedPost.subject }}</h1>
{{fetchedPost.content}}
</div>
<div id="Messages">
<p v-for="msg in fetchedPost.answers">{{msg.author.firtName}} {{msg.author.lastName}} - {{msg.content}}</p>
<input v-if=!fetchedPost.locked type="text" placeholder="response" @keyup.enter="sendAnswer(fetchedPost.id, $event.target.value); $event.target.value = ''"/>
</div>
</div>
</div>
<div class=popup v-if="selectedForum === 'create' || addPost" @click.self="selectedForum = ''; addPost = false" >
<!-- Popup to add forum -->
<div id="addForumForm" v-if="selectedForum === 'create'" @keyup.enter="createForum(selectedCourse, addForumName); selectedForum = '';">
<label>{{ i18n("forum.create.name") }}</label>
<input type="text" placeholder="Name" v-model=addForumName />
</div>
<!-- Popup to add Post -->
<div id="addPostForm" v-if=addPost>
<label>{{ i18n("forum.post.create.name") }}</label>
<input type="text" placeholder="subject" v-model=addPostSubject @keyup.enter="createPost(selectedForum, addPostSubject, addPostContent); addPost = false;"/>
<textarea v-model="addPostContent" placeholder=content></textarea>
<input type="submit" value="send" @click="createPost(selectedForum, addPostSubject, addPostContent); addPost = false;">
</div>
</div>
</template>
<style scoped>
.popup{
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: #00000022;
z-index: 9;
}
#addForumForm{
position: relative;
width: 30%;
left: calc(50% - 30% / 2);
top: calc(50% - 10% / 2);
border-radius: 10px;
height: 10%;
background-color: white;
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
}
#addPostForm{
position: relative;
width: 30%;
left: calc(50% - 30% / 2);
top: calc(50% - 50% / 2);
border-radius: 10px;
height: 50%;
background-color: white;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
gap: 10px;
}
#app{
display: grid;
width: 100%;
height: 100%;
grid-template: 5em auto / 25% 75%;
}
#ForumSelector{
background-color: #FFFFFF0E;
grid-column: 1 / 3;
border-radius: 100px;
margin: 10px;
display: flex;
justify-content: space-around;
}
#ForumSelector select{
background-color: #ffa000;
border: none;
margin: 10px;
border-radius: 10px;
width: 200px;
text-align: center;
}
#PostSelector button{
background-color: green;
color: white;
border: none;
height: 4vh;
margin: 5px;
border-radius: 0 30px 30px 0;
align-items: center;
justify-content: center;
}
#PostSelector{
background-color: #FFFFFF0E;
border-radius: 0 25px 25px 0;
margin: 10px 0 10px 10px;
overflow: hidden;
padding: 10px;
display: flex;
flex-direction: column;
}
.postItem{
color: darkorange;
display: flex;
font-family: sans-serif;
font-weight: bold;
height: 4vh;
margin: 5px;
border-radius: 0 30px 30px 0;
align-items: center;
justify-content: center;
border: 1px solid darkorange;
}
.postItem:hover{
background-color: gray;
}
#PostViewer{
background-color: #FFFFFF0E;
border-radius: 25px;
margin: 10px;
max-height: 100%;
overflow: scroll;
}
#Post{
padding: 25px;
color: white;
}
#Post > h1{
text-align: center;
text-decoration: underline;
}
#Messages{
padding: 25px;
border-top: 3px dotted white;
}
#Messages > p {
background-color: orange;
}
</style>

View File

@ -0,0 +1,136 @@
<script setup>
import {
addUninscReq, editChangeCurrReq, editChangeCurrReqTeacherState,
editScholarshipReq,
editUnregReq, getChangeCurrReqById,
getScholarshipReqById,
getUnregisterbyId
} from "@/rest/requests.js";
import i18n from "@/i18n.js";
import {getSelf, getUser} from "@/rest/Users.js";
import {reactive, ref} from "vue";
import AboutStudent from "@/Apps/Inscription/AboutStudent.vue";
const props = defineProps(["reqId"])
const req = ref(await getChangeCurrReqById(props.reqId))
const user = await getSelf()
//0 liste, 1 profil
const localwindowstate = ref(0);
const tag = req.value.user.regNo
const windowState = defineModel("windowState")
async function uploadandrefreshChangeRequest(state){
await editChangeCurrReq(req.value.id, state);
}
async function editChangeCurrReqTeacherApproval(state){
await editChangeCurrReqTeacherState(req.value.id, state)
}
</script>
<template>
<div class="body" v-if="localwindowstate === 0">
<div class="container">
<div class="globalInfos">
<div class="infosContainer">
<div>
{{i18n("firstname/name")}} : {{req.user.firstName}} {{req.user.lastName}}
</div>
<div>
{{i18n("regNo")}} : {{req.user.regNo}}
</div>
<div v-if="req.actualCurriculum !== null">
{{i18n("From")}} : Bac {{req.actualCurriculum.year}} {{req.actualCurriculum.option}}
{{i18n("To")}} : Bac {{req.destinationCurriculum.year}} {{req.destinationCurriculum.option}}
</div>
<div v-else>
{{i18n("WantedCursus")}} : Bac {{req.destinationCurriculum.year}} {{req.destinationCurriculum.option}}
</div>
<div>
<button @click="localwindowstate++"> {{ i18n("seeprofile") }} </button>
</div>
<div>
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';uploadandrefreshChangeRequest('Accepted')">{{ i18n("request.accept") }}</button>
<button v-if="req.state === 'Pending'" @click="req.state='Refused';uploadandrefreshChangeRequest('Refused')" style="margin-left: 2%;">{{i18n("request.refuse")}}</button>
</div>
<div v-if="user.role === 'Teacher' || user.role === 'Admin'">
<button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Accepted';editChangeCurrReqTeacherApproval('Accepted')">{{i18n("acceptequiv")}}</button>
<button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Refused';editChangeCurrReqTeacherApproval('Refused')">{{i18n("refuseequiv")}}</button>
</div>
</div>
</div>
</div>
</div>
<div v-if="localwindowstate === 0" style="margin-left: 23%">
<button @click="windowState = 0" style="margin-left: 10%">{{ i18n("courses.back") }}</button>
</div>
<div v-if="localwindowstate === 1">
<AboutStudent :target="tag"></AboutStudent>
<button @click="localwindowstate--;" style="margin-left: 10%">{{ i18n("courses.back") }}</button>
</div>
</template>
<style scoped>
.container{
min-width:675px;
display:grid;
grid-template-columns:10vw 50vw;
grid-template-rows:200px auto;
column-gap:2.7%;
row-gap:45px;
grid-template-areas:
"profilPic globalInfos"
"minfos minfos";
}
.profilPic{
width:100%;
grid-area:profilPic;
}
.globalInfos {
grid-area:globalInfos;
align-self :center;
}
.body {
min-width:960px;
width:100%;
display:flex;
align-items:center;
justify-content:center;
margin-top:7%;
}
.subContainter{
width:100%;
background-color:rgb(50,50,50);
border-radius:20px;
border:4px solid black;
}
.infosContainer {
min-width:350px;
padding-bottom:50px;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;
}
button{
border:none;
background-color:rgb(239, 60, 168);
border-radius:10px;
height:35px;
margin-top:10px;
}
</style>

View File

@ -0,0 +1,124 @@
<script setup>
import {
addUninscReq,
editExempReqState,
editScholarshipReq,
getExempReq,
getScholarshipReqById
} from "@/rest/requests.js";
import i18n from "@/i18n.js";
import {getUser} from "@/rest/Users.js";
import {reactive, ref} from "vue";
import AboutStudent from "@/Apps/Inscription/AboutStudent.vue";
const props = defineProps(["reqId"])
const req = ref(await getExempReq(props.reqId))
const profile = ref(false)
const windowState = defineModel("windowState")
async function editExemp(newstate){
await editExempReqState(req.value.id, newstate)
}
</script>
<template>
<div class="body" v-if="profile === false">
<div class="container">
<div class="globalInfos">
<div class="infosContainer">
<div>
{{ i18n("firstname/name") }} : {{req.user.firstName}} {{req.user.lastName}}
</div>
<div>
{{ i18n("course") }}: {{req.course.title}}
</div>
<div>
{{ i18n("state") }} : {{req.state}}
</div>
<div>
<button @click="profile = !profile">{{ i18n("seeprofile") }}</button>
</div>
<div>
<button>{{ i18n("dljustifdoc") }}</button>
</div>
<div>
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';editExemp('Accepted')">{{ i18n("request.accept") }}</button>
<button v-if="req.state === 'Pending'" @click="req.state='Refused';editExemp('Refused')" style="margin-left: 2%;">{{ i18n("request.refuse") }}</button>
</div>
</div>
</div>
</div>
</div>
<div v-else>
<AboutStudent :target="req.user.regNo"></AboutStudent>
<button @click="profile=!profile" style="margin-left: 17%;margin-top: 3%">{{ i18n("backtoreq") }}</button>
</div>
<div>
<button v-if="profile===false" @click="windowState = 0" style="margin-left: 31%">{{ i18n("courses.back") }}</button>
</div>
</template>
<style scoped>
.container{
min-width:675px;
display:grid;
grid-template-columns:10vw 50vw;
grid-template-rows:200px auto;
column-gap:2.7%;
row-gap:45px;
grid-template-areas:
"profilPic globalInfos"
"minfos minfos";
}
.profilPic{
width:100%;
grid-area:profilPic;
}
.globalInfos {
grid-area:globalInfos;
align-self :center;
}
.body {
min-width:960px;
width:100%;
display:flex;
align-items:center;
justify-content:center;
margin-top:7%;
}
.subContainter{
width:100%;
background-color:rgb(50,50,50);
border-radius:20px;
border:4px solid black;
}
.infosContainer {
min-width:350px;
padding-bottom:50px;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;
}
button{
border:none;
background-color:rgb(239, 60, 168);
border-radius:10px;
height:35px;
margin-top:10px;
}
</style>

View File

@ -1,7 +1,7 @@
<script setup>
import i18n from "@/i18n.js"
import {getSelf, getUser} from '../../rest/Users.js'
import {getcurriculum,getSomeonesCurriculumList} from "@/rest/curriculum.js";
import {getcurriculum} from "@/rest/curriculum.js";
import {getRegisters} from "@/rest/ServiceInscription.js";
import {get} from "jsdom/lib/jsdom/named-properties-tracker.js";
import {getExternalCurriculumByInscrReq} from "@/rest/externalCurriculum.js";
@ -16,6 +16,8 @@ const user = await getSelf();
const list = ref(false);
const externalCurriculum = await getExternalCurriculumByInscrReq(request.id)
//Get the parent page windowState to display the correct button
const windowState = defineModel("windowState")
function getPP(){
if(request.profilePictureUrl === null){
return "/Clyde.png"
@ -29,7 +31,7 @@ async function editEquivalence(id, newstate){
</script>
<template>
<div class="body" v-if="list == false">
<div class="body" v-if="list == false" style="margin-top: 10%;">
<div class="container">
<div class="profilPic">
<img class="subContainter" :src=getPP()>
@ -37,36 +39,43 @@ async function editEquivalence(id, newstate){
<div class = "globalInfos">
<div class="infosContainer">
<div>
FirstName/Name : {{request.firstName}} {{request.lastName}}
{{ i18n("firstname/name") }} : {{request.firstName}} {{request.lastName}}
</div>
<div>
E-mail: {{request.email}}
{{ i18n("login.guest.email") }}: {{request.email}}
</div>
<div>
Adresse : {{request.address}}
{{ i18n("login.guest.address") }} : {{request.address}}
</div>
<div>
Pays : {{request.country}}
{{ i18n("login.guest.country") }} : {{request.country}}
</div>
<div>
Date de naissance : {{request.birthDate}}
{{ i18n("login.guest.birthday") }} : {{request.birthDate}}
</div>
<div>
Cursus voulu : BAB {{cursus.year}} {{cursus.option}}
{{ i18n("WantedCursus") }} : BAB {{cursus.year}} {{cursus.option}}
</div>
<div style="margin-top: 3%">
<a :href="request.identityCard">{{ i18n("dlidentitycard") }}</a>
<button v-if="request.admissionDocUrl != null">{{ i18n("dladmissiondoc") }}</button>
</div>
<div v-if="cursus.year > 1">
<button style="background-color:rgb(105,05,105);margin-left: 5%" @click="list=!list" v-if="(user.role == 'Teacher' || user.role == 'Admin')&& request.equivalenceState == 'Pending'">See external curriculums</button>
<button style="background-color:rgb(105,05,105);margin-top: 3%" @click="list=!list" v-if="(user.role == 'Teacher' || user.role == 'Admin')">{{ i18n("seeextcur") }}</button>
</div>
</div>
</div>
</div>
</div>
<div v-if="list == false" style="margin-left: 30%; margin-top: 5%">
<button @click="windowState = 0">{{ i18n("courses.back") }}</button>
</div>
<div v-if="list==true">
<ExternalCurriculumList :ext-curr-list="externalCurriculum" :inscr-req-id="request.id"></ExternalCurriculumList>
<ExternalCurriculumList :ext-curr-list="externalCurriculum" :mode="0"></ExternalCurriculumList>
<div style="margin-left: 15%;margin-top: 5%;">
<button style="margin-left: 2%" @click="list = false;editEquivalence(request.id, 'Accepted'); request.equivalenceState='Accepted'">Accept Equivalence</button>
<button style="margin-left: 2%" @click="list = false;editEquivalence(request.id, 'Refused'); request.equivalenceState='Refused'">Refuse Equivalence</button>
<button style="margin-left: 2%" @click="list=false">Return to profile</button>
<button style="margin-left: 2%" v-if="request.equivalenceState === 'Pending'" @click="list = false;editEquivalence(request.id, 'Accepted'); request.equivalenceState='Accepted'">{{i18n("acceptequiv")}}</button>
<button style="margin-left: 2%" v-if="request.equivalenceState === 'Pending'" @click="list = false;editEquivalence(request.id, 'Refused'); request.equivalenceState='Refused'">{{i18n("refuseequiv")}}</button>
<button style="margin-left: 2%" @click="list=false">Back</button>
</div>
</div>
</template>
@ -123,10 +132,10 @@ async function editEquivalence(id, newstate){
}
button{
font-size:15px;
height:50px;
width:100px;
border:none;
border-radius:20px;
background-color:rgb(239, 60, 168);
border-radius:10px;
height:35px;
margin-top:10px;
}
</style>

View File

@ -0,0 +1,132 @@
<script setup>
import {addUninscReq, editScholarshipReq, getScholarshipReqById} from "@/rest/requests.js";
import i18n from "@/i18n.js";
import {getUser} from "@/rest/Users.js";
import {reactive, ref} from "vue";
const props = defineProps(["reqId"])
const req = ref(await getScholarshipReqById(props.reqId))
const user = req.value.user;
const scholarshipData = reactive({
amount : 0,
id : req.value.id,
state : ""
})
function getPP(){
if(user.profilePictureUrl === null){
return "/Clyde.png"
}
return user.profilePictureUrl
}
async function uploadandrefreshScholarshipRequest(){
await editScholarshipReq(scholarshipData);
req.value = await getScholarshipReqById(props.reqId);
}
</script>
<template>
<div class="body">
<div class="container">
<div class="profilPic">
<img class="subContainter" :src=getPP()>
</div>
<div class="globalInfos">
<div class="infosContainer">
<div>
{{ i18n("firstname/name") }} : {{user.firstName}} {{user.lastName}}
</div>
<div>
{{ i18n("login.guest.email") }}: {{user.email}}
</div>
<div>
{{ i18n("login.guest.address") }} : {{user.address}}
</div>
<div>
{{ i18n("login.guest.country") }} : {{user.country}}
</div>
<div>
{{ i18n("login.guest.birthday") }} : {{user.birthDate.slice(0,10)}}
</div>
<div>
<button @click="">{{ i18n("dltaxdoc") }}</button>
<button style="margin-left: 2%">{{ i18n("dlresidency") }}</button>
</div>
<div v-if="req.state == 'Pending'" style="margin-top: 2%; margin-bottom: 2%;">
{{i18n("enteramount")}}
<input type="number" v-model="scholarshipData.amount">
</div>
<div>
<button v-if="req.state === 'Pending'" @click="scholarshipData.state='Accepted';uploadandrefreshScholarshipRequest()">{{i18n("request.accept")}}</button>
<button v-if="req.state === 'Pending'" @click="scholarshipData.state='Refused';uploadandrefreshScholarshipRequest()" style="margin-left: 2%;">{{i18n("request.refuse")}}</button>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.container{
min-width:675px;
display:grid;
grid-template-columns:10vw 50vw;
grid-template-rows:200px auto;
column-gap:2.7%;
row-gap:45px;
grid-template-areas:
"profilPic globalInfos"
"minfos minfos";
}
.profilPic{
width:100%;
grid-area:profilPic;
}
.globalInfos {
grid-area:globalInfos;
align-self :center;
}
.body {
min-width:960px;
width:100%;
display:flex;
align-items:center;
justify-content:center;
margin-top:10%;
}
.subContainter{
width:100%;
background-color:rgb(50,50,50);
border-radius:20px;
border:4px solid black;
}
.infosContainer {
min-width:350px;
padding-bottom:50px;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;
}
button{
border:none;
background-color:rgb(239, 60, 168);
border-radius:10px;
height:35px;
margin-top:10px;
}
</style>

View File

@ -1,10 +1,11 @@
<script setup>
import i18n from "@/i18n.js"
import {getUser} from '../../rest/Users.js'
import {getSelf, getUser} from '../../rest/Users.js'
import {getSomeonesCurriculumList} from "@/rest/curriculum.js";
import {ref} from "vue";
import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue";
import {getExternalCurriculumByUser} from "@/rest/externalCurriculum.js";
import {getUserActualCourses} from "@/rest/courses.js";
const props = defineProps(['target'])
const user = await getUser(props.target)
@ -12,6 +13,10 @@
const externalcurrlist = await getExternalCurriculumByUser(user.regNo)
const extercurrlist = ref(false)
const courselist = await getUserActualCourses(user.regNo)
console.log(courselist)
const watchingUser = await getSelf()
function getPP(){
if(user.profilePictureUrl === null){
return "/Clyde.png"
@ -40,47 +45,50 @@
<div class = "globalInfos">
<div class="infosContainer">
<div>
FirstName/Name : {{user.firstName}} {{user.lastName}}
{{ i18n("firstname/name") }} : {{user.firstName}} {{user.lastName}}
</div>
<div>
E-mail: {{user.email}}
{{ i18n("login.guest.email") }}: {{user.email}}
</div>
<div>
Adresse : {{user.address}}
{{ i18n("login.guest.address") }} : {{user.address}}
</div>
<div>
Pays : {{user.country}}
{{ i18n("login.guest.country") }} : {{user.country}}
</div>
<div>
Date de naissance : {{user.birthDate}}
{{ i18n("login.guest.birthday") }} : {{user.birthDate}}
</div>
<div>
<button @click="extercurrlist=!extercurrlist">See external curriculums</button>
<button v-if="watchingUser.role === 'Admin' || watchingUser.role === 'InscriptionService' || watchingUser.role === 'Secretary' || watchingUser.regNo === user.regNo">{{i18n("dlidentitycard")}}</button>
</div>
<div>
<button @click="extercurrlist=!extercurrlist">{{i18n("seeextcur")}}</button>
</div>
</div>
</div>
<div class="moreInfos">
<div class="moreInfos" style="margin-top: 15%">
<div class = "oldcursus">
<div class="listTitle">
Anciens Cursus
{{ i18n("oldcursus") }}
</div>
<div class="listElement">
<div class=" containerElement" v-for="item in UserCurriculum.curriculumList">
<div class="year" v-if="parseInt(item.dateyear) !== getYear()">Bac {{item.year}}</div>
<div class="option" v-if="parseInt(item.dateyear) !== getYear()">{{item.option}}</div>
<div class="dateyear" v-if="parseInt(item.dateyear) !== getYear()">Année {{item.dateyear}}-{{item.dateyear+1}}</div>
<div class="year" v-if="item.actual === false">Bac {{item.year}}</div>
<div class="option" v-if="item.actual === false">{{item.option}}</div>
<div class="dateyear" v-if="item.actual === false">{{ i18n("year") }} {{item.dateyear}}-{{item.dateyear+1}}</div>
</div>
</div>
</div>
<div class="newcursus">
<div class="listTitle">
Cursus Actuel
{{ i18n("newcursus") }}
</div>
<div class="listElement">
<div class=" containerElement" v-for="item in UserCurriculum.curriculumList" >
<div class="year" v-if="parseInt(item.dateyear) === getYear()">Bac {{item.year}}</div>
<div class="option" v-if="parseInt(item.dateyear) === getYear()">{{item.option}}</div>
<div class="dateyear" v-if="parseInt(item.dateyear) === getYear()">Année {{item.dateyear}}-{{item.dateyear+1}}</div>
<div class="year" v-if="item.actual === true">Bac {{item.year}}</div>
<div class="option" v-if="item.actual === true">{{item.option}}</div>
<div class="dateyear" v-if="item.actual === true">{{ i18n("year") }} {{item.dateyear}}-{{item.dateyear+1}}</div>
</div>
</div>
</div>
@ -88,12 +96,13 @@
</div>
</div>
<div v-if="extercurrlist==true">
<ExternalCurriculumList :ext-curr-list="externalcurrlist"></ExternalCurriculumList>
<ExternalCurriculumList :ext-curr-list="externalcurrlist" :mode="1"></ExternalCurriculumList>
</div>
</template>
<style scoped>
.container{
min-width:675px;
display:grid;
@ -102,8 +111,7 @@
column-gap:2.7%;
row-gap:45px;
grid-template-areas:
"profilPic globalInfos"
"minfos minfos";
"profilPic globalInfos";
}
.profilPic{
@ -143,12 +151,10 @@
}
.moreInfos {
display:grid;
grid-template-rows:200px auto;
display:inline-grid;
column-gap:50px;
row-gap:45px;
grid-template-areas:
"minfos minfos";
"oldcursus newcursus";
grid-template-columns:600px 600px;
align-items:center;
justify-content:center;
@ -189,4 +195,12 @@
column-gap:40px;
padding-left: 25px;
}
button{
border:none;
background-color:rgb(239, 60, 168);
border-radius:10px;
height:35px;
margin-top:10px;
}
</style>

View File

@ -0,0 +1,109 @@
<script setup>
import {
addUninscReq,
editScholarshipReq,
editUnregReq,
getScholarshipReqById,
getUnregisterbyId
} from "@/rest/requests.js";
import i18n from "@/i18n.js";
import {getUser} from "@/rest/Users.js";
import {reactive, ref} from "vue";
const props = defineProps(["reqId"])
const req = ref(await getUnregisterbyId(props.reqId))
function getPP(){
if(user.profilePictureUrl === null){
return "/Clyde.png"
}
return user.profilePictureUrl
}
async function uploadandrefreshUnregRequest(state){
await editUnregReq(req.value.id, state)
req.value.state = state
}
</script>
<template>
<div class="body">
<div class="container">
<div class="globalInfos">
<div class="infosContainer">
<div>
{{ i18n("firstname/name") }} : {{req.firstName}} {{req.lastName}}
</div>
<div>
{{ i18n("login.guest.email") }}: {{req.email}}
</div>
<div>
{{ i18n("regNo") }} : {{req.regNo}}
</div>
<div>
{{ i18n("reason") }}
<input type="text" v-model="req.reason" readonly/>
</div>
<div>
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';uploadandrefreshUnregRequest('Accepted')">{{i18n("request.accept")}}</button>
<button v-if="req.state === 'Pending'" @click="req.state='Refused';uploadandrefreshUnregRequest('Refused')" style="margin-left: 2%;">{{i18n("request.refuse")}}</button>
</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.container{
min-width:675px;
display:grid;
grid-template-columns:10vw 50vw;
grid-template-rows:200px auto;
column-gap:2.7%;
row-gap:45px;
grid-template-areas:
"profilPic globalInfos"
"minfos minfos";
}
.profilPic{
width:100%;
grid-area:profilPic;
}
.globalInfos {
grid-area:globalInfos;
align-self :center;
}
.body {
min-width:960px;
width:100%;
display:flex;
align-items:center;
justify-content:center;
margin-top:7%;
}
.subContainter{
width:100%;
background-color:rgb(50,50,50);
border-radius:20px;
border:4px solid black;
}
.infosContainer {
min-width:350px;
padding-bottom:50px;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;
}
</style>

View File

@ -5,13 +5,16 @@ import i18n from "@/i18n.js";
import {getCourse} from "@/rest/courses.js";
import {getcurriculum} from "@/rest/curriculum.js";
import {uploadFile, uploadProfilePicture} from "@/rest/uploads.js";
import {createExemptionsRequest} from "@/rest/requests.js";
import {createExemptionsRequest, getExempByUser} from "@/rest/requests.js";
import {getSelf} from "@/rest/Users.js";
const props = defineProps(["cursuslist"])
const selectedCurriculum = ref(props.cursuslist[0])
const user = await getSelf()
const windowState = defineModel("windowState")
const exempList = await getExempByUser(user.regNo)
const courseslist = ref(await getcurriculum(selectedCurriculum.value.curriculumId))
const list = ref(true)
@ -30,11 +33,20 @@ const exemptReq = reactive({
courseId : null,
justifDocument : "",
})
function isExempted(course){
for (let i = 0; i < exempList.length; i++){
if (exempList[i].course.courseID === course.courseId && exempList[i].state === "Accepted"){
return true
}
return false
}
}
</script>
<template style="margin-top:5%;">
<div v-if="list == true">
<span>Selected Cursus : </span>
<span>{{i18n("selectedcursus")}} : </span>
<select v-model="selectedCurriculum" @change="updateCourseList">
<option v-for="item in props.cursuslist" :value="item">Bac {{item.year}} {{item.option}}</option>
</select>
@ -45,20 +57,29 @@ const exemptReq = reactive({
<div class="firstname">{{item.owner.firstName}}</div>
<div class="lastname">{{item.owner.lastName}}</div>
<div class="credits">credits : {{item.credits}}</div>
<div class="askexemption"><button style="background-color:rgb(105,0,0);" @click="list= !list;exemptReq.courseId=item.courseId">Ask exemption</button></div>
<div class="askexemption" v-if="!isExempted(item)"><button style="background-color:rgb(105,0,0);" @click="list= !list;exemptReq.courseId=item.courseId">{{i18n("askexemp")}}</button></div>
<div v-else class="askexemption" style="font-size: 50%">{{ i18n("exemp") }}</div>
</div>
</div>
</div>
<div>
<button @click="windowState = 0">{{ i18n("courses.back")}}</button>
</div>
</div>
<div v-else>
<p>Please upload the justification document for the exemption </p>
<div v-if="list === false" class="infosContainer">
<p>{{ i18n("uploadjustifdoc") }} </p>
<div>
<label class="browser">
<input type="file" @change="ppData.value = $event.target.files" accept="image/*" ref="filepath">
</label>
<button style="width:15%; margin-top: 5%;" @click="postExemptionRequest(ppData.value, 'JustificationDocument');">
Submit exemption request
</div>
<button style="margin-top: 3%" @click="postExemptionRequest(ppData.value, 'JustificationDocument');">
{{ i18n("subexemreq") }}
</button>
</div>
<div v-if="list === false">
<button @click="list=!list">{{ i18n("courses.back") }}</button>
</div>
</template>
<style scoped>
@ -135,5 +156,15 @@ button{
margin-top:10px;
}
.infosContainer {
padding-bottom:50px;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;
}
</style>

View File

@ -1,25 +1,134 @@
<script setup>
import i18n from "@/i18n.js";
import {ref} from "vue";
import {reactive, ref} from "vue";
import {getSelf} from "@/rest/Users.js";
import {createExternalCurriculum, getExternalCurriculumByUser} from "@/rest/externalCurriculum.js";
import {uploadFile} from "@/rest/uploads.js";
const props = defineProps(["extCurrList"])
//mode 0 = externalcurr related to inscrreq, 1 = externalcurr related to user, 2 inscription procedure
const props = defineProps(["extCurrList", "mode"])
const extCurrList = ref(props.extCurrList)
console.log(extCurrList)
//Only usefull to pass the external curr array in the inscription procedure
const externalCurrTab = defineModel();
const extCurrList = ref({})
let extNum = 0
const User = ref({})
if (props.mode === 1){
User.value = await getSelf()
}
const list = ref(true)
const editmode = ref(false)
const notcompletedCheck = ref(false);
const externalCurr = reactive({
inscriptionRequestId : null,
school:null,
formation :null,
completion : "completed",
startYear : 0,
endYear: 0,
justifdocUrl : null,
userRegNo : null
})
if (props.mode === 1){
externalCurr.userRegNo = props.extCurrList[0].user.regNo
}else if(props.mode === 2){
extCurrList.value = externalCurrTab.value
}
if(props.mode !== 2){
extCurrList.value = props.extCurrList
console.log("oe")
}
function deleteExtCursus(extcursus){
externalCurrTab.value.splice(externalCurrTab.value.indexOf(extcursus),1)
}
async function postExternalCurr(){
if (props.mode === 1){
const temp = await uploadFile(externalCurr.justifdocUrl, "JustificationDocument")
await createExternalCurriculum(externalCurr.inscriptionRequestId, externalCurr.school, externalCurr.formation, externalCurr.completion, externalCurr.startYear, externalCurr.endYear, temp.url, externalCurr.userRegNo);
//We refresh the list
extCurrList.value = await getExternalCurriculumByUser(externalCurr.userRegNo);
list.value = !list.value;
}else if (props.mode === 2){
externalCurrTab.value.push({
inscriptionRequestId : externalCurr.inscriptionRequestId,
school:externalCurr.school,
formation :externalCurr.formation,
completion : externalCurr.completion,
startYear : externalCurr.startYear,
endYear: externalCurr.endYear,
justifdocUrl : externalCurr.justifdocUrl,
userRegNo : externalCurr.userRegNo
});
extCurrList.value = externalCurrTab.value
list.value = !list.value;
}
}
</script>
<template style="margin-top:5%;">
<div style="display:flex; justify-content:center; " v-for="item in extCurrList">
<div class="bodu">
<div class="container">
<div class="status"><a style="margin-left:30px">{{item.state}}</a></div>
<div class="school"><a>{{item.school}}</a></div>
<div class="formation"><a>{{item.formation}}</a></div>
<div class="completion"><a>{{item.completion}}</a></div>
<div class="download"><button>Download document</button></div>
<div v-if="list">
<div v-if="props.mode === 2||User.regNo === externalCurr.userRegNo" style="margin-left: 2%;margin-top: 2%">
<button @click="list = !list" style="margin-left:15%;">{{ i18n("addextcurr") }}</button>
</div>
<div style="display:flex; justify-content:center;" v-for="(item, index) in extCurrList">
<div class="bodu">
<div class="container">
<div class="status"><a style="margin-left:30px">{{item.state}}</a></div>
<div class="school"><a>{{item.school}}</a></div>
<div class="formation"><a>{{item.formation}}</a></div>
<div class="completion"><a>{{item.completion}}</a></div>
<div class="download"><button>{{ i18n("dldoc") }}</button></div>
<div class="edit" v-if="props.mode === 2"><button @click="list=!list;externalCurr.justifdocUrl=item.justifDocUrl; externalCurr.endYear = item.endYear; externalCurr.startYear = item.startYear; externalCurr.school = item.school;externalCurr.completion = item.completion;externalCurr.formation=item.formation;editmode=!editmode;extNum=index">{{i18n("edit")}}</button></div>
<div class="delete" v-if="props.mode === 2"><button @click="deleteExtCursus(item)">{{ i18n("delete") }}</button></div>
</div>
</div>
</div>
</div>
<div v-else class="loginbox" style="margin-left: 35%; margin-top: 3%">
<form class="form">
<div class="inputBox">
<p>{{ i18n("school") }}</p>
<input type="text" v-model="externalCurr.school">
</div>
<div class="inputBox">
<p>Formation</p>
<input type="text" v-model="externalCurr.formation">
</div>
<div class="inputBox">
<p>{{i18n("checkifnotcompleted")}}</p>
<input v-model="notcompletedCheck" type="checkbox" id="checkboxformation">
<div v-if="notcompletedCheck">
<p>{{i18n("wichyearstop")}}</p>
<input type="text" v-model="externalCurr.completion">
</div>
</div>
<div class="inputBox">
<p>{{ i18n("startyear") }}</p>
<input type="number" v-model="externalCurr.startYear">
</div>
<div class="inputBox">
<p>{{ i18n("endyear") }}</p>
<input type="number" v-model="externalCurr.endYear">
</div>
<div class="inputBox">
<p>{{i18n("giveextcurdoc")}}</p>
<input type="file" @change="externalCurr.justifdocUrl = $event.target.files">
</div>
<div class="inputBox" style="margin-top: 3%; margin-bottom: 3%">
<input v-if="!editmode" type="submit" value="upload" @click="postExternalCurr()">
<input v-else type="submit" value="edit" @click="externalCurrTab[extNum] = {inscriptionRequestId : externalCurr.inscriptionRequestId,school:externalCurr.school,formation :externalCurr.formation,completion : externalCurr.completion,startYear : externalCurr.startYear,endYear: externalCurr.endYear,justifdocUrl : externalCurr.justifdocUrl,userRegNo : externalCurr.userRegNo};editmode=!editmode;list=!list">
</div>
</form>
</div>
</template>
<style scoped>
@ -28,9 +137,9 @@
height:100px;
font-size:30px;
display:grid;
grid-template-columns:15% 10% 20% 15% 13.1%;
grid-template-columns:5% 10% 20% 15% 20% 10%;
grid-template-areas:
"status school formation completion download";
"status school formation completion download edit delete";
column-gap:10px;
}
@ -40,6 +149,15 @@
font-size: 70%;
}
.edit{
grid-area: edit;
align-self: center;
}
.delete{
grid-area: delete;
align-self: center;
}
.school{
grid-area:school;
align-self:center;
@ -61,18 +179,12 @@
font-size: 70%;
}
.download{
grid-area: download;
align-self:center;
}
button{
font-size:15px;
height:50px;
width:75%;
border:none;
border-radius:20px;
}
.bodu {
margin-top:2%;
@ -82,6 +194,49 @@ button{
background-color:rgb(50,50,50);
}
.loginbox {
background-color: rgb(24,24,24);
width: 400px;
display:flex;
justify-content: center;
border-radius: 5%;
box-shadow:0 5px 25px #000000;
}
.form {
position:relative;
width:100%;
display: flex;
flex-direction: column;
align-items:center;
gap: 3%;
}
.inputBox input,select {
width:100%;
border: none;
margin-right: 12.5%;
padding-left: 2.5%;
padding-top:2.5%;
padding-bottom:2.5%;
outline:none;
border-radius: 10px;
font-size:1.35em;
}
.inputBox p{
position:relative;
z-index: 100;
font-family:sans-serif ;
color:rgb(239,60,168);
}
button{
border:none;
background-color:rgb(239, 60, 168);
border-radius:10px;
height:35px;
margin-top:10px;
}
</style>

View File

@ -1,18 +1,28 @@
<script setup>
import i18n from "@/i18n.js"
import {ref} from 'vue'
import {ref, vModelSelect, watch} from 'vue'
import {validateRegister, getAllRegisters } from '@/rest/ServiceInscription.js'
import AboutRequest from "@/Apps/Inscription/AboutRequest.vue";
import {getAllExemptionsRequest, getAllScholarShipsRequest} from "@/rest/requests.js";
import {
getAllChangeCurrReq,
getAllExemptionsRequest,
getAllScholarShipsRequest,
getAllUnregisters
} from "@/rest/requests.js";
import AboutScholarship from "@/Apps/Inscription/AboutScholarship.vue";
import AboutUnregister from "@/Apps/Inscription/AboutUnregister.vue";
import AboutChangeCurriculum from "@/Apps/Inscription/AboutChangeCurriculum.vue";
import AboutExemption from "@/Apps/Inscription/AboutExemption.vue";
import {getSelf} from "@/rest/Users.js";
const requests = ref(await getAllRegisters());
let targetId = "";
const user = await getSelf()
const requestType = ref("inscription");
const filterType = ref("None");
//0 = liste, 1 = détails, 2 = sure?
let windowsState = ref(0);
//0 = liste, 1 = détails, 2 = sure?, 3 = manage scholarship, 4 manage unregister, 5 = manage curriculum change, 6 = manage exemptions
const windowsState = ref(0);
async function upPage(id,review){
await validateRegister(id,review);
@ -21,34 +31,50 @@
}
async function loadRequests(){
if (requestType.value === "inscription"){
requests.value = await getAllRegisters();
}
if (requestType.value === "scholarship"){
requests.value = await getAllScholarShipsRequest();
}
if(requestType.value === "exemption"){
requests.value = await getAllExemptionsRequest();
switch (requestType.value){
case i18n("inscription"):
requests.value = await getAllRegisters();
break;
case i18n("scholarship"):
requests.value = await getAllScholarShipsRequest();
break;
case i18n("exemption"):
requests.value = await getAllExemptionsRequest();
break;
case i18n("unregister"):
requests.value = await getAllUnregisters();
break;
case i18n("curriculumch"):
requests.value = await getAllChangeCurrReq();
}
}
//When we come back to the list we need to reload the list
watch(windowsState, () => {
if (windowsState.value === 0){
loadRequests();
}
})
</script>
<template>
<div v-if="windowsState === 1">
<AboutRequest :target="targetId"></AboutRequest>
<AboutRequest :target="targetId" v-model:window-state="windowsState"></AboutRequest>
</div>
<div v-if="windowsState === 0">
<div style="margin-top: 2%;margin-left: 2%">
<span>Request type : </span>
<span>{{ i18n("reqtype") }} : </span>
<select v-model="requestType" @change="loadRequests()">
<option>inscription</option>
<option>scholarship</option>
<option>exemption</option>
<option>{{ i18n("inscription") }}</option>
<option v-if="user.role === 'Admin' || user.role === 'InscriptionService'">{{ i18n("scholarship") }}</option>
<option v-if="user.role === 'Admin' || user.role === 'Teacher'">{{ i18n("exemption") }}</option>
<option v-if="user.role === 'Admin' || user.role === 'InscriptionService'">{{ i18n("unregister") }}</option>
<option>{{ i18n("curriculumch") }}</option>
</select>
<span style="margin-left: 5%">
Filter :
{{ i18n("filter") }}
<select v-model="filterType">
<option>None</option>
<option>Pending</option>
@ -58,44 +84,73 @@
</span>
</div>
<div style='display:flex; justify-content:center; min-width:1140px;' v-for="item of requests">
<div class="bodu" style="width: 95%" v-if="filterType == 'None' || filterType == item.state">
<div class="container" style="grid-template-columns:11% 15% 20% 10% 10% 9% 9%;grid-template-areas:'date state equivalencestate surname firstname accept refuse infos';" v-if="requestType === 'inscription'">
<!--
The condition below avoids an error occuring because loadRequests() finishes after the vue refresh
then submissionDate is undefined an it triggers an error in the console despite the fact that it is working
properly at the end.
-->
<div class="bodu" style="width: 95%" v-if="(filterType == 'None' || filterType == item.state) && requestType !== i18n('exemption')">
<div class="container" style="grid-template-columns:11% 15% 20% 10% 10% 9% 9%;grid-template-areas:'date state equivalencestate surname firstname accept refuse infos';" v-if="requestType === i18n('inscription')">
<div class="date" v-if="item.submissionDate !== undefined">{{item.submissionDate.slice(0, 10)}}</div>
<div class="state" style="font-size: 80%">Approval : {{item.state}}</div>
<div class="equivalencestate" style="font-size: 80%">Teacher approval : {{item.equivalenceState}}</div>
<div class="state" style="font-size: 80%">{{ i18n("approval") }} {{item.state}}</div>
<div class="equivalencestate" style="font-size: 80%">{{ i18n("teacherapproval") }} {{item.equivalenceState}}</div>
<div class="surname">{{item.lastName}}</div>
<div class="firstname">{{item.firstName}}</div>
<div class="accept" v-if="item.state === 'Pending'"><button @click="windowsState=2;targetId=item.id;" style="background-color:rgb(0,105,50);">{{i18n("request.accept")}}</button></div>
<div class="refuse" v-if="item.state === 'Pending'"><button @click="upPage(item.id,'Refused')" style="background-color:rgb(105,0,0);">{{i18n("request.refuse")}}</button></div>
<div class="infos"><button style="background-color:rgb(105,05,105);" @click="targetId=item.id;windowsState=1;">{{i18n("request.moreInfos")}}</button></div>
</div>
<div class="container" style="grid-template-columns:25% 15% 15% 25% 14.2%;grid-template-areas:'date reqState studentfirstname studentlastname infos';" v-if="requestType === 'scholarship'">
<div class="container" style="grid-template-columns:25% 15% 15% 25% 14.2%;grid-template-areas:'date reqState studentfirstname studentlastname infos';" v-if="requestType === i18n('scholarship')">
<div class="date" v-if="item.date !== undefined"> {{item.date.slice(0,10)}}</div>
<div class="studentfirstname">{{item.user.firstName}}</div>
<div class="studentlastname">{{item.user.lastName}}</div>
<div class="reqState">{{item.state}}</div>
<div class="infos"><button>More infos</button></div>
<div class="infos" @click="windowsState = 3; targetId=item.id;"><button>{{ i18n("request.moreInfos") }}</button></div>
</div>
<div class="container" style="grid-template-columns:17% 15% 12% 15% 25%;grid-template-areas:'date reqState studentfirstname studentlastname course infos';"v-if="requestType === 'exemption'">
<div class="container" v-if="requestType === i18n('unregister')" style="grid-template-columns:17% 15% 12% 15%;grid-template-areas:'date reqState regno studentfirstname studentlastname infos';">
<div class="date" v-if="item.date != undefined">{{item.date.slice(0,10)}}</div>
<div class="studentfirstname">{{item.firstName}}</div>
<div class="studentlastname">{{item.lastName}}</div>
<div class="regno">id : {{item.regNo}}</div>
<div class="reqState">{{item.state}}</div>
<div class="infos"><button @click="windowsState=4;targetId=item.id">{{ i18n("request.moreInfos") }}</button></div>
</div>
<div class="container" v-if="requestType === i18n('curriculumch')" style="grid-template-columns:17% 20% 15% 5%;grid-template-areas:'date reqState teacherApproval regno studentfirstname studentlastname infos';">
<div class="date" v-if="item.date != undefined">{{item.date.slice(0,10)}}</div>
<div class="studentfirstname">{{item.user.firstName}}</div>
<div class="studentlastname">{{item.user.lastName}}</div>
<div class="reqState">{{ i18n("approval")}}{{item.state}}</div>
<div class="teacherApproval">{{ i18n("teacherapproval") }} : {{item.teacherApprovalState}}</div>
<div class="infos"><button @click="windowsState=5;targetId=item.id">{{ i18n("request.moreInfos") }}</button></div>
</div>
</div>
<div class="bodu" v-if="(filterType == 'None' || filterType == item.state) && requestType === i18n('exemption') && (item.course.owner.regNo === user.regNo || user.role === 'Admin')">
<div class="container" style="grid-template-columns:17% 15% 12% 15% 25%;grid-template-areas:'date reqState studentfirstname studentlastname course infos';">
<div class="date" v-if="item.date != undefined">{{item.date.slice(0,10)}}</div>
<div class="studentfirstname">{{item.user.firstName}}</div>
<div class="studentlastname">{{item.user.lastName}}</div>
<div class="course">{{item.course.title}}</div>
<div class="reqState">{{item.state}}</div>
<div class="infos"><button>More infos</button></div>
<div class="infos"><button @click="windowsState=6;targetId=item.id">{{ i18n("request.moreInfos") }}</button></div>
</div>
</div>
</div>
</div>
<div style='display:flex; justify-content:center; min-width:1140px;margin-top: 10%' v-if="windowsState === 2">
<p>Etes vous sur de vouloir accepter cette demande ?</p>
<button style="background-color:rgb(105,05,105);" @click="upPage(targetId,'Accepted');windowsState=0;">Valider</button>
<button style="background-color:rgb(105,05,105);" @click="windowsState=0;">Retour</button>
<p>{{ i18n("surreq") }}</p>
<button style="background-color:rgb(105,05,105);" @click="upPage(targetId,'Accepted');windowsState=0;">{{ i18n("validate") }}</button>
<button style="background-color:rgb(105,05,105);" @click="windowsState=0;">{{ i18n("courses.back")}}</button>
</div>
<div v-if="windowsState === 3">
<AboutScholarship :req-id="targetId"></AboutScholarship>
<div>
<button style="margin-left: 31%; margin-top: 5%" @click="windowsState=0">{{ i18n("courses.back")}}</button>
</div>
</div>
<div v-if="windowsState === 4">
<AboutUnregister :req-id="targetId"></AboutUnregister>
<button @click="windowsState=0" style="margin-left: 31%">{{ i18n("courses.back")}}</button>
</div>
<div v-if="windowsState === 5">
<AboutChangeCurriculum :req-id="targetId" v-model:window-state="windowsState"></AboutChangeCurriculum>
</div>
<div v-if="windowsState === 6">
<AboutExemption :req-id="targetId" v-model:window-state="windowsState"></AboutExemption>
</div>
</template>
@ -112,6 +167,11 @@
grid-area: equivalencestate;
align-self: center;
}
.teacherApproval{
grid-area: teacherApproval;
align-self: center;
}
.studentfirstname{
grid-area: studentfirstname;
align-self: center;
@ -151,6 +211,10 @@
align-self:center;
}
.regno{
grid-area: regno;
align-self: center;
}
.state{
grid-area:state;
margin-left:40px;
@ -174,12 +238,11 @@
}
button{
font-size:15px;
height:50px;
width:100px;
border:none;
border-radius:20px;
background-color:rgb(239, 60, 168);
border-radius:10px;
height: 35px;
margin-top:10px;
}
.bodu {

View File

@ -0,0 +1,78 @@
<script setup>
import i18n from "@/i18n.js";
import {ref} from "vue";
import {getAllPayments} from "@/rest/requests.js";
const paymentsList = await getAllPayments()
</script>
<template style="margin-top:5%;">
<div style="display:flex; justify-content:center; " v-for="item in paymentsList">
<div class="bodu">
<div class="container">
<div class="regNo"><a style="margin-left:30px">{{ i18n("regNo") }} : {{item.studentRegNo}}</a></div>
<div class="client"><a>Client : {{item.client}}</a></div>
<div class="amount"><a>{{ i18n("amount")}} : {{item.amount}}</a></div>
<div class="date" style="margin-left: 10%">{{item.date.slice(0,10)}}</div>
</div>
</div>
</div>
</template>
<style scoped>
.container{
color:white;
height:100px;
font-size:30px;
display:grid;
grid-template-columns:20% 25% 15% 17%;
grid-template-areas:
"date regNo client amount";
column-gap:10px;
}
.regNo {
grid-area:regNo;
align-self:center;
font-size: 70%;
}
.client{
grid-area:client;
align-self:center;
font-size: 70%;
}
.amount{
grid-area:amount;
align-self:center;
font-size: 70%;
}
.date{
grid-area:date;
align-self:center;
font-size: 70%;
}
button{
font-size:15px;
height:50px;
width:75%;
border:none;
border-radius:20px;
}
.bodu {
margin-top:2%;
width:66%;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
</style>

View File

@ -3,10 +3,11 @@
import i18n from '@/i18n.js'
import {login, register, disconnect, isLogged} from '@/rest/Users.js'
import {getAllCurriculums, getcurriculum} from '@/rest/curriculum.js'
import { uploadProfilePicture } from '@/rest/uploads.js'
import {uploadFile, uploadProfilePicture} from '@/rest/uploads.js'
import {toast} from 'vue3-toastify'
import 'vue3-toastify/dist/index.css';
import {createExternalCurriculum} from "@/rest/externalCurriculum.js";
import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue";
const loginPage= ref(true)
const page = ref(0)
@ -23,18 +24,6 @@
equivalenceState: "Unrequired"
})
const notcompletedCheck = ref(false);
const externalCurr = reactive({
inscriptionRequestId : null,
school:null,
formation :null,
completion : null,
startYear : null,
endYear: null,
justifdocUrl : null
})
//Stores some externalCurriculums in order to upload them all at the confirmation of the registration request
const externalCurrTab = ref([]);
@ -44,8 +33,8 @@
const imageSaved = ref(false)
let ppData = ""
//Contains the id of the newly created request (useful to link the student's formations informations to the request)
let requestId = ""
const idcardfile = ref({})
const justifcardfile = ref({})
const curricula= await getAllCurriculums();
@ -53,7 +42,7 @@
setTimeout(() => {
window.location.href="#/home";
}, "500");
}
}
function verifyInputs(pass){
if(pass==passwordConfirm.value){
page.value++;
@ -83,31 +72,36 @@
}
}
async function getCurriculumYear(curriculumId){
const curriculum = await getcurriculum(curriculumId);
return parseInt(curriculum.year);
}
//Post the register request and return the id of the newly created request and also post the external curriculum list in the database
async function postRegisterReq(){
const val = await register(outputs.firstname, outputs.surname, outputs.birthday, outputs.password, outputs.email, outputs.address, outputs.country, outputs.curriculum, ppData, null, new Date(), outputs.equivalenceState);
//We upload the two files and we get their paths on the server
const identityCardFile = await uploadFile(idcardfile.value, "IdentityCard")
const justifFile = ref(null)
if (curricula[outputs.curriculum-1].requireCertificate){
justifFile.value = await uploadFile(justifcardfile.value, "JustificationDocument")
}
let justif;
if (justifFile.value !== null){
justif = justifFile.value.url
}else{
justif = null
}
const val = await register(outputs.firstname, outputs.surname, outputs.birthday, outputs.password, outputs.email, outputs.address, outputs.country, outputs.curriculum, ppData, identityCardFile.url, new Date(), outputs.equivalenceState, justif);
for (let item in externalCurrTab.value){
await createExternalCurriculum(val.id, externalCurrTab.value[item].school, externalCurrTab.value[item].formation, externalCurrTab.value[item].completion, externalCurrTab.value[item].startYear, externalCurrTab.value[item].endYear, externalCurrTab.value[item].justifdocUrl);
const temp = await uploadFile(externalCurrTab.value[item].justifdocUrl, "JustificationDocument")
await createExternalCurriculum(val.id, externalCurrTab.value[item].school, externalCurrTab.value[item].formation, externalCurrTab.value[item].completion, externalCurrTab.value[item].startYear, externalCurrTab.value[item].endYear, temp.url);
}
}
function deleteExtCursus(extcursus){
externalCurrTab.value.splice(externalCurrTab.value.indexOf(extcursus),1)
}
</script>
<template>
<div class="setup">
<div v-if="loginPage">
<div class="setup" v-if="page !== 4">
<div v-if="loginPage">
<div class='loginBox' style="margin-top:30%;">
<form @submit.prevent="login(outputs.email,outputs.password);goBackHome();"class="form">
<h1 style="color:rgb(239,60,168); font-family: sans-serif;">
@ -125,7 +119,7 @@
<a @click="loginPage=!loginPage">{{i18n("login.guest.register")}}</a>
</div>
<div class="inputBox" style="margin-bottom:35px;">
<input type="submit" v-model="submitValue">
<input v-model="submitValue" type="submit">
</div>
</form>
</div>
@ -183,11 +177,10 @@
<p>{{i18n("profile.picture").toUpperCase()}}</p>
</form>
<label class="browser">
Parcourir . . .
{{i18n("login.guest.browse")}}
<input type="file" :disabled="imageSaved" @change="ppData = uploadProfilePicture($event.target.files); imageSaved = true;" accept="image/*">
</label>
<form novalidate enctype="multipart/form-data" class="inputBox">
<p>{{i18n("profile.picture").toUpperCase()}}</p>
<input type="file" @change="uploadPP($event.target.files); imageSaved = true;" accept="image/*">
</form>
<div class="inputBox">
@ -197,8 +190,7 @@
</select>
</div>
<p style="color:rgb(239,60,168);">
Si vous êtes déja inscrits dans cette université veuillez vous connecter a votre compte et utilisez les fonctions
changer de cursus/réinscription sinon continuez ici.
{{i18n("login.guest.disclaimer")}}
</p>
<div style="align-self:center;" class="inputBox">
<button style="margin-top:25px;" @click="page++;">
@ -213,67 +205,38 @@
</div>
</div>
<div v-if="page === 2">
<form novalidate enctype="multipart/form-data" class="inputBox">
Carte d'identité :
</form>
<button @click="page++">{{i18n("login.guest.nextpage")}}</button>
<p style="color:rgb(239,60,168);">{{i18n("login.guest.identityCard")}}</p>
<label class="browser">
{{i18n("login.guest.browse")}}
<input type="file" @change="idcardfile = $event.target.files">
</label>
<div v-if="curricula[outputs.curriculum-1].requireCertificate === true" style="margin-top: 3%; margin-bottom: 4%">
<p style="color:rgb(239,60,168);">{{ i18n("login.guest.attestationdisclaimer") }}</p>
<div style="margin-top: 2%">
<p style="color:rgb(239,60,168);">Attestation:</p>
<label class="browser">
{{i18n("login.guest.browse")}}
<input type="file" @change="justifcardfile = $event.target.files">
</label>
</div>
</div>
<button @click="page++;" style="margin-top: 10%">{{i18n("login.guest.nextpage")}}</button>
</div>
<div v-if="page === 3">
<p>
Vous avez séléctionné un cursus qui possède des prérequis veuillez ajouter vos formations antérieures
dans l'enseignement supérieur, votre dossier sera vérifié par un membre du service d'inscription.
<p style="color:rgb(239,60,168);margin-bottom: 5%">
{{i18n("login.guest.formationdisclaimer")}}
</p>
<button @click="page++">Ajouter une formation</button>
<button @click="postRegisterReq();">Envoyer la demande d'inscription</button>
</div>
<div v-if="page===4">
<form @submit.prevent=""class="form">
<div class="inputBox">
<p>Ecole</p>
<input type="text" v-model="externalCurr.school">
</div>
<div class="inputBox">
<p>Formation</p>
<input type="text" v-model="externalCurr.formation">
</div>
<div class="inputBox">
<p>Cochez la case si vous n'avez terminé cette formation</p>
<input v-model="notcompletedCheck" type="checkbox" id="checkboxformation">
<div v-if="notcompletedCheck">
<p>En quelle année de la formation vous êtes vous arrété (exemple: 3ème) ?</p>
<input type="text" v-model="externalCurr.completion">
</div>
</div>
<div class="inputBox">
<p>Année de début</p>
<input type="text" v-model="externalCurr.startYear">
</div>
<div class="inputBox">
<p>Année de fin</p>
<input type="text" v-model="externalCurr.endYear">
</div>
<div class="inputBox" style="margin-bottom:35px;">
<input type="submit" v-model="submitValue" @click="externalCurrTab.push({inscriptionReqId:null, school:externalCurr.school, formation:externalCurr.formation, completion:externalCurr.completion, startYear:externalCurr.startYear, endYear:externalCurr.endYear, justifdocUrl:externalCurr.justifdocUrl});console.log(externalCurrTab);page--;">
</div>
</form>
<button @click="page++">{{i18n("login.guest.managecareer")}}</button>
<button @click="postRegisterReq();">{{ i18n("login.guest.sendRegReq") }}</button>
</div>
</form>
</div>
</div>
</div>
<div style="display:flex; justify-content:center; " v-for="item in externalCurrTab" v-if="page===3">
<div class="bodu">
<div class="container">
<div class="school"><a style="margin-left:30px;">{{item.school}}</a></div>
<div class="formation"><a>{{item.formation}}</a></div>
<div class="edit">
<button style="background-color:rgb(105,05,105);font-size:15px;height:50px;width:75%;border:none;border-radius:20px;" @click="externalCurr.school=item.school; externalCurr.completion=item.completion; externalCurr.formation=item.formation;externalCurr.endYear=item.endYear; externalCurr.startYear=item.startYear; externalCurr.justifdocUrl;page++;">Edit </button>
</div>
<div class="remove">
<button style="background-color:rgb(105,05,105);font-size:15px;height:50px;width:75%;border:none;border-radius:20px;" @click="deleteExtCursus(item)">Remove </button>
</div>
</div>
</div>
<div v-if="page===4">
<ExternalCurriculumList v-model="externalCurrTab" :mode="2"></ExternalCurriculumList>
<button style="margin-top: 2%;width: 5%; margin-left: 2%" @click="page--">{{i18n("courses.back")}}</button>
</div>
</template>
@ -295,7 +258,6 @@
justify-content: center;
border-radius: 5%;
box-shadow:0 5px 25px #000000;
}
.form {
position:relative;
@ -325,8 +287,6 @@
z-index: 100;
font-family:sans-serif ;
color:rgb(239,60,168);
transition: 0.5;
}
.register{
@ -354,8 +314,6 @@
outline:none;
border-radius: 4px;
font-size:0.8em;
align-self: right;
}
input[type=submit],button,select{

View File

@ -17,7 +17,7 @@
const editElementID = ref("")
function editItem(id){
editElementID = id;
editElementID.value = id;
}
//Juste pour montrer le Create Mode

View File

@ -1,19 +1,23 @@
<script setup>
import {reactive, ref } from 'vue'
import {getSelf,alterSelf,disconnect,deleteUser} from '../rest/Users.js'
import {getSelfCurriculum, getAllCurriculums, getSomeonesCurriculumList} from '../rest/curriculum.js'
import {getSelfCurriculum, getAllCurriculums, getSomeonesCurriculumList, getcurriculum} from '../rest/curriculum.js'
import {getCourses} from "../rest/courses.js"
import i18n from "@/i18n.js"
import {uploadFile, uploadProfilePicture} from '@/rest/uploads.js'
import CourseList from "@/Apps/Inscription/CourseList.vue";
import {editMinerval, getCurrentMinerval} from "@/rest/minerval.js";
import {postPayment} from "@/rest/payment.js";
import {addUninscReq, createScholarshipRequest} from "@/rest/requests.js";
import {addUninscReq, createScholarshipRequest, postChangeCurrReq} from "@/rest/requests.js";
import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue";
import {getExternalCurriculumByUser} from "@/rest/externalCurriculum.js";
const user = ref(await getSelf());
const UserCurriculum = ref("");
const curricula = ref (await getAllCurriculums());
const minerv = ref({});
const extcurrlist = ref(await getExternalCurriculumByUser(user.value.regNo))
if(user.value.role === "Student"){
minerv.value = ref(await getCurrentMinerval(user.value.regNo));
UserCurriculum.value = await getSomeonesCurriculumList(user.value.regNo);
@ -22,17 +26,15 @@
if(user.role === "Teacher"){
UserCurriculum.value = await getCourses("Teacher");
}
const modif = ref(false);
const curric = ref(false);
const reg = ref(false);
const courseslist = ref(false);
const minerval = ref(false);
const paymentPage = ref(false);
const scholarship = ref(false);
const scholarshipinfos = ref(false);
const uninscr = ref(false);
const sure = ref(0);
//0 base, 1 modif, 2 curriculum, 3 register, 4 courselist, 5 minerval, 6 payment, 7 scholarship, 8 scholarshipinfos, 9 unregister, 10 sure, 11 aboutunregister, 12 manage external curriculums
const windowState = ref(0);
const isChecked = ref(false);
const reRegState = ref(0);
const pattern = {
profilPictureUrl:null,
email:null,
@ -67,32 +69,41 @@
residencyDocUrl : ""
})
const changecurrdata = reactive({
userId : user.value.regNo,
actualcursus:null,
newcursus:1
})
//Used to post a uninscription request
const uninscriptionData = reactive({
reason : null,
userId : user.value.regNo
userId : user.value.regNo,
curriculumId:null
})
const paymentAmount = ref(0);
let toModify= Object.assign({}, pattern);
let personnalInfos = Object.assign({}, patternInfos);
//Used to store the year of the new cursus selected in change cursus feature
const selectedYear = ref(0);
function resetInputs(inputs,list){
inputs=Object.assign({},list);
}
async function ChangeInfos(){
for (let element in toModify){
if (element =="email" && (toModify[element] !== null)){
if (element ==="email" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{email : toModify[element]});
}
if (element =="profilPictureUrl" && (toModify[element] !== null)){
if (element ==="profilPictureUrl" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{ profilPictureUrl : toModify[element]});
}
else if(element == "address" && (toModify[element] !== null)){
else if(element === "address" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{address : toModify[element]});
}
else if(element == "password" && (toModify[element] !== null)){
else if(element === "password" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{password : toModify[element]});
}
}
@ -133,11 +144,14 @@
return date.getFullYear()
}
async function refreshExtCurrList(){
extcurrlist.value = await getExternalCurriculumByUser(user.value.regNo)
}
//This function travels through the student cursus array and extract the current cursus of the student
function getActualCurriculumList(){
let actualCurriculumList = [];
for (let i = 0; i < UserCurriculum.value.curriculumList.length; i++){
if (UserCurriculum.value.curriculumList[i].dateyear === getYear()){
if (UserCurriculum.value.curriculumList[i].actual === true){
actualCurriculumList.push(UserCurriculum.value.curriculumList[i]);
}
}
@ -155,96 +169,139 @@
await createScholarshipRequest(scholarshipData)
}
//1 = previous 0 = next
function getCurriculumsNextYear(){
const currlist = getActualCurriculumList()
let list = []
for (let i = 0; i < currlist.length; i++){
for (let j = 0; j < curricula.value.length; j++){
if (curricula.value[j].option === currlist[i].option && curricula.value[j].year === currlist[i].year + 1){
list.push(curricula.value[j])
}
}
}
return list
}
async function getActualCurr(curr){
const cursus = await getcurriculum(curr);
for (let i = 0; i < curricula.value.length; i++){
if (curricula.value[i].option === cursus.option && curricula.value[i].year === cursus.year - 1){
changecurrdata.actualcursus = curricula.value[i].curriculumId;
}
}
}
</script>
<template>
<div class="body">
<div class="container" v-if="courseslist == false">
<div class="profilPic">
<div class="body" v-if="windowState !== 12 && windowState!==4">
<div class="container">
<div class="profilPic" v-if="windowState===0">
<img class="subContainter" :src=getPP()>
</div>
<div class="globalInfos">
<div v-if="modif==false && curric==false && reg==false && minerval==false && paymentPage == false && scholarship==false && uninscr == false" class="infosContainer">
<div v-if="windowState === 0" class="infosContainer">
<div>
{{user.firstName}} {{user.lastName}}
</div>
<div>
E-mail: {{user.email}}
{{ i18n("login.guest.email") }}: {{user.email}}
</div>
<div v-if="user.role==='Student'">
{{user.option}} {{i18n(user.role)}}
{{ i18n("regNo") }} : {{user.regNo}}
</div>
<div v-else>
Role: {{i18n((user.role))}}
{{ i18n("role") }}: {{i18n((user.role))}}
</div>
<div>
<button @click="modif=!modif; setModify(user)"> {{i18n("profile.modify.data")}} </button>
<button @click="windowState=1; setModify(user)"> {{i18n("profile.modify.data")}} </button>
</div>
<div v-if="(user.role==='Student')">
<button @click="reg=!reg">{{i18n("profile.reRegister")}}</button>
<button @click="uninscr = !uninscr" style="float:right;background-color:rgb(150,0,0);">{{i18n("profile.unRegister")}}</button>
<button @click="windowState=9" style="float:right;background-color:rgb(150,0,0);">{{i18n("profile.unRegister")}}</button>
</div>
<div v-if="(user.role==='Student')">
<button @click="curric=!curric">{{i18n("profile.change.curriculum")}}</button>
<button @click="windowState=2">{{i18n("profile.change.curriculum")}}</button>
<button @click="windowState=12;refreshExtCurrList();" style="margin-left: 2%">{{ i18n("manageextcur") }}</button>
</div>
<div v-if="(user.role==='Student')">
<button @click="courseslist=!courseslist">Manage Courses</button>
<button @click="minerval = !minerval" style="margin-left: 2%">Manage minerval</button>
<button @click="windowState=4">{{ i18n("managecourse") }}</button>
<button @click="windowState=5" style="margin-left: 2%">{{ i18n("manageminerval") }}</button>
</div>
</div>
<div v-else-if="uninscr" class="infosContainer">
<div v-if="sure != 2">Please enter the reason you leave the university</div>
<textarea v-if="sure != 2" v-model="uninscriptionData.reason"></textarea>
<div v-if="sure != 2">
<button @click="sure++">Submit</button>
<div v-else-if="windowState === 9" class="infosContainer">
<div v-if="sure !== 2">{{ i18n("enterreason") }}</div>
<textarea v-if="sure !== 2" v-model="uninscriptionData.reason"></textarea>
<div v-if="sure !== 2">
{{i18n("onlycursus")}}
<input type="checkbox" v-model="isChecked">
</div>
<div v-if="sure !== 2 && isChecked">
{{ i18n("plsselectcurs") }}
<select v-model="uninscriptionData.curriculumId">
<option v-for="item in getActualCurriculumList()" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select>
</div>
<div v-if="sure !== 2">
<button @click="sure++">{{ i18n("login.guest.submit") }}</button>
</div>
<div v-if="sure==1">
Are you sure that you want to unregister ?
<button @click="addUninscReq(uninscriptionData.userId, uninscriptionData.reason);sure++">Yes</button>
<button @click="sure=0">No</button>
{{ i18n("sureunreg") }}
<button @click="addUninscReq(uninscriptionData.userId, uninscriptionData.reason, uninscriptionData.curriculumId);sure++">{{i18n("yes")}}</button>
<button @click="sure=0">{{ i18n("no") }}</button>
</div>
<p v-if="sure==2">You request has been send !</p>
<p v-if="sure==2">{{ i18n("reqsend") }}</p>
</div>
<div v-else-if="minerval" class="infosContainer">
<div v-if="minerv.value.toPay != 0">
Payment : {{minerv.value.toPay}} left to pay
<div v-if="windowState === 9">
<button @click="windowState=0">{{i18n("courses.back")}}</button>
</div>
<div v-else-if="windowState === 5" class="infosContainer">
<div v-if="minerv.value.toPay !== 0">
{{ i18n("payment") }} : {{minerv.value.toPay}} {{ i18n("lefttopay") }}
<div v-if="minerv.value.paidAmount <= 50">
<button @click="minerval = !minerval; paymentPage = !paymentPage; paymentAmount = 50">Pay deposit (50)</button>
<button @click="windowState=6; paymentAmount = 50">{{ i18n("paydeposit") }} (50)</button>
</div>
<div>
<button @click="minerval = !minerval; paymentPage = !paymentPage; paymentAmount = minerv.value.toPay">Pay all the rest ({{minerv.value.toPay}})</button>
<button @click="windowState=6; paymentAmount = minerv.value.toPay">{{ i18n("payrest") }} ({{minerv.value.toPay}})</button>
</div>
</div>
<div v-else>
Payment : School fees have already been paid this year
{{ i18n("alreadypaid") }}
</div>
<div>
<button @click="scholarship=!scholarship; minerval=!minerval">Ask for a scholarship</button>
<button @click="windowState=7">{{ i18n("askscholarship") }}</button>
</div>
</div>
<div v-else-if="scholarship && !scholarshipinfos" class="infosContainer">
<p>Please upload the required documents</p>
<div v-if="windowState === 5">
<button @click="windowState=0">{{ i18n("courses.back") }}</button>
</div>
<div v-else-if="windowState === 7" class="infosContainer">
<p>{{i18n("uploaddocs")}}</p>
<div>
Tax justification document :
{{ i18n("taxjustdoc") }}
<input type="file" @change="scholarshipData.taxDocUrl = $event.target.files">
</div>
<div>
Residency justification document :
{{i18n("residencydoc")}}
<input type="file" style="margin-top:2%" @change="scholarshipData.residencyDocUrl = $event.target.files">
</div>
<button style="margin-top: 5%" @click="scholarshipinfos = !scholarshipinfos;postScholarshipRequest(scholarshipData.taxDocUrl, 'JustificationDocument',scholarshipData.residencyDocUrl, 'JustificationDocument');">Submit scholarship request</button>
<button style="margin-top: 5%" @click="windowState=8;postScholarshipRequest(scholarshipData.taxDocUrl, 'JustificationDocument',scholarshipData.residencyDocUrl, 'JustificationDocument');">{{i18n("login.guest.submit")}}</button>
</div>
<div v-else-if="scholarship && scholarshipinfos" class="infosContainer">
<div v-if="windowState === 7">
<button @click="windowState = 5">{{ i18n("courses.back") }}</button>
</div>
<div v-else-if="windowState === 8" class="infosContainer">
<div>
Your request has been sent to the inscription service you will get notified when
the request is reviewed.
{{i18n("reqsent")}}
</div>
<button @click="scholarshipinfos=!scholarshipinfos; scholarship=!scholarship">
Go back to profile
<button @click="windowState = 0">
{{ i18n("backprofile") }}
</button>
</div>
<div v-else-if="paymentPage" class="infosContainer">
Proceed to payment of {{paymentAmount}}
<div v-else-if="windowState === 6" class="infosContainer">
{{ i18n("procpayment") }} {{paymentAmount}}
<div style="margin-top: 1%">
Client:
<input type="text" v-model="paymentData.client">
@ -258,20 +315,20 @@
<input type="date" v-model="paymentData.expDate">
</div>
<div style="margin-top: 1%">
<button @click="paymentPage=!paymentPage;minerval=!minerval;paymentData.amount=paymentAmount;paymentData.date=new Date();postPayment(paymentData);minerv.value.toPay -= paymentAmount; minerv.value.paidAmount += paymentAmount; editMinerval(minerv.value)">Process Payment</button>
<button @click="windowState=5;paymentData.amount=paymentAmount;paymentData.date=new Date();postPayment(paymentData);minerv.value.toPay -= paymentAmount; minerv.value.paidAmount += paymentAmount; editMinerval(minerv.value)">{{i18n("procpaybutton")}}</button>
</div>
<div>
<button @click="minerval = !minerval; paymentPage = !paymentPage;">Back</button>
<button @click="windowState = 5">{{ i18n("courses.back") }}</button>
</div>
</div>
<div v-else-if="modif" class="infosContainer">
<div v-else-if="windowState === 1" class="infosContainer">
<div>
{{i18n("profile.picture")}}:
<input type="file" @change="user.profilPicture = uploadProfilePicture($event.target.files);" accept="image/*">
</div>
<div>
E-mail:
<input type="mail" v-model="toModify.email" />
{{ i18n("login.guest.email")}}
<input type="email" v-model="toModify.email" />
</div>
<div>
{{i18n("profile.address")}}:
@ -286,79 +343,85 @@
<input type="password" v-model="toModify.passwordConfirm">
</div>
<div>
<button @click=" modif=!modif; ChangeInfos();">{{i18n("courses.confirm")}}</button>
<button @click="modif=!modif; resetInputs(toModify,pattern);" style="float:right;">{{i18n("courses.back")}}</button>
<button @click="windowState = 0; ChangeInfos();">{{i18n("courses.confirm")}}</button>
<button @click="windowState = 0; resetInputs(toModify,pattern);" style="float:right;">{{i18n("courses.back")}}</button>
</div>
</div>
<div v-else-if="curric" class="infosContainer">
<div style="height:40px;">
{{i18n("Curriculum")}}:
<select v-model="curriculum" >
<option v-for="item in curricula" style="font-size:20px;" :value="item">{{item.option}}</option>
<div v-else-if="windowState === 2" class="infosContainer">
<div>
{{ i18n("iwouldlike") }}
<select v-model="reRegState">
<option :value="1">{{ i18n("rereg") }}</option>
<option :value="2">{{ i18n("reregsup") }}</option>
<option :value="3">{{ i18n("chcur") }}</option>
</select>
</div>
<div>
<button @click=" curric=!curric;">{{i18n("courses.confirm")}}</button>
<button @click="curric=!curric; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button>
<div style="height:40px;" v-if="reRegState === 3">
{{i18n("Curriculum")}}:
<select v-model="changecurrdata.actualcursus" style="margin-right: 3%">
<option v-for="item in getActualCurriculumList()" style="font-size:20px;" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select>
{{ i18n("newcurr") }} :
<select v-model="changecurrdata.newcursus">
<option v-for="item in curricula" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select>
</div>
</div>
<div v-else-if="reg" class="infosContainer">
<div>
E-mail:
<input type="mail" v-model="toModify.email" />
<div style="height:40px;" v-if="reRegState === 2">
{{ i18n("newcurr") }} :
<select v-model="changecurrdata.newcursus">
<option v-for="item in curricula" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select>
</div>
<div style="height:40px;" v-if="reRegState === 1">
{{ i18n("newcurr") }} :
<select v-model="changecurrdata.newcursus" @change="getActualCurr(changecurrdata.newcursus);">
<option v-for="item in getCurriculumsNextYear()" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select>
</div>
<div v-if="curricula[changecurrdata.newcursus-1].year > 1 && reRegState !== 1">
{{i18n("cursusprereq")}}
</div>
<div>
ID :
<input type="text" v-model="toModify.id">
</div>
<div>
{{i18n("login.password")}}:
<input type="password" v-model="toModify.password">
</div>
<div>
{{i18n("login.cPassword")}}:
<input type="password" id="confirm">
</div>
<div>
<button @click=" reg=!reg;">{{i18n("courses.confirm")}}</button>
<button @click=" reg=!reg; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button>
<button @click=" windowState = 0;postChangeCurrReq(changecurrdata);changecurrdata.actualcursus=null;changecurrdata.newcursus=1">{{i18n("courses.confirm")}}</button>
<button @click="windowState = 0; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button>
</div>
</div>
</div>
<div v-if="user.role == 'Student' && modif==false && curric==false && reg==false && minerval==false && scholarship == false && uninscr == false" class="moreInfos">
<div v-if="windowState === 0" class="moreInfos">
<div class = "oldcursus">
<div class="listTitle">
Anciens Cursus
{{ i18n("oldcursus") }}
</div>
<div class="listElement">
<div class=" containerElement" v-for="item in UserCurriculum.curriculumList">
<div class="year" v-if="parseInt(item.dateyear) !== getYear()">Bac {{item.year}}</div>
<div class="option" v-if="parseInt(item.dateyear) !== getYear()">{{item.option}}</div>
<div class="dateyear" v-if="parseInt(item.dateyear) !== getYear()">Année {{item.dateyear}}-{{item.dateyear+1}}</div>
<div class="year" v-if="item.actual === false">Bac {{item.year}}</div>
<div class="option" v-if="item.actual === false">{{item.option}}</div>
<div class="dateyear" v-if="item.actual === false">{{ i18n("year") }} {{item.dateyear}}-{{item.dateyear+1}}</div>
</div>
</div>
</div>
<div class="actualcursus">
<div class="listTitle">
Cursus Actuel
{{ i18n("newcurr") }}
</div>
<div class="listElement">
<div class=" containerElement" v-for="item in UserCurriculum.curriculumList" >
<div class="year" v-if="parseInt(item.dateyear) === getYear()">Bac {{item.year}}</div>
<div class="option" v-if="parseInt(item.dateyear) === getYear()">{{item.option}}</div>
<div class="dateyear" v-if="parseInt(item.dateyear) === getYear()">Année {{item.dateyear}}-{{item.dateyear+1}}</div>
<div class="year" v-if="item.actual === true">Bac {{item.year}}</div>
<div class="option" v-if="item.actual === true">{{item.option}}</div>
<div class="dateyear" v-if="item.actual === true">{{ i18n("year") }} {{item.dateyear}}-{{item.dateyear+1}}</div>
</div>
</div>
</div>
</div>
</div>
<div v-if="courseslist === true" style="width: 80%">
<CourseList :cursuslist="getActualCurriculumList()"/>
<button style="width: 10%; margin-top: 5%" @click="courseslist = false">Return to profile</button>
</div>
</div>
<div v-if="windowState===4" style="width: 80%; margin-top: 3%; margin-left: 10%">
<CourseList :cursuslist="getActualCurriculumList()" v-model:window-state="windowState"/>
</div>
<div v-if="windowState === 12">
<ExternalCurriculumList :ext-curr-list="extcurrlist" :mode="1"></ExternalCurriculumList>
<button @click="windowState = 0;refreshExtCurrList()" style="margin-left: 17%;margin-top: 3%">{{ i18n("backprofile") }}</button>
</div>
</template>
<style scoped>
@ -439,21 +502,6 @@
}
.name {
grid-area:name;
align-self:center;
}
.teacher{
grid-area:teacher;
align-self:center;
}
.credits{
grid-area:credits;
align-self:center;
}
.listElement{
border:2px solid black;
@ -483,7 +531,6 @@ button{
border-radius:10px;
height:35px;
margin-top:10px;
}
button:hover{

View File

@ -12,7 +12,7 @@
<template style="margin-top:5%;">
<div v-if="list === false">
<AboutStudent :target=targetRegNo />
<button style="background-color:rgb(105,05,105);width:5%; margin-left: 10%;" @click="list = true;">Back</button>
<button style="background-color:rgb(105,05,105);width:5%; margin-left: 10%;" @click="list = true;">{{ i18n("courses.back") }}</button>
</div>
<div style="display:flex; justify-content:center; " v-for="item in users" v-if="list === true">
<div class="bodu">

View File

@ -1,3 +1,7 @@
:root {
--header-size: 61px;
}
body {
background-color: rgb(53, 25, 60);
margin:0;

View File

@ -26,7 +26,7 @@ export function disconnect(){
* @param curriculum
* @param imageId id of the image in database returned when uploaded
*/
export async function register(firstname, lastname, birthDate, password, email, address, country, curriculumId, imageId, identityCardId, submissionDate, equivalence){
export async function register(firstname, lastname, birthDate, password, email, address, country, curriculumId, imageId, identityCardId, submissionDate, equivalence,admissionDocUrl){
return restPost("/register", {
firstName: firstname,
lastName: lastname,
@ -39,7 +39,8 @@ export async function register(firstname, lastname, birthDate, password, email,
profilePicture: imageId,
identityCard : identityCardId,
submissionDate : submissionDate,
equivalenceState : equivalence
equivalenceState : equivalence,
admissionDocUrl: admissionDocUrl
});
}

View File

@ -4,13 +4,13 @@ import i18n from '@/i18n.js'
// Liste des apps
import LoginPage from '@/Apps/Login.vue'
import Inscription from "@/Apps/Inscription/ManageRequests.vue"
import Profil from "@/Apps/Profil.vue"
import Courses from "@/Apps/ManageCourses.vue"
import Users from "@/Apps/UsersList.vue"
import Students from "@/Apps/StudentsList.vue"
import AboutStudent from "@/Apps/Inscription/AboutStudent.vue";
import Msg from "@/Apps/Msg.vue"
import Forums from '@/Apps/Forums.vue'
import Payments from "@/Apps/Inscription/PaymentInfo.vue";
import ManageRequests from "@/Apps/Inscription/ManageRequests.vue";
const apps = {
@ -21,17 +21,20 @@ const apps = {
'/users-list' : Users,
'/students-list' : Students,
'/msg' : Msg,
'/forums': Forums,
'/payments': Payments
}
const appsList = {
'Msg': { path: '#/msg', icon: 'fa-comment', text: i18n("app.messages") },
'Notification': { path: '#/notifs', icon: 'fa-bell', text: i18n("app.notifications") },
'Forum': { path: '#/forum', icon: 'fa-envelope', text: i18n("app.forum") },
'Forum': { path: '#/forums', icon: 'fa-envelope', text: i18n("app.forum") },
'Schedule': { path: '#/schedule', icon: 'fa-calendar-days', text: i18n("app.schedules") },
'Requests': { path: '#/requests', icon: 'fa-users', text: "Requests" },
'ManageCourses': { path: '#/manage-courses', icon: 'fa-book', text: i18n("app.manage.courses") },
'StudentsList':{ path: '#/students-list',icon: 'fa-users',text: i18n("app.studentList")},
'UsersList':{ path: '#/users-list',icon: 'fa-users',text: i18n("app.users")},
'Payments':{path: '#/payments', icon:'fa-users', text:i18n("app.payments")}
}
const currentPath = ref(window.location.hash)

View File

@ -71,3 +71,11 @@ export async function getCourses(role){
export async function alterCourse(id, changes){
return restPatch("/course/" + id, changes);
}
/**
* Return a list containing all the actual courses of a user
*/
export async function getUserActualCourses(){
return restGet("/usercourses")
}

View File

@ -1,15 +1,16 @@
import {restGet, restPatch, restPost} from "@/rest/restConsumer.js";
import {parseInteger} from "jsdom/lib/jsdom/living/helpers/strings.js";
export async function createExternalCurriculum(inscriptionRequestId,school, formation, completion, startYear, endYear, justifdocUrl){
export async function createExternalCurriculum(inscriptionRequestId,school, formation, completion, startYear, endYear, justifdocUrl, userRegNo){
return restPost("/externalcurriculum", {
inscriptionRequestId: inscriptionRequestId,
school:school,
formation :formation,
completion : completion,
startYear : parseInteger(startYear),
endYear: parseInteger(endYear),
justifdocUrl : justifdocUrl
startYear : startYear,
endYear: endYear,
justifdocUrl : justifdocUrl,
userRegNo : userRegNo
})
}

View File

@ -0,0 +1,50 @@
/*******************************************************
* File: forum.js
* Author: Anthony Debucquoy
* Scope: Extension messagerie
* Description: Forum related functions and calls
*******************************************************/
import { ref } from 'vue'
import { restGet, restPost, restDelete, restPatch } from './restConsumer.js'
/**
* List forums of a course
*/
export async function getForumsOfCourse(id){
ForumsOfCurrentCourse.value = await restGet("/forums/" + id)
}
export const ForumsOfCurrentCourse = ref();
export function createForum(id, name){
restPost("/forums/" + id, {name: name}).then(_ => getForumsOfCourse(id));
}
/**
* List post of a specified forum
*/
export async function getPostsOfForum(id){
if(id != null){
PostsOfCurrentForum.value = await restGet("/forum/" + id);
}
}
export function createPost(id, subject, content){
restPost("/forum/" + id, {subject: subject, content: content}).then(_ => getPostsOfForum(id));
}
export const PostsOfCurrentForum = ref();
/**
* Get a post and its responses
*/
export async function fetchPost(id){
fetchedPost.value = await restGet("/forum/post/" + id);
}
export function sendAnswer(id, content){
restPost("/forum/post/" + id, {content: content}).then(_ => fetchPost(id))
}
export const fetchedPost = ref();

View File

@ -20,6 +20,62 @@ export async function editEquivalenceState(id, newstate){
return restPatch("/request/registerequiv/"+id+"/"+newstate)
}
export async function addUninscReq(userId, reason){
return restPost("/uninscriptionreq", {"userId" : userId, "reason" : reason})
export async function addUninscReq(userId, reason, curriculumId){
return restPost("/unregister", {"userId" : userId, "reason" : reason, "curriculumId":curriculumId})
}
export async function editScholarshipReq(body){
return restPatch("/scholarshipreq/", body)
}
export async function getScholarshipReqById(id){
return restGet("/scholarshipreq/"+id)
}
export async function getAllUnregisters(){
return restGet("/unregister")
}
export async function getUnregisterbyId(id){
return restGet("/unregister/"+id)
}
export async function editUnregReq(id, newstate){
return restPatch("/unregister/"+id+"/"+newstate)
}
export async function getAllPayments(){
return restGet("/payment")
}
export async function postChangeCurrReq(item){
return restPost("/changecurriculumreq", item)
}
export async function getAllChangeCurrReq(){
return restGet("/changecurriculumreq")
}
export async function getChangeCurrReqById(id){
return restGet("/changecurriculumreq/"+id)
}
export async function editChangeCurrReq(id, newState){
return restPatch("/changecurriculumreq/"+id+"/"+newState)
}
export async function editChangeCurrReqTeacherState(id, newState){
return restPatch("/changecurriculumreqteacher/"+id+"/"+newState)
}
export async function getExempReq(id){
return restGet("/exemptionsreq/"+id)
}
export async function editExempReqState(id, newstate){
return restPatch("/exemptionsreq/"+id+"/"+newstate)
}
export async function getExempByUser(userId){
return restGet("/exemptionreq/"+userId)
}

View File

@ -13,11 +13,11 @@ export async function uploadProfilePicture(file){
/**
* More generic version of the upload method
* More generic version of the uploadProfilePicture method
*/
export async function uploadFile(file, type){
const formData = new FormData();
formData.append("file", file[0]);
return restPostFile("/upload/"+type, formData)
}
}