Compare commits

...

59 Commits

Author SHA1 Message Date
70bec1a934 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
2024-04-21 10:35:07 +02:00
0837cc800a fixup! fixup! typo
All checks were successful
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) Successful in 1m8s
Build and test FrontEnd / Build-frontend (push) Successful in 23s
2024-04-21 10:33:33 +02:00
30f04b736b fixup! typo
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 2m16s
Build and test FrontEnd / Build-frontend (push) Successful in 25s
2024-04-21 10:18:49 +02:00
f83e689e4d typo
Some checks failed
Build and test backend / Build-backend (push) Successful in 1m23s
deploy to production / deploy-frontend (push) Successful in 28s
deploy to production / deploy-backend (push) Failing after 1m28s
Build and test FrontEnd / Build-frontend (push) Successful in 25s
2024-04-21 10:14:19 +02:00
29f13c3a3b fixing backend deploy
Some checks failed
Build and test backend / Build-backend (push) Successful in 1m22s
deploy to production / deploy-frontend (push) Successful in 28s
deploy to production / deploy-backend (push) Failing after 1m29s
Build and test FrontEnd / Build-frontend (push) Successful in 24s
2024-04-21 09:57:13 +02:00
33eb5c0f0c Merge pull request 'Forum for messaging extension' (#157) from tonitch/Clyde:forum into master
Some checks failed
Build and test backend / Build-backend (push) Successful in 1m23s
deploy to production / deploy-frontend (push) Successful in 28s
deploy to production / deploy-backend (push) Failing after 2m6s
Build and test FrontEnd / Build-frontend (push) Successful in 24s
Reviewed-on: #157
2024-04-21 09:44:25 +02:00
0621c6fe68 finish
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m25s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 24s
2024-04-21 09:46:46 +02:00
ecaf5e3df8 Merge remote-tracking branch 'origin/master' into forum
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m26s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 24s
2024-04-21 09:04:58 +02:00
846cdedc4b Merge pull request 'Translation of the student inscription extension and profile' (#166) from StudentInscription into master
Some checks failed
Build and test backend / Build-backend (push) Successful in 1m26s
deploy to production / deploy-frontend (push) Successful in 26s
deploy to production / deploy-backend (push) Failing after 2m5s
Build and test FrontEnd / Build-frontend (push) Successful in 26s
Reviewed-on: #166
2024-04-21 03:14:54 +02:00
881c935c00 Merge branch 'master' into StudentInscription
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
2024-04-21 03:10:49 +02:00
e8bf0d953d Translation of the student inscription extension and profile
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
2024-04-21 03:08:27 +02:00
8097f5314f Merge pull request 'Implement an endpoint to get all the courses of an user' (#165) from CoursesEndpoint into master
Some checks failed
Build and test backend / Build-backend (push) Successful in 1m23s
deploy to production / deploy-frontend (push) Successful in 26s
deploy to production / deploy-backend (push) Failing after 2m6s
Build and test FrontEnd / Build-frontend (push) Successful in 24s
Reviewed-on: #165
2024-04-20 23:32:03 +02:00
1e2efac5bc Implement an endpoint to get all the courses of an user
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m21s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 26s
2024-04-20 23:29:22 +02:00
061f329020 Merge pull request 'Removing toaster at every request' (#160) from tonitch/del/toast into master
Some checks failed
Build and test backend / Build-backend (push) Successful in 1m26s
deploy to production / deploy-frontend (push) Successful in 27s
deploy to production / deploy-backend (push) Failing after 2m7s
Build and test FrontEnd / Build-frontend (push) Successful in 26s
Reviewed-on: #160
2024-04-20 21:23:55 +02:00
892d4f0651 Merge pull request 'Leo/InscriptionDesEtudiants' (#164) from Leo/InscriptionDesEtudiants into master
Some checks failed
Build and test FrontEnd / Build-frontend (push) Waiting to run
Build and test backend / Build-backend (push) Successful in 1m29s
deploy to production / deploy-frontend (push) Successful in 28s
deploy to production / deploy-backend (push) Has been cancelled
Reviewed-on: #164
2024-04-20 21:21:13 +02:00
9e45e6a9c9 Merge branch 'master' into Leo/InscriptionDesEtudiants
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m23s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 25s
2024-04-20 21:18:49 +02:00
ef03a6bdca Reworking, patching and cleaning the extension
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 3m1s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 26s
2024-04-20 21:12:17 +02:00
e8917cd69e Small changes 2024-04-20 13:17:32 +02:00
cdc3772384 Small changes 2024-04-20 12:42:41 +02:00
e8fea7625f Removing toaster at every request
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m19s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 25s
It is possible to explicitly request a toaster for a request by setting
its config['toast'] to true
2024-04-20 10:05:01 +02:00
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
3ca074a3ba
typo
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m20s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 24s
2024-04-19 20:35:16 +02:00
7bb1df123f
Merge remote-tracking branch 'origin/master' into forum
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
2024-04-19 20:33:52 +02:00
92cdeaebba Merge remote-tracking branch 'origin/master' into Leo/InscriptionDesEtudiants 2024-04-19 19:25:42 +02:00
4e14370d4f Add the exemptions gestion and improve the navigation between requests 2024-04-19 19:25:28 +02:00
10c1c6096d
const error fix
Some checks failed
Build and test backend / Build-backend (push) Successful in 2m39s
deploy to production / deploy-frontend (push) Successful in 27s
deploy to production / deploy-backend (push) Failing after 2m8s
Build and test FrontEnd / Build-frontend (push) Successful in 25s
This error seems to be there for quite some times. for some reason I
haven't seen it at all. I tried to bisect it and couldn't find the
origin so I just fix it in this commit
2024-04-19 18:04:21 +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
70a8e98a0e Merge pull request 'Leo/InscriptionDesEtudiant' (#161) from Leo/InscriptionDesEtudiant into master
Some checks failed
Build and test backend / Build-backend (push) Successful in 1m27s
deploy to production / deploy-frontend (push) Successful in 26s
deploy to production / deploy-backend (push) Failing after 2m5s
Build and test FrontEnd / Build-frontend (push) Successful in 29s
Reviewed-on: #161
2024-04-18 21:43:47 +02:00
a9e52d34d4 Start the rework of externalCurriculum interface
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m59s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 26s
2024-04-18 21:35:50 +02:00
8a5a26e2ab Add the management of changeCurriculum requests 2024-04-18 14:09:06 +02:00
c9556e1eea Merge remote-tracking branch 'origin/master' into Leo/InscriptionDesEtudiant
# Conflicts:
#	backend/src/main/java/ovh/herisson/Clyde/EndPoints/MockController.java
#	backend/src/main/java/ovh/herisson/Clyde/Services/Inscription/InscriptionService.java
#	backend/src/main/java/ovh/herisson/Clyde/Tables/User.java
2024-04-18 10:46:45 +02:00
78507f798f Merge remote-tracking branch 'origin/master' into Leo/InscriptionDesEtudiant 2024-04-18 10:36:09 +02:00
f9b12a5061 Merge pull request 'Implements the RegNo feature' (#158) from Leo/masterRegNo into master
Some checks failed
Build and test backend / Build-backend (push) Successful in 1m26s
deploy to production / deploy-frontend (push) Successful in 29s
deploy to production / deploy-backend (push) Failing after 2m8s
Build and test FrontEnd / Build-frontend (push) Successful in 24s
Reviewed-on: #158
Reviewed-by: Maxime <231026@umons.ac.be>
Reviewed-by: Debucquoy Anthony <d.tonitch@gmail.com>
2024-04-18 10:32:24 +02:00
8724748642 Merge branch 'master' into Leo/masterRegNo
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m23s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 26s
2024-04-18 10:30:01 +02:00
f8d60f40fc
Removing toaster at every request
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m0s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 27s
It is possible to explicitly request a toaster for a request by setting
its config['toast'] to true
2024-04-18 08:32:06 +02:00
f19236b3f7 Avoid password leakage
Some checks failed
Build and test backend / Build-backend (push) Successful in 1m27s
deploy to production / deploy-frontend (push) Successful in 28s
deploy to production / deploy-backend (push) Failing after 2m10s
Build and test FrontEnd / Build-frontend (push) Successful in 26s
The password should never be parsed to json ever so can be safely
ignored.
2024-04-17 21:44:30 +02:00
cba11d54ff Page to right size (#152)
Some checks are pending
Build and test backend / Build-backend (push) Waiting to run
deploy to production / deploy-frontend (push) Waiting to run
deploy to production / deploy-backend (push) Waiting to run
Build and test FrontEnd / Build-frontend (push) Waiting to run
Reviewed-on: #152
Reviewed-by: Maxime <231026@umons.ac.be>
Co-authored-by: Anthony Debucquoy <debucquoy.anthony@gmail.com>
Co-committed-by: Anthony Debucquoy <debucquoy.anthony@gmail.com>
2024-04-17 21:43:49 +02:00
a27cf63daf Add the post feature for differents types of changeCurriculumRequest 2024-04-17 21:42:33 +02:00
1be7b4cdbe Add the unregistration of a specific cursus only 2024-04-17 13:57:52 +02:00
058c53dbbc Add the actual in UserCurriculum
Rework the unregister procedure
Add ChangeCurriculumRequest
Add the changeCurriculumRequest submit
2024-04-17 11:55:56 +02:00
caa39696d2 Rework the profile page
Add the accept/refuse for unreg request
2024-04-17 08:53:28 +02:00
b9d7950e12 Merge branch 'master' into Leo/masterRegNo
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m43s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 27s
2024-04-17 07:52:58 +02:00
451944e4fb Implements the RegNo feature
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m50s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 29s
2024-04-15 20:57:29 +02:00
c434b28fe3 Add the display for unregister requests
Rename all ocurrences of uninscription
to unregister
Rework the uninscriptionRequest so we have an history and it doesn't take an user so better security
2024-04-15 20:13:01 +02:00
a89d1b192c Add the gestion of scholarshipRequest (accept and refuse and select the amount) 2024-04-15 16:17:27 +02:00
c6ce6d3e5b
translations of forum
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 3m58s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 26s
2024-04-13 16:05:14 +02:00
2e02cd8870
Style bits redone 2024-04-13 15:56:43 +02:00
106bf96a98
responses and general modifications 2024-04-09 23:41:43 +02:00
7b0d76dae8
Merge remote-tracking branch 'origin/master' into forum 2024-04-09 17:28:59 +02:00
61e269eb27
Linking front for forum creation 2024-04-09 17:27:26 +02:00
5f483216b9
indev 2024-04-08 10:02:03 +02:00
5a4d066c45
Forum and topic getter and creator endpoints 2024-04-07 18:16:05 +02:00
f9bcff6d4f
Avoid password leakage
The password should never be parsed to json ever so can be safely
ignored.
2024-04-07 14:46:14 +02:00
7bd745fd5e
Adding frontend visual side 2024-04-05 08:57:19 +02:00
a96609d2ef
Page to right size 2024-04-03 14:58:04 +02:00
cb750b8505
Database creation (Tables) 2024-04-02 21:40:52 +02:00
70 changed files with 2770 additions and 652 deletions

View File

@ -18,15 +18,3 @@ jobs:
- uses: gradle/gradle-build-action@v3 - uses: gradle/gradle-build-action@v3
- name: building - name: building
run: ./gradlew backend:build -x test run: ./gradlew backend:build -x test
# Test-backend:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# - uses: actions/setup-java@v3
# with:
# java-version: '21'
# distribution: 'temurin'
# - run: curl -fsSL https://get.docker.com | sh
# - uses: gradle/gradle-build-action@v3
# - name: testing
# run: ./gradlew backend:test

View File

@ -39,13 +39,6 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: actions/setup-java@v3
with:
java-version: '21'
distribution: 'temurin'
- uses: gradle/gradle-build-action@v3
- name: building
run: ./gradlew backend:build -x test
- name: pushing to the server - name: pushing to the server
run: | run: |
echo "${{ secrets.SSH_KEY }}" > key echo "${{ secrets.SSH_KEY }}" > key
@ -53,5 +46,5 @@ jobs:
scp -o "StrictHostKeyChecking=no" -o "LogLevel=ERROR" -i key -r * ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:api/ scp -o "StrictHostKeyChecking=no" -o "LogLevel=ERROR" -i key -r * ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:api/
- name: restarting the backend - name: restarting the backend
run: | run: |
ssh -o "StrictHostKeyChecking=no" -o "LogLevel=ERROR" -i key ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} 'cd api/backend && docker build -t clyde/backend . && docker rm clyde_backend_prod -f || true && docker run --rm -d -u $(id -u clyde):$(id -g clyde) -v /var/run/postgresql:/var/run/postgresql --name clyde_backend_prod -p 4000:8080 clyde/backend && docker image prune -f' ssh -o "StrictHostKeyChecking=no" -o "LogLevel=ERROR" -i key ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} 'cd api/ && docker-compose up --force-recreate --build -d'
- run: echo "The backend has been deployed. running at https://clyde.herisson.ovh/api" - run: echo "The backend has been deployed. running at https://clyde.herisson.ovh/api"

View File

@ -70,6 +70,9 @@ public class ApplicationsController {
if (!authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token)){ if (!authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token)){
authorizedApps.add(Applications.UsersList);} authorizedApps.add(Applications.UsersList);}
if (!authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin, Role.InscriptionService},token)){
authorizedApps.add(Applications.Payments);}
return authorizedApps; return authorizedApps;
} }
} }

View File

@ -3,15 +3,17 @@ package ovh.herisson.Clyde.EndPoints;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Repositories.CurriculumCourseRepository;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse; import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService; import ovh.herisson.Clyde.Services.*;
import ovh.herisson.Clyde.Services.CourseService;
import ovh.herisson.Clyde.Services.ProtectionService;
import ovh.herisson.Clyde.Services.TeacherCourseService;
import ovh.herisson.Clyde.Tables.Course; import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.User; import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.UserCurriculum;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
@RestController @RestController
@ -24,10 +26,20 @@ public class CourseController {
private final AuthenticatorService authServ; private final AuthenticatorService authServ;
public CourseController(CourseService courseServ, TeacherCourseService teacherCourseServ, AuthenticatorService authServ) { private final UserService userService;
private final UserCurriculumService userCurriculumService;
private final CurriculumCourseRepository curriculumCourseRepository;
private final CurriculumCourseService curriculumCourseService;
public CourseController(CourseService courseServ, TeacherCourseService teacherCourseServ, AuthenticatorService authServ, UserService userService, UserCurriculumService userCurriculumService, CurriculumCourseRepository curriculumCourseRepository, CurriculumCourseService curriculumCourseService) {
this.courseServ = courseServ; this.courseServ = courseServ;
this.teacherCourseServ = teacherCourseServ; this.teacherCourseServ = teacherCourseServ;
this.authServ = authServ; this.authServ = authServ;
this.userService = userService;
this.userCurriculumService = userCurriculumService;
this.curriculumCourseRepository = curriculumCourseRepository;
this.curriculumCourseService = curriculumCourseService;
} }
@GetMapping("/course/{id}") @GetMapping("/course/{id}")
@ -136,4 +148,28 @@ public class CourseController {
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
//Get all the courses followed by an user
@GetMapping("/usercourses")
public ResponseEntity<List<Course>> getAllUserCourses(@RequestHeader("Authorization") String token){
User u = authServ.getUserFromToken(token);
//We get all the actual curriculums of the user
List<UserCurriculum> userCurricula = userCurriculumService.findByStudentAndActual(u, true);
List<Course> toReturn = new ArrayList<>();
//We iterate through all the curriculums and we extract the courses
for (int i = 0; i < userCurricula.size(); i++){
curriculumCourseRepository.findCoursesByCurriculum(userCurricula.get(i).getCurriculum()).forEach((item) -> {
//We need this to eliminate clones because a course can belong to several curriculums
if(!toReturn.contains(item)){
toReturn.add(item);
}
});
}
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
} }

View File

@ -30,9 +30,16 @@ public class ExternalCurriculumController {
//everyone can post some externalcurriculums (the validity of the elements is assured by the inscription service) //everyone can post some externalcurriculums (the validity of the elements is assured by the inscription service)
@PostMapping("/externalcurriculum") @PostMapping("/externalcurriculum")
public ResponseEntity<ExternalCurriculum> postExternalCurriculum(@RequestBody Map<String, Object> externalCurrInfos){ public ResponseEntity<ExternalCurriculum> postExternalCurriculum(@RequestBody Map<String, Object> externalCurrInfos){
InscriptionRequest ir = inscriptionRepository.findById((Integer) externalCurrInfos.get("inscriptionRequestId")); //An external curriculum can either be linked to an User or to an InscriptionRequest
InscriptionRequest ir = null;
User user = null;
if (externalCurrInfos.get("inscriptionRequestId") != null){
ir = inscriptionRepository.findById((Integer) externalCurrInfos.get("inscriptionRequestId"));
}else{
user = userRepository.findById((Integer) externalCurrInfos.get("userRegNo"));
}
ExternalCurriculum toSave = new ExternalCurriculum(ir, (String) externalCurrInfos.get("school"),(String) externalCurrInfos.get("formation"),(String) externalCurrInfos.get("completion"), (Integer)externalCurrInfos.get("startYear"), (Integer)externalCurrInfos.get("endYear"), (String)externalCurrInfos.get("justifDocUrl"), null); ExternalCurriculum toSave = new ExternalCurriculum(ir, (String) externalCurrInfos.get("school"),(String) externalCurrInfos.get("formation"),(String) externalCurrInfos.get("completion"), (Integer)externalCurrInfos.get("startYear"), (Integer)externalCurrInfos.get("endYear"), (String)externalCurrInfos.get("justifDocUrl"), user);
return new ResponseEntity<>(ecr.save(toSave), HttpStatus.OK); return new ResponseEntity<>(ecr.save(toSave), HttpStatus.OK);
} }

View File

@ -29,7 +29,7 @@ public class InscriptionController {
@GetMapping("/requests/register") @GetMapping("/requests/register")
public ResponseEntity<Iterable<Map<String,Object>>> getAllRequests(@RequestHeader("Authorization") String token){ public ResponseEntity<Iterable<Map<String,Object>>> getAllRequests(@RequestHeader("Authorization") String token){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService},token)) if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService, Role.Teacher},token))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
Iterable<InscriptionRequest> inscriptionRequests = inscriptionServ.getAll(); Iterable<InscriptionRequest> inscriptionRequests = inscriptionServ.getAll();
@ -41,7 +41,7 @@ public class InscriptionController {
@GetMapping("/request/register/{id}") @GetMapping("/request/register/{id}")
public ResponseEntity<Map<String,Object>> getById(@RequestHeader("Authorization") String token, @PathVariable long id){ public ResponseEntity<Map<String,Object>> getById(@RequestHeader("Authorization") String token, @PathVariable long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService},token)) if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService, Role.Teacher},token))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
InscriptionRequest foundInscriptionRequest = inscriptionServ.getById(id); InscriptionRequest foundInscriptionRequest = inscriptionServ.getById(id);
@ -87,6 +87,12 @@ public class InscriptionController {
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
InscriptionRequest toEdit = inscriptionServ.getById(id); InscriptionRequest toEdit = inscriptionServ.getById(id);
//If the request is already accepted we just return ok (otherwise we would duplicate the procedure below)
if (toEdit.getEquivalenceState() == RequestState.Accepted){
return new ResponseEntity<>(HttpStatus.OK);
}
toEdit.setEquivalenceState(newstate); toEdit.setEquivalenceState(newstate);
inscriptionServ.save(toEdit); inscriptionServ.save(toEdit);

View File

@ -34,4 +34,12 @@ public class PaymentController {
return new ResponseEntity<>(toReturn, HttpStatus.OK); return new ResponseEntity<>(toReturn, HttpStatus.OK);
} }
@GetMapping("/payment")
public ResponseEntity<ArrayList<Payment>> getAllPayments(){
ArrayList<Payment> toReturn = new ArrayList<Payment>();
paymentRepository.findAll().forEach(toReturn::add);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
} }

View File

