diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index e125390..438dd64 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -9,6 +9,7 @@ import { authGuard } from './guards/auth/auth.guard'; import { HomeComponent } from './components/home/home.component'; import { NotFoundComponent } from './components/general/not-found/not-found.component'; import { OauthButtonComponent } from './components/oauth/oauth-button/oauth-button.component'; +import { AdminLoginComponent } from './components/admin/auth/admin-login/admin-login.component'; const routes: Routes = [ { path: '', component: HomeComponent, pathMatch: 'full' }, @@ -29,14 +30,13 @@ const routes: Routes = [ path: 'authentication', loadChildren: () => import('./components/oauth/oauth.module').then(m => m.OauthModule) }, - { - path: 'admin', - loadChildren: () => import('./components/admin/admin.module').then(m => m.AdminModule) - }, { path: 'other', loadChildren: () => import('./components/other-activity/other-activity.module').then(m => m.OtherActivityModule) }, + { + path: "admin-login", component: AdminLoginComponent, + }, { path: '404', component: NotFoundComponent }, { path: '**', redirectTo: '/404', pathMatch: 'full' } ]; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index b510806..f8d345d 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -45,6 +45,7 @@ import { MatFormFieldModule } from '@angular/material/form-field'; import { MatChipsModule } from '@angular/material/chips'; import { GithubCallbackComponent } from './components/callback/github-callback/github-callback.component'; import { AuthInterceptor } from './guards/auth/interceptor/auth-interceptor.service'; +import { AdminLoginComponent } from './components/admin/auth/admin-login/admin-login.component'; // AOT compilation support export function HttpLoaderFactory(http: HttpClient) { @@ -79,7 +80,8 @@ export function HttpLoaderFactory(http: HttpClient) { FileUploadComponent, ConfirmDialogComponent, QuestionEditDialogComponent, - GithubCallbackComponent + GithubCallbackComponent, + AdminLoginComponent ], // ... diff --git a/src/app/components/admin/admin-routing.module.ts b/src/app/components/admin/admin-routing.module.ts index 9c64866..e7952f7 100644 --- a/src/app/components/admin/admin-routing.module.ts +++ b/src/app/components/admin/admin-routing.module.ts @@ -10,6 +10,8 @@ import { MarkdownRendererComponent } from './markdown-renderer/markdown-renderer import { FileUploadComponent } from '../general/file/file-upload/file-upload.component'; import { CsharpInterviewQaComponent } from './topic/csharp-interview-qa/csharp-interview-qa.component'; import { UserComponent } from './user/user/user.component'; +import { adminGuard } from 'src/app/guards/admin/admin.guard'; +import { AdminLoginComponent } from './auth/admin-login/admin-login.component'; const routes: Routes = [{ path: "", component: AdminComponent, children: [ @@ -22,7 +24,7 @@ const routes: Routes = [{ { path: "file", component: FileUploadComponent }, { path: "topic", component: CsharpInterviewQaComponent }, { path: "user", component: UserComponent } - ] + ], canActivate: [adminGuard] }]; @NgModule({ diff --git a/src/app/components/admin/auth/admin-login/admin-login.component.css b/src/app/components/admin/auth/admin-login/admin-login.component.css new file mode 100644 index 0000000..4e2abed --- /dev/null +++ b/src/app/components/admin/auth/admin-login/admin-login.component.css @@ -0,0 +1,193 @@ +html { + height: 100%; +} + +body { + margin: 0; + padding: 0; + font-family: sans-serif; + background: linear-gradient(#141e30, #243b55); +} + +button { + background: none; + border: none; + color: #03e9f4; +} + +button:hover { + color: white; +} + +.login-box { + position: absolute; + top: 50%; + left: 50%; + width: 400px; + padding: 40px; + transform: translate(-50%, -50%); + background: rgba(0, 0, 0, .5); + box-sizing: border-box; + box-shadow: 0 15px 25px rgba(0, 0, 0, .6); + border-radius: 10px; +} + +.login-box h2 { + margin: 0 0 30px; + padding: 0; + color: #fff; + text-align: center; +} + +.login-box .user-box { + position: relative; +} + +.login-box .user-box input { + width: 100%; + padding: 10px 0; + font-size: 16px; + color: #fff; + margin-bottom: 30px; + border: none; + border-bottom: 1px solid #fff; + outline: none; + background: transparent; +} + +.login-box .user-box label { + position: absolute; + top: 0; + left: 0; + padding: 10px 0; + font-size: 16px; + color: #fff; + pointer-events: none; + transition: .5s; +} + +.login-box .user-box input:focus~label, +.login-box .user-box input:valid~label { + top: -20px; + left: 0; + color: #03e9f4; + font-size: 12px; +} + +.login-box form button { + position: relative; + display: inline-block; + padding: 10px 20px; + font-size: 16px; + text-decoration: none; + text-transform: uppercase; + overflow: hidden; + transition: .5s; + margin-top: 40px; + letter-spacing: 4px +} + +.login-box button:hover { + background: #03e9f4; + color: #fff; + border-radius: 5px; + box-shadow: 0 0 5px #03e9f4, + 0 0 25px #03e9f4, + 0 0 50px #03e9f4, + 0 0 100px #03e9f4; +} + +.login-box button span { + position: absolute; + display: block; +} + +.login-box button span:nth-child(1) { + top: 0; + left: -100%; + width: 100%; + height: 2px; + background: linear-gradient(90deg, transparent, #03e9f4); + animation: btn-anim1 1s linear infinite; +} + +@keyframes btn-anim1 { + 0% { + left: -100%; + } + + 50%, + 100% { + left: 100%; + } +} + +.login-box button span:nth-child(2) { + top: -100%; + right: 0; + width: 2px; + height: 100%; + background: linear-gradient(180deg, transparent, #03e9f4); + animation: btn-anim2 1s linear infinite; + animation-delay: .25s +} + +@keyframes btn-anim2 { + 0% { + top: -100%; + } + + 50%, + 100% { + top: 100%; + } +} + +.login-box button span:nth-child(3) { + bottom: 0; + right: -100%; + width: 100%; + height: 2px; + background: linear-gradient(270deg, transparent, #03e9f4); + animation: btn-anim3 1s linear infinite; + animation-delay: .5s +} + +@keyframes btn-anim3 { + 0% { + right: -100%; + } + + 50%, + 100% { + right: 100%; + } +} + +.login-box button span:nth-child(4) { + bottom: -100%; + left: 0; + width: 2px; + height: 100%; + background: linear-gradient(360deg, transparent, #03e9f4); + animation: btn-anim4 1s linear infinite; + animation-delay: .75s +} + +@keyframes btn-anim4 { + 0% { + bottom: -100%; + } + + 50%, + 100% { + bottom: 100%; + } +} + +input[type="text"]:focus, +input[type="password"]:focus, +.form-control:focus { + /*Remove input blue border on click*/ + outline: none !important; +} diff --git a/src/app/components/admin/auth/admin-login/admin-login.component.html b/src/app/components/admin/auth/admin-login/admin-login.component.html new file mode 100644 index 0000000..87a7971 --- /dev/null +++ b/src/app/components/admin/auth/admin-login/admin-login.component.html @@ -0,0 +1,20 @@ +
+

