Compare commits
187 Commits
bc87748b31
...
JalonB
Author | SHA1 | Date | |
---|---|---|---|
c1b8c39e92
|
|||
3825565b16 | |||
48640dfa8b | |||
3acfd02bfb
|
|||
a3fe6ce6bd
|
|||
96965bde97 | |||
302e0b555c | |||
84a408298d | |||
3b48e5adfb | |||
78da7b23d2
|
|||
1831cc7eb2
|
|||
cc51510dac | |||
44bb04f21b | |||
1ed61c8c7b | |||
59c82d7482 | |||
772fa09e28 | |||
672fcd099f | |||
3198a7ade0 | |||
5516f75346 | |||
1f66ac5a4d | |||
59b82abf71 | |||
cf0c465248 | |||
2917d645fa | |||
730a72dba3 | |||
47eb98da57 | |||
eafcf6b265 | |||
34e537ff02 | |||
364f39c4bc | |||
f2675ed764 | |||
85c1282f48 | |||
4d6387ca8b | |||
fa2deca1b9 | |||
490bf403f0 | |||
c61a092809 | |||
2cffe28720
|
|||
060526c20d
|
|||
af8bc8872d | |||
12ff43e970 | |||
82cf7cbfaf
|
|||
3b63896439 | |||
bd3b03dfea | |||
b38b1ab6b8 | |||
6e0a9a46e5 | |||
2d8fcb4712 | |||
fcb48ac71a | |||
043f5c87d2
|
|||
a03983d625
|
|||
b382bf957f | |||
bbddcb26ad
|
|||
22665f0565 | |||
d324d7447d | |||
71c2af7fcb | |||
c717205764 | |||
4d007534b3 | |||
8ac1f7ed8b
|
|||
1a266cdfbd | |||
32810a9b01 | |||
217ad7f0d1 | |||
2d20b45c3a | |||
9cbdaac09d | |||
a90243f4b9
|
|||
636e17b4bf | |||
9cd54bdae9 | |||
69be9681ff | |||
98082f34b7 | |||
43883caef0
|
|||
88b057e19d
|
|||
260191d790
|
|||
608b6e4893 | |||
05ed28626a | |||
ca10084400 | |||
fa1a2c6d3b | |||
4485dbf803 | |||
b52c50fd76 | |||
172837d6d1 | |||
9a5115f7fe | |||
0d6b4ec57c | |||
e0a3a618a1 | |||
0b9227a822
|
|||
f14d41f04d
|
|||
76dcea186c | |||
a79f23fed0 | |||
43f3d66eb9 | |||
e25ead6230 | |||
70bec1a934 | |||
0837cc800a | |||
30f04b736b | |||
f83e689e4d | |||
29f13c3a3b | |||
33eb5c0f0c | |||
0621c6fe68 | |||
ecaf5e3df8 | |||
846cdedc4b | |||
881c935c00 | |||
e8bf0d953d | |||
219165aacf | |||
8097f5314f | |||
1e2efac5bc | |||
061f329020 | |||
892d4f0651 | |||
9e45e6a9c9 | |||
ef03a6bdca | |||
f081b7206f | |||
54d19eb888 | |||
e8917cd69e | |||
cdc3772384 | |||
e8fea7625f | |||
041fe7f95d | |||
3ca074a3ba
|
|||
7bb1df123f
|
|||
6077e65b50 | |||
92cdeaebba | |||
be7f42aafe | |||
e998fb2ab4 | |||
a168d41aee | |||
3f4f6ed49a | |||
fed567e9ab | |||
14c5423328 | |||
7394a23b45 | |||
939b4f5492 | |||
da2c0f472d | |||
dff225b0f5
|
|||
f8d60f40fc
|
|||
3281bf1d7e | |||
47f1bffb24 | |||
8fa29460ef
|
|||
3ea48c20aa | |||
8c70108a1c | |||
e303048f7e | |||
6116cbdaa4 | |||
bdfa2e6389 | |||
d4c442c64a | |||
94be706226
|
|||
5c0dfa3596 | |||
24f82812f4 | |||
881b30e5c9
|
|||
f269e24bb4 | |||
7a05fc1316 | |||
821377a72f | |||
388c53e47b | |||
87b02af68e | |||
f184de21a8 | |||
63d0087d0c | |||
eacdf8d47a | |||
1498cfa11e | |||
c6ce6d3e5b
|
|||
2e02cd8870
|
|||
17cb969160 | |||
4720669c2c | |||
5e9eccc4f6 | |||
8650482d11 | |||
783cd8fa9f | |||
40186f9898 | |||
106bf96a98
|
|||
b7a729c899 | |||
fdf4993def | |||
dad6953f99 | |||
f99ed470f8 | |||
9a83d14aea | |||
7b0d76dae8
|
|||
61e269eb27
|
|||
0cbe0dd82b | |||
3167d1f2fc | |||
a94167c8a0 | |||
5f483216b9
|
|||
5a4d066c45
|
|||
d31547c4cc | |||
ec2b975467 | |||
f9bcff6d4f
|
|||
b8b193f344
|
|||
05359d64ac | |||
7bd745fd5e
|
|||
3d78851b29 | |||
dbe28a7fed | |||
bd7d2c2d51 | |||
a96609d2ef
|
|||
cb750b8505
|
|||
91c7f42521 | |||
bd27ffd3cb | |||
91ee3adbcd | |||
c1b2742a8f | |||
2805fede4b | |||
951feed3c8 | |||
95054fa973 | |||
3af83a58d3 | |||
47c5c14862 | |||
db895a6091 |
@ -18,15 +18,3 @@ jobs:
|
||||
- uses: gradle/gradle-build-action@v3
|
||||
- name: building
|
||||
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
|
||||
|
@ -14,38 +14,31 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy-frontend:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v3
|
||||
working-directory: ./frontend
|
||||
- run: npm ci
|
||||
name: clean install
|
||||
working-directory: ./frontend
|
||||
- name: building
|
||||
working-directory: ./frontend
|
||||
run: npm run build
|
||||
- name: pushing to the server
|
||||
working-directory: ./frontend
|
||||
run: |
|
||||
echo "${{ secrets.SSH_KEY }}" > key
|
||||
chmod 0600 key
|
||||
scp -o "StrictHostKeyChecking=no" -o "LogLevel=ERROR" -i key -r dist/ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:
|
||||
- run: echo "The website has been deployed. visit https://clyde.herisson.ovh/"
|
||||
# deploy-frontend:
|
||||
# runs-on: ubuntu-latest
|
||||
# steps:
|
||||
# - uses: actions/checkout@v4
|
||||
# - name: Use Node.js ${{ matrix.node-version }}
|
||||
# uses: actions/setup-node@v3
|
||||
# working-directory: ./frontend
|
||||
# - run: npm ci
|
||||
# name: clean install
|
||||
# working-directory: ./frontend
|
||||
# - name: building
|
||||
# working-directory: ./frontend
|
||||
# run: npm run build
|
||||
# - name: pushing to the server
|
||||
# working-directory: ./frontend
|
||||
# run: |
|
||||
# echo "${{ secrets.SSH_KEY }}" > key
|
||||
# chmod 0600 key
|
||||
# scp -o "StrictHostKeyChecking=no" -o "LogLevel=ERROR" -i key -r dist/ ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:
|
||||
# - run: echo "The website has been deployed. visit https://clyde.herisson.ovh/"
|
||||
|
||||
deploy-backend:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- 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
|
||||
run: |
|
||||
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/
|
||||
- name: restarting the backend
|
||||
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/ && sed -i compose.yaml -e "s/8080:8080/4001:8080/" -e "s/8000:8080/4000:8080/" && sed -e "8d" -i frontend/Dockerfile && docker-compose up --force-recreate --build -d'
|
||||
- run: echo "The backend has been deployed. running at https://clyde.herisson.ovh/api"
|
||||
|
14
README.md
14
README.md
@ -1,5 +1,7 @@
|
||||
# Clyde project
|
||||
|
||||
Système de gestion d'universitée (dévelopé dans le cadre du cours de projet de génie logiciel de l'Umons 2024)
|
||||
|
||||
## Signature
|
||||
|
||||
Projet du groupe 01:
|
||||
@ -11,21 +13,28 @@ Projet du groupe 01:
|
||||
|
||||
## Running
|
||||
|
||||
**Attention**: Vous devez avoir installé docker-compose pour lancer ce projet.
|
||||
|
||||
Le projet peut être lancé grace à docker compose.
|
||||
|
||||
```sh
|
||||
$ docker compose up
|
||||
```
|
||||
|
||||
Dans le cas ou vous modifiers des fichiers, pour éviter que les images de docker soient recrées avec les changement
|
||||
Dans le cas ou vous modifiez des fichiers, pour éviter que les images de docker ne soient réutilisés sans les
|
||||
changements.
|
||||
|
||||
```sh
|
||||
$ docker compose up --force-recreate --build
|
||||
```
|
||||
Vous pouvez alors accéder au frontend à l'adresse [http://localhost:5173](http://localhost:5173)
|
||||
|
||||
Une version finie du site construite automatiquement à l'aide de gitea actions tourne à l'adresse
|
||||
[https://clyde.herisson.ovh/](https://clyde.herisson.ovh/)
|
||||
|
||||
## Dévelopement
|
||||
|
||||
Dans le cas ou vous êtes dans une phase de développement, il est plus simple d'utiliser gradle pour lancer le backend et frontend dans un mode de développement.
|
||||
Dans le cas ou vous êtes dans une phase de développement, il est plus simple d'utiliser gradle pour lancer le backend et frontend.
|
||||
**Attention**: Ce mode n'est pas fait pour être utilisé en production!
|
||||
|
||||
```sh
|
||||
@ -38,4 +47,3 @@ Ceci requière également docker pour lancer une instance de postgresql pris en
|
||||
Il est possible de se passer entièrement de docker en supprimant la dépendance dans le fichier `backend/build.gradle.kts`: ~~`developmentOnly("org.springframework.boot:spring-boot-docker-compose")`~~
|
||||
Il est alors nécéssaire d'avoir une instance de postgresql tournant sur `localhost:5432` avec une table `clyde`, utilisateur: `devel` et password: `devel`
|
||||
(cette configuration peut également être changée dans le fichier resources/application.properties de spring)
|
||||
|
||||
|
@ -27,6 +27,7 @@ dependencies {
|
||||
implementation("com.kohlschutter.junixsocket:junixsocket-core:2.9.0")
|
||||
// implementation("org.springframework.session:spring-session-jdbc")
|
||||
developmentOnly("org.springframework.boot:spring-boot-devtools")
|
||||
developmentOnly("org.springframework.boot:spring-boot-docker-compose")
|
||||
runtimeOnly("org.postgresql:postgresql")
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||
testImplementation("org.springframework.boot:spring-boot-testcontainers")
|
||||
|
@ -0,0 +1,63 @@
|
||||
package ovh.herisson.Clyde.DTO.ScientificPublications;
|
||||
|
||||
/******************************************************
|
||||
* @file ResearchDTO.java
|
||||
* @author Bartha Maxime
|
||||
* @scope Publications Scientifiques
|
||||
*
|
||||
* Research format to return to front (without author's password)
|
||||
******************************************************/
|
||||
|
||||
import lombok.Data;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Access;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.PaperType;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Research;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@Data
|
||||
public class ResearchDTO {
|
||||
|
||||
private long id;
|
||||
private String title;
|
||||
private ResearcherDTO researcher;
|
||||
private final Set<ResearcherDTO> coAuthors;
|
||||
private Date releaseDate;
|
||||
private PaperType paperType;
|
||||
private String pdfLocation;
|
||||
private String bibTexLocation;
|
||||
private String language;
|
||||
private Access access;
|
||||
private String domain;
|
||||
private String summary;
|
||||
private long views;
|
||||
|
||||
private ResearchDTO(String title, ResearcherDTO researcherDTO, Date releaseDate, PaperType paperType, String pdfLocation, String language, Access access, String domain, String bibTexLocation, String summary, Set<Researcher> coAuthors, long id, long views) {
|
||||
this.title = title;
|
||||
this.researcher = researcherDTO;
|
||||
this.releaseDate = releaseDate;
|
||||
this.paperType = paperType;
|
||||
this.pdfLocation = pdfLocation;
|
||||
this.language = language;
|
||||
this.access = access;
|
||||
this.domain = domain;
|
||||
this.summary = summary;
|
||||
this.id = id;
|
||||
this.bibTexLocation = bibTexLocation;
|
||||
this.coAuthors = new HashSet<>();
|
||||
for (Researcher coAuthor: coAuthors) {
|
||||
this.coAuthors.add(ResearcherDTO.construct(coAuthor));
|
||||
}
|
||||
this.views = views;
|
||||
}
|
||||
|
||||
|
||||
public static ResearchDTO construct(Research research){
|
||||
return new ResearchDTO(research.getTitle(), ResearcherDTO.construct(research.getAuthor()), research.getReleaseDate(),
|
||||
research.getPaperType(),research.getPdfLocation(),research.getLanguage(),research.getAccess(),
|
||||
research.getDomain(),research.getBibTexLocation(), research.getSummary(), research.getCoAuthors(),research.getId(), research.getViews());
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package ovh.herisson.Clyde.DTO.ScientificPublications;
|
||||
|
||||
/******************************************************
|
||||
* @file ResearcherDTO.java
|
||||
* @author Bartha Maxime
|
||||
* @scope Publications Scientifiques
|
||||
*
|
||||
* Researcher Format to return to front (without user password)
|
||||
******************************************************/
|
||||
import lombok.Data;
|
||||
import ovh.herisson.Clyde.Services.ProtectionService;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class ResearcherDTO {
|
||||
|
||||
private long id;
|
||||
private Map<String,Object> user;
|
||||
private String site;
|
||||
private String domain;
|
||||
private String orcidId;
|
||||
|
||||
|
||||
private ResearcherDTO(long id, Map<String ,Object> user, String site,String domain,String orcidId){
|
||||
this.domain = domain;
|
||||
this.orcidId = orcidId;
|
||||
this.site = site;
|
||||
this.user = user;
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static ResearcherDTO construct(Researcher researcher){
|
||||
return new ResearcherDTO(researcher.getId(), ProtectionService.userWithoutPassword(researcher.getUser()),researcher.getSite(),
|
||||
researcher.getDomain(),researcher.getOrcidId());
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import ovh.herisson.Clyde.Services.AuthenticatorService;
|
||||
import ovh.herisson.Clyde.Services.ScientificPublications.ResearchesService;
|
||||
import ovh.herisson.Clyde.Tables.Applications;
|
||||
import ovh.herisson.Clyde.Tables.Role;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
@ -20,7 +21,10 @@ public class ApplicationsController {
|
||||
|
||||
AuthenticatorService authServ;
|
||||
|
||||
public ApplicationsController(AuthenticatorService authServ){
|
||||
ResearchesService researchesServ;
|
||||
|
||||
public ApplicationsController(AuthenticatorService authServ, ResearchesService researchesServ){
|
||||
this.researchesServ = researchesServ;
|
||||
this.authServ = authServ;
|
||||
}
|
||||
|
||||
@ -47,6 +51,7 @@ public class ApplicationsController {
|
||||
|
||||
//if unAuthed
|
||||
authorizedApps.add(Applications.Login);
|
||||
authorizedApps.add(Applications.ListResearches);
|
||||
authorizedApps.add(Applications.Schedule);
|
||||
|
||||
User user = authServ.getUserFromToken(token);
|
||||
@ -71,10 +76,15 @@ public class ApplicationsController {
|
||||
authorizedApps.add(Applications.Requests);
|
||||
authorizedApps.add(Applications.StudentsList);}
|
||||
|
||||
if (researchesServ.getResearcherByUser(user) != null)
|
||||
authorizedApps.add(Applications.ManageResearcherProfile);
|
||||
|
||||
if (!authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token)){
|
||||
authorizedApps.add(Applications.UsersList);
|
||||
authorizedApps.add(Applications.ManageSchedules);
|
||||
authorizedApps.add(Applications.LessonRequests);}
|
||||
authorizedApps.add(Applications.LessonRequests);
|
||||
authorizedApps.add(Applications.CreateUser);
|
||||
}
|
||||
|
||||
if (!authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin, Role.InscriptionService},token)){
|
||||
authorizedApps.add(Applications.Payments);}
|
||||
|
@ -3,15 +3,14 @@ package ovh.herisson.Clyde.EndPoints;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ovh.herisson.Clyde.Repositories.CurriculumCourseRepository;
|
||||
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
|
||||
import ovh.herisson.Clyde.Services.AuthenticatorService;
|
||||
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.Role;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
import ovh.herisson.Clyde.Services.*;
|
||||
import ovh.herisson.Clyde.Tables.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@ -24,10 +23,23 @@ public class CourseController {
|
||||
|
||||
private final AuthenticatorService authServ;
|
||||
|
||||
public CourseController(CourseService courseServ, TeacherCourseService teacherCourseServ, AuthenticatorService authServ) {
|
||||
private final UserService userService;
|
||||
|
||||
private final CurriculumService curriculumService;
|
||||
|
||||
private final UserCurriculumService userCurriculumService;
|
||||
|
||||
private final CurriculumCourseRepository curriculumCourseRepository;
|
||||
private final CurriculumCourseService curriculumCourseService;
|
||||
public CourseController(CourseService courseServ, TeacherCourseService teacherCourseServ, AuthenticatorService authServ, UserService userService, CurriculumService curriculumService, UserCurriculumService userCurriculumService, CurriculumCourseRepository curriculumCourseRepository, CurriculumCourseService curriculumCourseService) {
|
||||
this.courseServ = courseServ;
|
||||
this.teacherCourseServ = teacherCourseServ;
|
||||
this.authServ = authServ;
|
||||
this.userService = userService;
|
||||
this.curriculumService = curriculumService;
|
||||
this.userCurriculumService = userCurriculumService;
|
||||
this.curriculumCourseRepository = curriculumCourseRepository;
|
||||
this.curriculumCourseService = curriculumCourseService;
|
||||
}
|
||||
|
||||
@GetMapping("/course/{id}")
|
||||
@ -70,17 +82,18 @@ public class CourseController {
|
||||
}
|
||||
|
||||
|
||||
@PostMapping("/course")
|
||||
@PostMapping("/course/curriculum/{id}")
|
||||
public ResponseEntity<Map<String ,Object>> postCourse(@RequestHeader("Authorization") String token,
|
||||
@RequestBody Course course)
|
||||
@RequestBody Course course,@PathVariable long id)
|
||||
{
|
||||
if (authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token))
|
||||
return new UnauthorizedResponse<>(null);
|
||||
System.out.println(course.getOwner().getRegNo());
|
||||
Course createdCourse = courseServ.save(course);
|
||||
if (createdCourse == null)
|
||||
Curriculum curriculum = curriculumService.findById(id);
|
||||
if (createdCourse == null || curriculum == null)
|
||||
return new ResponseEntity<>(null,HttpStatus.BAD_REQUEST);
|
||||
|
||||
CurriculumCourse curriculumCourse = new CurriculumCourse(curriculum,course);
|
||||
curriculumCourseService.save(curriculumCourse);
|
||||
return new ResponseEntity<>(ProtectionService.courseWithoutPassword(createdCourse), HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@ -134,4 +147,28 @@ public class CourseController {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ public class CurriculumController {
|
||||
|
||||
|
||||
private final CurriculumService curriculumServ;
|
||||
private final CourseService courseServ;
|
||||
private final AuthenticatorService authServ;
|
||||
|
||||
private final UserCurriculumService userCurriculumServ;
|
||||
@ -27,8 +28,9 @@ public class CurriculumController {
|
||||
private final UserService userServ;
|
||||
|
||||
private final ExternalCurriculumRepository ecr;
|
||||
public CurriculumController(CurriculumService curriculumServ, AuthenticatorService authServ, UserCurriculumService userCurriculumServ, CurriculumCourseService curriculumCourseServ, InscriptionRepository ir, UserService userServ, ExternalCurriculumRepository ecr){
|
||||
public CurriculumController(CurriculumService curriculumServ, CourseService courseServ, AuthenticatorService authServ, UserCurriculumService userCurriculumServ, CurriculumCourseService curriculumCourseServ, InscriptionRepository ir, UserService userServ, ExternalCurriculumRepository ecr){
|
||||
this.curriculumServ = curriculumServ;
|
||||
this.courseServ = courseServ;
|
||||
this.authServ = authServ;
|
||||
this.userCurriculumServ = userCurriculumServ;
|
||||
this.curriculumCourseServ = curriculumCourseServ;
|
||||
@ -60,6 +62,18 @@ public class CurriculumController {
|
||||
return new ResponseEntity<>(curriculumCourseServ.getDepthCurriculum(curriculum),HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/course/curriculum/{id}")
|
||||
public ResponseEntity<Iterable<Curriculum>> getCurriculumsByCourse(@RequestHeader("Authorization") String token, @PathVariable long id){
|
||||
if(authServ.isNotIn(new Role[]{Role.Admin, Role.Secretary},token))
|
||||
return new UnauthorizedResponse<>(null);
|
||||
Course course = courseServ.findById(id);
|
||||
if(course == null)
|
||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||
Iterable<Curriculum> curriculum = curriculumCourseServ.findCurriculumByCourses(course);
|
||||
return new ResponseEntity<>(curriculum, HttpStatus.OK);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Return the list of all curicullums of an user
|
||||
@GetMapping("/onescurriculum/{userId}")
|
||||
@ -91,17 +105,20 @@ public class CurriculumController {
|
||||
}
|
||||
|
||||
@PostMapping("/curriculum/{id}")
|
||||
public ResponseEntity<String> postCoursesToCurriculum(@RequestHeader("Authorization") String token,
|
||||
@RequestBody Iterable<Long> coursesIds,
|
||||
@PathVariable long id)
|
||||
{
|
||||
public ResponseEntity<String> postCourseToCurriculum(@RequestHeader("Authorization") String token,
|
||||
@RequestBody long coursesId,
|
||||
@PathVariable long id){
|
||||
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token))
|
||||
return new UnauthorizedResponse<>(null);
|
||||
|
||||
if (!curriculumCourseServ.saveAll(coursesIds, curriculumServ.findById(id)))
|
||||
CurriculumCourse curriculumCourse = new CurriculumCourse(curriculumServ.findById(id), courseServ.findById(coursesId));
|
||||
if(curriculumCourse.getCourse() == null || curriculumCourse.getCurriculum() == null)
|
||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||
|
||||
|
||||
curriculumCourseServ.save(curriculumCourse);
|
||||
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ public class ExternalCurriculumController {
|
||||
user = userRepository.findById((Integer) externalCurrInfos.get("userRegNo"));
|
||||
}
|
||||
|
||||
ExternalCurriculum toSave = new ExternalCurriculum(ir, (String) externalCurrInfos.get("school"),(String) externalCurrInfos.get("formation"),(String) externalCurrInfos.get("completion"), (Integer)externalCurrInfos.get("startYear"), (Integer)externalCurrInfos.get("endYear"), (String)externalCurrInfos.get("justifDocUrl"), user);
|
||||
ExternalCurriculum toSave = new ExternalCurriculum(ir, (String) externalCurrInfos.get("school"),(String) externalCurrInfos.get("formation"),(String) externalCurrInfos.get("completion"), (Integer)externalCurrInfos.get("startYear"), (Integer)externalCurrInfos.get("endYear"), (String)externalCurrInfos.get("justifdocUrl"), user);
|
||||
|
||||
return new ResponseEntity<>(ecr.save(toSave), HttpStatus.OK);
|
||||
}
|
||||
|
@ -3,10 +3,12 @@ package ovh.herisson.Clyde.EndPoints.Inscription;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ovh.herisson.Clyde.Repositories.CurriculumRepository;
|
||||
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
|
||||
import ovh.herisson.Clyde.Services.AuthenticatorService;
|
||||
import ovh.herisson.Clyde.Services.Inscription.InscriptionService;
|
||||
import ovh.herisson.Clyde.Services.ProtectionService;
|
||||
import ovh.herisson.Clyde.Tables.Curriculum;
|
||||
import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest;
|
||||
import ovh.herisson.Clyde.Tables.RequestState;
|
||||
import ovh.herisson.Clyde.Tables.Role;
|
||||
@ -19,17 +21,18 @@ public class InscriptionController {
|
||||
|
||||
private final InscriptionService inscriptionServ;
|
||||
private final AuthenticatorService authServ;
|
||||
|
||||
public InscriptionController(InscriptionService inscriptionServ, AuthenticatorService authServ){
|
||||
private final CurriculumRepository curriculumRepository;
|
||||
public InscriptionController(InscriptionService inscriptionServ, AuthenticatorService authServ, CurriculumRepository curriculumRepository){
|
||||
this.inscriptionServ = inscriptionServ;
|
||||
this.authServ = authServ;
|
||||
this.curriculumRepository = curriculumRepository;
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/requests/register")
|
||||
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);
|
||||
|
||||
Iterable<InscriptionRequest> inscriptionRequests = inscriptionServ.getAll();
|
||||
@ -41,7 +44,7 @@ public class InscriptionController {
|
||||
@GetMapping("/request/register/{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);
|
||||
|
||||
InscriptionRequest foundInscriptionRequest = inscriptionServ.getById(id);
|
||||
@ -87,6 +90,12 @@ public class InscriptionController {
|
||||
return new UnauthorizedResponse<>(null);
|
||||
|
||||
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);
|
||||
|
||||
inscriptionServ.save(toEdit);
|
||||
@ -97,4 +106,31 @@ public class InscriptionController {
|
||||
}
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PatchMapping("/request/registerequivimpose/{id}/{cursusid}")
|
||||
public ResponseEntity<Object> editRegisterEquiv(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable long cursusid){
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher}, token))
|
||||
return new UnauthorizedResponse<>(null);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
//We impose a curriculum
|
||||
Curriculum curriculum = curriculumRepository.findById(cursusid);
|
||||
|
||||
toEdit.setCurriculumId(curriculum.getCurriculumId());
|
||||
toEdit.setEquivalenceState(RequestState.Accepted);
|
||||
|
||||
inscriptionServ.save(toEdit);
|
||||
|
||||
if (toEdit.getState() == RequestState.Accepted && (toEdit.getEquivalenceState() == RequestState.Accepted || toEdit.getEquivalenceState() == RequestState.Unrequired))
|
||||
{
|
||||
inscriptionServ.createUser(toEdit);
|
||||
}
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
|
@ -5,19 +5,15 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ovh.herisson.Clyde.Repositories.CourseRepository;
|
||||
import ovh.herisson.Clyde.Repositories.CurriculumRepository;
|
||||
import ovh.herisson.Clyde.Repositories.Inscription.ChangeCurriculumRequestRepository;
|
||||
import ovh.herisson.Clyde.Repositories.Inscription.ExemptionsRequestRepository;
|
||||
import ovh.herisson.Clyde.Repositories.Inscription.ScholarshipRequestRepository;
|
||||
import ovh.herisson.Clyde.Repositories.Inscription.UnregisterRequestRepository;
|
||||
import ovh.herisson.Clyde.Repositories.Inscription.*;
|
||||
import ovh.herisson.Clyde.Repositories.UserCurriculumRepository;
|
||||
import ovh.herisson.Clyde.Repositories.UserRepository;
|
||||
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
|
||||
import ovh.herisson.Clyde.Services.AuthenticatorService;
|
||||
import ovh.herisson.Clyde.Services.TokenService;
|
||||
import ovh.herisson.Clyde.Services.UserService;
|
||||
import ovh.herisson.Clyde.Tables.*;
|
||||
import ovh.herisson.Clyde.Tables.Inscription.ExemptionsRequest;
|
||||
import ovh.herisson.Clyde.Tables.Inscription.ScholarshipRequest;
|
||||
import ovh.herisson.Clyde.Tables.Inscription.UnregisterRequest;
|
||||
import ovh.herisson.Clyde.Tables.Inscription.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
@ -28,6 +24,7 @@ import java.util.Map;
|
||||
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
|
||||
public class RequestsController {
|
||||
|
||||
public final TokenService tokenService;
|
||||
public final ExemptionsRequestRepository err;
|
||||
public final ScholarshipRequestRepository srr;
|
||||
public final UserRepository userRepository;
|
||||
@ -37,10 +34,11 @@ public class RequestsController {
|
||||
public final UserService userService;
|
||||
public final UserCurriculumRepository userCurriculumRepository;
|
||||
public final CurriculumRepository curriculumRepository;
|
||||
|
||||
public final MinervalRepository minervalRepository;
|
||||
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, MinervalRepository minervalRepository, ChangeCurriculumRequestRepository changeCurriculumRequestRepository) {
|
||||
this.tokenService = tokenService;
|
||||
this.err = err;
|
||||
this.srr = srr;
|
||||
this.userRepository = userRepository;
|
||||
@ -50,6 +48,7 @@ public class RequestsController {
|
||||
this.userService = userService;
|
||||
this.userCurriculumRepository = userCurriculumRepository;
|
||||
this.curriculumRepository = curriculumRepository;
|
||||
this.minervalRepository = minervalRepository;
|
||||
this.changeCurriculumRequestRepository = changeCurriculumRequestRepository;
|
||||
}
|
||||
|
||||
@ -78,7 +77,7 @@ public class RequestsController {
|
||||
//Get all the exemptions Request
|
||||
@GetMapping(value = "/exemptionsreq")
|
||||
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);
|
||||
|
||||
ArrayList<ExemptionsRequest> toReturn = new ArrayList<>();
|
||||
@ -90,7 +89,7 @@ public class RequestsController {
|
||||
|
||||
@GetMapping(value = "/exemptionsreq/{id}")
|
||||
public ResponseEntity<ExemptionsRequest> getExemptionRequestbyId(@RequestHeader("Authorization") String token, @PathVariable long id){
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher,Role.InscriptionService},token))
|
||||
return new UnauthorizedResponse<>(null);
|
||||
|
||||
ExemptionsRequest exemptionsRequest = err.findById(id);
|
||||
@ -100,10 +99,15 @@ public class RequestsController {
|
||||
|
||||
@PatchMapping(value = "/exemptionsreq/{id}/{newstate}")
|
||||
public ResponseEntity<String> changeExemptionReqState(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newstate){
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher},token))
|
||||
return new UnauthorizedResponse<>(null);
|
||||
|
||||
ExemptionsRequest exemptionsRequest = err.findById(id);
|
||||
|
||||
if (exemptionsRequest.getState() == RequestState.Accepted){
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
exemptionsRequest.setState(newstate);
|
||||
err.save(exemptionsRequest);
|
||||
|
||||
@ -140,12 +144,28 @@ public class RequestsController {
|
||||
}
|
||||
|
||||
@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"));
|
||||
|
||||
User u = scholarshipRequest.getUser();
|
||||
|
||||
//If the request is already accepted we just return ok (otherwise we would duplicate the procedure below)
|
||||
if (scholarshipRequest.getState() == RequestState.Accepted){
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
if (infos.get("state").equals("Accepted")){
|
||||
scholarshipRequest.setState(RequestState.Accepted);
|
||||
scholarshipRequest.setAmount((int) infos.get("amount"));
|
||||
|
||||
//We then deduce then amount from the minerval
|
||||
ArrayList<Minerval> minerval = minervalRepository.getMinervalsByStudentRegNoOrderByYearDesc(u.getRegNo());
|
||||
minerval.get(0).setPaidAmount(minerval.get(0).getPaidAmount() + scholarshipRequest.getAmount());
|
||||
minerval.get(0).setToPay(minerval.get(0).getToPay() - scholarshipRequest.getAmount());
|
||||
minervalRepository.save(minerval.get(0));
|
||||
}else{
|
||||
scholarshipRequest.setState(RequestState.Refused);
|
||||
}
|
||||
@ -155,30 +175,48 @@ public class RequestsController {
|
||||
}
|
||||
|
||||
@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);
|
||||
return new ResponseEntity<>(toReturn, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@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<>();
|
||||
unregisterRequestRepository.findAll().forEach(toReturn::add);
|
||||
return new ResponseEntity<>(toReturn, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@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);
|
||||
return new ResponseEntity<>(unregisterRequest, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@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);
|
||||
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 (unregisterRequest.getCurriculum() == null){
|
||||
ArrayList<UserCurriculum> userCurricula = userCurriculumRepository.findByUserOrderByCurriculum(u);
|
||||
@ -193,8 +231,6 @@ public class RequestsController {
|
||||
userCurriculumRepository.save(userCurriculum);
|
||||
}
|
||||
}
|
||||
|
||||
unregisterRequestRepository.save(unregisterRequest);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@ -236,7 +272,7 @@ public class RequestsController {
|
||||
|
||||
@GetMapping("/changecurriculumreq")
|
||||
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);
|
||||
|
||||
ArrayList<ChangeCurriculumRequest> toReturn = new ArrayList<>();
|
||||
@ -248,7 +284,7 @@ public class RequestsController {
|
||||
|
||||
@GetMapping("/changecurriculumreq/{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);
|
||||
|
||||
ChangeCurriculumRequest toReturn = changeCurriculumRequestRepository.findById(id);
|
||||
@ -257,37 +293,45 @@ public class RequestsController {
|
||||
|
||||
@PatchMapping("/changecurriculumreq/{id}/{newState}")
|
||||
public ResponseEntity<String> editCCReq(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newState){
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin,Role.InscriptionService},token))
|
||||
return new UnauthorizedResponse<>(null);
|
||||
|
||||
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 actual curriculum is not null then we need to set that the user doesn't follow it anymore
|
||||
acceptProcedure(toEdit);
|
||||
}
|
||||
|
||||
changeCurriculumRequestRepository.save(toEdit);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PatchMapping("/changecurriculumreqteacher/{id}/{newteacherstate}")
|
||||
public ResponseEntity<String> editCCReqTeacherState(@RequestHeader("Authorization") String token, @PathVariable long id, @PathVariable RequestState newteacherstate){
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary,Role.InscriptionService},token))
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher},token))
|
||||
return new UnauthorizedResponse<>(null);
|
||||
|
||||
ChangeCurriculumRequest toEdit = changeCurriculumRequestRepository.findById(id);
|
||||
|
||||
toEdit.setState(newteacherstate);
|
||||
//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.setTeacherApprovalState(newteacherstate);
|
||||
changeCurriculumRequestRepository.save(toEdit);
|
||||
|
||||
if (newteacherstate == RequestState.Accepted && toEdit.getState() == RequestState.Accepted){
|
||||
//If actual curriculum is not null then we need to set that the user doesn't follow it anymore
|
||||
acceptProcedure(toEdit);
|
||||
}
|
||||
|
||||
changeCurriculumRequestRepository.save(toEdit);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
@ -309,4 +353,18 @@ public class RequestsController {
|
||||
UserCurriculum userCurriculum = new UserCurriculum(u, toEdit.getDestinationCurriculum(), c.get(Calendar.YEAR), true);
|
||||
userCurriculumRepository.save(userCurriculum);
|
||||
}
|
||||
|
||||
@GetMapping("/exemptionreq/{userId}")
|
||||
public ResponseEntity<ArrayList<ExemptionsRequest>> getExReqByuser(@RequestHeader("Authorization") String token, @PathVariable long userId){
|
||||
User currentUser = tokenService.getUserFromToken(token);
|
||||
|
||||
//Only admin, teacher, secretary and the student himself can access a student's data here
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Teacher, Role.Secretary},token) && currentUser.getRegNo() != userId)
|
||||
return new UnauthorizedResponse<>(null);
|
||||
|
||||
User u = userRepository.findById(userId);
|
||||
|
||||
ArrayList<ExemptionsRequest> exList = err.findByUser(u);
|
||||
return new ResponseEntity<>(exList, HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
|
@ -12,14 +12,8 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
|
||||
import ovh.herisson.Clyde.Services.AuthenticatorService;
|
||||
import ovh.herisson.Clyde.Services.LessonRequestService;
|
||||
import ovh.herisson.Clyde.Services.LessonService;
|
||||
import ovh.herisson.Clyde.Services.ProtectionService;
|
||||
import ovh.herisson.Clyde.Tables.LessonChangesRequest;
|
||||
import ovh.herisson.Clyde.Tables.RequestState;
|
||||
import ovh.herisson.Clyde.Tables.Role;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
import ovh.herisson.Clyde.Services.*;
|
||||
import ovh.herisson.Clyde.Tables.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@ -28,11 +22,13 @@ import java.util.Map;
|
||||
public class LessonRequestsController {
|
||||
private final LessonRequestService lessonRequestServ;
|
||||
private final AuthenticatorService authServ;
|
||||
private final UserService userServ;
|
||||
|
||||
private final LessonService lessonServ;
|
||||
public LessonRequestsController(LessonRequestService lessonRequestServer, AuthenticatorService authServ, LessonService lessonServ) {
|
||||
public LessonRequestsController(LessonRequestService lessonRequestServer, AuthenticatorService authServ, UserService userServ, LessonService lessonServ) {
|
||||
this.lessonRequestServ = lessonRequestServer;
|
||||
this.authServ = authServ;
|
||||
this.userServ = userServ;
|
||||
this.lessonServ = lessonServ;
|
||||
}
|
||||
/**
|
||||
@ -113,6 +109,7 @@ public class LessonRequestsController {
|
||||
if(lessonRequest.getRequestType() == 0 ) {
|
||||
if (!lessonRequestServ.modifyCreateRequestState(lessonRequest, state, local))
|
||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||
userServ.Notify(lessonRequest.getUser(), new Notification("Request took in charge","Request"+ state + ":" + lessonRequest.getCourse().getTitle(), "#/manage-owned-lessons"));
|
||||
}
|
||||
|
||||
else if(lessonRequest.getRequestType() == 1){
|
||||
@ -122,12 +119,14 @@ public class LessonRequestsController {
|
||||
if(!lessonRequestServ.modifyChangeRequestState(infos,lessonRequest.getLessonId(),state))
|
||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||
lessonRequest.setState(state);
|
||||
userServ.Notify(lessonRequest.getUser(), new Notification("Request took in charge","Request"+ state + ":" + lessonServ.findById(lessonRequest.getLessonId()).getCourse().getTitle(), "#/manage-owned-lessons"));
|
||||
|
||||
}
|
||||
|
||||
else{
|
||||
userServ.Notify(lessonRequest.getUser(), new Notification("Request took in charge","Request"+ state + ":" + lessonServ.findById(lessonRequest.getLessonId()).getCourse().getTitle(), "#/manage-owned-lessons"));
|
||||
lessonRequestServ.modifyDeleteRequest(lessonRequest, state);
|
||||
lessonRequest.setState(state);
|
||||
|
||||
}
|
||||
lessonRequestServ.save(lessonRequest);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
|
@ -1,6 +1,5 @@
|
||||
package ovh.herisson.Clyde.EndPoints;
|
||||
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ovh.herisson.Clyde.Repositories.*;
|
||||
import ovh.herisson.Clyde.Repositories.Inscription.ExternalCurriculumRepository;
|
||||
@ -8,19 +7,24 @@ import ovh.herisson.Clyde.Repositories.Inscription.MinervalRepository;
|
||||
import ovh.herisson.Clyde.Repositories.Inscription.ScholarshipRequestRepository;
|
||||
import ovh.herisson.Clyde.Repositories.Inscription.UnregisterRequestRepository;
|
||||
import ovh.herisson.Clyde.Services.*;
|
||||
import ovh.herisson.Clyde.Services.Inscription.InscriptionService;
|
||||
import ovh.herisson.Clyde.Services.ScientificPublications.ResearchesService;
|
||||
import ovh.herisson.Clyde.Tables.*;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Access;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.PaperType;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Research;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher;
|
||||
import ovh.herisson.Clyde.Services.Inscription.InscriptionService;
|
||||
import ovh.herisson.Clyde.Tables.Inscription.ExternalCurriculum;
|
||||
import ovh.herisson.Clyde.Tables.Inscription.InscriptionRequest;
|
||||
import ovh.herisson.Clyde.Tables.Inscription.Minerval;
|
||||
import ovh.herisson.Clyde.Tables.Inscription.ScholarshipRequest;
|
||||
import ovh.herisson.Clyde.Tables.Inscription.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.*;
|
||||
|
||||
@RestController
|
||||
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
|
||||
|
||||
public class MockController {
|
||||
private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
||||
public final UserService userService;
|
||||
public final UserRepository userRepo;
|
||||
public final TokenRepository tokenRepo;
|
||||
@ -38,14 +42,14 @@ public class MockController {
|
||||
public final LessonRequestService lessonRequestService;
|
||||
ArrayList<User> mockUsers;
|
||||
|
||||
public static boolean isMocked = false;
|
||||
public final ResearchesService researchesService;
|
||||
public final UserCurriculumRepository ucr;
|
||||
|
||||
public final MinervalRepository minervalRepository;
|
||||
|
||||
public final ScholarshipRequestRepository scholarshipRequestRepository;
|
||||
|
||||
|
||||
public final UnregisterRequestRepository uninscriptionRequestRepository;
|
||||
public MockController(UserService userService, UserRepository userRepo, TokenRepository tokenRepo, TokenService tokenService, CurriculumCourseService CurriculumCourseService, CurriculumService curriculumService, CourseService courseService, ExternalCurriculumRepository externalCurriculumRepository, InscriptionService inscriptionService, UserCurriculumRepository ucr, MinervalRepository minervalRepository, ScholarshipRequestRepository scholarshipRequestRepository, UnregisterRequestRepository unregisterRequestRepository, LessonService lessonService, ScheduleService scheduleService, ScheduleLessonService scheduleLessonService, LessonRequestService lessonRequestService){
|
||||
public MockController(UserService userService, UserRepository userRepo, TokenRepository tokenRepo, TokenService tokenService, CurriculumCourseService CurriculumCourseService, CurriculumService curriculumService, CourseService courseService, ExternalCurriculumRepository externalCurriculumRepository, ResearchesService researchesService, InscriptionService inscriptionService, UserCurriculumRepository ucr, MinervalRepository minervalRepository, ScholarshipRequestRepository scholarshipRequestRepository, UnregisterRequestRepository unregisterRequestRepository, LessonService lessonService, ScheduleService scheduleService, ScheduleLessonService scheduleLessonService, LessonRequestService lessonRequestService){
|
||||
this.userService = userService;
|
||||
this.tokenRepo = tokenRepo;
|
||||
this.userRepo = userRepo;
|
||||
@ -55,6 +59,7 @@ public class MockController {
|
||||
this.courseService = courseService;
|
||||
this.externalCurriculumRepository = externalCurriculumRepository;
|
||||
this.inscriptionService = inscriptionService;
|
||||
this.researchesService = researchesService;
|
||||
this.lessonService = lessonService;
|
||||
this.scheduleService = scheduleService;
|
||||
this.scheduleLessonService = scheduleLessonService;
|
||||
@ -72,16 +77,17 @@ public class MockController {
|
||||
*/
|
||||
|
||||
@PostMapping("/mock")
|
||||
public void postMock(){
|
||||
public void postMock() {
|
||||
|
||||
if(!isMocked){
|
||||
// user part
|
||||
User herobrine = new User("brine","hero","admin@admin.com","behind","ShadowsLand",new Date(0), null,Role.Admin,passwordEncoder.encode("admin"));
|
||||
User joe = new User("Mama","Joe","student@student.com","roundabout","England",new Date(0), null,Role.Student,passwordEncoder.encode("student"));
|
||||
User meh = new User("Polo","Marco","secretary@secretary.com","a Box","Monaco",new Date(0), null,Role.Secretary,passwordEncoder.encode("secretary"));
|
||||
User joke = new User("Gaillard","Corentin","teacher@teacher.com","lab","faculty",new Date(0), null,Role.Teacher,passwordEncoder.encode("teacher"));
|
||||
User jojo = new User("Bridoux","Justin","teacher2@teacher2.com","lab","faculty",new Date(0), null,Role.Teacher,passwordEncoder.encode("teacher"));
|
||||
User lena = new User("Louille","Lena","inscriptionService@InscriptionService.com","no","yes",new Date(0), null,Role.InscriptionService,passwordEncoder.encode("inscriptionService"));
|
||||
User popo = new User("Smith", "Paul", "paulsmith@gmail.com", "306 rue du poulet", "belgique", new Date(0), null, Role.Student, passwordEncoder.encode("jesuispaulleroi"));
|
||||
User herobrine = new User("brine","hero","admin@admin.com","behind","ShadowsLand",new Date(0), null,Role.Admin,"admin");
|
||||
User joe = new User("Piplo","Joe","student@student.com","roundabout","England",new Date(0), null,Role.Student,"student");
|
||||
User meh = new User("Polo","Marco","secretary@secretary.com","a Box","Monaco",new Date(0), null,Role.Secretary,"secretary");
|
||||
User joke = new User("Gaillard","Corentin","teacher@teacher.com","lab","faculty",new Date(0), null,Role.Teacher,"teacher");
|
||||
User jojo = new User("Bridoux","Justin","teacher2@teacher2.com","lab","faculty",new Date(0), null,Role.Teacher,"teacher");
|
||||
User lena = new User("Louille","Lena","inscriptionService@InscriptionService.com","no","yes",new Date(0), null,Role.InscriptionService,"inscriptionService");
|
||||
User popo = new User("Smith", "Paul", "paulsmith@gmail.com", "306 rue du poulet", "belgique", new Date(0), null, Role.Student, "jesuispaulleroi");
|
||||
mockUsers = new ArrayList<>(Arrays.asList(herobrine,joe,meh,joke,lena,jojo, popo));
|
||||
|
||||
userService.saveAll(mockUsers);
|
||||
@ -89,9 +95,9 @@ public class MockController {
|
||||
ExternalCurriculum externalCurriculum = new ExternalCurriculum(null, "HEH", "Bachelier en ingénieur", "completed", 2015, 2017, null, joe);
|
||||
externalCurriculumRepository.save(externalCurriculum);
|
||||
|
||||
Minerval minerval = new Minerval(joe.getRegNo(), 0, 852, 2023);
|
||||
minervalRepository.save(minerval);
|
||||
// Course / Curriculum part
|
||||
Minerval minerval = new Minerval(joe.getRegNo(), 0, 852, 2023);
|
||||
minervalRepository.save(minerval);
|
||||
// Course / Curriculum part
|
||||
|
||||
Curriculum infoBab1 = new Curriculum(1,"info", false);
|
||||
Curriculum chemistryBab1 = new Curriculum(1,"chemistry", false);
|
||||
@ -119,40 +125,71 @@ public class MockController {
|
||||
ucr.save(new UserCurriculum(popo, infoBab2, 2023, true));
|
||||
|
||||
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 commun = new Course(2, "cours commun",joke);
|
||||
|
||||
courseService.save(progra1);
|
||||
courseService.save(chemistry1);
|
||||
courseService.save(psycho1);
|
||||
courseService.save(commun);
|
||||
courseService.save(progra1);
|
||||
courseService.save(chemistry1);
|
||||
courseService.save(psycho1);
|
||||
courseService.save(commun);
|
||||
|
||||
ScholarshipRequest ssr1 = new ScholarshipRequest(joe, RequestState.Pending, 0, new Date(), "test", "test");
|
||||
scholarshipRequestRepository.save(ssr1);
|
||||
|
||||
ScholarshipRequest ssr1 = new ScholarshipRequest(joe, RequestState.Pending, 0, new Date(), "test", "test");
|
||||
scholarshipRequestRepository.save(ssr1);
|
||||
|
||||
CurriculumCourseService.save(new CurriculumCourse(infoBab1,progra1));
|
||||
CurriculumCourseService.save(new CurriculumCourse(infoBab1,commun));
|
||||
CurriculumCourseService.save(new CurriculumCourse(infoBab1, psycho1));
|
||||
CurriculumCourseService.save(new CurriculumCourse(psychologyBab1,psycho1));
|
||||
CurriculumCourseService.save(new CurriculumCourse(psychologyBab1,commun));
|
||||
CurriculumCourseService.save(new CurriculumCourse(chemistryBab1, chemistry1));
|
||||
|
||||
CurriculumCourseService.save(new CurriculumCourse(chemistryBab1, commun));
|
||||
CurriculumCourseService.save(new CurriculumCourse(chemistryBab1, chemistry1));
|
||||
|
||||
CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,commun));
|
||||
CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,chemistry1));
|
||||
|
||||
InscriptionRequest inscriptionRequest = new InscriptionRequest("helen","prenom","non","helen@gmail.com","america",new Date(),(long) 4,RequestState.Pending,"yes.png","password", null, new Date(), RequestState.Pending, null);
|
||||
|
||||
inscriptionService.save(inscriptionRequest);
|
||||
inscriptionService.save(inscriptionRequest);
|
||||
|
||||
///////////////////////////
|
||||
// extension Publications Scientifiques
|
||||
Researcher jojoResearcherAccount = new Researcher(jojo, "3363-22555-AB33-T", null, "IT");
|
||||
|
||||
Researcher joResearchAccount = new Researcher(joe,"N555-321213-BED-DD",null, "Physics");
|
||||
|
||||
|
||||
Researcher output = researchesService.saveResearcher(jojoResearcherAccount);
|
||||
Researcher joOutput = researchesService.saveResearcher(joResearchAccount);
|
||||
|
||||
Set<Researcher> coAuthor = new HashSet<>();
|
||||
coAuthor.add(joOutput);
|
||||
|
||||
Research jojoResearch = new Research("Graphs : Advanced Search Algorithms", output, new Date(0),
|
||||
PaperType.Article, "test.pdf", null, "english",
|
||||
Access.OpenSource, "IT", "This Article's title speaks for itself \n We'll discuss about advanced Graph search Algorithms",coAuthor);
|
||||
Research restrictedResearch = new Research("the great Constantinople war", output, new Date(1111111111),
|
||||
PaperType.Article, "restricted", null, "Portuguese",
|
||||
Access.Restricted, "history", "this is a summary", new HashSet<>());
|
||||
|
||||
Research privateResearch = new Research("the great Potato War", output, new Date(),
|
||||
PaperType.Article, "private", null, "english",
|
||||
Access.Private, "agriculture", "my life is potato",null);
|
||||
|
||||
|
||||
researchesService.saveResearch(restrictedResearch);
|
||||
researchesService.saveResearch(privateResearch);
|
||||
researchesService.saveResearch(jojoResearch);
|
||||
|
||||
|
||||
//Schedule part
|
||||
|
||||
Lesson lesson_0_progra1 = new Lesson(progra1, "Mon Apr 22 2024 08:15", "Mon Apr 22 2024 10:15","rgb(0,50,100)","A0B2","Course");
|
||||
Lesson lesson_0_chemistry1 = new Lesson(chemistry1, "Wed Mar 27 2024 08:15", "Wed Mar 27 2024 09:15","rgb(100,50,0)","A0B2","TP");
|
||||
Lesson lesson_0_psycho1 = new Lesson(psycho1, "Sun Mar 24 2024 10:30 ","Sun Mar 24 2024 12:30 ","rgb(100,50,100)", "A0B2","TD");
|
||||
Lesson lesson_1_progra1 = new Lesson(progra1, "Mon Apr 02 2024 13:30", "Mon Apr 02 2024 15:30","rgb(0,50,100)","A0B2","TP");
|
||||
Lesson lesson_0_commun = new Lesson(commun, "Mon Apr 01 2024 10:30", "Mon Apr 01 2024 12:30","rgb(0,50,100)","A0B2","Course");
|
||||
Lesson lesson_0_progra1 = new Lesson(progra1, "Mon Apr 22 2024 08:15", "Mon Apr 22 2024 10:15","rgb(255,36,175)","A0B2","Course");
|
||||
Lesson lesson_0_chemistry1 = new Lesson(chemistry1, "Wed Mar 27 2024 08:15", "Wed Mar 27 2024 09:15","rgb(36,175,255)","A0B2","TP");
|
||||
Lesson lesson_0_psycho1 = new Lesson(psycho1, "Sun Mar 24 2024 10:30 ","Sun Mar 24 2024 12:30 ","rgb(255,36,175)", "A0B2","TD");
|
||||
Lesson lesson_1_progra1 = new Lesson(progra1, "Mon Apr 02 2024 13:30", "Mon Apr 02 2024 15:30","rgb(36,175,255)","A0B2","TP");
|
||||
Lesson lesson_0_commun = new Lesson(commun, "Mon Apr 01 2024 10:30", "Mon Apr 01 2024 12:30","rgb(255,36,175)","A0B2","Course");
|
||||
|
||||
LessonChangesRequest request1 = new LessonChangesRequest(joke,RequestState.Pending,null,null,null,null,2,null,1);
|
||||
LessonChangesRequest request2 = new LessonChangesRequest(joke,RequestState.Pending,"Fri Apr 19 2024 10:30 ","Fri Apr 19 2024 12:30 ",null,null,1,null,2);
|
||||
@ -194,6 +231,9 @@ public class MockController {
|
||||
|
||||
externalCurriculum = new ExternalCurriculum(inscriptionRequest, "HEH", "Bachelier en informatique", "Completed", 2015, 2018, null, null);
|
||||
externalCurriculumRepository.save(externalCurriculum);
|
||||
|
||||
isMocked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) || f.getCourse().getOwner().equals(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);
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package ovh.herisson.Clyde.EndPoints;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
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.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import ovh.herisson.Clyde.Repositories.NotificationRepository;
|
||||
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
|
||||
import ovh.herisson.Clyde.Services.AuthenticatorService;
|
||||
import ovh.herisson.Clyde.Tables.Notification;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
import ovh.herisson.Clyde.Tables.Notification.Status;
|
||||
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
|
||||
public class NotificationController {
|
||||
|
||||
private AuthenticatorService authServ;
|
||||
private NotificationRepository notifRepo;
|
||||
|
||||
@GetMapping("/notifications")
|
||||
public ResponseEntity<List<Notification>> getNotifications(@RequestHeader("Authorization") String token){
|
||||
User u = authServ.getUserFromToken(token);
|
||||
if(u == null){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
ArrayList<Notification> ret = new ArrayList<>();
|
||||
for (Notification n : u.getNotifications()) {
|
||||
if(!n.getStatus().equals(Status.Archived)){
|
||||
ret.add(n);
|
||||
}
|
||||
}
|
||||
return new ResponseEntity<>(ret, HttpStatus.OK);
|
||||
|
||||
}
|
||||
|
||||
@PostMapping("/notifications/{id}")
|
||||
public ResponseEntity<Notification> archiveNotification(@RequestHeader("Authorization") String token, @PathVariable long id){
|
||||
User u = authServ.getUserFromToken(token);
|
||||
Notification n = notifRepo.findById(id).orElse(null);
|
||||
if(u == null || n.getUser() != u){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
|
||||
n.setStatus(Status.Archived);
|
||||
notifRepo.save(n);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
}
|
@ -30,16 +30,13 @@ public class ScheduleController {
|
||||
private final ScheduleService scheduleServ;
|
||||
private final LessonService lessonServ;
|
||||
|
||||
private final UserCurriculumService userCurriculumService;
|
||||
|
||||
private final CurriculumService curriculumServ;
|
||||
private final AuthenticatorService authServ;
|
||||
|
||||
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.userCurriculumService = userCurriculumService;
|
||||
this.authServ = authServ;
|
||||
this.scheduleLessonServ = scheduleLessonServ;
|
||||
this.curriculumServ = curriculumServ;
|
||||
|
@ -0,0 +1,167 @@
|
||||
package ovh.herisson.Clyde.EndPoints.ScientificPublications;
|
||||
|
||||
/******************************************************
|
||||
* @file ResearchController.java
|
||||
* @author Bartha Maxime
|
||||
* @scope Publications Scientifiques
|
||||
*
|
||||
* API class for the researches
|
||||
******************************************************/
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ovh.herisson.Clyde.DTO.ScientificPublications.ResearchDTO;
|
||||
import ovh.herisson.Clyde.DTO.ScientificPublications.ResearcherDTO;
|
||||
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
|
||||
import ovh.herisson.Clyde.Services.AuthenticatorService;
|
||||
import ovh.herisson.Clyde.Services.ScientificPublications.ResearchesService;
|
||||
import ovh.herisson.Clyde.Tables.Role;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Research;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
|
||||
@AllArgsConstructor
|
||||
public class ResearchController {
|
||||
|
||||
|
||||
|
||||
private final ResearchesService researchesServ;
|
||||
|
||||
private final AuthenticatorService authServ;
|
||||
|
||||
/** Is accessible by anyone
|
||||
* but if the user doesn't have the permission to download the research
|
||||
* the return Research Download URL will be null
|
||||
*/
|
||||
@GetMapping("/research/{id}")
|
||||
public ResponseEntity<ResearchDTO> getResearch(@RequestHeader(value = "Authorization", required = false) String token, @PathVariable long id){
|
||||
|
||||
Research research = researchesServ.getResearchById(id);
|
||||
|
||||
if (research == null)
|
||||
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
||||
|
||||
if (researchesServ.hasNoAccessTo(research,authServ.getUserFromToken(token))){
|
||||
research.setPdfLocation(null);
|
||||
}// If the user doesn't have access to the document he can't download the pdf
|
||||
|
||||
return new ResponseEntity<>(ResearchDTO.construct(research), HttpStatus.OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param token used to know if the user can download or not the research pdf
|
||||
* @return every research
|
||||
*/
|
||||
@GetMapping("/researches")
|
||||
public ResponseEntity<Iterable<ResearchDTO>> getResearches(@RequestHeader(value = "Authorization",required = false) String token){
|
||||
Iterable<Research> researches = researchesServ.getAllResearches();
|
||||
|
||||
ArrayList<ResearchDTO> toReturnResearches = new ArrayList<>();
|
||||
|
||||
for (Research research: researches){
|
||||
if (researchesServ.hasNoAccessTo(research,authServ.getUserFromToken(token))){
|
||||
research.setPdfLocation(null);
|
||||
}
|
||||
toReturnResearches.add(ResearchDTO.construct(research));
|
||||
}
|
||||
return new ResponseEntity<>(toReturnResearches,HttpStatus.OK);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/researches/{id}")
|
||||
public ResponseEntity<Iterable<ResearchDTO>> getResearchesFromResearcher(@RequestHeader(value = "Authorization",required = false) String token,
|
||||
@PathVariable Long id
|
||||
){
|
||||
Iterable<Research> researches = researchesServ.getResearchesByAuthor(id);
|
||||
if (researches == null) return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
||||
|
||||
ArrayList<ResearchDTO> toReturnResearches = new ArrayList<>();
|
||||
|
||||
for (Research research: researches){
|
||||
if (researchesServ.hasNoAccessTo(research,authServ.getUserFromToken(token))){
|
||||
research.setPdfLocation(null);
|
||||
}
|
||||
toReturnResearches.add(ResearchDTO.construct(research));
|
||||
}
|
||||
return new ResponseEntity<>(toReturnResearches,HttpStatus.OK);
|
||||
}
|
||||
|
||||
/** post a new research
|
||||
*
|
||||
* @return the research saved
|
||||
*/
|
||||
@PostMapping("/research")
|
||||
public ResponseEntity<Research> postResearch(@RequestHeader("Authorization") String token, @RequestBody Research research){
|
||||
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin},token) &&
|
||||
researchesServ.getResearcherByUser(authServ.getUserFromToken(token)) == null){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
} // if the poster isn't a researcher
|
||||
|
||||
return new ResponseEntity<>(researchesServ.saveResearch(research), HttpStatus.OK);
|
||||
}
|
||||
|
||||
/** post updates to the research
|
||||
* in the updates, the coAuthors have to be referenced by their ids
|
||||
*
|
||||
*/
|
||||
@PatchMapping("/research/{id}")
|
||||
public ResponseEntity<String> patchResearch(@RequestHeader("Authorization") String token,
|
||||
@RequestBody Map<String,Object> updates,
|
||||
@PathVariable long id
|
||||
)
|
||||
{
|
||||
Research research = researchesServ.getResearchById(id);
|
||||
Researcher researcher = researchesServ.getResearcherByUser(authServ.getUserFromToken(token));
|
||||
|
||||
if (research == null)
|
||||
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
||||
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token) &&
|
||||
researcher != research.getAuthor()) {
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
|
||||
researchesServ.modifyResearchData(research, updates);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
/** Only Admin, Secretary and author can delete a research
|
||||
*
|
||||
*/
|
||||
@DeleteMapping("/research/{id}")
|
||||
public ResponseEntity<String> deleteResearch(@RequestHeader("Authorization") String token, @PathVariable long id){
|
||||
|
||||
Research research = researchesServ.getResearchById(id);
|
||||
Researcher researcher = researchesServ.getResearcherByUser(authServ.getUserFromToken(token));
|
||||
|
||||
if (research == null)
|
||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin, Role.Secretary},token) &&
|
||||
researcher != research.getAuthor()){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
|
||||
researchesServ.deleteResearch(research);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
|
||||
///////
|
||||
//views part
|
||||
@PostMapping("/addview/cdn/{url}")
|
||||
public ResponseEntity<ResearchDTO> addView(@PathVariable String url){
|
||||
System.out.println(url);
|
||||
Research research = researchesServ.getResearchByUrl("cdn/" + url);
|
||||
if (research ==null) return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||
|
||||
return new ResponseEntity<>(ResearchDTO.construct(researchesServ.addView(research)), HttpStatus.OK);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
package ovh.herisson.Clyde.EndPoints.ScientificPublications;
|
||||
|
||||
/******************************************************
|
||||
* @file ResearcherController.java
|
||||
* @author Bartha Maxime
|
||||
* @scope Publications Scientifiques
|
||||
*
|
||||
* API class for the researchers
|
||||
******************************************************/
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ovh.herisson.Clyde.DTO.ScientificPublications.ResearcherDTO;
|
||||
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
|
||||
import ovh.herisson.Clyde.Services.AuthenticatorService;
|
||||
import ovh.herisson.Clyde.Services.ScientificPublications.ResearchesService;
|
||||
import ovh.herisson.Clyde.Tables.Role;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
|
||||
@AllArgsConstructor
|
||||
public class ResearcherController {
|
||||
|
||||
ResearchesService researchesServ;
|
||||
AuthenticatorService authServ;
|
||||
|
||||
|
||||
@GetMapping("/researcher/{id}")
|
||||
public ResponseEntity<ResearcherDTO> getResearcher(@PathVariable long id){
|
||||
Researcher researcher = researchesServ.getResearcherById(id);
|
||||
return new ResponseEntity<>(ResearcherDTO.construct(researcher),HttpStatus.OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Everyone can access every researcher Account
|
||||
* @return all the researchers accounts
|
||||
*/
|
||||
@GetMapping("/researchers")
|
||||
public ResponseEntity<Iterable<ResearcherDTO>> getAllResearchers(){
|
||||
Iterable<Researcher> researchers = researchesServ.getAllResearchers();
|
||||
ArrayList<ResearcherDTO> toReturnResearchersDTO = new ArrayList<>();
|
||||
for (Researcher researcher: researchers){
|
||||
toReturnResearchersDTO.add(ResearcherDTO.construct(researcher));
|
||||
}
|
||||
return new ResponseEntity<>(toReturnResearchersDTO, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/researcher")
|
||||
public ResponseEntity<ResearcherDTO> getSelf(@RequestHeader("Authorization") String token){
|
||||
|
||||
Researcher self = researchesServ.getResearcherByUser(authServ.getUserFromToken(token));
|
||||
|
||||
if (self ==null) return new UnauthorizedResponse<>(null);
|
||||
|
||||
return new ResponseEntity<>(ResearcherDTO.construct(self), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping("/researcher")
|
||||
public ResponseEntity<ResearcherDTO> postResearcher(@RequestHeader("Authorization") String token, @RequestBody Researcher researcher){
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary}, token)){
|
||||
return new UnauthorizedResponse<>(null);
|
||||
}
|
||||
|
||||
Researcher posted = researchesServ.saveResearcher(researcher);
|
||||
|
||||
if (posted == null) return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
|
||||
|
||||
return new ResponseEntity<>(ResearcherDTO.construct(posted), HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@PatchMapping("/researcher/{id}")
|
||||
public ResponseEntity<ResearcherDTO> patchResearcher(@RequestHeader("Authorization") String token,
|
||||
@PathVariable long id,
|
||||
@RequestBody Map<String ,Object> updates){
|
||||
|
||||
Researcher researcher = researchesServ.getResearcherById(id);
|
||||
if (authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin}, token)
|
||||
&& researcher.getId() != researchesServ.getResearcherByUser(authServ.getUserFromToken(token)).getId())
|
||||
return new UnauthorizedResponse<>(null);
|
||||
|
||||
|
||||
if (researcher == null) return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||
|
||||
researchesServ.modifyResearcherData(researcher,updates);
|
||||
|
||||
return new ResponseEntity<>(ResearcherDTO.construct(researcher),HttpStatus.OK);
|
||||
}
|
||||
|
||||
@DeleteMapping("/researcher/{id}")
|
||||
public ResponseEntity<String> deleteResearcher(@RequestHeader ("Authorization") String token, @PathVariable long id){
|
||||
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token))
|
||||
return new UnauthorizedResponse<>(null);
|
||||
|
||||
researchesServ.deleteResearcher(researchesServ.getResearcherById(id));
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package ovh.herisson.Clyde.EndPoints.ScientificPublications;
|
||||
|
||||
/******************************************************
|
||||
* @file StatController.java
|
||||
* @author Bartha Maxime
|
||||
* @scope Publications Scientifiques
|
||||
*
|
||||
* Api class for handling statistics
|
||||
******************************************************/
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import ovh.herisson.Clyde.Services.ScientificPublications.ResearchesService;
|
||||
import ovh.herisson.Clyde.Services.ScientificPublications.StatisticsService;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@RestController
|
||||
@CrossOrigin(originPatterns = "*", allowCredentials = "true")
|
||||
@AllArgsConstructor
|
||||
public class StatController {
|
||||
|
||||
|
||||
private StatisticsService statServ;
|
||||
private ResearchesService researchesServ;
|
||||
|
||||
/** returns all the statistics in a 2D array
|
||||
*
|
||||
* @param id the researcher's id
|
||||
* @return all the stats in a 2D array
|
||||
*/
|
||||
@GetMapping("/stats/{id}")
|
||||
public ResponseEntity<Iterable<Iterable<Map<String, Integer>>>> getStat(@PathVariable Long id){
|
||||
|
||||
Researcher researcher = researchesServ.getResearcherById(id);
|
||||
if (researcher == null) return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||
|
||||
Iterable<Iterable<Map<String,Integer>>> stats = statServ.generateStats(researcher);
|
||||
|
||||
if (stats == null) return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||
|
||||
return new ResponseEntity<>(stats,HttpStatus.OK);
|
||||
|
||||
}
|
||||
}
|
@ -44,7 +44,7 @@ public class UserController {
|
||||
@GetMapping("/user/{id}")
|
||||
public ResponseEntity<HashMap<String ,Object>> getUserById(@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.Secretary,Role.InscriptionService, Role.Teacher},token))
|
||||
return new UnauthorizedResponse<>(null);
|
||||
|
||||
return new ResponseEntity<>(ProtectionService.userWithoutPassword(userService.getUserById(id)), HttpStatus.OK);
|
||||
@ -86,19 +86,20 @@ public class UserController {
|
||||
* @return a string clarifying the issue (if there is any)
|
||||
*/
|
||||
@PatchMapping("/user/{id}")
|
||||
public ResponseEntity<String> patchUser(@RequestHeader("Authorization") String token,
|
||||
public ResponseEntity<Map<String,Object>> patchUser(@RequestHeader("Authorization") String token,
|
||||
@RequestBody Map<String,Object> updates,
|
||||
@PathVariable Long id) {
|
||||
|
||||
if (token == null) return new UnauthorizedResponse<>(null);
|
||||
|
||||
User poster = authServ.getUserFromToken(token);
|
||||
if (poster == null) {return new UnauthorizedResponse<>("bad token");}
|
||||
if (poster == null) {return new UnauthorizedResponse<>(null);}
|
||||
|
||||
if (!userService.modifyData(id, updates, poster))
|
||||
return new UnauthorizedResponse<>("there was an issue with the updates requested");
|
||||
User modified = userService.modifyData(id,updates,poster);
|
||||
if (modified ==null)
|
||||
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
|
||||
|
||||
return new ResponseEntity<>(null, HttpStatus.OK);
|
||||
return new ResponseEntity<>(ProtectionService.userWithoutPassword(modified), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/teachers")
|
||||
|
@ -1,5 +1,7 @@
|
||||
package ovh.herisson.Clyde.Repositories;
|
||||
|
||||
import jakarta.transaction.Transactional;
|
||||
import org.springframework.data.jpa.repository.Modifying;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import ovh.herisson.Clyde.Tables.Course;
|
||||
@ -11,7 +13,15 @@ public interface CurriculumCourseRepository extends CrudRepository<CurriculumCou
|
||||
@Query("select distinct cc.course from CurriculumCourse cc where cc.curriculum = ?1")
|
||||
Iterable<Course> findCoursesByCurriculum(Curriculum curriculum);
|
||||
|
||||
@Query("select distinct cc.curriculum from CurriculumCourse cc where cc.course = ?1")
|
||||
Iterable<Curriculum> findCurriculumByCourses(Course course);
|
||||
|
||||
@Query("select distinct cc.curriculum from CurriculumCourse cc")
|
||||
Iterable<Curriculum> findDistinctCurriculums();
|
||||
|
||||
@Modifying
|
||||
@Transactional
|
||||
@Query("delete from CurriculumCourse cc where cc.course =?1")
|
||||
void delete(Course course);
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package ovh.herisson.Clyde.Repositories.Inscription;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import ovh.herisson.Clyde.Tables.ChangeCurriculumRequest;
|
||||
import ovh.herisson.Clyde.Tables.Inscription.ChangeCurriculumRequest;
|
||||
|
||||
public interface ChangeCurriculumRequestRepository extends CrudRepository<ChangeCurriculumRequest, Long> {
|
||||
ChangeCurriculumRequest findById(long id);
|
||||
|
@ -2,7 +2,12 @@ package ovh.herisson.Clyde.Repositories.Inscription;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import ovh.herisson.Clyde.Tables.Inscription.ExemptionsRequest;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public interface ExemptionsRequestRepository extends CrudRepository<ExemptionsRequest, Long> {
|
||||
ExemptionsRequest findById(long id);
|
||||
|
||||
ArrayList<ExemptionsRequest> findByUser(User user);
|
||||
}
|
||||
|
@ -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> {
|
||||
|
||||
}
|
||||
|
@ -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> {
|
||||
|
||||
}
|
@ -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> {
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
package ovh.herisson.Clyde.Repositories;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
import ovh.herisson.Clyde.Tables.Notification;
|
||||
|
||||
public interface NotificationRepository extends CrudRepository<Notification, Long> {}
|
||||
|
@ -22,6 +22,9 @@ public interface ScheduleLessonRepository extends CrudRepository<ScheduleLesson,
|
||||
@Query("select distinct sl.schedule from ScheduleLesson sl where sl.schedule.curriculum = ?1")
|
||||
Schedule findScheduleByCurriculum(Curriculum curriculum);
|
||||
|
||||
@Query("select distinct sl from ScheduleLesson sl where sl.lesson = ?1")
|
||||
ScheduleLesson findByLesson(Lesson lesson);
|
||||
|
||||
@Modifying
|
||||
@Transactional
|
||||
@Query("delete from ScheduleLesson sl where sl.lesson =?1")
|
||||
|
@ -0,0 +1,26 @@
|
||||
package ovh.herisson.Clyde.Repositories.ScientificPublications;
|
||||
|
||||
/******************************************************
|
||||
* @file ResearchRepository.java
|
||||
* @author Bartha Maxime
|
||||
* @scope Publications Scientifiques
|
||||
*
|
||||
* Repository handling communication with Reseach table
|
||||
******************************************************/
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Research;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface ResearchRepository extends CrudRepository<Research,Long> {
|
||||
|
||||
Research findById(long id);
|
||||
|
||||
Iterable<Research> findByAuthor(Researcher author);
|
||||
|
||||
@Query("select r from Research r where r.pdfLocation = ?1")
|
||||
Research findByPdfLocation(String url);
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package ovh.herisson.Clyde.Repositories.ScientificPublications;
|
||||
|
||||
/******************************************************
|
||||
* @file ResearcherRepository.java
|
||||
* @author Bartha Maxime
|
||||
* @scope Publications Scientifiques
|
||||
*
|
||||
* Repository handling communication with Reseacher table
|
||||
******************************************************/
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Research;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
|
||||
public interface ResearcherRepository extends CrudRepository<Researcher,Long> {
|
||||
Researcher findByUser(User user);
|
||||
|
||||
Researcher findById(long id);
|
||||
|
||||
@Query("select r from Research r where r.author = ?1")
|
||||
Iterable<Research> findAllByAuthorId(Researcher author);
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package ovh.herisson.Clyde.Repositories.ScientificPublications;
|
||||
|
||||
/******************************************************
|
||||
* @file StatsRepository.java
|
||||
* @author Bartha Maxime
|
||||
* @scope Publications Scientifiques
|
||||
*
|
||||
* Repository handling communication with Reseach table for making statistics
|
||||
******************************************************/
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Research;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface StatsRepository extends CrudRepository<Research,Long> {
|
||||
|
||||
@Query("select new map(to_char(r.releaseDate, 'month') as label, sum(r.views) as y) from Research r where r.author.id = ?1 group by to_char(r.releaseDate, 'month')")
|
||||
Iterable<Map<String ,Integer>> viewsByMonths(long researcherId);
|
||||
|
||||
@Query("select new map(to_char(r.releaseDate,'YYYY') as label, sum (r.views) as y) from Research r group by to_char(r.releaseDate,'YYYY')")
|
||||
Iterable<Map<String ,Integer>> viewsByYears(long researcherId);
|
||||
|
||||
|
||||
@Query("select new map(r.domain as label, sum(r.views) as y) from Research r where r.author.id = ?1 group by r.domain")
|
||||
Iterable<Map<String ,Integer>> viewsByTopics(long researcherId);
|
||||
|
||||
|
||||
@Query("select new map(r.domain as label, count(distinct r.language) as y) from Research r where r.author.id = ?1 group by r.domain")
|
||||
Iterable<Map<String ,Integer>> languageByTopics(long researcherId);
|
||||
|
||||
@Query("select new map(to_char(r.releaseDate,'YYYY') as label, count(distinct r.language) as y) from Research r where r.author.id = ?1 group by to_char(r.releaseDate,'YYYY')")
|
||||
Iterable<Map<String ,Integer>> languageByYears(long researcherId);
|
||||
|
||||
@Query("select new map(to_char(r.releaseDate, 'month') as label, count(distinct r.language) as y) from Research r where r.author.id = ?1 group by to_char(r.releaseDate, 'month')")
|
||||
Iterable<Map<String ,Integer>> languageByMonths(long researcherId);
|
||||
|
||||
@Query("select new map(to_char(r.releaseDate,'YYYY') as label, count(distinct r) as y) from Research r where r.author.id = ?1 group by to_char(r.releaseDate,'YYYY')")
|
||||
Iterable<Map<String ,Integer>> researchesByYears(long researcherId);
|
||||
|
||||
@Query("select new map(r.domain as label, count(distinct r) as y) from Research r where r.author.id = ?1 group by r.domain")
|
||||
Iterable<Map<String ,Integer>> researchesByTopics(long researcherId);
|
||||
|
||||
@Query("select new map(to_char(r.releaseDate, 'month') as label, count(distinct r) as y) from Research r where r.author.id = ?1 group by to_char(r.releaseDate, 'month')")
|
||||
Iterable<Map<String ,Integer>> researchesByMonth(long researcherId);
|
||||
|
||||
}
|
@ -13,7 +13,11 @@ public interface UserCurriculumRepository extends CrudRepository<UserCurriculum,
|
||||
@Query("select uc.curriculum from UserCurriculum uc where uc.user = ?1")
|
||||
Curriculum findByUser(User student);
|
||||
|
||||
@Query("select distinct uc.user from UserCurriculum uc where uc.curriculum = ?1")
|
||||
Iterable<User> findUsersByCurriculum(Curriculum curriculum);
|
||||
|
||||
ArrayList<UserCurriculum> findByUserOrderByCurriculum(User student);
|
||||
UserCurriculum findByUserAndCurriculumAndActual(User user, Curriculum curriculum, boolean actual);
|
||||
|
||||
ArrayList<UserCurriculum> findByUserAndActual(User user, boolean actual);
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ public class AuthenticatorService {
|
||||
return tokenService.getUserFromToken(token);
|
||||
}
|
||||
|
||||
|
||||
public String login(String identifier, String password, Date expirationDate){
|
||||
User user = userService.getUser(identifier);
|
||||
if (user == null){return null;}
|
||||
|
@ -51,6 +51,10 @@ public class CurriculumCourseService {
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
public Iterable<Curriculum> findCurriculumByCourses(Course course){
|
||||
return curriculumCourseRepo.findCurriculumByCourses(course);
|
||||
}
|
||||
|
||||
public Iterable<Map<String, Object>> getAllDepthCurriculum(){
|
||||
|
||||
ArrayList<Map<String,Object>> toReturn = new ArrayList<>();
|
||||
|
@ -1,6 +1,5 @@
|
||||
package ovh.herisson.Clyde.Services.Inscription;
|
||||
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ovh.herisson.Clyde.Repositories.*;
|
||||
import ovh.herisson.Clyde.Repositories.Inscription.ExternalCurriculumRepository;
|
||||
@ -27,9 +26,9 @@ public class InscriptionService {
|
||||
private final CurriculumRepository curriculumRepo;
|
||||
|
||||
private final MinervalRepository minervalRepository;
|
||||
private final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
|
||||
private final ExternalCurriculumRepository externalCurriculumRepository;
|
||||
private final UserService userService;
|
||||
|
||||
public InscriptionService(InscriptionRepository inscriptionRepo, UserRepository userRepo, UserCurriculumRepository userCurriculumRepo, CurriculumRepository curriculumRepo, MinervalRepository minervalRepository, ExternalCurriculumRepository externalCurriculumRepository, UserService userService){
|
||||
this.inscriptionRepo = inscriptionRepo;
|
||||
this.userRepo = userRepo;
|
||||
@ -41,7 +40,6 @@ public class InscriptionService {
|
||||
}
|
||||
|
||||
public InscriptionRequest save(InscriptionRequest inscriptionRequest){
|
||||
inscriptionRequest.setPassword(passwordEncoder.encode(inscriptionRequest.getPassword()));
|
||||
return inscriptionRepo.save(inscriptionRequest);
|
||||
}
|
||||
|
||||
@ -59,6 +57,11 @@ public class InscriptionService {
|
||||
if (inscrRequest == null)
|
||||
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);
|
||||
save(inscrRequest);
|
||||
|
||||
@ -84,7 +87,8 @@ public class InscriptionService {
|
||||
inscrRequest.getCountry(),
|
||||
inscrRequest.getBirthDate(),
|
||||
inscrRequest.getProfilePicture(),
|
||||
inscrRequest.getPassword()
|
||||
inscrRequest.getPassword(),
|
||||
inscrRequest.getIdentityCard()
|
||||
);
|
||||
|
||||
userService.save(userFromRequest);
|
||||
|
@ -7,10 +7,7 @@ package ovh.herisson.Clyde.Services;
|
||||
* @scope Extension Horaire
|
||||
******************************************************/
|
||||
import org.springframework.stereotype.Service;
|
||||
import ovh.herisson.Clyde.Repositories.CourseRepository;
|
||||
import ovh.herisson.Clyde.Repositories.CurriculumCourseRepository;
|
||||
import ovh.herisson.Clyde.Repositories.LessonRepository;
|
||||
import ovh.herisson.Clyde.Repositories.UserCurriculumRepository;
|
||||
import ovh.herisson.Clyde.Repositories.*;
|
||||
import ovh.herisson.Clyde.Tables.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -19,13 +16,17 @@ import java.util.Map;
|
||||
@Service
|
||||
public class LessonService {
|
||||
private final LessonRepository lessonRepo;
|
||||
private final UserCurriculumRepository userCurriculumRepo;
|
||||
private final CourseRepository courseRepo;
|
||||
|
||||
private final ScheduleLessonRepository scheduleLessonRepo;
|
||||
private final UserCurriculumRepository userCurriculumRepo;
|
||||
private final UserService userServ;
|
||||
private final CourseRepository courseRepo;
|
||||
private final CurriculumCourseRepository curriculumCourseRepo;
|
||||
public LessonService(LessonRepository lessonRepo, UserCurriculumRepository userCurriculumRepo, CourseRepository courseRepo, CurriculumCourseRepository curriculumCourseRepo){
|
||||
public LessonService(LessonRepository lessonRepo, ScheduleLessonRepository scheduleLessonRepo, UserCurriculumRepository userCurriculumRepo, UserService userServ, CourseRepository courseRepo, CurriculumCourseRepository curriculumCourseRepo){
|
||||
this.lessonRepo = lessonRepo;
|
||||
this.scheduleLessonRepo = scheduleLessonRepo;
|
||||
this.userCurriculumRepo = userCurriculumRepo;
|
||||
this.userServ = userServ;
|
||||
this.courseRepo = courseRepo;
|
||||
this.curriculumCourseRepo = curriculumCourseRepo;
|
||||
}
|
||||
@ -65,11 +66,15 @@ public class LessonService {
|
||||
public Iterable<Lesson> findOnesLessons(User student){
|
||||
ArrayList<Lesson> toReturn = new ArrayList<>();
|
||||
ArrayList<Course> courses = new ArrayList<>();
|
||||
ArrayList<UserCurriculum> userCurriculums = userCurriculumRepo.findByUserOrderByCurriculum(student);
|
||||
for(UserCurriculum uc: userCurriculums){
|
||||
Curriculum c = uc.getCurriculum();
|
||||
if(uc.isActual())
|
||||
courses.addAll((ArrayList<Course>) curriculumCourseRepo.findCoursesByCurriculum(c));
|
||||
ArrayList<UserCurriculum> userCurricula = userCurriculumRepo.findByUserAndActual(student, true);
|
||||
for (UserCurriculum userCurriculum : userCurricula) {
|
||||
curriculumCourseRepo.findCoursesByCurriculum(userCurriculum.getCurriculum()).forEach((item) -> {
|
||||
//We need this to eliminate clones because a course can belong to several curriculums
|
||||
if (!courses.contains(item)) {
|
||||
System.out.println(item.getTitle());
|
||||
courses.add(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
for (Course element : courses) {
|
||||
for(Lesson lesson : lessonRepo.findLessonByCourse(element))
|
||||
@ -100,7 +105,7 @@ public class LessonService {
|
||||
case "lessonType":
|
||||
target.setLessonType((String) entry.getValue());
|
||||
break;
|
||||
case "courseId":
|
||||
case "courseID":
|
||||
target.setCourse(courseRepo.findById((int) entry.getValue()));
|
||||
break;
|
||||
}
|
||||
@ -133,7 +138,12 @@ public class LessonService {
|
||||
break;
|
||||
}
|
||||
}
|
||||
lessonRepo.save(target);
|
||||
Lesson lesson = lessonRepo.save(target);
|
||||
ScheduleLesson scheduleLesson = scheduleLessonRepo.findByLesson(lesson);
|
||||
Iterable<User> users = userCurriculumRepo.findUsersByCurriculum(scheduleLesson.getSchedule().getCurriculum());
|
||||
for(User user: users){
|
||||
userServ.Notify(user, new Notification("Course modified in the schedule", "Course Modified " + lesson.getCourse().getTitle() , "/#/schedule"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
|
@ -17,6 +17,8 @@ import org.springframework.stereotype.Service;
|
||||
import com.fasterxml.jackson.databind.util.JSONPObject;
|
||||
|
||||
import ovh.herisson.Clyde.Repositories.Msg.DiscussionRepository;
|
||||
import ovh.herisson.Clyde.Services.UserService;
|
||||
import ovh.herisson.Clyde.Tables.Notification;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Discussion;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Message;
|
||||
@ -26,6 +28,8 @@ public class DiscussionService {
|
||||
|
||||
@Autowired
|
||||
private DiscussionRepository discRepo;
|
||||
@Autowired
|
||||
private UserService userServ;
|
||||
|
||||
public Discussion create(String name, User author){
|
||||
return discRepo.save(new Discussion(name, author));
|
||||
@ -42,6 +46,9 @@ public class DiscussionService {
|
||||
* Create a message and link it to it's discussion
|
||||
*/
|
||||
public Discussion CreateMessage(Discussion disc, Message msg){
|
||||
for(User u: disc.getMembers()){
|
||||
userServ.Notify(u, new Notification("msg.notification.new", msg.getContent(), "/#/msg"));
|
||||
}
|
||||
disc.addMessage(msg);
|
||||
return discRepo.save(disc);
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
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.Services.UserService;
|
||||
import ovh.herisson.Clyde.Tables.Course;
|
||||
import ovh.herisson.Clyde.Tables.Notification;
|
||||
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 UserService userServ;
|
||||
private CourseRepository courseRepo;
|
||||
private ForumRepository forumRepo;
|
||||
private TopicRepository topicRepo;
|
||||
|
||||
public void createForum(Course c, Forum f){
|
||||
c.addForum(f);
|
||||
for (User u: f.getRegister()) {
|
||||
userServ.Notify(u, new Notification("forum.notification.forum.new", f.getName(), "/#/Forum"));
|
||||
}
|
||||
courseRepo.save(c);
|
||||
}
|
||||
|
||||
public void createTopic(Forum f, Topic data) {
|
||||
f.addTopic(data);
|
||||
for (User u: f.getRegister()) {
|
||||
userServ.Notify(u, new Notification("forum.notification.topic.new", data.getSubject(), "/#/Forum"));
|
||||
}
|
||||
forumRepo.save(f);
|
||||
}
|
||||
|
||||
public void answerTopic(Topic t, Answer data, User u) {
|
||||
data.setAuthor(u);
|
||||
t.addAnswer(data);
|
||||
topicRepo.save(t);
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package ovh.herisson.Clyde.Services;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class NotificationService {
|
||||
|
||||
}
|
@ -29,6 +29,7 @@ public class ProtectionService {
|
||||
toReturn.put("country",user.getCountry());
|
||||
toReturn.put("profilePictureUrl",user.getProfilePictureUrl());
|
||||
toReturn.put("role",user.getRole());
|
||||
toReturn.put("identityCard", user.getIdentityCardUrl());
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
@ -50,7 +51,7 @@ public class ProtectionService {
|
||||
|
||||
HashMap<String ,Object> toReturn = new HashMap<>();
|
||||
|
||||
toReturn.put("courseId",course.getCourseID());
|
||||
toReturn.put("courseID",course.getCourseID());
|
||||
toReturn.put("credits",course.getCredits());
|
||||
toReturn.put("title", course.getTitle());
|
||||
toReturn.put("owner", userWithoutPassword(course.getOwner()));
|
||||
@ -116,6 +117,7 @@ public class ProtectionService {
|
||||
toReturn.put("identityCard", inscriptionRequest.getIdentityCard());
|
||||
toReturn.put("submissionDate", inscriptionRequest.getSubmissionDate());
|
||||
toReturn.put("equivalenceState", inscriptionRequest.getEquivalenceState());
|
||||
toReturn.put("admissionDocUrl", inscriptionRequest.getAdmissionDocUrl());
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
|
@ -9,22 +9,26 @@ import org.springframework.stereotype.Service;
|
||||
import ovh.herisson.Clyde.Repositories.LessonRepository;
|
||||
import ovh.herisson.Clyde.Repositories.ScheduleLessonRepository;
|
||||
import ovh.herisson.Clyde.Repositories.ScheduleRepository;
|
||||
import ovh.herisson.Clyde.Repositories.UserCurriculumRepository;
|
||||
import ovh.herisson.Clyde.Tables.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class ScheduleLessonService {
|
||||
|
||||
private final ScheduleLessonRepository scheduleLessonRepo;
|
||||
|
||||
private final UserCurriculumRepository userCurriculumRepo;
|
||||
private final UserService userServ;
|
||||
private final LessonRepository lessonRepo;
|
||||
private final ScheduleRepository scheduleRepo;
|
||||
public ScheduleLessonService(ScheduleLessonRepository scheduleLessonRepo, LessonRepository lessonRepo, ScheduleRepository scheduleRepo) {
|
||||
public ScheduleLessonService(ScheduleLessonRepository scheduleLessonRepo, UserCurriculumRepository userCurriculumRepo, UserService userServ, LessonRepository lessonRepo, ScheduleRepository scheduleRepo) {
|
||||
this.scheduleLessonRepo = scheduleLessonRepo;
|
||||
this.userCurriculumRepo = userCurriculumRepo;
|
||||
this.userServ = userServ;
|
||||
this.lessonRepo = lessonRepo;
|
||||
this.scheduleRepo = scheduleRepo;
|
||||
}
|
||||
@ -32,19 +36,22 @@ public class ScheduleLessonService {
|
||||
if(scheduleLesson == null)
|
||||
return false;
|
||||
scheduleLessonRepo.save(scheduleLesson);
|
||||
Iterable<User> users = userCurriculumRepo.findUsersByCurriculum(scheduleLesson.getSchedule().getCurriculum());
|
||||
for(User user: users){
|
||||
userServ.Notify(user, new Notification("New course in the schedule", "Course added " + scheduleLesson.getLesson().getCourse().getTitle(), "/#/schedule"));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Save a lesson to all the schedule it is linked
|
||||
*/
|
||||
public boolean saveToAllSchedule(Lesson lesson){
|
||||
public void saveToAllSchedule(Lesson lesson){
|
||||
Iterable<Schedule> schedules = scheduleRepo.findAllLessonSchedule(lesson.getCourse());
|
||||
if(schedules == null)
|
||||
return false;
|
||||
return;
|
||||
for (Schedule schedule : schedules){
|
||||
save(new ScheduleLesson(schedule, lesson));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Delete a scheduleLesson via its lesson
|
||||
@ -52,6 +59,11 @@ public class ScheduleLessonService {
|
||||
public boolean delete(long lessonId){
|
||||
if(lessonId == 0)
|
||||
return false;
|
||||
ScheduleLesson scheduleLesson = scheduleLessonRepo.findByLesson(lessonRepo.findById(lessonId));
|
||||
Iterable<User> users = userCurriculumRepo.findUsersByCurriculum(scheduleLesson.getSchedule().getCurriculum());
|
||||
for(User user: users){
|
||||
userServ.Notify(user, new Notification("Course deleted in the schedule","Course deleted " + scheduleLesson.getLesson().getCourse().getTitle(), "/#/schedule"));
|
||||
}
|
||||
scheduleLessonRepo.delete(lessonRepo.findById(lessonId));
|
||||
return true;
|
||||
}
|
||||
|
@ -0,0 +1,178 @@
|
||||
package ovh.herisson.Clyde.Services.ScientificPublications;
|
||||
|
||||
/******************************************************
|
||||
* @file ResearchesService.java
|
||||
* @author Bartha Maxime
|
||||
* @scope Publications Scientifiques
|
||||
*
|
||||
* Service for managing researcher and researches
|
||||
******************************************************/
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ovh.herisson.Clyde.Repositories.ScientificPublications.ResearchRepository;
|
||||
import ovh.herisson.Clyde.Repositories.ScientificPublications.ResearcherRepository;
|
||||
import ovh.herisson.Clyde.Tables.Role;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.*;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
@SuppressWarnings("unchecked")
|
||||
public class ResearchesService {
|
||||
|
||||
private final ResearcherRepository researcherRepo;
|
||||
private final ResearchRepository articleRepo;
|
||||
|
||||
|
||||
// researches Part
|
||||
public Research getResearchById(long id) {
|
||||
return articleRepo.findById(id);
|
||||
}
|
||||
|
||||
public Research getResearchByUrl(String url) {
|
||||
return articleRepo.findByPdfLocation(url);
|
||||
}
|
||||
|
||||
|
||||
public Iterable<Research> getResearchesByAuthor(long authorId){
|
||||
Researcher researcher = researcherRepo.findById(authorId);
|
||||
if (researcher == null) return null;
|
||||
|
||||
return researcherRepo.findAllByAuthorId(researcher);
|
||||
}
|
||||
|
||||
public Research saveResearch(Research research) {
|
||||
return articleRepo.save(research);
|
||||
}
|
||||
|
||||
public void modifyResearchData(Research research, Map<String, Object> updates) {
|
||||
for (Map.Entry<String, Object> entry : updates.entrySet()){
|
||||
switch (entry.getKey()){
|
||||
case "title":
|
||||
research.setTitle((String) entry.getValue());
|
||||
break;
|
||||
case "paperType":
|
||||
research.setPaperType((PaperType) entry.getValue());
|
||||
break;
|
||||
case "language":
|
||||
research.setLanguage((String) entry.getValue());
|
||||
break;
|
||||
case "domain":
|
||||
research.setDomain((String) entry.getValue());
|
||||
break;
|
||||
case "summary":
|
||||
research.setSummary((String) entry.getValue());
|
||||
break;
|
||||
case "access":
|
||||
research.setAccess(Access.valueOf((String) entry.getValue()));
|
||||
break;
|
||||
case "coAuthors":
|
||||
Set<Researcher> set = new HashSet<>();
|
||||
|
||||
for (int id : (List<Integer>) entry.getValue()) {
|
||||
|
||||
Researcher r = researcherRepo.findById(id);
|
||||
if (r != null){
|
||||
set.add(r);
|
||||
}
|
||||
}
|
||||
research.setCoAuthors(set);
|
||||
break;
|
||||
}
|
||||
}
|
||||
articleRepo.save(research);
|
||||
}
|
||||
|
||||
public void deleteResearch(Research research) {
|
||||
articleRepo.delete(research);
|
||||
}
|
||||
|
||||
|
||||
// Researchers Part
|
||||
public Researcher getResearcherByUser(User user){
|
||||
return researcherRepo.findByUser(user);
|
||||
}
|
||||
|
||||
public Iterable<Research> getAllResearches() {
|
||||
return articleRepo.findAll();
|
||||
}
|
||||
|
||||
public Researcher saveResearcher(Researcher researcher) {
|
||||
|
||||
if (researcherRepo.findByUser(researcher.getUser()) != null) return null;
|
||||
return researcherRepo.save(researcher);
|
||||
}
|
||||
|
||||
public Iterable<Researcher> getAllResearchers() {
|
||||
return researcherRepo.findAll();
|
||||
}
|
||||
|
||||
public Researcher getResearcherById(long id) {
|
||||
return researcherRepo.findById(id);
|
||||
}
|
||||
|
||||
public void deleteResearcher(Researcher researcher) {
|
||||
articleRepo.findAll();
|
||||
for (Research r: articleRepo.findAll())
|
||||
{
|
||||
if (r.getCoAuthors().contains(researcher)){
|
||||
r.getCoAuthors().remove(researcher);
|
||||
articleRepo.save(r);
|
||||
}
|
||||
}
|
||||
researcherRepo.delete(researcher);
|
||||
}
|
||||
|
||||
public void modifyResearcherData(Researcher researcher, Map<String, Object> updates) {
|
||||
|
||||
for (Map.Entry<String, Object> entry : updates.entrySet()){
|
||||
switch (entry.getKey()){
|
||||
case "orcidId":
|
||||
if (entry.getValue() != null)
|
||||
researcher.setOrcidId((String) entry.getValue());
|
||||
break;
|
||||
case "domain":
|
||||
if (entry.getValue() != null)
|
||||
researcher.setDomain((String) entry.getValue());
|
||||
break;
|
||||
case "site":
|
||||
if (entry.getValue() != null)
|
||||
researcher.setSite((String) entry.getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
researcherRepo.save(researcher);
|
||||
}
|
||||
// Other stuff
|
||||
|
||||
public Research addView(Research research) {
|
||||
research.setViews(research.getViews()+1);
|
||||
return articleRepo.save(research);
|
||||
}
|
||||
|
||||
public boolean hasNoAccessTo(Research research, User user){
|
||||
if (research.getAccess() == Access.OpenSource) return false; // if the access is open source even non-users can see it
|
||||
if (user == null) return true; // else you need at least to be a user
|
||||
|
||||
if (user.getRole() == Role.Admin) return false;
|
||||
|
||||
|
||||
Researcher researcher = getResearcherByUser(user);
|
||||
if (researcher !=null ){
|
||||
if (research.getAuthor().getId() == researcher.getId())
|
||||
return false;
|
||||
|
||||
for (Researcher coAuthor: research.getCoAuthors()){
|
||||
if (coAuthor.getId() == researcher.getId())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return research.getAccess() != Access.Restricted || (user.getRole() != Role.Secretary &&
|
||||
user.getRole() != Role.Teacher && user.getRole() != Role.InscriptionService);
|
||||
// if the access is restricted only the staff member (above) can access the research
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package ovh.herisson.Clyde.Services.ScientificPublications;
|
||||
|
||||
/******************************************************
|
||||
* @file StatisticsService
|
||||
* @author Bartha Maxime
|
||||
* @scope Publications Scientifiques
|
||||
*
|
||||
* Service for managing statistics
|
||||
******************************************************/
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ovh.herisson.Clyde.Repositories.ScientificPublications.ResearchRepository;
|
||||
import ovh.herisson.Clyde.Repositories.ScientificPublications.StatsRepository;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Research;
|
||||
import ovh.herisson.Clyde.Tables.ScientificPublications.Researcher;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class StatisticsService {
|
||||
|
||||
|
||||
private ResearchRepository articleRepo;
|
||||
private StatsRepository statsRepo;
|
||||
|
||||
|
||||
public Iterable<Iterable<Map<String, Integer>>> generateStats(Researcher researcher){
|
||||
|
||||
Iterable<Research> researches = articleRepo.findByAuthor(researcher);
|
||||
|
||||
if (researches == null) return null;
|
||||
|
||||
|
||||
ArrayList<Iterable<Map<String,Integer>>> toReturn = new ArrayList<>();
|
||||
|
||||
toReturn.add(statsRepo.viewsByYears(researcher.getId()));
|
||||
toReturn.add(statsRepo.viewsByMonths(researcher.getId()));
|
||||
toReturn.add(statsRepo.viewsByTopics(researcher.getId()));
|
||||
|
||||
toReturn.add(statsRepo.researchesByYears(researcher.getId()));
|
||||
toReturn.add(statsRepo.researchesByMonth(researcher.getId()));
|
||||
toReturn.add(statsRepo.researchesByTopics(researcher.getId()));
|
||||
|
||||
toReturn.add(statsRepo.languageByYears(researcher.getId()));
|
||||
toReturn.add(statsRepo.languageByMonths(researcher.getId()));
|
||||
toReturn.add(statsRepo.languageByTopics(researcher.getId()));
|
||||
return toReturn;
|
||||
}
|
||||
}
|
@ -51,8 +51,8 @@ public class TokenService {
|
||||
ArrayList<Token> tokenList = tokenRepo.getByUserOrderByExpirationDate(token.getUser());
|
||||
|
||||
while(tokenList.size() >= 5){
|
||||
tokenRepo.delete(tokenList.getFirst());
|
||||
tokenList.remove(tokenList.getFirst());
|
||||
tokenRepo.delete(tokenList.get(0));
|
||||
tokenList.remove(tokenList.get(0));
|
||||
}
|
||||
tokenRepo.save(token);
|
||||
}
|
||||
|
@ -49,5 +49,7 @@ public class UserCurriculumService {
|
||||
return toReturn;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<UserCurriculum> findByStudentAndActual(User u, boolean actual){
|
||||
return userCurriculumRepository.findByUserAndActual(u, actual);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import ovh.herisson.Clyde.Tables.RegNoGenerator;
|
||||
import ovh.herisson.Clyde.Repositories.UserRepository;
|
||||
import ovh.herisson.Clyde.Tables.Notification;
|
||||
import ovh.herisson.Clyde.Tables.Role;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
import java.util.*;
|
||||
@ -44,61 +45,55 @@ public class UserService {
|
||||
* @param targetId the id of the user to update
|
||||
* @return if the changes were done or not
|
||||
*/
|
||||
public boolean modifyData(long targetId, Map<String ,Object> updates, User poster){
|
||||
public User modifyData(long targetId, Map<String ,Object> updates, User poster){
|
||||
|
||||
User target = userRepo.findById(targetId);
|
||||
if (target == null)
|
||||
return false;
|
||||
return null;
|
||||
|
||||
if (poster.getRegNo().equals(target.getRegNo())){
|
||||
for (Map.Entry<String, Object> entry : updates.entrySet()){
|
||||
if (!target.getRegNo().equals(poster.getRegNo()) && !(poster.getRole() == Role.Secretary) &&
|
||||
!(poster.getRole() == Role.Admin))
|
||||
return null;
|
||||
|
||||
switch (entry.getKey()){
|
||||
case "firstName":
|
||||
target.setFirstName((String) entry.getValue());
|
||||
break;
|
||||
case "lastName":
|
||||
target.setLastName((String) entry.getValue());
|
||||
break;
|
||||
case "email":
|
||||
target.setEmail((String) entry.getValue());
|
||||
break;
|
||||
case "address":
|
||||
target.setAddress((String) entry.getValue());
|
||||
break;
|
||||
case "country":
|
||||
target.setCountry((String) entry.getValue());
|
||||
break;
|
||||
case "birthDate":
|
||||
target.setBirthDate((Date) entry.getValue());
|
||||
break;
|
||||
case "profilePictureUrl":
|
||||
target.setProfilePictureUrl((String) entry.getValue());
|
||||
break;
|
||||
case "password":
|
||||
target.setPassword(passwordEncoder.encode((String) entry.getValue()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
userRepo.save(target);
|
||||
return true;
|
||||
}
|
||||
// the secretary can change roles (for example if a student becomes a teacher)
|
||||
else if (poster.getRole() == Role.Secretary)
|
||||
{
|
||||
for (Map.Entry<String, Object> entry : updates.entrySet()){
|
||||
|
||||
if ( entry.getKey().equals("role")) {
|
||||
|
||||
if (entry.getValue() == Role.Admin) {return false;}
|
||||
|
||||
target.setRole((Role) entry.getValue());
|
||||
userRepo.save(target);
|
||||
return true;
|
||||
}
|
||||
for (Map.Entry<String, Object> entry : updates.entrySet()){
|
||||
System.out.println(entry.getValue());
|
||||
switch (entry.getKey()){
|
||||
case "firstName":
|
||||
target.setFirstName((String) entry.getValue());
|
||||
break;
|
||||
case "lastName":
|
||||
target.setLastName((String) entry.getValue());
|
||||
break;
|
||||
case "email":
|
||||
target.setEmail((String) entry.getValue());
|
||||
break;
|
||||
case "address":
|
||||
target.setAddress((String) entry.getValue());
|
||||
break;
|
||||
case "country":
|
||||
target.setCountry((String) entry.getValue());
|
||||
break;
|
||||
case "birthDate":
|
||||
target.setBirthDate((Date) entry.getValue());
|
||||
break;
|
||||
case "profilePictureUrl":
|
||||
target.setProfilePictureUrl((String) entry.getValue());
|
||||
break;
|
||||
case "password":
|
||||
target.setPassword((String) entry.getValue());
|
||||
break;
|
||||
case "role":
|
||||
//a user can't change his own role
|
||||
if (poster.getRole()==Role.Secretary || poster.getRole() == Role.Admin){
|
||||
Role wanted = Role.valueOf((String) entry.getValue());
|
||||
if (wanted == Role.Admin && poster.getRole() != Role.Admin)
|
||||
return null;
|
||||
target.setRole(wanted);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
userRepo.save(target);
|
||||
return target;
|
||||
}
|
||||
|
||||
|
||||
@ -108,7 +103,6 @@ public class UserService {
|
||||
|
||||
public User save(User user){
|
||||
RegNoGenerator.resetCount();
|
||||
user.setPassword(passwordEncoder.encode(user.getPassword()));
|
||||
return userRepo.save(user);
|
||||
}
|
||||
|
||||
@ -139,4 +133,10 @@ public class UserService {
|
||||
public void delete(User user) {
|
||||
userRepo.delete(user);
|
||||
}
|
||||
|
||||
public void Notify(User u, Notification n){
|
||||
n.setUser(u);
|
||||
u.getNotifications().add(n);
|
||||
userRepo.save(u);
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ public enum Applications {
|
||||
// with any token
|
||||
Profile,
|
||||
|
||||
|
||||
// Students and higher authorization
|
||||
Msg,
|
||||
Forum,
|
||||
@ -27,6 +26,13 @@ public enum Applications {
|
||||
|
||||
// InscriptionService authorization
|
||||
Requests,
|
||||
StudentsList,
|
||||
// profile of a researcher
|
||||
ResearcherProfile,
|
||||
ManageResearcherProfile,
|
||||
|
||||
//the list of all researches (filterable)
|
||||
ListResearches,
|
||||
CreateUser,
|
||||
StudentsList,
|
||||
Payments
|
||||
}
|
||||
|
@ -1,14 +1,24 @@
|
||||
package ovh.herisson.Clyde.Tables;
|
||||
|
||||
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.OnDeleteAction;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Course {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private int courseId;
|
||||
private int courseID;
|
||||
private int credits;
|
||||
private String title;
|
||||
|
||||
@ -17,42 +27,19 @@ public class Course {
|
||||
@JoinColumn(name = "Users")
|
||||
private User owner;
|
||||
|
||||
//// Extension Messagerie /////
|
||||
@OneToMany(mappedBy = "course", cascade = CascadeType.ALL)
|
||||
private List<Forum> forums;
|
||||
|
||||
public void addForum(Forum f){
|
||||
f.setCourse(this);
|
||||
forums.add(f);
|
||||
}
|
||||
///////////////////////////////
|
||||
|
||||
public Course(int credits, String title, User owner){
|
||||
this.credits = credits;
|
||||
this.title = title;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package ovh.herisson.Clyde.Tables;
|
||||
public enum FileType {
|
||||
ProfilePicture,
|
||||
EducationCertificate,
|
||||
Research,
|
||||
ResearchBibTex,
|
||||
JustificationDocument,
|
||||
IdentityCard,
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package ovh.herisson.Clyde.Tables;
|
||||
package ovh.herisson.Clyde.Tables.Inscription;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import ovh.herisson.Clyde.Tables.Curriculum;
|
||||
import ovh.herisson.Clyde.Tables.RequestState;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
|
||||
import java.util.Date;
|
||||
|
@ -2,8 +2,6 @@ package ovh.herisson.Clyde.Tables.Inscription;
|
||||
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import org.hibernate.annotations.OnDelete;
|
||||
import org.hibernate.annotations.OnDeleteAction;
|
||||
import ovh.herisson.Clyde.Tables.Course;
|
||||
import ovh.herisson.Clyde.Tables.RequestState;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
|
@ -7,7 +7,6 @@ import ovh.herisson.Clyde.Tables.RequestState;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
@Entity
|
||||
public class ScholarshipRequest {
|
||||
|
@ -3,7 +3,6 @@ package ovh.herisson.Clyde.Tables.Inscription;
|
||||
import jakarta.persistence.*;
|
||||
import ovh.herisson.Clyde.Tables.Curriculum;
|
||||
import ovh.herisson.Clyde.Tables.RequestState;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package ovh.herisson.Clyde.Tables.Msg;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
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
|
||||
@JsonIgnore
|
||||
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;
|
||||
}
|
@ -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
|
||||
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
package ovh.herisson.Clyde.Tables;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
import jakarta.annotation.Nullable;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@Entity
|
||||
public class Notification {
|
||||
|
||||
public enum Status {
|
||||
Unread,
|
||||
Read,
|
||||
Archived
|
||||
}
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private int id;
|
||||
|
||||
private String subject;
|
||||
|
||||
private String body;
|
||||
|
||||
private Status status = Status.Unread;
|
||||
|
||||
private String link;
|
||||
|
||||
@ManyToOne
|
||||
@JsonIgnore
|
||||
private User user;
|
||||
|
||||
@CreationTimestamp
|
||||
private Date creation;
|
||||
|
||||
public Notification(String subject, @Nullable String body, @Nullable String link){
|
||||
this.subject = subject;
|
||||
this.body = body;
|
||||
this.link = link;
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package ovh.herisson.Clyde.Tables.ScientificPublications;
|
||||
|
||||
/******************************************************
|
||||
* @file Access.java
|
||||
* @author Maxime Bartha
|
||||
* @scope Extension Publications scientifiques
|
||||
*
|
||||
* Access Type for the Articles
|
||||
*
|
||||
******************************************************/
|
||||
public enum Access {
|
||||
OpenSource, // everyone can see
|
||||
Restricted, // only Researchers and Staff Members (secretary, teachers and Inscription Service)
|
||||
Private, // only authors and co-authors
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package ovh.herisson.Clyde.Tables.ScientificPublications;
|
||||
|
||||
/******************************************************
|
||||
* @file PaperType.java
|
||||
* @author Maxime Bartha
|
||||
* @scope Extension Publications scientifiques
|
||||
*
|
||||
* Type of the scientific paper
|
||||
*
|
||||
******************************************************/
|
||||
public enum PaperType {
|
||||
Article,
|
||||
Paper,
|
||||
Book,
|
||||
BookChapter,
|
||||
}
|
@ -0,0 +1,79 @@
|
||||
package ovh.herisson.Clyde.Tables.ScientificPublications;
|
||||
|
||||
/******************************************************
|
||||
* @file Research.java
|
||||
* @author Maxime Bartha
|
||||
* @scope Extension Publications scientifiques
|
||||
*
|
||||
* Research entity
|
||||
******************************************************/
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.annotations.CreationTimestamp;
|
||||
import org.hibernate.annotations.OnDelete;
|
||||
import org.hibernate.annotations.OnDeleteAction;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@Entity
|
||||
@Table(name = "Research")
|
||||
public class Research {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
private String title;
|
||||
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
@OnDelete(action = OnDeleteAction.CASCADE)
|
||||
@JoinColumn(name ="Researcher")
|
||||
private Researcher author;
|
||||
|
||||
@Column(nullable = false)
|
||||
private Date releaseDate;
|
||||
|
||||
private PaperType paperType;
|
||||
|
||||
private String pdfLocation;
|
||||
|
||||
private String bibTexLocation;
|
||||
|
||||
private String language;
|
||||
|
||||
private Access access;
|
||||
|
||||
private String domain;
|
||||
|
||||
private String summary;
|
||||
|
||||
private int views;
|
||||
|
||||
@ManyToMany(cascade = {CascadeType.MERGE})
|
||||
@JoinTable(name = "ResearchCoAuhors",
|
||||
joinColumns = @JoinColumn(name = "research_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "researcher_id")
|
||||
)
|
||||
private Set<Researcher> coAuthors;
|
||||
|
||||
public Research(String title, Researcher author, Date releaseDate, PaperType paperType,
|
||||
String pdfLocation, String bibTexLocation, String language, Access access, String domain, String summary,Set<Researcher> coauthors){
|
||||
this.author = author;
|
||||
this.title = title;
|
||||
this.releaseDate = releaseDate;
|
||||
this.paperType = paperType;
|
||||
this.pdfLocation = pdfLocation;
|
||||
this.bibTexLocation = bibTexLocation;
|
||||
this.language = language;
|
||||
this.access = access;
|
||||
this.domain = domain;
|
||||
this.summary = summary;
|
||||
this.coAuthors = coauthors;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,40 @@
|
||||
package ovh.herisson.Clyde.Tables.ScientificPublications;
|
||||
|
||||
/******************************************************
|
||||
* @file Researcher.java
|
||||
* @author Maxime Bartha
|
||||
* @scope Extension Publications scientifiques
|
||||
*
|
||||
* Researcher entity
|
||||
******************************************************/
|
||||
import jakarta.persistence.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.annotations.OnDelete;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@Entity
|
||||
@Table(name = "Researcher")
|
||||
public class Researcher {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private long id;
|
||||
@OneToOne
|
||||
private User user;
|
||||
private String orcidId;
|
||||
private String site;
|
||||
private String domain;
|
||||
|
||||
public Researcher(User user, String orcidId, String site, String domain){
|
||||
this.user = user;
|
||||
this.orcidId = orcidId;
|
||||
this.site = site;
|
||||
this.domain = domain;
|
||||
}
|
||||
}
|
@ -2,17 +2,26 @@ package ovh.herisson.Clyde.Tables;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import jakarta.persistence.*;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.hibernate.annotations.OnDelete;
|
||||
import org.hibernate.annotations.OnDeleteAction;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Discussion;
|
||||
import ovh.herisson.Clyde.Tables.Msg.Message;
|
||||
import ovh.herisson.Clyde.Tables.Notification.Status;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
|
||||
@Entity
|
||||
@Table(name = "Users")
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class User {
|
||||
@Id
|
||||
@GenericGenerator(name = "userGen", type = ovh.herisson.Clyde.Tables.RegNoGenerator.class)
|
||||
@ -27,18 +36,25 @@ public class User {
|
||||
private Date birthDate;
|
||||
private String profilePictureUrl;
|
||||
private Role role;
|
||||
|
||||
private String identityCardUrl;
|
||||
@JsonIgnore
|
||||
private String password;
|
||||
|
||||
@JsonIgnore
|
||||
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
|
||||
private List<Notification> notifications = new ArrayList<>();
|
||||
|
||||
////// Extension Messagerie /////
|
||||
@JsonIgnore
|
||||
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL)
|
||||
private List<Message> msgs;
|
||||
/////////////////////////////////
|
||||
|
||||
@JsonIgnore
|
||||
@ManyToMany( mappedBy = "members" )
|
||||
private List<Discussion> discussions;
|
||||
/////////////////////////////////
|
||||
|
||||
/////////////////////////////////
|
||||
public User(String lastName, String firstName, String email, String address,
|
||||
String country, Date birthDate, String profilePictureUrl, Role role, String password)
|
||||
{
|
||||
@ -50,11 +66,13 @@ public class User {
|
||||
this.birthDate = birthDate;
|
||||
this.profilePictureUrl = profilePictureUrl;
|
||||
this.role = role;
|
||||
this.password = password;
|
||||
this.password = (new BCryptPasswordEncoder()).encode(password);
|
||||
}
|
||||
|
||||
|
||||
//This constructor is used to add a student
|
||||
public User(String lastName, String firstName, String email, String address,
|
||||
String country, Date birthDate, String profilePictureUrl, String password)
|
||||
String country, Date birthDate, String profilePictureUrl, String password,String identityCardUrl)
|
||||
{
|
||||
this.lastName = lastName;
|
||||
this.firstName = firstName;
|
||||
@ -63,79 +81,12 @@ public class User {
|
||||
this.country = country;
|
||||
this.birthDate = birthDate;
|
||||
this.profilePictureUrl = profilePictureUrl;
|
||||
this.password = password;
|
||||
this.password = (new BCryptPasswordEncoder()).encode(password);
|
||||
this.role = Role.Student;
|
||||
}
|
||||
public User() {}
|
||||
|
||||
public Long getRegNo(){
|
||||
return this.regNo;
|
||||
}
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
this.identityCardUrl = identityCardUrl;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public Date getBirthDate() {
|
||||
return birthDate;
|
||||
}
|
||||
|
||||
public void setBirthDate(Date birthDate) {
|
||||
this.birthDate = birthDate;
|
||||
}
|
||||
|
||||
public String getProfilePictureUrl(){return this.profilePictureUrl;}
|
||||
|
||||
public void setProfilePictureUrl(String profilePictureUrl){
|
||||
this.profilePictureUrl = profilePictureUrl;
|
||||
}
|
||||
public ovh.herisson.Clyde.Tables.Role getRole() {
|
||||
return role;
|
||||
}
|
||||
|
||||
public void setRole(ovh.herisson.Clyde.Tables.Role role) {
|
||||
this.role = role;
|
||||
}
|
||||
public String getPassword(){
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
public void setPassword(String password) {
|
||||
this.password = (new BCryptPasswordEncoder()).encode(password);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,17 @@
|
||||
package ovh.herisson.Clyde.Tables;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import org.hibernate.annotations.OnDelete;
|
||||
import org.hibernate.annotations.OnDeleteAction;
|
||||
|
||||
@Entity
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class UserCurriculum {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
@ -26,48 +33,10 @@ public class UserCurriculum {
|
||||
//True if the user has that curriculum at the moment false if not
|
||||
private boolean actual;
|
||||
|
||||
public UserCurriculum(User user, Curriculum curriculum, int year, boolean actual){
|
||||
this.user = user;
|
||||
this.curriculum = curriculum;
|
||||
this.year = year;
|
||||
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;
|
||||
}
|
||||
public UserCurriculum(User u, Curriculum cu, int year, boolean actual){
|
||||
this.user = u;
|
||||
this.curriculum = cu;
|
||||
this.year = year;
|
||||
this.actual = actual;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import ovh.herisson.Clyde.Repositories.TokenRepository;
|
||||
import ovh.herisson.Clyde.Repositories.UserRepository;
|
||||
import ovh.herisson.Clyde.Responses.UnauthorizedResponse;
|
||||
import ovh.herisson.Clyde.Services.TokenService;
|
||||
import ovh.herisson.Clyde.Services.UserService;
|
||||
import ovh.herisson.Clyde.Tables.Role;
|
||||
import ovh.herisson.Clyde.Tables.Token;
|
||||
import ovh.herisson.Clyde.Tables.User;
|
||||
@ -46,7 +47,8 @@ public class UserControllerTest {
|
||||
|
||||
@Autowired
|
||||
private TokenService tokenService;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
@Autowired
|
||||
@ -72,6 +74,7 @@ public class UserControllerTest {
|
||||
@BeforeEach
|
||||
void setup(){
|
||||
RestAssured.baseURI = "http://localhost:" + port;
|
||||
userRepository.deleteAll();
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
@ -84,7 +87,7 @@ public class UserControllerTest {
|
||||
public void userPostTest(){
|
||||
User god = new User("god","god","admin@admin.com","everywhere","every",new Date(0), null, Role.Admin,"goddoesntneedpassword");
|
||||
Token godToken = new Token(god, tokenService.generateNewToken(), new Date());
|
||||
userRepository.save(god);
|
||||
userService.save(god);
|
||||
tokenService.saveToken(godToken);
|
||||
|
||||
//Can god post herobrine himself ?
|
||||
|
@ -70,7 +70,7 @@ class TokenServiceTest {
|
||||
ArrayList<Token> tokenList = new ArrayList<>();
|
||||
GregorianCalendar gc = new GregorianCalendar();
|
||||
|
||||
User malveillant = new User("Cargo", "John", "CargoJ@mail.com", "secret", "secret", null, null, null, "secret");
|
||||
User malveillant = new User("Cargo", "John", "CargoJ@mail.com", "secret", "secret", new Date(), null, "secret", null);
|
||||
userRepository.save(malveillant);
|
||||
|
||||
for (int i = 0; i < 20; i++){
|
||||
|
104
frontend/package-lock.json
generated
104
frontend/package-lock.json
generated
@ -8,6 +8,8 @@
|
||||
"name": "clyde",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@canvasjs/vue-charts": "^1.0.4",
|
||||
"@vueuse/core": "^10.9.0",
|
||||
"vite-plugin-top-level-await": "^1.4.1",
|
||||
"vue": "^3.4.15",
|
||||
"vue3-toastify": "^0.2.1"
|
||||
@ -29,6 +31,20 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@canvasjs/charts": {
|
||||
"version": "3.7.45",
|
||||
"resolved": "https://registry.npmjs.org/@canvasjs/charts/-/charts-3.7.45.tgz",
|
||||
"integrity": "sha512-FPMX8wn+PEHzAa/GLBsL5lWB81AzKZLw51t7SiSUjMbtUN5/OIrmDcwUTw+53/Bbdd9gm2LLmxAdZsQ75JI31g=="
|
||||
},
|
||||
"node_modules/@canvasjs/vue-charts": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@canvasjs/vue-charts/-/vue-charts-1.0.4.tgz",
|
||||
"integrity": "sha512-PzOA8xeb/f68a39uoFZNn843dGPU36bsqmbO5DWjP7k6FwkK5AeGkYa/H3RHC02Xc6mG68vg9aFNj2Fyqhu4UQ==",
|
||||
"dependencies": {
|
||||
"@canvasjs/charts": "^3.7.5",
|
||||
"vue": ">=3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
|
||||
@ -753,6 +769,11 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
|
||||
},
|
||||
"node_modules/@types/web-bluetooth": {
|
||||
"version": "0.0.20",
|
||||
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz",
|
||||
"integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow=="
|
||||
},
|
||||
"node_modules/@vitejs/plugin-vue": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz",
|
||||
@ -866,6 +887,89 @@
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz",
|
||||
"integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw=="
|
||||
},
|
||||
"node_modules/@vueuse/core": {
|
||||
"version": "10.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-10.9.0.tgz",
|
||||
"integrity": "sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==",
|
||||
"dependencies": {
|
||||
"@types/web-bluetooth": "^0.0.20",
|
||||
"@vueuse/metadata": "10.9.0",
|
||||
"@vueuse/shared": "10.9.0",
|
||||
"vue-demi": ">=0.14.7"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/core/node_modules/vue-demi": {
|
||||
"version": "0.14.7",
|
||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz",
|
||||
"integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==",
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.0.0-rc.1",
|
||||
"vue": "^3.0.0-0 || ^2.6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/metadata": {
|
||||
"version": "10.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.9.0.tgz",
|
||||
"integrity": "sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/shared": {
|
||||
"version": "10.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-10.9.0.tgz",
|
||||
"integrity": "sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==",
|
||||
"dependencies": {
|
||||
"vue-demi": ">=0.14.7"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/shared/node_modules/vue-demi": {
|
||||
"version": "0.14.7",
|
||||
"resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz",
|
||||
"integrity": "sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==",
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.0.0-rc.1",
|
||||
"vue": "^3.0.0-0 || ^2.6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz",
|
||||
|
@ -9,6 +9,8 @@
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@canvasjs/vue-charts": "^1.0.4",
|
||||
"@vueuse/core": "^10.9.0",
|
||||
"vite-plugin-top-level-await": "^1.4.1",
|
||||
"vue": "^3.4.15",
|
||||
"vue3-toastify": "^0.2.1"
|
||||
|
@ -13,6 +13,13 @@ login.guest.lastpage=Last Page
|
||||
login.guest.submit=Submit
|
||||
login.guest.birthday=BIRTHDAY
|
||||
login.guest.confirm=CONFIRM
|
||||
login.guest.browse=Browse...
|
||||
login.guest.disclaimer=If you are already registered please connect to your account and use the change cursus/reregister function if not continue here.
|
||||
login.guest.identityCard=Identity Card :
|
||||
login.guest.attestationdisclaimer=This curriculum requires an entrance exam attestation
|
||||
login.guest.formationdisclaimer=Please add your old formations with the associated degree/attestation,your case will be check by a member of the inscription service.
|
||||
login.guest.managecareer=Manage your external formations
|
||||
login.guest.sendRegReq=Send register request
|
||||
login.cPassword=Confirm Password
|
||||
login.password=Password
|
||||
app.home=Home
|
||||
@ -29,18 +36,80 @@ app.language=Language
|
||||
app.manage.profile=Manage profile
|
||||
app.studentList=Students List
|
||||
app.users=Users
|
||||
app.manage.researcherProfile=Manage researcher profile
|
||||
app.list.researches=List researches
|
||||
app.Create.User=Create User
|
||||
app.manageOwnLessons=Manage Owned Courses Schedule
|
||||
app.lessonRequests=Schedule Requests
|
||||
app.payments = Payments
|
||||
app.payments=Payments
|
||||
request.moreInfos=More Infos
|
||||
request.accept=Accept
|
||||
request.refuse=Refuse
|
||||
Pending=Pending
|
||||
Delete=Delete
|
||||
Modify=Modify
|
||||
Create=Créer
|
||||
requestType=Request Type
|
||||
lessonType=Course 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.deleteCourse=Delete course
|
||||
courses.modify=Modify
|
||||
courses.toDelete=Course to Delete
|
||||
courses.confirm=Confirm
|
||||
courses.back=Back
|
||||
courses.AddToCurriculum=Add to a new Curriculum
|
||||
profile.modify.data=Modify personnal data
|
||||
profile.reRegister=Re-register
|
||||
profile.unRegister=Unregister
|
||||
@ -56,3 +125,169 @@ Curriculum=curriculum
|
||||
Credits=Credits
|
||||
InscriptionService=I.S.
|
||||
faculty=Faculty
|
||||
Year=Year
|
||||
Access=Access
|
||||
Access.Restricted=Restricted
|
||||
Access.OpenSource=OpenSource
|
||||
Access.Private=Private
|
||||
Language=Language
|
||||
Month=Month
|
||||
Month.01=january
|
||||
Month.02=february
|
||||
Month.03=march
|
||||
Month.04=april
|
||||
Month.05=may
|
||||
Month.06=june
|
||||
Month.07=july
|
||||
Month.08=august
|
||||
Month.09=september
|
||||
Month.10=october
|
||||
Month.11=november
|
||||
Month.12=december
|
||||
Domain=Domain
|
||||
PaperType=PaperType
|
||||
Submit=Submit
|
||||
Search.Researches=Search For Researches
|
||||
Search.Researchers=Search For Researchers
|
||||
Filters=Filters
|
||||
Toggle.Researcher=Toggle Researcher Search
|
||||
Untoggle.Researcher=Toggle Research Search
|
||||
MoreInfo=More Info
|
||||
Modify.Research=Modify Research
|
||||
To.Change.In.Options=To change in regular account options
|
||||
Modify.Data=Modify Data
|
||||
Confirm.Changes=Confirm Changes
|
||||
Cancel.Changes=Cancel Changes
|
||||
Post.Research=Post a new Research
|
||||
Summary=Summary
|
||||
Title=Title
|
||||
Views=Number of Views
|
||||
See.Research=See Research
|
||||
SeeBibTex=See BibTex
|
||||
Author=Author
|
||||
CoAuthors=Co-Authors
|
||||
ReleaseDate=ReleaseDate
|
||||
Article.Id=Article Id
|
||||
Delete.Research=Delete Research
|
||||
Here=Here
|
||||
Stat.Type=Stat Type
|
||||
Researches=Researches
|
||||
Please.Select.Option=Please Select an Option
|
||||
Class.By=Class By
|
||||
PaperType.Article=Article
|
||||
PaperType.Book=Book
|
||||
PaperType.Book.Chapter=Book Chapter
|
||||
PaperType.Paper=Paper
|
||||
Research.Pdf=Research Pdf
|
||||
BibTex.Pdf=BibTex Pdf
|
||||
CoAuthors.List=Co-Author List
|
||||
Confirm.Publish=Confirm Publishing
|
||||
Cancel.Publish=Cancel Publishing
|
||||
Years=Years
|
||||
Months=Months
|
||||
By=By
|
||||
RegNo=RegNo
|
||||
Address=Address
|
||||
Country=Country
|
||||
BirthDate=Birth Date
|
||||
Researcher.Delete=Delete Researcher Profile
|
||||
Researcher.Add=Create Researcher Profile
|
||||
Confirm=Confirm
|
||||
Cancel=Cancel
|
||||
LastName=Last Name
|
||||
FirstName=First Name
|
||||
Profile.Picture=Profile Picture
|
||||
Role=Role
|
||||
Password=Password
|
||||
Create.User=Create User
|
||||
msg.notification.new=You have a new message
|
||||
forum.create=Create forum
|
||||
forum.create.name=New forum's name
|
||||
forum.post.create.name=New post's title
|
||||
forum.notification.topic.new=New topic created
|
||||
forum.notification.forum.new=New Forum created
|
||||
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=Actual curriculums
|
||||
cursusprereq=The cursus you selected has some prerequisites ensure that your external curriculum data is updated in your profile
|
||||
imposecurriculum=Impose a curriculum
|
||||
impose=Impose
|
||||
gotimposed=The selected curriculum has been imposed
|
||||
DifferentLanguage=Different Languages
|
||||
|
@ -13,6 +13,13 @@ login.guest.lastpage=Derniere Page
|
||||
login.guest.submit=Envoyer
|
||||
login.guest.birthday=DATE DE NAISSANCE
|
||||
login.guest.confirm=CONFIRMER
|
||||
login.guest.browse=Parcourir...
|
||||
login.guest.disclaimer=Si vous êtes déja inscrits dans cette université veuillez vous connecter a votre compte et utilisez les fonctions changer de cursus/réinscription sinon continuez ici.
|
||||
login.guest.identityCard=Carte d'identité :
|
||||
login.guest.attestationdisclaimer=Ce cursus requiert une attestation de réussite d'un examen d'entrée
|
||||
login.guest.formationdisclaimer=Veuillez ajouter vos formations antérieures en y joignant les attestations/diplomes, votre dossier sera vérifié par un membre du service d'inscription.
|
||||
login.guest.managecareer=Gèrer mon parcours extérieur
|
||||
login.guest.sendRegReq=Envoyer la demande d'inscription
|
||||
login.cPassword=Confirmer mot de passe
|
||||
login.password=Mot de passe
|
||||
app.home=Home
|
||||
@ -29,18 +36,80 @@ app.language=Langue
|
||||
app.manage.profile=Gérer le profil
|
||||
app.studentList=Liste des étudiants
|
||||
app.users=Utilisateurs
|
||||
app.manage.researcherProfile= gérer son profil de chercheur
|
||||
app.list.researches=Lister les recherches
|
||||
app.Create.User=créer un utilisateur
|
||||
app.manageOwnLessons=Gérer ses horaires de cours
|
||||
app.lessonRequests=Requêtes d'horaire
|
||||
app.payments = Payements
|
||||
app.payments=Payements
|
||||
request.moreInfos=Plus d'Infos
|
||||
request.accept=Accepter
|
||||
request.refuse=Refuser
|
||||
Pending=En attente
|
||||
Delete=Supprimer
|
||||
Modify=Modifier
|
||||
Create=Créer
|
||||
requestType=Type de Requête
|
||||
lessonType=Type de cours
|
||||
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.deleteCourse=Supprimer un cours
|
||||
courses.modify=Modifier
|
||||
courses.toDelete=Cours à supprimer
|
||||
courses.confirm=Confirmer
|
||||
courses.back=Retour
|
||||
courses.AddToCurriculum=Ajouter à un cursus
|
||||
profile.modify.data=Modifier données personnelles
|
||||
profile.reRegister=Réinsciption
|
||||
profile.unRegister=Désinscription
|
||||
@ -56,4 +125,167 @@ Curriculum=Cursus
|
||||
Credits=Credits
|
||||
InscriptionService=S.I.
|
||||
faculty=Faculté
|
||||
|
||||
Year=Année
|
||||
Access=Accès
|
||||
Access.Restricted=Restreint
|
||||
Access.OpenSource=Libre
|
||||
Access.Private=Privé
|
||||
Language=Langue
|
||||
Month=Mois
|
||||
Month.01=janvier
|
||||
Month.02=fevrier
|
||||
Month.03=mars
|
||||
Month.04=avril
|
||||
Month.05=mai
|
||||
Month.06=juin
|
||||
Month.07=juillet
|
||||
Month.08=août
|
||||
Month.09=septembre
|
||||
Month.10=octobre
|
||||
Month.11=novembre
|
||||
Month.12=decembre
|
||||
Domain=Domaine
|
||||
PaperType=Type de recherche
|
||||
Submit=Envoyer
|
||||
Search.Researches=Chercher Par Recherche
|
||||
Search.Researchers=Chercher Par Chercheur
|
||||
Filters=Filtres
|
||||
Toggle.Researcher=Activer la recherche par chercheur
|
||||
Untoggle.Researcher=Désactiver la recherche par chercheur
|
||||
MoreInfo=Plus d'info
|
||||
Modify.Research=Modifer l'article
|
||||
To.Change.In.Options=À changer dans les options
|
||||
Modify.Data=Modifier
|
||||
Confirm.Changes=Confirmer les Changements
|
||||
Cancel.Changes=Abandonner les Changements
|
||||
Post.Research=Poster un nouvel article
|
||||
Summary=Résumé
|
||||
Title=Titre
|
||||
Views=Nombre de Vues
|
||||
See.Research=Ouvrir l'article
|
||||
SeeBibTex=Ouvrir le BibTex
|
||||
Author=Autheur
|
||||
CoAuthors=Co-Autheurs
|
||||
ReleaseDate=Date de Parution
|
||||
Article.Id=Id de l'article
|
||||
Delete.Research=Supprimer l'article
|
||||
Here=Ici
|
||||
Stat.Type=Type de Stat
|
||||
Researches=Recherches
|
||||
Please.Select.Option=Selectionnez des Options
|
||||
Class.By=Classifer Par
|
||||
PaperType.Article=Article
|
||||
PaperType.Book=Livre
|
||||
PaperType.Book.Chapter=Chapitre de Livre
|
||||
PaperType.Paper=Papier
|
||||
Research.Pdf=Pdf de la Recherche
|
||||
BibTex.Pdf=BibTex de la Recherche
|
||||
CoAuthors.List=Liste des Co-Autheurs
|
||||
Confirm.Publish=Confirmer la Publication
|
||||
Cancel.Publish=Annuler la Publication
|
||||
Years=Années
|
||||
Months=Mois
|
||||
By=par
|
||||
RegNo=Matricule
|
||||
Address=Adresse
|
||||
Country=Pays
|
||||
BirthDate=Date de Naissance
|
||||
Confirm=Confirmer
|
||||
Cancel=Annuler
|
||||
LastName=Nom de Famille
|
||||
FirstName=Prénom
|
||||
Profile.Picture=Photo de Profil
|
||||
Role=Role
|
||||
Password=Mot de Passe
|
||||
Create.User=Créer l'utilisateur
|
||||
msg.notification.new=Vous avez un nouveau message!
|
||||
forum.create=Créer un forum
|
||||
forum.create.name=Nom du forum
|
||||
forum.post.create.name=Titre du post
|
||||
forum.notification.topic.new=Nouveau Topic crée
|
||||
forum.notification.forum.new=Nouveau forum crée
|
||||
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=Cursus actuels
|
||||
cursusprereq=Le cursus que vous avez selectionné a des prérequis assurez vous que votre dossier de parcours est a jour dans votre profil
|
||||
imposecurriculum=Imposer un cursusgotimposed
|
||||
impose=Imposer
|
||||
gotimposed=Le cursus selectionné a été imposé
|
||||
DifferentLanguage=Langues différentes
|
||||
|
@ -1,18 +1,24 @@
|
||||
<script setup>
|
||||
import { toast } from 'vue3-toastify';
|
||||
import { ref } from 'vue'
|
||||
import i18n, { setLang } from './i18n.js'
|
||||
import { isLogged } from '@/rest/Users.js'
|
||||
|
||||
import { isLogged, getSelf } from '@/rest/Users.js'
|
||||
import { notifications, fetchNotifications, archiveNotification } from '@/rest/notifications.js'
|
||||
import {postMock} from "@/rest/restConsumer.js";
|
||||
import { appList, currentView } from '@/rest/apps.js'
|
||||
var prevURL;
|
||||
var currentURL = window.location.hash;
|
||||
|
||||
postMock()
|
||||
window.onhashchange = function() {
|
||||
prevURL = currentURL;
|
||||
currentURL = window.location.hash;
|
||||
}
|
||||
const Logged = ref(isLogged());
|
||||
const user = ref();
|
||||
|
||||
if(Logged.value){
|
||||
fetchNotifications();
|
||||
getSelf().then(e => user.value = e);
|
||||
}
|
||||
|
||||
window.addEventListener('hashchange', () => {
|
||||
if((location.hash === "#/home" && prevURL === "#/login") || (location.hash === "#/home" && prevURL === "#/profil")){
|
||||
@ -20,10 +26,10 @@ window.addEventListener('hashchange', () => {
|
||||
}
|
||||
});
|
||||
const home=ref(i18n("app.home"))
|
||||
const notifications=ref(i18n("app.notifications"))
|
||||
const settings=ref(i18n("app.settings"))
|
||||
const login=ref(i18n("app.login"))
|
||||
const active=ref(false)
|
||||
const notification = ref(false)
|
||||
|
||||
const apps = ref([])
|
||||
appList().then(e => apps.value = e)
|
||||
@ -35,7 +41,7 @@ window.addEventListener('hashchange', () => {
|
||||
<div class="topBar">
|
||||
<ul class="horizontal">
|
||||
<li title=home>
|
||||
<a class="icon" href="#home">
|
||||
<a class="icon" href="#home">
|
||||
<img class="clyde" src="/Clyde.png" style="width: 40px; height: auto; margin-top:4px">
|
||||
</a></li>
|
||||
<li title=home>
|
||||
@ -44,14 +50,17 @@ window.addEventListener('hashchange', () => {
|
||||
</a></li>
|
||||
<li style="float: right;" title=login>
|
||||
<a class="icon" href="#/login">
|
||||
<div class="fa-solid fa-user" :style="Logged ? 'color: orange' : 'haha'" style="margin-top: 7px; margin-bottom: 3px; "></div>
|
||||
<div class="fa-solid fa-user" :style="Logged ? 'color: red' : ''" style="margin-top: 7px; margin-bottom: 3px; "></div>
|
||||
</a></li>
|
||||
<li style="float: right;" title=notifications>
|
||||
<a class="icon" href="#Notifications">
|
||||
<div class="fa-solid fa-bell" style="margin-top: 7px; margin-bottom: 3px;"></div>
|
||||
<li style="float: right;" title=notifications @click="notification = !notification">
|
||||
<a class="icon">
|
||||
<div class="fa-solid fa-bell" :style="notifications.length != 0 ? 'color:orange': '' " style="margin-top: 7px; margin-bottom: 3px;"></div>
|
||||
<ul v-if=notification id="notification">
|
||||
<li v-for="notif in notifications" @click="archiveNotification(notif.id)"> {{ i18n(notif.subject) }} - {{ notif.body }}</li>
|
||||
</ul>
|
||||
</a></li>
|
||||
<li @click="active=!active" class="option"style="float: right;" title=settings>
|
||||
<a class="icon" >
|
||||
<a class="icon">
|
||||
<div class="fa-solid fa-gear" style="margin-top: 7px; margin-bottom: 3px;"></div>
|
||||
<div v-if="active" class="dropdown">
|
||||
<div class="dropdown-content">{{i18n("app.language")}}</div>
|
||||
@ -67,6 +76,7 @@ window.addEventListener('hashchange', () => {
|
||||
{{i18n("app.manage.profile")}}
|
||||
</a>
|
||||
</div>
|
||||
<span v-if=Logged>RegNo - {{ user.regNo }}</span>
|
||||
</div>
|
||||
</a></li>
|
||||
</ul>
|
||||
@ -125,10 +135,12 @@ window.addEventListener('hashchange', () => {
|
||||
|
||||
|
||||
.dropdown {
|
||||
color:black;
|
||||
margin-top:55px;
|
||||
width:160px;
|
||||
display: inline-block;
|
||||
height:110px;
|
||||
/* height:110px; */
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
@ -154,14 +166,14 @@ window.addEventListener('hashchange', () => {
|
||||
margin-top: var(--header-size);
|
||||
top:0;
|
||||
left:0;
|
||||
padding: 25px 0 0;
|
||||
padding: 25px 0;
|
||||
width: 70px ;
|
||||
background-color: rgb(53, 53, 53);
|
||||
border-right:5px;
|
||||
border-color:black;
|
||||
height: 100%;
|
||||
height: calc( 95% - var(--header-size) ) ;
|
||||
position: fixed;
|
||||
overflow:;
|
||||
overflow: scroll;
|
||||
transition-duration: .3s;
|
||||
}
|
||||
|
||||
@ -215,8 +227,6 @@ window.addEventListener('hashchange', () => {
|
||||
background-color: black;
|
||||
border-radius:6px;
|
||||
color:white;
|
||||
transform: translate(0px ,1px);
|
||||
|
||||
}
|
||||
|
||||
ul.vertical:hover {
|
||||
@ -231,8 +241,7 @@ window.addEventListener('hashchange', () => {
|
||||
.text {
|
||||
right: 0%;
|
||||
width: 0%;
|
||||
visibility: collapse;
|
||||
opacity: 0;
|
||||
display:none;
|
||||
color: white;
|
||||
font-size: 1.2em;
|
||||
font-weight: 600;
|
||||
@ -241,7 +250,7 @@ window.addEventListener('hashchange', () => {
|
||||
|
||||
ul.vertical:hover .text {
|
||||
opacity:1;
|
||||
visibility:visible;
|
||||
display: inline;
|
||||
width: 60%;
|
||||
transition-duration: .3s;
|
||||
padding-left: 15px;
|
||||
@ -250,6 +259,32 @@ window.addEventListener('hashchange', () => {
|
||||
.clyde:hover{
|
||||
content: url("./assets/angry_clyde.png")
|
||||
}
|
||||
|
||||
#notification{
|
||||
position: absolute;
|
||||
top: 61px;
|
||||
right: 0;
|
||||
background-color: white;
|
||||
width: 300px;
|
||||
height: 600px;
|
||||
border-radius: 10px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
#notification > li{
|
||||
color: black;
|
||||
list-style: none;
|
||||
font-size: 0.4em;
|
||||
display: block;
|
||||
background-color: #00FF00A0;
|
||||
margin: 1px;
|
||||
border-radius: 42px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
#notification > li:hover{
|
||||
background-color: #00FF0000
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
215
frontend/src/Apps/AboutUser.vue
Normal file
215
frontend/src/Apps/AboutUser.vue
Normal file
@ -0,0 +1,215 @@
|
||||
<script setup>
|
||||
import i18n from "../i18n.js";
|
||||
import {ref} from "vue";
|
||||
import {fetchAllResearchers} from "@/rest/ScientificPublications/ManageResearch.js";
|
||||
import {deleteResearcher, postResearcher} from "@/rest/ScientificPublications/ResearcherProfile.js";
|
||||
import {patchUser} from "@/rest/Users.js";
|
||||
const props = defineProps(['user'])
|
||||
const modifying =ref(false)
|
||||
const toModify = Object.assign({},{})
|
||||
const toCreate = Object.assign({},{})
|
||||
const allResearcher = ref( await fetchAllResearchers())
|
||||
const researcher = ref()
|
||||
const user = ref(props.user)
|
||||
const isResearcher = ref(false)
|
||||
const creating = ref(false)
|
||||
|
||||
for (let i = 0; i < allResearcher.value.length; i++) {
|
||||
if (user.value.regNo === allResearcher.value[i].user.regNo){
|
||||
researcher.value = allResearcher.value[i]
|
||||
isResearcher.value = true
|
||||
}
|
||||
}
|
||||
|
||||
function getPP(){
|
||||
if(user.value.profilePictureUrl === null){
|
||||
return "/Clyde.png"
|
||||
}
|
||||
return user.value.profilePictureUrl
|
||||
}
|
||||
|
||||
async function createResearcher(){
|
||||
toCreate.user = user.value
|
||||
await postResearcher(toCreate)
|
||||
creating.value = false
|
||||
allResearcher.value = await fetchAllResearchers()
|
||||
for (let i = 0; i < allResearcher.value.length; i++) {
|
||||
if (user.value.regNo === allResearcher.value[i].user.regNo){
|
||||
researcher.value = allResearcher.value[i]
|
||||
isResearcher.value = true
|
||||
}
|
||||
}
|
||||
toCreate.value = Object.assign({},{})
|
||||
}
|
||||
|
||||
async function deleteResearcherById(){
|
||||
isResearcher.value = false
|
||||
await deleteResearcher(researcher.value.id)
|
||||
allResearcher.value = await fetchAllResearchers()
|
||||
}
|
||||
|
||||
async function modify(){
|
||||
if (modifying.value){
|
||||
user.value = await patchUser(user.value.regNo, toModify)
|
||||
}
|
||||
modifying.value =!modifying.value
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="body">
|
||||
<div class="container">
|
||||
<div class="profilPic">
|
||||
<img class="subContainer" :src=getPP()>
|
||||
</div>
|
||||
<div class = "globalInfos">
|
||||
<div class="infosContainer">
|
||||
<div>
|
||||
{{i18n("RegNo")}} : {{user.regNo}}
|
||||
</div>
|
||||
<div>
|
||||
{{i18n("name")}} : {{user.firstName}} {{user.lastName}}
|
||||
</div>
|
||||
<div>
|
||||
Role :
|
||||
<span v-if="!modifying"> {{i18n(user.role)}}</span>
|
||||
<select v-else v-model="toModify.role">
|
||||
<option value="Student">{{i18n("Student")}}</option>
|
||||
<option value="Teacher">{{i18n("Teacher")}}</option>
|
||||
<option value="Secretary">{{i18n("Secretary")}}</option>
|
||||
<option value="InscriptionService">{{i18n("InscriptionService")}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
E-mail: {{user.email}}
|
||||
</div>
|
||||
<div>
|
||||
{{i18n("Address")}} :
|
||||
<span v-if="!modifying"> {{user.address}}</span>
|
||||
<input v-else type="text" v-model="toModify.address">
|
||||
</div>
|
||||
<div>
|
||||
{{i18n("Country")}} : {{user.country}}
|
||||
</div>
|
||||
<div>
|
||||
{{i18n("BirthDate")}} : {{user.birthDate.split("T")[0]}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div></div>
|
||||
<button id="ModifyButton" @click="modify"> {{i18n("Modify.Data")}}</button>
|
||||
<div></div>
|
||||
<div>
|
||||
<button v-if="isResearcher" id="deleteButton" @click="deleteResearcherById"> {{i18n("Researcher.Delete")}}</button>
|
||||
<button v-else id="createButton" @click="creating = !creating"> {{i18n("Researcher.Add")}}</button>
|
||||
</div>
|
||||
<div v-if="creating">
|
||||
<button id="createButton" @click="createResearcher"> {{i18n("Confirm")}}</button>
|
||||
<button id="deleteButton" @click="creating = !creating"> {{i18n("Cancel")}}</button>
|
||||
</div>
|
||||
<div v-if="creating" style="color: white">
|
||||
<ul>
|
||||
<li>
|
||||
Orcid :
|
||||
<input type="text" v-model="toCreate.orcid"></li>
|
||||
<li>
|
||||
Site :
|
||||
<input type="text" v-model="toCreate.site"></li>
|
||||
<li>
|
||||
{{i18n("Domain")}} :
|
||||
<input type="text" v-model="toCreate.domain"></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
#ModifyButton{
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: xx-large;
|
||||
background-color:rgba(191, 64, 191,0.5);
|
||||
border-radius: 20px;
|
||||
}
|
||||
#ModifyButton:hover{
|
||||
background:rgba(191,64,191)
|
||||
}
|
||||
|
||||
.container{
|
||||
margin-top: 25px;
|
||||
min-width:675px;
|
||||
display:grid;
|
||||
grid-template-columns:10vw 50vw;
|
||||
grid-template-rows:200px auto;
|
||||
column-gap:2.7%;
|
||||
row-gap:45px;
|
||||
grid-template-areas:
|
||||
"profilPic globalInfos";
|
||||
}
|
||||
|
||||
.profilPic{
|
||||
grid-area:profilPic;
|
||||
}
|
||||
|
||||
.globalInfos {
|
||||
grid-area:globalInfos;
|
||||
align-self :center;
|
||||
|
||||
}
|
||||
|
||||
.body {
|
||||
min-width:960px;
|
||||
width:100%;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.subContainer{
|
||||
width:100%;
|
||||
background-color:rgb(50,50,50);
|
||||
border-radius:20px;
|
||||
border:4px solid black;
|
||||
}
|
||||
|
||||
.infosContainer {
|
||||
border:2px solid black;
|
||||
font-size:23px;
|
||||
color:white;
|
||||
background-color:rgb(50,50,50);
|
||||
border-radius:10px;
|
||||
}
|
||||
|
||||
#deleteButton{
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: x-large;
|
||||
background-color: red;
|
||||
border-radius: 20px;
|
||||
}
|
||||
#deleteButton:hover{
|
||||
background: #ff2d55;
|
||||
}
|
||||
#createButton{
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: x-large;
|
||||
background-color: #07bc0c;
|
||||
border-radius: 20px
|
||||
}
|
||||
#createButton:hover{
|
||||
background: #4cd964;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
117
frontend/src/Apps/CreateUser.vue
Normal file
117
frontend/src/Apps/CreateUser.vue
Normal file
@ -0,0 +1,117 @@
|
||||
<script setup>
|
||||
|
||||
import i18n from "@/i18n.js";
|
||||
import {uploadProfilePicture} from "@/rest/uploads.js";
|
||||
import {postUser} from "@/rest/Users.js";
|
||||
import {ref} from "vue";
|
||||
let toCreate = Object.assign({},{})
|
||||
const today = new Date()
|
||||
const date = today.getFullYear() +"-" + ("0" + (today.getMonth()+1)).slice(-2) + "-" + ("0" + today.getDate()).slice(-2);
|
||||
|
||||
|
||||
async function createUser(){
|
||||
|
||||
if (toCreate.lastName === null || toCreate.birthDate === null || toCreate.firstName === null ||
|
||||
toCreate.email === null || toCreate.address === null || toCreate.role === null || toCreate.password === null)
|
||||
return
|
||||
|
||||
await postUser(toCreate)
|
||||
toCreate = Object.assign({},{})
|
||||
}
|
||||
|
||||
async function getProfilePic(data){
|
||||
const pp= await uploadProfilePicture(data)
|
||||
toCreate.profilePictureUrl = pp.url
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="body">
|
||||
<div class="container">
|
||||
<div class = "globalInfos">
|
||||
<div class="infosContainer">
|
||||
<ul>
|
||||
<li>{{i18n("LastName")}} : <input type="text" v-model="toCreate.lastName"></li>
|
||||
<li>{{i18n("FirstName")}} : <input type="text" v-model="toCreate.firstName"></li>
|
||||
<li> E-mail : <input type="text" v-model="toCreate.email"></li>
|
||||
<li>{{i18n("Country")}} : <input type="text" v-model="toCreate.country"></li>
|
||||
<li>{{i18n("Address")}} : <input type="text" v-model="toCreate.address"></li>
|
||||
<li>{{i18n("BirthDate")}} : <input type="date" min="1924-01-01" :max="date" v-model="toCreate.birthDate"></li>
|
||||
|
||||
<li>{{i18n("Profile.Picture")}} :
|
||||
<input type="file" @change="getProfilePic($event.target.files);" accept="image/*">
|
||||
</li>
|
||||
|
||||
|
||||
<li>{{i18n("Role")}} :
|
||||
<select v-model="toCreate.role">
|
||||
<option value="Student">{{i18n("Student")}}</option>
|
||||
<option value="Teacher">{{i18n("Teacher")}}</option>
|
||||
<option value="Secretary">{{i18n("Secretary")}}</option>
|
||||
<option value="InscriptionService">{{i18n("InscriptionService")}}</option>
|
||||
</select>
|
||||
</li>
|
||||
|
||||
<li>{{i18n("Password")}} : <input type="password" v-model="toCreate.password"></li>
|
||||
|
||||
</ul>
|
||||
<div style="text-align: end"> <button id="createButton" @click="createUser"> {{i18n("Create.User")}}</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.container{
|
||||
margin-top: 25px;
|
||||
min-width:675px;
|
||||
display:grid;
|
||||
grid-template-columns:10vw 50vw;
|
||||
grid-template-rows:200px auto;
|
||||
column-gap:2.7%;
|
||||
row-gap:45px;
|
||||
grid-template-areas:
|
||||
"profilPic globalInfos"
|
||||
"minfos minfos";
|
||||
}
|
||||
.globalInfos {
|
||||
grid-area:globalInfos;
|
||||
align-self :center;
|
||||
|
||||
}
|
||||
|
||||
.body {
|
||||
min-width:960px;
|
||||
width:100%;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
margin-top:5%;
|
||||
}
|
||||
|
||||
|
||||
.infosContainer {
|
||||
border:2px solid black;
|
||||
font-size:23px;
|
||||
color:white;
|
||||
background-color:rgb(50,50,50);
|
||||
border-radius:10px;
|
||||
}
|
||||
|
||||
#createButton{
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: x-large;
|
||||
background-color: #07bc0c;
|
||||
border-radius: 20px
|
||||
}
|
||||
#createButton:hover{
|
||||
background: #4cd964;
|
||||
}
|
||||
|
||||
</style>
|
215
frontend/src/Apps/Forums.vue
Normal file
215
frontend/src/Apps/Forums.vue
Normal 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' || Role === 'Teacher' ? await reactive(getCourses(Role)) : 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>
|
||||
|
@ -1,15 +1,12 @@
|
||||
<script setup>
|
||||
|
||||
import {
|
||||
addUninscReq, editChangeCurrReq, editChangeCurrReqTeacherState,
|
||||
editScholarshipReq,
|
||||
editUnregReq, getChangeCurrReqById,
|
||||
getScholarshipReqById,
|
||||
getUnregisterbyId
|
||||
editChangeCurrReq, editChangeCurrReqTeacherState,
|
||||
getChangeCurrReqById,
|
||||
} from "@/rest/requests.js";
|
||||
import i18n from "@/i18n.js";
|
||||
import {getSelf, getUser} from "@/rest/Users.js";
|
||||
import {reactive, ref} from "vue";
|
||||
import {getSelf} from "@/rest/Users.js";
|
||||
import {ref} from "vue";
|
||||
import AboutStudent from "@/Apps/Inscription/AboutStudent.vue";
|
||||
|
||||
const props = defineProps(["reqId"])
|
||||
@ -39,39 +36,39 @@ async function editChangeCurrReqTeacherApproval(state){
|
||||
<div class="globalInfos">
|
||||
<div class="infosContainer">
|
||||
<div>
|
||||
Firstname/Name : {{req.user.firstName}} {{req.user.lastName}}
|
||||
{{i18n("firstname/name")}} : {{req.user.firstName}} {{req.user.lastName}}
|
||||
</div>
|
||||
<div>
|
||||
regNo : {{req.user.regNo}}
|
||||
{{i18n("regNo")}} : {{req.user.regNo}}
|
||||
</div>
|
||||
<div v-if="req.actualCurriculum !== null">
|
||||
From : Bac {{req.actualCurriculum.year}} {{req.actualCurriculum.option}}
|
||||
To : Bac {{req.destinationCurriculum.year}} {{req.destinationCurriculum.option}}
|
||||
{{i18n("From")}} : Bac {{req.actualCurriculum.year}} {{req.actualCurriculum.option}}
|
||||
{{i18n("To")}} : Bac {{req.destinationCurriculum.year}} {{req.destinationCurriculum.option}}
|
||||
</div>
|
||||
<div v-else>
|
||||
Wanted cursus : Bac {{req.destinationCurriculum.year}} {{req.destinationCurriculum.option}}
|
||||
{{i18n("WantedCursus")}} : Bac {{req.destinationCurriculum.year}} {{req.destinationCurriculum.option}}
|
||||
</div>
|
||||
<div>
|
||||
<button @click="localwindowstate++"> See profile </button>
|
||||
<button @click="localwindowstate++"> {{ i18n("seeprofile") }} </button>
|
||||
</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='Refused';uploadandrefreshChangeRequest('Refused')" style="margin-left: 2%;">Refuse</button>
|
||||
<div v-if="user.role === 'InscriptionService' || user.role==='Admin'">
|
||||
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';uploadandrefreshChangeRequest('Accepted')">{{ i18n("request.accept") }}</button>
|
||||
<button v-if="req.state === 'Pending'" @click="req.state='Refused';uploadandrefreshChangeRequest('Refused')" style="margin-left: 2%;">{{i18n("request.refuse")}}</button>
|
||||
</div>
|
||||
<div v-if="user.role === 'Teacher' || user.role === 'Admin'">
|
||||
<button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Accepted';editChangeCurrReqTeacherApproval('Accepted')">Accept equivalence</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='Accepted';editChangeCurrReqTeacherApproval('Accepted')" style="margin-right: 2%">{{i18n("acceptequiv")}}</button>
|
||||
<button v-if="req.teacherApprovalState === 'Pending'" @click="req.teacherApprovalState='Refused';editChangeCurrReqTeacherApproval('Refused')">{{i18n("refuseequiv")}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="localwindowstate === 0">
|
||||
<button @click="windowState = 0" style="margin-left: 10%">Back</button>
|
||||
<div v-if="localwindowstate === 0" style="margin-left: 23%">
|
||||
<button @click="windowState = 0" style="margin-left: 10%">{{ i18n("courses.back") }}</button>
|
||||
</div>
|
||||
<div v-if="localwindowstate === 1">
|
||||
<AboutStudent :target="tag"></AboutStudent>
|
||||
<button @click="localwindowstate--;">Back</button>
|
||||
<button @click="localwindowstate--;" style="margin-left: 10%">{{ i18n("courses.back") }}</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -88,11 +85,6 @@ async function editChangeCurrReqTeacherApproval(state){
|
||||
"minfos minfos";
|
||||
}
|
||||
|
||||
.profilPic{
|
||||
width:100%;
|
||||
grid-area:profilPic;
|
||||
}
|
||||
|
||||
.globalInfos {
|
||||
grid-area:globalInfos;
|
||||
align-self :center;
|
||||
@ -108,13 +100,6 @@ async function editChangeCurrReqTeacherApproval(state){
|
||||
margin-top:7%;
|
||||
}
|
||||
|
||||
.subContainter{
|
||||
width:100%;
|
||||
background-color:rgb(50,50,50);
|
||||
border-radius:20px;
|
||||
border:4px solid black;
|
||||
}
|
||||
|
||||
.infosContainer {
|
||||
min-width:350px;
|
||||
padding-bottom:50px;
|
||||
@ -125,4 +110,12 @@ async function editChangeCurrReqTeacherApproval(state){
|
||||
background-color:rgb(50,50,50);
|
||||
border-radius:20px;
|
||||
}
|
||||
|
||||
button{
|
||||
border:none;
|
||||
background-color:rgb(239, 60, 168);
|
||||
border-radius:10px;
|
||||
height:35px;
|
||||
margin-top:10px;
|
||||
}
|
||||
</style>
|
@ -1,15 +1,11 @@
|
||||
<script setup>
|
||||
|
||||
import {
|
||||
addUninscReq,
|
||||
editExempReqState,
|
||||
editScholarshipReq,
|
||||
getExempReq,
|
||||
getScholarshipReqById
|
||||
} from "@/rest/requests.js";
|
||||
import i18n from "@/i18n.js";
|
||||
import {getUser} from "@/rest/Users.js";
|
||||
import {reactive, ref} from "vue";
|
||||
import {ref} from "vue";
|
||||
import AboutStudent from "@/Apps/Inscription/AboutStudent.vue";
|
||||
|
||||
const props = defineProps(["reqId"])
|
||||
@ -32,23 +28,23 @@ async function editExemp(newstate){
|
||||
<div class="globalInfos">
|
||||
<div class="infosContainer">
|
||||
<div>
|
||||
Firstname/Name : {{req.user.firstName}} {{req.user.lastName}}
|
||||
{{ i18n("firstname/name") }} : {{req.user.firstName}} {{req.user.lastName}}
|
||||
</div>
|
||||
<div>
|
||||
Course: {{req.course.title}}
|
||||
{{ i18n("course") }}: {{req.course.title}}
|
||||
</div>
|
||||
<div>
|
||||
State : {{req.state}}
|
||||
{{ i18n("state") }} : {{req.state}}
|
||||
</div>
|
||||
<div>
|
||||
<button @click="profile = !profile">Voir le profil</button>
|
||||
<button @click="profile = !profile">{{ i18n("seeprofile") }}</button>
|
||||
</div>
|
||||
<div>
|
||||
<button>Download justification document</button>
|
||||
<button><a :href="req.justifDocument">{{ i18n("dljustifdoc") }}</a></button>
|
||||
</div>
|
||||
<div>
|
||||
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';editExemp('Accepted')">Accept</button>
|
||||
<button v-if="req.state === 'Pending'" @click="req.state='Refused';editExemp('Refused')" style="margin-left: 2%;">Refuse</button>
|
||||
<button v-if="req.state === 'Pending'" @click="req.state='Accepted';editExemp('Accepted')">{{ i18n("request.accept") }}</button>
|
||||
<button v-if="req.state === 'Pending'" @click="req.state='Refused';editExemp('Refused')" style="margin-left: 2%;">{{ i18n("request.refuse") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -56,10 +52,10 @@ async function editExemp(newstate){
|
||||
</div>
|
||||
<div v-else>
|
||||
<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>
|
||||
<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>
|
||||
</template>
|
||||
|
||||
@ -76,11 +72,6 @@ async function editExemp(newstate){
|
||||
"minfos minfos";
|
||||
}
|
||||
|
||||
.profilPic{
|
||||
width:100%;
|
||||
grid-area:profilPic;
|
||||
}
|
||||
|
||||
.globalInfos {
|
||||
grid-area:globalInfos;
|
||||
align-self :center;
|
||||
@ -96,13 +87,6 @@ async function editExemp(newstate){
|
||||
margin-top:7%;
|
||||
}
|
||||
|
||||
.subContainter{
|
||||
width:100%;
|
||||
background-color:rgb(50,50,50);
|
||||
border-radius:20px;
|
||||
border:4px solid black;
|
||||
}
|
||||
|
||||
.infosContainer {
|
||||
min-width:350px;
|
||||
padding-bottom:50px;
|
||||
@ -113,4 +97,12 @@ async function editExemp(newstate){
|
||||
background-color:rgb(50,50,50);
|
||||
border-radius:20px;
|
||||
}
|
||||
|
||||
button{
|
||||
border:none;
|
||||
background-color:rgb(239, 60, 168);
|
||||
border-radius:10px;
|
||||
height:35px;
|
||||
margin-top:10px;
|
||||
}
|
||||
</style>
|
@ -1,20 +1,23 @@
|
||||
<script setup>
|
||||
import i18n from "@/i18n.js"
|
||||
import {getSelf, getUser} from '../../rest/Users.js'
|
||||
import {getcurriculum,getSomeonesCurriculumList} from "@/rest/curriculum.js";
|
||||
import {getSelf} from '../../rest/Users.js'
|
||||
import {getAllCurriculums, getcurriculum} from "@/rest/curriculum.js";
|
||||
import {getRegisters} from "@/rest/ServiceInscription.js";
|
||||
import {get} from "jsdom/lib/jsdom/named-properties-tracker.js";
|
||||
import {getExternalCurriculumByInscrReq} from "@/rest/externalCurriculum.js";
|
||||
import {ref} from "vue";
|
||||
import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue";
|
||||
import {editEquivalenceState} from "@/rest/requests.js";
|
||||
import {editEquivalenceState, imposeCurriculum} from "@/rest/requests.js";
|
||||
|
||||
const curriculums = await getAllCurriculums()
|
||||
const props = defineProps(['target']);
|
||||
const request = await getRegisters(props.target);
|
||||
const cursus = await getcurriculum(request.curriculum);
|
||||
const user = await getSelf();
|
||||
const list = ref(false);
|
||||
const externalCurriculum = await getExternalCurriculumByInscrReq(request.id)
|
||||
const impose = ref(false)
|
||||
const imposeCurr = ref(0)
|
||||
const imposed = ref(false)
|
||||
|
||||
//Get the parent page windowState to display the correct button
|
||||
const windowState = defineModel("windowState")
|
||||
@ -28,10 +31,14 @@ function getPP(){
|
||||
async function editEquivalence(id, newstate){
|
||||
await editEquivalenceState(id, newstate)
|
||||
}
|
||||
|
||||
async function refreshCursus(){
|
||||
cursus.value = await getcurriculum(request.curriculum)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="body" v-if="list == false">
|
||||
<div class="body" v-if="list == false" style="margin-top: 10%;">
|
||||
<div class="container">
|
||||
<div class="profilPic">
|
||||
<img class="subContainter" :src=getPP()>
|
||||
@ -39,39 +46,54 @@ async function editEquivalence(id, newstate){
|
||||
<div class = "globalInfos">
|
||||
<div class="infosContainer">
|
||||
<div>
|
||||
FirstName/Name : {{request.firstName}} {{request.lastName}}
|
||||
{{ i18n("firstname/name") }} : {{request.firstName}} {{request.lastName}}
|
||||
</div>
|
||||
<div>
|
||||
E-mail: {{request.email}}
|
||||
{{ i18n("login.guest.email") }}: {{request.email}}
|
||||
</div>
|
||||
<div>
|
||||
Adresse : {{request.address}}
|
||||
{{ i18n("login.guest.address") }} : {{request.address}}
|
||||
</div>
|
||||
<div>
|
||||
Pays : {{request.country}}
|
||||
{{ i18n("login.guest.country") }} : {{request.country}}
|
||||
</div>
|
||||
<div>
|
||||
Date de naissance : {{request.birthDate}}
|
||||
{{ i18n("login.guest.birthday") }} : {{request.birthDate.slice(0,10)}}
|
||||
</div>
|
||||
<div>
|
||||
Cursus voulu : BAB {{cursus.year}} {{cursus.option}}
|
||||
{{ i18n("WantedCursus") }} : BAB {{cursus.year}} {{cursus.option}}
|
||||
</div>
|
||||
<div v-if="cursus.year > 1">
|
||||
<button style="background-color:rgb(105,05,105);margin-left: 5%" @click="list=!list" v-if="(user.role == 'Teacher' || user.role == 'Admin')&& request.equivalenceState == 'Pending'">See external curriculums</button>
|
||||
<div style="margin-top: 3%">
|
||||
<button><a :href="request.identityCard">{{ i18n("dlidentitycard") }}</a></button>
|
||||
<button style="margin-left: 3%" v-if="request.admissionDocUrl != null"><a :href="request.admissionDocUrl">{{ i18n("dladmissiondoc") }}</a></button>
|
||||
</div>
|
||||
<div>
|
||||
<button style="background-color:rgb(105,05,105);margin-top: 3%" @click="list=!list" v-if="(user.role === 'Teacher' || user.role === 'Admin')">{{ i18n("seeextcur") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="list == false">
|
||||
<button @click="windowState = 0">Back</button>
|
||||
<div v-if="list == false" style="margin-left: 30%; margin-top: 5%">
|
||||
<button @click="windowState = 0">{{ i18n("courses.back") }}</button>
|
||||
</div>
|
||||
<div v-if="list==true">
|
||||
<ExternalCurriculumList :ext-curr-list="externalCurriculum" :mode="0"></ExternalCurriculumList>
|
||||
<div style="margin-left: 15%;margin-top: 5%;">
|
||||
<button style="margin-left: 2%" @click="list = false;editEquivalence(request.id, 'Accepted'); request.equivalenceState='Accepted'">Accept Equivalence</button>
|
||||
<button style="margin-left: 2%" @click="list = false;editEquivalence(request.id, 'Refused'); request.equivalenceState='Refused'">Refuse Equivalence</button>
|
||||
<button style="margin-left: 2%" @click="list=false">Back</button>
|
||||
<button style="margin-left: 2%" v-if="request.equivalenceState === 'Pending' && !impose" @click="list = false;editEquivalence(request.id, 'Accepted'); request.equivalenceState='Accepted'">{{i18n("acceptequiv")}}</button>
|
||||
<button style="margin-left: 2%;margin-right: 3%" v-if="request.equivalenceState === 'Pending' && !impose" @click="list = false;editEquivalence(request.id, 'Refused'); request.equivalenceState='Refused'">{{i18n("refuseequiv")}}</button>
|
||||
<div v-if="!imposed && request.equivalenceState !== 'Accepted'" style="margin-top: 3%;margin-left: 1%">
|
||||
{{i18n("imposecurriculum")}}
|
||||
<input type="checkbox" v-model="impose" v-if="!imposed">
|
||||
<select v-if="impose" v-model="imposeCurr">
|
||||
<option v-for="item in curriculums" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<button v-if="impose && !imposed" style="margin-left: 2%" @click="imposeCurriculum(request.id, imposeCurr);request.equivalenceState='Accepted';imposed=true;">{{ i18n("impose") }}</button>
|
||||
<div v-if="imposed">
|
||||
{{ i18n("gotimposed") }}
|
||||
</div>
|
||||
<button style="margin-left: 2%" @click="list=false;refreshCursus()">{{ i18n("courses.back") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -128,10 +150,10 @@ async function editEquivalence(id, newstate){
|
||||
}
|
||||
|
||||
button{
|
||||
font-size:15px;
|
||||
height:50px;
|
||||
width:100px;
|
||||
border:none;
|
||||
border-radius:20px;
|
||||
background-color:rgb(239, 60, 168);
|
||||
border-radius:10px;
|
||||
height:35px;
|
||||
margin-top:10px;
|
||||
}
|
||||
</style>
|
@ -1,8 +1,7 @@
|
||||
<script setup>
|
||||
|
||||
import {addUninscReq, editScholarshipReq, getScholarshipReqById} from "@/rest/requests.js";
|
||||
import {editScholarshipReq, getScholarshipReqById} from "@/rest/requests.js";
|
||||
import i18n from "@/i18n.js";
|
||||
import {getUser} from "@/rest/Users.js";
|
||||
import {reactive, ref} from "vue";
|
||||
|
||||
const props = defineProps(["reqId"])
|
||||
@ -39,31 +38,31 @@ async function uploadandrefreshScholarshipRequest(){
|
||||
<div class="globalInfos">
|
||||
<div class="infosContainer">
|
||||
<div>
|
||||
Firstname/Name : {{user.firstName}} {{user.lastName}}
|
||||
{{ i18n("firstname/name") }} : {{user.firstName}} {{user.lastName}}
|
||||
</div>
|
||||
<div>
|
||||
E-mail: {{user.email}}
|
||||
{{ i18n("login.guest.email") }}: {{user.email}}
|
||||
</div>
|
||||
<div>
|
||||
Adresse : {{user.address}}
|
||||
{{ i18n("login.guest.address") }} : {{user.address}}
|
||||
</div>
|
||||
<div>
|
||||
Country : {{user.country}}
|
||||
{{ i18n("login.guest.country") }} : {{user.country}}
|
||||
</div>
|
||||
<div>
|
||||
Birthdate : {{user.birthDate.slice(0,10)}}
|
||||
{{ i18n("login.guest.birthday") }} : {{user.birthDate.slice(0,10)}}
|
||||
</div>
|
||||
<div>
|
||||
<button>Download tax justif document</button>
|
||||
<button style="margin-left: 2%">Download residency justif document</button>
|
||||
<button><a :href="req.taxDocUrl">{{ i18n("dltaxdoc") }}</a></button>
|
||||
<button style="margin-left: 2%"><a :href="req.residencyDocUrl">{{ i18n("dlresidency") }}</a></button>
|
||||
</div>
|
||||
<div v-if="req.state == 'Pending'">
|
||||
Please enter the amount to provide :
|
||||
<div v-if="req.state == 'Pending'" style="margin-top: 2%; margin-bottom: 2%;">
|
||||
{{i18n("enteramount")}}
|
||||
<input type="number" v-model="scholarshipData.amount">
|
||||
</div>
|
||||
<div>
|
||||
<button v-if="req.state === 'Pending'" @click="scholarshipData.state='Accepted';uploadandrefreshScholarshipRequest()">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='Accepted';uploadandrefreshScholarshipRequest()">{{i18n("request.accept")}}</button>
|
||||
<button v-if="req.state === 'Pending'" @click="scholarshipData.state='Refused';uploadandrefreshScholarshipRequest()" style="margin-left: 2%;">{{i18n("request.refuse")}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -101,7 +100,7 @@ async function uploadandrefreshScholarshipRequest(){
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
margin-top:7%;
|
||||
margin-top:10%;
|
||||
}
|
||||
|
||||
.subContainter{
|
||||
@ -121,4 +120,12 @@ async function uploadandrefreshScholarshipRequest(){
|
||||
background-color:rgb(50,50,50);
|
||||
border-radius:20px;
|
||||
}
|
||||
|
||||
button{
|
||||
border:none;
|
||||
background-color:rgb(239, 60, 168);
|
||||
border-radius:10px;
|
||||
height:35px;
|
||||
margin-top:10px;
|
||||
}
|
||||
</style>
|
@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import i18n from "@/i18n.js"
|
||||
import {getUser} from '../../rest/Users.js'
|
||||
import {getSelf, getUser} from '../../rest/Users.js'
|
||||
import {getSomeonesCurriculumList} from "@/rest/curriculum.js";
|
||||
import {ref} from "vue";
|
||||
import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue";
|
||||
@ -12,23 +12,13 @@
|
||||
const externalcurrlist = await getExternalCurriculumByUser(user.regNo)
|
||||
const extercurrlist = ref(false)
|
||||
|
||||
const watchingUser = await getSelf()
|
||||
function getPP(){
|
||||
if(user.profilePictureUrl === null){
|
||||
return "/Clyde.png"
|
||||
}
|
||||
return user.profilePictureUrl
|
||||
}
|
||||
|
||||
//Cette function renvoie l'année académique concernée si on est dans l'année 2023-2024 elle renvoie 2023
|
||||
//car dans la db l'année scolaire 2023-2024 est representée juste par 2023 (le même système s'applique pour chaque années on prend la borne inférieure
|
||||
function getYear(){
|
||||
let date = new Date();
|
||||
if (date.getMonth() <= 6){
|
||||
return date.getFullYear()-1
|
||||
}
|
||||
return date.getFullYear()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -40,47 +30,53 @@
|
||||
<div class = "globalInfos">
|
||||
<div class="infosContainer">
|
||||
<div>
|
||||
FirstName/Name : {{user.firstName}} {{user.lastName}}
|
||||
{{ i18n("firstname/name") }} : {{user.firstName}} {{user.lastName}}
|
||||
</div>
|
||||
<div>
|
||||
E-mail: {{user.email}}
|
||||
{{ i18n("regNo") }} : {{user.regNo}}
|
||||
</div>
|
||||
<div>
|
||||
Adresse : {{user.address}}
|
||||
{{ i18n("login.guest.email") }}: {{user.email}}
|
||||
</div>
|
||||
<div>
|
||||
Pays : {{user.country}}
|
||||
{{ i18n("login.guest.address") }} : {{user.address}}
|
||||
</div>
|
||||
<div>
|
||||
Date de naissance : {{user.birthDate}}
|
||||
{{ i18n("login.guest.country") }} : {{user.country}}
|
||||
</div>
|
||||
<div>
|
||||
<button @click="extercurrlist=!extercurrlist">See external curriculums</button>
|
||||
{{ i18n("login.guest.birthday") }} : {{user.birthDate}}
|
||||
</div>
|
||||
<div>
|
||||
<button v-if="watchingUser.role === 'Admin' || watchingUser.role === 'InscriptionService' || watchingUser.role === 'Secretary' || watchingUser.regNo === user.regNo"><a :href="user.identityCard">{{i18n("dlidentitycard")}}</a></button>
|
||||
</div>
|
||||
<div>
|
||||
<button @click="extercurrlist=!extercurrlist">{{i18n("seeextcur")}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="moreInfos">
|
||||
<div class="moreInfos" style="margin-top: 15%">
|
||||
<div class = "oldcursus">
|
||||
<div class="listTitle">
|
||||
Anciens Cursus
|
||||
{{ i18n("oldcursus") }}
|
||||
</div>
|
||||
<div class="listElement">
|
||||
<div class=" containerElement" v-for="item in UserCurriculum.curriculumList">
|
||||
<div class="year" v-if="item.actual === false">Bac {{item.year}}</div>
|
||||
<div class="option" v-if="item.actual === false">{{item.option}}</div>
|
||||
<div class="dateyear" v-if="item.actual === false">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 class="newcursus">
|
||||
<div class="listTitle">
|
||||
Cursus Actuel
|
||||
{{ i18n("newcursus") }}
|
||||
</div>
|
||||
<div class="listElement">
|
||||
<div class=" containerElement" v-for="item in UserCurriculum.curriculumList" >
|
||||
<div class="year" v-if="item.actual === true">Bac {{item.year}}</div>
|
||||
<div class="option" v-if="item.actual === true">{{item.option}}</div>
|
||||
<div class="dateyear" v-if="item.actual === true">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>
|
||||
@ -94,6 +90,7 @@
|
||||
|
||||
|
||||
<style scoped>
|
||||
|
||||
.container{
|
||||
min-width:675px;
|
||||
display:grid;
|
||||
@ -102,8 +99,7 @@
|
||||
column-gap:2.7%;
|
||||
row-gap:45px;
|
||||
grid-template-areas:
|
||||
"profilPic globalInfos"
|
||||
"minfos minfos";
|
||||
"profilPic globalInfos";
|
||||
}
|
||||
|
||||
.profilPic{
|
||||
@ -143,12 +139,10 @@
|
||||
}
|
||||
|
||||
.moreInfos {
|
||||
display:grid;
|
||||
grid-template-rows:200px auto;
|
||||
display:inline-grid;
|
||||
column-gap:50px;
|
||||
row-gap:45px;
|
||||
grid-template-areas:
|
||||
"minfos minfos";
|
||||
"oldcursus newcursus";
|
||||
grid-template-columns:600px 600px;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
@ -189,4 +183,12 @@
|
||||
column-gap:40px;
|
||||
padding-left: 25px;
|
||||
}
|
||||
|
||||
button{
|
||||
border:none;
|
||||
background-color:rgb(239, 60, 168);
|
||||
border-radius:10px;
|
||||
height:35px;
|
||||
margin-top:10px;
|
||||
}
|
||||
</style>
|
@ -1,26 +1,15 @@
|
||||
<script setup>
|
||||
|
||||
import {
|
||||
addUninscReq,
|
||||
editScholarshipReq,
|
||||
editUnregReq,
|
||||
getScholarshipReqById,
|
||||
getUnregisterbyId
|
||||
} from "@/rest/requests.js";
|
||||
import i18n from "@/i18n.js";
|
||||
import {getUser} from "@/rest/Users.js";
|
||||
import {reactive, ref} from "vue";
|
||||
import {ref} from "vue";
|
||||
|
||||
const props = defineProps(["reqId"])
|
||||
const req = ref(await getUnregisterbyId(props.reqId))
|
||||
|
||||
function getPP(){
|
||||
if(user.profilePictureUrl === null){
|
||||
return "/Clyde.png"
|
||||
}
|
||||
return user.profilePictureUrl
|
||||
}
|
||||
|
||||
async function uploadandrefreshUnregRequest(state){
|
||||
await editUnregReq(req.value.id, state)
|
||||
req.value.state = state
|
||||
@ -34,21 +23,21 @@ async function uploadandrefreshUnregRequest(state){
|
||||
<div class="globalInfos">
|
||||
<div class="infosContainer">
|
||||
<div>
|
||||
Firstname/Name : {{req.firstName}} {{req.lastName}}
|
||||
{{ i18n("firstname/name") }} : {{req.firstName}} {{req.lastName}}
|
||||
</div>
|
||||
<div>
|
||||
E-mail: {{req.email}}
|
||||
{{ i18n("login.guest.email") }}: {{req.email}}
|
||||
</div>
|
||||
<div>
|
||||
regNo : {{req.regNo}}
|
||||
{{ i18n("regNo") }} : {{req.regNo}}
|
||||
</div>
|
||||
<div>
|
||||
Reason :
|
||||
{{ i18n("reason") }}
|
||||
<input type="text" v-model="req.reason" readonly/>
|
||||
</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='Refused';uploadandrefreshUnregRequest('Refused')" style="margin-left: 2%;">Refuse</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%;">{{i18n("request.refuse")}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -69,15 +58,9 @@ async function uploadandrefreshUnregRequest(state){
|
||||
"minfos minfos";
|
||||
}
|
||||
|
||||
.profilPic{
|
||||
width:100%;
|
||||
grid-area:profilPic;
|
||||
}
|
||||
|
||||
.globalInfos {
|
||||
grid-area:globalInfos;
|
||||
align-self :center;
|
||||
|
||||
}
|
||||
|
||||
.body {
|
||||
@ -89,13 +72,6 @@ async function uploadandrefreshUnregRequest(state){
|
||||
margin-top:7%;
|
||||
}
|
||||
|
||||
.subContainter{
|
||||
width:100%;
|
||||
background-color:rgb(50,50,50);
|
||||
border-radius:20px;
|
||||
border:4px solid black;
|
||||
}
|
||||
|
||||
.infosContainer {
|
||||
min-width:350px;
|
||||
padding-bottom:50px;
|
||||
|
@ -2,16 +2,18 @@
|
||||
|
||||
import {reactive, ref} from "vue";
|
||||
import i18n from "@/i18n.js";
|
||||
import {getCourse} from "@/rest/courses.js";
|
||||
import {getcurriculum} from "@/rest/curriculum.js";
|
||||
import {uploadFile, uploadProfilePicture} from "@/rest/uploads.js";
|
||||
import {createExemptionsRequest} from "@/rest/requests.js";
|
||||
import {uploadFile} from "@/rest/uploads.js";
|
||||
import {createExemptionsRequest, getExempByUser} from "@/rest/requests.js";
|
||||
import {getSelf} from "@/rest/Users.js";
|
||||
|
||||
const props = defineProps(["cursuslist"])
|
||||
const selectedCurriculum = ref(props.cursuslist[0])
|
||||
const user = await getSelf()
|
||||
|
||||
const windowState = defineModel("windowState")
|
||||
const exempList = await getExempByUser(user.regNo)
|
||||
const submitted = ref(false)
|
||||
const courseslist = ref(await getcurriculum(selectedCurriculum.value.curriculumId))
|
||||
const list = ref(true)
|
||||
|
||||
@ -30,11 +32,20 @@ const exemptReq = reactive({
|
||||
courseId : null,
|
||||
justifDocument : "",
|
||||
})
|
||||
|
||||
function isExempted(course){
|
||||
for (let i = 0; i < exempList.length; i++){
|
||||
if (exempList[i].course.courseID === course.courseId && exempList[i].state === "Accepted"){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template style="margin-top:5%;">
|
||||
<div v-if="list == true">
|
||||
<span>Selected Cursus : </span>
|
||||
<span>{{i18n("selectedcursus")}} : </span>
|
||||
<select v-model="selectedCurriculum" @change="updateCourseList">
|
||||
<option v-for="item in props.cursuslist" :value="item">Bac {{item.year}} {{item.option}}</option>
|
||||
</select>
|
||||
@ -45,19 +56,31 @@ const exemptReq = reactive({
|
||||
<div class="firstname">{{item.owner.firstName}}</div>
|
||||
<div class="lastname">{{item.owner.lastName}}</div>
|
||||
<div class="credits">credits : {{item.credits}}</div>
|
||||
<div class="askexemption"><button style="background-color:rgb(105,0,0);" @click="list= !list;exemptReq.courseId=item.courseId">Ask exemption</button></div>
|
||||
<div class="askexemption" v-if="!isExempted(item)"><button style="background-color:rgb(105,0,0);" @click="list= !list;exemptReq.courseId=item.courseID;">{{i18n("askexemp")}}</button></div>
|
||||
<div v-else class="askexemption" style="font-size: 50%">{{ i18n("exemp") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button @click="windowState = 0">{{ i18n("courses.back")}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p>Please upload the justification document for the exemption </p>
|
||||
<label class="browser">
|
||||
<input type="file" @change="ppData.value = $event.target.files" accept="image/*" ref="filepath">
|
||||
<div v-if="list === false" class="infosContainer">
|
||||
<p v-if="!submitted">{{ i18n("uploadjustifdoc") }} </p>
|
||||
<div>
|
||||
<label class="browser" v-if="!submitted">
|
||||
<input type="file" @change="ppData.value = $event.target.files" ref="filepath">
|
||||
</label>
|
||||
<button style="width:15%; margin-top: 5%;" @click="postExemptionRequest(ppData.value, 'JustificationDocument');">
|
||||
Submit exemption request
|
||||
</div>
|
||||
<button style="margin-top: 3%" v-if="!submitted" @click="postExemptionRequest(ppData.value, 'JustificationDocument');submitted=!submitted">
|
||||
{{ i18n("subexemreq") }}
|
||||
</button>
|
||||
<div v-if="submitted">
|
||||
{{i18n("reqsent")}}
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="list === false">
|
||||
<button @click="list=!list;submitted=false">{{ i18n("courses.back") }}</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -135,5 +158,15 @@ button{
|
||||
margin-top:10px;
|
||||
|
||||
}
|
||||
|
||||
.infosContainer {
|
||||
padding-bottom:50px;
|
||||
border:2px solid black;
|
||||
font-size:25px;
|
||||
color:white;
|
||||
padding:20px;
|
||||
background-color:rgb(50,50,50);
|
||||
border-radius:20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
import {reactive, ref} from "vue";
|
||||
import {getSelf} from "@/rest/Users.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
|
||||
const props = defineProps(["extCurrList", "mode"])
|
||||
@ -30,7 +31,7 @@
|
||||
completion : "completed",
|
||||
startYear : 0,
|
||||
endYear: 0,
|
||||
justifdocUrl : null,
|
||||
justifdocUrl : "",
|
||||
userRegNo : null
|
||||
})
|
||||
|
||||
@ -42,7 +43,6 @@
|
||||
|
||||
if(props.mode !== 2){
|
||||
extCurrList.value = props.extCurrList
|
||||
console.log("oe")
|
||||
}
|
||||
|
||||
function deleteExtCursus(extcursus){
|
||||
@ -51,7 +51,8 @@
|
||||
|
||||
async function postExternalCurr(){
|
||||
if (props.mode === 1){
|
||||
await createExternalCurriculum(externalCurr.inscriptionRequestId, externalCurr.school, externalCurr.formation, externalCurr.completion, externalCurr.startYear, externalCurr.endYear, externalCurr.justifdocUrl, externalCurr.userRegNo);
|
||||
const temp = await uploadFile(externalCurr.justifdocUrl, "JustificationDocument")
|
||||
await createExternalCurriculum(externalCurr.inscriptionRequestId, externalCurr.school, externalCurr.formation, externalCurr.completion, externalCurr.startYear, externalCurr.endYear, temp.url, externalCurr.userRegNo);
|
||||
//We refresh the list
|
||||
extCurrList.value = await getExternalCurriculumByUser(externalCurr.userRegNo);
|
||||
list.value = !list.value;
|
||||
@ -68,7 +69,6 @@
|
||||
});
|
||||
extCurrList.value = externalCurrTab.value
|
||||
list.value = !list.value;
|
||||
console.log(externalCurrTab.value)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -76,18 +76,18 @@
|
||||
<template style="margin-top:5%;">
|
||||
<div v-if="list">
|
||||
<div v-if="props.mode === 2||User.regNo === externalCurr.userRegNo" style="margin-left: 2%;margin-top: 2%">
|
||||
<button @click="list = !list">Add external curriculum</button>
|
||||
<button @click="list = !list" style="margin-left:15%;">{{ i18n("addextcurr") }}</button>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:center; " v-for="(item, index) in extCurrList">
|
||||
<div style="display:flex; justify-content:center;" v-for="(item, index) in extCurrList">
|
||||
<div class="bodu">
|
||||
<div class="container">
|
||||
<div class="status"><a style="margin-left:30px">{{item.state}}</a></div>
|
||||
<div class="school"><a>{{item.school}}</a></div>
|
||||
<div class="formation"><a>{{item.formation}}</a></div>
|
||||
<div class="completion"><a>{{item.completion}}</a></div>
|
||||
<div class="download"><button>Download document</button></div>
|
||||
<div class="edit" v-if="props.mode === 2"><button @click="list=!list;externalCurr.justifdocUrl=item.justifDocUrl; externalCurr.endYear = item.endYear; externalCurr.startYear = item.startYear; externalCurr.school = item.school;externalCurr.completion = item.completion;externalCurr.formation=item.formation;editmode=!editmode;extNum=index">Edit</button></div>
|
||||
<div class="delete" v-if="props.mode === 2"><button @click="deleteExtCursus(item)">Delete</button></div>
|
||||
<div class="download" v-if="props.mode!==2"><button><a :href="item.justifdocUrl">{{ i18n("dldoc") }}</a></button></div>
|
||||
<div class="edit" v-if="props.mode === 2"><button @click="list=!list;externalCurr.justifdocUrl=item.justifDocUrl; externalCurr.endYear = item.endYear; externalCurr.startYear = item.startYear; externalCurr.school = item.school;externalCurr.completion = item.completion;externalCurr.formation=item.formation;editmode=!editmode;extNum=index">{{i18n("edit")}}</button></div>
|
||||
<div class="delete" v-if="props.mode === 2"><button @click="deleteExtCursus(item)">{{ i18n("delete") }}</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -95,7 +95,7 @@
|
||||
<div v-else class="loginbox" style="margin-left: 35%; margin-top: 3%">
|
||||
<form class="form">
|
||||
<div class="inputBox">
|
||||
<p>Ecole</p>
|
||||
<p>{{ i18n("school") }}</p>
|
||||
<input type="text" v-model="externalCurr.school">
|
||||
</div>
|
||||
<div class="inputBox">
|
||||
@ -103,24 +103,28 @@
|
||||
<input type="text" v-model="externalCurr.formation">
|
||||
</div>
|
||||
<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">
|
||||
<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">
|
||||
</div>
|
||||
</div>
|
||||
<div class="inputBox">
|
||||
<p>Année de début</p>
|
||||
<p>{{ i18n("startyear") }}</p>
|
||||
<input type="number" v-model="externalCurr.startYear">
|
||||
</div>
|
||||
<div class="inputBox">
|
||||
<p>Année de fin</p>
|
||||
<p>{{ i18n("endyear") }}</p>
|
||||
<input type="number" v-model="externalCurr.endYear">
|
||||
</div>
|
||||
<div class="inputBox">
|
||||
<p>{{i18n("giveextcurdoc")}}</p>
|
||||
<input type="file" @change="externalCurr.justifdocUrl = $event.target.files">
|
||||
</div>
|
||||
<div class="inputBox" style="margin-top: 3%; margin-bottom: 3%">
|
||||
<input v-if="!editmode" type="submit" value="Upload curriculum" @click="postExternalCurr()">
|
||||
<input v-else type="submit" value="Edit curriculum" @click="externalCurrTab[extNum] = {inscriptionRequestId : externalCurr.inscriptionRequestId,school:externalCurr.school,formation :externalCurr.formation,completion : externalCurr.completion,startYear : externalCurr.startYear,endYear: externalCurr.endYear,justifdocUrl : externalCurr.justifdocUrl,userRegNo : externalCurr.userRegNo};editmode=!editmode;list=!list">
|
||||
<input v-if="!editmode" type="submit" value="upload" @click="postExternalCurr()">
|
||||
<input v-else type="submit" value="edit" @click="externalCurrTab[extNum] = {inscriptionRequestId : externalCurr.inscriptionRequestId,school:externalCurr.school,formation :externalCurr.formation,completion : externalCurr.completion,startYear : externalCurr.startYear,endYear: externalCurr.endYear,justifdocUrl : externalCurr.justifdocUrl,userRegNo : externalCurr.userRegNo};editmode=!editmode;list=!list">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@ -224,8 +228,14 @@
|
||||
z-index: 100;
|
||||
font-family:sans-serif ;
|
||||
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>
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import i18n from "@/i18n.js"
|
||||
import {ref, vModelSelect} from 'vue'
|
||||
import {ref, watch} from 'vue'
|
||||
import {validateRegister, getAllRegisters } from '@/rest/ServiceInscription.js'
|
||||
import AboutRequest from "@/Apps/Inscription/AboutRequest.vue";
|
||||
import {
|
||||
@ -13,11 +13,12 @@
|
||||
import AboutUnregister from "@/Apps/Inscription/AboutUnregister.vue";
|
||||
import AboutChangeCurriculum from "@/Apps/Inscription/AboutChangeCurriculum.vue";
|
||||
import AboutExemption from "@/Apps/Inscription/AboutExemption.vue";
|
||||
import {getSelf} from "@/rest/Users.js";
|
||||
|
||||
const requests = ref(await getAllRegisters());
|
||||
let targetId = "";
|
||||
|
||||
const requestType = ref("inscription");
|
||||
const user = await getSelf()
|
||||
const requestType = ref(i18n("inscription"));
|
||||
const filterType = ref("None");
|
||||
|
||||
//0 = liste, 1 = détails, 2 = sure?, 3 = manage scholarship, 4 manage unregister, 5 = manage curriculum change, 6 = manage exemptions
|
||||
@ -31,22 +32,29 @@
|
||||
|
||||
async function loadRequests(){
|
||||
switch (requestType.value){
|
||||
case "inscription":
|
||||
case i18n("inscription"):
|
||||
requests.value = await getAllRegisters();
|
||||
break;
|
||||
case "scholarship":
|
||||
case i18n("scholarship"):
|
||||
requests.value = await getAllScholarShipsRequest();
|
||||
break;
|
||||
case "exemption":
|
||||
case i18n("exemption"):
|
||||
requests.value = await getAllExemptionsRequest();
|
||||
break;
|
||||
case "unregister":
|
||||
case i18n("unregister"):
|
||||
requests.value = await getAllUnregisters();
|
||||
break;
|
||||
case "curriculum change":
|
||||
case i18n("curriculumch"):
|
||||
requests.value = await getAllChangeCurrReq();
|
||||
}
|
||||
}
|
||||
|
||||
//When we come back to the list we need to reload the list
|
||||
watch(windowsState, () => {
|
||||
if (windowsState.value === 0){
|
||||
loadRequests();
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@ -57,16 +65,16 @@
|
||||
</div>
|
||||
<div v-if="windowsState === 0">
|
||||
<div style="margin-top: 2%;margin-left: 2%">
|
||||
<span>Request type : </span>
|
||||
<span>{{ i18n("reqtype") }} : </span>
|
||||
<select v-model="requestType" @change="loadRequests()">
|
||||
<option>inscription</option>
|
||||
<option>scholarship</option>
|
||||
<option>exemption</option>
|
||||
<option>unregister</option>
|
||||
<option>curriculum change</option>
|
||||
<option>{{ i18n("inscription") }}</option>
|
||||
<option v-if="user.role === 'Admin' || user.role === 'InscriptionService'">{{ i18n("scholarship") }}</option>
|
||||
<option v-if="user.role === 'Admin' || user.role === 'Teacher'">{{ i18n("exemption") }}</option>
|
||||
<option v-if="user.role === 'Admin' || user.role === 'InscriptionService'">{{ i18n("unregister") }}</option>
|
||||
<option>{{ i18n("curriculumch") }}</option>
|
||||
</select>
|
||||
<span style="margin-left: 5%">
|
||||
Filter :
|
||||
{{ i18n("filter") }}
|
||||
<select v-model="filterType">
|
||||
<option>None</option>
|
||||
<option>Pending</option>
|
||||
@ -76,70 +84,69 @@
|
||||
</span>
|
||||
</div>
|
||||
<div style='display:flex; justify-content:center; min-width:1140px;' v-for="item of requests">
|
||||
<div class="bodu" style="width: 95%" v-if="filterType == 'None' || filterType == item.state">
|
||||
<div class="container" style="grid-template-columns:11% 15% 20% 10% 10% 9% 9%;grid-template-areas:'date state equivalencestate surname firstname accept refuse infos';" v-if="requestType === 'inscription'">
|
||||
<!--
|
||||
The condition below avoids an error occuring because loadRequests() finishes after the vue refresh
|
||||
then submissionDate is undefined an it triggers an error in the console despite the fact that it is working
|
||||
properly at the end.
|
||||
-->
|
||||
<div class="bodu" style="width: 95%" v-if="(filterType == 'None' || filterType == item.state) && requestType !== i18n('exemption')">
|
||||
<div class="container" style="grid-template-columns:11% 15% 20% 10% 10% 9% 9%;grid-template-areas:'date state equivalencestate surname firstname accept refuse infos';" v-if="requestType === i18n('inscription')">
|
||||
<div class="date" v-if="item.submissionDate !== undefined">{{item.submissionDate.slice(0, 10)}}</div>
|
||||
<div class="state" style="font-size: 80%">Approval : {{item.state}}</div>
|
||||
<div class="equivalencestate" style="font-size: 80%">Teacher approval : {{item.equivalenceState}}</div>
|
||||
<div class="state" style="font-size: 80%">{{ i18n("approval") }} {{item.state}}</div>
|
||||
<div class="equivalencestate" style="font-size: 80%">{{ i18n("teacherapproval") }} {{item.equivalenceState}}</div>
|
||||
<div class="surname">{{item.lastName}}</div>
|
||||
<div class="firstname">{{item.firstName}}</div>
|
||||
<div class="accept" v-if="item.state === 'Pending'"><button @click="windowsState=2;targetId=item.id;" style="background-color:rgb(0,105,50);">{{i18n("request.accept")}}</button></div>
|
||||
<div class="refuse" v-if="item.state === 'Pending'"><button @click="upPage(item.id,'Refused')" style="background-color:rgb(105,0,0);">{{i18n("request.refuse")}}</button></div>
|
||||
<div class="accept" v-if="item.state === 'Pending' && (user.role === 'Admin' || user.role === 'InscriptionService')"><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' && (user.role === 'Admin' || user.role === 'InscriptionService')"><button @click="upPage(item.id,'Refused')" style="background-color:rgb(105,0,0);">{{i18n("request.refuse")}}</button></div>
|
||||
<div class="infos"><button style="background-color:rgb(105,05,105);" @click="targetId=item.id;windowsState=1;">{{i18n("request.moreInfos")}}</button></div>
|
||||
</div>
|
||||
<div class="container" style="grid-template-columns:25% 15% 15% 25% 14.2%;grid-template-areas:'date reqState studentfirstname studentlastname infos';" v-if="requestType === 'scholarship'">
|
||||
<div class="container" style="grid-template-columns:25% 15% 15% 25% 14.2%;grid-template-areas:'date reqState studentfirstname studentlastname infos';" v-if="requestType === i18n('scholarship')">
|
||||
<div class="date" v-if="item.date !== undefined"> {{item.date.slice(0,10)}}</div>
|
||||
<div class="studentfirstname">{{item.user.firstName}}</div>
|
||||
<div class="studentlastname">{{item.user.lastName}}</div>
|
||||
<div class="reqState">{{item.state}}</div>
|
||||
<div class="infos" @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 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="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="container" v-if="requestType === i18n('unregister')" style="grid-template-columns:17% 15% 12% 15%;grid-template-areas:'date reqState regno studentfirstname studentlastname infos';">
|
||||
<div class="date" v-if="item.date != undefined">{{item.date.slice(0,10)}}</div>
|
||||
<div class="studentfirstname">{{item.firstName}}</div>
|
||||
<div class="studentlastname">{{item.lastName}}</div>
|
||||
<div class="regno">id : {{item.regNo}}</div>
|
||||
<div class="reqState">{{item.state}}</div>
|
||||
<div class="infos"><button @click="windowsState=4;targetId=item.id">More infos</button></div>
|
||||
<div class="infos"><button @click="windowsState=4;targetId=item.id">{{ i18n("request.moreInfos") }}</button></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="studentfirstname">{{item.user.firstName}}</div>
|
||||
<div class="studentlastname">{{item.user.lastName}}</div>
|
||||
<div class="reqState">IS approval : {{item.state}}</div>
|
||||
<div class="teacherApproval">Teacher approval : {{item.teacherApprovalState}}</div>
|
||||
<div class="infos"><button @click="windowsState=5;targetId=item.id">More infos</button></div>
|
||||
<div class="reqState">{{ i18n("approval")}}{{item.state}}</div>
|
||||
<div class="teacherApproval">{{ i18n("teacherapproval") }} {{item.teacherApprovalState}}</div>
|
||||
<div class="infos"><button @click="windowsState=5;targetId=item.id">{{ i18n("request.moreInfos") }}</button></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bodu" v-if="(filterType == 'None' || filterType == item.state) && requestType === i18n('exemption') && (item.course.owner.regNo === user.regNo || user.role === 'Admin')">
|
||||
<div class="container" style="grid-template-columns:17% 15% 12% 15% 25%;grid-template-areas:'date reqState studentfirstname studentlastname course infos';">
|
||||
<div class="date" v-if="item.date != undefined">{{item.date.slice(0,10)}}</div>
|
||||
<div class="studentfirstname">{{item.user.firstName}}</div>
|
||||
<div class="studentlastname">{{item.user.lastName}}</div>
|
||||
<div class="course">{{item.course.title}}</div>
|
||||
<div class="reqState">{{item.state}}</div>
|
||||
<div class="infos"><button @click="windowsState=6;targetId=item.id">{{ i18n("request.moreInfos") }}</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style='display:flex; justify-content:center; min-width:1140px;margin-top: 10%' v-if="windowsState === 2">
|
||||
<p>Etes vous sur de vouloir accepter cette demande ?</p>
|
||||
<button style="background-color:rgb(105,05,105);" @click="upPage(targetId,'Accepted');windowsState=0;">Valider</button>
|
||||
<button style="background-color:rgb(105,05,105);" @click="windowsState=0;">Retour</button>
|
||||
<div class="infosContainer" style='margin-left:15%;display:flex; justify-content:center; width: 70%;margin-top: 10%' v-if="windowsState === 2">
|
||||
<p>{{ i18n("surreq") }}</p>
|
||||
<div style="margin-left: 10%; margin-top: 1.5%; width: 30%">
|
||||
<button style="background-color:rgb(105,05,105);margin-right: 2%" @click="upPage(targetId,'Accepted');windowsState=0;">{{ i18n("validate") }}</button>
|
||||
<button style="background-color:rgb(105,05,105);" @click="windowsState=0;">{{ i18n("courses.back")}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="windowsState === 3">
|
||||
<AboutScholarship :req-id="targetId"></AboutScholarship>
|
||||
<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 v-if="windowsState === 4">
|
||||
<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 v-if="windowsState === 5">
|
||||
<AboutChangeCurriculum :req-id="targetId" v-model:window-state="windowsState"></AboutChangeCurriculum>
|
||||
@ -233,12 +240,11 @@
|
||||
}
|
||||
|
||||
button{
|
||||
font-size:15px;
|
||||
height:50px;
|
||||
width:100px;
|
||||
border:none;
|
||||
border-radius:20px;
|
||||
|
||||
background-color:rgb(239, 60, 168);
|
||||
border-radius:10px;
|
||||
height: 35px;
|
||||
margin-top:10px;
|
||||
}
|
||||
|
||||
.bodu {
|
||||
@ -249,7 +255,15 @@
|
||||
background-color:rgb(50,50,50);
|
||||
}
|
||||
|
||||
|
||||
.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>
|
||||
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
<script setup>
|
||||
import i18n from "@/i18n.js";
|
||||
import {ref} from "vue";
|
||||
import {getAllPayments} from "@/rest/requests.js";
|
||||
|
||||
const paymentsList = await getAllPayments()
|
||||
|
||||
</script>
|
||||
|
||||
<template style="margin-top:5%;">
|
||||
<div style="display:flex; justify-content:center; " v-for="item in paymentsList">
|
||||
<div class="bodu">
|
||||
<div class="container">
|
||||
<div class="regNo"><a style="margin-left:30px">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="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>
|
||||
</div>
|
||||
|
@ -1,26 +1,42 @@
|
||||
|
||||
<!----------------------------------------------------
|
||||
File: LessonRequests.vue
|
||||
Author: William Karpinski
|
||||
Scope: Extension Horaire
|
||||
Description: Lesson Requests Management Page
|
||||
----------------------------------------------------->
|
||||
|
||||
<script setup>
|
||||
import i18n from "@/i18n.js"
|
||||
import {ref} from 'vue'
|
||||
import {changeRequestState, getAllRequests} from "@/rest/LessonRequests.js";
|
||||
import {getLesson} from "@/rest/lessonSchedule.js";
|
||||
import {getCourse} from "@/rest/courses.js"
|
||||
import {formatDate, getHoursMinutes} from "@/scheduleFunctions.js";
|
||||
|
||||
const requests = ref(await getAllRequests());
|
||||
|
||||
const AcceptMod = ref(false);
|
||||
const moreInfosMod = ref(false);
|
||||
const requestTypes = ["Create", "Modify", "Delete"]
|
||||
const editElementID = ref('');
|
||||
const chosenLocal = ref("");
|
||||
const chosenLocal = ref();
|
||||
const locals = ["A0B1","A1B1","A2B1","A0B2"];
|
||||
const moreInfos = ref({});
|
||||
|
||||
|
||||
/*
|
||||
* Change a request's state and refreshes the requests '
|
||||
*/
|
||||
|
||||
async function upPage(id,review){
|
||||
await changeRequestState(id, review) ;
|
||||
requests.value = await getAllRequests();
|
||||
chosenLocal.value = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set correctly the variables after clicking on the ACCEPT button
|
||||
*/
|
||||
|
||||
async function AcceptSetup(id,type){
|
||||
if(type !== 2 ){
|
||||
editElementID.value = id
|
||||
@ -31,10 +47,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){
|
||||
|
||||
moreInfos.value = Object.assign({},{})
|
||||
@ -64,17 +79,17 @@ async function setMoreInfos(item){
|
||||
<template>
|
||||
|
||||
<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 class="containerElement" v-if="editElementID !== item.id">
|
||||
<div class="id">{{requestTypes[item.requestType]}}</div>
|
||||
<div class="surname">{{item.state}}</div>
|
||||
<div class="id">{{i18n(requestTypes[item.requestType].toString())}}</div>
|
||||
<div class="surname">{{i18n(item.state.toString())}}</div>
|
||||
<div class="firstname">{{item.user.lastName}}</div>
|
||||
|
||||
<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")}}
|
||||
</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 +102,13 @@ async function setMoreInfos(item){
|
||||
<select v-model="chosenLocal">
|
||||
<option v-for="item in locals">{{item}}</option>
|
||||
</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>
|
||||
<template v-if="moreInfosMod" v-for="(key,value) in moreInfos">
|
||||
|
||||
<div class="container" v-if="key != null" style="align-self:center;">
|
||||
<div style="margin:0 auto 0 auto">
|
||||
{{value}}:
|
||||
{{i18n(value.toString())}}:
|
||||
{{key}}
|
||||
</div>
|
||||
</div>
|
||||
@ -105,7 +120,9 @@ async function setMoreInfos(item){
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.centerer{
|
||||
|
||||
|
||||
.center{
|
||||
margin:0 auto 0 auto;
|
||||
}
|
||||
|
||||
@ -193,33 +210,10 @@ button{
|
||||
width:100%;
|
||||
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>
|
||||
|
||||
|
@ -2,12 +2,11 @@
|
||||
import {reactive, ref } from 'vue'
|
||||
import i18n from '@/i18n.js'
|
||||
import {login, register, disconnect, isLogged} from '@/rest/Users.js'
|
||||
import {getAllCurriculums, getcurriculum} from '@/rest/curriculum.js'
|
||||
import {getAllCurriculums} from '@/rest/curriculum.js'
|
||||
import {uploadFile, uploadProfilePicture} from '@/rest/uploads.js'
|
||||
import {toast} from 'vue3-toastify'
|
||||
import 'vue3-toastify/dist/index.css';
|
||||
import {createExternalCurriculum} from "@/rest/externalCurriculum.js";
|
||||
import ManageCourses from "@/Apps/ManageCourses.vue";
|
||||
import ExternalCurriculumList from "@/Apps/Inscription/ExternalCurriculumList.vue";
|
||||
|
||||
const loginPage= ref(true)
|
||||
@ -17,7 +16,7 @@
|
||||
surname:null,
|
||||
firstname:null,
|
||||
password:null,
|
||||
birthday:null,
|
||||
birthday:"1990-01-01",
|
||||
email:null,
|
||||
address:null,
|
||||
country:null,
|
||||
@ -25,18 +24,6 @@
|
||||
equivalenceState: "Unrequired"
|
||||
})
|
||||
|
||||
const notcompletedCheck = ref(false);
|
||||
|
||||
const externalCurr = reactive({
|
||||
inscriptionRequestId : null,
|
||||
school:null,
|
||||
formation :null,
|
||||
completion : null,
|
||||
startYear : null,
|
||||
endYear: null,
|
||||
justifdocUrl : null
|
||||
})
|
||||
|
||||
//Stores some externalCurriculums in order to upload them all at the confirmation of the registration request
|
||||
const externalCurrTab = ref([]);
|
||||
|
||||
@ -44,14 +31,12 @@
|
||||
const passwordConfirm=ref("")
|
||||
|
||||
const imageSaved = ref(false)
|
||||
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 ppData = ref({})
|
||||
const idcardfile = ref({})
|
||||
const justifcardfile = ref({})
|
||||
|
||||
const allfileshere = ref(0)
|
||||
const curricula= await getAllCurriculums();
|
||||
|
||||
function goBackHome(){
|
||||
@ -74,11 +59,6 @@
|
||||
disconnect();
|
||||
window.location.reload();}
|
||||
|
||||
async function uploadPP(arg){
|
||||
const data = await uploadProfilePicture(arg);
|
||||
ppData = data.url;
|
||||
}
|
||||
|
||||
//This functions makes the distinction between a master cursus (year 4 or more) and a bachelor cursus (year 3 or less)
|
||||
function getCursusDisplay(cursus){
|
||||
if (cursus.year <= 3){
|
||||
@ -94,6 +74,13 @@
|
||||
const identityCardFile = await uploadFile(idcardfile.value, "IdentityCard")
|
||||
const justifFile = ref(null)
|
||||
|
||||
|
||||
const profilepic = ref(null)
|
||||
if (imageSaved){
|
||||
profilepic.value = await uploadProfilePicture(ppData.value)
|
||||
}
|
||||
|
||||
|
||||
if (curricula[outputs.curriculum-1].requireCertificate){
|
||||
justifFile.value = await uploadFile(justifcardfile.value, "JustificationDocument")
|
||||
}
|
||||
@ -105,16 +92,23 @@
|
||||
justif = null
|
||||
}
|
||||
|
||||
const val = await register(outputs.firstname, outputs.surname, outputs.birthday, outputs.password, outputs.email, outputs.address, outputs.country, outputs.curriculum, ppData, identityCardFile.url, new Date(), outputs.equivalenceState, justif);
|
||||
const val = await register(outputs.firstname, outputs.surname, outputs.birthday, outputs.password, outputs.email, outputs.address, outputs.country, outputs.curriculum, profilepic.value.url, identityCardFile.url, new Date(), outputs.equivalenceState, justif);
|
||||
|
||||
for (let item in externalCurrTab.value){
|
||||
await createExternalCurriculum(val.id, externalCurrTab.value[item].school, externalCurrTab.value[item].formation, externalCurrTab.value[item].completion, externalCurrTab.value[item].startYear, externalCurrTab.value[item].endYear, externalCurrTab.value[item].justifdocUrl);
|
||||
const temp = await uploadFile(externalCurrTab.value[item].justifdocUrl, "JustificationDocument")
|
||||
await createExternalCurriculum(val.id, externalCurrTab.value[item].school, externalCurrTab.value[item].formation, externalCurrTab.value[item].completion, externalCurrTab.value[item].startYear, externalCurrTab.value[item].endYear, temp.url);
|
||||
}
|
||||
}
|
||||
|
||||
function everyfilehere(){
|
||||
if(allfileshere.value === 2 || (allfileshere.value === 1 && curricula[outputs.curriculum-1].requireCertificate === false)){
|
||||
return true
|
||||
}else{
|
||||
return false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="setup" v-if="page !== 4">
|
||||
<div v-if="loginPage">
|
||||
@ -135,7 +129,7 @@
|
||||
<a @click="loginPage=!loginPage">{{i18n("login.guest.register")}}</a>
|
||||
</div>
|
||||
<div class="inputBox" style="margin-bottom:35px;">
|
||||
<input type="submit" v-model="submitValue">
|
||||
<input v-model="submitValue" type="submit">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@ -157,7 +151,7 @@
|
||||
</div>
|
||||
<div class="inputBox">
|
||||
<p>{{i18n("login.guest.birthday")}}</p>
|
||||
<input type="date" v-model="outputs.birthday">
|
||||
<input type="date" v-model="outputs.birthday" value="1990-01-05" min="1912-01-01" max="2024-01-01">
|
||||
</div>
|
||||
<div class="inputBox">
|
||||
<p>{{i18n("login.guest.password")}}</p>
|
||||
@ -169,7 +163,7 @@
|
||||
</div>
|
||||
|
||||
<div class="switchpage">
|
||||
<button @click="verifyInputs(outputs.password);">{{i18n("login.guest.nextpage")}}</button>
|
||||
<button @click="verifyInputs(outputs.password);idcardfile={};justifcardfile={}">{{i18n("login.guest.nextpage")}}</button>
|
||||
|
||||
</div>
|
||||
<div @click="(loginPage=!loginPage) && (page=0)" class="register">
|
||||
@ -192,14 +186,7 @@
|
||||
<form class="inputBox" novalidate enctype="multipart/form-data">
|
||||
<p>{{i18n("profile.picture").toUpperCase()}}</p>
|
||||
</form>
|
||||
<label class="browser">
|
||||
Parcourir . . .
|
||||
<input type="file" :disabled="imageSaved" @change="ppData = uploadProfilePicture($event.target.files); imageSaved = true;" accept="image/*">
|
||||
</label>
|
||||
<form novalidate enctype="multipart/form-data" class="inputBox">
|
||||
<p>{{i18n("profile.picture").toUpperCase()}}</p>
|
||||
<input type="file" @change="uploadPP($event.target.files); imageSaved = true;" accept="image/*">
|
||||
</form>
|
||||
<input style="color:rgb(239,60,168);" type="file" name="picture" @change="ppData = $event.target.files;imageSaved=true" accept="image/*">
|
||||
<div class="inputBox">
|
||||
<p>{{i18n("Curriculum").toUpperCase()}}</p>
|
||||
<select v-model="outputs.curriculum">
|
||||
@ -207,8 +194,7 @@
|
||||
</select>
|
||||
</div>
|
||||
<p style="color:rgb(239,60,168);">
|
||||
Si vous êtes déja inscrits dans cette université veuillez vous connecter a votre compte et utilisez les fonctions
|
||||
changer de cursus/réinscription sinon continuez ici.
|
||||
{{i18n("login.guest.disclaimer")}}
|
||||
</p>
|
||||
<div style="align-self:center;" class="inputBox">
|
||||
<button style="margin-top:25px;" @click="page++;">
|
||||
@ -223,39 +209,35 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="page === 2">
|
||||
<p style="color:rgb(239,60,168);">Carte d'indentité :</p>
|
||||
<label class="browser">
|
||||
Parcourir . . .
|
||||
<input type="file" @change="idcardfile = $event.target.files">
|
||||
</label>
|
||||
<p style="color:rgb(239,60,168);">{{i18n("login.guest.identityCard")}}</p>
|
||||
<input style="color:rgb(239,60,168);margin-bottom: 3%" type="file" @change="idcardfile = $event.target.files;allfileshere = Math.min(allfileshere+1, 2)">
|
||||
<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%">
|
||||
<p style="color:rgb(239,60,168);">Attestation:</p>
|
||||
<label class="browser">
|
||||
Parcourir . . .
|
||||
<input type="file" @change="justifcardfile = $event.target.files">
|
||||
</label>
|
||||
<input style=" color:rgb(239,60,168);" type="file" @change="justifcardfile = $event.target.files;allfileshere = Math.min(allfileshere+1, 2)">
|
||||
</div>
|
||||
</div>
|
||||
<button @click="page++;">{{i18n("login.guest.nextpage")}}</button>
|
||||
|
||||
<div v-if="everyfilehere()"><button @click="page++;" style="margin-top: 10%">{{i18n("login.guest.nextpage")}}</button></div>
|
||||
<div v-else style="color: rgb(239,60,168); margin-top: 5%; margin-bottom: 5%">Please upload all the required files</div>
|
||||
</div>
|
||||
<div v-if="page === 3">
|
||||
<p>
|
||||
Vous avez séléctionné un cursus qui possède des prérequis veuillez ajouter vos formations antérieures
|
||||
dans l'enseignement supérieur, votre dossier sera vérifié par un membre du service d'inscription.
|
||||
<p style="color:rgb(239,60,168);margin-bottom: 5%">
|
||||
{{i18n("login.guest.formationdisclaimer")}}
|
||||
</p>
|
||||
<button @click="page++">Gèrer mon parcours extérieur</button>
|
||||
<button @click="postRegisterReq();">Envoyer la demande d'inscription</button>
|
||||
<button @click="page++">{{i18n("login.guest.managecareer")}}</button>
|
||||
<button @click="postRegisterReq();page+=2">{{ i18n("login.guest.sendRegReq") }}</button>
|
||||
</div>
|
||||
<div v-if="page===5" style="margin-left: 7%">
|
||||
<p style="color: rgb(239,60,168);">{{i18n("reqsent")}}</p>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="page===4">
|
||||
<ExternalCurriculumList v-model="externalCurrTab" :mode="2"></ExternalCurriculumList>
|
||||
<button style="margin-top: 2%;width: 5%; margin-left: 2%" @click="page--">Back</button>
|
||||
<button style="margin-top: 2%;width: 5%; margin-left: 2%" @click="page--">{{i18n("courses.back")}}</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -306,8 +288,6 @@
|
||||
z-index: 100;
|
||||
font-family:sans-serif ;
|
||||
color:rgb(239,60,168);
|
||||
transition: 0.5;
|
||||
|
||||
}
|
||||
|
||||
.register{
|
||||
@ -318,13 +298,7 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.bodu {
|
||||
margin-top:2%;
|
||||
width:50%;
|
||||
border:2px solid black;
|
||||
border-radius:9px;
|
||||
background-color:rgb(50,50,50);
|
||||
}
|
||||
|
||||
|
||||
.switchpage{
|
||||
width:100px;
|
||||
@ -335,8 +309,6 @@
|
||||
outline:none;
|
||||
border-radius: 4px;
|
||||
font-size:0.8em;
|
||||
align-self: right;
|
||||
|
||||
}
|
||||
|
||||
input[type=submit],button,select{
|
||||
@ -350,9 +322,6 @@ input[type=submit],button,select{
|
||||
|
||||
}
|
||||
|
||||
input[type=file]{
|
||||
display:none;
|
||||
}
|
||||
|
||||
.browser{
|
||||
display:inline-block;
|
||||
@ -365,22 +334,8 @@ input[type=file]{
|
||||
background:#FFFFFF;
|
||||
}
|
||||
|
||||
.container{
|
||||
margin-top: 2%;
|
||||
color:white;
|
||||
height:60px;
|
||||
font-size:30px;
|
||||
display:grid;
|
||||
grid-template-columns:30% 30% 20% 20%;
|
||||
grid-template-areas:
|
||||
"school formation completion edit remove";
|
||||
column-gap:10px;
|
||||
}
|
||||
|
||||
button:active ,.switchpage:active{
|
||||
opacity:0.8;
|
||||
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
@ -3,26 +3,27 @@
|
||||
import {reactive , ref} from 'vue'
|
||||
import { getCourses,deleteCourse,alterCourse,createCourse } from "@/rest/courses.js"
|
||||
import {getUser, getSelf, getTeachers } from "@/rest/Users.js"
|
||||
import {addCourseToCurriculum, getAllCurriculums, getCurriculumsByCourse} from "@/rest/curriculum.js";
|
||||
|
||||
|
||||
const self = await getSelf();
|
||||
|
||||
const curriculum = ref(await getCourses(self.role));
|
||||
const profList = await getTeachers();
|
||||
|
||||
const allCurriculums = ref(await getAllCurriculums());
|
||||
const curriculumToAdd = ref();
|
||||
|
||||
const createMod = ref(false)
|
||||
const deleteMod = ref(false)
|
||||
|
||||
const editElementID = ref("")
|
||||
const editAddCourse = ref("");
|
||||
|
||||
function editItem(id){
|
||||
editElementID.value = id;
|
||||
}
|
||||
|
||||
//Juste pour montrer le Create Mode
|
||||
|
||||
const curriculumToAddId = ref()
|
||||
|
||||
const pattern = {
|
||||
"id":null,
|
||||
"title":null,
|
||||
"credits":null,
|
||||
"owner":null,
|
||||
@ -41,14 +42,40 @@
|
||||
|
||||
}
|
||||
if (!isnull){
|
||||
await createCourse(toAdd.title,toAdd.credits,toAdd.owner);
|
||||
await createCourse(toAdd.id,toAdd.title,toAdd.credits,toAdd.owner);
|
||||
|
||||
toAdd= Object.assign({},pattern);
|
||||
|
||||
curriculum.value = await getCourses(self.role);
|
||||
|
||||
|
||||
}}
|
||||
|
||||
async function setAddToCurriculum(item){
|
||||
let temp = [];
|
||||
let courseCurriculum = await getCurriculumsByCourse(item.courseID);
|
||||
let isIn = false;
|
||||
for (let element in allCurriculums.value){
|
||||
for (let item in courseCurriculum){
|
||||
if((courseCurriculum[item].option == allCurriculums.value[element].option) && (courseCurriculum[item].year == allCurriculums.value[element].year) ){
|
||||
isIn = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if(!isIn){
|
||||
temp.push(allCurriculums.value[element])
|
||||
}
|
||||
isIn = false;
|
||||
}
|
||||
curriculumToAdd.value = temp.slice();
|
||||
}
|
||||
|
||||
async function addToCurriculum(item){
|
||||
await addCourseToCurriculum(curriculumToAddId.value,item.courseID);
|
||||
curriculumToAddId.value = null;
|
||||
curriculumToAdd.value = null;
|
||||
allCurriculums.value = await getAllCurriculums();
|
||||
}
|
||||
function setModify(item){
|
||||
for(const el in profList){
|
||||
|
||||
@ -64,13 +91,13 @@
|
||||
async function patchCourse(course){
|
||||
for (let element in toModify){
|
||||
if (element =="owner" && (toModify[element].regNo != course.owner.regNo)){
|
||||
await alterCourse(course.courseId,{owner:toModify[element].regNo});
|
||||
await alterCourse(course.courseID,{owner:toModify[element].regNo});
|
||||
}
|
||||
else if(element == "title" && (toModify[element] != course.title)){
|
||||
await alterCourse(course.courseId,{title:toModify[element]});
|
||||
await alterCourse(course.courseID,{title:toModify[element]});
|
||||
}
|
||||
else if(element == "credits" && (parseInt(toModify[element]) != course.credits)){
|
||||
await alterCourse(course.courseId,{credits:parseInt(toModify[element])});
|
||||
await alterCourse(course.courseID,{credits:parseInt(toModify[element])});
|
||||
}
|
||||
}
|
||||
toModify= Object.assign({},pattern);
|
||||
@ -96,13 +123,18 @@
|
||||
<button class="create" @click="editElementID= '';createMod = true;">
|
||||
{{i18n("courses.createCourse")}}
|
||||
</button>
|
||||
<button class="delete" @click="deleteMod=true" >
|
||||
<button class="delete" @click="deleteMod=true">
|
||||
{{i18n("courses.deleteCourse")}}
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="createMod">
|
||||
<form class="listElement" style="width:40%;margin-right:auto;margin-left:auto;">
|
||||
|
||||
<div style="margin-bottom: 20px">
|
||||
{{i18n("Curriculum")}}
|
||||
<select v-model="toAdd.id">
|
||||
<option v-for="element in allCurriculums" :value="element.curriculumId">{{element.option}}-{{element.year}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
{{i18n("name")}} :
|
||||
<input v-model="toAdd.title">
|
||||
@ -136,24 +168,37 @@
|
||||
</div>
|
||||
|
||||
<div v-if="!createMod && !deleteMod" v-for="item in curriculum" :key="item.title" style="width:50%;margin-left:auto; margin-right:auto;">
|
||||
<div v-if="editElementID !== item.title" style ="padding:15px 15px 15px 15px;">
|
||||
<button @click="editElementID = item.title; setModify(item); ">
|
||||
{{i18n("courses.modify")}}
|
||||
</button>
|
||||
<div v-if="editElementID !== item.title && editAddCourse !== item.title" style="display:flex;">
|
||||
<button @click="editElementID = item.title; editAddCourse = ''; setModify(item);">{{i18n("courses.modify")}}</button>
|
||||
<button v-if="self.role !== 'Teacher'"@click="editAddCourse = item.title; editElementID ='';setAddToCurriculum(item)">{{i18n("courses.AddToCurriculum")}}</button>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-if="editElementID == item.title">
|
||||
<button @click="editElementID= '';patchCourse(item)"> {{i18n("courses.confirm")}} </button>
|
||||
<button @click="editElementID= '';"> {{i18n("courses.back")}} </button>
|
||||
</div>
|
||||
<div class="listElement" >
|
||||
<div v-if="editAddCourse == item.title">
|
||||
<button @click="editAddCourse= '';addToCurriculum(item)"> {{i18n("courses.confirm")}} </button>
|
||||
<button @click="editAddCourse= '';"> {{i18n("courses.back")}} </button>
|
||||
</div>
|
||||
<div class="listElement">
|
||||
|
||||
<div class="containerElement" v-if="editElementID !== item.title" >
|
||||
<div class="containerElement" v-if="editElementID !== item.title && editAddCourse !== item.title" >
|
||||
|
||||
<div class="name"> {{item.title}} </div>
|
||||
<div class="teacher">{{item.owner.lastName}}</div>
|
||||
<div class="credits">{{i18n("Credits")}}:{{item.credits}}</div>
|
||||
</div>
|
||||
<div class="containerElement"v-else>
|
||||
|
||||
<div class="containerElement" v-if="editAddCourse == item.title" >
|
||||
{{i18n("Curriculum")}}:
|
||||
<select v-model="curriculumToAddId">
|
||||
<option v-for="element in curriculumToAdd" :value="element.curriculumId">
|
||||
{{element.option}}-{{element.year}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="containerElement" v-if="editElementID == item.title">
|
||||
|
||||
<input style="max-width:200px;" class="name" v-model="toModify.title">
|
||||
<select v-if="self.role != 'Secretary'" style="max-width:200px;" class="teacher" v-model="toModify.owner">
|
||||
<option v-for="(item,index) in profList" :value='item'>{{item.lastName}}</option>
|
||||
@ -162,6 +207,8 @@
|
||||
<input v-if="self.role !='Secretary'"style="max-width:100px;"class="credits" v-model="toModify.credits">
|
||||
<div v-else class="credits">{{i18n("Credits")}}:{{item.credits}}</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,7 +1,14 @@
|
||||
<!----------------------------------------------------
|
||||
File: LessonRequests.vue
|
||||
Author: William Karpinski
|
||||
Scope: Extension Horaire
|
||||
Description: Lessons Management Page for the teachers
|
||||
----------------------------------------------------->
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
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 {getSelf} from "@/rest/Users.js";
|
||||
import {createRequest} from "@/rest/LessonRequests.js"
|
||||
@ -21,6 +28,14 @@ const currentDate = new Date();
|
||||
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 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){
|
||||
let toCompare = new Date(lesson.lessonStart);
|
||||
let current = new Date();
|
||||
@ -31,28 +46,6 @@ function inFuture(lesson){
|
||||
async function setCourses(){
|
||||
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 = {
|
||||
"lessonId":null,
|
||||
@ -62,8 +55,6 @@ const pattern = {
|
||||
"lessonEnd": null,
|
||||
"lessonType": null,
|
||||
}
|
||||
|
||||
|
||||
const patternRequest ={
|
||||
"user": user.regNo,
|
||||
"state": "Pending",
|
||||
@ -91,6 +82,9 @@ function setCreate(){
|
||||
createMod.value = !createMod.value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Constructs a request and posts it
|
||||
*/
|
||||
async function createLessonRequest(){
|
||||
if(requestType.value === 0 || requestType.value === 1){
|
||||
//modify
|
||||
@ -121,7 +115,12 @@ async function createLessonRequest(){
|
||||
editElementID.value = '';
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Creates a request of a certain type
|
||||
* 0 = CREATE REQUEST
|
||||
* 1 = MODIFY REQUEST
|
||||
* 2 = DELETE REQUEST
|
||||
*/
|
||||
async function askChanges(i){
|
||||
requestType.value= i;
|
||||
await createLessonRequest()
|
||||
@ -135,33 +134,33 @@ async function askChanges(i){
|
||||
<div v-if="createMod">
|
||||
<form class="listElement" style="width:40%; margin:0 auto 0 auto;">
|
||||
<div style="margin-bottom:20px;">
|
||||
Schedule :
|
||||
{{i18n("schedule")}} :
|
||||
<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>
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
Lesson :
|
||||
{{i18n("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>
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
Day:
|
||||
{{i18n("day")}}:
|
||||
<input type="date" :min="minDate" :max="maxDate" v-model="toModify.day">
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
Start:
|
||||
{{i18n("start")}}:
|
||||
<input v-model="toModify.lessonStart" type="time" min="08:00" max="18:00" required />
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
End:
|
||||
{{i18n("end")}}:
|
||||
<input v-model="toModify.lessonEnd" type="time" min="10:00" max="20:00" required />
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
Type:
|
||||
<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>
|
||||
</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="editElementID !== element.lessonID" style ="padding:15px 15px 15px 15px;">
|
||||
<button v-if="inFuture(element)" @click="editElementID = element.lessonID;setModify(element);">
|
||||
Ask Changes
|
||||
{{i18n("schedule.askChanges")}}
|
||||
</button>
|
||||
</div>
|
||||
<div v-else>
|
||||
@ -194,34 +193,34 @@ async function askChanges(i){
|
||||
<div>{{getHoursMinutes(element.lessonStart)}}-{{getHoursMinutes(element.lessonEnd)}}
|
||||
</div>
|
||||
<div>{{element.local}}</div>
|
||||
<div>{{element.lessonType}}</div>
|
||||
<div>{{i18n(element.lessonType)}}</div>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<div>{{element.course.title}}</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
Day:
|
||||
{{i18n("day")}}:
|
||||
<input type="date" :min="minDate" :max="maxDate" v-model="toModify.day">
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
Start:
|
||||
{{i18n("start")}}:
|
||||
<input v-model="toModify.lessonStart" type="time" min="8:00" max="20:00"/>
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
End:
|
||||
{{i18n("end")}}:
|
||||
<input v-model="toModify.lessonEnd" type="time" min="10:00" max="20:00" required />
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
Type:
|
||||
{{i18n("Type")}}:
|
||||
<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>
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
Local:
|
||||
{{element.local}}
|
||||
<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>
|
||||
@ -260,7 +259,7 @@ input, select{
|
||||
}
|
||||
button{
|
||||
font-size:15px;
|
||||
height:50px;
|
||||
height:auto;
|
||||
width:100px;
|
||||
border:none;
|
||||
border-radius:20px;
|
||||
|
@ -1,11 +1,20 @@
|
||||
|
||||
<!----------------------------------------------------
|
||||
File: LessonRequests.vue
|
||||
Author: William Karpinski
|
||||
Scope: Extension Horaire
|
||||
Description: Lessons Management Page for the secretary
|
||||
----------------------------------------------------->
|
||||
|
||||
<script setup>
|
||||
|
||||
import { ref } from 'vue'
|
||||
import i18n from '@/i18n.js'
|
||||
import {formatDate,getHoursMinutes} from '../scheduleFunctions.js'
|
||||
import {getAllSchedule, deleteLessonFromSchedule ,getSchedule, getCurriculumSchedule,addLessonToSchedule} from "@/rest/scheduleRest.js";
|
||||
import {getLessons , createLesson, alterLesson , deleteLesson} from "@/rest/lessonSchedule.js"
|
||||
import {getTeachers} from "@/rest/Users.js"
|
||||
import { getcurriculum} from "@/rest/curriculum.js"
|
||||
import {formatDate,getHoursMinutes, invertedFormatDate, createLessonEvent} from '../scheduleFunctions.js'
|
||||
import {getAllSchedule, deleteLessonFromSchedule ,getSchedule, createSchedule} from "@/rest/scheduleRest.js";
|
||||
import {getLessons, createLesson, alterLesson, deleteLesson} from "@/rest/lessonSchedule.js"
|
||||
import {getTeachers} from "@/rest/Users.js"
|
||||
import {getcurriculum, getAllCurriculums} from "@/rest/curriculum.js"
|
||||
|
||||
const trueSchedule = ref()
|
||||
const schedule = ref();
|
||||
@ -18,41 +27,22 @@ import i18n from '@/i18n.js'
|
||||
const types = ["TP","TD","Course","Exam"];
|
||||
const locals = ["A0B1","A1B1","A2B1","A0B2"]
|
||||
const teachers = await getTeachers() ;
|
||||
const allCurriculum = ref();
|
||||
const courses = ref();
|
||||
|
||||
|
||||
const createScheduleMod = ref(false);
|
||||
const createMod = 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 currentDate = new Date();
|
||||
|
||||
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 editElementID = 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)))
|
||||
|
||||
function createLessonEvent(date,hour){
|
||||
const str = date.concat(' ',hour);
|
||||
return new Date(str);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const pattern = {
|
||||
"course": null,
|
||||
@ -65,7 +55,7 @@ function createLessonEvent(date,hour){
|
||||
}
|
||||
|
||||
const lessonCreator = {
|
||||
"courseId" : null,
|
||||
"courseID" : null,
|
||||
"lessonStart":null,
|
||||
"lessonEnd":null,
|
||||
"lessonType":null,
|
||||
@ -80,7 +70,34 @@ function createLessonEvent(date,hour){
|
||||
"local":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 lessonBuffer = ref(Object.assign({}, pattern));
|
||||
const lessonCreatorBuffer = ref(Object.assign({},lessonCreator));
|
||||
@ -104,6 +121,9 @@ async function setCourses(){
|
||||
courses.value = (await getcurriculum(curriculum.value.curriculumId)).courses
|
||||
}
|
||||
|
||||
/*
|
||||
* Sort the lessons via a criteria
|
||||
*/
|
||||
function sortSchedule(){
|
||||
schedule.value =trueSchedule.value.lessons;
|
||||
if(filter.value =="Teacher"){
|
||||
@ -137,7 +157,7 @@ async function setCourses(){
|
||||
}
|
||||
const matrix = [];
|
||||
for (let element in lessons){
|
||||
if(lessons[element].course.courseId == course.courseId){
|
||||
if(lessons[element].course.courseID == course.courseID){
|
||||
matrix.push(lessons[element])
|
||||
}
|
||||
}
|
||||
@ -157,7 +177,9 @@ async function setCourses(){
|
||||
return matrix
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Change the schedule filter
|
||||
*/
|
||||
async function changeSchedule(){
|
||||
schedule.value =trueSchedule.value.lessons;
|
||||
curriculum.value = trueSchedule.value.curriculum;
|
||||
@ -188,7 +210,7 @@ async function setCourses(){
|
||||
lessonCreatorBuffer.value.color = lessonBuffer.value.color;
|
||||
lessonCreatorBuffer.value.lessonType =lessonBuffer.value.lessonType;
|
||||
lessonCreatorBuffer.value.local = lessonBuffer.value.local;
|
||||
lessonCreatorBuffer.value.courseId = lessonBuffer.value.course.courseId;
|
||||
lessonCreatorBuffer.value.courseID = lessonBuffer.value.course.courseID;
|
||||
|
||||
await createLesson(lessonCreatorBuffer.value);
|
||||
|
||||
@ -199,10 +221,16 @@ async function setCourses(){
|
||||
lessonBuffer.value = Object.assign({}, pattern);
|
||||
lessonFinder.value = null;
|
||||
lessonCreatorBuffer.value = Object.assign({},lessonCreator)
|
||||
allSchedules.value = await getAllSchedule();
|
||||
schedule.value = null;
|
||||
trueSchedule.value = null;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Modify a lesson
|
||||
*/
|
||||
|
||||
async function patchLesson(lesson){
|
||||
|
||||
for (let element in toModify.value){
|
||||
@ -246,44 +274,53 @@ async function patchLesson(lesson){
|
||||
editElementID.value= '';
|
||||
|
||||
}
|
||||
/*
|
||||
* Create a new Schedule
|
||||
*/
|
||||
async function newSchedule(){
|
||||
await createSchedule(curriculum.value);
|
||||
allSchedules.value = await getAllSchedule();
|
||||
setCurriculum();
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<div class="body">
|
||||
<div class="listTitle buttonGrid"v-if="!createMod" >
|
||||
<button class="create" @click="createMod = true;">Create</button>
|
||||
<button class="delete" @click="deleteMod = !deleteMod;">{{!deleteMod ? "Delete" : "Remove Delete"}}</button>
|
||||
<div class="listTitle buttonGrid"v-if="!createMod && !createScheduleMod" >
|
||||
<button class="create" @click="setCurriculum();createScheduleMod = true"> {{i18n("schedule.createSchedule")}}</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 v-if="createMod">
|
||||
<form class="listElement" style="width:40%; margin:0 auto 0 auto;">
|
||||
<div style="margin-bottom:20px;">
|
||||
Schedule :
|
||||
{{i18n("schedule")}} :
|
||||
<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>
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
Lesson :
|
||||
{{i18n("Course")}} :
|
||||
<select v-if="curriculum != null" v-model="lessonBuffer.course">
|
||||
<option v-for="item in courses" :value='item'>{{item.title}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
Day:
|
||||
{{i18n("day")}}:
|
||||
<input type="date" :min="minDate" :max="maxDate" v-model="lessonBuffer.day">
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
Start:
|
||||
{{i18n("start")}}:
|
||||
<input v-model="lessonBuffer.lessonStart" type="time" min="08:00" max="18:00" required />
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
End:
|
||||
{{i18n("end")}}:
|
||||
<input v-model="lessonBuffer.lessonEnd" type="time" min="10:00" max="20:00" required />
|
||||
</div>
|
||||
<div style="margin-bottom:20px;">
|
||||
Type:
|
||||
Type:
|
||||
<select v-model="lessonBuffer.lessonType">
|
||||
<option v-for="item in types" :value='item'>{{item}}</option>
|
||||
</select>
|
||||
@ -293,27 +330,35 @@ async function patchLesson(lesson){
|
||||
<select v-model="lessonBuffer.local">
|
||||
<option v-for="item in locals" :value='item'>{{item}}</option>
|
||||
</select>
|
||||
|
||||
|
||||
</div>
|
||||
<div></div>
|
||||
|
||||
|
||||
|
||||
<button class="create" @click="createMod=!createMod; newLesson();"> {{i18n("courses.confirm")}} </button>
|
||||
<button style="float:right;" @click="createMod=!createMod">{{i18n("courses.back")}}</button>
|
||||
</form>
|
||||
</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">
|
||||
<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 v-if="schedule != null" @change="subFilter = 'null'" v-model="filter">
|
||||
<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 @change="sortSchedule()" v-if="filter == 'Teacher'" v-model="subFilter">
|
||||
<option :value ="null">No Filter</option>
|
||||
@ -329,7 +374,7 @@ async function patchLesson(lesson){
|
||||
</select>
|
||||
|
||||
</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;">
|
||||
<button v-if="inFuture(element)" @click="editElementID = element.lessonID;setModify(element);">
|
||||
{{i18n("courses.modify")}}
|
||||
@ -385,8 +430,6 @@ async function patchLesson(lesson){
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</template>
|
||||
<style scoped>
|
||||
.body {
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script setup>
|
||||
import {reactive, ref } from 'vue'
|
||||
import {getSelf,alterSelf,disconnect,deleteUser} from '../rest/Users.js'
|
||||
import {getSelfCurriculum, getAllCurriculums, getSomeonesCurriculumList, getcurriculum} from '../rest/curriculum.js'
|
||||
import {getSelf,alterSelf} from '../rest/Users.js'
|
||||
import {getAllCurriculums, getSomeonesCurriculumList, getcurriculum} from '../rest/curriculum.js'
|
||||
import {getCourses} from "../rest/courses.js"
|
||||
import i18n from "@/i18n.js"
|
||||
import {uploadFile, uploadProfilePicture} from '@/rest/uploads.js'
|
||||
@ -93,12 +93,14 @@
|
||||
|
||||
async function ChangeInfos(){
|
||||
for (let element in toModify){
|
||||
console.log(element)
|
||||
console.log(toModify[element])
|
||||
if (element ==="email" && (toModify[element] !== null)){
|
||||
await alterSelf(user.value.regNo,{email : toModify[element]});
|
||||
}
|
||||
|
||||
if (element ==="profilPictureUrl" && (toModify[element] !== null)){
|
||||
await alterSelf(user.value.regNo,{ profilPictureUrl : toModify[element]});
|
||||
if (element ==="profilePictureUrl" && (toModify[element] !== null)){
|
||||
await alterSelf(user.value.regNo,{ profilePictureUrl : toModify[element]});
|
||||
}
|
||||
else if(element === "address" && (toModify[element] !== null)){
|
||||
await alterSelf(user.value.regNo,{address : toModify[element]});
|
||||
@ -116,32 +118,14 @@
|
||||
toModify.address = item.address;
|
||||
toModify.profilPictureUrl = item.profilPictureUrl;
|
||||
toModify.email= item.email;
|
||||
toModify.password= item.password;
|
||||
}
|
||||
|
||||
|
||||
async function unRegister(){
|
||||
deleteUser(user.value.regNo);
|
||||
disconnect()
|
||||
setTimeout(() => {
|
||||
window.location.href="#/home";
|
||||
}, "500");
|
||||
|
||||
toModify.password= item.password
|
||||
}
|
||||
|
||||
function getPP(){
|
||||
if(user.value.profilePictureUrl === null){
|
||||
return "/Clyde.png"
|
||||
}
|
||||
return user.profilePictureUrl
|
||||
}
|
||||
|
||||
function getYear(){
|
||||
let date = new Date();
|
||||
if (date.getMonth() <= 6){
|
||||
return date.getFullYear()-1
|
||||
}
|
||||
return date.getFullYear()
|
||||
return user.value.profilePictureUrl
|
||||
}
|
||||
|
||||
async function refreshExtCurrList(){
|
||||
@ -194,11 +178,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function getProfilePic(data){
|
||||
const pp= await uploadProfilePicture(data)
|
||||
toModify.profilePictureUrl = pp.url
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="body" v-if="windowState !== 12">
|
||||
<div class="container" v-if="windowState!==4">
|
||||
<div class="body" v-if="windowState !== 12 && windowState!==4">
|
||||
<div class="container">
|
||||
<div class="profilPic" v-if="windowState===0">
|
||||
<img class="subContainter" :src=getPP()>
|
||||
</div>
|
||||
@ -208,93 +199,100 @@
|
||||
{{user.firstName}} {{user.lastName}}
|
||||
</div>
|
||||
<div>
|
||||
E-mail: {{user.email}}
|
||||
{{ i18n("login.guest.email") }}: {{user.email}}
|
||||
</div>
|
||||
<div v-if="user.role==='Student'">
|
||||
{{user.option}} {{i18n(user.role)}}
|
||||
<div>
|
||||
{{ i18n("regNo") }} : {{user.regNo}}
|
||||
</div>
|
||||
<div v-else>
|
||||
Role: {{i18n((user.role))}}
|
||||
<div>
|
||||
{{ i18n("role") }}: {{i18n((user.role))}}
|
||||
</div>
|
||||
<div>
|
||||
<button @click="windowState=1; setModify(user)"> {{i18n("profile.modify.data")}} </button>
|
||||
</div>
|
||||
<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>
|
||||
</div>
|
||||
<div v-if="(user.role==='Student')">
|
||||
<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 v-if="(user.role==='Student')">
|
||||
<button @click="windowState=4">Manage Courses</button>
|
||||
<button @click="windowState=5" style="margin-left: 2%">Manage minerval</button>
|
||||
<button @click="windowState=4">{{ i18n("managecourse") }}</button>
|
||||
<button @click="windowState=5" style="margin-left: 2%">{{ i18n("manageminerval") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="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>
|
||||
<div v-if="sure !== 2">
|
||||
I only want to unregister from a specific cursus
|
||||
{{i18n("onlycursus")}}
|
||||
<input type="checkbox" v-model="isChecked">
|
||||
</div>
|
||||
<div v-if="sure !== 2 && isChecked">
|
||||
Please select that cursus
|
||||
{{ i18n("plsselectcurs") }}
|
||||
<select v-model="uninscriptionData.curriculumId">
|
||||
<option v-for="item in getActualCurriculumList()" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div v-if="sure !== 2">
|
||||
<button @click="sure++">Submit</button>
|
||||
<button @click="sure++">{{ i18n("login.guest.submit") }}</button>
|
||||
</div>
|
||||
<div v-if="sure==1">
|
||||
Are you sure that you want to unregister ?
|
||||
<button @click="addUninscReq(uninscriptionData.userId, uninscriptionData.reason, uninscriptionData.curriculumId);sure++">Yes</button>
|
||||
<button @click="sure=0">No</button>
|
||||
{{ i18n("sureunreg") }}
|
||||
<button @click="addUninscReq(uninscriptionData.userId, uninscriptionData.reason, uninscriptionData.curriculumId);sure++">{{i18n("yes")}}</button>
|
||||
<button @click="sure=0">{{ i18n("no") }}</button>
|
||||
</div>
|
||||
<p v-if="sure==2">You request has been send !</p>
|
||||
<p v-if="sure==2">{{ i18n("reqsend") }}</p>
|
||||
</div>
|
||||
<div v-if="windowState === 9">
|
||||
<button @click="windowState=0">{{i18n("courses.back")}}</button>
|
||||
</div>
|
||||
<div v-else-if="windowState === 5" class="infosContainer">
|
||||
<div v-if="minerv.value.toPay !== 0">
|
||||
Payment : {{minerv.value.toPay}}€ left to pay
|
||||
<div v-if="minerv.value.toPay > 0">
|
||||
{{ i18n("payment") }} : {{minerv.value.toPay}}€ {{ i18n("lefttopay") }}
|
||||
<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>
|
||||
<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 v-else>
|
||||
Payment : School fees have already been paid this year
|
||||
{{ i18n("alreadypaid") }}
|
||||
</div>
|
||||
<div>
|
||||
<button @click="windowState=7">Ask for a scholarship</button>
|
||||
<button @click="windowState=7" v-if="minerv.value.toPay >= 0">{{ i18n("askscholarship") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="windowState === 5">
|
||||
<button @click="windowState=0">{{ i18n("courses.back") }}</button>
|
||||
</div>
|
||||
<div v-else-if="windowState === 7" class="infosContainer">
|
||||
<p>Please upload the required documents</p>
|
||||
<p>{{i18n("uploaddocs")}}</p>
|
||||
<div>
|
||||
Tax justification document :
|
||||
{{ i18n("taxjustdoc") }}
|
||||
<input type="file" @change="scholarshipData.taxDocUrl = $event.target.files">
|
||||
</div>
|
||||
<div>
|
||||
Residency justification document :
|
||||
{{i18n("residencydoc")}}
|
||||
<input type="file" style="margin-top:2%" @change="scholarshipData.residencyDocUrl = $event.target.files">
|
||||
</div>
|
||||
<button style="margin-top: 5%" @click="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 v-else-if="windowState === 8" class="infosContainer">
|
||||
<div>
|
||||
Your request has been sent to the inscription service you will get notified when
|
||||
the request is reviewed.
|
||||
{{i18n("reqsent")}}
|
||||
</div>
|
||||
<button @click="windowState = 0">
|
||||
Go back to profile
|
||||
{{ i18n("backprofile") }}
|
||||
</button>
|
||||
</div>
|
||||
<div v-else-if="windowState === 6" class="infosContainer">
|
||||
Proceed to payment of {{paymentAmount}}€
|
||||
{{ i18n("procpayment") }} {{paymentAmount}}€
|
||||
<div style="margin-top: 1%">
|
||||
Client:
|
||||
<input type="text" v-model="paymentData.client">
|
||||
@ -308,19 +306,19 @@
|
||||
<input type="date" v-model="paymentData.expDate">
|
||||
</div>
|
||||
<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>
|
||||
<button @click="windowState = 5">Back</button>
|
||||
<button @click="windowState = 5">{{ i18n("courses.back") }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="windowState === 1" class="infosContainer">
|
||||
<div>
|
||||
{{i18n("profile.picture")}}:
|
||||
<input type="file" @change="user.profilPicture = uploadProfilePicture($event.target.files);" accept="image/*">
|
||||
<input type="file" @change="getProfilePic($event.target.files)" accept="image/*">
|
||||
</div>
|
||||
<div>
|
||||
E-mail:
|
||||
{{ i18n("login.guest.email")}}
|
||||
<input type="email" v-model="toModify.email" />
|
||||
</div>
|
||||
<div>
|
||||
@ -342,11 +340,11 @@
|
||||
</div>
|
||||
<div v-else-if="windowState === 2" class="infosContainer">
|
||||
<div>
|
||||
I would like to :
|
||||
{{ i18n("iwouldlike") }}
|
||||
<select v-model="reRegState">
|
||||
<option :value="1">Reregister in the next year of one of my cursus</option>
|
||||
<option :value="2">Register for a supplementary cursus</option>
|
||||
<option :value="3">Change from a cursus to another</option>
|
||||
<option :value="1">{{ i18n("rereg") }}</option>
|
||||
<option :value="2">{{ i18n("reregsup") }}</option>
|
||||
<option :value="3">{{ i18n("chcur") }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="height:40px;" v-if="reRegState === 3">
|
||||
@ -354,90 +352,66 @@
|
||||
<select v-model="changecurrdata.actualcursus" style="margin-right: 3%">
|
||||
<option v-for="item in getActualCurriculumList()" style="font-size:20px;" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
|
||||
</select>
|
||||
New Curriculum :
|
||||
{{ i18n("newcursus") }} :
|
||||
<select v-model="changecurrdata.newcursus">
|
||||
<option v-for="item in curricula" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="height:40px;" v-if="reRegState === 2">
|
||||
New Curriculum :
|
||||
{{ i18n("newcursus") }} :
|
||||
<select v-model="changecurrdata.newcursus">
|
||||
<option v-for="item in curricula" :value="item.curriculumId">Bac {{item.year}} {{item.option}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div style="height:40px;" v-if="reRegState === 1">
|
||||
New Curriculum :
|
||||
{{ i18n("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>
|
||||
</select>
|
||||
</div>
|
||||
<div v-if="curricula[changecurrdata.newcursus-1].year > 1 && reRegState !== 1">
|
||||
The cursus you selected has some prerequisites
|
||||
{{i18n("cursusprereq")}}
|
||||
</div>
|
||||
<div>
|
||||
<button @click=" windowState = 0;postChangeCurrReq(changecurrdata);changecurrdata.actualcursus=null;changecurrdata.newcursus=1">{{i18n("courses.confirm")}}</button>
|
||||
<button @click="windowState = 0; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div 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 v-if="windowState === 0" class="moreInfos">
|
||||
<div v-if="windowState === 0 && user.role==='Student'" class="moreInfos">
|
||||
<div class = "oldcursus">
|
||||
<div class="listTitle">
|
||||
Anciens Cursus
|
||||
{{ i18n("oldcursus") }}
|
||||
</div>
|
||||
<div class="listElement">
|
||||
<div class=" containerElement" v-for="item in UserCurriculum.curriculumList">
|
||||
<div class="year" v-if="item.actual === false">Bac {{item.year}}</div>
|
||||
<div class="option" v-if="item.actual === false">{{item.option}}</div>
|
||||
<div class="dateyear" v-if="item.actual === false">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 class="actualcursus">
|
||||
<div class="listTitle">
|
||||
Cursus Actuel
|
||||
{{ i18n("newcurr") }}
|
||||
</div>
|
||||
<div class="listElement">
|
||||
<div class=" containerElement" v-for="item in UserCurriculum.curriculumList" >
|
||||
<div class="year" v-if="item.actual === true">Bac {{item.year}}</div>
|
||||
<div class="option" v-if="item.actual === true">{{item.option}}</div>
|
||||
<div class="dateyear" v-if="item.actual === true">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 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 v-if="windowState===4" style="width: 80%; margin-top: 3%; margin-left: 10%">
|
||||
<CourseList :cursuslist="getActualCurriculumList()" v-model:window-state="windowState"/>
|
||||
</div>
|
||||
<div v-if="windowState === 12">
|
||||
<ExternalCurriculumList :ext-curr-list="extcurrlist" :mode="1"></ExternalCurriculumList>
|
||||
<button @click="windowState = 0;refreshExtCurrList()">Back to profile</button>
|
||||
<button @click="windowState = 0;refreshExtCurrList()" style="margin-left: 17%;margin-top: 3%">{{ i18n("backprofile") }}</button>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
@ -548,7 +522,6 @@ button{
|
||||
border-radius:10px;
|
||||
height:35px;
|
||||
margin-top:10px;
|
||||
|
||||
}
|
||||
|
||||
button:hover{
|
||||
|
@ -1,9 +1,20 @@
|
||||
|
||||
<!----------------------------------------------------
|
||||
File: Schedule.vue
|
||||
Author: William Karpinski
|
||||
Scope: Extension Horaire
|
||||
Description: Schedules Page accessed by everyone
|
||||
----------------------------------------------------->
|
||||
|
||||
<script setup>
|
||||
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} from '../scheduleFunctions.js'
|
||||
import {getAllSchedule} from "@/rest/scheduleRest.js";
|
||||
import {getOnesLessons, getOwnedLessons } from "@/rest/lessonSchedule.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 log = await isLogged();
|
||||
@ -31,44 +42,40 @@
|
||||
|
||||
if(log){
|
||||
user = await getSelf();
|
||||
if(user.role == "Admin" || user.role == "Secretary" || user.role == "InscriptionService"){
|
||||
}
|
||||
|
||||
else{
|
||||
if(user.role == "Teacher" || user.role == "Student"){
|
||||
|
||||
if(user.role == "Teacher"){
|
||||
ownSchedule.value = await getOwnedLessons();
|
||||
}
|
||||
|
||||
if(user.role == "Student"){
|
||||
let test = await getUserActualCourses();
|
||||
console.log(test);
|
||||
ownSchedule.value = await getOnesLessons();}
|
||||
|
||||
schedule.value = ownSchedule.value;
|
||||
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
const display =ref("Week");
|
||||
const format = ref("Grid");
|
||||
|
||||
const filters = ["Type","Teacher","Course"];
|
||||
const types = ["TP","TD","Course","Exam"];
|
||||
const teachers = await getTeachers() ;
|
||||
const courses = ref();
|
||||
|
||||
|
||||
if(curriculum.value != null){
|
||||
courses.value = curriculum.value.courses;
|
||||
}
|
||||
const days = ["Lundi","Mardi","Mercredi","Jeudi","Vendredi","Samedi","Dimanche"];
|
||||
const months = ["Janvier","Fevrier","Mars","Avril",'Mai',"Juin","Juillet","Aout","Septembre","Octobre","Novembre","Decembre"]
|
||||
const firstDayOfMonth = ref(getFirstDay(new Date()))
|
||||
const monthDone = ref(false);
|
||||
const days = ["monday","tuesday","wednesday","thursday","friday","saturday","sunday"];
|
||||
const months = ["january","february","march","april",'may',"june","july","august","september","october","november","december"]
|
||||
function getMonday(d) {
|
||||
d = new Date(d);
|
||||
d.setHours(0,0,0);
|
||||
@ -89,19 +96,9 @@
|
||||
return (user.role == "Student" || user.role == "Teacher");
|
||||
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(){
|
||||
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());
|
||||
value = 1;
|
||||
counter=0;
|
||||
@ -109,6 +106,9 @@
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a JSON from a schedule
|
||||
*/
|
||||
function createJSON(){
|
||||
const json = {"data":[]};
|
||||
for(let element in schedule.value){
|
||||
@ -122,6 +122,10 @@
|
||||
return json
|
||||
}
|
||||
|
||||
/*
|
||||
* Export a JSON
|
||||
*/
|
||||
|
||||
function exportJSON(){
|
||||
let json = createJSON();
|
||||
const data = JSON.stringify(json);
|
||||
@ -132,6 +136,10 @@
|
||||
a.click();
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Used to convert a JSON imported to an object
|
||||
*/
|
||||
function onFileChange(e) {
|
||||
let files = e.target.files || e.dataTransfer.files;
|
||||
if (!files.length) return;
|
||||
@ -162,33 +170,40 @@
|
||||
toEventList.push(temp);
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
/*
|
||||
* Display the JSON on the schedule
|
||||
*/
|
||||
function switchToJSON(){
|
||||
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());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* used to focus on a lesson when we click on it
|
||||
*/
|
||||
function lessonFocus(element){
|
||||
if(!jsonMod.value){
|
||||
focus.value = element;
|
||||
var lessonsList = [];
|
||||
for (let element in schedule.value){
|
||||
if (schedule.value[element].course.courseId == focus.value.course.courseId){
|
||||
if (schedule.value[element].course.courseID == focus.value.course.courseID){
|
||||
lessonsList.push(schedule.value[element]);
|
||||
}
|
||||
}
|
||||
focusLessons.value = lessonsList;}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* convert the current date to a DATE object
|
||||
*/
|
||||
function dateOfMonth(i){
|
||||
|
||||
return new Date(currentDate.value.getFullYear(),currentDate.value.getMonth(),i);
|
||||
@ -198,7 +213,7 @@
|
||||
schedule.value =trueSchedule.value.lessons;
|
||||
if(filter.value =="Teacher"){
|
||||
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());
|
||||
value = 1;
|
||||
counter=0;
|
||||
@ -207,7 +222,7 @@
|
||||
}
|
||||
else if(filter.value =="Type"){
|
||||
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());
|
||||
value = 1;
|
||||
counter=0;
|
||||
@ -217,7 +232,7 @@
|
||||
}
|
||||
else if(filter.value =="Course"){
|
||||
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());
|
||||
value = 1;
|
||||
counter=0;
|
||||
@ -250,7 +265,7 @@
|
||||
}
|
||||
const matrix = [];
|
||||
for (let element in lessons){
|
||||
if(lessons[element].course.courseId == course.courseId){
|
||||
if(lessons[element].course.courseID == course.courseID){
|
||||
matrix.push(lessons[element])
|
||||
}
|
||||
}
|
||||
@ -270,12 +285,14 @@
|
||||
return matrix
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Change the schedule filter
|
||||
*/
|
||||
async function changeSchedule(){
|
||||
schedule.value =trueSchedule.value.lessons;
|
||||
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());
|
||||
value = 1;
|
||||
counter=0;
|
||||
@ -287,18 +304,23 @@
|
||||
focusLessons.value = null;
|
||||
jsonMod.value = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* change the week to display
|
||||
*/
|
||||
function changeWeek(i){
|
||||
const temp = getAnyDays(i);
|
||||
mondayOfWeek.value = temp;
|
||||
if(scheduleByWeek.value != null)
|
||||
if(jsonMod.value){
|
||||
scheduleByWeek.value = sundayToTheEnd(matrixFromList(jsonSchedule.value, mondayOfWeek.value))}
|
||||
scheduleByWeek.value = sundayToTheEnd(weekFromList(jsonSchedule.value, mondayOfWeek.value))}
|
||||
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){
|
||||
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);
|
||||
@ -316,6 +338,9 @@
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* used to display correctly the dates of a month
|
||||
*/
|
||||
|
||||
function isAValue(){
|
||||
if(value-shift.value<0 ){
|
||||
@ -352,15 +377,15 @@
|
||||
<table class="table">
|
||||
<tr style="background-color:rgb(24,24,24)">
|
||||
<th>
|
||||
<button @click="changeWeek(-7)">Previous</button>
|
||||
<button @click="changeWeek(7)">Next</button>
|
||||
<button @click="changeWeek(-7)">{{i18n("schedule.previous")}}</button>
|
||||
<button @click="changeWeek(7)">{{i18n("schedule.next")}}</button>
|
||||
<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 class="header" v-for='d,index in 7' >
|
||||
<p class="childHeader">
|
||||
{{days[index]}}
|
||||
{{i18n(days[index])}}
|
||||
</p>
|
||||
<p class="childHeader">
|
||||
{{formatDate(getAnyDays(index))}}
|
||||
@ -404,16 +429,16 @@
|
||||
<table class="table">
|
||||
<tr style="background-color:rgb(24,24,24); height:8.33%;">
|
||||
<th colspan="7" class="header">
|
||||
<div>{{months[currentDate.getMonth()]}} {{currentDate.getFullYear()}}</div>
|
||||
<button style="position:absolute; top:0; left:0;" @click="changeMonth(-1)">previous</button>
|
||||
<button style="position:absolute; bottom:0; left:0;"@click="changeMonth(1)">next</button>
|
||||
<div>{{i18n(months[currentDate.getMonth()])}} {{currentDate.getFullYear()}}</div>
|
||||
<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)">{{i18n("schedule.next")}}</button>
|
||||
|
||||
</th>
|
||||
|
||||
</tr>
|
||||
<tr style="background-color:rgb(24,24,24); height:8.33%;" >
|
||||
<th class="header" v-for='d,index in 7' >
|
||||
{{days[index]}}
|
||||
{{i18n(days[index])}}
|
||||
</th>
|
||||
</tr>
|
||||
<tr v-for="n in 5" style="height:16.67%;">
|
||||
@ -450,11 +475,11 @@
|
||||
<button @click="changeWeek(-7)">Previous</button>
|
||||
<button @click="changeWeek(7)">Next</button>
|
||||
<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">
|
||||
<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>
|
||||
<template v-if="scheduleByWeek != null">
|
||||
<div class="body" style="background-color:#353535;" >
|
||||
@ -476,10 +501,10 @@
|
||||
<div v-if="display == 'Month'">
|
||||
<button @click="changeMonth(-1)">Previous</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">
|
||||
<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>
|
||||
<template v-if="scheduleByWeek != null">
|
||||
<div class="body" style="background-color:#353535;" >
|
||||
@ -502,20 +527,20 @@
|
||||
|
||||
<div class="options">
|
||||
<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">
|
||||
<option v-for="item in allSchedules" :value='item'>{{item.curriculum.option}}-{{item.curriculum.year}}</option>
|
||||
</select>
|
||||
<button v-if="display=='Week'" @click="display='Month'">Week</button>
|
||||
<button v-if="display=='Month'" @click="display='Week'; value=1;">Month</button>
|
||||
<button v-if="format == 'Grid'" @click="format ='List'">Grid</button>
|
||||
<button v-if="format == 'List'" @click ="format = 'Grid'">List</button>
|
||||
<button v-if="verifUser()" @click="jsonMod=false ;displayOwnSchedule();">OwnSchedule</button>
|
||||
<button v-if="importedJSON != null" @click="switchToJSON()">Switch to JSON FILE</button>
|
||||
<button v-if="display=='Week'" @click="display='Month'">{{i18n("Week")}}</button>
|
||||
<button v-if="display=='Month'" @click="display='Week'; value=1;">{{i18n("Month")}}</button>
|
||||
<button v-if="format == 'Grid'" @click="format ='List'">{{i18n("Grid")}}</button>
|
||||
<button v-if="format == 'List'" @click ="format = 'Grid'">{{i18n("List")}}</button>
|
||||
<button v-if="verifUser()" @click="jsonMod=false ;displayOwnSchedule();">{{i18n("OwnSchedule")}}</button>
|
||||
<button v-if="importedJSON != null" @click="switchToJSON()">{{i18n("SwitchToJSON")}}</button>
|
||||
|
||||
<select v-if="schedule != null && !jsonMod" @change="subFilter = 'null'" v-model="filter">
|
||||
<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 @change="sortSchedule()" v-if="filter == 'Teacher'" v-model="subFilter">
|
||||
<option :value ="null">No Filter</option>
|
||||
@ -527,7 +552,7 @@
|
||||
</select>
|
||||
<select @change="sortSchedule()" v-if="filter == 'Type'" v-model="subFilter">
|
||||
<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>
|
||||
<button @click="exportJSON()" >Export JSON</button>
|
||||
|
||||
@ -537,22 +562,23 @@
|
||||
|
||||
</div>
|
||||
<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}">
|
||||
{{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>{{focus.course.owner.lastName}}</div>
|
||||
<div v-for="element in focus.course.owner.assistants">
|
||||
<div v-for="element in focus.course.assistants">
|
||||
{{element.lastName}}
|
||||
</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">
|
||||
{{formatDate(lesson.lessonStart)}}
|
||||
{{ getHoursMinutes(lesson.lessonStart)}}-{{getHoursMinutes(lesson.lessonEnd)}}
|
||||
{{ lesson.local}}
|
||||
{{lesson.lessonType}}
|
||||
{{i18n(lesson.lessonType.toString())}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -561,7 +587,7 @@
|
||||
</template>
|
||||
<style scoped>
|
||||
.grid{
|
||||
min-width:1200px;
|
||||
min-width:1400px;
|
||||
display:grid;
|
||||
margin-top:2%;
|
||||
align-items:center;
|
||||
|
153
frontend/src/Apps/ScientificPublications/FilterComponent.vue
Normal file
153
frontend/src/Apps/ScientificPublications/FilterComponent.vue
Normal file
@ -0,0 +1,153 @@
|
||||
<!----------------------------------------------------
|
||||
File: ResearchComponent.vue
|
||||
Author: Maxime Bartha
|
||||
Scope: Extension Publicatons scientifiquess
|
||||
Description: Pop Up for selecting search Filters
|
||||
----------------------------------------------------->
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import {onClickOutside} from '@vueuse/core'
|
||||
import i18n from "@/i18n.js";
|
||||
const yearList = ref([])
|
||||
const yearCheckedList = ref([])
|
||||
const monthList = ref([])
|
||||
const monthCheckedList = ref([])
|
||||
const accessList = ref([])
|
||||
const accessCheckedList = ref([])
|
||||
const languageList = ref([])
|
||||
const languageCheckedList = ref([])
|
||||
const domainList = ref([])
|
||||
const domainCheckedList = ref([])
|
||||
const paperTypeList = ref([])
|
||||
const paperTypCheckedList = ref([])
|
||||
|
||||
const filters = Object.assign({},{
|
||||
year:[],
|
||||
month:[],
|
||||
access:[],
|
||||
language:[],
|
||||
domain:[],
|
||||
paperType:[],
|
||||
})
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
isOpen: Boolean,
|
||||
allArticles: ref([Object])
|
||||
});
|
||||
|
||||
|
||||
function submit(){
|
||||
filters.paperType = paperTypCheckedList.value
|
||||
filters.year = yearCheckedList.value
|
||||
filters.month = monthCheckedList.value
|
||||
filters.access = accessCheckedList.value
|
||||
filters.language = languageCheckedList.value
|
||||
filters.domain = domainCheckedList.value
|
||||
emit("modal-close")
|
||||
emit("submit", filters)
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (let i=0;i< props.allArticles.length;i++) {
|
||||
let r = props.allArticles[i];
|
||||
let year = r.releaseDate.split("-")[0]
|
||||
let month = r.releaseDate.split("-")[1]
|
||||
|
||||
if (!yearList.value.includes(year) && year !== null) yearList.value.push(year);
|
||||
|
||||
if (!monthList.value.includes(month) && month !== null) monthList.value.push(month);
|
||||
|
||||
if (!accessList.value.includes(r.access) && r.access !== null ) accessList.value.push(r.access);
|
||||
|
||||
if (!languageList.value.includes(r.language) && r.language !== null) languageList.value.push(r.language);
|
||||
|
||||
if (!domainList.value.includes(r.domain) && r.domain !== null) domainList.value.push(r.domain);
|
||||
|
||||
if (!paperTypeList.value.includes(r.paperType) && r.paperType !== null) paperTypeList.value.push(r.paperType);
|
||||
}
|
||||
const emit = defineEmits(["modal-close", "submit"]);
|
||||
|
||||
const target = ref(null)
|
||||
onClickOutside(target, ()=>emit('modal-close'))
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="isOpen" class="modal-mask">
|
||||
<div class="modal-wrapper">
|
||||
<div class="modal-container" ref="target">
|
||||
<div id="filterGrid">
|
||||
<div> {{i18n("Year")}} :<ul class="checkers"> <li v-for="n in yearList"> <input type="checkbox" :value=n v-model="yearCheckedList"> {{n}} </li> </ul> </div>
|
||||
<div class="vl"> {{i18n("Access")}}:<ul class="checkers"> <li v-for="n in accessList"> <input type="checkbox" :value=n v-model="accessCheckedList"> {{i18n("Access."+n)}} </li> </ul> </div>
|
||||
<div class="vl"> {{i18n("Language")}} :<ul class="checkers"> <li v-for="n in languageList"> <input type="checkbox" :value=n v-model="languageCheckedList"> {{n}} </li> </ul> </div>
|
||||
<div> {{i18n("Month")}} :<ul class="checkers"> <li v-for="n in monthList"> <input type="checkbox" :value=n v-model="monthCheckedList"> {{i18n("Month." + n)}} </li> </ul> </div>
|
||||
<div class="vl"> {{i18n("Domain")}} :<ul class="checkers"> <li v-for="n in domainList"> <input type="checkbox" :value=n v-model="domainCheckedList"> {{n}} </li> </ul> </div>
|
||||
<div class="vl"> {{i18n("PaperType")}} :<ul class="checkers"> <li v-for="n in paperTypeList"> <input type="checkbox" :value=n v-model="paperTypCheckedList"> {{n}} </li> </ul> </div>
|
||||
</div>
|
||||
<div id="submit">
|
||||
<button @click.stop="submit">{{i18n("Submit")}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.modal-mask {
|
||||
position: fixed;
|
||||
z-index: 9998;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
width: 70%;
|
||||
margin: 150px auto;
|
||||
padding: 20px 30px;
|
||||
background: rgba(157, 99, 205);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
|
||||
}
|
||||
|
||||
#filterGrid {
|
||||
display: grid;
|
||||
grid-template-columns: auto auto auto;
|
||||
column-gap: 5px;
|
||||
grid-template-rows: auto auto;
|
||||
}
|
||||
#filterGrid ul {
|
||||
list-style-type: none;
|
||||
padding: 15px;
|
||||
height: 100px;
|
||||
overflow: scroll;
|
||||
scrollbar-color: #8a2be2 rgb(255,255,255,0.04);
|
||||
background-color: rgba(255, 255, 255, 0.09);
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
|
||||
.vl {
|
||||
border-left: 6px solid #8a2be2;
|
||||
}
|
||||
#submit {
|
||||
text-align: end;
|
||||
}
|
||||
|
||||
#submit button {
|
||||
margin-left: 2px;
|
||||
font-size: large;
|
||||
color: white;
|
||||
background: rgba(191, 64, 191,0.5);
|
||||
border:2px solid black;
|
||||
border-radius: 5px;
|
||||
}
|
||||
#submit button:hover{
|
||||
background: rgba(191, 64, 191);
|
||||
}
|
||||
|
||||
</style>
|
235
frontend/src/Apps/ScientificPublications/ListResearches.vue
Normal file
235
frontend/src/Apps/ScientificPublications/ListResearches.vue
Normal file
@ -0,0 +1,235 @@
|
||||
<!----------------------------------------------------
|
||||
File: ListResearches.vue
|
||||
Author: Maxime Bartha
|
||||
Scope: Extension Publicatons scientifiquess
|
||||
Description: Listing of the researches with filters
|
||||
----------------------------------------------------->
|
||||
<script setup>
|
||||
import {ref, watch} from "vue";
|
||||
import FilterComponent from "@/Apps/ScientificPublications/FilterComponent.vue";
|
||||
import ArticleComponent from "@/Apps/ScientificPublications/ResearchComponent.vue";
|
||||
import {fetchAllResearches} from "@/rest/ScientificPublications/ManageResearch.js";
|
||||
import i18n from "../../i18n.js";
|
||||
const input = ref("")
|
||||
const isFilterOpened = ref(false);
|
||||
const isResearchOpened = ref(false);
|
||||
const articleToDisplay = ref(Object)
|
||||
const isResearcher = ref(false)
|
||||
const filters = ref(null)
|
||||
const researchList = ref(await fetchAllResearches())
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
researchList:ref(),
|
||||
manage:Boolean,
|
||||
allResearcher:ref()
|
||||
});
|
||||
|
||||
if (typeof props.researchList !== 'undefined'){
|
||||
researchList.value = props.researchList
|
||||
}
|
||||
watch(
|
||||
() => props.researchList,
|
||||
(newValue) => {
|
||||
researchList.value = newValue
|
||||
}
|
||||
);
|
||||
|
||||
async function modified(){
|
||||
if (typeof props.researchList === 'undefined'){
|
||||
researchList.value = await fetchAllResearches()
|
||||
}
|
||||
else {
|
||||
emit('modified')
|
||||
}
|
||||
}
|
||||
|
||||
const openFilter = () => {
|
||||
isFilterOpened.value = true;
|
||||
};
|
||||
const closeFilter = () => {
|
||||
isFilterOpened.value = false;
|
||||
};
|
||||
const submitFilters = (receivedFilters)=>{
|
||||
filters.value = receivedFilters
|
||||
}
|
||||
|
||||
|
||||
const openResearch = (article) => {
|
||||
isResearchOpened.value = true;
|
||||
articleToDisplay.value = article;
|
||||
}
|
||||
|
||||
const closeResearch = () => {
|
||||
isResearchOpened.value =false;
|
||||
articleToDisplay.value = null;
|
||||
}
|
||||
|
||||
|
||||
function searchInList(list, searchInput) {
|
||||
let retList = []
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
let researcher = list[i].researcher.user.firstName + " " +list[i].researcher.user.lastName
|
||||
if (isResearcher.value && (lDistance(researcher, searchInput) < 5 || researcher.toUpperCase().indexOf(searchInput.toUpperCase()) > -1)){
|
||||
retList.push(list[i])
|
||||
}
|
||||
if (!isResearcher.value && (lDistance(list[i].title, searchInput) < 10 || list[i].title.toUpperCase().indexOf(searchInput.toUpperCase()) > -1)){
|
||||
|
||||
if (filters.value === null) {
|
||||
retList.push(list[i])
|
||||
continue;
|
||||
}
|
||||
if ( (filters.value.access.length === 0 || filters.value.access.includes(list[i].access))
|
||||
&& ( filters.value.domain.length === 0|| filters.value.domain.includes(list[i].domain))
|
||||
&& ( filters.value.paperType.length === 0 || filters.value.paperType.includes(list[i].paperType))
|
||||
&& ( filters.value.year.length === 0|| filters.value.year.includes(list[i].releaseDate.split("-")[0]))
|
||||
&& ( filters.value.month.length === 0|| filters.value.month.includes(list[i].releaseDate.split("-")[1]))
|
||||
&& ( filters.value.language.length === 0|| filters.value.language.includes(list[i].language)))
|
||||
{
|
||||
retList.push(list[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
return retList
|
||||
}
|
||||
|
||||
function lDistance(s,t){
|
||||
if (!s.length) return t.length;
|
||||
if (!t.length) return s.length;
|
||||
const arr = [];
|
||||
for (let i = 0; i <= t.length; i++) {
|
||||
arr[i] = [i];
|
||||
for (let j = 1; j <= s.length; j++) {
|
||||
arr[i][j] =
|
||||
i === 0
|
||||
? j
|
||||
: Math.min(
|
||||
arr[i - 1][j] + 1,
|
||||
arr[i][j - 1] + 1,
|
||||
arr[i - 1][j - 1] + (s[j - 1] === t[i - 1] ? 0 : 1)
|
||||
);
|
||||
}
|
||||
}
|
||||
return arr[t.length][s.length];
|
||||
}
|
||||
|
||||
const emit = defineEmits(["modified"]);
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="researches">
|
||||
<FilterComponent :isOpen="isFilterOpened" :allArticles="researchList" @modal-close="closeFilter" @submit="submitFilters"></FilterComponent>
|
||||
<ArticleComponent :allResearcher="allResearcher" :article="articleToDisplay" :isOpen="isResearchOpened" :manage="props.manage" @modal-close="closeResearch" @modified="modified"></ArticleComponent>
|
||||
<div id="search">
|
||||
<input v-if="!isResearcher" type="text" id="search-input" :placeholder="i18n('Search.Researches')" v-model="input"/>
|
||||
<input v-else type="text" id="search-input" :placeholder="i18n('Search.Researchers')" v-model="input"/>
|
||||
<button v-if="!isResearcher" id="filterButton" @click="openFilter"> {{i18n("Filters")}} </button>
|
||||
<button v-if="!isResearcher" id="unToggledResearchButton" @click="isResearcher = !isResearcher"> {{i18n("Toggle.Researcher")}}</button>
|
||||
<button v-if="isResearcher" id="toggledResearchButton" @click="isResearcher = !isResearcher"> {{i18n("Untoggle.Researcher")}}</button>
|
||||
</div>
|
||||
<div id="researches">
|
||||
<ul id="researchUL">
|
||||
<li id="researchLi" v-for="n in searchInList(researchList,input)">
|
||||
<div class="vl"> {{n.title}}</div>
|
||||
<div class="vl"> <a :href="'#/researcher-profile?id=' + n.researcher.id"> {{ n.researcher.user.firstName +" "+ n.researcher.user.lastName }}</a>
|
||||
</div>
|
||||
<a v-if="!manage" @click="openResearch(n)"> {{i18n("MoreInfo")}}</a>
|
||||
<a v-else @click="openResearch(n)"> {{i18n("Modify.Research")}}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
#researches{
|
||||
padding-top: 15px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
#search{
|
||||
width: 100%;
|
||||
height: 10%;
|
||||
display: inline-flex;
|
||||
}
|
||||
#search-input {
|
||||
margin-left: 25px;
|
||||
width: 75%;
|
||||
font-size: 16px;
|
||||
padding: 12px 20px 12px 40px;
|
||||
border: 1px solid #ddd;
|
||||
height: 20px;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
#filterButton {
|
||||
align-self: center;
|
||||
margin-left: 2px;
|
||||
font-size: xx-large;
|
||||
color: white;
|
||||
background: rgba(191, 64, 191,0.5);
|
||||
border:2px solid black;
|
||||
}
|
||||
#filterButton:hover{
|
||||
background: rgba(191, 64, 191);
|
||||
}
|
||||
|
||||
|
||||
#researchUL {
|
||||
list-style-type: none;
|
||||
color: white;
|
||||
padding: 12px;
|
||||
margin: 5px;
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
}
|
||||
#researchLi{
|
||||
display: grid;
|
||||
grid-template-columns: auto auto auto;
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: x-large;
|
||||
text-align: center;
|
||||
text-indent: 7px;
|
||||
background-color: rgba(255, 255, 255, 0.09);
|
||||
border-radius: 18px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
a{
|
||||
color:#007aff;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.vl {
|
||||
border-right: 2px solid black;
|
||||
}
|
||||
|
||||
#unToggledResearchButton{
|
||||
align-self: center;
|
||||
margin-left: 2px;
|
||||
font-size:16px ;
|
||||
color: white;
|
||||
background: #2a1981;
|
||||
border:2px solid black;
|
||||
}
|
||||
|
||||
#unToggledResearchButton:hover{
|
||||
background: #5ac8fa;
|
||||
|
||||
}
|
||||
|
||||
#toggledResearchButton {
|
||||
align-self: center;
|
||||
margin-left: 2px;
|
||||
font-size: large;
|
||||
color: white;
|
||||
background: crimson;
|
||||
border:2px solid black;
|
||||
}
|
||||
#toggledResearchButton:hover{
|
||||
background: #ff2d55;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,184 @@
|
||||
<!----------------------------------------------------
|
||||
File: ManageResearchesProfile.vue
|
||||
Author: Maxime Bartha
|
||||
Scope: Extension Publicatons scientifiquess
|
||||
Description: Managing Researcher Profile page
|
||||
----------------------------------------------------->
|
||||
<script setup>
|
||||
import { ref} from "vue";
|
||||
import {fetchResearches, } from "@/rest/ScientificPublications/ResearcherProfile.js";
|
||||
import {getSelf, patchProfile} from "@/rest/ScientificPublications/ManageResearcherProfile.js";
|
||||
import ResearchPostComponent from "@/Apps/ScientificPublications/ResearchPostComponent.vue";
|
||||
import ListResearches from "@/Apps/ScientificPublications/ListResearches.vue";
|
||||
import i18n from "../../i18n.js";
|
||||
import {fetchAllResearchers} from "@/rest/ScientificPublications/ManageResearch.js";
|
||||
const input = ref("");
|
||||
const isPostResearchOpened = ref(false);
|
||||
const changing = ref(false);
|
||||
|
||||
let toModify= Object.assign({}, {});
|
||||
|
||||
const researcher = ref(await getSelf());
|
||||
const researchList = ref(await fetchResearches(researcher.value.id));
|
||||
const allResearcher = ref(await fetchAllResearchers())
|
||||
function openPostResearch(){
|
||||
isPostResearchOpened.value = true
|
||||
}
|
||||
function cancelChanges(){
|
||||
changing.value = false
|
||||
toModify= Object.assign({}, {});
|
||||
}
|
||||
async function confirmChanges(){
|
||||
await patchProfile(researcher.value.id, toModify)
|
||||
changing.value = false
|
||||
toModify= Object.assign({}, {});
|
||||
researcher.value = await getSelf();
|
||||
}
|
||||
|
||||
async function modifiedResearch(){
|
||||
researchList.value = await fetchResearches(researcher.value.id)
|
||||
}
|
||||
|
||||
function getPP(){
|
||||
if(researcher.value.user.profilePictureUrl === null){
|
||||
return "/Clyde.png"
|
||||
}
|
||||
return researcher.value.user.profilePictureUrl
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template> <div class="body"><div id="main">
|
||||
<ResearchPostComponent :allResearcher="allResearcher" :researcher="researcher" :isOpen="isPostResearchOpened" @modal-close="isPostResearchOpened = false" @posted="modifiedResearch"></ResearchPostComponent>
|
||||
<div id="profilePicture" >
|
||||
<img :src=getPP() style="border-radius: 20%"/>
|
||||
</div>
|
||||
<div id="researcherInfos">
|
||||
<div class="surrounded" v-if="!changing">{{researcher.user.lastName}} {{researcher.user.firstName}}</div>
|
||||
<div class="surrounded" v-else> {{i18n("To.Change.In.Options")}}</div>
|
||||
|
||||
<div class="surrounded" v-if="!changing">Orcid : {{researcher.orcidId}}</div>
|
||||
<div class="surrounded" v-else>Orcid : <input v-model="toModify.orcidId"> </div>
|
||||
|
||||
<div class="surrounded" v-if="!changing">Email : {{researcher.user.email}}</div>
|
||||
<div class="surrounded" v-else> {{i18n("To.Change.In.Options")}}</div>
|
||||
|
||||
<div class="surrounded" v-if="!changing">
|
||||
Site : <a :href=researcher.site style="color: #007aff"> {{researcher.site}}</a>
|
||||
</div>
|
||||
<div class="surrounded" v-else>Site : <input v-model="toModify.site"></div>
|
||||
|
||||
<div class="surrounded" v-if="!changing">{{i18n("Domain")}} : {{researcher.domain}}</div>
|
||||
<div class="surrounded" v-else>Domain : <input v-model="toModify.domain"></div>
|
||||
|
||||
<div style="text-align: center; align-self: center" v-if="!changing"> <button class="modifyButton" @click="changing = !changing">{{i18n("Modify.Data")}}</button></div>
|
||||
<div v-else style="text-align: center; align-self: center">
|
||||
<button id="confirmButton" @click="confirmChanges"> {{i18n("Confirm.Changes")}}</button>
|
||||
<button id="cancelButton" @click="cancelChanges"> {{i18n("Cancel.Changes")}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="postArticle" style="text-align: center">
|
||||
<button class="modifyButton" @click="openPostResearch">{{i18n("Post.Research")}}</button>
|
||||
|
||||
|
||||
</div>
|
||||
<div> <ListResearches :allResearcher="allResearcher" :research-list="researchList" :manage="true" @modified="modifiedResearch"></ListResearches> </div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
#main {
|
||||
display: grid;
|
||||
grid-template-columns: 22% auto;
|
||||
grid-template-rows: 26% auto;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#profilePicture {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#profilePicture img {
|
||||
align-self: center;
|
||||
justify-self: center;
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
#researcherInfos {
|
||||
display: grid;
|
||||
grid-template-columns: auto auto auto;
|
||||
column-gap: 5px;
|
||||
grid-template-rows: auto auto;
|
||||
}
|
||||
|
||||
.surrounded {
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: x-large;
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
background-color: rgba(255, 255, 255, 0.09);
|
||||
border-radius: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.surrounded select {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
border: 1px solid black;
|
||||
color: white;
|
||||
background-color: rgb(255, 255, 255, 0.1);
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
.modifyButton{
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: xx-large;
|
||||
background-color:rgba(191, 64, 191,0.5);
|
||||
border-radius: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.modifyButton:hover{
|
||||
background:rgba(191,64,191)
|
||||
}
|
||||
|
||||
#cancelButton{
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: x-large;
|
||||
background-color: red;
|
||||
border-radius: 20px;
|
||||
}
|
||||
#cancelButton:hover{
|
||||
background: #ff2d55;
|
||||
}
|
||||
|
||||
#confirmButton{
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: x-large;
|
||||
background-color: #07bc0c;
|
||||
border-radius: 20px;
|
||||
}
|
||||
#confirmButton:hover{
|
||||
background: #4cd964;
|
||||
}
|
||||
|
||||
a{
|
||||
color:#007aff;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
242
frontend/src/Apps/ScientificPublications/ResearchComponent.vue
Normal file
242
frontend/src/Apps/ScientificPublications/ResearchComponent.vue
Normal file
@ -0,0 +1,242 @@
|
||||
<!----------------------------------------------------
|
||||
File: ResearchComponent.vue
|
||||
Author: Maxime Bartha
|
||||
Scope: Extension Publicatons scientifiquess
|
||||
Description: Pop Up summarizing a research infos
|
||||
----------------------------------------------------->
|
||||
|
||||
<script setup xmlns="http://www.w3.org/1999/html">
|
||||
import {ref, watch} from "vue";
|
||||
import {onClickOutside} from '@vueuse/core'
|
||||
import {
|
||||
patchArticle,
|
||||
deleteArticle,
|
||||
addView,
|
||||
} from "@/rest/ScientificPublications/ManageResearch.js";
|
||||
import i18n from "../../i18n.js";
|
||||
const coAuthors = ref()
|
||||
const restURL = import.meta.env.VITE_CLYDE_MODE === 'container' ? "http://localhost:8000": import.meta.env.DEV ? "http://localhost:5173" : "https://clyde.herisson.ovh/api"
|
||||
const props = defineProps({
|
||||
isOpen: Boolean,
|
||||
article: ref(Object),
|
||||
manage:Boolean,
|
||||
allResearcher: ref()
|
||||
});
|
||||
|
||||
|
||||
watch(
|
||||
() => props.article,
|
||||
(newValue) => {
|
||||
if (newValue !== null)
|
||||
coAuthors.value = newValue.coAuthors
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
function format(date){
|
||||
let split = date.split("-")
|
||||
let month = split[1]
|
||||
let day = split[2].split("T")[0]
|
||||
let year = split[0]
|
||||
return day +"/"+ month +"/"+ year
|
||||
}
|
||||
|
||||
const emit = defineEmits(["modal-close","modified"]);
|
||||
|
||||
const target = ref(null)
|
||||
onClickOutside(target, ()=>{emit('modal-close'); })
|
||||
|
||||
let toModify= Object.assign({}, {});
|
||||
|
||||
function cancelChanges(){
|
||||
toModify= Object.assign({}, {});
|
||||
emit('modal-close')
|
||||
}
|
||||
|
||||
async function confirmChanges(){
|
||||
let coAuthorsId =[]
|
||||
coAuthors.value.forEach(n => (coAuthorsId.push(n.id)))
|
||||
toModify.coAuthors = coAuthorsId
|
||||
await patchArticle(props.article.id, toModify)
|
||||
toModify= Object.assign({}, {});
|
||||
emit('modal-close')
|
||||
emit("modified")
|
||||
}
|
||||
|
||||
async function deleteThisArticle(){
|
||||
await deleteArticle(props.article.id)
|
||||
emit('modal-close')
|
||||
emit("modified")
|
||||
}
|
||||
function downloadPdf(){
|
||||
return (restURL + "/" + props.article.pdfLocation)
|
||||
}
|
||||
|
||||
function downloadBibTex(){
|
||||
return (restURL + "/" + props.article.bibTexLocation)
|
||||
}
|
||||
|
||||
async function articleClicked(){
|
||||
await addView(props.article.pdfLocation)
|
||||
emit('modal-close')
|
||||
emit('modified')
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="isOpen" class="modal-mask">
|
||||
<div class="modal-wrapper">
|
||||
<div class="modal-container" ref="target">
|
||||
<div><ul>
|
||||
<li>{{i18n("Article.Id")}} : {{article.id}}</li>
|
||||
<li>{{i18n("Title")}} : {{article.title}}</li>
|
||||
<li>{{i18n("Author")}} : {{article.researcher.user.lastName + " " + article.researcher.user.firstName}}</li>
|
||||
<li>{{i18n("CoAuthors")}} : <ul id="coAuthors" v-for="n in article.coAuthors"> <li id="coAuthorsLi"> {{n.user.firstName}} {{n.user.lastName}}, </li></ul></li>
|
||||
<li>{{i18n("Summary")}} : {{article.summary}}</li>
|
||||
<li>{{i18n("ReleaseDate")}} : {{format(article.releaseDate)}}</li>
|
||||
<li>{{i18n("Language")}} : {{article.language}}</li>
|
||||
<li>{{i18n("PaperType")}} : {{article.paperType}}</li>
|
||||
<li>{{i18n("Domain")}} : {{article.domain}}</li>
|
||||
<li>{{i18n("Views")}} : {{article.views}}</li>
|
||||
<li>{{i18n("Access")}} : {{i18n("Access."+article.access)}}</li>
|
||||
</ul>
|
||||
<div id="downloads" v-if="article.pdfLocation !== null && !manage">
|
||||
<a :href=downloadPdf() @click.stop="articleClicked" target="_blank">{{i18n("See.Research")}}</a>
|
||||
<a v-if="article.bibTexLocation !== null" :href=downloadBibTex() @click.stop="emit('modal-close')" target="_blank">{{i18n("SeeBibTex")}}</a> </div>
|
||||
</div>
|
||||
<div v-if="manage" id="manage">
|
||||
<div>
|
||||
<ul>
|
||||
<li>{{i18n("Title")}} : <input v-model="toModify.title"></li>
|
||||
<li>{{i18n("Language")}} : <input v-model="toModify.language"></li>
|
||||
<li>{{i18n("Summary")}} : <input v-model="toModify.summary"></li>
|
||||
<li>{{i18n("Domain")}} : <input v-model="toModify.domain"></li>
|
||||
<li>{{i18n("Access")}} :
|
||||
<select id="classed-select" v-model="toModify.access">
|
||||
<option value="OpenSource">{{i18n("Access.OpenSource")}}</option>
|
||||
<option value="Restricted">{{i18n("Access.Restricted")}}</option>
|
||||
<option value="Private">{{i18n("Access.Private")}}</option>
|
||||
</select></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div> {{i18n("CoAuthors.List")}} :
|
||||
<ul id="coAuthorListUl" style="list-style-type: none;" v-for="n in props.allResearcher">
|
||||
<li v-if="n.id !== props.article.researcher.id"> <input type="checkbox" :value=n v-model="coAuthors"> {{n.id}} : {{n.user.firstName}} {{n.user.lastName}}</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
<button id="confirmButton" @click="confirmChanges"> {{i18n("Confirm.Changes")}}</button>
|
||||
<button id="cancelButton" @click="cancelChanges">{{i18n("Cancel.Changes")}}</button>
|
||||
</div>
|
||||
<div style="text-align: end">
|
||||
<button id="deleteButton" @click="deleteThisArticle">{{i18n("Delete.Research")}} </button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.modal-mask {
|
||||
position: fixed;
|
||||
z-index: 9998;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 120%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
width: 70%;
|
||||
margin: 150px auto;
|
||||
padding: 20px 30px;
|
||||
background: rgba(157, 99, 205);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
|
||||
}
|
||||
|
||||
.modal-container ul{
|
||||
margin-top: 9px;
|
||||
}
|
||||
#manage{
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
}
|
||||
|
||||
#coAuthors{
|
||||
list-style: none;
|
||||
display: inline;
|
||||
padding: 0;
|
||||
}
|
||||
#coAuthorsLi{
|
||||
display: inline;
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
#downloads {
|
||||
text-align: end;
|
||||
}
|
||||
|
||||
#coAuthorListUl{
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
#downloads a {
|
||||
align-self: center;
|
||||
margin-left: 2px;
|
||||
font-size: large;
|
||||
color: white;
|
||||
background: rgba(191, 64, 191,0.5);
|
||||
border:2px solid black;
|
||||
border-radius: 5px;
|
||||
text-underline-mode: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
#downloads button:hover{
|
||||
background: rgba(191, 64, 191);
|
||||
}
|
||||
|
||||
#deleteButton{
|
||||
align-self: end;
|
||||
text-align: end;
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: x-large;
|
||||
border-radius: 20px;
|
||||
background-color: red;
|
||||
}
|
||||
|
||||
#deleteButton:hover{
|
||||
background: #ff2d55;
|
||||
}
|
||||
|
||||
#cancelButton{
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: x-large;
|
||||
background-color:rgba(191, 64, 191,0.5);
|
||||
border-radius: 20px;
|
||||
}
|
||||
#cancelButton:hover{
|
||||
background:rgba(191,64,191)
|
||||
}
|
||||
|
||||
#confirmButton{
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: x-large;
|
||||
background-color: #07bc0c;
|
||||
border-radius: 20px;
|
||||
}
|
||||
#confirmButton:hover{
|
||||
background: #4cd964;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,177 @@
|
||||
<!----------------------------------------------------
|
||||
File: ResearchPostComponent.vue
|
||||
Author: Maxime Bartha
|
||||
Scope: Extension Publicatons scientifiquess
|
||||
Description: pop up for posting a research
|
||||
----------------------------------------------------->
|
||||
<script setup>
|
||||
|
||||
import { ref } from "vue";
|
||||
import {onClickOutside} from '@vueuse/core'
|
||||
import {uploadFile, postResearch} from "@/rest/ScientificPublications/ManageResearch.js";
|
||||
import i18n from "../../i18n.js";
|
||||
const coAuthors = ref([])
|
||||
|
||||
let toPost = Object.assign({}, {coAuthors:[]});
|
||||
|
||||
|
||||
const props = defineProps({
|
||||
isOpen: Boolean,
|
||||
researcher: ref(Object),
|
||||
allResearcher:ref()
|
||||
});
|
||||
|
||||
|
||||
async function uploadResearchPdf(pdf){
|
||||
const data = await uploadFile(pdf);
|
||||
toPost.pdfLocation = data.url;
|
||||
}
|
||||
async function uploadBibTex(pdf){
|
||||
const data = await uploadFile(pdf);
|
||||
toPost.bibTexLocation = data.url;
|
||||
}
|
||||
|
||||
|
||||
async function postNewResearch(){
|
||||
toPost.releaseDate = new Date()
|
||||
toPost.author = props.researcher
|
||||
toPost.coAuthors = coAuthors.value
|
||||
//the Pdf and a title are required
|
||||
if (toPost.pdfLocation == null || toPost.title == null || toPost.title === "") {
|
||||
emit("modal-close")
|
||||
return;
|
||||
}
|
||||
await postResearch(toPost)
|
||||
toPost = Object.assign({}, {});
|
||||
coAuthors.value = []
|
||||
emit("modal-close")
|
||||
emit("posted")
|
||||
}
|
||||
|
||||
function cancelPost(){
|
||||
emit("modal-close")
|
||||
toPost = Object.assign({}, {});
|
||||
}
|
||||
const emit = defineEmits(["modal-close","posted"]);
|
||||
|
||||
const target = ref(null)
|
||||
onClickOutside(target, ()=>emit('modal-close'))
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="isOpen" class="modal-mask">
|
||||
<div class="modal-wrapper">
|
||||
<div class="modal-container" ref="target">
|
||||
<div ><ul>
|
||||
|
||||
<li>{{i18n("Title")}} : <input v-model="toPost.title"></li>
|
||||
<li>{{i18n("Summary")}} : <input v-model="toPost.summary"></li>
|
||||
<li>{{i18n("Language")}} : <input v-model="toPost.language"></li>
|
||||
<li>{{i18n("Domain")}} : <input v-model="toPost.domain"></li>
|
||||
<li>{{i18n("PaperType")}} : <select id="classed-select" v-model="toPost.paperType">
|
||||
<option value="Article">{{i18n("PaperType.Article")}}</option>
|
||||
<option value="Book">{{i18n("PaperType.Book")}}</option>
|
||||
<option value="BookChapter">{{i18n("PaperType.Book.Chapter")}}</option>
|
||||
<option value="Paper">{{i18n("PaperType.Paper")}}Paper</option>
|
||||
</select></li>
|
||||
<li>{{i18n("Access")}} : <select id="classed-select" v-model="toPost.access">
|
||||
<option value="OpenSource">{{i18n("Access.OpenSource")}}</option>
|
||||
<option value="Restricted">{{i18n("Access.Restricted")}}</option>
|
||||
<option value="Private">{{i18n("Access.Private")}}</option>
|
||||
</select></li>
|
||||
|
||||
|
||||
<li> {{i18n("Research.Pdf")}} :
|
||||
<form novalidate enctype="multipart/form-data" class="inputBox">
|
||||
<input type="file" @change="uploadResearchPdf($event.target.files);" accept="application/pdf">
|
||||
</form></li>
|
||||
<li> {{i18n("BibTex.Pdf")}}
|
||||
<form novalidate enctype="multipart/form-data" class="inputBox">
|
||||
<input type="file" @change="uploadBibTex($event.target.files);" accept=".bib">
|
||||
</form></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="CoAuthorList"> {{i18n("CoAuthors.List")}} :
|
||||
<ul style="list-style-type: none;" v-for="n in props.allResearcher">
|
||||
<li v-if="n.id !== props.researcher.id"> <input type="checkbox" :value=n v-model="coAuthors"> {{n.id}} : {{n.user.firstName}} {{n.user.lastName}}</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<div></div>
|
||||
<div>
|
||||
<button id="confirmButton" @click="postNewResearch">{{i18n("Confirm.Publish")}}</button>
|
||||
<button id="cancelButton" @click="cancelPost">{{i18n("Cancel.Publish")}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.modal-mask {
|
||||
position: fixed;
|
||||
z-index: 9998;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
display: grid;
|
||||
grid-template-columns: 40% 60%;
|
||||
width: 70%;
|
||||
margin: 150px auto;
|
||||
padding: 20px 30px;
|
||||
background: rgba(157, 99, 205);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
|
||||
}
|
||||
|
||||
.modal-container ul{
|
||||
margin-top: 9px;
|
||||
}
|
||||
|
||||
#downloads button {
|
||||
align-self: center;
|
||||
margin-left: 2px;
|
||||
font-size: large;
|
||||
color: white;
|
||||
background: rgba(191, 64, 191,0.5);
|
||||
border:2px solid black;
|
||||
border-radius: 5px;
|
||||
}
|
||||
#downloads button:hover{
|
||||
background: rgba(191, 64, 191);
|
||||
}
|
||||
|
||||
|
||||
#cancelButton{
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: x-large;
|
||||
background-color:rgba(191, 64, 191,0.5);
|
||||
border-radius: 20px;
|
||||
}
|
||||
#cancelButton:hover{
|
||||
background:rgba(191,64,191)
|
||||
}
|
||||
|
||||
#confirmButton{
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: x-large;
|
||||
background-color: #07bc0c;
|
||||
border-radius: 20px;
|
||||
}
|
||||
#confirmButton:hover{
|
||||
background: #4cd964;
|
||||
}
|
||||
</style>
|
174
frontend/src/Apps/ScientificPublications/ResearcherProfile.vue
Normal file
174
frontend/src/Apps/ScientificPublications/ResearcherProfile.vue
Normal file
@ -0,0 +1,174 @@
|
||||
<!----------------------------------------------------
|
||||
File: ResearcherProfile.vue
|
||||
Author: Maxime Bartha
|
||||
Scope: Extension Publicatons scientifiquess
|
||||
Description: Researcher Profile Page containing his articles and his statistics
|
||||
----------------------------------------------------->
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import {fetchResearcher, fetchResearches, fetchStats} from "@/rest/ScientificPublications/ResearcherProfile.js";
|
||||
import ListResearches from "@/Apps/ScientificPublications/ListResearches.vue";
|
||||
import i18n from "../../i18n.js";
|
||||
const input = ref("");
|
||||
const statsOf = ref();
|
||||
const statsBy = ref();
|
||||
let chart;
|
||||
|
||||
const researcherId = window.location.href.split("=")[1]
|
||||
|
||||
|
||||
function getPP(){
|
||||
if(researcher.value.user.profilePictureUrl === null){
|
||||
return "/Clyde.png"
|
||||
}
|
||||
return researcher.value.user.profilePictureUrl
|
||||
}
|
||||
const researchList = ref(await fetchResearches(researcherId));
|
||||
const researcher = ref(await fetchResearcher(researcherId));
|
||||
const stats = ref(await fetchStats(researcherId))
|
||||
|
||||
function downloadCoAuthors(){
|
||||
let coAuthors = []
|
||||
for (let i in researchList.value) {
|
||||
for (const j in researchList.value[i].coAuthors){
|
||||
const coAuthor = researchList.value[i].coAuthors[j]
|
||||
coAuthors.push(coAuthor)
|
||||
}
|
||||
}
|
||||
const data = JSON.stringify(coAuthors);
|
||||
const blob = new Blob([data], {type:"application/json"});
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
const options = reactive({
|
||||
backgroundColor:null,
|
||||
theme: "light2",
|
||||
animationEnabled: true,
|
||||
title: {
|
||||
fontColor: "white",
|
||||
text : i18n("Please.Select.Option"),
|
||||
},
|
||||
data: [
|
||||
{
|
||||
type: "pie",
|
||||
indexLabel: "{label} (#percent%)",
|
||||
yValueFormatString: "#,##0",
|
||||
indexLabelFontColor: "white",
|
||||
toolTipContent:
|
||||
"<span style='\"'color: {color};'\"'>{label}</span> {y}(#percent%)",
|
||||
}]
|
||||
});
|
||||
|
||||
function update(){
|
||||
options.title = {
|
||||
fontColor: "white",
|
||||
}
|
||||
|
||||
let index = (statsOf.value === "Views"?0:(statsOf.value === "Researches"?3:6)) + (statsBy.value ==="Years"?0:(statsBy.value==="Months"?1:2))
|
||||
if (typeof statsBy.value !== 'undefined' && typeof statsOf.value !== 'undefined'){
|
||||
options.data[0].dataPoints = stats.value[index]
|
||||
options.title.text = i18n(statsOf.value) +" "+ i18n("By") +" " + i18n(statsBy.value);
|
||||
chart.render();
|
||||
}
|
||||
|
||||
}
|
||||
async function modifiedResearch(){
|
||||
researchList.value = await fetchResearches(researcher.value.id)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="main">
|
||||
<div id="profilePicture">
|
||||
<img :src=getPP() style="border-radius: 20%"/>
|
||||
</div>
|
||||
<div id="researcherInfos">
|
||||
<div class="surrounded">{{researcher.user.lastName}} {{researcher.user.firstName}}</div>
|
||||
<div class="surrounded">Orcid : {{researcher.orcidId}}</div>
|
||||
<div class="surrounded">Email : {{researcher.user.email}}</div>
|
||||
<div class="surrounded">
|
||||
Site : <a :href=researcher.site style="color: #007aff"> {{researcher.site}}</a>
|
||||
</div>
|
||||
<div class="surrounded">{{i18n("Domain")}} : {{researcher.domain}}</div>
|
||||
<div id="coAuthorList" class="surrounded">Co-authors list : <a :href=downloadCoAuthors() download="coAuthors.json">{{i18n("Here")}}</a></div>
|
||||
</div>
|
||||
<div id="stats">
|
||||
<div class="surrounded">
|
||||
{{i18n("Stat.Type")}} :
|
||||
<select @change="update()" id="stats-select" v-model="statsOf">
|
||||
<option value="Views">{{i18n("Views")}}</option>
|
||||
<option value="Researches">{{i18n("Researches")}}</option>
|
||||
<option value="DifferentLanguage">{{i18n("DifferentLanguage")}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="surrounded">
|
||||
{{i18n("Class.By")}} :
|
||||
<select @change="update()" id="classed-select" v-model="statsBy">
|
||||
<option value="Years">{{i18n("Years")}}</option>
|
||||
<option value="Months">{{i18n("Months")}}</option>
|
||||
<option value="Domain">{{i18n("Domain")}}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div id="statsPie">
|
||||
<CanvasJSChart :options="options" id=chart @chart-ref="c => chart = c "/>
|
||||
</div>
|
||||
</div>
|
||||
<div id="researches" style="margin-top: -15px"><list-researches :researchList="researchList" @modified="modifiedResearch"></list-researches></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
#main {
|
||||
display: grid;
|
||||
grid-template-columns: 22% auto;
|
||||
grid-template-rows: 26% auto;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#profilePicture {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#profilePicture img {
|
||||
align-self: center;
|
||||
justify-self: center;
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
#researcherInfos {
|
||||
display: grid;
|
||||
grid-template-columns: auto auto auto;
|
||||
column-gap: 5px;
|
||||
grid-template-rows: auto auto;
|
||||
}
|
||||
|
||||
.surrounded {
|
||||
border: 2px solid black;
|
||||
color: white;
|
||||
font-size: x-large;
|
||||
align-self: center;
|
||||
text-align: center;
|
||||
background-color: rgba(255, 255, 255, 0.09);
|
||||
border-radius: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.surrounded select {
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
border: 1px solid black;
|
||||
color: white;
|
||||
background-color: rgb(255, 255, 255, 0.1);
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
a{
|
||||
color:#007aff;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
@ -12,7 +12,7 @@
|
||||
<template style="margin-top:5%;">
|
||||
<div v-if="list === false">
|
||||
<AboutStudent :target=targetRegNo />
|
||||
<button style="background-color:rgb(105,05,105);width:5%; margin-left: 10%;" @click="list = true;">Back</button>
|
||||
<button style="background-color:rgb(105,05,105);width:5%; margin-left: 10%;" @click="list = true;">{{ i18n("courses.back") }}</button>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:center; " v-for="item in users" v-if="list === true">
|
||||
<div class="bodu">
|
||||
|
@ -1,20 +1,30 @@
|
||||
|
||||
<script setup>
|
||||
import i18n from "@/i18n.js"
|
||||
import { reactive } from 'vue'
|
||||
import { getAllUsers } from '../rest/Users.js'
|
||||
import {ref} from "vue";
|
||||
import AboutUser from "@/Apps/AboutUser.vue";
|
||||
const list = ref(true)
|
||||
const targetRegNo =ref()
|
||||
|
||||
|
||||
const users = await getAllUsers();
|
||||
|
||||
</script>
|
||||
<template style="margin-top:5%;">
|
||||
<div style="display:flex; justify-content:center; min-width:1140px;" v-for="item in users">
|
||||
<div class="bodu">
|
||||
<div v-if="list === false">
|
||||
<AboutUser :user=target />
|
||||
<button style="background-color:rgb(105,05,105);width:5%; margin-left: 10%;" @click="list = true;">Back</button>
|
||||
</div>
|
||||
<div style="display:flex; justify-content:center; min-width:1140px;" v-for="item in users" v-if="list">
|
||||
<div class="body">
|
||||
<div class="container">
|
||||
<div class="role"><a style="margin-left:30px">{{i18n(item.role)}}</a></div>
|
||||
<div class="surname"><a>{{item.lastName}}</a></div>
|
||||
<div class="firstname"><a>{{item.firstName}}</a></div>
|
||||
<div class="infos"><button style="background-color:rgb(105,05,105);" >{{i18n("request.moreInfos")}} </button></div>
|
||||
<div class="infos">
|
||||
<button style="background-color:rgb(105,05,105);" @click="list = false; target = item;">{{i18n("request.moreInfos")}} </button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -70,7 +80,7 @@
|
||||
|
||||
}
|
||||
|
||||
.bodu {
|
||||
.body {
|
||||
margin-top:2%;
|
||||
width:66%;
|
||||
border:2px solid black;
|
||||
|
@ -4,5 +4,8 @@ import 'https://kit.fontawesome.com/fb3bbd0a95.js'
|
||||
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import CanvasJSChart from '@canvasjs/vue-charts';
|
||||
|
||||
createApp(App).mount('#app')
|
||||
const app = createApp(App);
|
||||
app.use(CanvasJSChart);
|
||||
app.mount('#app');
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user