1
0
forked from PGL/Clyde

Final Schedule - merge

This commit is contained in:
Wawilski 2024-04-21 18:10:00 +02:00
commit e0a3a618a1
52 changed files with 1688 additions and 629 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

@ -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}")
@ -134,4 +146,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

@ -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

@ -13,6 +13,7 @@ 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.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;
@ -28,6 +29,7 @@ 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;
@ -40,7 +42,8 @@ public class RequestsController {
public final ChangeCurriculumRequestRepository changeCurriculumRequestRepository; public final ChangeCurriculumRequestRepository changeCurriculumRequestRepository;
public RequestsController(ExemptionsRequestRepository err, ScholarshipRequestRepository srr, UserRepository userRepository, AuthenticatorService authServ, UnregisterRequestRepository unregisterRequestRepository, CourseRepository courseRepository, UserService userService, UserCurriculumRepository userCurriculumRepository, CurriculumRepository curriculumRepository, 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;
@ -78,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<>();
@ -90,7 +93,7 @@ public class RequestsController {
@GetMapping(value = "/exemptionsreq/{id}") @GetMapping(value = "/exemptionsreq/{id}")
public ResponseEntity<ExemptionsRequest> getExemptionRequestbyId(@RequestHeader("Authorization") String token, @PathVariable long id){ public ResponseEntity<ExemptionsRequest> getExemptionRequestbyId(@RequestHeader("Authorization") String token, @PathVariable long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token)) if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
ExemptionsRequest exemptionsRequest = err.findById(id); ExemptionsRequest exemptionsRequest = err.findById(id);
@ -100,10 +103,15 @@ public class RequestsController {
@PatchMapping(value = "/exemptionsreq/{id}/{newstate}") @PatchMapping(value = "/exemptionsreq/{id}/{newstate}")
public ResponseEntity<String> changeExemptionReqState(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newstate){ public ResponseEntity<String> changeExemptionReqState(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newstate){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token)) if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher},token))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
ExemptionsRequest exemptionsRequest = err.findById(id); ExemptionsRequest exemptionsRequest = err.findById(id);
if (exemptionsRequest.getState() == RequestState.Accepted){
return new ResponseEntity<>(HttpStatus.OK);
}
exemptionsRequest.setState(newstate); exemptionsRequest.setState(newstate);
err.save(exemptionsRequest); err.save(exemptionsRequest);
@ -140,9 +148,17 @@ public class RequestsController {
} }
@PatchMapping(value = "/scholarshipreq/") @PatchMapping(value = "/scholarshipreq/")
public ResponseEntity<String> editScholReq(@RequestBody Map<String,Object> infos){ 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")); 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")){ if (infos.get("state").equals("Accepted")){
scholarshipRequest.setState(RequestState.Accepted); scholarshipRequest.setState(RequestState.Accepted);
scholarshipRequest.setAmount((int) infos.get("amount")); scholarshipRequest.setAmount((int) infos.get("amount"));
@ -155,30 +171,48 @@ public class RequestsController {
} }
@GetMapping(value = "/scholarshipreq/{id}") @GetMapping(value = "/scholarshipreq/{id}")
public ResponseEntity<ScholarshipRequest> getScholReqbyId(@PathVariable long 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); ScholarshipRequest toReturn = srr.findById(id);
return new ResponseEntity<>(toReturn, HttpStatus.OK); return new ResponseEntity<>(toReturn, HttpStatus.OK);
} }
@GetMapping(value = "/unregister") @GetMapping(value = "/unregister")
public ResponseEntity<ArrayList<UnregisterRequest>> getAllUnregReq(){ 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<>(); ArrayList<UnregisterRequest> toReturn = new ArrayList<>();
unregisterRequestRepository.findAll().forEach(toReturn::add); unregisterRequestRepository.findAll().forEach(toReturn::add);
return new ResponseEntity<>(toReturn, HttpStatus.OK); return new ResponseEntity<>(toReturn, HttpStatus.OK);
} }
@GetMapping(value = "/unregister/{id}") @GetMapping(value = "/unregister/{id}")
public ResponseEntity<UnregisterRequest> getUnregbyId(@PathVariable long 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); UnregisterRequest unregisterRequest = unregisterRequestRepository.findById(id);
return new ResponseEntity<>(unregisterRequest, HttpStatus.OK); return new ResponseEntity<>(unregisterRequest, HttpStatus.OK);
} }
@PatchMapping(value = "/unregister/{id}/{newstate}") @PatchMapping(value = "/unregister/{id}/{newstate}")
public ResponseEntity<String> pathUnregReq(@PathVariable long id, @PathVariable RequestState 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); UnregisterRequest unregisterRequest = unregisterRequestRepository.findById(id);
User u = userRepository.findById(unregisterRequest.getRegNo()); User u = userRepository.findById(unregisterRequest.getRegNo());
unregisterRequest.setState(newstate);
//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 (newstate == RequestState.Accepted){
if (unregisterRequest.getCurriculum() == null){ if (unregisterRequest.getCurriculum() == null){
ArrayList<UserCurriculum> userCurricula = userCurriculumRepository.findByUserOrderByCurriculum(u); ArrayList<UserCurriculum> userCurricula = userCurriculumRepository.findByUserOrderByCurriculum(u);
@ -193,8 +227,6 @@ public class RequestsController {
userCurriculumRepository.save(userCurriculum); userCurriculumRepository.save(userCurriculum);
} }
} }
unregisterRequestRepository.save(unregisterRequest);
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
@ -236,7 +268,7 @@ public class RequestsController {
@GetMapping("/changecurriculumreq") @GetMapping("/changecurriculumreq")
public ResponseEntity<ArrayList <ChangeCurriculumRequest>> getAllChangeCurrReq(@RequestHeader("Authorization") String token){ public ResponseEntity<ArrayList <ChangeCurriculumRequest>> getAllChangeCurrReq(@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<ChangeCurriculumRequest> toReturn = new ArrayList<>(); ArrayList<ChangeCurriculumRequest> toReturn = new ArrayList<>();
@ -248,7 +280,7 @@ public class RequestsController {
@GetMapping("/changecurriculumreq/{id}") @GetMapping("/changecurriculumreq/{id}")
public ResponseEntity<ChangeCurriculumRequest> getCCrbyId(@RequestHeader("Authorization") String token, @PathVariable long id){ public ResponseEntity<ChangeCurriculumRequest> getCCrbyId(@RequestHeader("Authorization") String token, @PathVariable long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token)) if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
ChangeCurriculumRequest toReturn = changeCurriculumRequestRepository.findById(id); ChangeCurriculumRequest toReturn = changeCurriculumRequestRepository.findById(id);
@ -257,37 +289,45 @@ public class RequestsController {
@PatchMapping("/changecurriculumreq/{id}/{newState}") @PatchMapping("/changecurriculumreq/{id}/{newState}")
public ResponseEntity<String> editCCReq(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newState){ public ResponseEntity<String> editCCReq(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newState){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token)) if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService},token))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
ChangeCurriculumRequest toEdit = changeCurriculumRequestRepository.findById(id); ChangeCurriculumRequest toEdit = changeCurriculumRequestRepository.findById(id);
toEdit.setState(newState); //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 (newState == RequestState.Accepted && (toEdit.getTeacherApprovalState() == RequestState.Accepted || toEdit.getTeacherApprovalState() == RequestState.Unrequired)){
//If actual curriculum is not null then we need to set that the user doesn't follow it anymore //If actual curriculum is not null then we need to set that the user doesn't follow it anymore
acceptProcedure(toEdit); acceptProcedure(toEdit);
} }
changeCurriculumRequestRepository.save(toEdit);
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
@PatchMapping("/changecurriculumreqteacher/{id}/{newteacherstate}") @PatchMapping("/changecurriculumreqteacher/{id}/{newteacherstate}")
public ResponseEntity<String> editCCReqTeacherState(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newteacherstate){ public ResponseEntity<String> editCCReqTeacherState(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newteacherstate){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token)) if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher},token))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
ChangeCurriculumRequest toEdit = changeCurriculumRequestRepository.findById(id); 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); toEdit.setState(newteacherstate);
changeCurriculumRequestRepository.save(toEdit);
if (newteacherstate == RequestState.Accepted && toEdit.getState() == RequestState.Accepted){ 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 //If actual curriculum is not null then we need to set that the user doesn't follow it anymore
acceptProcedure(toEdit); acceptProcedure(toEdit);
} }
changeCurriculumRequestRepository.save(toEdit);
return new ResponseEntity<>(HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK);
} }
@ -309,4 +349,18 @@ public class RequestsController {
UserCurriculum userCurriculum = new UserCurriculum(u, toEdit.getDestinationCurriculum(), c.get(Calendar.YEAR), true); UserCurriculum userCurriculum = new UserCurriculum(u, toEdit.getDestinationCurriculum(), c.get(Calendar.YEAR), true);
userCurriculumRepository.save(userCurriculum); userCurriculumRepository.save(userCurriculum);
} }
@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

@ -119,7 +119,7 @@ public class MockController {
ucr.save(new UserCurriculum(popo, infoBab2, 2023, true)); 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);
@ -136,7 +136,7 @@ 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));

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

@ -30,16 +30,13 @@ public class ScheduleController {
private final ScheduleService scheduleServ; private final ScheduleService scheduleServ;
private final LessonService lessonServ; private final LessonService lessonServ;
private final UserCurriculumService userCurriculumService;
private final CurriculumService curriculumServ; private final CurriculumService curriculumServ;
private final AuthenticatorService authServ; private final AuthenticatorService authServ;
private final ScheduleLessonService scheduleLessonServ; private final ScheduleLessonService scheduleLessonServ;
public ScheduleController(ScheduleService scheduleServ, UserCurriculumService userCurriculumService, AuthenticatorService authServ, ScheduleLessonService scheduleLessonServ, CurriculumService curriculumServ,LessonService lessonServ) { public ScheduleController(ScheduleService scheduleServ, AuthenticatorService authServ, ScheduleLessonService scheduleLessonServ, CurriculumService curriculumServ,LessonService lessonServ) {
this.scheduleServ = scheduleServ; this.scheduleServ = scheduleServ;
this.userCurriculumService = userCurriculumService;
this.authServ = authServ; this.authServ = authServ;
this.scheduleLessonServ = scheduleLessonServ; this.scheduleLessonServ = scheduleLessonServ;
this.curriculumServ = curriculumServ; this.curriculumServ = curriculumServ;

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); ExemptionsRequest findById(long id);
ArrayList<ExemptionsRequest> findByUser(User user);
} }

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

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

View File

@ -59,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);

View File