Admin Login

+
+
+ + +
+
+ + +
+ +
+
diff --git a/src/app/components/admin/auth/admin-login/admin-login.component.spec.ts b/src/app/components/admin/auth/admin-login/admin-login.component.spec.ts new file mode 100644 index 0000000..0a53550 --- /dev/null +++ b/src/app/components/admin/auth/admin-login/admin-login.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AdminLoginComponent } from './admin-login.component'; + +describe('AdminLoginComponent', () => { + let component: AdminLoginComponent; + let fixture: ComponentFixture; + + beforeEach(() => { + TestBed.configureTestingModule({ + declarations: [AdminLoginComponent] + }); + fixture = TestBed.createComponent(AdminLoginComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/admin/auth/admin-login/admin-login.component.ts b/src/app/components/admin/auth/admin-login/admin-login.component.ts new file mode 100644 index 0000000..fb84f86 --- /dev/null +++ b/src/app/components/admin/auth/admin-login/admin-login.component.ts @@ -0,0 +1,55 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'app-admin-login', + templateUrl: './admin-login.component.html', + styleUrls: ['./admin-login.component.css'] +}) +export class AdminLoginComponent implements OnInit { + loginForm: FormGroup; + loginError!: string; + /** + * + */ + constructor(private formBuilder: FormBuilder, private router: Router) { + this.loginForm = this.formBuilder.group({ + userName: ['', [Validators.required]], + password: ['', [Validators.required]] + }); + } + ngOnInit(): void { + console.log('AdminLogin page loaded'); + } + + onSubmit() { + // Log the form data to the console + console.log('Form Data:', this.loginForm.value); + + if (this.loginForm.valid) { + + // Implement your authentication logic here. + // If successful, navigate to the dashboard or appropriate page. + // On failure, set this.loginError to the error message. + const { userName, password } = this.loginForm.value; + + if (userName !== 'admin' && password !== 'admin') { + console.log('Invalid username or password'); + this.loginError = 'Invalid username or password'; + } + else { + console.log('Form is valid.'); + + console.log("username: " + userName + '; password: ' + password); + // this.authService.login(organizationId, userName, password); + localStorage.setItem('isAdminLoggedIn', "true"); + this.router.navigate(['/admin']); + } + } + else { + // If the form is invalid, you may want to log that as well + console.log('Form is not valid'); + } + } +} diff --git a/src/app/components/other-activity/spotify/spotify-routing.module.ts b/src/app/components/other-activity/spotify/spotify-routing.module.ts index 33538a6..faa91d9 100644 --- a/src/app/components/other-activity/spotify/spotify-routing.module.ts +++ b/src/app/components/other-activity/spotify/spotify-routing.module.ts @@ -1,9 +1,17 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { NowPlayingComponent } from './now-playing/now-playing.component'; +import { SpotifyComponent } from './spotify.component'; const routes: Routes = [ - { path: "now-playing", component: NowPlayingComponent } + { + path: "", component: SpotifyComponent, children: [ + { + path: "now-playing", + component: NowPlayingComponent + } + ] + } ]; @NgModule({ diff --git a/src/app/guards/admin/admin.guard.ts b/src/app/guards/admin/admin.guard.ts index 558613a..8f1aa18 100644 --- a/src/app/guards/admin/admin.guard.ts +++ b/src/app/guards/admin/admin.guard.ts @@ -1,5 +1,15 @@ -import { CanActivateFn } from '@angular/router'; +import { inject } from '@angular/core'; +import { CanActivateFn, Router } from '@angular/router'; export const adminGuard: CanActivateFn = (route, state) => { - return true; + // return false; + const router = inject(Router); + const isLoggedIn = localStorage.getItem('isAdminLoggedIn'); + + if (isLoggedIn) { + console.log("logged in successfully!"); + return true; + } + + return router.createUrlTree(['/']); }; diff --git a/src/app/models/admin/navbar/menu.ts b/src/app/models/admin/navbar/menu.ts index 4e06c05..cf1de55 100644 --- a/src/app/models/admin/navbar/menu.ts +++ b/src/app/models/admin/navbar/menu.ts @@ -68,5 +68,17 @@ export const menu: NavItem[] = [ displayName: 'Topic', iconName: 'question_answer', route: 'topic' + }, + { + displayName:"other", + iconName:"more_horiz", + route:"other", + children:[ + { + displayName:"spotify", + iconName:"music_note", + route:"/other/spotify" + } + ] } ];