Skip to content

Commit

Permalink
Update: Added K8s & Jenkins CI/CD
Browse files Browse the repository at this point in the history
  • Loading branch information
hoangsonww committed Oct 20, 2024
1 parent 17e28a7 commit 312b0b2
Show file tree
Hide file tree
Showing 45 changed files with 717 additions and 290 deletions.
20 changes: 11 additions & 9 deletions LMS-Frontend/app/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ import { FooterComponent } from './core/footer/footer.component';
</div>
<app-footer></app-footer>
`,
styles: [`
.container {
margin-top: 20px;
padding: 15px;
max-width: 1200px;
margin-left: auto;
margin-right: auto;
}
`]
styles: [
`
.container {
margin-top: 20px;
padding: 15px;
max-width: 1200px;
margin-left: auto;
margin-right: auto;
}
`,
],
})
export class AppComponent {}
4 changes: 2 additions & 2 deletions LMS-Frontend/app/src/app/app.config.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ export const config: ApplicationConfig = {
providers: [
provideHttpClient(),
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
importProvidersFrom([])
]
importProvidersFrom([]),
],
};
2 changes: 1 addition & 1 deletion LMS-Frontend/app/src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ export const appConfig: ApplicationConfig = {
provideRouter(routes),
provideHttpClient(withFetch()),
provideClientHydration(),
]
],
};
2 changes: 1 addition & 1 deletion LMS-Frontend/app/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ export const routes: Routes = [
{ path: 'lessons', component: LessonListComponent },
{ path: 'enrollments', component: EnrollmentListComponent },
{ path: 'progress', component: ProgressListComponent },
{ path: '**', redirectTo: '', pathMatch: 'full' }
{ path: '**', redirectTo: '', pathMatch: 'full' },
];
4 changes: 3 additions & 1 deletion LMS-Frontend/app/src/app/auth/login/login.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
font-weight: 600;
padding: 0.75rem 1rem;
font-size: 1rem;
transition: background-color 0.3s, transform 0.3s;
transition:
background-color 0.3s,
transform 0.3s;
border-radius: 8px;
}

Expand Down
11 changes: 9 additions & 2 deletions LMS-Frontend/app/src/app/auth/login/login.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,17 @@ <h2 class="text-center text-primary mb-4">Login</h2>

<!-- Login Button or Loading Indicator -->
<div class="form-group mb-3">
<button type="submit" class="btn btn-primary btn-lg w-100 mt-3" [disabled]="isLoading">
<button
type="submit"
class="btn btn-primary btn-lg w-100 mt-3"
[disabled]="isLoading"
>
<span *ngIf="!isLoading">Login</span>
<span *ngIf="isLoading">
<div class="spinner-border spinner-border-sm text-light" role="status">
<div
class="spinner-border spinner-border-sm text-light"
role="status"
>
<span class="visually-hidden">Loading...</span>
</div>
Logging in...
Expand Down
12 changes: 8 additions & 4 deletions LMS-Frontend/app/src/app/auth/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@ import { CommonModule } from '@angular/common';
standalone: true,
imports: [FormsModule, CommonModule],
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
styleUrls: ['./login.component.css'],
})
export class LoginComponent {
username: string = '';
password: string = '';
errorMessage: string = '';
isLoading: boolean = false; // New flag to manage loading state

constructor(private authService: AuthService, private router: Router) {}
constructor(
private authService: AuthService,
private router: Router,
) {}

login(): void {
// Reset error message before login attempt
Expand All @@ -35,8 +38,9 @@ export class LoginComponent {
(error) => {
// Reset loading state and show error on failure
this.isLoading = false;
this.errorMessage = error.error?.detail || 'Invalid username or password';
}
this.errorMessage =
error.error?.detail || 'Invalid username or password';
},
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@
font-weight: 600;
padding: 0.75rem 1rem;
font-size: 1rem;
transition: background-color 0.3s, transform 0.3s;
transition:
background-color 0.3s,
transform 0.3s;
border-radius: 8px;
}

Expand Down
34 changes: 27 additions & 7 deletions LMS-Frontend/app/src/app/auth/register/register.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<div class="register-container d-flex justify-content-center align-items-center">
<div
class="register-container d-flex justify-content-center align-items-center"
>
<div class="card p-5 shadow-lg register-card">
<h2 class="text-center text-primary mb-4">Register</h2>
<form (ngSubmit)="register()" #registerForm="ngForm">
Expand All @@ -15,7 +17,10 @@ <h2 class="text-center text-primary mb-4">Register</h2>
required
#usernameCtrl="ngModel"
/>
<div *ngIf="usernameCtrl.invalid && usernameCtrl.touched" class="text-danger">
<div
*ngIf="usernameCtrl.invalid && usernameCtrl.touched"
class="text-danger"
>
Username is required.
</div>
</div>
Expand All @@ -36,7 +41,9 @@ <h2 class="text-center text-primary mb-4">Register</h2>
/>
<div *ngIf="emailCtrl.invalid && emailCtrl.touched" class="text-danger">
<span *ngIf="emailCtrl.errors?.['required']">Email is required.</span>
<span *ngIf="emailCtrl.errors?.['email']">Enter a valid email address.</span>
<span *ngIf="emailCtrl.errors?.['email']"
>Enter a valid email address.</span
>
</div>
</div>

Expand All @@ -54,7 +61,10 @@ <h2 class="text-center text-primary mb-4">Register</h2>
#password1Ctrl="ngModel"
(ngModelChange)="validatePassword()"
/>
<div *ngIf="password1Ctrl.invalid && password1Ctrl.touched" class="text-danger">
<div
*ngIf="password1Ctrl.invalid && password1Ctrl.touched"
class="text-danger"
>
Password is required.
</div>
<div *ngIf="passwordError" class="text-danger">
Expand All @@ -75,17 +85,27 @@ <h2 class="text-center text-primary mb-4">Register</h2>
required
#password2Ctrl="ngModel"
/>
<div *ngIf="password1 !== password2 && password2Ctrl.touched" class="text-danger">
<div
*ngIf="password1 !== password2 && password2Ctrl.touched"
class="text-danger"
>
Passwords do not match.
</div>
</div>

<!-- Register Button or Loading Indicator -->
<div class="form-group mb-3">
<button type="submit" class="btn btn-primary btn-lg w-100 mt-3" [disabled]="registerForm.invalid || passwordError || isLoading">
<button
type="submit"
class="btn btn-primary btn-lg w-100 mt-3"
[disabled]="registerForm.invalid || passwordError || isLoading"
>
<span *ngIf="!isLoading">Register</span>
<span *ngIf="isLoading">
<div class="spinner-border spinner-border-sm text-light" role="status">
<div
class="spinner-border spinner-border-sm text-light"
role="status"
>
<span class="visually-hidden">Loading...</span>
</div>
Registering...
Expand Down
36 changes: 21 additions & 15 deletions LMS-Frontend/app/src/app/auth/register/register.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { CommonModule } from '@angular/common';
standalone: true,
imports: [FormsModule, CommonModule],
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
styleUrls: ['./register.component.css'],
})
export class RegisterComponent {
username: string = '';
Expand All @@ -18,9 +18,12 @@ export class RegisterComponent {
password2: string = '';
errorMessage: string = '';
passwordError: string | null = null;
isLoading: boolean = false; // New flag to manage loading state
isLoading: boolean = false; // New flag to manage loading state

constructor(private authService: AuthService, private router: Router) {}
constructor(
private authService: AuthService,
private router: Router,
) {}

/**
* This function ensures the password is not purely numeric and also
Expand Down Expand Up @@ -49,17 +52,20 @@ export class RegisterComponent {
// Set loading state to true before making the request
this.isLoading = true;

this.authService.register(this.username, this.email, this.password1, this.password2).subscribe(
() => {
// Reset loading state on success
this.isLoading = false;
this.router.navigate(['/login']); // Redirect to login page after successful registration
},
(error) => {
// Reset loading state and show error on failure
this.isLoading = false;
this.errorMessage = error.error?.detail || 'Registration failed. Please try again.';
}
);
this.authService
.register(this.username, this.email, this.password1, this.password2)
.subscribe(
() => {
// Reset loading state on success
this.isLoading = false;
this.router.navigate(['/login']); // Redirect to login page after successful registration
},
(error) => {
// Reset loading state and show error on failure
this.isLoading = false;
this.errorMessage =
error.error?.detail || 'Registration failed. Please try again.';
},
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

.card {
border: none;
transition: transform 0.3s, box-shadow 0.3s;
transition:
transform 0.3s,
box-shadow 0.3s;
padding: 15px;
}

Expand Down Expand Up @@ -51,7 +53,12 @@
display: flex;
justify-content: center;
align-items: center;
background-color: rgba(255, 255, 255, 0.8); /* Optional: light overlay effect */
background-color: rgba(
255,
255,
255,
0.8
); /* Optional: light overlay effect */
z-index: 9999; /* Ensure it stays on top */
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,16 @@ <h2 class="mb-4 text-primary text-center">Platform Overview</h2>
<!-- Courses and Errors (only shown when loading is false) -->
<div *ngIf="!loading">
<h2 class="mb-4 text-primary text-center">Courses</h2>
<div *ngIf="errorMessage" class="alert alert-danger" style="text-align: center;">{{ errorMessage }}</div>
<div *ngIf="courses.length === 0 && !errorMessage" class="alert alert-info">No courses available.</div>
<div
*ngIf="errorMessage"
class="alert alert-danger"
style="text-align: center"
>
{{ errorMessage }}
</div>
<div *ngIf="courses.length === 0 && !errorMessage" class="alert alert-info">
No courses available.
</div>

<!-- Course Cards Section -->
<div class="row justify-content-center">
Expand All @@ -29,8 +37,11 @@ <h2 class="mb-4 text-primary text-center">Courses</h2>
<div>
<h4 class="card-title text-primary">{{ course.title }}</h4>
<p class="card-text text-muted">{{ course.description }}</p>
<hr>
<p class="card-text"><strong>Instructor:</strong> {{ formatInstructorName(course.instructor) }}</p>
<hr />
<p class="card-text">
<strong>Instructor:</strong>
{{ formatInstructorName(course.instructor) }}
</p>
</div>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,22 @@ Chart.register(...registerables);
standalone: true,
imports: [CommonModule],
templateUrl: './course-list.component.html',
styleUrls: ['./course-list.component.css']
styleUrls: ['./course-list.component.css'],
})
export class CourseListComponent implements OnInit {
courses: any[] = [];
errorMessage: string = '';
loading: boolean = true; // Track loading state
chart: Chart<'pie'> | undefined;
private apiUrl = 'https://learning-management-system-fullstack.onrender.com/api/';
private apiUrl =
'https://learning-management-system-fullstack.onrender.com/api/';
lessonsLength: number = 0;
enrollmentsLength: number = 0;
isAuthenticated: boolean = true; // Flag to check authentication status

constructor(
private courseService: CourseService,
private http: HttpClient
private http: HttpClient,
) {}

ngOnInit(): void {
Expand All @@ -39,7 +40,9 @@ export class CourseListComponent implements OnInit {

const courses$ = this.courseService.getCourses();
const lessons$ = this.http.get(`${this.apiUrl}lessons/`, { headers });
const enrollments$ = this.http.get(`${this.apiUrl}enrollments/`, { headers });
const enrollments$ = this.http.get(`${this.apiUrl}enrollments/`, {
headers,
});

forkJoin([courses$, lessons$, enrollments$]).subscribe(
([coursesData, lessonsData, enrollmentsData]: [any[], any, any]) => {
Expand All @@ -64,7 +67,7 @@ export class CourseListComponent implements OnInit {
if (this.isAuthenticated) {
this.renderChart(); // Ensure the chart is only rendered if authenticated
}
}
},
);
}

Expand All @@ -83,19 +86,25 @@ export class CourseListComponent implements OnInit {
type: 'pie',
data: {
labels: ['Courses', 'Lessons', 'Enrollments'],
datasets: [{
data: [this.courses.length, this.lessonsLength, this.enrollmentsLength],
backgroundColor: ['#007bff', '#ffc107', '#28a745']
}]
datasets: [
{
data: [
this.courses.length,
this.lessonsLength,
this.enrollmentsLength,
],
backgroundColor: ['#007bff', '#ffc107', '#28a745'],
},
],
},
options: {
responsive: true,
plugins: {
legend: {
position: 'bottom'
}
}
}
position: 'bottom',
},
},
},
};

this.chart = new Chart(ctx, chartConfig);
Expand Down
Loading

0 comments on commit 312b0b2

Please sign in to comment.