@ -4,18 +4,24 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import ovh.herisson.Clyde.Repositories.CourseRepository; import ovh.herisson.Clyde.Repositories.CourseRepository;
import ovh.herisson.Clyde.Repositories.CurriculumRepository;
import ovh.herisson.Clyde.Repositories.Inscription.ChangeCurriculumRequestRepository;
import ovh.herisson.Clyde.Repositories.Inscription.ExemptionsRequestRepository; import ovh.herisson.Clyde.Repositories.Inscription.ExemptionsRequestRepository;
import ovh.herisson.Clyde.Repositories.Inscription.ScholarshipRequestRepository; import ovh.herisson.Clyde.Repositories.Inscription.ScholarshipRequestRepository;
import ovh.herisson.Clyde.Repositories.Inscription.UninscriptionRequestRepository; import ovh.herisson.Clyde.Repositories.Inscription.UnregisterRequestRepository;
import ovh.herisson.Clyde.Repositories.UserCurriculumRepository;
import ovh.herisson.Clyde.Repositories.UserRepository; import ovh.herisson.Clyde.Repositories.UserRepository;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse; import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService; import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.TokenService;
import ovh.herisson.Clyde.Services.UserService;
import ovh.herisson.Clyde.Tables.*; import ovh.herisson.Clyde.Tables.*;
import ovh.herisson.Clyde.Tables.Inscription.ExemptionsRequest; import ovh.herisson.Clyde.Tables.Inscription.ExemptionsRequest;
import ovh.herisson.Clyde.Tables.Inscription.ScholarshipRequest; import ovh.herisson.Clyde.Tables.Inscription.ScholarshipRequest;
import ovh.herisson.Clyde.Tables.Inscription.UninscriptionRequest; import ovh.herisson.Clyde.Tables.Inscription.UnregisterRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Map; import java.util.Map;
@ -23,20 +29,31 @@ import java.util.Map;
@CrossOrigin(originPatterns = "*", allowCredentials = "true") @CrossOrigin(originPatterns = "*", allowCredentials = "true")
public class RequestsController { public class RequestsController {
public final TokenService tokenService;
public final ExemptionsRequestRepository err; public final ExemptionsRequestRepository err;
public final ScholarshipRequestRepository srr; public final ScholarshipRequestRepository srr;
public final UserRepository userRepository; public final UserRepository userRepository;
public final AuthenticatorService authServ; public final AuthenticatorService authServ;
public final UninscriptionRequestRepository uninscriptionRequestRepository; public final UnregisterRequestRepository unregisterRequestRepository;
public final CourseRepository courseRepository; public final CourseRepository courseRepository;
public final UserService userService;
public final UserCurriculumRepository userCurriculumRepository;
public final CurriculumRepository curriculumRepository;
public RequestsController(ExemptionsRequestRepository err, ScholarshipRequestRepository srr, UserRepository userRepository, AuthenticatorService authServ, UninscriptionRequestRepository uninscriptionRequestRepository, CourseRepository courseRepository) { public final ChangeCurriculumRequestRepository changeCurriculumRequestRepository;
public RequestsController(TokenService tokenService, ExemptionsRequestRepository err, ScholarshipRequestRepository srr, UserRepository userRepository, AuthenticatorService authServ, UnregisterRequestRepository unregisterRequestRepository, CourseRepository courseRepository, UserService userService, UserCurriculumRepository userCurriculumRepository, CurriculumRepository curriculumRepository, ChangeCurriculumRequestRepository changeCurriculumRequestRepository) {
this.tokenService = tokenService;
this.err = err; this.err = err;
this.srr = srr; this.srr = srr;
this.userRepository = userRepository; this.userRepository = userRepository;
this.authServ = authServ; this.authServ = authServ;
this.uninscriptionRequestRepository = uninscriptionRequestRepository; this.unregisterRequestRepository = unregisterRequestRepository;
this.courseRepository = courseRepository; this.courseRepository = courseRepository;
this.userService = userService;
this.userCurriculumRepository = userCurriculumRepository;
this.curriculumRepository = curriculumRepository;
this.changeCurriculumRequestRepository = changeCurriculumRequestRepository;
} }
@PostMapping(value="/exemptionreq") @PostMapping(value="/exemptionreq")
@ -64,7 +81,7 @@ public class RequestsController {
//Get all the exemptions Request //Get all the exemptions Request
@GetMapping(value = "/exemptionsreq") @GetMapping(value = "/exemptionsreq")
public ResponseEntity<ArrayList<ExemptionsRequest>> getAllExemptionsRequests(@RequestHeader("Authorization") String token){ public ResponseEntity<ArrayList<ExemptionsRequest>> getAllExemptionsRequests(@RequestHeader("Authorization") String token){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token)) if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService, Role.Teacher},token))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
ArrayList<ExemptionsRequest> toReturn = new ArrayList<>(); ArrayList<ExemptionsRequest> toReturn = new ArrayList<>();
@ -74,6 +91,33 @@ 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.Teacher,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.Teacher},token))
return new UnauthorizedResponse<>(null);
ExemptionsRequest exemptionsRequest = err.findById(id);
if (exemptionsRequest.getState() == RequestState.Accepted){
return new ResponseEntity<>(HttpStatus.OK);
}
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){
@ -87,11 +131,236 @@ public class RequestsController {
return new ResponseEntity<>(toReturn, HttpStatus.OK); return new ResponseEntity<>(toReturn, HttpStatus.OK);
} }
@PostMapping(value = "/uninscriptionreq") @PostMapping(value = "/unregister")
public ResponseEntity<String> postUnregReq(@RequestBody Map<String,Object> uninscr){ public ResponseEntity<String> postUnregReq(@RequestBody Map<String,Object> uninscr){
User u = userRepository.findById((int) uninscr.get("userId")); User u = userRepository.findById((int) uninscr.get("userId"));
UninscriptionRequest ur = new UninscriptionRequest(RequestState.Pending, (String) uninscr.get("reason"), new Date(), u); Curriculum c;
uninscriptionRequestRepository.save(ur);
if (uninscr.get("curriculumId") == null){
c = null;
}else{
c = curriculumRepository.findById((Integer) uninscr.get("curriculumId"));
}
UnregisterRequest ur = new UnregisterRequest(RequestState.Pending, (String) uninscr.get("reason"), new Date(), u.getRegNo(), u.getFirstName(), u.getLastName(), u.getEmail(), c);
unregisterRequestRepository.save(ur);
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
@PatchMapping(value = "/scholarshipreq/")
public ResponseEntity<String> editScholReq(@RequestHeader("Authorization") String token, @RequestBody Map<String,Object> infos){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ScholarshipRequest scholarshipRequest = srr.findById((Integer) infos.get("id"));
//If the request is already accepted we just return ok (otherwise we would duplicate the procedure below)
if (scholarshipRequest.getState() == RequestState.Accepted){
return new ResponseEntity<>(HttpStatus.OK);
}
if (infos.get("state").equals("Accepted")){
scholarshipRequest.setState(RequestState.Accepted);
scholarshipRequest.setAmount((int) infos.get("amount"));
}else{
scholarshipRequest.setState(RequestState.Refused);
}
srr.save(scholarshipRequest);
return new ResponseEntity<>(HttpStatus.OK);
}
@GetMapping(value = "/scholarshipreq/{id}")
public ResponseEntity<ScholarshipRequest> getScholReqbyId(@RequestHeader("Authorization") String token, @PathVariable long id){
if (authServ.isNotIn(new Role[]{Role.Admin, Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ScholarshipRequest toReturn = srr.findById(id);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
@GetMapping(value = "/unregister")
public ResponseEntity<ArrayList<UnregisterRequest>> getAllUnregReq(@RequestHeader("Authorization") String token){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ArrayList<UnregisterRequest> toReturn = new ArrayList<>();
unregisterRequestRepository.findAll().forEach(toReturn::add);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
@GetMapping(value = "/unregister/{id}")
public ResponseEntity<UnregisterRequest> getUnregbyId(@RequestHeader("Authorization") String token, @PathVariable long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
UnregisterRequest unregisterRequest = unregisterRequestRepository.findById(id);
return new ResponseEntity<>(unregisterRequest, HttpStatus.OK);
}
@PatchMapping(value = "/unregister/{id}/{newstate}")
public ResponseEntity<String> pathUnregReq(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newstate){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
UnregisterRequest unregisterRequest = unregisterRequestRepository.findById(id);
User u = userRepository.findById(unregisterRequest.getRegNo());
//If the request is already accepted we just return ok (otherwise we would duplicate the procedure below)
if (unregisterRequest.getState() == RequestState.Accepted){
return new ResponseEntity<>(HttpStatus.OK);
}
unregisterRequest.setState(newstate);
unregisterRequestRepository.save(unregisterRequest);
if (newstate == RequestState.Accepted){
if (unregisterRequest.getCurriculum() == null){
ArrayList<UserCurriculum> userCurricula = userCurriculumRepository.findByUserOrderByCurriculum(u);
for (int i = 0; i < userCurricula.size(); i++){
userCurricula.get(i).setActual(false);
}
userCurriculumRepository.saveAll(userCurricula);
}else{
//This usercurriculum will contain the usercurriculum to set false
UserCurriculum userCurriculum = userCurriculumRepository.findByUserAndCurriculumAndActual(u, unregisterRequest.getCurriculum(), true);
userCurriculum.setActual(false);
userCurriculumRepository.save(userCurriculum);
}
}
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")
public ResponseEntity<String> addChangeCurrReq(@RequestBody Map<String,Object> reqInfos){
User user = userRepository.findById((Integer) reqInfos.get("userId"));
Curriculum actualCurriculum;
//If null then it means we are in a supplementary cursus case
if (reqInfos.get("actualcursus") == null){
actualCurriculum = null;
}else{
actualCurriculum = curriculumRepository.findById((Integer) reqInfos.get("actualcursus"));
}
Curriculum destinationCurriculum = curriculumRepository.findById((Integer) reqInfos.get("newcursus"));
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);
return new ResponseEntity<>(HttpStatus.OK);
}
@GetMapping("/changecurriculumreq")
public ResponseEntity<ArrayList <ChangeCurriculumRequest>> getAllChangeCurrReq(@RequestHeader("Authorization") String token){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService, Role.Teacher},token))
return new UnauthorizedResponse<>(null);
ArrayList<ChangeCurriculumRequest> toReturn = new ArrayList<>();
changeCurriculumRequestRepository.findAll().forEach(toReturn::add);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
@GetMapping("/changecurriculumreq/{id}")
public ResponseEntity<ChangeCurriculumRequest> getCCrbyId(@RequestHeader("Authorization") String token, @PathVariable long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ChangeCurriculumRequest toReturn = changeCurriculumRequestRepository.findById(id);
return new ResponseEntity<>(toReturn, HttpStatus.OK);
}
@PatchMapping("/changecurriculumreq/{id}/{newState}")
public ResponseEntity<String> editCCReq(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newState){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null);
ChangeCurriculumRequest toEdit = changeCurriculumRequestRepository.findById(id);
//If the request is already accepted we just return ok (otherwise we would duplicate the procedure below)
if (toEdit.getState() == RequestState.Accepted){
return new ResponseEntity<>(HttpStatus.OK);
}
toEdit.setState(newState);
changeCurriculumRequestRepository.save(toEdit);
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
acceptProcedure(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.Teacher},token))
return new UnauthorizedResponse<>(null);
ChangeCurriculumRequest toEdit = changeCurriculumRequestRepository.findById(id);
//If the request is already accepted we just return ok (otherwise we would duplicate the procedure below)
if (toEdit.getTeacherApprovalState() == RequestState.Accepted){
return new ResponseEntity<>(HttpStatus.OK);
}
toEdit.setState(newteacherstate);
changeCurriculumRequestRepository.save(toEdit);
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);
}
return new ResponseEntity<>(HttpStatus.OK);
}
private void acceptProcedure(ChangeCurriculumRequest toEdit) {
User u = toEdit.getUser();
if (toEdit.getActualCurriculum() != null){
ArrayList<UserCurriculum> listcurr = userCurriculumRepository.findByUserOrderByCurriculum(u);
for (int i = 0; i < listcurr.size(); i++){
if (listcurr.get(i).getCurriculum() == toEdit.getActualCurriculum()){
listcurr.get(i).setActual(false);
}
}
userCurriculumRepository.saveAll(listcurr);
}
Calendar c = Calendar.getInstance();
UserCurriculum userCurriculum = new UserCurriculum(u, toEdit.getDestinationCurriculum(), c.get(Calendar.YEAR), true);
userCurriculumRepository.save(userCurriculum);
}
@GetMapping("/exemptionreq/{userId}")
public ResponseEntity<ArrayList<ExemptionsRequest>> getExReqByuser(@RequestHeader("Authorization") String token, @PathVariable long userId){
User currentUser = tokenService.getUserFromToken(token);
//Only admin, teacher, secretary and the student himself can access a student's data here
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher, Role.Secretary},token) && currentUser.getRegNo() != userId)
return new UnauthorizedResponse<>(null);
User u = userRepository.findById(userId);
ArrayList<ExemptionsRequest> exList = err.findByUser(u);
return new ResponseEntity<>(exList, HttpStatus.OK);
}
} }

View File

