Skip to content
Snippets Groups Projects
Commit a2883d01 authored by bedran.sezer's avatar bedran.sezer
Browse files

adding list of exercise for student

parent 8d25d20a
No related branches found
No related tags found
No related merge requests found
Showing
with 288 additions and 30 deletions
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
</profile>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/dojoweb.iml" filepath="$PROJECT_DIR$/.idea/dojoweb.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectTasksOptions" suppressed-tasks="SCSS" />
</project>
\ No newline at end of file
...@@ -11,16 +11,16 @@ ...@@ -11,16 +11,16 @@
"dependencies": { "dependencies": {
"@angular/animations": "^14.2.0", "@angular/animations": "^14.2.0",
"@angular/cdk": "^14.2.0", "@angular/cdk": "^14.2.0",
"@angular/common": "^14.2.0", "@angular/common": "^14.3.0",
"@angular/compiler": "^14.2.0", "@angular/compiler": "^14.2.0",
"@angular/core": "^14.2.0", "@angular/core": "^14.2.0",
"@angular/elements": "^14.2.0", "@angular/elements": "^14.2.0",
"@angular/forms": "^14.2.0", "@angular/forms": "^14.3.0",
"@angular/localize": "^14.2.0", "@angular/localize": "^14.2.0",
"@angular/material": "^14.2.0", "@angular/material": "^14.2.0",
"@angular/platform-browser": "^14.2.0", "@angular/platform-browser": "^14.2.0",
"@angular/platform-browser-dynamic": "^14.2.0", "@angular/platform-browser-dynamic": "^14.2.0",
"@angular/router": "^14.2.0", "@angular/router": "^14.3.0",
"ajv": "8.11.0", "ajv": "8.11.0",
"arrive": "2.4.1", "arrive": "2.4.1",
"bootstrap": "4.6.1", "bootstrap": "4.6.1",
...@@ -46,12 +46,12 @@ ...@@ -46,12 +46,12 @@
"@angular/cli": "~14.2.7", "@angular/cli": "~14.2.7",
"@angular/compiler-cli": "^14.2.0", "@angular/compiler-cli": "^14.2.0",
"@angular/language-service": "14.2.0", "@angular/language-service": "14.2.0",
"@types/bootstrap": "4.5.0", "@types/bootstrap": "^4.5.0",
"@types/chartist": "0.11.1", "@types/chartist": "0.11.1",
"@types/google.maps": "3.47.4", "@types/google.maps": "3.47.4",
"@types/jasmine": "~4.0.0", "@types/jasmine": "~4.0.0",
"@types/jasminewd2": "~2.0.10", "@types/jasminewd2": "~2.0.10",
"@types/jquery": "3.5.6", "@types/jquery": "^3.5.6",
"@types/node": "^17.0.21", "@types/node": "^17.0.21",
"codelyzer": "6.0.2", "codelyzer": "6.0.2",
"jasmine-core": "~4.4.0", "jasmine-core": "~4.4.0",
......
...@@ -19,16 +19,16 @@ ...@@ -19,16 +19,16 @@
"dependencies": { "dependencies": {
"@angular/animations": "^14.2.0", "@angular/animations": "^14.2.0",
"@angular/cdk": "^14.2.0", "@angular/cdk": "^14.2.0",
"@angular/common": "^14.2.0", "@angular/common": "^14.3.0",
"@angular/compiler": "^14.2.0", "@angular/compiler": "^14.2.0",
"@angular/core": "^14.2.0", "@angular/core": "^14.2.0",
"@angular/elements": "^14.2.0", "@angular/elements": "^14.2.0",
"@angular/forms": "^14.2.0", "@angular/forms": "^14.3.0",
"@angular/localize": "^14.2.0", "@angular/localize": "^14.2.0",
"@angular/material": "^14.2.0", "@angular/material": "^14.2.0",
"@angular/platform-browser": "^14.2.0", "@angular/platform-browser": "^14.2.0",
"@angular/platform-browser-dynamic": "^14.2.0", "@angular/platform-browser-dynamic": "^14.2.0",
"@angular/router": "^14.2.0", "@angular/router": "^14.3.0",
"ajv": "8.11.0", "ajv": "8.11.0",
"arrive": "2.4.1", "arrive": "2.4.1",
"bootstrap": "4.6.1", "bootstrap": "4.6.1",
...@@ -46,22 +46,21 @@ ...@@ -46,22 +46,21 @@
"popper.js": "1.16.1", "popper.js": "1.16.1",
"rxjs": "~7.5.0", "rxjs": "~7.5.0",
"tslib": "^2.3.0", "tslib": "^2.3.0",
"zone.js": "~0.11.4", "web-animations-js": "2.3.2",
"web-animations-js": "2.3.2" "zone.js": "~0.11.4"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "^14.2.7", "@angular-devkit/build-angular": "^14.2.7",
"@angular/cli": "~14.2.7", "@angular/cli": "~14.2.7",
"@angular/compiler-cli": "^14.2.0", "@angular/compiler-cli": "^14.2.0",
"@angular/language-service": "14.2.0", "@angular/language-service": "14.2.0",
"@types/bootstrap": "^4.5.0",
"@types/chartist": "0.11.1",
"@types/google.maps": "3.47.4",
"@types/jasmine": "~4.0.0", "@types/jasmine": "~4.0.0",
"@types/jasminewd2": "~2.0.10", "@types/jasminewd2": "~2.0.10",
"@types/jquery": "^3.5.6",
"@types/node": "^17.0.21", "@types/node": "^17.0.21",
"@types/bootstrap": "4.5.0",
"@types/chartist": "0.11.1",
"@types/google.maps": "3.47.4",
"@types/jquery": "3.5.6",
"sass": "1.32.13",
"codelyzer": "6.0.2", "codelyzer": "6.0.2",
"jasmine-core": "~4.4.0", "jasmine-core": "~4.4.0",
"jasmine-spec-reporter": "~7.0.0", "jasmine-spec-reporter": "~7.0.0",
...@@ -72,6 +71,7 @@ ...@@ -72,6 +71,7 @@
"karma-jasmine": "~5.1.0", "karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.0.0", "karma-jasmine-html-reporter": "~2.0.0",
"protractor": "7.0.0", "protractor": "7.0.0",
"sass": "1.32.13",
"ts-node": "~10.9.1", "ts-node": "~10.9.1",
"typescript": "~4.7.2" "typescript": "~4.7.2"
} }
......
...@@ -2,13 +2,22 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; ...@@ -2,13 +2,22 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http'; import { HttpClientModule } from '@angular/common/http';
import { RouterModule } from '@angular/router'; import { RouterModule, Routes} from '@angular/router';
import { AppRoutingModule } from './app.routing'; import { AppRoutingModule } from './app.routing';
import { ComponentsModule } from './components/components.module'; import { ComponentsModule } from './components/components.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { AdminLayoutComponent } from './layouts/admin-layout/admin-layout.component'; import { AdminLayoutComponent } from './layouts/admin-layout/admin-layout.component';
import { CreateExerciseComponent } from './create-exercise/create-exercise.component';
import { ListExerciseComponent } from './list-exercise/list-exercise.component';
import { ExerciseDetailsComponent } from './exercise-details/exercise-details.component';
import * as bootstrap from "bootstrap";
import * as $ from "jquery";
// import { ExercisePageComponent } from './exercise-page/exercise-page.component'; // import { ExercisePageComponent } from './exercise-page/exercise-page.component';
const routes: Routes = [
// Add other routes as needed
];
@NgModule({ @NgModule({
imports: [ imports: [
BrowserAnimationsModule, BrowserAnimationsModule,
...@@ -16,12 +25,15 @@ import { AdminLayoutComponent } from './layouts/admin-layout/admin-layout.compon ...@@ -16,12 +25,15 @@ import { AdminLayoutComponent } from './layouts/admin-layout/admin-layout.compon
ReactiveFormsModule, ReactiveFormsModule,
HttpClientModule, HttpClientModule,
ComponentsModule, ComponentsModule,
RouterModule, RouterModule.forRoot(routes),
AppRoutingModule, AppRoutingModule,
], ],
declarations: [ declarations: [
AppComponent, AppComponent,
AdminLayoutComponent, AdminLayoutComponent,
CreateExerciseComponent,
ListExerciseComponent,
ExerciseDetailsComponent,
], ],
providers: [], providers: [],
bootstrap: [AppComponent] bootstrap: [AppComponent]
......
...@@ -4,6 +4,9 @@ import { BrowserModule } from '@angular/platform-browser'; ...@@ -4,6 +4,9 @@ import { BrowserModule } from '@angular/platform-browser';
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule } from '@angular/router';
import { AdminLayoutComponent } from './layouts/admin-layout/admin-layout.component'; import { AdminLayoutComponent } from './layouts/admin-layout/admin-layout.component';
import { CreateExerciseComponent } from './create-exercise/create-exercise.component';
import { ListExerciseComponent } from './list-exercise/list-exercise.component';
import { ExerciseDetailsComponent } from './exercise-details/exercise-details.component';
const routes: Routes =[ const routes: Routes =[
{ {
...@@ -17,7 +20,10 @@ const routes: Routes =[ ...@@ -17,7 +20,10 @@ const routes: Routes =[
path: '', path: '',
loadChildren: () => import('./layouts/admin-layout/admin-layout.module').then(m => m.AdminLayoutModule) loadChildren: () => import('./layouts/admin-layout/admin-layout.module').then(m => m.AdminLayoutModule)
}] }]
} },
{ path: 'list_exercice', component: ListExerciseComponent },
{ path: 'create_exercise', component: CreateExerciseComponent },
{ path: 'exercise-details/:id', component: ExerciseDetailsComponent }
]; ];
@NgModule({ @NgModule({
......
import { TestBed } from '@angular/core/testing';
import { AssignmentService } from './assignment.service';
describe('AssignmentService', () => {
let service: AssignmentService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(AssignmentService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Assignment } from './model/assignment';
@Injectable({
providedIn: 'root'
})
export class AssignmentService {
private baseUrl = 'http://localhost:3000';
constructor(private http: HttpClient) {}
getAssignment(): Observable<Assignment[]> {
return this.http.get<Assignment[]>(`${this.baseUrl}/assignments`);
}
getAssignmentTitles(): Observable<string[]> {
return this.http.get<string[]>(`${this.baseUrl}/assignments/name`);
}
}
import { Injectable, OnDestroy } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Router } from '@angular/router';
import { BehaviorSubject, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class AuthService implements OnDestroy {
private gitLabClientId = 'aa238db2a5ca6d9eda4214dc563c0ae49224d1dad2b1364cfe68f8a653c4bd9f';
private gitLabRedirectUri = 'http://localhost:4200/login';
private gitLabAuthUrl = 'https://githepia.hesge.ch/oauth/authorize';
private gitLabTokenUrl = 'https://githepia.hesge.ch/oauth/token';
private GITLAB_SECRET = 'gloas-4b3615b522437402e34617e1ce2bccaf690caf8225c664fee4cd14f38300521a'
private destroy$ = new Subject<void>();
// Propriété pour stocker le nom d'utilisateur
private usernameSubject: BehaviorSubject<string> = new BehaviorSubject<string>('');
// Propriété observable pour permettre à d'autres parties de l'application d'accéder au nom d'utilisateur
username$ = this.usernameSubject.asObservable();
constructor(private http: HttpClient, private router: Router) {}
authenticateWithGitLab(): void {
const redirectUri = encodeURIComponent(this.gitLabRedirectUri);
const authUrl = `${this.gitLabAuthUrl}?client_id=${this.gitLabClientId}&redirect_uri=${redirectUri}&response_type=code&scope=api+create_runner+read_repository+write_repository`;
window.location.href = authUrl;
console.log("test");
}
getUserInfo(accessToken: string): void {
const headers = new HttpHeaders({
Authorization: `Bearer ${accessToken}`
});
// Faire une requête à l'API GitLab pour obtenir les détails de l'utilisateur
this.http.get('https://githepia.hesge.ch/api/v4/user', { headers })
.pipe(takeUntil(this.destroy$))
.subscribe(
(user: any) => {
// Récupérer le nom du compte de l'utilisateur
const accountName = user.username;
this.usernameSubject.next(accountName);
console.log(`Nom du compte: ${accountName}`);
},
(error) => {
console.error(error);
}
);
}
exchangeCodeForToken(code: string): void {
const redirectUri = encodeURIComponent(this.gitLabRedirectUri);
const body = `client_id=${this.gitLabClientId}&client_secret=${this.GITLAB_SECRET}&code=${code}&grant_type=authorization_code&redirect_uri=${redirectUri}`;
this.http.post(this.gitLabTokenUrl, body)
.pipe(takeUntil(this.destroy$))
.subscribe(
(response: any) => {
// Récupérer le jeton d'accès depuis la réponse
const accessToken = response.access_token;
// Ajouter une déclaration de débogage pour vérifier l'accessToken
console.log('AccessToken récupéré :', accessToken);
// Utiliser le jeton pour récupérer les informations de l'utilisateur
this.getUserInfo(accessToken);
localStorage.setItem('authorizationCode', code);
localStorage.setItem('accessToken', response.access_token);
},
(error) => {
console.error(error);
}
);
}
isAuthorizationCodeStored(): boolean {
return localStorage.getItem('authorizationCode') !== null;
}
isAccessTokenStored(): boolean {
return localStorage.getItem('accessToken') !== null;
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
}
/* navbar.component.css */
.dropdown-content {
position: absolute;
display: block;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content p {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
\ No newline at end of file
...@@ -20,14 +20,6 @@ ...@@ -20,14 +20,6 @@
</div> </div>
</form> </form>
<ul class="navbar-nav"> <ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">
<i class="material-icons">dashboard</i>
<p>
<span class="d-lg-none d-md-block">Stats</span>
</p>
</a>
</li>
<li class="nav-item dropdown"> <li class="nav-item dropdown">
<a class="nav-link" href="javascript:void(0)" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <a class="nav-link" href="javascript:void(0)" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="material-icons">notifications</i> <i class="material-icons">notifications</i>
...@@ -45,12 +37,17 @@ ...@@ -45,12 +37,17 @@
</div> </div>
</li> </li>
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="javascript:void(0)"> <a class="nav-link" href="javascript:void(0)" (click)="toggleDropdown()">
<i class="material-icons">person</i> <i class="material-icons">person</i>
<p> <p>
<span class="d-lg-none d-md-block">Account</span> <span class="d-lg-none d-md-block">Account</span>
</p> </p>
</a> </a>
<div *ngIf="dropdownVisible" class="dropdown-content">
<p>Contact</p>
<p>Déconnexion</p>
<p>{{ username }}</p>
</div>
</li> </li>
</ul> </ul>
</div> </div>
......
...@@ -2,6 +2,7 @@ import { Component, OnInit, ElementRef } from '@angular/core'; ...@@ -2,6 +2,7 @@ import { Component, OnInit, ElementRef } from '@angular/core';
import { ROUTES } from '../sidebar/sidebar.component'; import { ROUTES } from '../sidebar/sidebar.component';
import {Location, LocationStrategy, PathLocationStrategy} from '@angular/common'; import {Location, LocationStrategy, PathLocationStrategy} from '@angular/common';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { AuthService} from "../../auth_service";
@Component({ @Component({
selector: 'app-navbar', selector: 'app-navbar',
...@@ -9,18 +10,28 @@ import { Router } from '@angular/router'; ...@@ -9,18 +10,28 @@ import { Router } from '@angular/router';
styleUrls: ['./navbar.component.css'] styleUrls: ['./navbar.component.css']
}) })
export class NavbarComponent implements OnInit { export class NavbarComponent implements OnInit {
username: string = '';
accountName: string = 'Nom du compte par défaut'; // Initialisez avec une valeur par défaut
dropdownVisible: boolean = false;
toggleDropdown() {
this.dropdownVisible = !this.dropdownVisible;
}
private listTitles: any[]; private listTitles: any[];
location: Location; location: Location;
mobile_menu_visible: any = 0; mobile_menu_visible: any = 0;
private toggleButton: any; private toggleButton: any;
private sidebarVisible: boolean; private sidebarVisible: boolean;
constructor(location: Location, private element: ElementRef, private router: Router) { constructor(location: Location, private element: ElementRef, private router: Router,private authService:AuthService) {
this.location = location; this.location = location;
this.sidebarVisible = false; this.sidebarVisible = false;
} }
ngOnInit(){ ngOnInit(){
this.authService.username$.subscribe(username => {
this.username = username;
});
this.listTitles = ROUTES.filter(listTitle => listTitle); this.listTitles = ROUTES.filter(listTitle => listTitle);
const navbar: HTMLElement = this.element.nativeElement; const navbar: HTMLElement = this.element.nativeElement;
this.toggleButton = navbar.getElementsByClassName('navbar-toggler')[0]; this.toggleButton = navbar.getElementsByClassName('navbar-toggler')[0];
......
<div class="logo"> <div class="logo">
<a href="https://www.creative-tim.com" class="simple-text"> <a href="" class="simple-text">
<div class="logo-img"> <div class="logo-img">
<img src="/assets/img/angular2-logo-red.png"/> <img src="/assets/img/angular2-logo-red.png"/>
</div> </div>
Creative Tim DOJO
</a> </a>
</div> </div>
<div class="sidebar-wrapper"> <div class="sidebar-wrapper">
......
...@@ -9,10 +9,13 @@ declare interface RouteInfo { ...@@ -9,10 +9,13 @@ declare interface RouteInfo {
} }
export const ROUTES: RouteInfo[] = [ export const ROUTES: RouteInfo[] = [
{ path: '/dashboard', title: 'Dashboard', icon: 'dashboard', class: '' }, { path: '/dashboard', title: 'Dashboard', icon: 'dashboard', class: '' },
{ path: '/login', title: 'Login', icon:'login', class: '' },
{ path: '/user-profile', title: 'Create assignment', icon:'assignment_add', class: '' }, { path: '/user-profile', title: 'Create assignment', icon:'assignment_add', class: '' },
{ path: '/table-list', title: 'Assignment', icon:'content_paste', class: '' }, { path: '/table-list', title: 'Assignment', icon:'content_paste', class: '' },
{ path: '/exercise-page', title: 'Exercise Page', icon:'description', class: '' }, { path: '/exercise-page', title: 'Exercise Page', icon:'description', class: '' },
{ path: '/typography', title: 'Typography', icon:'library_books', class: '' }, { path: '/typography', title: 'Typography', icon:'library_books', class: '' },
{ path: '/exercise', title: 'Exercices', icon:'exercises', class: '' },
// { path: '/icons', title: 'Icons', icon:'bubble_chart', class: '' }, // { path: '/icons', title: 'Icons', icon:'bubble_chart', class: '' },
// { path: '/maps', title: 'Maps', icon:'location_on', class: '' }, // { path: '/maps', title: 'Maps', icon:'location_on', class: '' },
{ path: '/notifications', title: 'Notifications', icon:'notifications', class: '' }, { path: '/notifications', title: 'Notifications', icon:'notifications', class: '' },
......
<!-- create-exercise.component.html -->
<div class="main-content">
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header card-header-danger">
<h4 class="card-title">Créer un exercice</h4>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table">
<tbody>
<tr>
<td>Nom de l'exercice:</td>
<td>
<input type="text" name="exerciseName" [(ngModel)]="exerciseName" class="form-control" required>
</td>
</tr>
<tr>
<td>Énoncé de l'exercice:</td>
<td>
<select name="selectedAssignment" [(ngModel)]="selectedAssignment" class="form-control" required>
<option *ngFor="let assignment of assignments" [ngValue]="assignment">{{ assignment.name }}</option>
</select>
</td>
</tr>
</tbody>
</table>
<button (click)="createExercise()" class="btn btn-primary">Créer l'exercice</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment