Compare commits

...

6 Commits

Author SHA1 Message Date
c15ddccbb0 Merge pull request 'Leo/InscriptionDesEtudiants' (#163) from Leo/InscriptionDesEtudiants into master
Some checks failed
Build and test backend / Build-backend (push) Successful in 1m25s
deploy to production / deploy-frontend (push) Successful in 27s
deploy to production / deploy-backend (push) Failing after 2m2s
Build and test FrontEnd / Build-frontend (push) Successful in 26s
Reviewed-on: #163
2024-04-19 20:44:55 +02:00
211bf77322 Merge pull request 'master' (#162) from master into Leo/InscriptionDesEtudiants
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 26s
Reviewed-on: #162
2024-04-19 20:40:58 +02:00
4e14370d4f Add the exemptions gestion and improve the navigation between requests 2024-04-19 19:25:28 +02:00
69fb4e881e Add the Teacher approval for reregister requests 2024-04-19 15:53:31 +02:00
25575fa4e0 Implements some files uploading in the inscription form and change inscriptionRequest and Curriculum for the cursus acceptance attestation feature 2024-04-19 12:26:48 +02:00
5a57fc78f3 Generalize the ExternalCurriculumList interface so it fits for inscriptionRequest, Studentlist, and inscriptionform 2024-04-19 09:31:55 +02:00
19 changed files with 416 additions and 205 deletions

View File

@ -88,6 +88,28 @@ public class RequestsController {
return new ResponseEntity<>(toReturn, HttpStatus.OK); return new ResponseEntity<>(toReturn, HttpStatus.OK);
} }
@GetMapping(value = "/exemptionsreq/{id}")
public ResponseEntity<ExemptionsRequest> getExemptionRequestbyId(@RequestHeader("Authorization") String token, @PathVariable long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ExemptionsRequest exemptionsRequest = err.findById(id);
return new ResponseEntity<>(exemptionsRequest, HttpStatus.OK);
}
@PatchMapping(value = "/exemptionsreq/{id}/{newstate}")
public ResponseEntity<String> changeExemptionReqState(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newstate){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ExemptionsRequest exemptionsRequest = err.findById(id);
exemptionsRequest.setState(newstate);
err.save(exemptionsRequest);
return new ResponseEntity<>(HttpStatus.OK);
}
//Get all the scholarships requests //Get all the scholarships requests
@GetMapping(value = "/scholarshipreq") @GetMapping(value = "/scholarshipreq")
public ResponseEntity<ArrayList<ScholarshipRequest>> getAllScholarshipRequests(@RequestHeader("Authorization") String token){ public ResponseEntity<ArrayList<ScholarshipRequest>> getAllScholarshipRequests(@RequestHeader("Authorization") String token){
@ -176,6 +198,16 @@ public class RequestsController {
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
//We look in the usercursus table if the student has already the previous year of a curriculum
public boolean studentHasPrevYear(Curriculum curriculum, User user){
ArrayList<UserCurriculum> userCurrList = userCurriculumRepository.findByUserOrderByCurriculum(user);
for (int i = 0; i < userCurrList.size(); i++){
if (userCurrList.get(i).getCurriculum().getOption().equals(curriculum.getOption()) && userCurrList.get(i).getCurriculum().getYear() == curriculum.getYear()-1){
return true;
}
}
return false;
}
@PostMapping("/changecurriculumreq") @PostMapping("/changecurriculumreq")
public ResponseEntity<String> addChangeCurrReq(@RequestBody Map<String,Object> reqInfos){ public ResponseEntity<String> addChangeCurrReq(@RequestBody Map<String,Object> reqInfos){
User user = userRepository.findById((Integer) reqInfos.get("userId")); User user = userRepository.findById((Integer) reqInfos.get("userId"));
@ -191,8 +223,12 @@ public class RequestsController {
Curriculum destinationCurriculum = curriculumRepository.findById((Integer) reqInfos.get("newcursus")); Curriculum destinationCurriculum = curriculumRepository.findById((Integer) reqInfos.get("newcursus"));
ChangeCurriculumRequest changeCurriculumRequest = new ChangeCurriculumRequest(user, actualCurriculum, destinationCurriculum, new Date(), RequestState.Pending); ChangeCurriculumRequest changeCurriculumRequest = new ChangeCurriculumRequest(user, actualCurriculum, destinationCurriculum, new Date(), RequestState.Pending, RequestState.Unrequired);
//Si l'année du cursus est plus grande que 1 et que l'étudiant n'a pas dans sa liste de cursus l'année d'en dessous alors on demande l'accord du prof
if (destinationCurriculum.getYear() > 1 && !studentHasPrevYear(destinationCurriculum, user)){
changeCurriculumRequest.setTeacherApprovalState(RequestState.Pending);
}
changeCurriculumRequestRepository.save(changeCurriculumRequest); changeCurriculumRequestRepository.save(changeCurriculumRequest);
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
@ -228,8 +264,34 @@ public class RequestsController {
toEdit.setState(newState); toEdit.setState(newState);
if (newState == RequestState.Accepted){ if (newState == RequestState.Accepted && (toEdit.getTeacherApprovalState() == RequestState.Accepted || toEdit.getTeacherApprovalState() == RequestState.Unrequired)){
//If actual curriculum is not null then we need to set that the user doesn't follow it anymore //If actual curriculum is not null then we need to set that the user doesn't follow it anymore
acceptProcedure(toEdit);
}
changeCurriculumRequestRepository.save(toEdit);
return new ResponseEntity<>(HttpStatus.OK);
}
@PatchMapping("/changecurriculumreqteacher/{id}/{newteacherstate}")
public ResponseEntity<String> editCCReqTeacherState(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newteacherstate){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ChangeCurriculumRequest toEdit = changeCurriculumRequestRepository.findById(id);
toEdit.setState(newteacherstate);
if (newteacherstate == RequestState.Accepted && toEdit.getState() == RequestState.Accepted){
//If actual curriculum is not null then we need to set that the user doesn't follow it anymore
acceptProcedure(toEdit);
}
changeCurriculumRequestRepository.save(toEdit);
return new ResponseEntity<>(HttpStatus.OK);
}
private void acceptProcedure(ChangeCurriculumRequest toEdit) {
User u = toEdit.getUser(); User u = toEdit.getUser();
if (toEdit.getActualCurriculum() != null){ if (toEdit.getActualCurriculum() != null){
ArrayList<UserCurriculum> listcurr = userCurriculumRepository.findByUserOrderByCurriculum(u); ArrayList<UserCurriculum> listcurr = userCurriculumRepository.findByUserOrderByCurriculum(u);
@ -247,8 +309,4 @@ public class RequestsController {
UserCurriculum userCurriculum = new UserCurriculum(u, toEdit.getDestinationCurriculum(), c.get(Calendar.YEAR), true); UserCurriculum userCurriculum = new UserCurriculum(u, toEdit.getDestinationCurriculum(), c.get(Calendar.YEAR), true);
userCurriculumRepository.save(userCurriculum); userCurriculumRepository.save(userCurriculum);
} }
changeCurriculumRequestRepository.save(toEdit);
return new ResponseEntity<>(HttpStatus.OK);
}
} }

View File

@ -83,13 +83,15 @@ public class MockController {
minervalRepository.save(minerval); minervalRepository.save(minerval);
// Course / Curriculum part // Course / Curriculum part
Curriculum infoBab1 = new Curriculum(1,"info"); Curriculum infoBab1 = new Curriculum(1,"info", false);
Curriculum chemistryBab1 = new Curriculum(1,"chemistry"); Curriculum chemistryBab1 = new Curriculum(1,"chemistry", false);
Curriculum psychologyBab1 = new Curriculum(1,"psychology"); Curriculum psychologyBab1 = new Curriculum(1,"psychology", false);
Curriculum infoBab2 = new Curriculum(2,"info"); Curriculum infoBab2 = new Curriculum(2,"info", false);
Curriculum masterinfo1 = new Curriculum(4, "info"); Curriculum masterinfo1 = new Curriculum(4, "info", false);
Curriculum masterinfo2 = new Curriculum(5, "info"); Curriculum masterinfo2 = new Curriculum(5, "info", false);
Curriculum chemistryBab2 = new Curriculum(2, "chemistry"); Curriculum chemistryBab2 = new Curriculum(2, "chemistry", false);
Curriculum ingebab1 = new Curriculum(1, "ingénieur", true);
curriculumService.save(infoBab1); curriculumService.save(infoBab1);
curriculumService.save(chemistryBab1); curriculumService.save(chemistryBab1);
curriculumService.save(psychologyBab1); curriculumService.save(psychologyBab1);
@ -97,6 +99,7 @@ public class MockController {
curriculumService.save(masterinfo1); curriculumService.save(masterinfo1);
curriculumService.save(masterinfo2); curriculumService.save(masterinfo2);
curriculumService.save(chemistryBab2); curriculumService.save(chemistryBab2);
curriculumService.save(ingebab1);
ucr.save(new UserCurriculum(joe, infoBab1, 2022, false)); ucr.save(new UserCurriculum(joe, infoBab1, 2022, false));
ucr.save(new UserCurriculum(joe, chemistryBab1, 2023, true)); ucr.save(new UserCurriculum(joe, chemistryBab1, 2023, true));
@ -128,8 +131,7 @@ public class MockController {
CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,commun)); CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,commun));
CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,chemistry1)); CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,chemistry1));
InscriptionRequest inscriptionRequest = new InscriptionRequest("helen","prenom","non","helen@gmail.com","america",new Date(),(long) 4,RequestState.Pending,"yes.png","password", null, new Date(), RequestState.Pending, null);
InscriptionRequest inscriptionRequest = new InscriptionRequest("helen","prenom","non","helen@gmail.com","america",new Date(),(long) 4,RequestState.Pending,"yes.png","password", null, new Date(), RequestState.Pending);
inscriptionService.save(inscriptionRequest); inscriptionService.save(inscriptionRequest);

View File

@ -4,5 +4,5 @@ import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Inscription.ExemptionsRequest; import ovh.herisson.Clyde.Tables.Inscription.ExemptionsRequest;
public interface ExemptionsRequestRepository extends CrudRepository<ExemptionsRequest, Long> { public interface ExemptionsRequestRepository extends CrudRepository<ExemptionsRequest, Long> {
ExemptionsRequest findById(long id);
} }

View File

@ -46,7 +46,7 @@ public class CurriculumCourseService {
toReturn.put("curriculumId", curriculum.getCurriculumId()); toReturn.put("curriculumId", curriculum.getCurriculumId());
toReturn.put("year", curriculum.getYear()); toReturn.put("year", curriculum.getYear());
toReturn.put("option", curriculum.getOption()); toReturn.put("option", curriculum.getOption());
toReturn.put("requireCertificate", curriculum.isRequireCertificate());
return toReturn; return toReturn;
} }

View File

@ -26,14 +26,16 @@ public class ChangeCurriculumRequest {
private RequestState state; private RequestState state;
private RequestState teacherApprovalState;
public ChangeCurriculumRequest(){} public ChangeCurriculumRequest(){}
public ChangeCurriculumRequest(User user, Curriculum actualCurriculum, Curriculum destinationCurriculum, Date date, RequestState state){ public ChangeCurriculumRequest(User user, Curriculum actualCurriculum, Curriculum destinationCurriculum, Date date, RequestState state, RequestState teacherApprovalState){
this.user = user; this.user = user;
this.actualCurriculum = actualCurriculum; this.actualCurriculum = actualCurriculum;
this.destinationCurriculum = destinationCurriculum; this.destinationCurriculum = destinationCurriculum;
this.date = date; this.date = date;
this.state = state; this.state = state;
this.teacherApprovalState = teacherApprovalState;
} }
public User getUser() { public User getUser() {
@ -80,4 +82,14 @@ public class ChangeCurriculumRequest {
public int getId() { public int getId() {
return id; return id;
} }
public RequestState getTeacherApprovalState() {
return teacherApprovalState;
} }
public void setTeacherApprovalState(RequestState teacherApprovalState) {
this.teacherApprovalState = teacherApprovalState;
}
}

View File

@ -12,9 +12,13 @@ public class Curriculum {
private int curriculumId; private int curriculumId;
private int year; private int year;
private String option; private String option;
public Curriculum(int year, String option){
//True if the curriculum need an entry exam
private boolean requireCertificate;
public Curriculum(int year, String option, boolean requireCertificate){
this.year = year; this.year = year;
this.option = option; this.option = option;
this.requireCertificate = requireCertificate;
} }
public Curriculum() {} public Curriculum() {}
@ -39,4 +43,11 @@ public class Curriculum {
this.option = option; this.option = option;
} }
public void setRequireCertificate(boolean requireCertificate) {
this.requireCertificate = requireCertificate;
}
public boolean isRequireCertificate() {
return requireCertificate;
}
} }

View File

@ -3,5 +3,6 @@ package ovh.herisson.Clyde.Tables;
public enum FileType { public enum FileType {
ProfilePicture, ProfilePicture,
EducationCertificate, EducationCertificate,
JustificationDocument JustificationDocument,
IdentityCard,
} }

View File

@ -80,4 +80,8 @@ public class ExemptionsRequest {
public void setDate(Date date) { public void setDate(Date date) {
this.date = date; this.date = date;
} }
public int getId() {
return id;
}
} }

