55 Commits

Author SHA1 Message Date
b8b193f344 proposition of some fixes 2024-04-05 09:44:41 +02:00
3d78851b29 moving file into extensions directory 2024-04-04 21:27:51 +02:00
dbe28a7fed making the chart responsive 2024-04-04 16:14:19 +02:00
bd7d2c2d51 adding colors to piechart 2024-04-04 15:01:10 +02:00
91c7f42521 finished mock researcher profile 2024-04-02 19:52:38 +02:00
bd27ffd3cb search bar not working (to be shared with william) 2024-04-01 19:13:39 +02:00
91ee3adbcd adding the dependance 2024-03-30 13:10:11 +01:00
c1b2742a8f better select buttons 2024-03-30 12:38:18 +01:00
2805fede4b researcher profile page separations 2024-03-30 12:38:18 +01:00
951feed3c8 Full screen apps 2024-03-30 12:38:18 +01:00
95054fa973 Login 'fixed' 2024-03-30 12:38:18 +01:00
3af83a58d3 Just to merge 2024-03-30 12:38:17 +01:00
47c5c14862 Make app use full space 2024-03-30 12:38:17 +01:00
db895a6091 added temporary fix to docker issue 2024-03-23 14:38:26 +01:00
3d6941ab93 adding cdn to CI
All checks were successful
Build and test backend / Build-backend (push) Successful in 1m57s
Build and test FrontEnd / Build-frontend (push) Successful in 23s
deploy to production / deploy-frontend (push) Successful in 27s
deploy to production / deploy-backend (push) Successful in 1m29s
2024-03-18 21:39:31 +01:00
de72bd800c CI fix
All checks were successful
Build and test backend / Build-backend (push) Successful in 1m53s
deploy to production / deploy-frontend (push) Successful in 26s
deploy to production / deploy-backend (push) Successful in 2m3s
Build and test FrontEnd / Build-frontend (push) Successful in 23s
2024-03-18 21:13:00 +01:00
b465dcfa92 Merge pull request 'Clean le projet' (#146) from Leo/Backend/Cleaning into master
Some checks failed
Build and test backend / Build-backend (push) Successful in 1m55s
deploy to production / deploy-frontend (push) Successful in 26s
deploy to production / deploy-backend (push) Failing after 2m51s
Build and test FrontEnd / Build-frontend (push) Successful in 24s
Reviewed-on: #146
Reviewed-by: Wal <karpinskiwal@gmail.com>
Reviewed-by: Debucquoy Anthony <d.tonitch@gmail.com>
2024-03-18 21:06:02 +01:00
73f3df0bc6 Clean le projet
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m46s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 24s
2024-03-18 20:54:16 +01:00
90a7b7b70e Merge pull request 'Link back and front all get' (#115) from wal/front/listingUsers into master
Some checks failed
Build and test backend / Build-backend (push) Successful in 1m53s
deploy to production / deploy-frontend (push) Successful in 25s
deploy to production / deploy-backend (push) Failing after 2m48s
Build and test FrontEnd / Build-frontend (push) Successful in 24s
Reviewed-on: #115
Reviewed-by: Debucquoy Anthony <d.tonitch@gmail.com>
Reviewed-by: LeoMoulin <leomoulin125@gmail.com>
2024-03-18 20:20:35 +01:00
4715441afd FINAL COMMIT
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m2s
Build and test backend / Test-backend (pull_request) Successful in 1m58s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 23s
2024-03-18 18:47:00 +01:00
77ac771b8f Merge remote-tracking branch 'origin/Max/Backend/UserDelete' into wal/front/listingUsers
Some checks failed
Build and test backend / Build-backend (pull_request) Failing after 1m31s
Build and test backend / Test-backend (pull_request) Failing after 1m31s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 23s
2024-03-18 17:36:07 +01:00
3762750968 Tempo 2024-03-18 17:34:35 +01:00
25c5c1b018 Nearly finish
Some checks failed
Build and test backend / Build-backend (pull_request) Failing after 1m31s
Build and test backend / Test-backend (pull_request) Failing after 1m31s
Build and test FrontEnd / Build-frontend (pull_request) Failing after 20s
2024-03-18 17:28:14 +01:00
c35f675a11 Manage course + delete course END
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m3s
Build and test backend / Test-backend (pull_request) Successful in 1m57s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 23s
2024-03-18 15:47:04 +01:00
a9e5e45872 Merge branch 'master' into wal/front/listingUsers
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m5s
Build and test backend / Test-backend (pull_request) Successful in 2m1s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 23s
2024-03-18 14:57:49 +01:00
73d50f3f50 Merge remote-tracking branch 'refs/remotes/origin/wal/front/listingUsers' into wal/front/listingUsers
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m59s
Build and test backend / Test-backend (pull_request) Successful in 2m2s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 26s
2024-03-18 14:52:29 +01:00
0871d2971d manage Course finished 2024-03-18 14:51:27 +01:00
a762b6875d removing cdn
Some checks failed
Build and test backend / Build-backend (pull_request) Failing after 1m34s
Build and test backend / Test-backend (pull_request) Failing after 1m32s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 23s
2024-03-18 13:54:31 +01:00
92079c5a47 Merge remote-tracking branch 'origin/Max/Backend/UserDelete' into wal/front/listingUsers
Some checks failed
Build and test backend / Build-backend (pull_request) Failing after 1m32s
Build and test backend / Test-backend (pull_request) Failing after 1m33s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 23s
2024-03-18 11:59:44 +01:00
753af3874e Login and register ok and starting requests 2024-03-18 11:55:51 +01:00
8ff29ca34e Register
Some checks failed
Build and test backend / Build-backend (pull_request) Successful in 2m3s
Build and test backend / Test-backend (pull_request) Successful in 1m57s
Build and test FrontEnd / Build-frontend (pull_request) Failing after 23s
2024-03-17 23:19:36 +01:00
7e7cec2f6c Merge branch 'Max/Backend/GetUserById' into wal/front/listingUsers
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m2s
Build and test backend / Test-backend (pull_request) Successful in 1m57s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 23s
2024-03-17 22:00:56 +01:00
19b4950be4 Merge branch 'master' into wal/front/listingUsers
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m4s
Build and test backend / Test-backend (pull_request) Successful in 1m57s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 23s
2024-03-17 21:39:04 +01:00
d9307753c4 trop de truc
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m58s
Build and test backend / Test-backend (pull_request) Successful in 1m56s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 23s
2024-03-17 21:38:10 +01:00
b2d0be014c UserList and Student List part1
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m2s
Build and test backend / Test-backend (pull_request) Successful in 1m56s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 23s
2024-03-17 15:59:12 +01:00
210fda0401 Merge branch 'master' into wal/front/listingUsers 2024-03-17 13:33:47 +01:00
b67b25b4a4 Login Finished, add curricula and apps
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m2s
Build and test backend / Test-backend (pull_request) Successful in 2m0s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 23s
2024-03-17 13:24:24 +01:00
5a7934b2a3 Merge branch 'master' into wal/front/listingUsers
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m14s
Build and test backend / Test-backend (pull_request) Successful in 2m7s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 27s
2024-03-16 19:57:53 +01:00
8476563678 profil part3 2024-03-16 19:54:42 +01:00
36fc33c3e9 Profil part.2/?
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m4s
Build and test backend / Test-backend (pull_request) Successful in 2m4s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 25s
2024-03-16 17:01:26 +01:00
36ce5a553b Profil, merge Master and corrections
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m0s
Build and test backend / Test-backend (pull_request) Successful in 1m59s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 25s
2024-03-16 15:21:10 +01:00
a5807148e1 And again we continue
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m59s
Build and test backend / Test-backend (pull_request) Successful in 1m57s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 24s
2024-03-16 15:06:21 +01:00
8d1235be92 again links
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m0s
Build and test backend / Test-backend (pull_request) Successful in 1m58s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 25s
2024-03-16 14:31:44 +01:00
e84e34d735 login 2024-03-16 12:47:49 +01:00
Wal
ca6f676fb7 Merge pull request 'tonitch/front/manageCourses/LinkToBackend' (#125) from tonitch/front/manageCourses/LinkToBackend into wal/front/listingUsers
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m59s
Build and test backend / Test-backend (pull_request) Successful in 1m57s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 26s
Reviewed-on: #125
2024-03-16 12:26:57 +01:00
cc8530621d Merge branch 'master' into tonitch/front/manageCourses/LinkToBackend
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m0s
Build and test backend / Test-backend (pull_request) Successful in 1m56s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 24s
2024-03-16 12:01:44 +01:00
41288258c9 Merge branch 'master' into wal/front/listingUsers
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m1s
Build and test backend / Test-backend (pull_request) Successful in 2m2s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 24s
2024-03-16 11:56:37 +01:00
47a0c97f3d small commit but its for the big merge+ verif psswrd and confirm in login
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m1s
Build and test backend / Test-backend (pull_request) Successful in 2m1s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 25s
2024-03-16 11:52:31 +01:00
d5e4387303 Merge branch 'master' into wal/front/listingUsers
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m59s
Build and test backend / Test-backend (pull_request) Successful in 2m0s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 24s
2024-03-15 22:49:26 +01:00
1903a6c9be "trying functions"
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m4s
Build and test backend / Test-backend (pull_request) Successful in 2m1s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 24s
2024-03-15 22:47:40 +01:00
ae4ad036a8 Merge remote-tracking branch 'origin/master' into tonitch/front/manageCourses/LinkToBackend 2024-03-15 22:32:21 +01:00
3996765c8a Simple hook for when the backend is ready
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m2s
Build and test backend / Test-backend (pull_request) Successful in 1m59s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 23s
2024-03-15 22:25:26 +01:00
b047c4de35 Listing users and students
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 2m2s
Build and test backend / Test-backend (pull_request) Successful in 1m58s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 24s
2024-03-15 20:23:33 +01:00
385640c10e Merge branch 'master' into wal/front/listingUsers
All checks were successful
Build and test backend / Build-backend (pull_request) Successful in 1m59s
Build and test backend / Test-backend (pull_request) Successful in 1m59s
Build and test FrontEnd / Build-frontend (pull_request) Successful in 23s
2024-03-15 15:14:18 +01:00
a0c38a8d59 adding list of user PROTO 2024-03-15 15:12:01 +01:00
35 changed files with 1069 additions and 444 deletions

View File

@ -45,7 +45,7 @@ jobs:
distribution: 'temurin' distribution: 'temurin'
- uses: gradle/gradle-build-action@v3 - uses: gradle/gradle-build-action@v3
- name: building - name: building
run: ./gradlew backend:build run: ./gradlew backend:build -x test
- name: pushing to the server - name: pushing to the server
run: | run: |
echo "${{ secrets.SSH_KEY }}" > key echo "${{ secrets.SSH_KEY }}" > key

2
backend/.gitignore vendored
View File

@ -35,3 +35,5 @@ out/
### VS Code ### ### VS Code ###
.vscode/ .vscode/
/cdn

View File

@ -1,5 +1,6 @@
FROM eclipse-temurin:21-jdk-alpine FROM eclipse-temurin:21-jdk-alpine
VOLUME /tmp VOLUME /tmp
VOLUME /cdn
ENV SPRING_PROFILES_ACTIVE=prod ENV SPRING_PROFILES_ACTIVE=prod
COPY build/libs/backend-0.0.1-SNAPSHOT.jar /app.jar COPY build/libs/backend-0.0.1-SNAPSHOT.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"] ENTRYPOINT ["java", "-jar", "/app.jar"]

View File

@ -25,7 +25,7 @@ dependencies {
implementation("com.kohlschutter.junixsocket:junixsocket-core:2.9.0") implementation("com.kohlschutter.junixsocket:junixsocket-core:2.9.0")
// implementation("org.springframework.session:spring-session-jdbc") // implementation("org.springframework.session:spring-session-jdbc")
developmentOnly("org.springframework.boot:spring-boot-devtools") developmentOnly("org.springframework.boot:spring-boot-devtools")
developmentOnly("org.springframework.boot:spring-boot-docker-compose") // developmentOnly("org.springframework.boot:spring-boot-docker-compose")
runtimeOnly("org.postgresql:postgresql") runtimeOnly("org.postgresql:postgresql")
testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.boot:spring-boot-testcontainers") testImplementation("org.springframework.boot:spring-boot-testcontainers")

View File

@ -64,9 +64,12 @@ public class ApplicationsController {
if (!authServ.isNotIn(new Role[]{Role.Teacher,Role.Secretary,Role.Admin},token)) if (!authServ.isNotIn(new Role[]{Role.Teacher,Role.Secretary,Role.Admin},token))
authorizedApps.add(Applications.ManageCourses); authorizedApps.add(Applications.ManageCourses);
if (!authServ.isNotIn(new Role[]{Role.InscriptionService,Role.Admin},token)) if (!authServ.isNotIn(new Role[]{Role.InscriptionService,Role.Admin},token)){
authorizedApps.add(Applications.Inscription); authorizedApps.add(Applications.Inscription);
authorizedApps.add(Applications.StudentsList);}
if (!authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token)){
authorizedApps.add(Applications.UsersList);}
return authorizedApps; return authorizedApps;
} }
} }