@ -74,8 +74,8 @@ public class LessonRequestService {
if(lessonRequest == null || state == lessonRequest.getState() || state == null){ if(lessonRequest == null || state == lessonRequest.getState() || state == null){
return false;} return false;}
if (state == RequestState.Accepted){ if (state == RequestState.Accepted){
Course course = courseRepository.findById(lessonRequest.getCourse().getCourseID()); Course course = courseRepository.findById(lessonRequest.getCourse().getCourseId());
if(courseRepository.findById(lessonRequest.getCourse().getCourseID())==null|| local == null){ if(courseRepository.findById(lessonRequest.getCourse().getCourseId())==null|| local == null){
return false;} return false;}
Lesson lesson = new Lesson(); Lesson lesson = new Lesson();
lesson.setCourse(course); lesson.setCourse(course);

View File

@ -21,7 +21,6 @@ public class LessonService {
private final LessonRepository lessonRepo; private final LessonRepository lessonRepo;
private final UserCurriculumRepository userCurriculumRepo; private final UserCurriculumRepository userCurriculumRepo;
private final CourseRepository courseRepo; private final CourseRepository courseRepo;
private final CurriculumCourseRepository curriculumCourseRepo; private final CurriculumCourseRepository curriculumCourseRepo;
public LessonService(LessonRepository lessonRepo, UserCurriculumRepository userCurriculumRepo, CourseRepository courseRepo, CurriculumCourseRepository curriculumCourseRepo){ public LessonService(LessonRepository lessonRepo, UserCurriculumRepository userCurriculumRepo, CourseRepository courseRepo, CurriculumCourseRepository curriculumCourseRepo){
this.lessonRepo = lessonRepo; this.lessonRepo = lessonRepo;
@ -65,11 +64,15 @@ public class LessonService {
public Iterable<Lesson> findOnesLessons(User student){ public Iterable<Lesson> findOnesLessons(User student){
ArrayList<Lesson> toReturn = new ArrayList<>(); ArrayList<Lesson> toReturn = new ArrayList<>();
ArrayList<Course> courses = new ArrayList<>(); ArrayList<Course> courses = new ArrayList<>();
ArrayList<UserCurriculum> userCurriculums = userCurriculumRepo.findByUserOrderByCurriculum(student); ArrayList<UserCurriculum> userCurricula = userCurriculumRepo.findByUserAndActual(student, true);
for(UserCurriculum uc: userCurriculums){ for (UserCurriculum userCurriculum : userCurricula) {
Curriculum c = uc.getCurriculum(); curriculumCourseRepo.findCoursesByCurriculum(userCurriculum.getCurriculum()).forEach((item) -> {
if(uc.isActual()) //We need this to eliminate clones because a course can belong to several curriculums
courses.addAll((ArrayList<Course>) curriculumCourseRepo.findCoursesByCurriculum(c)); if (!courses.contains(item)) {
System.out.println(item.getTitle());
courses.add(item);
}
});
} }
for (Course element : courses) { for (Course element : courses) {
for(Lesson lesson : lessonRepo.findLessonByCourse(element)) for(Lesson lesson : lessonRepo.findLessonByCourse(element))

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

@ -50,7 +50,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

@ -49,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

@ -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,42 +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 void setCourseID(int courseId){
this.courseId = 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

@ -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

@ -11,6 +11,7 @@ import ovh.herisson.Clyde.Tables.Msg.Message;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
@Entity @Entity
@Table(name = "Users") @Table(name = "Users")
public class User { public class User {
@ -27,7 +28,6 @@ public class User {
private Date birthDate; private Date birthDate;
private String profilePictureUrl; private String profilePictureUrl;
private Role role; private Role role;
@JsonIgnore @JsonIgnore
private String password; private String password;

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)
@ -26,48 +33,10 @@ public class UserCurriculum {
//True if the user has that curriculum at the moment false if not //True if the user has that curriculum at the moment false if not
private boolean actual; private boolean actual;
public UserCurriculum(User user, Curriculum curriculum, int year, boolean actual){ public UserCurriculum(User u, Curriculum cu, int year, boolean actual){
this.user = user; this.user = u;
this.curriculum = curriculum; this.curriculum = cu;
this.year = year; this.year = year;
this.actual = actual; this.actual = actual;
} }
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;
}
public void setActual(boolean actual) {
this.actual = actual;
}
public boolean isActual() {
return actual;
}
} }

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
@ -35,6 +42,63 @@ app.payments = Payments
request.moreInfos=More Infos request.moreInfos=More Infos
request.accept=Accept request.accept=Accept
request.refuse=Refuse request.refuse=Refuse
Pending=Pending
Delete=Delete
Modify=Modify
Create=Créer
requestType=Request Type
day=Day
start=Start
end=End
monday=Monday
tuesday=Tuesday
wednesday=Wednesday
thursday=Thursday
friday=Friday
saturday=Saturday
sunday=Sunday
january=January
february=February
march=March
april=April
may=May
june=June
july=July
august=August
september=September
october=October
november=November
december=December
Grid=Grid
Week=Week
Month=Month
List=List
Type=Type
Teacher=Teacher
Course=Course
TP=TP
TD=TD
Exam=Exam
OwnSchedule=Own Schedule
SwitchToJSON=Switch to JSON FILE
schedule.previous=Previous
schedule.next=Next
schedule.current=Current
schedule.settings=Settings
schedule.courses=Courses
schedule.teachers=Teacher(s)
schedule.askChanges=Ask Changes
schedule.askCreate=Ask to create course
schedule.askDeletion=Ask Deletion
schedule.createSchedule=Create Schedule
schedule.createLesson=Create course
schedule.deleteMod=Unable deletion
schedule.noDeleteMod=Disable deletion
schedule=Schedule
old_day=Precedent day
old_start=Precedent start
old_end=Precedent end
old_type=Precedent type
courses.createCourse=Create course courses.createCourse=Create course
courses.deleteCourse=Delete course courses.deleteCourse=Delete course
courses.modify=Modify courses.modify=Modify
@ -56,3 +120,87 @@ Curriculum=curriculum
Credits=Credits Credits=Credits
InscriptionService=I.S. InscriptionService=I.S.
faculty=Faculty faculty=Faculty
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
@ -35,6 +42,63 @@ 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
Pending=En attente
Delete=Supprimer
Modify=Modifier
Create=Créer
requestType=Type de Requête
day=Jour
start=Début
end=Fin
monday=Lundi
tuesday=Mardi
wednesday=Mercredi
thursday=Jeudi
friday=Vendredi
saturday=Samedi
sunday=Dimanche
january=Janvier
february=Février
march=Mars
april=Avril
may=Mai
june=Juin
july=Juillet
august=Août
september=Septembre
october=Octobre
november=Novembre
december=Decembre
Grid=Grille
Week=Semaine
Month=Mois
List=Liste
Type=Type
Teacher=Professeur
Course=Cours
TP=TP
TD=TD
Exam=Exam
OwnSchedule=Mon Horaire
SwitchToJSON=Afficher le JSON
schedule.previous=Précédent
schedule.next=Prochain
schedule.current=Actuel
schedule.settings=Options
schedule.courses=Cours
schedule.teachers=Professeurs(s)
schedule.askChanges=Demander Changement
schedule.askCreate=Demander de créer un cours
schedule.askDeletion=Demander suppression
schedule.createSchedule=Créer Horaire
schedule.createLesson=Créer cours
schedule.deleteMod=Activer suppression
schedule.noDeleteMod=Désactiver suppression
schedule=Horaire
old_day=Ancien Jour
old_start=Ancien Début
old_end=Ancienne Fin
old_type=Ancien Type
courses.createCourse=Créer un cours courses.createCourse=Créer un cours
courses.deleteCourse=Supprimer un cours courses.deleteCourse=Supprimer un cours
courses.modify=Modifier courses.modify=Modifier
@ -56,4 +120,87 @@ Curriculum=Cursus
Credits=Credits Credits=Credits
InscriptionService=S.I. InscriptionService=S.I.
faculty=Faculté faculty=Faculté
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

@ -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

@ -39,39 +39,39 @@ async function editChangeCurrReqTeacherApproval(state){
<div class="globalInfos"> <div class="globalInfos">
<div class="infosContainer"> <div class="infosContainer">
<div> <div>
Firstname/Name : {{req.user.firstName}} {{req.user.lastName}} {{i18n("firstname/name")}} : {{req.user.firstName}} {{req.user.lastName}}
</div> </div>
<div> <div>
regNo : {{req.user.regNo}} {{i18n("regNo")}} : {{req.user.regNo}}
</div> </div>
<div v-if="req.actualCurriculum !== null"> <div v-if="req.actualCurriculum !== null">
From : Bac {{req.actualCurriculum.year}} {{req.actualCurriculum.option}} {{i18n("From")}} : Bac {{req.actualCurriculum.year}} {{req.actualCurriculum.option}}
To : Bac {{req.destinationCurriculum.year}} {{req.destinationCurriculum.option}} {{i18n("To")}} : Bac {{req.destinationCurriculum.year}} {{req.destinationCurriculum.option}}
</div> </div>
<div v-else> <div v-else>
Wanted cursus : Bac {{req.destinationCurriculum.year}} {{req.destinationCurriculum.option}} {{i18n("WantedCursus")}} : Bac {{req.destinationCurriculum.year}} {{req.destinationCurriculum.option}}
</div> </div>
<div> <div>
<button @click="localwindowstate++"> See profile </button> <button @click="localwindowstate++"> {{ i18n("seeprofile") }} </button>
</div> </div>
<div> <div>
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';uploadandrefreshChangeRequest('Accepted')">Accept</button> <button v-if="req.state === 'Pending'" @click="req.state='Accepted';uploadandrefreshChangeRequest('Accepted')">{{ i18n("request.accept") }}</button>
<button v-if="req.state === 'Pending'" @click="req.state='Refused';uploadandrefreshChangeRequest('Refused')" style="margin-left: 2%;">Refuse</button> <button v-if="req.state === 'Pending'" @click="req.state='Refused';uploadandrefreshChangeRequest('Refused')" style="margin-left: 2%;">{{i18n("request.refuse")}}</button>
</div> </div>
<div v-if="user.role === 'Teacher' || user.role === 'Admin'"> <div v-if="user.role === 'Teacher' || user.role === 'Admin'">
<button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Accepted';editChangeCurrReqTeacherApproval('Accepted')">Accept equivalence</button> <button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Accepted';editChangeCurrReqTeacherApproval('Accepted')">{{i18n("acceptequiv")}}</button>
<button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Refused';editChangeCurrReqTeacherApproval('Refused')">Refuse equivalence</button> <button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Refused';editChangeCurrReqTeacherApproval('Refused')">{{i18n("refuseequiv")}}</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div v-if="localwindowstate === 0"> <div v-if="localwindowstate === 0" style="margin-left: 23%">
<button @click="windowState = 0" style="margin-left: 10%">Back</button> <button @click="windowState = 0" style="margin-left: 10%">{{ i18n("courses.back") }}</button>
</div> </div>
<div v-if="localwindowstate === 1"> <div v-if="localwindowstate === 1">
<AboutStudent :target="tag"></AboutStudent> <AboutStudent :target="tag"></AboutStudent>
<button @click="localwindowstate--;">Back</button> <button @click="localwindowstate--;" style="margin-left: 10%">{{ i18n("courses.back") }}</button>
</div> </div>
</template> </template>
@ -125,4 +125,12 @@ async function editChangeCurrReqTeacherApproval(state){
background-color:rgb(50,50,50); background-color:rgb(50,50,50);
border-radius:20px; border-radius:20px;
} }
button{
border:none;
background-color:rgb(239, 60, 168);
border-radius:10px;
height:35px;
margin-top:10px;
}
</style> </style>

View File

@ -32,23 +32,23 @@ async function editExemp(newstate){
<div class="globalInfos"> <div class="globalInfos">
<div class="infosContainer"> <div class="infosContainer">
<div> <div>
Firstname/Name : {{req.user.firstName}} {{req.user.lastName}} {{ i18n("firstname/name") }} : {{req.user.firstName}} {{req.user.lastName}}
</div> </div>
<div> <div>
Course: {{req.course.title}} {{ i18n("course") }}: {{req.course.title}}
</div> </div>
<div> <div>
State : {{req.state}} {{ i18n("state") }} : {{req.state}}
</div> </div>
<div> <div>
<button @click="profile = !profile">Voir le profil</button> <button @click="profile = !profile">{{ i18n("seeprofile") }}</button>
</div> </div>
<div> <div>
<button>Download justification document</button> <button>{{ i18n("dljustifdoc") }}</button>
</div> </div>
<div> <div>
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';editExemp('Accepted')">Accept</button> <button v-if="req.state === 'Pending'" @click="req.state='Accepted';editExemp('Accepted')">{{ i18n("request.accept") }}</button>
<button v-if="req.state === 'Pending'" @click="req.state='Refused';editExemp('Refused')" style="margin-left: 2%;">Refuse</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>
@ -56,10 +56,10 @@ async function editExemp(newstate){
</div> </div>
<div v-else> <div v-else>
<AboutStudent :target="req.user.regNo"></AboutStudent> <AboutStudent :target="req.user.regNo"></AboutStudent>
<button @click="profile=!profile">Back</button> <button @click="profile=!profile" style="margin-left: 17%;margin-top: 3%">{{ i18n("backtoreq") }}</button>
</div> </div>
<div> <div>
<button v-if="profile===false" @click="windowState = 0" style="margin-left: 30%">Back</button> <button v-if="profile===false" @click="windowState = 0" style="margin-left: 31%">{{ i18n("courses.back") }}</button>
</div> </div>
</template> </template>
@ -113,4 +113,12 @@ async function editExemp(newstate){
background-color:rgb(50,50,50); background-color:rgb(50,50,50);
border-radius:20px; border-radius:20px;
} }
button{
border:none;
background-color:rgb(239, 60, 168);
border-radius:10px;
height:35px;
margin-top:10px;
}
</style> </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";
@ -31,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()>
@ -39,38 +39,42 @@ 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"> <div v-if="list == false" style="margin-left: 30%; margin-top: 5%">
<button @click="windowState = 0">Back</button> <button @click="windowState = 0">{{ i18n("courses.back") }}</button>
</div> </div>
<div v-if="list==true"> <div v-if="list==true">
<ExternalCurriculumList :ext-curr-list="externalCurriculum" :mode="0"></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">Back</button> <button style="margin-left: 2%" @click="list=false">Back</button>
</div> </div>
</div> </div>
@ -128,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

@ -39,31 +39,31 @@ async function uploadandrefreshScholarshipRequest(){
<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>
Country : {{user.country}} {{ i18n("login.guest.country") }} : {{user.country}}
</div> </div>
<div> <div>
Birthdate : {{user.birthDate.slice(0,10)}} {{ i18n("login.guest.birthday") }} : {{user.birthDate.slice(0,10)}}
</div> </div>
<div> <div>
<button>Download tax justif document</button> <button @click="">{{ i18n("dltaxdoc") }}</button>
<button style="margin-left: 2%">Download residency justif document</button> <button style="margin-left: 2%">{{ i18n("dlresidency") }}</button>
</div> </div>
<div v-if="req.state == 'Pending'"> <div v-if="req.state == 'Pending'" style="margin-top: 2%; margin-bottom: 2%;">
Please enter the amount to provide : {{i18n("enteramount")}}
<input type="number" v-model="scholarshipData.amount"> <input type="number" v-model="scholarshipData.amount">
</div> </div>
<div> <div>
<button v-if="req.state === 'Pending'" @click="scholarshipData.state='Accepted';uploadandrefreshScholarshipRequest()">Accept</button> <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%;">Refuse</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> </div>
@ -101,7 +101,7 @@ async function uploadandrefreshScholarshipRequest(){
display:flex; display:flex;
align-items:center; align-items:center;
justify-content:center; justify-content:center;
margin-top:7%; margin-top:10%;
} }
.subContainter{ .subContainter{
@ -121,4 +121,12 @@ async function uploadandrefreshScholarshipRequest(){
background-color:rgb(50,50,50); background-color:rgb(50,50,50);
border-radius:20px; border-radius:20px;
} }
button{
border:none;
background-color:rgb(239, 60, 168);
border-radius:10px;
height:35px;
margin-top:10px;
}
</style> </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="item.actual === false">Bac {{item.year}}</div> <div class="year" v-if="item.actual === false">Bac {{item.year}}</div>
<div class="option" v-if="item.actual === false">{{item.option}}</div> <div class="option" v-if="item.actual === false">{{item.option}}</div>
<div class="dateyear" v-if="item.actual === false">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="item.actual === true">Bac {{item.year}}</div> <div class="year" v-if="item.actual === true">Bac {{item.year}}</div>
<div class="option" v-if="item.actual === true">{{item.option}}</div> <div class="option" v-if="item.actual === true">{{item.option}}</div>
<div class="dateyear" v-if="item.actual === true">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>
@ -94,6 +102,7 @@
<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

@ -34,21 +34,21 @@ async function uploadandrefreshUnregRequest(state){
<div class="globalInfos"> <div class="globalInfos">
<div class="infosContainer"> <div class="infosContainer">
<div> <div>
Firstname/Name : {{req.firstName}} {{req.lastName}} {{ i18n("firstname/name") }} : {{req.firstName}} {{req.lastName}}
</div> </div>
<div> <div>
E-mail: {{req.email}} {{ i18n("login.guest.email") }}: {{req.email}}
</div> </div>
<div> <div>
regNo : {{req.regNo}} {{ i18n("regNo") }} : {{req.regNo}}
</div> </div>
<div> <div>
Reason : {{ i18n("reason") }}
<input type="text" v-model="req.reason" readonly/> <input type="text" v-model="req.reason" readonly/>
</div> </div>
<div> <div>
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';uploadandrefreshUnregRequest('Accepted')">Accept</button> <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%;">Refuse</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> </div>

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>
<div v-else> <div v-if="list === false" class="infosContainer">
<p>Please upload the justification document for the exemption </p> <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

@ -3,6 +3,7 @@
import {reactive, ref} from "vue"; import {reactive, ref} from "vue";
import {getSelf} from "@/rest/Users.js"; import {getSelf} from "@/rest/Users.js";
import {createExternalCurriculum, getExternalCurriculumByUser} from "@/rest/externalCurriculum.js"; import {createExternalCurriculum, getExternalCurriculumByUser} from "@/rest/externalCurriculum.js";
import {uploadFile} from "@/rest/uploads.js";
//mode 0 = externalcurr related to inscrreq, 1 = externalcurr related to user, 2 inscription procedure //mode 0 = externalcurr related to inscrreq, 1 = externalcurr related to user, 2 inscription procedure
const props = defineProps(["extCurrList", "mode"]) const props = defineProps(["extCurrList", "mode"])
@ -51,7 +52,8 @@
async function postExternalCurr(){ async function postExternalCurr(){
if (props.mode === 1){ if (props.mode === 1){
await createExternalCurriculum(externalCurr.inscriptionRequestId, externalCurr.school, externalCurr.formation, externalCurr.completion, externalCurr.startYear, externalCurr.endYear, externalCurr.justifdocUrl, externalCurr.userRegNo); 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 //We refresh the list
extCurrList.value = await getExternalCurriculumByUser(externalCurr.userRegNo); extCurrList.value = await getExternalCurriculumByUser(externalCurr.userRegNo);
list.value = !list.value; list.value = !list.value;
@ -68,7 +70,6 @@
}); });
extCurrList.value = externalCurrTab.value extCurrList.value = externalCurrTab.value
list.value = !list.value; list.value = !list.value;
console.log(externalCurrTab.value)
} }
} }
</script> </script>
@ -76,18 +77,18 @@
<template style="margin-top:5%;"> <template style="margin-top:5%;">
<div v-if="list"> <div v-if="list">
<div v-if="props.mode === 2||User.regNo === externalCurr.userRegNo" style="margin-left: 2%;margin-top: 2%"> <div v-if="props.mode === 2||User.regNo === externalCurr.userRegNo" style="margin-left: 2%;margin-top: 2%">
<button @click="list = !list">Add external curriculum</button> <button @click="list = !list" style="margin-left:15%;">{{ i18n("addextcurr") }}</button>
</div> </div>
<div style="display:flex; justify-content:center; " v-for="(item, index) in extCurrList"> <div style="display:flex; justify-content:center;" v-for="(item, index) in extCurrList">
<div class="bodu"> <div class="bodu">
<div class="container"> <div class="container">
<div class="status"><a style="margin-left:30px">{{item.state}}</a></div> <div class="status"><a style="margin-left:30px">{{item.state}}</a></div>
<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">Edit</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)">Delete</button></div> <div class="delete" v-if="props.mode === 2"><button @click="deleteExtCursus(item)">{{ i18n("delete") }}</button></div>
</div> </div>
</div> </div>
</div> </div>
@ -95,7 +96,7 @@
<div v-else class="loginbox" style="margin-left: 35%; margin-top: 3%"> <div v-else class="loginbox" style="margin-left: 35%; margin-top: 3%">
<form class="form"> <form class="form">
<div class="inputBox"> <div class="inputBox">
<p>Ecole</p> <p>{{ i18n("school") }}</p>
<input type="text" v-model="externalCurr.school"> <input type="text" v-model="externalCurr.school">
</div> </div>
<div class="inputBox"> <div class="inputBox">
@ -103,24 +104,28 @@
<input type="text" v-model="externalCurr.formation"> <input type="text" v-model="externalCurr.formation">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>Cochez la case si vous n'avez terminé cette formation</p> <p>{{i18n("checkifnotcompleted")}}</p>
<input v-model="notcompletedCheck" type="checkbox" id="checkboxformation"> <input v-model="notcompletedCheck" type="checkbox" id="checkboxformation">
<div v-if="notcompletedCheck"> <div v-if="notcompletedCheck">
<p>En quelle année de la formation vous êtes vous arrété (exemple: 3ème) ?</p> <p>{{i18n("wichyearstop")}}</p>
<input type="text" v-model="externalCurr.completion"> <input type="text" v-model="externalCurr.completion">
</div> </div>
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>Année de début</p> <p>{{ i18n("startyear") }}</p>
<input type="number" v-model="externalCurr.startYear"> <input type="number" v-model="externalCurr.startYear">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>Année de fin</p> <p>{{ i18n("endyear") }}</p>
<input type="number" v-model="externalCurr.endYear"> <input type="number" v-model="externalCurr.endYear">
</div> </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%"> <div class="inputBox" style="margin-top: 3%; margin-bottom: 3%">
<input v-if="!editmode" type="submit" value="Upload curriculum" @click="postExternalCurr()"> <input v-if="!editmode" type="submit" value="upload" @click="postExternalCurr()">
<input v-else type="submit" value="Edit curriculum" @click="externalCurrTab[extNum] = {inscriptionRequestId : externalCurr.inscriptionRequestId,school:externalCurr.school,formation :externalCurr.formation,completion : externalCurr.completion,startYear : externalCurr.startYear,endYear: externalCurr.endYear,justifdocUrl : externalCurr.justifdocUrl,userRegNo : externalCurr.userRegNo};editmode=!editmode;list=!list"> <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> </div>
</form> </form>
</div> </div>
@ -224,8 +229,14 @@
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; }
button{
border:none;
background-color:rgb(239, 60, 168);
border-radius:10px;
height:35px;
margin-top:10px;
} }
</style> </style>

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import i18n from "@/i18n.js" import i18n from "@/i18n.js"
import {ref, vModelSelect} 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 { import {
@ -13,10 +13,11 @@
import AboutUnregister from "@/Apps/Inscription/AboutUnregister.vue"; import AboutUnregister from "@/Apps/Inscription/AboutUnregister.vue";
import AboutChangeCurriculum from "@/Apps/Inscription/AboutChangeCurriculum.vue"; import AboutChangeCurriculum from "@/Apps/Inscription/AboutChangeCurriculum.vue";
import AboutExemption from "@/Apps/Inscription/AboutExemption.vue"; 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");
@ -31,22 +32,29 @@
async function loadRequests(){ async function loadRequests(){
switch (requestType.value){ switch (requestType.value){
case "inscription": case i18n("inscription"):
requests.value = await getAllRegisters(); requests.value = await getAllRegisters();
break; break;
case "scholarship": case i18n("scholarship"):
requests.value = await getAllScholarShipsRequest(); requests.value = await getAllScholarShipsRequest();
break; break;
case "exemption": case i18n("exemption"):
requests.value = await getAllExemptionsRequest(); requests.value = await getAllExemptionsRequest();
break; break;
case "unregister": case i18n("unregister"):
requests.value = await getAllUnregisters(); requests.value = await getAllUnregisters();
break; break;
case "curriculum change": case i18n("curriculumch"):
requests.value = await getAllChangeCurrReq(); 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>
@ -57,16 +65,16 @@
</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>unregister</option> <option v-if="user.role === 'Admin' || user.role === 'InscriptionService'">{{ i18n("unregister") }}</option>
<option>curriculum change</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>
@ -76,70 +84,67 @@
</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" @click="windowsState = 3; targetId=item.id;"><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.user.firstName}}</div>
<div class="studentlastname">{{item.user.lastName}}</div>
<div class="course">{{item.course.title}}</div>
<div class="reqState">{{item.state}}</div>
<div class="infos"><button @click="windowsState=6;targetId=item.id">More infos</button></div>
</div>
<div class="container" v-if="requestType === 'unregister'" style="grid-template-columns:17% 15% 12% 15%;grid-template-areas:'date reqState regno studentfirstname studentlastname infos';">
<div class="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.firstName}}</div> <div class="studentfirstname">{{item.firstName}}</div>
<div class="studentlastname">{{item.lastName}}</div> <div class="studentlastname">{{item.lastName}}</div>
<div class="regno">id : {{item.regNo}}</div> <div class="regno">id : {{item.regNo}}</div>
<div class="reqState">{{item.state}}</div> <div class="reqState">{{item.state}}</div>
<div class="infos"><button @click="windowsState=4;targetId=item.id">More infos</button></div> <div class="infos"><button @click="windowsState=4;targetId=item.id">{{ i18n("request.moreInfos") }}</button></div>
</div> </div>
<div class="container" v-if="requestType === 'curriculum change'" style="grid-template-columns:17% 20% 15% 5%;grid-template-areas:'date reqState teacherApproval regno studentfirstname studentlastname infos';"> <div class="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="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">IS approval : {{item.state}}</div> <div class="reqState">{{ i18n("approval")}}{{item.state}}</div>
<div class="teacherApproval">Teacher approval : {{item.teacherApprovalState}}</div> <div class="teacherApproval">{{ i18n("teacherapproval") }} : {{item.teacherApprovalState}}</div>
<div class="infos"><button @click="windowsState=5;targetId=item.id">More infos</button></div> <div class="infos"><button @click="windowsState=5;targetId=item.id">{{ i18n("request.moreInfos") }}</button></div>
</div>
</div>
<div class="bodu" v-if="(filterType == 'None' || filterType == item.state) && requestType === i18n('exemption') && (item.course.owner.regNo === user.regNo || user.role === 'Admin')">
<div class="container" style="grid-template-columns:17% 15% 12% 15% 25%;grid-template-areas:'date reqState studentfirstname studentlastname course infos';">
<div class="date" v-if="item.date != undefined">{{item.date.slice(0,10)}}</div>
<div class="studentfirstname">{{item.user.firstName}}</div>
<div class="studentlastname">{{item.user.lastName}}</div>
<div class="course">{{item.course.title}}</div>
<div class="reqState">{{item.state}}</div>
<div class="infos"><button @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>
<div v-if="windowsState === 3"> <div v-if="windowsState === 3">
<AboutScholarship :req-id="targetId"></AboutScholarship> <AboutScholarship :req-id="targetId"></AboutScholarship>
<div> <div>
<button style="margin-left: 30%" @click="loadRequests();windowsState=0">Back</button> <button style="margin-left: 31%; margin-top: 5%" @click="windowsState=0">{{ i18n("courses.back")}}</button>
</div> </div>
</div> </div>
<div v-if="windowsState === 4"> <div v-if="windowsState === 4">
<AboutUnregister :req-id="targetId"></AboutUnregister> <AboutUnregister :req-id="targetId"></AboutUnregister>
<button @click="windowsState=0">Back</button> <button @click="windowsState=0" style="margin-left: 31%">{{ i18n("courses.back")}}</button>
</div> </div>
<div v-if="windowsState === 5"> <div v-if="windowsState === 5">
<AboutChangeCurriculum :req-id="targetId" v-model:window-state="windowsState"></AboutChangeCurriculum> <AboutChangeCurriculum :req-id="targetId" v-model:window-state="windowsState"></AboutChangeCurriculum>
@ -233,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

@ -4,15 +4,16 @@ import {ref} from "vue";
import {getAllPayments} from "@/rest/requests.js"; import {getAllPayments} from "@/rest/requests.js";
const paymentsList = await getAllPayments() const paymentsList = await getAllPayments()
</script> </script>
<template style="margin-top:5%;"> <template style="margin-top:5%;">
<div style="display:flex; justify-content:center; " v-for="item in paymentsList"> <div style="display:flex; justify-content:center; " v-for="item in paymentsList">
<div class="bodu"> <div class="bodu">
<div class="container"> <div class="container">
<div class="regNo"><a style="margin-left:30px">RegNo : {{item.studentRegNo}}</a></div> <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="client"><a>Client : {{item.client}}</a></div>
<div class="amount"><a>Amount : {{item.amount}}</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 class="date" style="margin-left: 10%">{{item.date.slice(0,10)}}</div>
</div> </div>
</div> </div>

View File

@ -1,14 +1,19 @@
<!----------------------------------------------------
File: LessonRequests.vue
Author: William Karpinski
Scope: Extension Horaire
Description: Lesson Requests Management Page
----------------------------------------------------->
<script setup> <script setup>
import i18n from "@/i18n.js" import i18n from "@/i18n.js"
import {ref} from 'vue' import {ref} from 'vue'
import {changeRequestState, getAllRequests} from "@/rest/LessonRequests.js"; import {changeRequestState, getAllRequests} from "@/rest/LessonRequests.js";
import {getLesson} from "@/rest/lessonSchedule.js"; import {getLesson} from "@/rest/lessonSchedule.js";
import {getCourse} from "@/rest/courses.js"
import {formatDate, getHoursMinutes} from "@/scheduleFunctions.js"; import {formatDate, getHoursMinutes} from "@/scheduleFunctions.js";
const requests = ref(await getAllRequests()); const requests = ref(await getAllRequests());
const AcceptMod = ref(false); const AcceptMod = ref(false);
const moreInfosMod = ref(false); const moreInfosMod = ref(false);
const requestTypes = ["Create", "Modify", "Delete"] const requestTypes = ["Create", "Modify", "Delete"]
@ -16,11 +21,21 @@ const editElementID = ref('');
const chosenLocal = ref(""); const chosenLocal = ref("");
const locals = ["A0B1","A1B1","A2B1","A0B2"]; const locals = ["A0B1","A1B1","A2B1","A0B2"];
const moreInfos = ref({}); const moreInfos = ref({});
/*
* Change a request's state and refreshes the requests '
*/
async function upPage(id,review){ async function upPage(id,review){
await changeRequestState(id, review) ; await changeRequestState(id, review) ;
requests.value = await getAllRequests(); requests.value = await getAllRequests();
} }
/*
* Set correctly the variables after clicking on the ACCEPT button
*/
async function AcceptSetup(id,type){ async function AcceptSetup(id,type){
if(type !== 2 ){ if(type !== 2 ){
editElementID.value = id editElementID.value = id
@ -31,10 +46,9 @@ async function AcceptSetup(id,type){
} }
} }
function editItem(item){ /*
editElementID.value = item.id; * Set the infos to show when clicking MORE INFOS
} */
async function setMoreInfos(item){ async function setMoreInfos(item){
moreInfos.value = Object.assign({},{}) moreInfos.value = Object.assign({},{})
@ -64,17 +78,17 @@ async function setMoreInfos(item){
<template> <template>
<div class="body"> <div class="body">
<div v-for="item of requests" :key="item.id" :style="{width:[moreInfosMod ? 95:70] + '%'}" class="centerer"> <div v-for="item of requests" :key="item.id" :style="{width:[moreInfosMod ? 95:70] + '%'}" class="center">
<button v-if="moreInfosMod && editElementID == item.id" @click="moreInfosMod = false; editElementID = ''; moreInfos='';">back</button> <button v-if="moreInfosMod && editElementID == item.id" @click="moreInfosMod = false; editElementID = ''; moreInfos='';">{{i18n("courses.back")}}</button>
<div v-if ="item.state === 'Pending'" class="listElement"> <div v-if ="item.state === 'Pending'" class="listElement">
<div class="containerElement" v-if="editElementID !== item.id"> <div class="containerElement" v-if="editElementID !== item.id">
<div class="id">{{requestTypes[item.requestType]}}</div> <div class="id">{{i18n(requestTypes[item.requestType].toString())}}</div>
<div class="surname">{{item.state}}</div> <div class="surname">{{i18n(item.state.toString())}}</div>
<div class="firstname">{{item.user.lastName}}</div> <div class="firstname">{{item.user.lastName}}</div>
<div class="infos"> <div class="infos">
<button @click=" setMoreInfos(item); console.log(item);" style="background-color:rgb(105,05,105);" > <button @click=" setMoreInfos(item);" style="background-color:rgb(105,05,105);" >
{{i18n("request.moreInfos")}} {{i18n("request.moreInfos")}}
</button></div> </button></div>
<div class="accept"><button @click="AcceptSetup(item.id,item.requestType);" style="background-color:rgb(0,105,50);">{{i18n("request.accept")}}</button></div> <div class="accept"><button @click="AcceptSetup(item.id,item.requestType);" style="background-color:rgb(0,105,50);">{{i18n("request.accept")}}</button></div>
@ -87,13 +101,13 @@ async function setMoreInfos(item){
<select v-model="chosenLocal"> <select v-model="chosenLocal">
<option v-for="item in locals">{{item}}</option> <option v-for="item in locals">{{item}}</option>
</select> </select>
<button @click="AcceptMod = false;upPage(item.id,{local: chosenLocal, state:'Accepted'})">Accept</button> <button @click="AcceptMod = false;upPage(item.id,{local: chosenLocal, state:'Accepted'})">{{i18n("request.accept")}}</button>
</div> </div>
<template v-if="moreInfosMod" v-for="(key,value) in moreInfos"> <template v-if="moreInfosMod" v-for="(key,value) in moreInfos">
<div class="container" v-if="key != null" style="align-self:center;"> <div class="container" v-if="key != null" style="align-self:center;">
<div style="margin:0 auto 0 auto"> <div style="margin:0 auto 0 auto">
{{value}}: {{i18n(value.toString())}}:
{{key}} {{key}}
</div> </div>
</div> </div>
@ -105,7 +119,9 @@ async function setMoreInfos(item){
</template> </template>
<style scoped> <style scoped>
.centerer{
.center{
margin:0 auto 0 auto; margin:0 auto 0 auto;
} }
@ -193,33 +209,10 @@ button{
width:100%; width:100%;
margin-top:3.5%; margin-top:3.5%;
} }
button:hover{
opacity:0.8;
}
.buttonGrid{
display:grid;
grid-template-columns: auto auto;
column-gap:50px;
grid-template-areas:
"create delete";
}.listTitle{
min-width:380px;
display: flex;
justify-content: center;
align-items: center;
width:25%;
margin-left:auto;
margin-right:auto;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;
margin-bottom:10px;
button:hover{
opacity:0.8;
}
}
</style> </style>

View File

@ -7,7 +7,6 @@
import {toast} from 'vue3-toastify' import {toast} from 'vue3-toastify'
import 'vue3-toastify/dist/index.css'; import 'vue3-toastify/dist/index.css';
import {createExternalCurriculum} from "@/rest/externalCurriculum.js"; import {createExternalCurriculum} from "@/rest/externalCurriculum.js";
import ManageCourses from "@/Apps/ManageCourses.vue";
import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue"; import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue";
const loginPage= ref(true) const loginPage= ref(true)
@ -25,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([]);
@ -45,9 +32,6 @@
const imageSaved = ref(false) const imageSaved = ref(false)
let ppData = "" let ppData = ""
let requiredCertif = false
//Contains the id of the newly created request (useful to link the student's formations informations to the request)
let requestId = ""
const idcardfile = ref({}) const idcardfile = ref({})
const justifcardfile = ref({}) const justifcardfile = ref({})
@ -108,13 +92,13 @@
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); 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);
} }
} }
</script> </script>
<template> <template>
<div class="setup" v-if="page !== 4"> <div class="setup" v-if="page !== 4">
<div v-if="loginPage"> <div v-if="loginPage">
@ -135,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>
@ -193,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">
@ -207,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++;">
@ -223,31 +205,30 @@
</div> </div>
</div> </div>
<div v-if="page === 2"> <div v-if="page === 2">
<p style="color:rgb(239,60,168);">Carte d'indentité :</p> <p style="color:rgb(239,60,168);">{{i18n("login.guest.identityCard")}}</p>
<label class="browser"> <label class="browser">
Parcourir . . . {{i18n("login.guest.browse")}}
<input type="file" @change="idcardfile = $event.target.files"> <input type="file" @change="idcardfile = $event.target.files">
</label> </label>
<div v-if="curricula[outputs.curriculum-1].requireCertificate === true" style="margin-top: 3%; margin-bottom: 4%"> <div v-if="curricula[outputs.curriculum-1].requireCertificate === true" style="margin-top: 3%; margin-bottom: 4%">
<p style="color:rgb(239,60,168);">Ce cursus requiert une attestation de réussite d'un examen d'entrée</p> <p style="color:rgb(239,60,168);">{{ i18n("login.guest.attestationdisclaimer") }}</p>
<div style="margin-top: 2%"> <div style="margin-top: 2%">
<p style="color:rgb(239,60,168);">Attestation:</p> <p style="color:rgb(239,60,168);">Attestation:</p>
<label class="browser"> <label class="browser">
Parcourir . . . {{i18n("login.guest.browse")}}
<input type="file" @change="justifcardfile = $event.target.files"> <input type="file" @change="justifcardfile = $event.target.files">
</label> </label>
</div> </div>
</div> </div>
<button @click="page++;">{{i18n("login.guest.nextpage")}}</button> <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++">Gèrer mon parcours extérieur</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> </div>
</form> </form>
</div> </div>
@ -255,7 +236,7 @@
</div> </div>
<div v-if="page===4"> <div v-if="page===4">
<ExternalCurriculumList v-model="externalCurrTab" :mode="2"></ExternalCurriculumList> <ExternalCurriculumList v-model="externalCurrTab" :mode="2"></ExternalCurriculumList>
<button style="margin-top: 2%;width: 5%; margin-left: 2%" @click="page--">Back</button> <button style="margin-top: 2%;width: 5%; margin-left: 2%" @click="page--">{{i18n("courses.back")}}</button>
</div> </div>
</template> </template>
@ -306,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{
@ -335,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

@ -1,7 +1,14 @@
<!----------------------------------------------------
File: LessonRequests.vue
Author: William Karpinski
Scope: Extension Horaire
Description: Lessons Management Page for the teachers
----------------------------------------------------->
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import i18n from '@/i18n.js' import i18n from '@/i18n.js'
import {formatDate,getHoursMinutes,sortByDate} from '../scheduleFunctions.js' import {formatDate,invertedFormatDate,getHoursMinutes,sortByDate, createLessonEvent} from '../scheduleFunctions.js'
import {getOwnedLessons} from "@/rest/lessonSchedule.js"; import {getOwnedLessons} from "@/rest/lessonSchedule.js";
import {getSelf} from "@/rest/Users.js"; import {getSelf} from "@/rest/Users.js";
import {createRequest} from "@/rest/LessonRequests.js" import {createRequest} from "@/rest/LessonRequests.js"
@ -21,6 +28,14 @@ const currentDate = new Date();
const types = ["TP","TD","Course","Exam"]; const types = ["TP","TD","Course","Exam"];
const colors = {"TP":"rgb(36,175,255)","TD":"rgb(255,36,175)","Exam":"rgb(175,255,36)","Course":"rgb(255,36,175)"} const colors = {"TP":"rgb(36,175,255)","TD":"rgb(255,36,175)","Exam":"rgb(175,255,36)","Course":"rgb(255,36,175)"}
const courses = ref(); const courses = ref();
const maxDate = ref(invertedFormatDate(new Date([currentDate.getMonth()<7 ? currentDate.getFullYear() : (currentDate.getFullYear())+1],7,31)));
const minDate = ref(invertedFormatDate((new Date()).setDate(currentDate.getDate()+1)))
/*
* Checks if a lesson is in the future or not
*/
function inFuture(lesson){ function inFuture(lesson){
let toCompare = new Date(lesson.lessonStart); let toCompare = new Date(lesson.lessonStart);
let current = new Date(); let current = new Date();
@ -31,28 +46,6 @@ function inFuture(lesson){
async function setCourses(){ async function setCourses(){
courses.value = (await getcurriculum(curriculum.value.curriculumId)).courses courses.value = (await getcurriculum(curriculum.value.curriculumId)).courses
} }
function invertedFormatDate(date) {
var d = new Date(date),
month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear();
if (month.length < 2)
month = '0' + month;
if (day.length < 2)
day = '0' + day;
return [year, month, day].join('-');
}
function createLessonEvent(date,hour){
const str = date.concat(' ',hour);
return new Date(str);
}
const maxDate = ref(invertedFormatDate(new Date([currentDate.getMonth()<7 ? currentDate.getFullYear() : (currentDate.getFullYear())+1],7,31)));
const minDate = ref(invertedFormatDate((new Date()).setDate(currentDate.getDate()+1)))
const pattern = { const pattern = {
"lessonId":null, "lessonId":null,
@ -62,8 +55,6 @@ const pattern = {
"lessonEnd": null, "lessonEnd": null,
"lessonType": null, "lessonType": null,
} }
const patternRequest ={ const patternRequest ={
"user": user.regNo, "user": user.regNo,
"state": "Pending", "state": "Pending",
@ -91,6 +82,9 @@ function setCreate(){
createMod.value = !createMod.value; createMod.value = !createMod.value;
} }
/*
* Constructs a request and posts it
*/
async function createLessonRequest(){ async function createLessonRequest(){
if(requestType.value === 0 || requestType.value === 1){ if(requestType.value === 0 || requestType.value === 1){
//modify //modify
@ -121,7 +115,12 @@ async function createLessonRequest(){
editElementID.value = ''; editElementID.value = '';
} }
/*
* Creates a request of a certain type
* 0 = CREATE REQUEST
* 1 = MODIFY REQUEST
* 2 = DELETE REQUEST
*/
async function askChanges(i){ async function askChanges(i){
requestType.value= i; requestType.value= i;
await createLessonRequest() await createLessonRequest()
@ -135,33 +134,33 @@ async function askChanges(i){
<div v-if="createMod"> <div v-if="createMod">
<form class="listElement" style="width:40%; margin:0 auto 0 auto;"> <form class="listElement" style="width:40%; margin:0 auto 0 auto;">
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
Schedule : {{i18n("schedule")}} :
<select @change="setCourses()"v-model="curriculum"> <select @change="setCourses()"v-model="curriculum">
<option v-for="item in allSchedules" :value='item.curriculum'>{{item.curriculum.option}}</option> <option v-for="item in allSchedules" :value='item.curriculum'>{{item.curriculum.option}}</option>
</select> </select>
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
Lesson : {{i18n("course")}}:
<select v-if="curriculum != null" v-model="toModify.course"> <select v-if="curriculum != null" v-model="toModify.course">
<option v-for="item in courses" :value='item.courseId'>{{item.title}}</option> <option v-for="item in courses" :value='item.courseId'>{{item.title}}</option>
</select> </select>
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
Day: {{i18n("day")}}:
<input type="date" :min="minDate" :max="maxDate" v-model="toModify.day"> <input type="date" :min="minDate" :max="maxDate" v-model="toModify.day">
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
Start: {{i18n("start")}}:
<input v-model="toModify.lessonStart" type="time" min="08:00" max="18:00" required /> <input v-model="toModify.lessonStart" type="time" min="08:00" max="18:00" required />
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
End: {{i18n("end")}}:
<input v-model="toModify.lessonEnd" type="time" min="10:00" max="20:00" required /> <input v-model="toModify.lessonEnd" type="time" min="10:00" max="20:00" required />
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
Type: Type:
<select v-model="toModify.lessonType"> <select v-model="toModify.lessonType">
<option v-for="item in types" :value='item'>{{item}}</option> <option v-for="item in types" :value='item'>{{i18n(item)}}</option>
</select> </select>
</div> </div>
@ -174,11 +173,11 @@ async function askChanges(i){
<button v-if="!createMod" @click="setCreate()" style="display:flex; margin:0 auto 0 auto;">Ask Create Request</button> <button v-if="!createMod" @click="setCreate()" style="display:flex; margin:0 auto 0 auto;">{{i18n("schedule.askCreate")}}</button>
<div v-if="!createMod"v-for="element in schedule" style="width:50%;margin-left:auto; margin-right:auto;" > <div v-if="!createMod"v-for="element in schedule" style="width:50%;margin-left:auto; margin-right:auto;" >
<div v-if="editElementID !== element.lessonID" style ="padding:15px 15px 15px 15px;"> <div v-if="editElementID !== element.lessonID" style ="padding:15px 15px 15px 15px;">
<button v-if="inFuture(element)" @click="editElementID = element.lessonID;setModify(element);"> <button v-if="inFuture(element)" @click="editElementID = element.lessonID;setModify(element);">
Ask Changes {{i18n("schedule.askChanges")}}
</button> </button>
</div> </div>
<div v-else> <div v-else>
@ -194,34 +193,34 @@ async function askChanges(i){
<div>{{getHoursMinutes(element.lessonStart)}}-{{getHoursMinutes(element.lessonEnd)}} <div>{{getHoursMinutes(element.lessonStart)}}-{{getHoursMinutes(element.lessonEnd)}}
</div> </div>
<div>{{element.local}}</div> <div>{{element.local}}</div>
<div>{{element.lessonType}}</div> <div>{{i18n(element.lessonType)}}</div>
</div> </div>
<div v-else> <div v-else>
<div>{{element.course.title}}</div> <div>{{element.course.title}}</div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
Day: {{i18n("day")}}:
<input type="date" :min="minDate" :max="maxDate" v-model="toModify.day"> <input type="date" :min="minDate" :max="maxDate" v-model="toModify.day">
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
Start: {{i18n("start")}}:
<input v-model="toModify.lessonStart" type="time" min="8:00" max="20:00"/> <input v-model="toModify.lessonStart" type="time" min="8:00" max="20:00"/>
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
End: {{i18n("end")}}:
<input v-model="toModify.lessonEnd" type="time" min="10:00" max="20:00" required /> <input v-model="toModify.lessonEnd" type="time" min="10:00" max="20:00" required />
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
Type: {{i18n("Type")}}:
<select v-model="toModify.lessonType"> <select v-model="toModify.lessonType">
<option v-for="item in types" :value='item'>{{item}}</option> <option v-for="item in types" :value='item'>{{i18n(item)}}</option>
</select> </select>
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
Local: Local:
{{element.local}} {{element.local}}
<div style="float:right;"> <div style="float:right;">
<button @click="askChanges(2)" class="delete"> ask Deletion </button> <button @click="askChanges(2)" class="delete"> {{i18n("schedule.askDeletion")}} </button>
</div> </div>
</div> </div>
@ -260,7 +259,7 @@ input, select{
} }
button{ button{
font-size:15px; font-size:15px;
height:50px; height:auto;
width:100px; width:100px;
border:none; border:none;
border-radius:20px; border-radius:20px;

View File

@ -1,11 +1,20 @@
<!----------------------------------------------------
File: LessonRequests.vue
Author: William Karpinski
Scope: Extension Horaire
Description: Lessons Management Page for the secretary
----------------------------------------------------->
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import i18n from '@/i18n.js' import i18n from '@/i18n.js'
import {formatDate,getHoursMinutes} from '../scheduleFunctions.js' import {formatDate,getHoursMinutes, invertedFormatDate, createLessonEvent} from '../scheduleFunctions.js'
import {getAllSchedule, deleteLessonFromSchedule ,getSchedule, getCurriculumSchedule,addLessonToSchedule} from "@/rest/scheduleRest.js"; import {getAllSchedule, deleteLessonFromSchedule ,getSchedule, createSchedule} from "@/rest/scheduleRest.js";
import {getLessons , createLesson, alterLesson , deleteLesson} from "@/rest/lessonSchedule.js" import {getLessons, createLesson, alterLesson, deleteLesson} from "@/rest/lessonSchedule.js"
import {getTeachers} from "@/rest/Users.js" import {getTeachers} from "@/rest/Users.js"
import { getcurriculum} from "@/rest/curriculum.js" import {getcurriculum, getAllCurriculums} from "@/rest/curriculum.js"
const trueSchedule = ref() const trueSchedule = ref()
const schedule = ref(); const schedule = ref();
@ -18,41 +27,22 @@ import i18n from '@/i18n.js'
const types = ["TP","TD","Course","Exam"]; const types = ["TP","TD","Course","Exam"];
const locals = ["A0B1","A1B1","A2B1","A0B2"] const locals = ["A0B1","A1B1","A2B1","A0B2"]
const teachers = await getTeachers() ; const teachers = await getTeachers() ;
const allCurriculum = ref();
const courses = ref(); const courses = ref();
const createScheduleMod = ref(false);
const createMod = ref(false); const createMod = ref(false);
const deleteMod = ref(false); const deleteMod = ref(false);
const colors = {"TP":"rgb(36,175,255)","TD":"rgb(255,36,175)","Exam":"rgb(175,255,36)","Course":"rgb(255,36,175)"} const colors = {"TP":"rgb(36,175,255)","TD":"rgb(255,36,175)","Exam":"rgb(175,255,36)","Course":"rgb(255,36,175)"}
const currentDate = new Date(); const currentDate = new Date();
const editElementID = ref() const editElementID = ref();
function invertedFormatDate(date) {
var d = new Date(date),
month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear();
if (month.length < 2)
month = '0' + month;
if (day.length < 2)
day = '0' + day;
return [year, month, day].join('-');
}
const maxDate = ref(invertedFormatDate(new Date([currentDate.getMonth()<7 ? currentDate.getFullYear() : (currentDate.getFullYear())+1],7,31))); const maxDate = ref(invertedFormatDate(new Date([currentDate.getMonth()<7 ? currentDate.getFullYear() : (currentDate.getFullYear())+1],7,31)));
const minDate = ref(invertedFormatDate((new Date()).setDate(currentDate.getDate()+1))) const minDate = ref(invertedFormatDate((new Date()).setDate(currentDate.getDate()+1)))
function createLessonEvent(date,hour){
const str = date.concat(' ',hour);
return new Date(str);
}
const pattern = { const pattern = {
"course": null, "course": null,
@ -80,7 +70,34 @@ function createLessonEvent(date,hour){
"local":null, "local":null,
"lessonType":null, "lessonType":null,
} }
/*
* Sets up allCurriculum to contain only the curriculums that don't have any schedule
*/
async function setCurriculum(){
const temp = await getAllCurriculums();
let isIn = false;
let toReturn =[] ;
for (let element in temp){
for (let item in allSchedules.value){
console.log(allSchedules.value[item])
console.log(temp[element])
if((allSchedules.value[item].curriculum.option == temp[element].option) && (allSchedules.value[item].curriculum.year == temp[element].year)){
isIn = true;
break;
}
}
if(!isIn){
toReturn.push(temp[element])
}
isIn = false;
}
allCurriculum.value = toReturn.slice();
}
const toModify = ref(Object.assign({}, pattern)); const toModify = ref(Object.assign({}, pattern));
const lessonBuffer = ref(Object.assign({}, pattern)); const lessonBuffer = ref(Object.assign({}, pattern));
const lessonCreatorBuffer = ref(Object.assign({},lessonCreator)); const lessonCreatorBuffer = ref(Object.assign({},lessonCreator));
@ -104,6 +121,9 @@ async function setCourses(){
courses.value = (await getcurriculum(curriculum.value.curriculumId)).courses courses.value = (await getcurriculum(curriculum.value.curriculumId)).courses
} }
/*
* Sort the lessons via a criteria
*/
function sortSchedule(){ function sortSchedule(){
schedule.value =trueSchedule.value.lessons; schedule.value =trueSchedule.value.lessons;
if(filter.value =="Teacher"){ if(filter.value =="Teacher"){
@ -157,7 +177,9 @@ async function setCourses(){
return matrix return matrix
} }
/*
* Change the schedule filter
*/
async function changeSchedule(){ async function changeSchedule(){
schedule.value =trueSchedule.value.lessons; schedule.value =trueSchedule.value.lessons;
curriculum.value = trueSchedule.value.curriculum; curriculum.value = trueSchedule.value.curriculum;
@ -203,6 +225,10 @@ async function setCourses(){
} }
/*
* Modify a lesson
*/
async function patchLesson(lesson){ async function patchLesson(lesson){
for (let element in toModify.value){ for (let element in toModify.value){
@ -246,44 +272,53 @@ async function patchLesson(lesson){
editElementID.value= ''; editElementID.value= '';
} }
/*
* Create a new Schedule
*/
async function newSchedule(){
await createSchedule(curriculum.value);
allSchedules.value = await getAllSchedule();
setCurriculum();
}
</script> </script>
<template> <template>
<div class="body"> <div class="body">
<div class="listTitle buttonGrid"v-if="!createMod" > <div class="listTitle buttonGrid"v-if="!createMod && !createScheduleMod" >
<button class="create" @click="createMod = true;">Create</button> <button class="create" @click="setCurriculum();createScheduleMod = true"> {{i18n("schedule.createSchedule")}}</button>
<button class="delete" @click="deleteMod = !deleteMod;">{{!deleteMod ? "Delete" : "Remove Delete"}}</button> <button class="create" @click="createMod = true;">{{i18n("schedule.createLesson")}}</button>
<button class="delete" @click="deleteMod = !deleteMod;">{{!deleteMod ? i18n("schedule.deleteMod") : i18n("schedule.noDeleteMod")}}</button>
</div> </div>
<div v-if="createMod"> <div v-if="createMod">
<form class="listElement" style="width:40%; margin:0 auto 0 auto;"> <form class="listElement" style="width:40%; margin:0 auto 0 auto;">
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
Schedule : {{i18n("schedule")}} :
<select @change="setCourses()"v-model="curriculum"> <select @change="setCourses()"v-model="curriculum">
<option v-for="item in allSchedules" :value='item.curriculum'>{{item.curriculum.option}}</option> <option v-for="item in allSchedules" :value='item.curriculum'>{{item.curriculum.option}} - {{item.curriculum.year}}</option>
</select> </select>
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
Lesson : {{i18n("Course")}} :
<select v-if="curriculum != null" v-model="lessonBuffer.course"> <select v-if="curriculum != null" v-model="lessonBuffer.course">
<option v-for="item in courses" :value='item'>{{item.title}}</option> <option v-for="item in courses" :value='item'>{{item.title}}</option>
</select> </select>
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
Day: {{i18n("day")}}:
<input type="date" :min="minDate" :max="maxDate" v-model="lessonBuffer.day"> <input type="date" :min="minDate" :max="maxDate" v-model="lessonBuffer.day">
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
Start: {{i18n("start")}}:
<input v-model="lessonBuffer.lessonStart" type="time" min="08:00" max="18:00" required /> <input v-model="lessonBuffer.lessonStart" type="time" min="08:00" max="18:00" required />
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
End: {{i18n("end")}}:
<input v-model="lessonBuffer.lessonEnd" type="time" min="10:00" max="20:00" required /> <input v-model="lessonBuffer.lessonEnd" type="time" min="10:00" max="20:00" required />
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
Type: Type:
<select v-model="lessonBuffer.lessonType"> <select v-model="lessonBuffer.lessonType">
<option v-for="item in types" :value='item'>{{item}}</option> <option v-for="item in types" :value='item'>{{item}}</option>
</select> </select>
@ -293,27 +328,35 @@ async function patchLesson(lesson){
<select v-model="lessonBuffer.local"> <select v-model="lessonBuffer.local">
<option v-for="item in locals" :value='item'>{{item}}</option> <option v-for="item in locals" :value='item'>{{item}}</option>
</select> </select>
</div> </div>
<div></div>
<button class="create" @click="createMod=!createMod; newLesson();"> {{i18n("courses.confirm")}} </button> <button class="create" @click="createMod=!createMod; newLesson();"> {{i18n("courses.confirm")}} </button>
<button style="float:right;" @click="createMod=!createMod">{{i18n("courses.back")}}</button> <button style="float:right;" @click="createMod=!createMod">{{i18n("courses.back")}}</button>
</form> </form>
</div> </div>
<div v-if="createScheduleMod">
<form class="listElement" style="width:40%; margin:0 auto 0 auto;">
<div style="margin-bottom:20px;">
{{i18n("schedule")}} :
<select v-model="curriculum">
<option v-for="item in allCurriculum" :value='item'>{{item.option}} - {{item.year}}</option>
</select>
</div>
<button class="create" @click="createScheduleMod=!createScheduleMod ;newSchedule();"> {{i18n("courses.confirm")}} </button>
<button style="float:right;" @click="createScheduleMod=!createScheduleMod;">{{i18n("courses.back")}}</button>
</form>
</div>
<div v-if="!createMod">
<div v-if="!createMod && !createScheduleMod">
<select @change="changeSchedule()" v-model="trueSchedule"> <select @change="changeSchedule()" v-model="trueSchedule">
<option v-for="item in allSchedules" :value='item'>{{item.curriculum.option}}</option> <option v-for="item in allSchedules" :value='item'>{{item.curriculum.option}} - {{item.curriculum.year}}</option>
</select> </select>
<select v-if="schedule != null" @change="subFilter = 'null'" v-model="filter"> <select v-if="schedule != null" @change="subFilter = 'null'" v-model="filter">
<option :value ="null">No Filter</option> <option :value ="null">No Filter</option>
<option v-for="item in filters" :value="item">{{item}}</option> <option v-for="item in filters" :value="item">{{i18n(item.toString())}}</option>
</select> </select>
<select @change="sortSchedule()" v-if="filter == 'Teacher'" v-model="subFilter"> <select @change="sortSchedule()" v-if="filter == 'Teacher'" v-model="subFilter">
<option :value ="null">No Filter</option> <option :value ="null">No Filter</option>
@ -329,7 +372,7 @@ async function patchLesson(lesson){
</select> </select>
</div> </div>
<div v-if="!createMod " :key="element.lessonID" v-for="element in schedule" style="width:50%;margin-left:auto; margin-right:auto;" > <div v-if="!createMod && !createScheduleMod" :key="element.lessonID" v-for="element in schedule" style="width:50%;margin-left:auto; margin-right:auto;" >
<div v-if="editElementID !== element.lessonID" style ="padding:15px 15px 15px 15px;"> <div v-if="editElementID !== element.lessonID" style ="padding:15px 15px 15px 15px;">
<button v-if="inFuture(element)" @click="editElementID = element.lessonID;setModify(element);"> <button v-if="inFuture(element)" @click="editElementID = element.lessonID;setModify(element);">
{{i18n("courses.modify")}} {{i18n("courses.modify")}}
@ -385,8 +428,6 @@ async function patchLesson(lesson){
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<style scoped> <style scoped>
.body { .body {

View File

@ -197,8 +197,8 @@
</script> </script>
<template> <template>
<div class="body" v-if="windowState !== 12"> <div class="body" v-if="windowState !== 12 && windowState!==4">
<div class="container" v-if="windowState!==4"> <div class="container">
<div class="profilPic" v-if="windowState===0"> <div class="profilPic" v-if="windowState===0">
<img class="subContainter" :src=getPP()> <img class="subContainter" :src=getPP()>
</div> </div>
@ -208,93 +208,100 @@
{{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="windowState=1; 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="windowState=3">{{i18n("profile.reRegister")}}</button>
<button @click="windowState=9" style="float:right;background-color:rgb(150,0,0);">{{i18n("profile.unRegister")}}</button> <button @click="windowState=9" style="float:right;background-color:rgb(150,0,0);">{{i18n("profile.unRegister")}}</button>
</div> </div>
<div v-if="(user.role==='Student')"> <div v-if="(user.role==='Student')">
<button @click="windowState=2">{{i18n("profile.change.curriculum")}}</button> <button @click="windowState=2">{{i18n("profile.change.curriculum")}}</button>
<button @click="windowState=12;refreshExtCurrList() ">Manage external curriculums</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="windowState=4">Manage Courses</button> <button @click="windowState=4">{{ i18n("managecourse") }}</button>
<button @click="windowState=5" 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="windowState === 9" class="infosContainer"> <div v-else-if="windowState === 9" class="infosContainer">
<div v-if="sure !== 2">Please enter the reason you leave</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">
I only want to unregister from a specific cursus {{i18n("onlycursus")}}
<input type="checkbox" v-model="isChecked"> <input type="checkbox" v-model="isChecked">
</div> </div>
<div v-if="sure !== 2 && isChecked"> <div v-if="sure !== 2 && isChecked">
Please select that cursus {{ i18n("plsselectcurs") }}
<select v-model="uninscriptionData.curriculumId"> <select v-model="uninscriptionData.curriculumId">
<option v-for="item in getActualCurriculumList()" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option> <option v-for="item in getActualCurriculumList()" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select> </select>
</div> </div>
<div v-if="sure !== 2"> <div v-if="sure !== 2">
<button @click="sure++">Submit</button> <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, uninscriptionData.curriculumId);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 v-if="windowState === 9">
<button @click="windowState=0">{{i18n("courses.back")}}</button>
</div> </div>
<div v-else-if="windowState === 5" class="infosContainer"> <div v-else-if="windowState === 5" class="infosContainer">
<div v-if="minerv.value.toPay !== 0"> <div v-if="minerv.value.toPay !== 0">
Payment : {{minerv.value.toPay}} left to pay {{ i18n("payment") }} : {{minerv.value.toPay}} {{ i18n("lefttopay") }}
<div v-if="minerv.value.paidAmount <= 50"> <div v-if="minerv.value.paidAmount <= 50">
<button @click="windowState=6; paymentAmount = 50">Pay deposit (50)</button> <button @click="windowState=6; paymentAmount = 50">{{ i18n("paydeposit") }} (50)</button>
</div> </div>
<div> <div>
<button @click="windowState=6; 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="windowState=7">Ask for a scholarship</button> <button @click="windowState=7">{{ i18n("askscholarship") }}</button>
</div> </div>
</div> </div>
<div v-if="windowState === 5">
<button @click="windowState=0">{{ i18n("courses.back") }}</button>
</div>
<div v-else-if="windowState === 7" class="infosContainer"> <div v-else-if="windowState === 7" class="infosContainer">
<p>Please upload the required documents</p> <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="windowState=8;postScholarshipRequest(scholarshipData.taxDocUrl, 'JustificationDocument',scholarshipData.residencyDocUrl, 'JustificationDocument');">Submit scholarship request</button> <button style="margin-top: 5%" @click="windowState=8;postScholarshipRequest(scholarshipData.taxDocUrl, 'JustificationDocument',scholarshipData.residencyDocUrl, 'JustificationDocument');">{{i18n("login.guest.submit")}}</button>
</div>
<div v-if="windowState === 7">
<button @click="windowState = 5">{{ i18n("courses.back") }}</button>
</div> </div>
<div v-else-if="windowState === 8" class="infosContainer"> <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="windowState = 0"> <button @click="windowState = 0">
Go back to profile {{ i18n("backprofile") }}
</button> </button>
</div> </div>
<div v-else-if="windowState === 6" 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">
@ -308,10 +315,10 @@
<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="windowState=5;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="windowState = 5">Back</button> <button @click="windowState = 5">{{ i18n("courses.back") }}</button>
</div> </div>
</div> </div>
<div v-else-if="windowState === 1" class="infosContainer"> <div v-else-if="windowState === 1" class="infosContainer">
@ -320,7 +327,7 @@
<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="email" v-model="toModify.email" /> <input type="email" v-model="toModify.email" />
</div> </div>
<div> <div>
@ -342,11 +349,11 @@
</div> </div>
<div v-else-if="windowState === 2" class="infosContainer"> <div v-else-if="windowState === 2" class="infosContainer">
<div> <div>
I would like to : {{ i18n("iwouldlike") }}
<select v-model="reRegState"> <select v-model="reRegState">
<option :value="1">Reregister in the next year of one of my cursus</option> <option :value="1">{{ i18n("rereg") }}</option>
<option :value="2">Register for a supplementary cursus</option> <option :value="2">{{ i18n("reregsup") }}</option>
<option :value="3">Change from a cursus to another</option> <option :value="3">{{ i18n("chcur") }}</option>
</select> </select>
</div> </div>
<div style="height:40px;" v-if="reRegState === 3"> <div style="height:40px;" v-if="reRegState === 3">
@ -354,90 +361,66 @@
<select v-model="changecurrdata.actualcursus" style="margin-right: 3%"> <select v-model="changecurrdata.actualcursus" style="margin-right: 3%">
<option v-for="item in getActualCurriculumList()" style="font-size:20px;" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option> <option v-for="item in getActualCurriculumList()" style="font-size:20px;" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select> </select>
New Curriculum : {{ i18n("newcurr") }} :
<select v-model="changecurrdata.newcursus"> <select v-model="changecurrdata.newcursus">
<option v-for="item in curricula" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option> <option v-for="item in curricula" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select> </select>
</div> </div>
<div style="height:40px;" v-if="reRegState === 2"> <div style="height:40px;" v-if="reRegState === 2">
New Curriculum : {{ i18n("newcurr") }} :
<select v-model="changecurrdata.newcursus"> <select v-model="changecurrdata.newcursus">
<option v-for="item in curricula" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option> <option v-for="item in curricula" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select> </select>
</div> </div>
<div style="height:40px;" v-if="reRegState === 1"> <div style="height:40px;" v-if="reRegState === 1">
New Curriculum : {{ i18n("newcurr") }} :
<select v-model="changecurrdata.newcursus" @change="getActualCurr(changecurrdata.newcursus);"> <select v-model="changecurrdata.newcursus" @change="getActualCurr(changecurrdata.newcursus);">
<option v-for="item in getCurriculumsNextYear()" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option> <option v-for="item in getCurriculumsNextYear()" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
</select> </select>
</div> </div>
<div v-if="curricula[changecurrdata.newcursus-1].year > 1 && reRegState !== 1"> <div v-if="curricula[changecurrdata.newcursus-1].year > 1 && reRegState !== 1">
The cursus you selected has some prerequisites {{i18n("cursusprereq")}}
</div> </div>
<div> <div>
<button @click=" windowState = 0;postChangeCurrReq(changecurrdata);changecurrdata.actualcursus=null;changecurrdata.newcursus=1">{{i18n("courses.confirm")}}</button> <button @click=" windowState = 0;postChangeCurrReq(changecurrdata);changecurrdata.actualcursus=null;changecurrdata.newcursus=1">{{i18n("courses.confirm")}}</button>
<button @click="windowState = 0; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button> <button @click="windowState = 0; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button>
</div> </div>
</div> </div>
<div v-else-if="windowState === 3" class="infosContainer">
<div>
E-mail:
<input type="email" v-model="toModify.email" />
</div>
<div>
ID :
<input type="text" v-model="toModify.id">
</div>
<div>
{{i18n("login.password")}}:
<input type="password" v-model="toModify.password">
</div>
<div>
{{i18n("login.cPassword")}}:
<input type="password" id="confirm">
</div>
<div>
<button @click=" windowState=0;">{{i18n("courses.confirm")}}</button>
<button @click=" windowState=0; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button>
</div>
</div>
</div> </div>
<div v-if="windowState === 0" 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="item.actual === false">Bac {{item.year}}</div> <div class="year" v-if="item.actual === false">Bac {{item.year}}</div>
<div class="option" v-if="item.actual === false">{{item.option}}</div> <div class="option" v-if="item.actual === false">{{item.option}}</div>
<div class="dateyear" v-if="item.actual === false">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="item.actual === true">Bac {{item.year}}</div> <div class="year" v-if="item.actual === true">Bac {{item.year}}</div>
<div class="option" v-if="item.actual === true">{{item.option}}</div> <div class="option" v-if="item.actual === true">{{item.option}}</div>
<div class="dateyear" v-if="item.actual === true">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="windowState===4" style="width: 80%">
<CourseList :cursuslist="getActualCurriculumList()"/>
<button style="width: 10%; margin-top: 5%" @click="windowState = 0">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"> <div v-if="windowState === 12">
<ExternalCurriculumList :ext-curr-list="extcurrlist" :mode="1"></ExternalCurriculumList> <ExternalCurriculumList :ext-curr-list="extcurrlist" :mode="1"></ExternalCurriculumList>
<button @click="windowState = 0;refreshExtCurrList()">Back to profile</button> <button @click="windowState = 0;refreshExtCurrList()" style="margin-left: 17%;margin-top: 3%">{{ i18n("backprofile") }}</button>
</div> </div>
</template> </template>
<style scoped> <style scoped>
@ -548,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

@ -1,9 +1,20 @@
<!----------------------------------------------------
File: Schedule.vue
Author: William Karpinski
Scope: Extension Horaire
Description: Schedules Page accessed by everyone
----------------------------------------------------->
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import {getDifferenceTime,lastDateOfMonth,formatDate,getFirstDay,sortByDate,matrixFromList,sundayToTheEnd,getMarginTop,getHoursMinutes, monthFromList} from '../scheduleFunctions.js' import {getDifferenceTime,lastDateOfMonth,formatDate,getFirstDay,sortByDate,weekFromList,sundayToTheEnd,getMarginTop,getHoursMinutes, monthFromList, durationCourse} from '../scheduleFunctions.js'
import {getAllSchedule} from "@/rest/scheduleRest.js"; import {getAllSchedule} from "@/rest/scheduleRest.js";
import {getOnesLessons, getOwnedLessons } from "@/rest/lessonSchedule.js" import {getOnesLessons, getOwnedLessons } from "@/rest/lessonSchedule.js"
import {isLogged, getSelf,getTeachers} from "@/rest/Users.js" import {isLogged, getSelf,getTeachers} from "@/rest/Users.js"
import {getUserActualCourses} from "@/rest/courses.js";
import {getcurriculum} from "@/rest/curriculum.js";
import i18n from "../i18n.js";
const trueSchedule = ref() const trueSchedule = ref()
const log = await isLogged(); const log = await isLogged();
@ -31,42 +42,40 @@
if(log){ if(log){
user = await getSelf(); user = await getSelf();
if(user.role == "Admin" || user.role == "Secretary" || user.role == "InscriptionService"){ if(user.role == "Teacher" || user.role == "Student"){
}
else{
if(user.role == "Teacher"){ if(user.role == "Teacher"){
ownSchedule.value = await getOwnedLessons(); ownSchedule.value = await getOwnedLessons();
} }
if(user.role == "Student"){ if(user.role == "Student"){
let test = await getUserActualCourses();
console.log(test);
ownSchedule.value = await getOnesLessons();} ownSchedule.value = await getOnesLessons();}
schedule.value = ownSchedule.value; schedule.value = ownSchedule.value;
schedule.value.sort((a,b) => sortByDate(a,b)); schedule.value.sort((a,b) => sortByDate(a,b));
scheduleByWeek.value = sundayToTheEnd(matrixFromList(schedule.value,mondayOfWeek.value)); scheduleByWeek.value = sundayToTheEnd(weekFromList(schedule.value,mondayOfWeek.value));
month.value = monthFromList(schedule.value,new Date().getMonth()); month.value = monthFromList(schedule.value,new Date().getMonth());
} }
} }
const display =ref("Week"); const display =ref("Week");
const format = ref("Grid"); const format = ref("Grid");
const filters = ["Type","Teacher","Course"]; const filters = ["Type","Teacher","Course"];
const types = ["TP","TD","Course","Exam"]; const types = ["TP","TD","Course","Exam"];
const teachers = await getTeachers() ; const teachers = await getTeachers() ;
const courses = ref(); const courses = ref();
if(curriculum.value != null){ if(curriculum.value != null){
courses.value = curriculum.value.courses; courses.value = curriculum.value.courses;
} }
const days = ["Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi","Dimanche"]; const days = ["monday","tuesday","wednesday","thursday","friday","saturday","sunday"];
const months = ["Janvier","Fevrier","Mars","Avril",'Mai',"Juin","Juillet","Aout","Septembre","Octobre","Novembre","Decembre"] const months = ["january","february","march","april",'may',"june","july","august","september","october","november","december"]
const firstDayOfMonth = ref(getFirstDay(new Date())) const firstDayOfMonth = ref(getFirstDay(new Date()))
const monthDone = ref(false); const monthDone = ref(false);
function getMonday(d) { function getMonday(d) {
@ -89,19 +98,9 @@
return (user.role == "Student" || user.role == "Teacher"); return (user.role == "Student" || user.role == "Teacher");
return false return false
} }
function isNotCourse(element){
return element==null;
}
function durationCourse(element){
const hour = element.lessonEnd.substring(3,5) -element.lessonStart.substring(3,5);
return (element.lessonEnd - element.lessonStart)%2;
}
function displayOwnSchedule(){ function displayOwnSchedule(){
schedule.value = ownSchedule.value; schedule.value = ownSchedule.value;
scheduleByWeek.value = sundayToTheEnd(matrixFromList(schedule.value,mondayOfWeek.value)); scheduleByWeek.value = sundayToTheEnd(weekFromList(schedule.value,mondayOfWeek.value));
month.value = monthFromList(schedule.value,currentDate.value.getMonth()); month.value = monthFromList(schedule.value,currentDate.value.getMonth());
value = 1; value = 1;
counter=0; counter=0;
@ -109,6 +108,9 @@
} }
/*
* Create a JSON from a schedule
*/
function createJSON(){ function createJSON(){
const json = {"data":[]}; const json = {"data":[]};
for(let element in schedule.value){ for(let element in schedule.value){
@ -122,6 +124,10 @@
return json return json
} }
/*
* Export a JSON
*/
function exportJSON(){ function exportJSON(){
let json = createJSON(); let json = createJSON();
const data = JSON.stringify(json); const data = JSON.stringify(json);
@ -132,6 +138,10 @@
a.click(); a.click();
} }
/*
* Used to convert a JSON imported to an object
*/
function onFileChange(e) { function onFileChange(e) {
let files = e.target.files || e.dataTransfer.files; let files = e.target.files || e.dataTransfer.files;
if (!files.length) return; if (!files.length) return;
@ -162,20 +172,25 @@
toEventList.push(temp); toEventList.push(temp);
} }
jsonSchedule.value = toEventList; jsonSchedule.value = toEventList;
scheduleByWeek.value = sundayToTheEnd(matrixFromList(jsonSchedule.value,mondayOfWeek.value)); scheduleByWeek.value = sundayToTheEnd(weekFromList(jsonSchedule.value,mondayOfWeek.value));
month.value = monthFromList(jsonSchedule.value,new Date().getMonth()); month.value = monthFromList(jsonSchedule.value,new Date().getMonth());
} }
/*
* Display the JSON on the schedule
*/
function switchToJSON(){ function switchToJSON(){
jsonMod.value = true; jsonMod.value = true;
scheduleByWeek.value = sundayToTheEnd(matrixFromList(jsonSchedule.value,mondayOfWeek.value)); scheduleByWeek.value = sundayToTheEnd(weekFromList(jsonSchedule.value,mondayOfWeek.value));
month.value = monthFromList(jsonSchedule.value,new Date().getMonth()); month.value = monthFromList(jsonSchedule.value,new Date().getMonth());
} }
/*
* used to focus on a lesson when we click on it
*/
function lessonFocus(element){ function lessonFocus(element){
if(!jsonMod.value){ if(!jsonMod.value){
focus.value = element; focus.value = element;
@ -188,7 +203,9 @@
focusLessons.value = lessonsList;} focusLessons.value = lessonsList;}
} }
/*
* convert the current date to a DATE object
*/
function dateOfMonth(i){ function dateOfMonth(i){
return new Date(currentDate.value.getFullYear(),currentDate.value.getMonth(),i); return new Date(currentDate.value.getFullYear(),currentDate.value.getMonth(),i);
@ -198,7 +215,7 @@
schedule.value =trueSchedule.value.lessons; schedule.value =trueSchedule.value.lessons;
if(filter.value =="Teacher"){ if(filter.value =="Teacher"){
schedule.value = sortByTeacher(schedule.value,subFilter.value); schedule.value = sortByTeacher(schedule.value,subFilter.value);
scheduleByWeek.value = sundayToTheEnd(matrixFromList(schedule.value,mondayOfWeek.value)); scheduleByWeek.value = sundayToTheEnd(weekFromList(schedule.value,mondayOfWeek.value));
month.value = monthFromList(schedule.value,currentDate.value.getMonth()); month.value = monthFromList(schedule.value,currentDate.value.getMonth());
value = 1; value = 1;
counter=0; counter=0;
@ -207,7 +224,7 @@
} }
else if(filter.value =="Type"){ else if(filter.value =="Type"){
schedule.value = sortByType(schedule.value,subFilter.value); schedule.value = sortByType(schedule.value,subFilter.value);
scheduleByWeek.value = sundayToTheEnd(matrixFromList(schedule.value,mondayOfWeek.value)); scheduleByWeek.value = sundayToTheEnd(weekFromList(schedule.value,mondayOfWeek.value));
month.value = monthFromList(schedule.value,currentDate.value.getMonth()); month.value = monthFromList(schedule.value,currentDate.value.getMonth());
value = 1; value = 1;
counter=0; counter=0;
@ -217,7 +234,7 @@
} }
else if(filter.value =="Course"){ else if(filter.value =="Course"){
schedule.value = sortByCourse(schedule.value,subFilter.value); schedule.value = sortByCourse(schedule.value,subFilter.value);
scheduleByWeek.value = sundayToTheEnd(matrixFromList(schedule.value,mondayOfWeek.value)); scheduleByWeek.value = sundayToTheEnd(weekFromList(schedule.value,mondayOfWeek.value));
month.value = monthFromList(schedule.value,currentDate.value.getMonth()); month.value = monthFromList(schedule.value,currentDate.value.getMonth());
value = 1; value = 1;
counter=0; counter=0;
@ -270,12 +287,14 @@
return matrix return matrix
} }
/*
* Change the schedule filter
*/
async function changeSchedule(){ async function changeSchedule(){
schedule.value =trueSchedule.value.lessons; schedule.value =trueSchedule.value.lessons;
curriculum.value = trueSchedule.value.curriculum; curriculum.value = trueSchedule.value.curriculum;
scheduleByWeek.value = sundayToTheEnd(matrixFromList(schedule.value,mondayOfWeek.value)); scheduleByWeek.value = sundayToTheEnd(weekFromList(schedule.value,mondayOfWeek.value));
month.value = monthFromList(schedule.value,currentDate.value.getMonth()); month.value = monthFromList(schedule.value,currentDate.value.getMonth());
value = 1; value = 1;
counter=0; counter=0;
@ -287,18 +306,23 @@
focusLessons.value = null; focusLessons.value = null;
jsonMod.value = false; jsonMod.value = false;
} }
/*
* change the week to display
*/
function changeWeek(i){ function changeWeek(i){
const temp = getAnyDays(i); const temp = getAnyDays(i);
mondayOfWeek.value = temp; mondayOfWeek.value = temp;
if(scheduleByWeek.value != null) if(scheduleByWeek.value != null)
if(jsonMod.value){ if(jsonMod.value){
scheduleByWeek.value = sundayToTheEnd(matrixFromList(jsonSchedule.value, mondayOfWeek.value))} scheduleByWeek.value = sundayToTheEnd(weekFromList(jsonSchedule.value, mondayOfWeek.value))}
else{ else{
scheduleByWeek.value = sundayToTheEnd(matrixFromList(schedule.value, mondayOfWeek.value))} scheduleByWeek.value = sundayToTheEnd(weekFromList(schedule.value, mondayOfWeek.value))}
} }
/*
* change the month to display
*/
function changeMonth(i){ function changeMonth(i){
const temp = currentDate.value; const temp = currentDate.value;
currentDate.value = new Date( ( 0< temp.getMonth()+i < 13 ? temp.getFullYear() : temp.getFullYear()+i), (0< temp.getMonth()+i <13 ? temp.getMonth()+i : 12 ),1); currentDate.value = new Date( ( 0< temp.getMonth()+i < 13 ? temp.getFullYear() : temp.getFullYear()+i), (0< temp.getMonth()+i <13 ? temp.getMonth()+i : 12 ),1);
@ -316,6 +340,9 @@
} }
/*
* used to display correctly the dates of a month
*/
function isAValue(){ function isAValue(){
if(value-shift.value<0 ){ if(value-shift.value<0 ){
@ -352,15 +379,15 @@
<table class="table"> <table class="table">
<tr style="background-color:rgb(24,24,24)"> <tr style="background-color:rgb(24,24,24)">
<th> <th>
<button @click="changeWeek(-7)">Previous</button> <button @click="changeWeek(-7)">{{i18n("schedule.previous")}}</button>
<button @click="changeWeek(7)">Next</button> <button @click="changeWeek(7)">{{i18n("schedule.next")}}</button>
<button @click="mondayOfWeek = getMonday(new Date()); <button @click="mondayOfWeek = getMonday(new Date());
scheduleByWeek != null ? scheduleByWeek = sundayToTheEnd(matrixFromList(schedule.value, mondayOfWeek)) : null;">Current</button> scheduleByWeek != null ? scheduleByWeek = sundayToTheEnd(weekFromList(schedule.value, mondayOfWeek)) : null;">{{i18n("schedule.current")}}</button>
</th> </th>
<th class="header" v-for='d,index in 7' > <th class="header" v-for='d,index in 7' >
<p class="childHeader"> <p class="childHeader">
{{days[index]}} {{i18n(days[index])}}
</p> </p>
<p class="childHeader"> <p class="childHeader">
{{formatDate(getAnyDays(index))}} {{formatDate(getAnyDays(index))}}
@ -404,16 +431,16 @@
<table class="table"> <table class="table">
<tr style="background-color:rgb(24,24,24); height:8.33%;"> <tr style="background-color:rgb(24,24,24); height:8.33%;">
<th colspan="7" class="header"> <th colspan="7" class="header">
<div>{{months[currentDate.getMonth()]}} {{currentDate.getFullYear()}}</div> <div>{{i18n(months[currentDate.getMonth()])}} {{currentDate.getFullYear()}}</div>
<button style="position:absolute; top:0; left:0;" @click="changeMonth(-1)">previous</button> <button style="position:absolute; top:0; left:0;" @click="changeMonth(-1)">{{i18n("schedule.previous")}}</button>
<button style="position:absolute; bottom:0; left:0;"@click="changeMonth(1)">next</button> <button style="position:absolute; bottom:0; left:0;"@click="changeMonth(1)">{{i18n("schedule.next")}}</button>
</th> </th>
</tr> </tr>
<tr style="background-color:rgb(24,24,24); height:8.33%;" > <tr style="background-color:rgb(24,24,24); height:8.33%;" >
<th class="header" v-for='d,index in 7' > <th class="header" v-for='d,index in 7' >
{{days[index]}} {{i18n(days[index])}}
</th> </th>
</tr> </tr>
<tr v-for="n in 5" style="height:16.67%;"> <tr v-for="n in 5" style="height:16.67%;">
@ -450,11 +477,11 @@
<button @click="changeWeek(-7)">Previous</button> <button @click="changeWeek(-7)">Previous</button>
<button @click="changeWeek(7)">Next</button> <button @click="changeWeek(7)">Next</button>
<button @click="mondayOfWeek = getMonday(new Date()); <button @click="mondayOfWeek = getMonday(new Date());
scheduleByWeek != null ? scheduleByWeek = sundayToTheEnd(matrixFromList(schedule.value, mondayOfWeek)) : null;">Current</button> scheduleByWeek != null ? scheduleByWeek = sundayToTheEnd(weekFromList(schedule.value, mondayOfWeek)) : null;">Current</button>
<template v-for="i,index in 7"> <template v-for="i,index in 7">
<div class="body" style="background-color:#181818;">{{days[index]}} {{formatDate(getAnyDays(index))}} <div class="body" style="background-color:#181818;">{{i18n(days[index])}} {{formatDate(getAnyDays(index))}}
</div> </div>
<template v-if="scheduleByWeek != null"> <template v-if="scheduleByWeek != null">
<div class="body" style="background-color:#353535;" > <div class="body" style="background-color:#353535;" >
@ -476,10 +503,10 @@
<div v-if="display == 'Month'"> <div v-if="display == 'Month'">
<button @click="changeMonth(-1)">Previous</button> <button @click="changeMonth(-1)">Previous</button>
<button @click="changeMonth(1)">Next</button> <button @click="changeMonth(1)">Next</button>
<div class="body" >{{months[currentDate.getMonth()]}} {{currentDate.getFullYear()}}</div> <div class="body" >{{i18n(months[currentDate.getMonth()])}} {{currentDate.getFullYear()}}</div>
<template v-for="i,index in lastDateOfMonth(currentDate.getMonth())-1"> <template v-for="i,index in lastDateOfMonth(currentDate.getMonth())-1">
<div class="body" style="background-color:#181818;">{{ dateOfMonth(i).getDay()-1== -1 ? days[6] : days[dateOfMonth(i).getDay()-1] }} {{formatDate(dateOfMonth(i))}} <div class="body" style="background-color:#181818;">{{ dateOfMonth(i).getDay()-1== -1 ? i18n(days[6]) : i18n(days[dateOfMonth(i).getDay()-1]) }} {{formatDate(dateOfMonth(i))}}
</div> </div>
<template v-if="scheduleByWeek != null"> <template v-if="scheduleByWeek != null">
<div class="body" style="background-color:#353535;" > <div class="body" style="background-color:#353535;" >
@ -502,20 +529,20 @@
<div class="options"> <div class="options">
<div class="settings"> <div class="settings">
<div class="body" style="background-color:rgb(50,50,50);margin:5% 0 5% 0;">Settings</div> <div class="body" style="background-color:rgb(50,50,50);margin:5% 0 5% 0;">{{i18n("schedule.settings")}}</div>
<select @change="changeSchedule()" v-model="trueSchedule"> <select @change="changeSchedule()" v-model="trueSchedule">
<option v-for="item in allSchedules" :value='item'>{{item.curriculum.option}}-{{item.curriculum.year}}</option> <option v-for="item in allSchedules" :value='item'>{{item.curriculum.option}}-{{item.curriculum.year}}</option>
</select> </select>
<button v-if="display=='Week'" @click="display='Month'">Week</button> <button v-if="display=='Week'" @click="display='Month'">{{i18n("Week")}}</button>
<button v-if="display=='Month'" @click="display='Week'; value=1;">Month</button> <button v-if="display=='Month'" @click="display='Week'; value=1;">{{i18("Month")}}</button>
<button v-if="format == 'Grid'" @click="format ='List'">Grid</button> <button v-if="format == 'Grid'" @click="format ='List'">{{i18n("Grid")}}</button>
<button v-if="format == 'List'" @click ="format = 'Grid'">List</button> <button v-if="format == 'List'" @click ="format = 'Grid'">{{i18n("List")}}</button>
<button v-if="verifUser()" @click="jsonMod=false ;displayOwnSchedule();">OwnSchedule</button> <button v-if="verifUser()" @click="jsonMod=false ;displayOwnSchedule();">{{i18n("OwnSchedule")}}</button>
<button v-if="importedJSON != null" @click="switchToJSON()">Switch to JSON FILE</button> <button v-if="importedJSON != null" @click="switchToJSON()">{{i18n("SwitchToJSON")}}</button>
<select v-if="schedule != null && !jsonMod" @change="subFilter = 'null'" v-model="filter"> <select v-if="schedule != null && !jsonMod" @change="subFilter = 'null'" v-model="filter">
<option :value ="null">No Filter</option> <option :value ="null">No Filter</option>
<option v-for="item in filters" :value="item">{{item}}</option> <option v-for="item in filters" :value="item">{{i18n(item)}}</option>
</select> </select>
<select @change="sortSchedule()" v-if="filter == 'Teacher'" v-model="subFilter"> <select @change="sortSchedule()" v-if="filter == 'Teacher'" v-model="subFilter">
<option :value ="null">No Filter</option> <option :value ="null">No Filter</option>
@ -527,7 +554,7 @@
</select> </select>
<select @change="sortSchedule()" v-if="filter == 'Type'" v-model="subFilter"> <select @change="sortSchedule()" v-if="filter == 'Type'" v-model="subFilter">
<option :value ="null">No Filter</option> <option :value ="null">No Filter</option>
<option v-for="item in types" :value='item'>{{item}}</option> <option v-for="item in types" :value='item'>{{i18n(item)}}</option>
</select> </select>
<button @click="exportJSON()" >Export JSON</button> <button @click="exportJSON()" >Export JSON</button>
@ -537,22 +564,22 @@
</div> </div>
<div v-if="focus != null && !jsonMod" class="moreInfos"> <div v-if="focus != null && !jsonMod" class="moreInfos">
<div class="body" style="background-color:rgb(50,50,50); height:10%; font-size:2em;" >More infos</div> <div class="body" style="background-color:rgb(50,50,50); height:10%; font-size:2em;" >{{i18n("request.moreInfos")}}</div>
<div class="body" :style="{background:focus.color,height:auto,fontSize:1.2+'em', alignItems:center}"> <div class="body" :style="{background:focus.color,height:auto,fontSize:1.2+'em', alignItems:center}">
{{focus.course.title}}</div> {{focus.course.title}}</div>
<div class="body" style="background-color:rgb(50,50,50);">Teacher(s)</div> <div class="body" style="background-color:rgb(50,50,50);">{{i18n("schedule.teachers")}}</div>
<div class="body" style="background-color:#484848;"> <div class="body" style="background-color:#484848;">
<div>{{focus.course.owner.lastName}}</div> <div>{{focus.course.owner.lastName}}</div>
<div v-for="element in focus.course.owner.assistants"> <div v-for="element in focus.course.assistants">
{{element.lastName}} {{element.lastName}}
</div> </div>
</div> </div>
<div class="body" style="background-color:rgb(50,50,50);">Lessons</div> <div class="body" style="background-color:rgb(50,50,50);">{{i18n("schedule.courses")}}</div>
<div class="body" style="background-color:#484848;"v-for="lesson in focusLessons"> <div class="body" style="background-color:#484848;"v-for="lesson in focusLessons">
{{ getHoursMinutes(lesson.lessonStart)}}-{{getHoursMinutes(lesson.lessonEnd)}} {{ getHoursMinutes(lesson.lessonStart)}}-{{getHoursMinutes(lesson.lessonEnd)}}
{{ lesson.local}} {{ lesson.local}}
{{lesson.lessonType}} {{i18n(lesson.lessonType.toString())}}
</div> </div>
</div> </div>
@ -561,7 +588,7 @@
</template> </template>
<style scoped> <style scoped>
.grid{ .grid{
min-width:1200px; min-width:1400px;
display:grid; display:grid;
margin-top:2%; margin-top:2%;
align-items:center; align-items:center;

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

@ -13,6 +13,7 @@ import ManageSchedule from "@/Apps/ManageSchedule.vue"
import ManageOwnedLessons from "@/Apps/ManageOwnLessons.vue"; import ManageOwnedLessons from "@/Apps/ManageOwnLessons.vue";
import LessonRequests from "@/Apps/LessonRequests.vue"; import LessonRequests from "@/Apps/LessonRequests.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 Payments from "@/Apps/Inscription/PaymentInfo.vue";
import ManageRequests from "@/Apps/Inscription/ManageRequests.vue"; import ManageRequests from "@/Apps/Inscription/ManageRequests.vue";
@ -28,13 +29,14 @@ const apps = {
'/manage-owned-lessons': ManageOwnedLessons, '/manage-owned-lessons': ManageOwnedLessons,
'/manage-schedule-requests' : LessonRequests, '/manage-schedule-requests' : LessonRequests,
'/msg' : Msg, '/msg' : Msg,
'/forums': Forums,
'/payments': Payments '/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") },
'ManageSchedules': { path: '#/manage-schedule', icon: 'fa-calendar-days', text: i18n("app.manageSchedules")}, 'ManageSchedules': { path: '#/manage-schedule', icon: 'fa-calendar-days', text: i18n("app.manageSchedules")},
'ManageCourses': { path: '#/manage-courses', icon: 'fa-book', text: i18n("app.manage.courses") }, 'ManageCourses': { path: '#/manage-courses', icon: 'fa-book', text: i18n("app.manage.courses") },

View File

@ -69,3 +69,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

@ -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

@ -74,4 +74,8 @@ export async function getExempReq(id){
export async function editExempReqState(id, newstate){ export async function editExempReqState(id, newstate){
return restPatch("/exemptionsreq/"+id+"/"+newstate) return restPatch("/exemptionsreq/"+id+"/"+newstate)
}
export async function getExempByUser(userId){
return restGet("/exemptionreq/"+userId)
} }

View File

@ -3,29 +3,28 @@ import { toast } from 'vue3-toastify'
const restURL = import.meta.env.VITE_CLYDE_MODE === 'container' ? "http://localhost:8080": import.meta.env.DEV ? "http://localhost:8080" : "https://clyde.herisson.ovh/api" const restURL = import.meta.env.VITE_CLYDE_MODE === 'container' ? "http://localhost:8080": import.meta.env.DEV ? "http://localhost:8080" : "https://clyde.herisson.ovh/api"
export async function restGet(endPoint) { export function restGet(endPoint) {
return await _rest(endPoint, {method: "GET"}); return _rest(endPoint, {method: "GET"});
} }
export async function restPost(endPoint, data) { export function restPost(endPoint, data) {
return await _rest(endPoint, {method: "POST", credentials: 'include', body: JSON.stringify(data)}); return _rest(endPoint, {method: "POST", credentials: 'include', body: JSON.stringify(data)});
} }
export async function restPostFile(endPoint, file){ export function restPostFile(endPoint, file){
let headers = new Headers(); let headers = new Headers();
return await _rest(endPoint, {method: "POST", credentials: 'include', body: file, headers: headers }); return _rest(endPoint, {method: "POST", credentials: 'include', body: file, headers: headers });
} }
export async function restDelete(endPoint) { export function restDelete(endPoint) {
return await _rest(endPoint, {method: "DELETE"}); return _rest(endPoint, {method: "DELETE"});
} }
export async function restDeleteItem(endPoint, data){ export function restDeleteItem(endPoint, data){
return await _rest(endPoint, {method: "DELETE", credentials: 'include', body: JSON.stringify(data)}); return _rest(endPoint, {method: "DELETE", credentials: 'include', body: JSON.stringify(data)});
} }
export function restPatch(endPoint, data) {
export async function restPatch(endPoint, data) { return _rest(endPoint, {method: "PATCH", credentials: 'include', body: JSON.stringify(data)});
return await _rest(endPoint, {method: "PATCH", credentials: 'include', body: JSON.stringify(data)});
} }
/** /**
@ -37,7 +36,7 @@ export async function restPatch(endPoint, data) {
* *
* @Example _rest("/ping", {user: data}) -> {id:0, txt:"pong"} * @Example _rest("/ping", {user: data}) -> {id:0, txt:"pong"}
*/ */
async function _rest(endPoint, config){ function _rest(endPoint, config){
endPoint.at(0) != "/" ? console.error("Carefull, you certainly should put a / at the begenning of your endPoint ") : true; endPoint.at(0) != "/" ? console.error("Carefull, you certainly should put a / at the begenning of your endPoint ") : true;
let session_token = getCookie("session_token"); let session_token = getCookie("session_token");
let headers = new Headers({ let headers = new Headers({
@ -45,13 +44,16 @@ async function _rest(endPoint, config){
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}); });
config['headers'] = config['headers'] == null ? headers : config['headers']; config['headers'] = config['headers'] == null ? headers : config['headers'];
return toast.promise(fetch(restURL + endPoint, config),
{ let ret = fetch(restURL + endPoint, config);
if(config['toast']){
ret = toast.promise(ret,
{
pending: config['pending'] != null ? config['pending'] : 'pending', pending: config['pending'] != null ? config['pending'] : 'pending',
error: config['error'] != null ? config['error'] : 'Network Failure...', error: config['error'] != null ? config['error'] : 'Network Failure...',
success: config['success'] != null ? config['success'] : {render(res){ success: config['success'] != null ? config['success'] : {render(res){
return res.data.ok ? "Success" : "error"; return res.data.ok ? "Success" : "error";
}}, }}})
}) }
.then( e => e.json()).catch( e => e ); return ret.then( e => e.json()).catch( e => e );
} }

View File

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

View File

@ -1,5 +1,8 @@
import {ref} from 'vue'
/*
* Get a date object in a date format dd-mm-yyyy
*/
export function formatDate(date) { export function formatDate(date) {
var d = new Date(date), var d = new Date(date),
month = '' + (d.getMonth() + 1), month = '' + (d.getMonth() + 1),
@ -14,8 +17,33 @@
return [day, month, year].join('-'); return [day, month, year].join('-');
} }
/*
* Get a date object in a date format yyyy-mm-dd
*/
export function invertedFormatDate(date) {
let d = new Date(date),
month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear();
if (month.length < 2)
month = '0' + month;
if (day.length < 2)
day = '0' + day;
return [year, month, day].join('-');
}
/*
* Create a string date via the hour and the date
*/
export function createLessonEvent(date,hour){
const str = date.concat(' ',hour);
return new Date(str);
}
/*
* Get the duration of a lesson
*/
export function durationCourse(element){ export function durationCourse(element){
const hour = element.lessonEnd.substring(3,5) -element.lessonStart.substring(3,5); const hour = element.lessonEnd.substring(3,5) -element.lessonStart.substring(3,5);
@ -23,6 +51,9 @@
return (element.lessonEnd - element.lessonStart)%2; return (element.lessonEnd - element.lessonStart)%2;
} }
/*
* Help to sort lessons chronologically
*/
export function sortByDate(a, b) { export function sortByDate(a, b) {
const nameA = new Date(a.lessonStart); // ignore upper and lowercase const nameA = new Date(a.lessonStart); // ignore upper and lowercase
const nameB = new Date(b.lessonStart); // ignore upper and lowercase const nameB = new Date(b.lessonStart); // ignore upper and lowercase
@ -36,15 +67,18 @@
return 0; return 0;
} }
/*
* Get the first day of the current month
*/
export function getFirstDay(d){ export function getFirstDay(d){
var date = new Date(d); var date = new Date(d);
return new Date(date.getFullYear(), date.getMonth(), 1); return new Date(date.getFullYear(), date.getMonth(), 1);
} }
/*
* Convert a list of lesson to a schedule in a week
export function matrixFromList(list,weekMonday){ */
export function weekFromList(list, weekMonday){
const weekStart = new Date(weekMonday); const weekStart = new Date(weekMonday);
const matrix = new Array(7); const matrix = new Array(7);
for (let i = 0; i < matrix.length; i++) { for (let i = 0; i < matrix.length; i++) {
@ -61,12 +95,18 @@
return matrix; return matrix;
} }
/*
* Return the last date of a month
*/
export function lastDateOfMonth(d){ export function lastDateOfMonth(d){
const date = new Date(d); const date = new Date(d);
const temp = new Date(date.getFullYear(), date.getMonth() + 1, 0); const temp = new Date(date.getFullYear(), date.getMonth() + 1, 0);
return temp.getDate(); return temp.getDate();
} }
/*
* Convert a list of lesson to a schedule in a month
*/
export function monthFromList(list,month){ export function monthFromList(list,month){
const beginning = getFirstDay(month); const beginning = getFirstDay(month);
const matrix = new Array(lastDateOfMonth(month)) const matrix = new Array(lastDateOfMonth(month))
@ -84,9 +124,11 @@
return matrix; return matrix;
} }
/*
* Put the first element of a weekly schedule (corresponds to sunday) to the end of the list
*/
export function sundayToTheEnd(list){ export function sundayToTheEnd(list){
const newlist = list; const newlist = list;
const sunday = newlist.shift(); const sunday = newlist.shift();
@ -94,19 +136,31 @@
return newlist; return newlist;
} }
/*
* Get the difference of time between 2 dates
*/
export function getDifferenceTime(date1,date2){ export function getDifferenceTime(date1,date2){
return Math.abs((new Date(date2).getTime() - new Date(date1).getTime())/60000); return Math.abs((new Date(date2).getTime() - new Date(date1).getTime())/60000);
} }
/*
* used to shift the lessons correctly
*/
export function getMarginTop(list, index1, index2){ export function getMarginTop(list, index1, index2){
if(index2 < 0){ if(index2 < 0){
const temp = new Date(list[index1].lessonStart); const temp = new Date(list[index1].lessonStart);
temp.setHours(8,0,0); temp.setHours(8,0,0);
return Math.abs((new Date(list[index1].lessonStart).getTime()- temp.getTime())/60000); return Math.abs((new Date(list[index1].lessonStart).getTime()- temp.getTime())/60000);
} }
if(new Date(list[index1].lessonStart).getTime() === new Date(list[index2].lessonEnd).getTime()){
return Math.abs(getMarginTop(list,index2,index2-1));
}
return Math.abs((new Date(list[index1].lessonStart).getTime()- new Date(list[index2].lessonEnd).getTime())/60000)+getMarginTop(list,index2,index2-1); return Math.abs((new Date(list[index1].lessonStart).getTime()- new Date(list[index2].lessonEnd).getTime())/60000)+getMarginTop(list,index2,index2-1);
} }
/*
* Get the hour and minutes of a date in the right format
*/
export function getHoursMinutes(date){ export function getHoursMinutes(date){
const d = new Date(date); const d = new Date(date);
let hours = [d.getHours().toString().length == 1 ? "0" + d.getHours().toString() : d.getHours()]; let hours = [d.getHours().toString().length == 1 ? "0" + d.getHours().toString() : d.getHours()];