View File

@ -22,11 +22,12 @@ public class InscriptionRequest {
private String profilePicture; private String profilePicture;
private String password; private String password;
private String identityCard; private String identityCard;
private String admissionDocUrl;
private Date submissionDate; private Date submissionDate;
private RequestState equivalenceState; private RequestState equivalenceState;
public InscriptionRequest(){} public InscriptionRequest(){}
public InscriptionRequest(String lastName, String firstName, String address, String email, String country, Date birthDate,Long curriculumId, RequestState state, String profilePicture, String password, String identityCard, Date submissionDate, RequestState equivalenceState){ public InscriptionRequest(String lastName, String firstName, String address, String email, String country, Date birthDate,Long curriculumId, RequestState state, String profilePicture, String password, String identityCard, Date submissionDate, RequestState equivalenceState, String admissionDocUrl){
this.lastName = lastName; this.lastName = lastName;
this.firstName = firstName; this.firstName = firstName;
this.address = address; this.address = address;
@ -40,6 +41,7 @@ public class InscriptionRequest {
this.identityCard = identityCard; this.identityCard = identityCard;
this.submissionDate = submissionDate; this.submissionDate = submissionDate;
this.equivalenceState = equivalenceState; this.equivalenceState = equivalenceState;
this.admissionDocUrl = admissionDocUrl;
} }
public int getId() { public int getId() {
@ -149,4 +151,12 @@ public class InscriptionRequest {
public void setEquivalenceState(RequestState equivalenceState) { public void setEquivalenceState(RequestState equivalenceState) {
this.equivalenceState = equivalenceState; this.equivalenceState = equivalenceState;
} }
public String getAdmissionDocUrl() {
return admissionDocUrl;
}
public void setAdmissionDocUrl(String admissionDocUrl) {
this.admissionDocUrl = admissionDocUrl;
}
} }

View File

@ -1,81 +0,0 @@
package ovh.herisson.Clyde.Tables.Inscription;
import jakarta.persistence.*;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import ovh.herisson.Clyde.Tables.Curriculum;
import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.User;
@Entity
public class ReInscriptionRequest {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@ManyToOne
@JoinColumn(name = "Users")
@OnDelete(action = OnDeleteAction.CASCADE)
private User user;
@ManyToOne
@JoinColumn(name = "Curriculum")
@OnDelete(action = OnDeleteAction.CASCADE)
private Curriculum newCurriculum;
private RequestState state;
//Permet de différencier les demandes de changement et une réinscription dans le même Curriculum
//Pour la réinscription on va le mettre a 0
private boolean type = false;
public ReInscriptionRequest(){}
public ReInscriptionRequest(User user, Curriculum newCurriculum, RequestState state, boolean type){
this.user = user;
this.newCurriculum = newCurriculum;
this.state = state;
this.type = type;
}
public ReInscriptionRequest(User user, Curriculum newCurriculum, RequestState state){
this.user = user;
this.newCurriculum = newCurriculum;
this.state = state;
}
public int getId() {
return id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Curriculum getNewCurriculum() {
return newCurriculum;
}
public void setNewCurriculum(Curriculum newCurriculum) {
this.newCurriculum = newCurriculum;
}
public RequestState getState() {
return state;
}
public void setState(RequestState state) {
this.state = state;
}
public boolean isType() {
return type;
}
public void setType(boolean type) {
this.type = type;
}
}

View File

@ -1,34 +1,40 @@
<script setup> <script setup>
import { import {
addUninscReq, editChangeCurrReq, addUninscReq, editChangeCurrReq, editChangeCurrReqTeacherState,
editScholarshipReq, editScholarshipReq,
editUnregReq, getChangeCurrReqById, editUnregReq, getChangeCurrReqById,
getScholarshipReqById, getScholarshipReqById,
getUnregisterbyId getUnregisterbyId
} from "@/rest/requests.js"; } from "@/rest/requests.js";
import i18n from "@/i18n.js"; import i18n from "@/i18n.js";
import {getUser} from "@/rest/Users.js"; import {getSelf, getUser} from "@/rest/Users.js";
import {reactive, ref} from "vue"; import {reactive, ref} from "vue";
import AboutStudent from "@/Apps/Inscription/AboutStudent.vue"; import AboutStudent from "@/Apps/Inscription/AboutStudent.vue";
const props = defineProps(["reqId"]) const props = defineProps(["reqId"])
const req = ref(await getChangeCurrReqById(props.reqId)) const req = ref(await getChangeCurrReqById(props.reqId))
const user = await getSelf()
//0 liste, 1 profil //0 liste, 1 profil
const windowstate = ref(0); const localwindowstate = ref(0);
const tag = req.value.user.regNo const tag = req.value.user.regNo
const windowState = defineModel("windowState")
async function uploadandrefreshChangeRequest(state){ async function uploadandrefreshChangeRequest(state){
await editChangeCurrReq(req.value.id, state); await editChangeCurrReq(req.value.id, state);
} }
async function editChangeCurrReqTeacherApproval(state){
await editChangeCurrReqTeacherState(req.value.id, state)
}
</script> </script>
<template> <template>
<div class="body" v-if="windowstate === 0"> <div class="body" v-if="localwindowstate === 0">
<div class="container"> <div class="container">
<div class="globalInfos"> <div class="globalInfos">
<div class="infosContainer"> <div class="infosContainer">
@ -46,19 +52,26 @@ async function uploadandrefreshChangeRequest(state){
Wanted cursus : Bac {{req.destinationCurriculum.year}} {{req.destinationCurriculum.option}} Wanted cursus : Bac {{req.destinationCurriculum.year}} {{req.destinationCurriculum.option}}
</div> </div>
<div> <div>
<button @click="windowstate++"> See profile </button> <button @click="localwindowstate++"> See profile </button>
</div> </div>
<div> <div>
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';uploadandrefreshChangeRequest('Accepted')">Accept</button> <button v-if="req.state === 'Pending'" @click="req.state='Accepted';uploadandrefreshChangeRequest('Accepted')">Accept</button>
<button v-if="req.state === 'Pending'" @click="req.state='Refused';uploadandrefreshChangeRequest('Refused')" style="margin-left: 2%;">Refuse</button> <button v-if="req.state === 'Pending'" @click="req.state='Refused';uploadandrefreshChangeRequest('Refused')" style="margin-left: 2%;">Refuse</button>
</div> </div>
<div v-if="user.role === 'Teacher' || user.role === 'Admin'">
<button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Accepted';editChangeCurrReqTeacherApproval('Accepted')">Accept equivalence</button>
<button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Refused';editChangeCurrReqTeacherApproval('Refused')">Refuse equivalence</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div v-if="windowstate === 1"> </div>
<div v-if="localwindowstate === 0">
<button @click="windowState = 0" style="margin-left: 10%">Back</button>
</div>
<div v-if="localwindowstate === 1">
<AboutStudent :target="tag"></AboutStudent> <AboutStudent :target="tag"></AboutStudent>
<button @click="windowstate--;">Return to request</button> <button @click="localwindowstate--;">Back</button>
</div> </div>
</template> </template>

View File

@ -0,0 +1,116 @@
<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>
Firstname/Name : {{req.user.firstName}} {{req.user.lastName}}
</div>
<div>
Course: {{req.course.title}}
</div>
<div>
State : {{req.state}}
</div>
<div>
<button @click="profile = !profile">Voir le profil</button>
</div>
<div>
<button>Download justification document</button>
</div>
<div>
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';editExemp('Accepted')">Accept</button>
<button v-if="req.state === 'Pending'" @click="req.state='Refused';editExemp('Refused')" style="margin-left: 2%;">Refuse</button>
</div>
</div>
</div>
</div>
</div>
<div v-else>
<AboutStudent :target="req.user.regNo"></AboutStudent>
<button @click="profile=!profile">Back</button>
</div>
<div>
<button v-if="profile===false" @click="windowState = 0" style="margin-left: 30%">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;
}
</style>

View File

@ -16,6 +16,8 @@ const user = await getSelf();
const list = ref(false); const list = ref(false);
const externalCurriculum = await getExternalCurriculumByInscrReq(request.id) const externalCurriculum = await getExternalCurriculumByInscrReq(request.id)
//Get the parent page windowState to display the correct button
const windowState = defineModel("windowState")
function getPP(){ function getPP(){
if(request.profilePictureUrl === null){ if(request.profilePictureUrl === null){
return "/Clyde.png" return "/Clyde.png"
@ -61,12 +63,15 @@ async function editEquivalence(id, newstate){
</div> </div>
</div> </div>
</div> </div>
<div v-if="list == false">
<button @click="windowState = 0">Back</button>
</div>
<div v-if="list==true"> <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%;"> <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, '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;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%" @click="list=false">Back</button>
</div> </div>
</div> </div>
</template> </template>

View File

@ -4,15 +4,23 @@
import {getSelf} from "@/rest/Users.js"; import {getSelf} from "@/rest/Users.js";
import {createExternalCurriculum, getExternalCurriculumByUser} from "@/rest/externalCurriculum.js"; import {createExternalCurriculum, getExternalCurriculumByUser} from "@/rest/externalCurriculum.js";
//mode 0 = externalcurr related to inscrreq, 1 = externalcurr related to user //mode 0 = externalcurr related to inscrreq, 1 = externalcurr related to user, 2 inscription procedure
const props = defineProps(["extCurrList", "mode"]) const props = defineProps(["extCurrList", "mode"])
const extCurrList = ref(props.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 User = await getSelf()
const list = ref(true) const list = ref(true)
const editmode = ref(false)
const notcompletedCheck = ref(false); const notcompletedCheck = ref(false);
const externalCurr = reactive({ const externalCurr = reactive({
@ -28,22 +36,49 @@
if (props.mode === 1){ if (props.mode === 1){
externalCurr.userRegNo = props.extCurrList[0].user.regNo 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(){ async function postExternalCurr(){
if (props.mode === 1){
await createExternalCurriculum(externalCurr.inscriptionRequestId, externalCurr.school, externalCurr.formation, externalCurr.completion, externalCurr.startYear, externalCurr.endYear, externalCurr.justifdocUrl, externalCurr.userRegNo); await createExternalCurriculum(externalCurr.inscriptionRequestId, externalCurr.school, externalCurr.formation, externalCurr.completion, externalCurr.startYear, externalCurr.endYear, externalCurr.justifdocUrl, externalCurr.userRegNo);
//We refresh the list //We refresh the list
extCurrList.value = await getExternalCurriculumByUser(externalCurr.userRegNo); extCurrList.value = await getExternalCurriculumByUser(externalCurr.userRegNo);
list.value = !list.value; 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;
console.log(externalCurrTab.value)
}
} }
</script> </script>
<template style="margin-top:5%;"> <template style="margin-top:5%;">
<div v-if="list"> <div v-if="list">
<div v-if="User.regNo === externalCurr.userRegNo" style="margin-left: 2%;margin-top: 2%"> <div v-if="props.mode === 2||User.regNo === externalCurr.userRegNo" style="margin-left: 2%;margin-top: 2%">
<button @click="list = !list">Add external curriculum</button> <button @click="list = !list">Add external curriculum</button>
</div> </div>
<div style="display:flex; justify-content:center; " v-for="item in extCurrList"> <div style="display:flex; justify-content:center; " v-for="(item, index) in extCurrList">
<div class="bodu"> <div class="bodu">
<div class="container"> <div class="container">
<div class="status"><a style="margin-left:30px">{{item.state}}</a></div> <div class="status"><a style="margin-left:30px">{{item.state}}</a></div>
@ -51,6 +86,8 @@
<div class="formation"><a>{{item.formation}}</a></div> <div class="formation"><a>{{item.formation}}</a></div>
<div class="completion"><a>{{item.completion}}</a></div> <div class="completion"><a>{{item.completion}}</a></div>
<div class="download"><button>Download document</button></div> <div class="download"><button>Download document</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">Edit</button></div>
<div class="delete" v-if="props.mode === 2"><button @click="deleteExtCursus(item)">Delete</button></div>
</div> </div>
</div> </div>
</div> </div>
@ -82,7 +119,8 @@
<input type="number" v-model="externalCurr.endYear"> <input type="number" v-model="externalCurr.endYear">
</div> </div>
<div class="inputBox" style="margin-top: 3%; margin-bottom: 3%"> <div class="inputBox" style="margin-top: 3%; margin-bottom: 3%">
<input type="submit" value="Upload curriculum" @click="postExternalCurr()"> <input v-if="!editmode" type="submit" value="Upload curriculum" @click="postExternalCurr()">
<input v-else type="submit" value="Edit curriculum" @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> </div>
</form> </form>
</div> </div>
@ -94,9 +132,9 @@
height:100px; height:100px;
font-size:30px; font-size:30px;
display:grid; display:grid;
grid-template-columns:15% 10% 20% 15% 13.1%; grid-template-columns:5% 10% 20% 15% 20% 10%;
grid-template-areas: grid-template-areas:
"status school formation completion download"; "status school formation completion download edit delete";
column-gap:10px; column-gap:10px;
} }
@ -106,6 +144,15 @@
font-size: 70%; font-size: 70%;
} }
.edit{
grid-area: edit;
align-self: center;
}
.delete{
grid-area: delete;
align-self: center;
}
.school{ .school{
grid-area:school; grid-area:school;
align-self:center; align-self:center;

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import i18n from "@/i18n.js" import i18n from "@/i18n.js"
import {ref} from 'vue' import {ref, vModelSelect} from 'vue'
import {validateRegister, getAllRegisters } from '@/rest/ServiceInscription.js' import {validateRegister, getAllRegisters } from '@/rest/ServiceInscription.js'
import AboutRequest from "@/Apps/Inscription/AboutRequest.vue"; import AboutRequest from "@/Apps/Inscription/AboutRequest.vue";
import { import {
@ -12,6 +12,7 @@
import AboutScholarship from "@/Apps/Inscription/AboutScholarship.vue"; import AboutScholarship from "@/Apps/Inscription/AboutScholarship.vue";
import AboutUnregister from "@/Apps/Inscription/AboutUnregister.vue"; import AboutUnregister from "@/Apps/Inscription/AboutUnregister.vue";
import AboutChangeCurriculum from "@/Apps/Inscription/AboutChangeCurriculum.vue"; import AboutChangeCurriculum from "@/Apps/Inscription/AboutChangeCurriculum.vue";
import AboutExemption from "@/Apps/Inscription/AboutExemption.vue";
const requests = ref(await getAllRegisters()); const requests = ref(await getAllRegisters());
let targetId = ""; let targetId = "";
@ -19,8 +20,8 @@
const requestType = ref("inscription"); const requestType = ref("inscription");
const filterType = ref("None"); const filterType = ref("None");
//0 = liste, 1 = détails, 2 = sure?, 3 = manage scholarship, 4 manage unregister, 5 = manage curriculum change //0 = liste, 1 = détails, 2 = sure?, 3 = manage scholarship, 4 manage unregister, 5 = manage curriculum change, 6 = manage exemptions
let windowsState = ref(0); const windowsState = ref(0);
async function upPage(id,review){ async function upPage(id,review){
await validateRegister(id,review); await validateRegister(id,review);
@ -52,7 +53,7 @@
<template> <template>
<div v-if="windowsState === 1"> <div v-if="windowsState === 1">
<AboutRequest :target="targetId"></AboutRequest> <AboutRequest :target="targetId" v-model:window-state="windowsState"></AboutRequest>
</div> </div>
<div v-if="windowsState === 0"> <div v-if="windowsState === 0">
<div style="margin-top: 2%;margin-left: 2%"> <div style="margin-top: 2%;margin-left: 2%">
@ -104,7 +105,7 @@
<div class="studentlastname">{{item.user.lastName}}</div> <div class="studentlastname">{{item.user.lastName}}</div>
<div class="course">{{item.course.title}}</div> <div class="course">{{item.course.title}}</div>
<div class="reqState">{{item.state}}</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">More infos</button></div>
</div> </div>
<div class="container" v-if="requestType === 'unregister'" style="grid-template-columns:17% 15% 12% 15%;grid-template-areas:'date reqState regno studentfirstname studentlastname infos';"> <div class="container" v-if="requestType === '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="date" v-if="item.date != undefined">{{item.date.slice(0,10)}}</div>
@ -114,11 +115,12 @@
<div class="reqState">{{item.state}}</div> <div class="reqState">{{item.state}}</div>
<div class="infos"><button @click="windowsState=4;targetId=item.id">More infos</button></div> <div class="infos"><button @click="windowsState=4;targetId=item.id">More infos</button></div>
</div> </div>
<div class="container" v-if="requestType === 'curriculum change'" style="grid-template-columns:17% 15% 12% 15%;grid-template-areas:'date reqState regno studentfirstname studentlastname infos';"> <div class="container" v-if="requestType === 'curriculum change'" 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="date" v-if="item.date != undefined">{{item.date.slice(0,10)}}</div>
<div class="studentfirstname">{{item.user.firstName}}</div> <div class="studentfirstname">{{item.user.firstName}}</div>
<div class="studentlastname">{{item.user.lastName}}</div> <div class="studentlastname">{{item.user.lastName}}</div>
<div class="reqState">{{item.state}}</div> <div class="reqState">IS approval : {{item.state}}</div>
<div class="teacherApproval">Teacher approval : {{item.teacherApprovalState}}</div>
<div class="infos"><button @click="windowsState=5;targetId=item.id">More infos</button></div> <div class="infos"><button @click="windowsState=5;targetId=item.id">More infos</button></div>
</div> </div>
</div> </div>
@ -137,9 +139,13 @@
</div> </div>
<div v-if="windowsState === 4"> <div v-if="windowsState === 4">
<AboutUnregister :req-id="targetId"></AboutUnregister> <AboutUnregister :req-id="targetId"></AboutUnregister>
<button @click="windowsState=0">Back</button>
</div> </div>
<div v-if="windowsState === 5"> <div v-if="windowsState === 5">
<AboutChangeCurriculum :req-id="targetId"></AboutChangeCurriculum> <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> </div>
</template> </template>
@ -156,6 +162,11 @@
grid-area: equivalencestate; grid-area: equivalencestate;
align-self: center; align-self: center;
} }
.teacherApproval{
grid-area: teacherApproval;
align-self: center;
}
.studentfirstname{ .studentfirstname{
grid-area: studentfirstname; grid-area: studentfirstname;
align-self: center; align-self: center;

View File

@ -3,10 +3,12 @@
import i18n from '@/i18n.js' import i18n from '@/i18n.js'
import {login, register, disconnect, isLogged} from '@/rest/Users.js' import {login, register, disconnect, isLogged} from '@/rest/Users.js'
import {getAllCurriculums, getcurriculum} from '@/rest/curriculum.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 {toast} from 'vue3-toastify'
import 'vue3-toastify/dist/index.css'; import 'vue3-toastify/dist/index.css';
import {createExternalCurriculum} from "@/rest/externalCurriculum.js"; import {createExternalCurriculum} from "@/rest/externalCurriculum.js";
import ManageCourses from "@/Apps/ManageCourses.vue";
import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue";
const loginPage= ref(true) const loginPage= ref(true)
const page = ref(0) const page = ref(0)
@ -43,10 +45,13 @@
const imageSaved = ref(false) const imageSaved = ref(false)
let ppData = "" let ppData = ""
let requiredCertif = false
//Contains the id of the newly created request (useful to link the student's formations informations to the request) //Contains the id of the newly created request (useful to link the student's formations informations to the request)
let requestId = "" let requestId = ""
const idcardfile = ref({})
const justifcardfile = ref({})
const curricula= await getAllCurriculums(); const curricula= await getAllCurriculums();
function goBackHome(){ function goBackHome(){
@ -85,21 +90,33 @@
//Post the register request and return the id of the newly created request and also post the external curriculum list in the database //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(){ 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){ 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); 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);
} }
} }
function deleteExtCursus(extcursus){
externalCurrTab.value.splice(externalCurrTab.value.indexOf(extcursus),1)
}
</script> </script>
<template> <template>
<div class="setup"> <div class="setup" v-if="page !== 4">
<div v-if="loginPage"> <div v-if="loginPage">
<div class='loginBox' style="margin-top:30%;"> <div class='loginBox' style="margin-top:30%;">
<form @submit.prevent="login(outputs.email,outputs.password);goBackHome();"class="form"> <form @submit.prevent="login(outputs.email,outputs.password);goBackHome();"class="form">
@ -206,67 +223,39 @@
</div> </div>
</div> </div>
<div v-if="page === 2"> <div v-if="page === 2">
<form novalidate enctype="multipart/form-data" class="inputBox"> <p style="color:rgb(239,60,168);">Carte d'indentité :</p>
Carte d'identité : <label class="browser">
</form> Parcourir . . .
<button @click="page++">{{i18n("login.guest.nextpage")}}</button> <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);">Ce cursus requiert une attestation de réussite d'un examen d'entrée</p>
<div style="margin-top: 2%">
<p style="color:rgb(239,60,168);">Attestation:</p>
<label class="browser">
Parcourir . . .
<input type="file" @change="justifcardfile = $event.target.files">
</label>
</div>
</div>
<button @click="page++;">{{i18n("login.guest.nextpage")}}</button>
</div> </div>
<div v-if="page === 3"> <div v-if="page === 3">
<p> <p>
Vous avez séléctionné un cursus qui possède des prérequis veuillez ajouter vos formations antérieures 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. dans l'enseignement supérieur, votre dossier sera vérifié par un membre du service d'inscription.
</p> </p>
<button @click="page++">Ajouter une formation</button> <button @click="page++">Gèrer mon parcours extérieur</button>
<button @click="postRegisterReq();">Envoyer la demande d'inscription</button> <button @click="postRegisterReq();">Envoyer la demande d'inscription</button>
</div> </div>
</form>
</div>
</div>
</div>
<div v-if="page===4"> <div v-if="page===4">
<form @submit.prevent=""class="form"> <ExternalCurriculumList v-model="externalCurrTab" :mode="2"></ExternalCurriculumList>
<div class="inputBox"> <button style="margin-top: 2%;width: 5%; margin-left: 2%" @click="page--">Back</button>
<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>
</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> </div>
</template> </template>

View File

@ -375,7 +375,7 @@
The cursus you selected has some prerequisites The cursus you selected has some prerequisites
</div> </div>
<div> <div>
<button @click=" windowState = 0;postChangeCurrReq(changecurrdata);changecurrdata.actualcursus=null;changecurrdata.newcursus=null">{{i18n("courses.confirm")}}</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> <button @click="windowState = 0; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button>
</div> </div>
</div> </div>

View File

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

View File

@ -63,3 +63,15 @@ export async function getChangeCurrReqById(id){
export async function editChangeCurrReq(id, newState){ export async function editChangeCurrReq(id, newState){
return restPatch("/changecurriculumreq/"+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)
}