feat: enhance dynamic forms and popups for About, Contact, and Resume sections; add project detail popup

This commit is contained in:
2026-02-15 05:27:23 +05:30
parent 55b436c7d2
commit 58929ae6d4
21 changed files with 605 additions and 87 deletions
+3 -3
View File
@@ -1,6 +1,6 @@
import { HttpClient } from '@angular/common/http';
import { inject, Injectable, PLATFORM_ID } from '@angular/core';
import { BehaviorSubject, map, Observable, of } from 'rxjs';
import { BehaviorSubject, map, Observable } from 'rxjs';
import { environment } from '../../environments/environment';
import { isPlatformBrowser } from '@angular/common';
import { Router } from '@angular/router';
@@ -107,11 +107,11 @@ export class AuthService {
return this.accessToken;
}
logout(): Observable<void> {
logout(): void {
this.http.post<void>(this.api('/api/v1/auth/logout'), {}).subscribe();
this.accessToken = null;
this.safeRemoveToken();
this.router.navigate(['/admin/login']);
return of();
}
refreshToken(): Observable<RefreshTokenResponse> {
+6
View File
@@ -28,6 +28,12 @@
<form [formGroup]="otpForm" (ngSubmit)="verifyOtp()">
<label for="otp">Enter 6-digit OTP</label>
<input id="otp" type="text" maxlength="6" formControlName="otp" placeholder="123456" />
@if (isError()) {
<div class="error-banner">
<i class="fa-solid fa-circle-exclamation"></i>
<span>{{ message() }}</span>
</div>
}
<button type="submit" [disabled]="otpForm.invalid">
Verify OTP
</button>
+34
View File
@@ -132,6 +132,40 @@ button {
font-size: 14px;
}
.error-text {
color: #ff6b6b;
font-size: 13px;
margin: 6px 0 0;
text-align: left;
}
.error-banner {
display: flex;
align-items: center;
gap: 8px;
background: rgba(255, 80, 80, 0.1);
border: 1px solid rgba(255, 80, 80, 0.3);
border-radius: 8px;
padding: 10px 14px;
margin: 10px 0 10px;
color: #ff6b6b;
font-size: 13px;
animation: shakeError 0.4s ease;
i {
font-size: 15px;
flex-shrink: 0;
}
}
@keyframes shakeError {
0%, 100% { transform: translateX(0); }
20% { transform: translateX(-6px); }
40% { transform: translateX(6px); }
60% { transform: translateX(-4px); }
80% { transform: translateX(4px); }
}
.info-text {
color: #ccc;
font-size: 14px;
+2 -2
View File
@@ -82,9 +82,9 @@ export class OtpComponent implements OnInit {
error: (err) => {
this.isError.set(true);
if (err.status === 401 && err.error?.message) {
console.log(err.error.message); // "OTP Expired" or "Invalid OTP"
this.message.set(err.error.message);
} else {
console.log('Something went wrong. Please try again.');
this.message.set('Something went wrong. Please try again.');
}
}
});