View File

@ -74,7 +74,8 @@ public class CourseController {
public ResponseEntity<Map<String ,Object>> postCourse(@RequestHeader("Authorization") String token, public ResponseEntity<Map<String ,Object>> postCourse(@RequestHeader("Authorization") String token,
@RequestBody Course course) @RequestBody Course course)
{ {
System.out.println(course);
System.out.println(token);
if (authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token)) if (authServ.isNotIn(new Role[]{Role.Secretary,Role.Admin},token))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);

View File

@ -57,7 +57,6 @@ public class InscriptionController {
@RequestHeader("Authorization") String token, @RequestHeader("Authorization") String token,
@RequestBody RequestState state) @RequestBody RequestState state)
{ {
if (authServ.isNotIn(new Role[]{Role.InscriptionService,Role.Admin},token)) if (authServ.isNotIn(new Role[]{Role.InscriptionService,Role.Admin},token))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);

View File

@ -49,12 +49,13 @@ public class MockController {
// user part // user part
User herobrine = new User("brine","hero","admin@admin.com","in your WalLs","ShadowsLand",new Date(0), null,Role.Admin,passwordEncoder.encode("admin")); 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","DaWarudo",new Date(0), null,Role.Student,passwordEncoder.encode("student")); User joe = new User("Mama","Joe","student@student.com","roundabout","England",new Date(0), null,Role.Student,passwordEncoder.encode("student"));
User meh = new User("Inspiration","lackOf","secretary@secretary.com","a Box","the street",new Date(0), null,Role.Secretary,passwordEncoder.encode("secretary")); 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("CthemBalls","Lemme","teacher@teacher.com","lab","faculty",new Date(0), null,Role.Teacher,passwordEncoder.encode("teacher")); 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 lena = new User("Louille","Lena","inscriptionService@InscriptionService.com","no","yes",new Date(0), null,Role.InscriptionService,passwordEncoder.encode("inscriptionService"));
mockUsers = new ArrayList<>(Arrays.asList(herobrine,joe,meh,joke,lena)); mockUsers = new ArrayList<>(Arrays.asList(herobrine,joe,meh,joke,lena,jojo));
userRepo.saveAll(mockUsers); userRepo.saveAll(mockUsers);
@ -71,7 +72,7 @@ public class MockController {
Course progra1 = new Course(5,"Programmation et algorithmique 1",joke); Course progra1 = new Course(5,"Programmation et algorithmique 1",joke);
Course chemistry1 = new Course(12, "Thermochimie",joke); Course chemistry1 = new Course(12, "Thermochimie",joke);
Course psycho1 = new Course(21, "rien faire t'as cru c'est psycho",joke); Course psycho1 = new Course(21, "Neuroreaction of isolated brain cells",joke);
Course commun = new Course(2, "cours commun",joke); Course commun = new Course(2, "cours commun",joke);
courseService.save(progra1); courseService.save(progra1);
@ -91,7 +92,7 @@ public class MockController {
CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,chemistry1)); CurriculumCourseService.save(new CurriculumCourse(chemistryBab1,chemistry1));
InscriptionRequest inscriptionRequest = new InscriptionRequest("helen","prenom","non","helen@gmail.com","america",new Date(),(long) 1,RequestState.Refused,"yes.png","password"); InscriptionRequest inscriptionRequest = new InscriptionRequest("helen","prenom","non","helen@gmail.com","america",new Date(),(long) 1,RequestState.Pending,"yes.png","password");
inscriptionService.save(inscriptionRequest); inscriptionService.save(inscriptionRequest);

View File

@ -122,9 +122,10 @@ public class UserController {
return new ResponseEntity<>(ProtectionService.usersWithoutPasswords(students), HttpStatus.OK); return new ResponseEntity<>(ProtectionService.usersWithoutPasswords(students), HttpStatus.OK);
} }
@DeleteMapping("/user/{id}") @DeleteMapping("/user/{id}")
public ResponseEntity<String> deleteStudent(@RequestHeader("Authorization") String token, @PathVariable Long id){ public ResponseEntity<String> deleteStudent(@RequestHeader("Authorization") String token, @PathVariable Long id){
if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token) || id.equals(authServ.getUserFromToken(token).getRegNo())) if (authServ.isNotIn(new Role[]{Role.Admin,Role.Secretary},token) && !id.equals(authServ.getUserFromToken(token).getRegNo()))
return new UnauthorizedResponse<>(null); return new UnauthorizedResponse<>(null);
User toDelete = userService.getUserById(id); User toDelete = userService.getUserById(id);

View File

@ -123,6 +123,7 @@ public class UserService {
public Iterable<User> getAllStudents(){return userRepo.findAllStudents();} public Iterable<User> getAllStudents(){return userRepo.findAllStudents();}
public User getUserById(long id) { public User getUserById(long id) {
return userRepo.findById(id); return userRepo.findById(id);
} }

View File

@ -15,7 +15,9 @@ public enum Applications {
// teachers and Secretary authorization // teachers and Secretary authorization
ManageCourses, ManageCourses,
UsersList,
// InscriptionService authorization // InscriptionService authorization
Inscription Inscription,
StudentsList
} }

View File

@ -88,14 +88,14 @@ public class UserControllerTest {
tokenService.saveToken(godToken); tokenService.saveToken(godToken);
//Can god post herobrine himself ? //Can god post herobrine himself ?
User herobrine = new User("brine","hero","herobrine@admin.com","in your WalLs","ShadowsLand",new Date(0), null,Role.Student,"test"); User herobrine = new User("brine","hero","herobrine@student.com","in your WalLs","ShadowsLand",new Date(0), null,Role.Student,"test");
with().body(herobrine).contentType(ContentType.JSON).header("Authorization", godToken.getToken()).when().request("POST", "/user").then().statusCode(201); with().body(herobrine).contentType(ContentType.JSON).header("Authorization", godToken.getToken()).when().request("POST", "/user").then().statusCode(201);
userRepository.delete(herobrine); userRepository.delete(herobrine);
//Can noob post herobrine without authorizations (no) //Can noob post herobrine without authorizations (no)
User noob = new User("boon","noob","noob@admintkt.com","everywhere","every",new Date(0), null, Role.Student,"noob"); User noob = new User("boon","noob","noob@student.com","everywhere","every",new Date(0), null, Role.Student,"noob");
Token noobToken = new Token(noob, tokenService.generateNewToken(), new Date()); Token noobToken = new Token(noob, tokenService.generateNewToken(), new Date());
userRepository.save(noob); userRepository.save(noob);
tokenService.saveToken(noobToken); tokenService.saveToken(noobToken);
@ -105,7 +105,7 @@ public class UserControllerTest {
@Test @Test
public void userGetTest(){ public void userGetTest(){
User herobrine = new User("brine","hero","herobrine@admin.com","in your WalLs","ShadowsLand",new Date(0), null,Role.Student,"test"); User herobrine = new User("brine","hero","herobrine@student.com","in your WalLs","ShadowsLand",new Date(0), null,Role.Student,"test");
userRepository.save(herobrine); userRepository.save(herobrine);
Token t = new Token(herobrine, tokenService.generateNewToken(), new Date()); Token t = new Token(herobrine, tokenService.generateNewToken(), new Date());

View File

@ -70,7 +70,7 @@ class TokenServiceTest {
ArrayList<Token> tokenList = new ArrayList<>(); ArrayList<Token> tokenList = new ArrayList<>();
GregorianCalendar gc = new GregorianCalendar(); GregorianCalendar gc = new GregorianCalendar();
User malveillant = new User("mechant", "veutdestoken", "donnezmoidestoken@mail.com", "secret", "secret", null, null, null, "secret"); User malveillant = new User("Cargo", "John", "CargoJ@mail.com", "secret", "secret", null, null, null, "secret");
userRepository.save(malveillant); userRepository.save(malveillant);
for (int i = 0; i < 20; i++){ for (int i = 0; i < 20; i++){

View File

@ -8,6 +8,7 @@
"name": "clyde", "name": "clyde",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@canvasjs/vue-charts": "^1.0.4",
"vite-plugin-top-level-await": "^1.4.1", "vite-plugin-top-level-await": "^1.4.1",
"vue": "^3.4.15", "vue": "^3.4.15",
"vue3-toastify": "^0.2.1" "vue3-toastify": "^0.2.1"
@ -29,6 +30,20 @@
"node": ">=6.0.0" "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": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.19.12", "version": "0.19.12",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",

View File

@ -9,6 +9,7 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@canvasjs/vue-charts": "^1.0.4",
"vite-plugin-top-level-await": "^1.4.1", "vite-plugin-top-level-await": "^1.4.1",
"vue": "^3.4.15", "vue": "^3.4.15",
"vue3-toastify": "^0.2.1" "vue3-toastify": "^0.2.1"

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -26,6 +26,8 @@ app.inscription.requests=Inscription Requests
app.manage.courses=Manage Courses app.manage.courses=Manage Courses
app.language=Language app.language=Language
app.manage.profile=Manage profile app.manage.profile=Manage profile
app.studentList=Students List
app.users=Users
request.moreInfos=More Infos request.moreInfos=More Infos
request.accept=Accept request.accept=Accept
request.refuse=Refuse request.refuse=Refuse
@ -41,10 +43,12 @@ profile.unRegister=Unregister
profile.course.list=Courses list profile.course.list=Courses list
profile.address=Address profile.address=Address
profile.picture=Profile picture profile.picture=Profile picture
profile.change.curriculum=Change curriculum
name=Name name=Name
teacher=Teacher Teacher=Teacher
student=Student Student=Student
secretary=Secretary Secretary=Secretary
curriculum=curriculum Curriculum=curriculum
credits=Credits Credits=Credits
InscriptionService=I.S.
faculty=Faculty faculty=Faculty

View File

@ -26,6 +26,8 @@ app.inscription.requests=Demandes d'Inscription
app.manage.courses=Gérer les cours app.manage.courses=Gérer les cours
app.language=Langue app.language=Langue
app.manage.profile=Gérer le profil app.manage.profile=Gérer le profil
app.studentList=Liste des étudiants
app.users=Utilisateurs
request.moreInfos=Plus d'Infos request.moreInfos=Plus d'Infos
request.accept=Accepter request.accept=Accepter
request.refuse=Refuser request.refuse=Refuser
@ -41,10 +43,12 @@ profile.unRegister=Désinscription
profile.course.list=Liste des cours profile.course.list=Liste des cours
profile.address=Adresse profile.address=Adresse
profile.picture=Photo de profil profile.picture=Photo de profil
profile.change.curriculum=Changer cursus
name=Nom name=Nom
teacher=Enseignant Teacher=Enseignant
student=Etudiant Student=Etudiant
secretary=Secrétaire Secretary=Secrétaire
curriculum=Cursus Curriculum=Cursus
credits=Credits Credits=Credits
InscriptionService=S.I.
faculty=Faculté faculty=Faculté

View File

@ -5,14 +5,26 @@
import { isLogged } from '@/rest/Users.js' import { isLogged } from '@/rest/Users.js'
import { appList, currentView } from '@/rest/apps.js' import { appList, currentView } from '@/rest/apps.js'
var prevURL;
var currentURL = window.location.hash;
window.onhashchange = function() {
prevURL = currentURL;
currentURL = window.location.hash;
}
const Logged = ref(isLogged());
window.addEventListener('hashchange', () => {
if((location.hash === "#/home" && prevURL === "#/login") || (location.hash === "#/home" && prevURL === "#/profil")){
window.location.reload();
}
});
const home=ref(i18n("app.home")) const home=ref(i18n("app.home"))
const notifications=ref(i18n("app.notifications")) const notifications=ref(i18n("app.notifications"))
const settings=ref(i18n("app.settings")) const settings=ref(i18n("app.settings"))
const login=ref(i18n("app.login")) const login=ref(i18n("app.login"))
const active=ref(false) const active=ref(false)
const Logged = ref(isLogged());
const apps = ref([]) const apps = ref([])
appList().then(e => apps.value = e) appList().then(e => apps.value = e)
@ -26,7 +38,7 @@
<ul class="horizontal"> <ul class="horizontal">
<li title=home> <li title=home>
<a class="icon" href="#home"> <a class="icon" href="#home">
<img class="clyde" src="./assets/Clyde.png" style="width: 40px; height: auto; margin-top:4px"> <img class="clyde" src="/Clyde.png" style="width: 40px; height: auto; margin-top:4px">
</a></li> </a></li>
<li title=home> <li title=home>
<a class="icon" href="#home"> <a class="icon" href="#home">
@ -66,18 +78,17 @@
<div class="leftBar"> <div class="leftBar">
<ul class="vertical"> <ul class="vertical">
<li v-for="app in apps"> <li v-for="app in apps">
<a href="app.path"> <a :href="app.path">
<div class="fa-solid" :class="app.icon" style="font-size: 40px;"></div> <div class="fa-solid" :class="app.icon" style="font-size: 40px;"></div>
<div class="text">{{app.text}}</div> <div class="text">{{app.text}}</div>
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
<div class="page"> <div class="page">
<div style=" margin:50px;"> <Suspense>
<component :is="currentView" /> <component :is="currentView" />
</div> </Suspense>
</div> </div>
</div> </div>
</template> </template>
@ -85,6 +96,8 @@
<style scoped> <style scoped>
.container{ .container{
height: 100%;
width: 100%;
display:grid; display:grid;
grid-template-columns:[firstCol-start]70px[firstCol-end secondCol-start]auto[endCol]; grid-template-columns:[firstCol-start]70px[firstCol-end secondCol-start]auto[endCol];
grid-template-rows:[firstRow-start]61px[firstRow-end secondRow-start] auto [endRow]; grid-template-rows:[firstRow-start]61px[firstRow-end secondRow-start] auto [endRow];
@ -97,6 +110,8 @@
.page { .page {
grid-area:page; grid-area:page;
height: 100%;
width: 100%;
place-self:center; place-self:center;
} }

View File

@ -1,10 +1,111 @@
<script setup> <script setup>
import Req from "./Request.vue" import i18n from "@/i18n.js"
import { getRegisters } from '@/rest/ServiceInscription.js' import {ref} from 'vue'
import {validateRegister, getAllRegisters } from '@/rest/ServiceInscription.js'
const requests_example = getRegisters(); const requests = ref(await getAllRegisters());
console.log(requests);
async function upPage(id,review){
await validateRegister(id,review);
requests.value = await getAllRegisters();
}
</script> </script>
<template> <template>
<Req v-for="item of requests_example"/> <div style='display:flex; justify-content:center; min-width:1140px;' v-for="item of requests">
<div class="bodu" v-if="item.state === 'Pending'">
<div class="container">
<div class="id"><a>{{item.id}}</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="accept"><button @click="upPage(item.id,'Accepted')" style="background-color:rgb(0,105,50);">{{i18n("request.accept")}}</button></div>
<div class="refuse"><button @click="upPage(item.id,'Refused')" style="background-color:rgb(105,0,0);">{{i18n("request.refuse")}}</button></div>
</div>
</div>
</div>
</template> </template>
<style scoped>
.container{
color:white;
height:100px;
font-size:20px;
display:grid;
grid-template-columns:10% 14.2% 19% 14.2% 14.2% 14.2% 14.2%;
grid-template-areas:
"id type surname firstname infos accept refuse";
}
.infos {
grid-area:infos;
align-self:center;
}
.accept{
grid-area:accept;
align-self:center;
}
.refuse{
grid-area:refuse;
align-self:center;
}
.titles {
grid-area:titles;
background-color:rgb(215,215,215);
}
.id{
grid-area:id;
margin-left:40px;
align-self:center;
}
.type{
grid-area:type;
align-self:center;
}
.surname{
grid-area:surname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
.firstname{
grid-area:firstname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
button{
font-size:15px;
height:50px;
width:100px;
border:none;
border-radius:20px;
}
.bodu {
margin-top:2%;
width:66%;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
</style>

View File

@ -1,86 +1,115 @@
<script setup> <script setup>
import { ref } from 'vue' import {reactive, ref } from 'vue'
import i18n from '@/i18n.js' import i18n from '@/i18n.js'
import { login , register, disconnect } from '@/rest/Users.js' import { login , register , disconnect, isLogged} from '@/rest/Users.js'
import { getAllCurriculums } from '@/rest/curriculum.js'
import { uploadProfilePicture } from '@/rest/uploads.js' import { uploadProfilePicture } from '@/rest/uploads.js'
import {toast} from 'vue3-toastify'
import 'vue3-toastify/dist/index.css';
const loginPage= ref(true) const loginPage= ref(true)
const page = ref(0) const page = ref(0)
const outputs = reactive({
surname:null,
firstname:null,
password:null,
birthday:null,
email:null,
address:null,
country:null,
curriculum:null,
})
const submitValue= ref(i18n("login.guest.submit")) const submitValue= ref(i18n("login.guest.submit"))
const surname=ref("")
const firstname=ref("")
const password=ref("")
const passwordConfirm=ref("") const passwordConfirm=ref("")
const birthday=ref("")
const email=ref("")
const address=ref("")
const country=ref("")
const curriculum=ref("")
const imageSaved = ref(false) const imageSaved = ref(false)
const ppData = ref(false) const ppData = ref(false)
disconnect() const curricula= await getAllCurriculums();
function goBackHome(){
setTimeout(() => {
window.location.href="#/home";
}, "500");
}
function verifyInputs(pass){
if(pass==passwordConfirm.value){
page.value++;
return toast('Password and Confirm Password are correct.', {
type: "success",});
}
else{
return toast('Password and Confirm Password are different',{type: "error",});
}
}
if (isLogged()){
disconnect();
window.location.reload();}
</script> </script>
<template> <template>
<div class='loginBox'> <div class="setup">
<div v-if="loginPage"> <div v-if="loginPage">
<form @submit.prevent="login(email, password)"class="form"> <div class='loginBox' style="margin-top:30%;">
<form @submit.prevent="login(outputs.email,outputs.password);goBackHome();"class="form">
<h1 style="color:rgb(239,60,168); font-family: sans-serif;"> <h1 style="color:rgb(239,60,168); font-family: sans-serif;">
{{i18n("login.guest.signin")}} {{i18n("login.guest.signin")}}
</h1> </h1>
<div class="inputBox"> <div class="inputBox">
<p>ID / {{i18n("login.guest.email")}}</p> <p>ID / {{i18n("login.guest.email")}}</p>
<input type="text" v-model="email"> <input type="text" v-model="outputs.email">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.password")}}</p> <p>{{i18n("login.guest.password")}}</p>
<input type="password" v-model="password"> <input type="password" v-model="outputs.password">
</div> </div>
<div class="register"> <div class="register">
<a @click="loginPage=!loginPage">{{i18n("login.guest.register")}}</a> <a @click="loginPage=!loginPage">{{i18n("login.guest.register")}}</a>
</div> </div>
<div class="inputBox"> <div class="inputBox" style="margin-bottom:35px;">
<input type="submit" v-model="submitValue"> <input type="submit" v-model="submitValue">
</div> </div>
</form> </form>
</div> </div>
</div>
<div v-else> <div v-else>
<form @submit.prevent="register(firstname, surname, birthday, password, mail, address, country, curriculum)" class="form"> <div class='loginBox' style="margin-top:30%; margin-bottom:50%;">
<form class="form">
<h1 style="color:rgb(239,60,168); font-family: sans-serif; text-align:center;"> <h1 style="color:rgb(239,60,168); font-family: sans-serif; text-align:center;">
{{i18n("login.guest.welcome")}} {{i18n("login.guest.welcome")}}
</h1> </h1>
<div v-if="page === 0"> <div v-if="page === 0">
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.surname")}}</p> <p>{{i18n("login.guest.surname")}}</p>
<input type="text" v-model="surname"> <input type="text" v-model="outputs.surname">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.firstname")}}</p> <p>{{i18n("login.guest.firstname")}}</p>
<input type="text" v-model="firstname"> <input type="text" v-model="outputs.firstname">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.birthday")}}</p> <p>{{i18n("login.guest.birthday")}}</p>
<input type="date" v-model="birthday"> <input type="date" v-model="outputs.birthday">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.password")}}</p> <p>{{i18n("login.guest.password")}}</p>
<input type="password" v-model="password"> <input type="password" v-model="outputs.password">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.confirm")}} {{i18n("login.guest.password")}}</p> <p>{{i18n("login.guest.confirm")}} {{i18n("login.guest.password")}}</p>
<input type="password" v-model="passwordConfirm"> <input type="password" v-model="passwordConfirm">
<!-- TODO: Verify password is same as passwordConfirm -->
</div> </div>
<div class="switchpage"> <div class="switchpage">
<button @click="page++">{{i18n("login.guest.nextpage")}}</button> <button @click="verifyInputs(outputs.password);">{{i18n("login.guest.nextpage")}}</button>
</div> </div>
<div @click="(loginPage=!loginPage) && (page=0)" class="register"> <div @click="(loginPage=!loginPage) && (page=0)" class="register">
@ -90,30 +119,34 @@
<div v-else> <div v-else>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.email")}}</p> <p>{{i18n("login.guest.email")}}</p>
<input type="mail" v-model="email"> <input type="mail" v-model="outputs.email">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.address")}}</p> <p>{{i18n("login.guest.address")}}</p>
<input type="text" v-model="address"> <input type="text" v-model="outputs.address">
</div> </div>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("login.guest.country")}}</p> <p>{{i18n("login.guest.country")}}</p>
<input type="text" v-model="country"> <input type="text" v-model="outputs.country">
</div> </div>
<form novalidate enctype="multipart/form-data" class="inputBox"> <form class="inputBox"novalidate enctype="multipart/form-data">
<p>ProfilePicture</p> <p>{{i18n("profile.picture").toUpperCase()}}</p>
<label class="browser">
Parcourir . . .
<input type="file" :disabled="imageSaved" @change="ppData = uploadProfilePicture($event.target.files); imageSaved = true;" accept="image/*"> <input type="file" :disabled="imageSaved" @change="ppData = uploadProfilePicture($event.target.files); imageSaved = true;" accept="image/*">
</label>
</form> </form>
<div class="inputBox"> <div class="inputBox">
<p>{{i18n("curriculum").toUpperCase()}}</p> <p>{{i18n("Curriculum").toUpperCase()}}</p>
<select v-model="curriculum"> <select v-model="outputs.curriculum">
<option value="Chemistry">Chemistry</option> <option v-for="item in curricula">{{item.curriculumId}}</option>
<option value="Psycho">Psychology</option>
<option value="IT">IT</option>
</select> </select>
</div> </div>
<div style="align-self:center;" class="inputBox"> <div style="align-self:center;" class="inputBox">
<button style="margin-top:25px;" @click="console.log(outputs)">{{i18n("login.guest.submit")}}</button> <button style="margin-top:25px;" @click="register(outputs.firstname, outputs.surname, outputs.birthday, outputs.password, outputs.email, outputs.address, outputs.country, outputs.curriculum, ppData);">
{{i18n("login.guest.submit")}}
</button>
</div> </div>
<div class="switchpage"> <div class="switchpage">
<button @click="page--">{{i18n("login.guest.lastpage")}}</button> <button @click="page--">{{i18n("login.guest.lastpage")}}</button>
@ -125,34 +158,25 @@
</form> </form>
</div> </div>
</div> </div>
</div>
</template> </template>
<style scoped> <style scoped>
.Home{
position:absolute;
display: flex;
z-index: 100;
padding: 8px 16px;
color:rgb(255, 255, 255);
text-decoration: none;
}
.Home:hover{ .setup {
width:40px; margin-left: auto;
background-color: black; margin-right:auto;
border-radius:6px; min-width:400px;
color:white;
transform: translate(0px ,1px);
}
width:25%;
height:60%;
}
.loginBox { .loginBox {
background-color: rgb(24,24,24); background-color: rgb(24,24,24);
width: 400px;
display:flex; display:flex;
justify-content: center; justify-content: center;
padding: 40px; border-radius: 5%;
border-radius: 20px;
box-shadow:0 5px 25px #000000; box-shadow:0 5px 25px #000000;
} }
@ -161,9 +185,8 @@
width:100%; width:100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center;
align-items:center; align-items:center;
gap: 15px; gap: 3%;
} }
@ -171,12 +194,12 @@
width:100%; width:100%;
border: none; border: none;
margin-right: 50px; margin-right: 12.5%;
padding-left: 10px; padding-left: 2.5%;
padding-top:10px; padding-top:2.5%;
padding-bottom:10px; padding-bottom:2.5%;
outline:none; outline:none;
border-radius: 4px; border-radius: 10px;
font-size:1.35em; font-size:1.35em;
} }
@ -191,8 +214,9 @@
.register{ .register{
color:rgb(239,60,168); color:rgb(239,60,168);
width: 100%; width:70%;
display:flex; margin-bottom:20px;
margin-top:20px;
cursor: pointer; cursor: pointer;
} }
@ -221,6 +245,21 @@ input[type=submit],button,select{
} }
input[type=file]{
display:none;
}
.browser{
display:inline-block;
cursor:pointer;
border-radius:20px;
background-color:rgb(239,60,168);
padding:5%;
font-size:1.35em;
font-family:sans-serif;
background:#FFFFFF;
}
button:active ,.switchpage:active{ button:active ,.switchpage:active{
opacity:0.8; opacity:0.8;

View File

@ -1,100 +1,103 @@
<script setup> <script setup>
import i18n from "@/i18n.js" import i18n from "@/i18n.js"
import {ref} from 'vue' import {reactive , ref} from 'vue'
const curriculum=[ import { getCourses,deleteCourse,alterCourse,createCourse } from "@/rest/courses.js"
{ import {getUser, getSelf, getTeachers } from "@/rest/Users.js"
"id": 12,
"name": "Math pour l'info",
"credits": 11,
"faculty": "science",
"teacher": 42,
"Assistants": []},
{
"id": 42,
"name": "Operating Systems",
"credits": 8,
"faculty": "science",
"teacher": 62,
"Assistants": []},
{
"id": 52,
"name": "Fonctionnement des ordinateurs",
"credits": 11,
"faculty": "science",
"teacher": 59,
"Assistants": []},
]
const profList=[42,45,62,84,59] const self = await getSelf();
const curriculum = ref(await getCourses(self.role));
const profList = await getTeachers();
const createMod = ref(false) const createMod = ref(false)
const deleteMod = ref(false) const deleteMod = ref(false)
const editElementID = ref(""); const editElementID = ref("")
function editItem(id){ function editItem(id){
editElementID = id; editElementID = id;
} }
//Juste pour montrer le Create Mode //Juste pour montrer le Create Mode
const pattern = { const pattern = {
"title":null,
"credits":null,
"owner":null,
}
"id": 0, let toModify = Object.assign({},pattern);
"name": null,
"credits": null,
"faculty": null,
"teacher": null,
"Assistants": []}
let toAdd = Object.assign({}, pattern); let toAdd = Object.assign({}, pattern);
function addToCourse (){ async function addToCourse(){
if (curriculum.length>0){
toAdd.id=(curriculum[curriculum.length-1].id)-1;}
else{
toAdd.id=0;
}
let isnull= false; let isnull= false;
for(const [key, value] of Object.entries(toAdd)){ for(const [key, value] of Object.entries(toAdd)){
console.log(toAdd.owner);
if(value === null){ if(value === null){
isnull=true; isnull=true;
} }
} }
if (!isnull){ if (!isnull){
curriculum.push(toAdd); await createCourse(toAdd.title,toAdd.credits,toAdd.owner);
}
toAdd= Object.assign({},pattern); toAdd= Object.assign({},pattern);
curriculum.value = await getCourses(self.role);
}}
function setModify(item){
for(const el in profList){
if(profList[el].regNo === item.owner.regNo){
toModify.owner= profList[el];
}
}
toModify.credits= item.credits;
toModify.title= item.title;
} }
async function patchCourse(course){
for (let element in toModify){
console.log(toModify,1)
console.log(toModify[element],2)
if (element =="owner" && (toModify[element].regNo != course.owner.regNo)){
await alterCourse(course.courseId,{owner:toModify[element].regNo});
}
else if(element == "title" && (toModify[element] != course.title)){
await alterCourse(course.courseId,{title:toModify[element]});
}
else if(element == "credits" && (parseInt(toModify[element]) != course.credits)){
await alterCourse(course.courseId,{credits:parseInt(toModify[element])});
}
}
toModify= Object.assign({},pattern);
curriculum.value = await getCourses(self.role);
}
//Juste pour montrer le Delete Mode //Juste pour montrer le Delete Mode
let toRemove; let toRemove = null;
function removeCourse() { async function removeCourse(course) {
console.log("ok");
console.log(toRemove); await deleteCourse(course.courseId)
let rem=-1; curriculum.value = await getCourses(self.role);
for(const [key, value] of Object.entries(curriculum)){ toRemove = null;
console.log(key); }
console.log(value)
if(value.name === toRemove){
rem = key;
break;
}
}
console.log(rem)
if (rem > -1){
curriculum.splice(rem, 1);}
console.log(curriculum);
}
</script> </script>
<template> <template>
<div class="body"> <div class="body">
<div v-if="!deleteMod && !createMod" class="listTitle buttonGrid"> <div v-if="!deleteMod && !createMod && (self.role !== 'Teacher')" class="listTitle buttonGrid">
<button class="create" @click="createMod = true"> <button class="create" @click="editElementID= '';createMod = true;">
{{i18n("courses.createCourse")}} {{i18n("courses.createCourse")}}
</button> </button>
<button class="delete" @click="deleteMod=true" > <button class="delete" @click="deleteMod=true" >
@ -102,71 +105,66 @@ const curriculum=[
</button> </button>
</div> </div>
<div v-if="createMod"> <div v-if="createMod">
<form class="listElement"> <form class="listElement" style="width:40%;margin-right:auto;margin-left:auto;">
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
{{i18n("name")}} : {{i18n("name")}} :
<input v-model="toAdd.name"> <input v-model="toAdd.title">
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
{{i18n("teacher")}} : {{i18n("Teacher")}} :
<select style="max-width:200px;" class="teacher" v-model="toAdd.teacher"> <select style="max-width:200px;" class="teacher" v-model="toAdd.owner">
<option v-for="item in profList">{{item}}</option> <option v-for="item in profList" :value="item">{{item.lastName}}</option>
</select> </select>
</div> </div>
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
{{i18n("credits")}} : {{i18n("Credits")}} :
<input v-model="toAdd.credits"> <input v-model="toAdd.credits">
</div> </div>
<div style="margin-bottom:20px;">
{{i18n("faculty")}} :
<input v-model="toAdd.faculty">
</div>
<button class="create" @click="createMod=!createMod; addToCourse();"> {{i18n("courses.confirm")}} </button> <button class="create" @click="createMod=!createMod; addToCourse();"> {{i18n("courses.confirm")}} </button>
<button style="float:right;" @click="createMod=!createMod">{{i18n("courses.back")}}</button> <button style="float:right;" @click="createMod=!createMod">{{i18n("courses.back")}}</button>
</form> </form>
</div> </div>
<div v-if="deleteMod"> <div v-if="deleteMod">
<form class="listElement"> <form class="listElement" style="width:40%;margin-right:auto;margin-left:auto;">
<div style="margin-bottom:20px;"> <div style="margin-bottom:20px;">
{{i18n("courses.toDelete")}} : {{i18n("courses.toDelete")}} :
<select style="max-width:200px;" class="teacher" v-model="toRemove"> <select style="max-width:200px;" class="teacher" v-model="toRemove">
<option v-for="item in curriculum">{{item.name}}</option> <option v-for="item in curriculum" :value='item'>{{item.title}}</option>
</select> </select>
</div> </div>
<div style="margin-bottom:20px;"> <button class="delete" @click="deleteMod=!deleteMod; removeCourse(toRemove);"> {{i18n("courses.deleteCourse")}} </button>
{{i18n("login.password")}}:
<input >
</div>
<div style="margin-bottom:20px;">
{{i18n("login.cPassword")}} :
<input>
</div>
<button class="delete" @click="deleteMod=!deleteMod;removeCourse();"> {{i18n("courses.deleteCourse")}} </button>
<button style="float:right;" @click="deleteMod=!deleteMod"> {{i18n("courses.back")}}</button> <button style="float:right;" @click="deleteMod=!deleteMod"> {{i18n("courses.back")}}</button>
</form> </form>
</div> </div>
<div v-if="!createMod && !deleteMod" v-for="item in curriculum" :key="item.name"> <div v-if="!createMod && !deleteMod" v-for="item in curriculum" :key="item.title" style="width:50%;margin-left:auto; margin-right:auto;">
<div style ="padding:15px 15px 15px 15px;"> <div v-if="editElementID !== item.title" style ="padding:15px 15px 15px 15px;">
<button v-if="editElementID !== item.name" @click="editElementID = item.name"> <button @click="editElementID = item.title; setModify(item); ">
{{i18n("courses.modify")}} {{i18n("courses.modify")}}
</button> </button>
<button v-else @click="editElementID= ''"> {{i18n("courses.confirm")}} </button> </div>
<div v-else>
<button @click="editElementID= '';patchCourse(item)"> {{i18n("courses.confirm")}} </button>
<button @click="editElementID= '';"> {{i18n("courses.back")}} </button>
</div> </div>
<div class="listElement" > <div class="listElement" >
<div class="containerElement" v-if="editElementID !== item.name" >
<div class="name"> {{item.name}} </div> <div class="containerElement" v-if="editElementID !== item.title" >
<div class="teacher">{{item.teacher}}</div>
<div class="credits">{{i18n("credits")}}:{{item.credits}}</div> <div class="name"> {{item.title}} </div>
<div class="teacher">{{item.owner.lastName}}</div>
<div class="credits">{{i18n("Credits")}}:{{item.credits}}</div>
</div> </div>
<div class="containerElement"v-else> <div class="containerElement"v-else>
<input style="max-width:200px;" class="name" v-model="item.name"> <input style="max-width:200px;" class="name" v-model="toModify.title">
<select style="max-width:200px;" class="teacher" v-model="item.teacher"> <select v-if="self.role === 'Secretary'" style="max-width:200px;" class="teacher" v-model="toModify.owner">
<option v-for="item in profList">{{item}}</option> <option v-for="(item,index) in profList" :value='item'>{{item.lastName}}</option>
</select> </select>
<input style="max-width:100px;"class="credits" v-model="item.credits"> <div v-else class="teacher">{{item.owner.lastName}}</div>
<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>
</div> </div>
@ -176,17 +174,27 @@ const curriculum=[
<style scoped> <style scoped>
.body { .body {
width:100%; width:100%;
margin-bottom:10px; margin-top:3.5%;
} }
.infosContainer {
min-width:350px;
padding-bottom:50px;
border:2px solid black;
font-size:25px;
color:white;
padding:20px;
background-color:rgb(50,50,50);
border-radius:20px;
}
.containerElement{ .containerElement{
justify-content:center; justify-content:center;
display:grid; display:grid;
grid-template-columns:350px 350px 200px; grid-template-columns:38.8% 38.8% 22.4%;
grid-template-areas: grid-template-areas:
"name teacher credits"; "name teacher credits";
column-gap:10px; column-gap:10px; }
}
.name { .name {
grid-area:name; grid-area:name;
@ -204,6 +212,7 @@ const curriculum=[
} }
.listElement{ .listElement{
min-width:625px;
border:2px solid black; border:2px solid black;
font-size:25px; font-size:25px;
color:white; color:white;
@ -211,6 +220,7 @@ const curriculum=[
background-color:rgb(50,50,50); background-color:rgb(50,50,50);
border-radius:20px; border-radius:20px;
margin-bottom:10px; margin-bottom:10px;
} }
.modify{ .modify{
@ -259,10 +269,11 @@ const curriculum=[
} }
.listTitle{ .listTitle{
min-width:380px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width:400px; width:25%;
margin-left:auto; margin-left:auto;
margin-right:auto; margin-right:auto;
border:2px solid black; border:2px solid black;
@ -270,7 +281,8 @@ const curriculum=[
color:white; color:white;
padding:20px; padding:20px;
background-color:rgb(50,50,50); background-color:rgb(50,50,50);
border-radius:20px;margin-bottom:10px; border-radius:20px;
margin-bottom:10px;
button:hover{ button:hover{
opacity:0.8; opacity:0.8;

View File

@ -1,108 +1,129 @@
<script setup> <script setup>
import {reactive, ref} from 'vue' import {reactive, ref } from 'vue'
import {getUser} from '../rest/Users.js' import {getSelf,alterSelf,disconnect,deleteUser} from '../rest/Users.js'
import {getSelfCurriculum, getAllCurriculums} from '../rest/curriculum.js'
import {getCourses} from "../rest/courses.js"
import i18n from "@/i18n.js" import i18n from "@/i18n.js"
/* import { uploadProfilePicture } from '@/rest/uploads.js'
const user = getUser();
*/
const user =reactive({
profilPicture:"../assets/clyde.png",
lastName:"Ghost",
firstName:"Clyde",
role:"student",
address: "Radiator Springs",
email:"ClydeGhost@gmail.com",
curriculum:[
{
"id": 12,
"name": "Math pour l'info",
"credits": 11,
"faculty": "science",
"teacher": 42,
"Assistants": []},
{
"id": 42,
"name": "Fonctionnement des ordinateurs",
"credits": 11,
"faculty": "science",
"teacher": 42,
"Assistants": []},
], const user = ref(await getSelf());
option:"IT", const UserCurriculum = ref("");
degree:"BAC1", const curricula = ref (await getAllCurriculums());
password:"CeciEstUnMotDePasse123", if(user.value.role === "Student"){
}) UserCurriculum.value = await getSelfCurriculum();
}
/* if(user.role === "Teacher"){
Teacher user UserCurriculum.value = await getCourses("Teacher");
const user =reactive({ }
profilPicture:"../assets/clyde.png", const modif = ref(false);
lastName:"Ghost", const curric = ref(false);
firstName:"Clyde", const reg = ref(false);
role:"teacher",
address: "Radiator Springs",
email:"ClydeGhost@gmail.com",
coursesOwned:[
{
"id": 12,
"name": "Math pour l'info",
"faculty": "science",
"teacher": 42,
"Assistants": []},
{
"id": 42,
"name": "Fonctionnement des ordinateurs",
"credits": 11,
"faculty": "science",
"teacher": 42,
"Assistants": []},
], const pattern = {
faculty:"Science", profilPictureUrl:null,
})*/ email:null,
address:null,
password:null,
};
const modif = ref(false); const patternInfos ={
email: null,
password: null,
passwordConfirm:null,
id:null,
}
const toModify = Object.assign({}, user);
let toModify= Object.assign({}, pattern);
let personnalInfos = Object.assign({}, patternInfos);
function resetInputs(inputs,list){
inputs=Object.assign({},list);
}
async function ChangeInfos(){
for (let element in toModify){
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]});
}
else if(element == "address" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{address : toModify[element]});
}
else if(element == "password" && (toModify[element] !== null)){
await alterSelf(user.value.regNo,{password : toModify[element]});
}
}
toModify= Object.assign({},pattern);
user.value = await getSelf()
}
function setModify(item){
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");
}
function getPP(){
if(user.value.profilePictureUrl === null){
return "/Clyde.png"
}
return user.profilePictureUrl
}
</script> </script>
<template> <template>
<div class="body"> <div class="body">
<div class="container"> <div class="container">
<div class="profilPic"> <div class="profilPic">
<img class="subContainter" src="../assets/Clyde.png"> <img class="subContainter" :src=getPP()>
</div> </div>
<div class="globalInfos"> <div class="globalInfos">
<div v-if="modif==false" class="infosContainer" > <div v-if="modif==false && curric==false && reg==false " class="infosContainer" >
<div> <div>
{{user.firstName}} {{user.lastName.toUpperCase()}} {{user.firstName}} {{user.lastName}}
</div> </div>
<div> <div>
E-mail: {{user.email}} E-mail: {{user.email}}
</div> </div>
<div v-if="user.role==='student'"> <div v-if="user.role==='Student'">
{{user.option}} {{i18n(user.role).toUpperCase()}} {{user.option}} {{i18n(user.role)}}
</div> </div>
<div v-else> <div v-else>
{{i18n("faculty")}}: {{user.faculty}} Role: {{i18n((user.role))}}
Role: {{i18n(user.role).toUpperCase()}}
</div> </div>
<div> <div>
<button @click="modif=!modif"> {{i18n("profile.modify.data")}} </button> <button @click="modif=!modif; setModify(user)"> {{i18n("profile.modify.data")}} </button>
</div> </div>
<div v-if="(user.role==='student')"> <div v-if="(user.role==='Student')">
<button>{{i18n("profile.reRegister")}}</button> <button @click="reg=!reg">{{i18n("profile.reRegister")}}</button>
<button style="float:right;background-color:rgb(150,0,0);">{{i18n("profile.unRegister")}}</button> <button @click="unRegister()" style="float:right;background-color:rgb(150,0,0);">{{i18n("profile.unRegister")}}</button>
</div>
<div v-if="(user.role==='Student')">
<button @click="curric=!curric">{{i18n("profile.change.curriculum")}}</button>
</div> </div>
</div> </div>
<div v-else class="infosContainer"> <div v-else-if="modif" class="infosContainer">
<div> <div>
{{i18n("profile.picture")}}: {{i18n("profile.picture")}}:
<input type="file"> <input type="file" @change="user.profilPicture = uploadProfilePicture($event.target.files);" accept="image/*">
</div> </div>
<div> <div>
E-mail: E-mail:
@ -110,7 +131,42 @@ const toModify = Object.assign({}, user);
</div> </div>
<div> <div>
{{i18n("profile.address")}}: {{i18n("profile.address")}}:
<input type="text" v-model="toModify.address"> <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" v-model="toModify.passwordConfirm">
</div>
<div>
<button @click=" modif=!modif; ChangeInfos();">{{i18n("courses.confirm")}}</button>
<button @click="modif=!modif; resetInputs(toModify,pattern);" style="float:right;">{{i18n("courses.back")}}</button>
</div>
</div>
<div v-else-if="curric" class="infosContainer">
<div style="height:40px;">
{{i18n("Curriculum")}}:
<select v-model="curriculum" >
<option v-for="item in curricula" style="font-size:20px;" :value="item">{{item.option}}</option>
</select>
</div>
<div>
<button @click=" curric=!curric;">{{i18n("courses.confirm")}}</button>
<button @click="curric=!curric; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button>
</div>
</div>
<div v-else-if="reg" class="infosContainer">
<div>
E-mail:
<input type="mail" v-model="toModify.email" />
</div>
<div>
ID :
<input type="text" v-model="toModify.id">
</div> </div>
<div> <div>
{{i18n("login.password")}}: {{i18n("login.password")}}:
@ -120,22 +176,25 @@ const toModify = Object.assign({}, user);
{{i18n("login.cPassword")}}: {{i18n("login.cPassword")}}:
<input type="password" id="confirm"> <input type="password" id="confirm">
</div> </div>
<div>
<button @click=" modif=!modif">{{i18n("courses.confirm")}}</button>
</div>
</div>
</div>
<div v-if="modif==false"class="moreInfos">
<div v-if="(user.role==='student')"> <div>
<button @click=" reg=!reg;">{{i18n("courses.confirm")}}</button>
<button @click=" reg=!reg; resetInputs(personnalInfos,patternInfos);" style="float:right;">{{i18n("courses.back")}}</button>
</div>
</div>
</div>
<div v-if="modif==false && curric==false && reg==false "class="moreInfos">
<div v-if="(user.role ==='Student')">
<div class="listTitle"> <div class="listTitle">
{{i18n("profile.course.list")}} {{i18n("profile.course.list")}}
</div> </div>
<div class="listElement " <div class="listElement" v-for="item in UserCurriculum.courses">
v-for="item in user.curriculum">
<div class=" containerElement"> <div class=" containerElement">
<div class="name"> {{item.name}} </div> <div class="name"> {{item.title}} </div>
<div class="teacher">{{item.teacher}}</div> <div class="teacher">{{item.owner.lastName}}</div>
<div class="credits">Credits:{{item.credits}}</div> <div class="credits">Credits:{{item.credits}}</div>
</div> </div>
</div> </div>
@ -144,18 +203,6 @@ const toModify = Object.assign({}, user);
<div> <div>
</div> </div>
<div v-if="(user.role==='teacher')">
<div class="listTitle">
{{i18n("profile.course.list")}}
</div>
<div class="listElement " v-for="item in user.coursesOwned">
{{item.name}}
</div>
</div>
<div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -163,18 +210,19 @@ const toModify = Object.assign({}, user);
<style scoped> <style scoped>
.container{ .container{
min-width:675px;
display:grid; display:grid;
grid-template-columns:200px 900px; grid-template-columns:10vw 50vw;
grid-template-rows:200px auto; grid-template-rows:200px auto;
column-gap:30px; column-gap:2.7%;
row-gap:25px; row-gap:45px;
grid-template-areas: grid-template-areas:
"profilPic globalInfos" "profilPic globalInfos"
"minfos minfos"; "minfos minfos";
} }
.profilPic{ .profilPic{
width:100%;
grid-area:profilPic; grid-area:profilPic;
} }
@ -195,13 +243,17 @@ const toModify = Object.assign({}, user);
grid-area:minfos; grid-area:minfos;
} }
.body { .body {
min-width:960px;
width:100%; width:100%;
margin-bottom:10px; display:flex;
align-items:center;
justify-content:center;
margin-top:5%;
} }
.containerElement{ .containerElement{
justify-content:center; justify-content:center;
display:grid; display:grid;
grid-template-columns:350px 350px 200px; grid-template-columns:38.8% 38.8% 22.4%;
grid-template-areas: grid-template-areas:
"name teacher credits"; "name teacher credits";
column-gap:10px; column-gap:10px;
@ -224,10 +276,11 @@ const toModify = Object.assign({}, user);
} }
.listTitle{ .listTitle{
min-width:197px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
width:200px; width:8vw;
margin-left:auto; margin-left:auto;
margin-right:auto; margin-right:auto;
border:2px solid black; border:2px solid black;
@ -239,6 +292,7 @@ const toModify = Object.assign({}, user);
} }
.listElement{ .listElement{
min-width:625px;
border:2px solid black; border:2px solid black;
font-size:25px; font-size:25px;
color:white; color:white;
@ -249,6 +303,7 @@ const toModify = Object.assign({}, user);
} }
.infosContainer { .infosContainer {
min-width:350px;
padding-bottom:50px; padding-bottom:50px;
border:2px solid black; border:2px solid black;
font-size:25px; font-size:25px;

View File

@ -1,109 +0,0 @@
<script setup>
import i18n from "@/i18n.js"
const props = defineProps({
id: Number,
type: String,
lastName: String,
firstName: String,
address: String,
country: String,
birthDate: String,
curriculum:String,
degree:String,});
</script>
<template>
<div class="bodu">
<div class="container">
<div class="id"><a>{{id}}</a></div>
<div class="type"><a>{{type}}</a></div>
<div class="surname"><a>{{lastName}}</a></div>
<div class="firstname"><a>{{firstName}}</a></div>
<div class="infos"><button style="background-color:rgb(105,05,105);" >{{i18n("request.moreInfos")}} </button></div>
<div class="accept"><button style="background-color:rgb(0,105,50);">{{i18n("request.accept")}}</button></div>
<div class="refuse"><button style="background-color:rgb(105,0,0);">{{i18n("request.refuse")}}</button></div>
</div>
</div>
</template>
<style scoped>
.container{
color:white;
height:100px;
font-size:20px;
display:grid;
grid-template-columns:[firstCol-start]100px[firstCol-end secondCol-start]150px[secondCol-end thirdCol-start]200px[thirdCol-end fourthCol-start]150px[fourthCol-end]150px[fifthCol-end]150px[sixthCol-end]150px[endCol];
grid-template-areas:
"id type surname firstname infos accept refuse";
column-gap:10px;
}
.infos {
grid-area:infos;
align-self:center;
}
.accept{
grid-area:accept;
align-self:center;
}
.refuse{
grid-area:refuse;
align-self:center;
}
.titles {
grid-area:titles;
background-color:rgb(215,215,215);
}
.id{
grid-area:id;
margin-left:40px;
align-self:center;
}
.type{
grid-area:type;
align-self:center;
}
.surname{
grid-area:surname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
.firstname{
grid-area:firstname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
button{
font-size:15px;
height:50px;
width:100px;
border:none;
border-radius:20px;
}
.bodu {
width:100%;
margin-bottom:10px;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
</style>

View File

@ -0,0 +1,236 @@
<!----------------------------------------------------
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";
const input = ref("");
const statsOf = ref("");
const statsBy = ref("");
let chart;
const jsonMockViewsByYears= [
{label: "2004", y:4},
{label: "2005", y:99},
{label: "2007", y:555},
{label: "2009", y:22},
{label: "2011", y:1666},
]
function inputKeyUp() {
let filter, ul, li, a, txtValue;
filter = input.value.toUpperCase();
if (document.getElementById("myUL") != null) {
ul = document.getElementById("myUL");
li = ul.getElementsByTagName("li");
// Loop through all list items, and hide those who don't match the search query
for (let i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
txtValue = a.textContent || a.innerText;
if (txtValue.toUpperCase().indexOf(filter) > -1) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
}
const options = reactive({
backgroundColor:null,
theme: "light2",
animationEnabled: true,
title: {
fontColor: "white",
text : "please select options",
},
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",
text: statsOf.value + " By "+ statsBy.value,
}
if (statsOf.value === "views" && statsBy.value === "years") {
options.data[0].dataPoints = jsonMockViewsByYears;
}
options.title.text = statsOf.value + " By "+ statsBy.value;
chart.render()
}
</script>
<template>
<div id="main">
<div id="profilePicture">
<img src="/Clyde.png" />
</div>
<div id="researcherInfos">
<div class="surrounded">John Doe</div>
<div class="surrounded">Orcid : 12144-2144-12336-B</div>
<div class="surrounded">Email : John.Doe@umons.ac.be</div>
<div class="surrounded">
site :
<a href="http://localhost:5173" style="color: #007aff">here</a>
</div>
<div class="surrounded">Domain : physics, IT</div>
<div id="coAuthorList" class="surrounded">Co-authors list : D</div>
</div>
<div id="stats">
<div class="surrounded">
Stat type :
<select @change="update()" id="stats-select" v-model="statsOf">
<option value="views">Views</option>
<option value="co-authors">Co-authors</option>
<option value="articles">Articles</option>
<option value="language">Languages</option>
</select>
</div>
<div class="surrounded">
Class by:
<select @change="update()" id="classed-select" v-model="statsBy">
<option selected="selected" value="years">Years</option>
<option value="months">Months</option>
<option value="topics">Topics</option>
</select>
</div>
<div id="statsPie">
<CanvasJSChart :options="options" id=chart @chart-ref="c => chart = c "/>
</div>
</div>
<div id="articles">
<input
type="text"
id="search-input"
@keyup="inputKeyUp()"
placeholder="search articles"
v-model="input"
/>
<ul id="myUL">
<li><a href="#">Adele</a></li>
<li><a href="#">Agnes</a></li>
<li><a href="#">Billy</a></li>
<li><a href="#">Bob</a></li>
<li><a href="#">Calvin</a></li>
<li><a href="#">Christina</a></li>
<li><a href="#">Cindy</a></li>
</ul>
</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;
align-self: center;
text-align: center;
}
#statsPie {
}
#articles {
background-color: orange;
}
#search-input {
width: 60%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid #ddd;
margin-bottom: 12px;
}
#myUL {
list-style-type: none;
padding: 0;
margin: 0;
}
#myUL li a {
border: 1px solid #ddd;
/* Add a border to all links */
margin-top: -1px;
/* Prevent double borders */
background-color: #f6f6f6;
/* Grey background color */
padding: 12px;
/* Add some padding */
text-decoration: none;
/* Remove default text underline */
font-size: 18px;
/* Increase the font-size */
color: black;
/* Add a black text color */
display: block;
/* Make it into a block element to fill the whole list */
}
#myUL li a:hover:not(.header) {
background-color: #eee;
}
#Chart{
width: "100%";
height: "100%";
}
</style>

View File

@ -0,0 +1,84 @@
<script setup>
import i18n from "@/i18n.js"
import { reactive } from 'vue'
import { getStudents } from '../rest/Users.js'
const users = await getStudents();
</script>
<template style="margin-top:5%;">
<div style="display:flex; justify-content:center; " v-for="item in users">
<div class="bodu">
<div class="container">
<div class="status"><a style="margin-left:30px">{{item.status}}</a></div>
<div class="option"><a>{{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>
</div>
</div>
</template>
<style scoped>
.container{
color:white;
height:100px;
font-size:30px;
display:grid;
grid-template-columns:21.7% 21.7% 21.7% 21.7% 13.1%;
grid-template-areas:
"status option surname firstname infos";
}
.infos {
grid-area:infos;
align-self:center;
}
.option{
grid-area:option;
align-self:center;
}
.status{
grid-area:status;
align-self:center;
}
.surname{
grid-area:surname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
.firstname{
grid-area:firstname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
button{
font-size:15px;
height:50px;
width:75%;
border:none;
border-radius:20px;
}
.bodu {
margin-top:2%;
width:66%;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
</style>

View File

@ -0,0 +1,81 @@
<script setup>
import i18n from "@/i18n.js"
import { reactive } from 'vue'
import { getAllUsers } from '../rest/Users.js'
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 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>
</div>
</div>
</template>
<style scoped>
.container{
color:white;
height:100px;
font-size:30px;
display:grid;
grid-template-columns:27.7% 27.7% 27.7% 16.9%;
grid-template-areas:
"role surname firstname infos";
}
.infos {
grid-area:infos;
align-self:center;
}
.role {
grid-area:role;
align-self:center;
}
.surname{
grid-area:surname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
.firstname{
grid-area:firstname;
align-self:center;
white-space: nowrap;
overflow: hidden;
text-overflow:ellipsis;
}
button{
font-size:15px;
height:50px;
width:75%;
border:none;
border-radius:20px;
}
.bodu {
margin-top:2%;
width:66%;
border:2px solid black;
border-radius:9px;
background-color:rgb(50,50,50);
}
</style>

View File

@ -1,4 +1,11 @@
body { body {
background-color: rgb(53, 25, 60); background-color: rgb(53, 25, 60);
margin:0; margin:0;
width: 100vw;
height: 100vh;
}
#app {
width: 100%;
height: 100%;
} }

View File

@ -4,5 +4,8 @@ import 'https://kit.fontawesome.com/fb3bbd0a95.js'
import { createApp } from 'vue' import { createApp } from 'vue'
import App from './App.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');

View File

@ -33,9 +33,13 @@ export async function getRegisters(id){
return restGet("/request/register") return restGet("/request/register")
} }
export async function getAllRegisters(){
return restGet("/requests/register")
}
/** /**
* Change the state of a requests. * Change the state of a requests.
*/ */
export async function validateRegister(id, state){ export async function validateRegister(id, state){
return restPatch("/request/register/" + id, {state: state}); return restPatch("/request/register/" + id, state);
} }

View File

@ -1,4 +1,4 @@
import { restGet, restPost } from './restConsumer.js' import { restGet, restPost, restPatch, restDelete} from './restConsumer.js'
import { getCookie, setCookie } from '@/utils.js' import { getCookie, setCookie } from '@/utils.js'
export async function login(user, pass, exp){ export async function login(user, pass, exp){
@ -26,16 +26,17 @@ export function disconnect(){
* @param curriculum * @param curriculum
* @param imageId id of the image in database returned when uploaded * @param imageId id of the image in database returned when uploaded
*/ */
export async function register(firstname, lastname, birthDate, password, email, address, country, curriculum, imageId){ export async function register(firstname, lastname, birthDate, password, email, address, country, curriculumId, imageId){
return restPost("/register", { return restPost("/register", {
firstname: firstname, firstName: firstname,
lastname: lastname, lastName: lastname,
birthDate: birthDate, birthDate: birthDate,
password: password, password: password,
email: email, email: email,
address: address, address: address,
country: country, country: country,
curriculum: curriculum curriculumId: curriculumId,
profilePictureUrl: imageId,
}); });
} }
@ -72,7 +73,7 @@ export async function createUser(firstname, lastname, birthDate, email, address,
* if the user is not authenticated. then an empty array should be returned * if the user is not authenticated. then an empty array should be returned
*/ */
export async function getUser(id){ export async function getUser(id){
const endpoint = "/user" + id != null ? "/" + id : ""; const endpoint = "/user/" + id;
return restGet(endpoint); return restGet(endpoint);
} }
@ -102,7 +103,23 @@ export async function getAllUsers(){
return restGet("/users"); return restGet("/users");
} }
/**
* Return the list of teachers
*
* @return a list of teachers
* each elements is of the form
* - id
* - name
* - role
*/
export async function getTeachers(){
return restGet("/teachers")
}
export async function getStudents(){
return restGet("/students")
}
/** /**
* Get informations about yourself * Get informations about yourself
* - RegNo * - RegNo
@ -123,6 +140,13 @@ export async function getSelf(){
* - Adress * - Adress
* - Password * - Password
*/ */
export async function alterSelf(data){ export async function alterSelf(id,data){
return restPatch("/user", data); console.log(data)
return restPatch("/user/"+id, data);
}
export async function deleteUser(id){
return restDelete("/user/" + id)
} }

View File

@ -7,12 +7,18 @@ import LoginPage from '@/Apps/Login.vue'
import Inscription from "@/Apps/Inscription.vue" import Inscription from "@/Apps/Inscription.vue"
import Profil from "@/Apps/Profil.vue" import Profil from "@/Apps/Profil.vue"
import Courses from "@/Apps/ManageCourses.vue" import Courses from "@/Apps/ManageCourses.vue"
import Users from "@/Apps/UsersList.vue"
import Students from "@/Apps/StudentsList.vue"
import ResearcherProfile from "@/Apps/ScientificPublications/ResearcherProfile.vue";
const apps = { const apps = {
'/login': LoginPage, '/login': LoginPage,
'/inscription': Inscription, '/inscription': Inscription,
'/profil': Profil, '/profil': Profil,
'/manage-courses' : Courses, '/manage-courses' : Courses,
'/users-list' : Users,
'/students-list' : Students,
'/researcher-profile' : ResearcherProfile,
} }
const appsList = { const appsList = {
@ -22,6 +28,8 @@ const appsList = {
'Schedule': { path: '#/schedule', icon: 'fa-calendar-days', text: i18n("app.schedules") }, 'Schedule': { path: '#/schedule', icon: 'fa-calendar-days', text: i18n("app.schedules") },
'Inscription': { path: '#/inscription', icon: 'fa-users', text: i18n("app.inscription.requests") }, 'Inscription': { path: '#/inscription', icon: 'fa-users', text: i18n("app.inscription.requests") },
'ManageCourses': { path: '#/manage-courses', icon: 'fa-book', text: i18n("app.manage.courses") }, 'ManageCourses': { path: '#/manage-courses', icon: 'fa-book', text: i18n("app.manage.courses") },
'StudentsList':{ path: '#/students-list',icon: 'fa-users',text: i18n("app.studentList")},
'UsersList':{ path: '#/users-list',icon: 'fa-users',text: i18n("app.users")},
} }
const currentPath = ref(window.location.hash) const currentPath = ref(window.location.hash)

View File

@ -7,8 +7,10 @@ import { restGet, restPost, restDelete, restPatch } from './restConsumer.js'
/** /**
* Create a new course * Create a new course
*/ */
export async function createCourse(name, credits, faculty, teacher, assistants){ export async function createCourse(name, credits, owner){
return restPost("/courses", {name: name, credits: credits, faculty: faculty, teacher: teacher, assistants: assistants} ) console.log(owner);
return restPost("/course", {title: name, credits: credits, owner} )
} }
/** /**
@ -34,6 +36,25 @@ export async function getCourse(id){
return restGet("/course/" + id); return restGet("/course/" + id);
} }
/**
* Get the list of courses to display on secretary's option
*
* @return list of courses of the form
* - id
* - name
* - credits
* - facutly
* - teacher
* - Assistants
*/
export async function getCourses(role){
if(role==="Teacher"){
return restGet("/courses/owned")
}
return restGet("/courses")
}
/** /**
* Change the options of a course * Change the options of a course
* *

View File

@ -2,7 +2,7 @@
* curriculum API * curriculum API
*/ */
import { restGet, restPostn, restDelete, restPatch } from './restConsumer.js' import { restGet, restPost, restDelete, restPatch } from './restConsumer.js'
/** /**
* Create a new curriculum (bundle of courses) * Create a new curriculum (bundle of courses)
@ -19,6 +19,10 @@ export async function deletecurriculum(id){
return restDelete("/curriculum/" + id); return restDelete("/curriculum/" + id);
} }
export async function getAllCurriculums(){
return restGet("/curriculums");
}
/** /**
* Get informations on a particular curriculum * Get informations on a particular curriculum
* *
@ -39,3 +43,8 @@ export async function getcurriculum(id){
export async function altercurriculum(id, courses){ export async function altercurriculum(id, courses){
return restPatch("/curriculum/" + id, courses); return restPatch("/curriculum/" + id, courses);
} }
export async function getSelfCurriculum(){
return restGet("/curriculum");
}

View File

@ -16,8 +16,8 @@ export async function restPostFile(endPoint, file){
return await _rest(endPoint, {method: "POST", credentials: 'include', body: file, headers: headers }); return await _rest(endPoint, {method: "POST", credentials: 'include', body: file, headers: headers });
} }
export async function restDelete(endPoint, data) { export async function restDelete(endPoint) {
return await _rest(endPoint, {method: "DELETE", credentials: 'include', body: JSON.stringify(data)}); return await _rest(endPoint, {method: "DELETE"});
} }
export async function restPatch(endPoint, data) { export async function restPatch(endPoint, data) {