@ -6,13 +6,11 @@ import ovh.herisson.Clyde.Repositories.*;
import ovh.herisson.Clyde.Repositories.Inscription.ExternalCurriculumRepository; import ovh.herisson.Clyde.Repositories.Inscription.ExternalCurriculumRepository;
import ovh.herisson.Clyde.Repositories.Inscription.MinervalRepository; import ovh.herisson.Clyde.Repositories.Inscription.MinervalRepository;
import ovh.herisson.Clyde.Repositories.Inscription.ScholarshipRequestRepository; import ovh.herisson.Clyde.Repositories.Inscription.ScholarshipRequestRepository;
import ovh.herisson.Clyde.Repositories.Inscription.UnregisterRequestRepository;
import ovh.herisson.Clyde.Services.*; import ovh.herisson.Clyde.Services.*;
import ovh.herisson.Clyde.Services.Inscription.InscriptionService; import ovh.herisson.Clyde.Services.Inscription.InscriptionService;
import ovh.herisson.Clyde.Tables.*; import ovh.herisson.Clyde.Tables.*;
import ovh.herisson.Clyde.Tables.Inscription.ExternalCurriculum; import ovh.herisson.Clyde.Tables.Inscription.*;
import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest;
import ovh.herisson.Clyde.Tables.Inscription.Minerval;
import ovh.herisson.Clyde.Tables.Inscription.ScholarshipRequest;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -23,7 +21,7 @@ import java.util.Date;
public class MockController { public class MockController {
private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
public final UserService userService;
public final UserRepository userRepo; public final UserRepository userRepo;
public final TokenRepository tokenRepo; public final TokenRepository tokenRepo;
public final TokenService tokenService; public final TokenService tokenService;
@ -40,7 +38,9 @@ public class MockController {
public final ScholarshipRequestRepository scholarshipRequestRepository; public final ScholarshipRequestRepository scholarshipRequestRepository;
public MockController(UserRepository userRepo, TokenRepository tokenRepo, TokenService tokenService, CurriculumCourseService CurriculumCourseService, CurriculumService curriculumService, CourseService courseService, ExternalCurriculumRepository externalCurriculumRepository, InscriptionService inscriptionService, UserCurriculumRepository ucr, MinervalRepository minervalRepository, ScholarshipRequestRepository scholarshipRequestRepository){ public final UnregisterRequestRepository uninscriptionRequestRepository;
public MockController(UserService userService, UserRepository userRepo, TokenRepository tokenRepo, TokenService tokenService, CurriculumCourseService CurriculumCourseService, CurriculumService curriculumService, CourseService courseService, ExternalCurriculumRepository externalCurriculumRepository, InscriptionService inscriptionService, UserCurriculumRepository ucr, MinervalRepository minervalRepository, ScholarshipRequestRepository scholarshipRequestRepository, UnregisterRequestRepository unregisterRequestRepository){
this.userService = userService;
this.tokenRepo = tokenRepo; this.tokenRepo = tokenRepo;
this.userRepo = userRepo; this.userRepo = userRepo;
this.tokenService = tokenService; this.tokenService = tokenService;
@ -52,6 +52,7 @@ public class MockController {
this.ucr = ucr; this.ucr = ucr;
this.minervalRepository = minervalRepository; this.minervalRepository = minervalRepository;
this.scholarshipRequestRepository = scholarshipRequestRepository; this.scholarshipRequestRepository = scholarshipRequestRepository;
this.uninscriptionRequestRepository = unregisterRequestRepository;
} }
/** Saves an example of each user type by : /** Saves an example of each user type by :
@ -73,18 +74,23 @@ public class MockController {
User popo = new User("Smith", "Paul", "paulsmith@gmail.com", "306 rue du poulet", "belgique", new Date(0), null, Role.Student, passwordEncoder.encode("jesuispaulleroi")); User popo = new User("Smith", "Paul", "paulsmith@gmail.com", "306 rue du poulet", "belgique", new Date(0), null, Role.Student, passwordEncoder.encode("jesuispaulleroi"));
mockUsers = new ArrayList<>(Arrays.asList(herobrine,joe,meh,joke,lena,jojo, popo)); mockUsers = new ArrayList<>(Arrays.asList(herobrine,joe,meh,joke,lena,jojo, popo));
userRepo.saveAll(mockUsers); userService.saveAll(mockUsers);
ExternalCurriculum externalCurriculum = new ExternalCurriculum(null, "HEH", "Bachelier en ingénieur", "completed", 2015, 2017, null, joe);
externalCurriculumRepository.save(externalCurriculum);
Minerval minerval = new Minerval(joe.getRegNo(), 0, 852, 2023); Minerval minerval = new Minerval(joe.getRegNo(), 0, 852, 2023);
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", false);
Curriculum ingebab1 = new Curriculum(1, "ingénieur", true);
curriculumService.save(infoBab1); curriculumService.save(infoBab1);
curriculumService.save(chemistryBab1); curriculumService.save(chemistryBab1);
@ -92,16 +98,18 @@ public class MockController {
curriculumService.save(infoBab2); curriculumService.save(infoBab2);
curriculumService.save(masterinfo1); curriculumService.save(masterinfo1);
curriculumService.save(masterinfo2); curriculumService.save(masterinfo2);
curriculumService.save(chemistryBab2);
curriculumService.save(ingebab1);
ucr.save(new UserCurriculum(joe, infoBab1, 2022)); ucr.save(new UserCurriculum(joe, infoBab1, 2022, false));
ucr.save(new UserCurriculum(joe, chemistryBab1, 2023)); ucr.save(new UserCurriculum(joe, chemistryBab1, 2023, true));
ucr.save(new UserCurriculum(joe, infoBab1, 2023)); ucr.save(new UserCurriculum(joe, infoBab1, 2023, true));
ucr.save(new UserCurriculum(joe, psychologyBab1, 2020)); ucr.save(new UserCurriculum(joe, psychologyBab1, 2020, false));
ucr.save(new UserCurriculum(popo, infoBab1, 2022)); ucr.save(new UserCurriculum(popo, infoBab1, 2022, false));
ucr.save(new UserCurriculum(popo, infoBab2, 2023)); ucr.save(new UserCurriculum(popo, infoBab2, 2023, true));
Course progra1 = new Course(5,"Programmation et algorithmique 1",joke); Course progra1 = new Course(5,"Programmation et algorithmique 1",joke);
Course chemistry1 = new Course(12, "Thermochimie",joke); Course chemistry1 = new Course(12, "Thermochimie",jojo);
Course psycho1 = new Course(21, "Neuroreaction of isolated brain cells",joke); Course psycho1 = new Course(21, "Neuroreaction of isolated brain cells",joke);
Course commun = new Course(2, "cours commun",joke); Course commun = new Course(2, "cours commun",joke);
@ -118,17 +126,19 @@ public class MockController {
CurriculumCourseService.save(new CurriculumCourse(infoBab1, psycho1)); CurriculumCourseService.save(new CurriculumCourse(infoBab1, psycho1));
CurriculumCourseService.save(new CurriculumCourse(psychologyBab1,psycho1)); CurriculumCourseService.save(new CurriculumCourse(psychologyBab1,psycho1));
CurriculumCourseService.save(new CurriculumCourse(psychologyBab1,commun)); CurriculumCourseService.save(new CurriculumCourse(psychologyBab1,commun));
CurriculumCourseService.save(new CurriculumCourse(chemistryBab1, chemistry1));
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);
ExternalCurriculum externalCurriculum = new ExternalCurriculum(inscriptionRequest, "HEH", "Bachelier en informatique", "Completed", 2015, 2018, null, null); UnregisterRequest unregisterRequest = new UnregisterRequest(RequestState.Pending, "je veux partir", new Date(), joe.getRegNo(), joe.getFirstName(), joe.getLastName(), joe.getEmail(), null);
uninscriptionRequestRepository.save(unregisterRequest);
externalCurriculum = new ExternalCurriculum(inscriptionRequest, "HEH", "Bachelier en informatique", "Completed", 2015, 2018, null, null);
externalCurriculumRepository.save(externalCurriculum); externalCurriculumRepository.save(externalCurriculum);
} }
} }

View File

@ -0,0 +1,113 @@
package ovh.herisson.Clyde.EndPoints.Msg;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import jakarta.websocket.server.PathParam;
import lombok.AllArgsConstructor;
import ovh.herisson.Clyde.Repositories.CourseRepository;
import ovh.herisson.Clyde.Repositories.Msg.AnswerRepository;
import ovh.herisson.Clyde.Repositories.Msg.ForumRepository;
import ovh.herisson.Clyde.Repositories.Msg.TopicRepository;
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
import ovh.herisson.Clyde.Services.AuthenticatorService;
import ovh.herisson.Clyde.Services.CourseService;
import ovh.herisson.Clyde.Services.Msg.ForumService;
import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.Role;
import ovh.herisson.Clyde.Tables.Token;
import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.Msg.Answer;
import ovh.herisson.Clyde.Tables.Msg.Forum;
import ovh.herisson.Clyde.Tables.Msg.Topic;
@RestController
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
@AllArgsConstructor
public class ForumController {
private CourseRepository courseRepo;
private AuthenticatorService authServ;
private ForumService forumServ;
private ForumRepository forumRepo;
private TopicRepository topicRepo;
//// Endpoints to get and create new forums
@GetMapping("/forums/{id}")
public ResponseEntity<List<Forum>> getForumFromCourseId(@RequestHeader("Authorization") String token, @PathVariable long id){
User u = authServ.getUserFromToken(token);
if(u == null){
return new UnauthorizedResponse<>(null);
}
return new ResponseEntity<>(courseRepo.findById(id).getForums(), HttpStatus.OK);
}
@PostMapping("/forums/{id}")
public ResponseEntity<Forum> createForumOfCourse(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody Forum data){
User u = authServ.getUserFromToken(token);
Course c = courseRepo.findById(id);
if(!(c.getOwner().equals(u) || u.getRole() == Role.Admin)){
return new UnauthorizedResponse<>(null);
}
forumServ.createForum(c, data);
return new ResponseEntity<>(HttpStatus.ACCEPTED);
}
//// Endpoints to get and create forum's topic
@GetMapping("/forum/{id}")
public ResponseEntity<List<Topic>> getTopicsFromForumId(@RequestHeader("Authorization") String token, @PathVariable long id){
User u = authServ.getUserFromToken(token);
if(u == null){
return new UnauthorizedResponse<>(null);
}
return new ResponseEntity<>(forumRepo.findById(id).orElse(null).getTopics(), HttpStatus.OK);
}
@PostMapping("/forum/{id}")
public ResponseEntity<Topic> postTopicToForum(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody Topic data){
User u = authServ.getUserFromToken(token);
Forum f = forumRepo.findById(id).orElse(null);
if(!(f.getWriters().contains(u) || u.getRole() == Role.Admin)){
return new UnauthorizedResponse<>(null);
}
forumServ.createTopic(f, data);
return new ResponseEntity<>(HttpStatus.ACCEPTED);
}
//// Endpoints related to topics and messages
@GetMapping("/forum/post/{id}")
public ResponseEntity<Topic> getPost(@RequestHeader("Authorization") String token, @PathVariable long id){
User u = authServ.getUserFromToken(token);
if(u == null){
return new UnauthorizedResponse<>(null);
}
Topic t = topicRepo.findById(id).orElse(null);
return new ResponseEntity<>(t, HttpStatus.OK);
}
@PostMapping("/forum/post/{id}")
public ResponseEntity<Topic> postTopicToForum(@RequestHeader("Authorization") String token, @PathVariable long id, @RequestBody Answer data){
User u = authServ.getUserFromToken(token);
Topic t = topicRepo.findById(id).orElse(null);
if(t.isLocked() && u.getRole() != Role.Admin){
return new UnauthorizedResponse<>(null);
}
System.out.println(data);
forumServ.answerTopic(t, data, u);
return new ResponseEntity<>(HttpStatus.ACCEPTED);
}
}

View File

@ -0,0 +1,9 @@
package ovh.herisson.Clyde.Repositories.Inscription;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.ChangeCurriculumRequest;
public interface ChangeCurriculumRequestRepository extends CrudRepository<ChangeCurriculumRequest, Long> {
ChangeCurriculumRequest findById(long id);
}

View File

@ -2,7 +2,12 @@ package ovh.herisson.Clyde.Repositories.Inscription;
import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Inscription.ExemptionsRequest; import ovh.herisson.Clyde.Tables.Inscription.ExemptionsRequest;
import ovh.herisson.Clyde.Tables.User;
import java.util.ArrayList;
public interface ExemptionsRequestRepository extends CrudRepository<ExemptionsRequest, Long> { public interface ExemptionsRequestRepository extends CrudRepository<ExemptionsRequest, Long> {
ExemptionsRequest findById(long id);
ArrayList<ExemptionsRequest> findByUser(User user);
} }

View File

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

View File

@ -1,7 +0,0 @@
package ovh.herisson.Clyde.Repositories.Inscription;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Inscription.UninscriptionRequest;
public interface UninscriptionRequestRepository extends CrudRepository<UninscriptionRequest, Long> {
}

View File

@ -0,0 +1,8 @@
package ovh.herisson.Clyde.Repositories.Inscription;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Inscription.UnregisterRequest;
public interface UnregisterRequestRepository extends CrudRepository<UnregisterRequest, Long> {
public UnregisterRequest findById(long l);
}

View File

@ -0,0 +1,10 @@
package ovh.herisson.Clyde.Repositories.Msg;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Msg.Answer;
public interface AnswerRepository extends CrudRepository<Answer, Long> {
}

View File

@ -0,0 +1,9 @@
package ovh.herisson.Clyde.Repositories.Msg;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Msg.Forum;
public interface ForumRepository extends CrudRepository<Forum, Long> {
}

View File

@ -0,0 +1,10 @@
package ovh.herisson.Clyde.Repositories.Msg;
import org.springframework.data.repository.CrudRepository;
import ovh.herisson.Clyde.Tables.Msg.Topic;
public interface TopicRepository extends CrudRepository<Topic, Long> {
}

View File

@ -14,4 +14,8 @@ public interface UserCurriculumRepository extends CrudRepository<UserCurriculum,
Curriculum findByUser(User student); Curriculum findByUser(User student);
ArrayList<UserCurriculum> findByUserOrderByCurriculum(User student); ArrayList<UserCurriculum> findByUserOrderByCurriculum(User student);
UserCurriculum findByUserAndCurriculumAndActual(User user, Curriculum curriculum, boolean actual);
ArrayList<UserCurriculum> findByUserAndActual(User user, boolean actual);
} }

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

@ -6,12 +6,14 @@ import ovh.herisson.Clyde.Repositories.*;
import ovh.herisson.Clyde.Repositories.Inscription.ExternalCurriculumRepository; import ovh.herisson.Clyde.Repositories.Inscription.ExternalCurriculumRepository;
import ovh.herisson.Clyde.Repositories.Inscription.InscriptionRepository; import ovh.herisson.Clyde.Repositories.Inscription.InscriptionRepository;
import ovh.herisson.Clyde.Repositories.Inscription.MinervalRepository; import ovh.herisson.Clyde.Repositories.Inscription.MinervalRepository;
import ovh.herisson.Clyde.Services.UserService;
import ovh.herisson.Clyde.Tables.*; import ovh.herisson.Clyde.Tables.*;
import ovh.herisson.Clyde.Tables.Inscription.ExternalCurriculum; import ovh.herisson.Clyde.Tables.Inscription.ExternalCurriculum;
import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest; import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest;
import ovh.herisson.Clyde.Tables.Inscription.Minerval; import ovh.herisson.Clyde.Tables.Inscription.Minerval;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
@Service @Service
public class InscriptionService { public class InscriptionService {
@ -27,14 +29,15 @@ public class InscriptionService {
private final MinervalRepository minervalRepository; private final MinervalRepository minervalRepository;
private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
private final ExternalCurriculumRepository externalCurriculumRepository; private final ExternalCurriculumRepository externalCurriculumRepository;
private final UserService userService;
public InscriptionService(InscriptionRepository inscriptionRepo, UserRepository userRepo, UserCurriculumRepository userCurriculumRepo, CurriculumRepository curriculumRepo, MinervalRepository minervalRepository, ExternalCurriculumRepository externalCurriculumRepository){ public InscriptionService(InscriptionRepository inscriptionRepo, UserRepository userRepo, UserCurriculumRepository userCurriculumRepo, CurriculumRepository curriculumRepo, MinervalRepository minervalRepository, ExternalCurriculumRepository externalCurriculumRepository, UserService userService){
this.inscriptionRepo = inscriptionRepo; this.inscriptionRepo = inscriptionRepo;
this.userRepo = userRepo; this.userRepo = userRepo;
this.userCurriculumRepo = userCurriculumRepo; this.userCurriculumRepo = userCurriculumRepo;
this.curriculumRepo = curriculumRepo; this.curriculumRepo = curriculumRepo;
this.minervalRepository = minervalRepository; this.minervalRepository = minervalRepository;
this.externalCurriculumRepository = externalCurriculumRepository; this.externalCurriculumRepository = externalCurriculumRepository;
this.userService = userService;
} }
public InscriptionRequest save(InscriptionRequest inscriptionRequest){ public InscriptionRequest save(InscriptionRequest inscriptionRequest){
@ -56,6 +59,11 @@ public class InscriptionService {
if (inscrRequest == null) if (inscrRequest == null)
return false; return false;
//If the request is already accepted we just return ok (otherwise we would duplicate the procedure below)
if (inscrRequest.getState() == RequestState.Accepted){
return true;
}
inscrRequest.setState(requestState); inscrRequest.setState(requestState);
save(inscrRequest); save(inscrRequest);
@ -84,8 +92,9 @@ public class InscriptionService {
inscrRequest.getPassword() inscrRequest.getPassword()
); );
userRepo.save(userFromRequest); userService.save(userFromRequest);
userCurriculumRepo.save(new UserCurriculum(userFromRequest, curriculumRepo.findById(inscrRequest.getCurriculumId()),0)); Calendar c = Calendar.getInstance();
userCurriculumRepo.save(new UserCurriculum(userFromRequest, curriculumRepo.findById(inscrRequest.getCurriculumId()),c.get(Calendar.YEAR), true));
//Create a minerval for the new student //Create a minerval for the new student
Minerval minerval = new Minerval(userFromRequest.getRegNo(), 0, 852, 2023); Minerval minerval = new Minerval(userFromRequest.getRegNo(), 0, 852, 2023);

View File

@ -0,0 +1,38 @@
package ovh.herisson.Clyde.Services.Msg;
import org.springframework.stereotype.Service;
import lombok.AllArgsConstructor;
import ovh.herisson.Clyde.Repositories.CourseRepository;
import ovh.herisson.Clyde.Repositories.Msg.ForumRepository;
import ovh.herisson.Clyde.Repositories.Msg.TopicRepository;
import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.User;
import ovh.herisson.Clyde.Tables.Msg.Answer;
import ovh.herisson.Clyde.Tables.Msg.Forum;
import ovh.herisson.Clyde.Tables.Msg.Topic;
@Service
@AllArgsConstructor
public class ForumService {
private CourseRepository courseRepo;
private ForumRepository forumRepo;
private TopicRepository topicRepo;
public void createForum(Course c, Forum f){
c.addForum(f);
courseRepo.save(c);
}
public void createTopic(Forum f, Topic data) {
f.addTopic(data);
forumRepo.save(f);
}
public void answerTopic(Topic t, Answer data, User u) {
data.setAuthor(u);
t.addAnswer(data);
topicRepo.save(t);
}
}

View File

@ -51,7 +51,7 @@ public class ProtectionService {
HashMap<String ,Object> toReturn = new HashMap<>(); HashMap<String ,Object> toReturn = new HashMap<>();
toReturn.put("courseId",course.getCourseID()); toReturn.put("courseID",course.getCourseID());
toReturn.put("credits",course.getCredits()); toReturn.put("credits",course.getCredits());
toReturn.put("title", course.getTitle()); toReturn.put("title", course.getTitle());
toReturn.put("owner", userWithoutPassword(course.getOwner())); toReturn.put("owner", userWithoutPassword(course.getOwner()));

View File

@ -35,11 +35,12 @@ public class UserCurriculumService {
HashMap<String, Object> element = new HashMap<>(); HashMap<String, Object> element = new HashMap<>();
Curriculum c = list.get(i).getCurriculum(); Curriculum c = list.get(i).getCurriculum();
element.put("curriculumId", c.getCurriculumId()); element.put("curriculumId", c.getCurriculumId());
element.put("year", c.getYear()); element.put("year", c.getYear());
element.put("option", c.getOption()); element.put("option", c.getOption());
element.put("dateyear", list.get(i).getYear()); element.put("dateyear", list.get(i).getYear());
element.put("actual", list.get(i).isActual());
curriculumlist.add(element); curriculumlist.add(element);
} }
@ -48,5 +49,7 @@ public class UserCurriculumService {
return toReturn; return toReturn;
} }
public ArrayList<UserCurriculum> findByStudentAndActual(User u, boolean actual){
return userCurriculumRepository.findByUserAndActual(u, actual);
}
} }

View File

@ -2,6 +2,7 @@ package ovh.herisson.Clyde.Services;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ovh.herisson.Clyde.Tables.RegNoGenerator;
import ovh.herisson.Clyde.Repositories.UserRepository; import ovh.herisson.Clyde.Repositories.UserRepository;
import ovh.herisson.Clyde.Tables.Notification; import ovh.herisson.Clyde.Tables.Notification;
import ovh.herisson.Clyde.Tables.Role; import ovh.herisson.Clyde.Tables.Role;
@ -107,10 +108,17 @@ public class UserService {
} }
public User save(User user){ public User save(User user){
RegNoGenerator.resetCount();
user.setPassword(passwordEncoder.encode(user.getPassword())); user.setPassword(passwordEncoder.encode(user.getPassword()));
return userRepo.save(user); return userRepo.save(user);
} }
public void saveAll(ArrayList<User> list){
//S'assure que le compteur est bien a 0
RegNoGenerator.resetCount();
userRepo.saveAll(list);
}
public Iterable<User> getAll(){ public Iterable<User> getAll(){
return userRepo.findAll(); return userRepo.findAll();
} }

View File

@ -19,5 +19,6 @@ public enum Applications {
// InscriptionService authorization // InscriptionService authorization
Requests, Requests,
StudentsList StudentsList,
Payments
} }

View File

@ -0,0 +1,95 @@
package ovh.herisson.Clyde.Tables;
import jakarta.persistence.*;
import java.util.Date;
@Entity
public class ChangeCurriculumRequest {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@ManyToOne
@JoinColumn(name="Users")
private User user;
@ManyToOne
@JoinColumn(name = "ActualCurriculum")
private Curriculum actualCurriculum;
@ManyToOne
@JoinColumn(name = "DestCurriculum")
private Curriculum destinationCurriculum;
private Date date;
private RequestState state;
private RequestState teacherApprovalState;
public ChangeCurriculumRequest(){}
public ChangeCurriculumRequest(User user, Curriculum actualCurriculum, Curriculum destinationCurriculum, Date date, RequestState state, RequestState teacherApprovalState){
this.user = user;
this.actualCurriculum = actualCurriculum;
this.destinationCurriculum = destinationCurriculum;
this.date = date;
this.state = state;
this.teacherApprovalState = teacherApprovalState;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Curriculum getActualCurriculum() {
return actualCurriculum;
}
public void setActualCurriculum(Curriculum actualCurriculum) {
this.actualCurriculum = actualCurriculum;
}
public Curriculum getDestinationCurriculum() {
return destinationCurriculum;
}
public void setDestinationCurriculum(Curriculum destinationCurriculum) {
this.destinationCurriculum = destinationCurriculum;
}
public void setDate(Date date) {
this.date = date;
}
public Date getDate() {
return date;
}
public RequestState getState() {
return state;
}
public void setState(RequestState state) {
this.state = state;
}
public int getId() {
return id;
}
public RequestState getTeacherApprovalState() {
return teacherApprovalState;
}
public void setTeacherApprovalState(RequestState teacherApprovalState) {
this.teacherApprovalState = teacherApprovalState;
}
}

View File

@ -1,10 +1,20 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import ovh.herisson.Clyde.Tables.Msg.Forum;
import java.util.List;
import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction; import org.hibernate.annotations.OnDeleteAction;
@Entity @Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Course { public class Course {
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
@ -17,39 +27,18 @@ public class Course {
@JoinColumn(name = "Users") @JoinColumn(name = "Users")
private User owner; private User owner;
//// Extension Messagerie /////
@OneToMany(cascade = CascadeType.ALL)
private List<Forum> forums;
public void addForum(Forum f){
forums.add(f);
}
///////////////////////////////
public Course(int credits, String title, User owner){ public Course(int credits, String title, User owner){
this.credits = credits; this.credits = credits;
this.title = title; this.title = title;
this.owner = owner; this.owner = owner;
} }
public Course() {}
public int getCourseID() {
return courseID;
}
public int getCredits() {
return credits;
}
public void setCredits(int credits){
this.credits = credits;
}
public String getTitle() {
return title;
}
public void setTitle(String title){
this.title = title;
}
public User getOwner() {
return owner;
}
public void setOwner(User owner) {
this.owner = owner;
}
} }

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

@ -12,7 +12,6 @@ public class Payment {
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
private long id; private long id;
private long studentRegNo; private long studentRegNo;
private String card; private String card;
private String client; private String client;

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

@ -7,15 +7,16 @@ import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.User; import ovh.herisson.Clyde.Tables.User;
import java.util.Date; import java.util.Date;
import java.util.Map;
@Entity @Entity
public class ScholarshipRequest { public class ScholarshipRequest {
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
private long id; private long id;
@JoinColumn(name="Users") @JoinColumn(name="Users")
@ManyToOne(fetch = FetchType.EAGER) @ManyToOne(fetch = FetchType.EAGER)
@OnDelete(action = OnDeleteAction.CASCADE)
private User user; private User user;
private RequestState state; private RequestState state;
private Date date; private Date date;

View File

@ -1,67 +0,0 @@
package ovh.herisson.Clyde.Tables.Inscription;
import jakarta.persistence.*;
import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.User;
import java.util.Date;
@Entity
public class UninscriptionRequest {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private RequestState state;
private String reason;
private Date date;
@JoinColumn(name = "Users")
@ManyToOne(fetch = FetchType.EAGER)
private User user;
public UninscriptionRequest(RequestState state,String reason, Date date, User user){
this.state = state;
this.reason = reason;
this.date = date;
this.user = user;
}
public UninscriptionRequest(){}
public RequestState getState() {
return state;
}
public void setState(RequestState state) {
this.state = state;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public long getId() {
return id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public void setDate(Date date) {
this.date = date;
}
public Date getDate() {
return date;
}
}

View File

@ -0,0 +1,115 @@
package ovh.herisson.Clyde.Tables.Inscription;
import jakarta.persistence.*;
import ovh.herisson.Clyde.Tables.Curriculum;
import ovh.herisson.Clyde.Tables.RequestState;
import ovh.herisson.Clyde.Tables.User;
import java.util.Date;
@Entity
public class UnregisterRequest {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private RequestState state;
private String reason;
private Date date;
//We store these informations again so if the user is deleted we still have the informations for history
private long regNo;
private String firstName;
private String lastName;
private String email;
//Null if the user unregister for the academic year, contains a curriculum if the user wants to unregister from a specific curriculum
@ManyToOne
@JoinColumn(name = "Curriculum")
private Curriculum curriculum;
public UnregisterRequest(RequestState state, String reason, Date date, long regNo, String firstName, String lastName, String email, Curriculum curriculum){
this.state = state;
this.reason = reason;
this.date = date;
this.regNo = regNo;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.curriculum = curriculum;
}
public UnregisterRequest(){}
public RequestState getState() {
return state;
}
public void setState(RequestState state) {
this.state = state;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public long getId() {
return id;
}
public void setDate(Date date) {
this.date = date;
}
public Date getDate() {
return date;
}
public String getEmail() {
return email;
}
public String getLastName() {
return lastName;
}
public String getFirstName() {
return firstName;
}
public void setEmail(String email) {
this.email = email;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setRegNo(long regNo) {
this.regNo = regNo;
}
public long getRegNo() {
return regNo;
}
public void setCurriculum(Curriculum curriculum) {
this.curriculum = curriculum;
}
public Curriculum getCurriculum() {
return curriculum;
}
}

View File

@ -0,0 +1,29 @@
package ovh.herisson.Clyde.Tables.Msg;
import java.util.Date;
import org.hibernate.annotations.CreationTimestamp;
import jakarta.persistence.*;
import lombok.Data;
import ovh.herisson.Clyde.Tables.User;
@Entity
@Data
public class Answer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@CreationTimestamp
private Date creation;
private String content;
@ManyToOne(cascade=CascadeType.ALL)
private User author;
private boolean anonymous;
}

View File

@ -0,0 +1,35 @@
package ovh.herisson.Clyde.Tables.Msg;
import java.util.List;
import jakarta.persistence.*;
import lombok.Data;
import ovh.herisson.Clyde.Tables.Course;
import ovh.herisson.Clyde.Tables.User;
@Entity
@Data
public class Forum {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
@ManyToOne
private Course course;
private String name;
@OneToMany(cascade = CascadeType.ALL)
private List<Topic> topics;
public void addTopic(Topic t) {
topics.add(t);
}
@OneToMany
private List<User> writers; // User who are authorized to create a post
@OneToMany
private List<User> register;
}

View File

@ -0,0 +1,31 @@
package ovh.herisson.Clyde.Tables.Msg;
import java.util.List;
import jakarta.persistence.*;
import lombok.Data;
import ovh.herisson.Clyde.Tables.User;
@Entity
@Data
public class Topic {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String subject, content;
@ManyToOne
private User author;
@OneToMany(cascade = CascadeType.ALL)
private List<Answer> answers;
public void addAnswer(Answer a){
answers.add(a);
}
private boolean locked; // true if new messages can be posted
}

View File

@ -0,0 +1,46 @@
package ovh.herisson.Clyde.Tables;
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.IdentifierGenerator;
import java.sql.*;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class RegNoGenerator implements IdentifierGenerator {
private static int count = 0;
@Override
public Object generate(SharedSessionContractImplementor session, Object object) {
try{
JdbcConnectionAccess jdbccon = session.getJdbcConnectionAccess();
Connection conn = jdbccon.obtainConnection();
Statement statement = conn.createStatement();
Calendar c = new GregorianCalendar();
int y = c.get(Calendar.YEAR);
String query = "select count(reg_no) + "+count+" from Users where reg_no/10000 = " + y%1000;
ResultSet set = statement.executeQuery(query);
long resp = 0;
if(set.next()){
resp = set.getLong(1)+((y%1000)*10000);
count += 1;
}
conn.close();
statement.close();
return resp;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static void resetCount(){
count = 0;
}
}

View File

@ -1,8 +1,12 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import org.hibernate.annotations.GenericGenerator;
import ovh.herisson.Clyde.Tables.Msg.Discussion; import ovh.herisson.Clyde.Tables.Msg.Discussion;
import ovh.herisson.Clyde.Tables.Msg.Message; import ovh.herisson.Clyde.Tables.Msg.Message;
@ -11,14 +15,14 @@ import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity @Entity
@Table(name = "Users") @Table(name = "Users")
@NoArgsConstructor @NoArgsConstructor
@Data @Data
public class User { public class User {
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GenericGenerator(name = "userGen", type = ovh.herisson.Clyde.Tables.RegNoGenerator.class)
@GeneratedValue(generator = "userGen")
private Long regNo; private Long regNo;
private String lastName; private String lastName;
private String firstName; private String firstName;

View File

@ -1,10 +1,17 @@
package ovh.herisson.Clyde.Tables; package ovh.herisson.Clyde.Tables;
import jakarta.persistence.*; import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction; import org.hibernate.annotations.OnDeleteAction;
@Entity @Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserCurriculum { public class UserCurriculum {
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.AUTO)
@ -23,39 +30,13 @@ public class UserCurriculum {
private int year; private int year;
public UserCurriculum(User user, Curriculum curriculum, int year){ //True if the user has that curriculum at the moment false if not
this.user = user; private boolean actual;
this.curriculum = curriculum;
this.year = year; public UserCurriculum(User u, Curriculum cu, int year, boolean actual){
} this.user = u;
this.curriculum = cu;
public UserCurriculum() {}
public int getId() {
return id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Curriculum getCurriculum() {
return curriculum;
}
public void setCurriculum(Curriculum curriculum) {
this.curriculum = curriculum;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year; this.year = year;
this.actual = actual;
} }
} }

View File

@ -24,6 +24,7 @@ public class UserRepoTest {
@BeforeEach @BeforeEach
public void setup(){ public void setup(){
userRepo.deleteAll();
User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand", new GregorianCalendar(2005, 4, 3).getTime(), null, Role.Admin,"admin"); User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand", new GregorianCalendar(2005, 4, 3).getTime(), null, Role.Admin,"admin");
userRepo.save(herobrine); userRepo.save(herobrine);
} }
@ -34,8 +35,8 @@ public class UserRepoTest {
} }
@Test @Test
public void usertest(){ public void usertest(){
Assert.assertEquals("brine", userRepo.findById(1).getLastName()); Assert.assertEquals("brine", userRepo.findByEmail("admin@admin.com").getLastName());
Assert.assertTrue(new GregorianCalendar(2005, 4, 3).getTime().equals(userRepo.findById(1).getBirthDate())); Assert.assertTrue(new GregorianCalendar(2005, 4, 3).getTime().equals(userRepo.findByEmail("admin@admin.com").getBirthDate()));
} }
} }

View File

@ -13,6 +13,13 @@ login.guest.lastpage=Last Page
login.guest.submit=Submit login.guest.submit=Submit
login.guest.birthday=BIRTHDAY login.guest.birthday=BIRTHDAY
login.guest.confirm=CONFIRM 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.cPassword=Confirm Password
login.password=Password login.password=Password
app.home=Home app.home=Home
@ -28,6 +35,7 @@ app.language=Language
app.manage.profile=Manage profile app.manage.profile=Manage profile
app.studentList=Students List app.studentList=Students List
app.users=Users app.users=Users
app.payments = Payments
request.moreInfos=More Infos request.moreInfos=More Infos
request.accept=Accept request.accept=Accept
request.refuse=Refuse request.refuse=Refuse
@ -53,3 +61,87 @@ Credits=Credits
InscriptionService=I.S. InscriptionService=I.S.
faculty=Faculty faculty=Faculty
msg.notification.new=You have a new message 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.submit=Envoyer
login.guest.birthday=DATE DE NAISSANCE login.guest.birthday=DATE DE NAISSANCE
login.guest.confirm=CONFIRMER 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.cPassword=Confirmer mot de passe
login.password=Mot de passe login.password=Mot de passe
app.home=Home app.home=Home
@ -28,6 +35,7 @@ app.language=Langue
app.manage.profile=Gérer le profil app.manage.profile=Gérer le profil
app.studentList=Liste des étudiants app.studentList=Liste des étudiants
app.users=Utilisateurs app.users=Utilisateurs
app.payments = Payements
request.moreInfos=Plus d'Infos request.moreInfos=Plus d'Infos
request.accept=Accepter request.accept=Accepter
request.refuse=Refuser request.refuse=Refuser
@ -53,3 +61,87 @@ Credits=Credits
InscriptionService=S.I. InscriptionService=S.I.
faculty=Faculté faculty=Faculté
msg.notification.new=Vous avez un nouveau message! 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 active=ref(false)
const notification = ref(false) const notification = ref(false)
const apps = ref([]) const apps = ref([])
appList().then(e => apps.value = e) appList().then(e => apps.value = e)
@ -38,7 +37,6 @@ window.addEventListener('hashchange', () => {
<template> <template>
<div class="container"> <div class="container">
<div class="topBar"> <div class="topBar">
<ul class="horizontal"> <ul class="horizontal">
<li title=home> <li title=home>
@ -77,7 +75,6 @@ window.addEventListener('hashchange', () => {
{{i18n("app.manage.profile")}} {{i18n("app.manage.profile")}}
</a> </a>
</div> </div>
</div> </div>
</a></li> </a></li>
</ul> </ul>
@ -107,20 +104,19 @@ window.addEventListener('hashchange', () => {
height: 100%; height: 100%;
width: 100%; width: 100%;
display:grid; 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: grid-template-areas:
"topBar topBar" "topBar topBar"
"leftBar page"; "leftBar page";
row-gap:0px;
column-gap:0px;
} }
.page { .page {
grid-area:page; grid-area:page;
height: 100%; height: 100%;
width: 100%; width: 100%;
place-self:center;
} }
.topBar{ .topBar{
@ -163,7 +159,7 @@ window.addEventListener('hashchange', () => {
ul.vertical{ ul.vertical{
list-style-type: none; list-style-type: none;
margin-top: 61px; margin-top: var(--header-size);
top:0; top:0;
left:0; left:0;
padding: 25px 0 0; padding: 25px 0 0;
@ -211,7 +207,7 @@ window.addEventListener('hashchange', () => {
left:0; left:0;
position: fixed; position: fixed;
height:61px; height:var(--header-size);
width: 100%; width: 100%;
background-color: rgb(24, 24, 24); 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> <script setup>
import i18n from "@/i18n.js" import i18n from "@/i18n.js"
import {getSelf, getUser} from '../../rest/Users.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 {getRegisters} from "@/rest/ServiceInscription.js";
import {get} from "jsdom/lib/jsdom/named-properties-tracker.js"; import {get} from "jsdom/lib/jsdom/named-properties-tracker.js";
import {getExternalCurriculumByInscrReq} from "@/rest/externalCurriculum.js"; import {getExternalCurriculumByInscrReq} from "@/rest/externalCurriculum.js";
@ -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"
@ -29,7 +31,7 @@ async function editEquivalence(id, newstate){
</script> </script>
<template> <template>
<div class="body" v-if="list == false"> <div class="body" v-if="list == false" style="margin-top: 10%;">
<div class="container"> <div class="container">
<div class="profilPic"> <div class="profilPic">
<img class="subContainter" :src=getPP()> <img class="subContainter" :src=getPP()>
@ -37,36 +39,43 @@ async function editEquivalence(id, newstate){
<div class = "globalInfos"> <div class = "globalInfos">
<div class="infosContainer"> <div class="infosContainer">
<div> <div>
FirstName/Name : {{request.firstName}} {{request.lastName}} {{ i18n("firstname/name") }} : {{request.firstName}} {{request.lastName}}
</div> </div>
<div> <div>
E-mail: {{request.email}} {{ i18n("login.guest.email") }}: {{request.email}}
</div> </div>
<div> <div>
Adresse : {{request.address}} {{ i18n("login.guest.address") }} : {{request.address}}
</div> </div>
<div> <div>
Pays : {{request.country}} {{ i18n("login.guest.country") }} : {{request.country}}
</div> </div>
<div> <div>
Date de naissance : {{request.birthDate}} {{ i18n("login.guest.birthday") }} : {{request.birthDate}}
</div> </div>
<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>
<div v-if="cursus.year > 1"> <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>
</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"> <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%" v-if="request.equivalenceState === 'Pending'" @click="list = false;editEquivalence(request.id, 'Accepted'); request.equivalenceState='Accepted'">{{i18n("acceptequiv")}}</button>
<button style="margin-left: 2%" @click="list = false;editEquivalence(request.id, 'Refused'); request.equivalenceState='Refused'">Refuse Equivalence</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">Return to profile</button> <button style="margin-left: 2%" @click="list=false">Back</button>
</div> </div>
</div> </div>
</template> </template>
@ -123,10 +132,10 @@ async function editEquivalence(id, newstate){
} }
button{ button{
font-size:15px;
height:50px;
width:100px;
border:none; border:none;
border-radius:20px; background-color:rgb(239, 60, 168);
border-radius:10px;
height:35px;
margin-top:10px;
} }
</style> </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> <script setup>
import i18n from "@/i18n.js" 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 {getSomeonesCurriculumList} from "@/rest/curriculum.js";
import {ref} from "vue"; import {ref} from "vue";
import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue"; import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue";
import {getExternalCurriculumByUser} from "@/rest/externalCurriculum.js"; import {getExternalCurriculumByUser} from "@/rest/externalCurriculum.js";
import {getUserActualCourses} from "@/rest/courses.js";
const props = defineProps(['target']) const props = defineProps(['target'])
const user = await getUser(props.target) const user = await getUser(props.target)
@ -12,6 +13,10 @@
const externalcurrlist = await getExternalCurriculumByUser(user.regNo) const externalcurrlist = await getExternalCurriculumByUser(user.regNo)
const extercurrlist = ref(false) const extercurrlist = ref(false)
const courselist = await getUserActualCourses(user.regNo)
console.log(courselist)
const watchingUser = await getSelf()
function getPP(){ function getPP(){
if(user.profilePictureUrl === null){ if(user.profilePictureUrl === null){
return "/Clyde.png" return "/Clyde.png"
@ -40,47 +45,50 @@
<div class = "globalInfos"> <div class = "globalInfos">
<div class="infosContainer"> <div class="infosContainer">
<div> <div>
FirstName/Name : {{user.firstName}} {{user.lastName}} {{ i18n("firstname/name") }} : {{user.firstName}} {{user.lastName}}
</div> </div>
<div> <div>
E-mail: {{user.email}} {{ i18n("login.guest.email") }}: {{user.email}}
</div> </div>
<div> <div>
Adresse : {{user.address}} {{ i18n("login.guest.address") }} : {{user.address}}
</div> </div>
<div> <div>
Pays : {{user.country}} {{ i18n("login.guest.country") }} : {{user.country}}
</div> </div>
<div> <div>
Date de naissance : {{user.birthDate}} {{ i18n("login.guest.birthday") }} : {{user.birthDate}}
</div> </div>
<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>
</div> </div>
<div class="moreInfos"> <div class="moreInfos" style="margin-top: 15%">
<div class = "oldcursus"> <div class = "oldcursus">
<div class="listTitle"> <div class="listTitle">
Anciens Cursus {{ i18n("oldcursus") }}
</div> </div>
<div class="listElement"> <div class="listElement">
<div class=" containerElement" v-for="item in UserCurriculum.curriculumList"> <div class=" containerElement" v-for="item in UserCurriculum.curriculumList">
<div class="year" v-if="parseInt(item.dateyear) !== getYear()">Bac {{item.year}}</div> <div class="year" v-if="item.actual === false">Bac {{item.year}}</div>
<div class="option" v-if="parseInt(item.dateyear) !== getYear()">{{item.option}}</div> <div class="option" v-if="item.actual === false">{{item.option}}</div>
<div class="dateyear" v-if="parseInt(item.dateyear) !== getYear()">Année {{item.dateyear}}-{{item.dateyear+1}}</div> <div class="dateyear" v-if="item.actual === false">{{ i18n("year") }} {{item.dateyear}}-{{item.dateyear+1}}</div>
</div> </div>
</div> </div>
</div> </div>
<div class="newcursus"> <div class="newcursus">
<div class="listTitle"> <div class="listTitle">
Cursus Actuel {{ i18n("newcursus") }}
</div> </div>
<div class="listElement"> <div class="listElement">
<div class=" containerElement" v-for="item in UserCurriculum.curriculumList" > <div class=" containerElement" v-for="item in UserCurriculum.curriculumList" >
<div class="year" v-if="parseInt(item.dateyear) === getYear()">Bac {{item.year}}</div> <div class="year" v-if="item.actual === true">Bac {{item.year}}</div>
<div class="option" v-if="parseInt(item.dateyear) === getYear()">{{item.option}}</div> <div class="option" v-if="item.actual === true">{{item.option}}</div>
<div class="dateyear" v-if="parseInt(item.dateyear) === getYear()">Année {{item.dateyear}}-{{item.dateyear+1}}</div> <div class="dateyear" v-if="item.actual === true">{{ i18n("year") }} {{item.dateyear}}-{{item.dateyear+1}}</div>
</div> </div>
</div> </div>
</div> </div>
@ -88,12 +96,13 @@
</div> </div>
</div> </div>
<div v-if="extercurrlist==true"> <div v-if="extercurrlist==true">
<ExternalCurriculumList :ext-curr-list="externalcurrlist"></ExternalCurriculumList> <ExternalCurriculumList :ext-curr-list="externalcurrlist" :mode="1"></ExternalCurriculumList>
</div> </div>
</template> </template>
<style scoped> <style scoped>
.container{ .container{
min-width:675px; min-width:675px;
display:grid; display:grid;
@ -102,8 +111,7 @@
column-gap:2.7%; column-gap:2.7%;
row-gap:45px; row-gap:45px;
grid-template-areas: grid-template-areas:
"profilPic globalInfos" "profilPic globalInfos";
"minfos minfos";
} }
.profilPic{ .profilPic{
@ -143,12 +151,10 @@
} }
.moreInfos { .moreInfos {
display:grid; display:inline-grid;
grid-template-rows:200px auto;
column-gap:50px; column-gap:50px;
row-gap:45px;
grid-template-areas: grid-template-areas:
"minfos minfos"; "oldcursus newcursus";
grid-template-columns:600px 600px; grid-template-columns:600px 600px;
align-items:center; align-items:center;
justify-content:center; justify-content:center;
@ -189,4 +195,12 @@
column-gap:40px; column-gap:40px;
padding-left: 25px; padding-left: 25px;
} }
button{
border:none;
background-color:rgb(239, 60, 168);
border-radius:10px;
height:35px;
margin-top:10px;
}
</style> </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 {getCourse} from "@/rest/courses.js";
import {getcurriculum} from "@/rest/curriculum.js"; import {getcurriculum} from "@/rest/curriculum.js";
import {uploadFile, uploadProfilePicture} from "@/rest/uploads.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"; import {getSelf} from "@/rest/Users.js";
const props = defineProps(["cursuslist"]) const props = defineProps(["cursuslist"])
const selectedCurriculum = ref(props.cursuslist[0]) const selectedCurriculum = ref(props.cursuslist[0])
const user = await getSelf() const user = await getSelf()
const windowState = defineModel("windowState")
const exempList = await getExempByUser(user.regNo)
const courseslist = ref(await getcurriculum(selectedCurriculum.value.curriculumId)) const courseslist = ref(await getcurriculum(selectedCurriculum.value.curriculumId))
const list = ref(true) const list = ref(true)
@ -30,11 +33,20 @@ const exemptReq = reactive({
courseId : null, courseId : null,
justifDocument : "", 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> </script>
<template style="margin-top:5%;"> <template style="margin-top:5%;">
<div v-if="list == true"> <div v-if="list == true">
<span>Selected Cursus : </span> <span>{{i18n("selectedcursus")}} : </span>
<select v-model="selectedCurriculum" @change="updateCourseList"> <select v-model="selectedCurriculum" @change="updateCourseList">
<option v-for="item in props.cursuslist" :value="item">Bac {{item.year}} {{item.option}}</option> <option v-for="item in props.cursuslist" :value="item">Bac {{item.year}} {{item.option}}</option>
</select> </select>
@ -45,20 +57,29 @@ const exemptReq = reactive({
<div class="firstname">{{item.owner.firstName}}</div> <div class="firstname">{{item.owner.firstName}}</div>
<div class="lastname">{{item.owner.lastName}}</div> <div class="lastname">{{item.owner.lastName}}</div>
<div class="credits">credits : {{item.credits}}</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>
</div> </div>
<div>
<button @click="windowState = 0">{{ i18n("courses.back")}}</button>
</div> </div>
<div v-else> </div>
<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"> <label class="browser">
<input type="file" @change="ppData.value = $event.target.files" accept="image/*" ref="filepath"> <input type="file" @change="ppData.value = $event.target.files" accept="image/*" ref="filepath">
</label> </label>
<button style="width:15%; margin-top: 5%;" @click="postExemptionRequest(ppData.value, 'JustificationDocument');"> </div>
Submit exemption request <button style="margin-top: 3%" @click="postExemptionRequest(ppData.value, 'JustificationDocument');">
{{ i18n("subexemreq") }}
</button> </button>
</div> </div>
<div v-if="list === false">
<button @click="list=!list">{{ i18n("courses.back") }}</button>
</div>
</template> </template>
<style scoped> <style scoped>
@ -135,5 +156,15 @@ button{
margin-top:10px; 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> </style>

View File

@ -1,25 +1,134 @@
<script setup> <script setup>
import i18n from "@/i18n.js"; 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) //Only usefull to pass the external curr array in the inscription procedure
console.log(extCurrList) 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> </script>
<template style="margin-top:5%;"> <template style="margin-top:5%;">
<div style="display:flex; justify-content:center; " v-for="item in extCurrList"> <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="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>
<div class="school"><a>{{item.school}}</a></div> <div class="school"><a>{{item.school}}</a></div>
<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>{{ 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> </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> </template>
<style scoped> <style scoped>
@ -28,9 +137,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;
} }
@ -40,6 +149,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;
@ -61,18 +179,12 @@
font-size: 70%; font-size: 70%;
} }
.download{ .download{
grid-area: download; grid-area: download;
align-self:center; align-self:center;
} }
button{
font-size:15px;
height:50px;
width:75%;
border:none;
border-radius:20px;
}
.bodu { .bodu {
margin-top:2%; margin-top:2%;
@ -82,6 +194,49 @@ button{
background-color:rgb(50,50,50); 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> </style>

View File

@ -1,18 +1,28 @@
<script setup> <script setup>
import i18n from "@/i18n.js" import i18n from "@/i18n.js"
import {ref} from 'vue' import {ref, vModelSelect, watch} 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 {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()); const requests = ref(await getAllRegisters());
let targetId = ""; let targetId = "";
const user = await getSelf()
const requestType = ref("inscription"); const requestType = ref("inscription");
const filterType = ref("None"); const filterType = ref("None");
//0 = liste, 1 = détails, 2 = sure? //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);
@ -21,34 +31,50 @@
} }
async function loadRequests(){ async function loadRequests(){
if (requestType.value === "inscription"){ switch (requestType.value){
case i18n("inscription"):
requests.value = await getAllRegisters(); requests.value = await getAllRegisters();
} break;
if (requestType.value === "scholarship"){ case i18n("scholarship"):
requests.value = await getAllScholarShipsRequest(); requests.value = await getAllScholarShipsRequest();
} break;
if(requestType.value === "exemption"){ case i18n("exemption"):
requests.value = await getAllExemptionsRequest(); 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> </script>
<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%">
<span>Request type : </span> <span>{{ i18n("reqtype") }} : </span>
<select v-model="requestType" @change="loadRequests()"> <select v-model="requestType" @change="loadRequests()">
<option>inscription</option> <option>{{ i18n("inscription") }}</option>
<option>scholarship</option> <option v-if="user.role === 'Admin' || user.role === 'InscriptionService'">{{ i18n("scholarship") }}</option>
<option>exemption</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> </select>
<span style="margin-left: 5%"> <span style="margin-left: 5%">
Filter : {{ i18n("filter") }}
<select v-model="filterType"> <select v-model="filterType">
<option>None</option> <option>None</option>
<option>Pending</option> <option>Pending</option>
@ -58,44 +84,73 @@
</span> </span>
</div> </div>
<div style='display:flex; justify-content:center; min-width:1140px;' v-for="item of requests"> <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="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 === 'inscription'"> <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')">
<!--
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="date" v-if="item.submissionDate !== undefined">{{item.submissionDate.slice(0, 10)}}</div> <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="state" style="font-size: 80%">{{ i18n("approval") }} {{item.state}}</div>
<div class="equivalencestate" style="font-size: 80%">Teacher approval : {{item.equivalenceState}}</div> <div class="equivalencestate" style="font-size: 80%">{{ i18n("teacherapproval") }} {{item.equivalenceState}}</div>
<div class="surname">{{item.lastName}}</div> <div class="surname">{{item.lastName}}</div>
<div class="firstname">{{item.firstName}}</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="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="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 class="infos"><button style="background-color:rgb(105,05,105);" @click="targetId=item.id;windowsState=1;">{{i18n("request.moreInfos")}}</button></div>
</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="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">{{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>
<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="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="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">{{ i18n("request.moreInfos") }}</button></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div style='display:flex; justify-content:center; min-width:1140px;margin-top: 10%' v-if="windowsState === 2"> <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> <p>{{ i18n("surreq") }}</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="upPage(targetId,'Accepted');windowsState=0;">{{ i18n("validate") }}</button>
<button style="background-color:rgb(105,05,105);" @click="windowsState=0;">Retour</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> </div>
</template> </template>
@ -112,6 +167,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;
@ -151,6 +211,10 @@
align-self:center; align-self:center;
} }
.regno{
grid-area: regno;
align-self: center;
}
.state{ .state{
grid-area:state; grid-area:state;
margin-left:40px; margin-left:40px;
@ -174,12 +238,11 @@
} }
button{ button{
font-size:15px;
height:50px;
width:100px;
border:none; border:none;
border-radius:20px; background-color:rgb(239, 60, 168);
border-radius:10px;
height: 35px;
margin-top:10px;
} }
.bodu { .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 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 ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue";
const loginPage= ref(true) const loginPage= ref(true)
const page = ref(0) const page = ref(0)
@ -23,18 +24,6 @@
equivalenceState: "Unrequired" 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 //Stores some externalCurriculums in order to upload them all at the confirmation of the registration request
const externalCurrTab = ref([]); const externalCurrTab = ref([]);
@ -44,8 +33,8 @@
const imageSaved = ref(false) const imageSaved = ref(false)
let ppData = "" let ppData = ""
//Contains the id of the newly created request (useful to link the student's formations informations to the request) const idcardfile = ref({})
let requestId = "" const justifcardfile = ref({})
const curricula= await getAllCurriculums(); const curricula= await getAllCurriculums();
@ -83,30 +72,35 @@
} }
} }
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 //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); 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> </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">
@ -125,7 +119,7 @@
<a @click="loginPage=!loginPage">{{i18n("login.guest.register")}}</a> <a @click="loginPage=!loginPage">{{i18n("login.guest.register")}}</a>
</div> </div>
<div class="inputBox" style="margin-bottom:35px;"> <div class="inputBox" style="margin-bottom:35px;">
<input type="submit" v-model="submitValue"> <input v-model="submitValue" type="submit">
</div> </div>
</form> </form>
</div> </div>
@ -183,11 +177,10 @@
<p>{{i18n("profile.picture").toUpperCase()}}</p> <p>{{i18n("profile.picture").toUpperCase()}}</p>
</form> </form>
<label class="browser"> <label class="browser">
Parcourir . . . {{i18n("login.guest.browse")}}
<input type="file" :disabled="imageSaved" @change="ppData = uploadProfilePicture($event.target.files); imageSaved = true;" accept="image/*"> <input type="file" :disabled="imageSaved" @change="ppData = uploadProfilePicture($event.target.files); imageSaved = true;" accept="image/*">
</label> </label>
<form novalidate enctype="multipart/form-data" class="inputBox"> <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/*"> <input type="file" @change="uploadPP($event.target.files); imageSaved = true;" accept="image/*">
</form> </form>
<div class="inputBox"> <div class="inputBox">
@ -197,8 +190,7 @@
</select> </select>
</div> </div>
<p style="color:rgb(239,60,168);"> <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 {{i18n("login.guest.disclaimer")}}
changer de cursus/réinscription sinon continuez ici.
</p> </p>
<div style="align-self:center;" class="inputBox"> <div style="align-self:center;" class="inputBox">
<button style="margin-top:25px;" @click="page++;"> <button style="margin-top:25px;" @click="page++;">
@ -213,67 +205,38 @@
</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);">{{i18n("login.guest.identityCard")}}</p>
Carte d'identité : <label class="browser">
</form> {{i18n("login.guest.browse")}}
<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);">{{ 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>
<div v-if="page === 3"> <div v-if="page === 3">
<p> <p style="color:rgb(239,60,168);margin-bottom: 5%">
Vous avez séléctionné un cursus qui possède des prérequis veuillez ajouter vos formations antérieures {{i18n("login.guest.formationdisclaimer")}}
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++">{{i18n("login.guest.managecareer")}}</button>
<button @click="postRegisterReq();">Envoyer la demande d'inscription</button> <button @click="postRegisterReq();">{{ i18n("login.guest.sendRegReq") }}</button>
</div>
</form>
</div>
</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--">{{i18n("courses.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>
@ -295,7 +258,6 @@
justify-content: center; justify-content: center;
border-radius: 5%; border-radius: 5%;
box-shadow:0 5px 25px #000000; box-shadow:0 5px 25px #000000;
} }
.form { .form {
position:relative; position:relative;
@ -325,8 +287,6 @@
z-index: 100; z-index: 100;
font-family:sans-serif ; font-family:sans-serif ;
color:rgb(239,60,168); color:rgb(239,60,168);
transition: 0.5;
} }
.register{ .register{
@ -354,8 +314,6 @@
outline:none; outline:none;
border-radius: 4px; border-radius: 4px;
font-size:0.8em; font-size:0.8em;
align-self: right;
} }
input[type=submit],button,select{ input[type=submit],button,select{

View File

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

View File

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

View File

@ -12,7 +12,7 @@
<template style="margin-top:5%;"> <template style="margin-top:5%;">
<div v-if="list === false"> <div v-if="list === false">
<AboutStudent :target=targetRegNo /> <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>
<div style="display:flex; justify-content:center; " v-for="item in users" v-if="list === true"> <div style="display:flex; justify-content:center; " v-for="item in users" v-if="list === true">
<div class="bodu"> <div class="bodu">

View File

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

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

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

View File

@ -71,3 +71,11 @@ export async function getCourses(role){
export async function alterCourse(id, changes){ export async function alterCourse(id, changes){
return restPatch("/course/" + 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 {restGet, restPatch, restPost} from "@/rest/restConsumer.js";
import {parseInteger} from "jsdom/lib/jsdom/living/helpers/strings.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", { return restPost("/externalcurriculum", {
inscriptionRequestId: inscriptionRequestId, inscriptionRequestId: inscriptionRequestId,
school:school, school:school,
formation :formation, formation :formation,
completion : completion, completion : completion,
startYear : parseInteger(startYear), startYear : startYear,
endYear: parseInteger(endYear), endYear: endYear,
justifdocUrl : justifdocUrl 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) return restPatch("/request/registerequiv/"+id+"/"+newstate)
} }
export async function addUninscReq(userId, reason){ export async function addUninscReq(userId, reason, curriculumId){
return restPost("/uninscriptionreq", {"userId" : userId, "reason" : reason}) 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,7 +13,7 @@ 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){ export async function uploadFile(file, type){