final fix
This commit is contained in:
@@ -64,10 +64,9 @@ For more information on using the Angular CLI, including detailed command refere
|
||||
|
||||
|
||||
|
||||
-fix upload of the image in edit mode
|
||||
-add deletion button to the card
|
||||
-centralize scss check the same styles for differnet buttons
|
||||
-adjust to mobile format
|
||||
|
||||
****animations transitions (prev next cards)
|
||||
|
||||
--DEPLOY AND WRITE README
|
||||
|
||||
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@@ -8,7 +8,7 @@
|
||||
"name": "iisa-web",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@angular/animations": "^19.1.0",
|
||||
"@angular/animations": "^19.2.14",
|
||||
"@angular/cdk": "^19.2.19",
|
||||
"@angular/common": "^19.1.0",
|
||||
"@angular/compiler": "^19.1.0",
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "^19.1.0",
|
||||
"@angular/animations": "^19.2.14",
|
||||
"@angular/cdk": "^19.2.19",
|
||||
"@angular/common": "^19.1.0",
|
||||
"@angular/compiler": "^19.1.0",
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { provideAnimations } from '@angular/platform-browser/animations';
|
||||
|
||||
import { routes } from './app.routes';
|
||||
import { provideHttpClient } from '@angular/common/http';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideHttpClient()]
|
||||
providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideHttpClient(), provideAnimations()]
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="container app-list">
|
||||
<div class="header-row">
|
||||
<div class="list-header-top">
|
||||
<button mat-button type="button" routerLink="/landing" class="back-button">
|
||||
<button mat-button type="button" routerLink="/landing" class="secondary-btn">
|
||||
Go Back
|
||||
</button>
|
||||
<h2 class="page-title">Applications</h2>
|
||||
@@ -82,7 +82,7 @@
|
||||
<div class="listItem" [routerLink]="'/application/' + application.id">
|
||||
@if (application.profileImage) {
|
||||
<img
|
||||
[src]="environment.hostUrl + '/uploads/' + application.profileImage"
|
||||
[src]="application.profileImage"
|
||||
alt="{{ application.fullName }}"
|
||||
class="profile-photo"
|
||||
/>
|
||||
|
||||
@@ -18,6 +18,23 @@
|
||||
position: relative;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
button.secondary-btn {
|
||||
background: transparent;
|
||||
color: #00ffff;
|
||||
border: 1px solid #00ffff;
|
||||
padding: 0.8rem 1.5rem;
|
||||
border-radius: 8px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
button.secondary-btn:hover {
|
||||
background: rgba(0, 255, 255, 0.12);
|
||||
box-shadow: 0 0 20px #00ffff;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.back-button {
|
||||
position: absolute;
|
||||
|
||||
@@ -13,6 +13,7 @@ import { BaseChartDirective } from 'ng2-charts';
|
||||
import { ChartData, ChartOptions, Chart, registerables } from 'chart.js';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
|
||||
Chart.register(...registerables);
|
||||
|
||||
@@ -28,6 +29,7 @@ Chart.register(...registerables);
|
||||
MatInputModule,
|
||||
MatProgressSpinnerModule,
|
||||
BaseChartDirective,
|
||||
MatButtonModule
|
||||
],
|
||||
templateUrl: './application-list.component.html',
|
||||
styleUrls: ['./application-list.component.scss']
|
||||
|
||||
@@ -1,86 +1,95 @@
|
||||
<div class="container application">
|
||||
<header class="header">
|
||||
|
||||
<header class="header">
|
||||
<button mat-button type="button" routerLink="/application-list" class="back-button">
|
||||
<mat-icon>arrow_back</mat-icon>
|
||||
Go Back
|
||||
</button>
|
||||
<h2>🛰 Application Details</h2>
|
||||
</header>
|
||||
|
||||
</header>
|
||||
<div class="content-wrapper">
|
||||
<div class="navigation-controls">
|
||||
<button
|
||||
mat-icon-button
|
||||
[disabled]="!canGoToPrevious()"
|
||||
(click)="goToPrevious()"
|
||||
class="nav-button"
|
||||
title="Previous Application"
|
||||
>
|
||||
<mat-icon>chevron_left</mat-icon>
|
||||
</button>
|
||||
<span class="navigation-info">
|
||||
{{ currentIndex() + 1 }} of {{ applicationList().length }}
|
||||
</span>
|
||||
<button
|
||||
mat-icon-button
|
||||
[disabled]="!canGoToNext()"
|
||||
(click)="goToNext()"
|
||||
class="nav-button"
|
||||
title="Next Application"
|
||||
>
|
||||
<mat-icon>chevron_right</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div [@animSlider]="currentIndex()" class="application-card-container">
|
||||
@if (isApplicationDetailsLoading) {
|
||||
<div class="loading-container">
|
||||
<mat-spinner diameter="50"></mat-spinner>
|
||||
<p class="loading-text">Loading application details...</p>
|
||||
</div>
|
||||
} @else if (hasApplicationData) {
|
||||
<div class="content-wrapper">
|
||||
|
||||
<div class="navigation-controls">
|
||||
<button
|
||||
mat-icon-button
|
||||
[disabled]="!canGoToPrevious()"
|
||||
(click)="goToPrevious()"
|
||||
class="nav-button"
|
||||
title="Previous Application"
|
||||
>
|
||||
<mat-icon>chevron_left</mat-icon>
|
||||
</button>
|
||||
|
||||
<span class="navigation-info">
|
||||
{{ currentIndex() + 1 }} of {{ applicationList().length }}
|
||||
</span>
|
||||
|
||||
<button
|
||||
mat-icon-button
|
||||
[disabled]="!canGoToNext()"
|
||||
(click)="goToNext()"
|
||||
class="nav-button"
|
||||
title="Next Application"
|
||||
>
|
||||
<mat-icon>chevron_right</mat-icon>
|
||||
</button>
|
||||
<div class="application-card">
|
||||
<div class="loading-container">
|
||||
<mat-spinner diameter="50"></mat-spinner>
|
||||
<p class="loading-text">Loading application details...</p>
|
||||
</div>
|
||||
|
||||
<div class="application-card">
|
||||
|
||||
</div>
|
||||
}
|
||||
@if(!isApplicationDetailsLoading){
|
||||
<div class="application-card">
|
||||
@if(this.currentApplication() === null) {
|
||||
<div class="no-data">
|
||||
<mat-icon class="no-data-icon">inbox</mat-icon>
|
||||
<p>No application data available</p>
|
||||
<button mat-button routerLink="/application-list" class="back-button">
|
||||
<mat-icon>arrow_back</mat-icon>
|
||||
Return to List
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
@if (this.currentApplication() !== null) {
|
||||
<div class="profile-section">
|
||||
@if (currentApplication().profileImage) {
|
||||
<div class="profile-image-container">
|
||||
<img
|
||||
[src]="environment.hostUrl + '/uploads/' + currentApplication().profileImage"
|
||||
[src]="currentApplication().profileImage"
|
||||
[alt]="currentApplication().fullName"
|
||||
class="profile-image"
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
<div class="profile-info">
|
||||
<h3 class="candidate-name">{{ currentApplication().fullName }}</h3>
|
||||
<div class="basic-info">
|
||||
<div class="info-item">
|
||||
<mat-icon>person</mat-icon>
|
||||
<span>{{ currentApplication().age }} years old</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<mat-icon>location_on</mat-icon>
|
||||
<span>{{ currentApplication().cityOrRegion }}</span>
|
||||
</div>
|
||||
@if (currentApplication().email) {
|
||||
<div class="info-item">
|
||||
<mat-icon>person</mat-icon>
|
||||
<span>{{ currentApplication().age }} years old</span>
|
||||
<mat-icon>email</mat-icon>
|
||||
<span>{{ currentApplication().email }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (currentApplication().phoneNumber) {
|
||||
<div class="info-item">
|
||||
<mat-icon>location_on</mat-icon>
|
||||
<span>{{ currentApplication().cityOrRegion }}</span>
|
||||
<mat-icon>phone</mat-icon>
|
||||
<span>{{ currentApplication().phoneNumber }}</span>
|
||||
</div>
|
||||
@if (currentApplication().email) {
|
||||
<div class="info-item">
|
||||
<mat-icon>email</mat-icon>
|
||||
<span>{{ currentApplication().email }}</span>
|
||||
</div>
|
||||
}
|
||||
@if (currentApplication().phoneNumber) {
|
||||
<div class="info-item">
|
||||
<mat-icon>phone</mat-icon>
|
||||
<span>{{ currentApplication().phoneNumber }}</span>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="details-grid">
|
||||
@if (getHobbiesArray().length > 0) {
|
||||
<div class="detail-section">
|
||||
@@ -92,14 +101,12 @@
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (currentApplication().justification) {
|
||||
<div class="detail-section full-width">
|
||||
<h4><mat-icon>rocket_launch</mat-icon> Journey Justification?</h4>
|
||||
<p class="detail-content">{{ currentApplication().justification }}</p>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (currentApplication().createdAt) {
|
||||
<div class="detail-section">
|
||||
<h4><mat-icon>calendar_today</mat-icon> Application Date</h4>
|
||||
@@ -109,7 +116,6 @@
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="edit-controls">
|
||||
@if (canEdit()) {
|
||||
<button
|
||||
@@ -133,21 +139,14 @@
|
||||
Delete Application
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<details class="raw-data-section">
|
||||
<summary>View Raw Data</summary>
|
||||
<pre class="raw-data">{{ currentApplication() | json }}</pre>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
} @else {
|
||||
<div class="no-data">
|
||||
<mat-icon class="no-data-icon">inbox</mat-icon>
|
||||
<p>No application data available</p>
|
||||
<button mat-button routerLink="/application-list" class="back-button">
|
||||
<mat-icon>arrow_back</mat-icon>
|
||||
Return to List
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
.container {
|
||||
|
||||
:host {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
@@ -113,17 +115,53 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Application Card */
|
||||
.application-card {
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
backdrop-filter: blur(15px);
|
||||
border: 1px solid rgba(0, 255, 255, 0.2);
|
||||
box-shadow: 0 8px 32px rgba(0, 255, 255, 0.1);
|
||||
margin-bottom: 2rem;
|
||||
.delete-button {
|
||||
margin-left: 12px;
|
||||
|
||||
background: rgba(255, 68, 68, 0.1);
|
||||
border: 1px solid #ff4444;
|
||||
border-radius: 8px;
|
||||
color: #ff4444;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.delete-button:hover {
|
||||
background: rgba(255, 68, 68, 0.2);
|
||||
color: #ff6666;
|
||||
box-shadow: 0 0 20px rgba(255, 68, 68, 0.4);
|
||||
transform: translateY(-2px);
|
||||
border-color: #ff6666;
|
||||
}
|
||||
|
||||
.delete-button mat-icon {
|
||||
font-size: 20px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
/* Application Card */
|
||||
.application-card-container {
|
||||
position: relative;
|
||||
overflow-x: hidden;
|
||||
border-radius: 16px;
|
||||
min-height: 60rem;
|
||||
.application-card {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
border-radius: 16px;
|
||||
padding: 2rem;
|
||||
backdrop-filter: blur(15px);
|
||||
border: 1px solid rgba(0, 255, 255, 0.2);
|
||||
box-shadow: 0 8px 32px rgba(0, 255, 255, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Profile Section */
|
||||
.profile-section {
|
||||
display: flex;
|
||||
@@ -414,4 +452,5 @@
|
||||
font-size: 0.95rem;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ import { CommonModule } from '@angular/common';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { SocketIOService } from '../../services/socket-io.service';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { trigger, transition } from '@angular/animations';
|
||||
import { slideLeft, slideRight } from './slide.animation';
|
||||
|
||||
@Component({
|
||||
selector: 'app-application',
|
||||
@@ -21,10 +23,16 @@ import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
MatCardModule,
|
||||
MatChipsModule,
|
||||
CommonModule,
|
||||
RouterLink
|
||||
RouterLink,
|
||||
],
|
||||
templateUrl: './application.component.html',
|
||||
styleUrls: ['./application.component.scss']
|
||||
styleUrls: ['./application.component.scss'],
|
||||
animations: [
|
||||
trigger('animSlider', [
|
||||
transition(':increment', slideRight),
|
||||
transition(':decrement', slideLeft),
|
||||
]),
|
||||
],
|
||||
})
|
||||
export class ApplicationComponent implements OnInit {
|
||||
dataService = inject(CandidateDataService);
|
||||
@@ -43,9 +51,6 @@ export class ApplicationComponent implements OnInit {
|
||||
return this.dataService.isApplicationDetailsLoading();
|
||||
}
|
||||
|
||||
get hasApplicationData() {
|
||||
return this.currentApplication() !== null;
|
||||
}
|
||||
|
||||
canGoToPrevious = computed(() => this.currentIndex() > 0);
|
||||
canGoToNext = computed(() =>
|
||||
|
||||
45
src/app/components/application/slide.animation.ts
Normal file
45
src/app/components/application/slide.animation.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { trigger, transition, query, style, animate, group } from '@angular/animations';
|
||||
|
||||
export const slideLeft = [
|
||||
group([
|
||||
query(':enter',
|
||||
[
|
||||
style({ transform: 'translateX(-100%)' }),
|
||||
animate('.6s ease-out', style({ transform: 'translateX(0%)' }))
|
||||
],
|
||||
{
|
||||
optional: true,
|
||||
}
|
||||
),
|
||||
query(':leave',
|
||||
[
|
||||
animate('.6s ease-out', style({ transform: 'translateX(100%)' }))
|
||||
],
|
||||
{
|
||||
optional: true,
|
||||
}
|
||||
),
|
||||
]),
|
||||
];
|
||||
|
||||
export const slideRight = [
|
||||
group([
|
||||
query(':enter',
|
||||
[
|
||||
style({ transform: 'translateX(100%)' }),
|
||||
animate('.4s ease-out', style({ transform: 'translateX(0%)' }))
|
||||
],
|
||||
{
|
||||
optional: true,
|
||||
}
|
||||
),
|
||||
query(':leave',
|
||||
[
|
||||
animate('.4s ease-out', style({ transform: 'translateX(-100%)' }))
|
||||
],
|
||||
{
|
||||
optional: true,
|
||||
}
|
||||
),
|
||||
]),
|
||||
];
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
<div class="fileUploadContainer" [ngStyle]="{'margin-top': value ? '5px' : '20px'}">
|
||||
<!-- Image preview -->
|
||||
@if (value) {
|
||||
@if (previewUrl) {
|
||||
<div class="previewContainer">
|
||||
<img [src]="previewUrl" class="previewImage" />
|
||||
<button
|
||||
@@ -17,7 +17,7 @@
|
||||
}
|
||||
|
||||
<!-- Upload UI when no image -->
|
||||
@if (!value) {
|
||||
@if (!previewUrl) {
|
||||
<div class="uploadPrompt">
|
||||
<mat-icon style="opacity: 60%;">file_upload</mat-icon>
|
||||
<button mat-raised-button color="primary" type="button" (click)="fileInput.click()">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, forwardRef, inject } from '@angular/core';
|
||||
import { Component, effect, forwardRef, inject, input } from '@angular/core';
|
||||
import { ControlValueAccessor, FormsModule, NG_VALUE_ACCESSOR, ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
@@ -34,15 +34,29 @@ export class ImageInputComponent implements ControlValueAccessor {
|
||||
value: File | null = null;
|
||||
disabled = false;
|
||||
previewUrl: string | null = null;
|
||||
src = input<string | null>(null);
|
||||
isDisplayOnly = false;
|
||||
|
||||
constructor() {
|
||||
effect(() => {
|
||||
if (this.src()) {
|
||||
this.previewUrl = this.src();
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onChange = (value: any) => { };
|
||||
onTouched = () => { };
|
||||
|
||||
writeValue(value: File | null): void {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
if (value) {
|
||||
this.previewUrl = URL.createObjectURL(value);
|
||||
} else {
|
||||
this.previewUrl = null;
|
||||
}
|
||||
}
|
||||
registerOnChange(fn: any): void {
|
||||
this.onChange = fn;
|
||||
}
|
||||
@@ -62,12 +76,14 @@ export class ImageInputComponent implements ControlValueAccessor {
|
||||
this.value = input.files[0];
|
||||
|
||||
this.previewUrl = URL.createObjectURL(this.value);
|
||||
console.log(this.previewUrl)
|
||||
this.onChange(this.value);
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.value = null;
|
||||
this.isDisplayOnly = false;
|
||||
if (this.previewUrl) {
|
||||
URL.revokeObjectURL(this.previewUrl);
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
</div>
|
||||
|
||||
<div class="stats">
|
||||
<p>👀 Total Visits: {{ stats.totalVisits() }}</p>
|
||||
<p>🖱️ Register Button Clicks: {{ stats.totalClicks() }}</p>
|
||||
<p>Total Visits: {{ stats.totalVisits() }}</p>
|
||||
<p>Register Button Clicks: {{ stats.totalClicks() }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
margin: 0;
|
||||
padding: 2rem;
|
||||
background: radial-gradient(circle at top, #0a0f2c 0%, #000000 100%);
|
||||
color: #e0e0ff;
|
||||
font-family: 'Orbitron', Arial, sans-serif;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
<div class="container">
|
||||
<div class="registration-header">
|
||||
@if(editMode()){
|
||||
<button mat-button type="button" routerLink="/application-list" class="button">
|
||||
Cancel Editing
|
||||
</button>
|
||||
<button mat-button type="button" (click)="cancelEdit()" class="button">
|
||||
Cancel Editing
|
||||
</button>
|
||||
}@else {
|
||||
<button mat-button type="button" routerLink="/landing" class="button">
|
||||
Go Back
|
||||
@@ -22,10 +22,12 @@
|
||||
<form class="registration-form" [formGroup]="form" (ngSubmit)="onSubmit()">
|
||||
|
||||
<!-- Profile Image Upload -->
|
||||
<div class="image-upload">
|
||||
<app-image-input formControlName="profileImage"></app-image-input>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="image-upload">
|
||||
<app-image-input [src]="this.previewUrl" formControlName="profileImage"></app-image-input>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Full Name -->
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>Full Name</mat-label>
|
||||
|
||||
@@ -44,8 +44,9 @@ export class RegistrationComponent implements OnInit {
|
||||
activatedRoute = inject(ActivatedRoute);
|
||||
snackBar = inject(MatSnackBar)
|
||||
socketService = inject(SocketIOService);
|
||||
previewUrl: string | ArrayBuffer | null = null;
|
||||
|
||||
originalImageUrl: string | null = null;
|
||||
previewUrl: string | null = null;
|
||||
editMode = signal(false);
|
||||
applicationId = signal<number | null>(null);
|
||||
|
||||
@@ -65,10 +66,11 @@ export class RegistrationComponent implements OnInit {
|
||||
const idParam = this.activatedRoute.snapshot.paramMap.get('id');
|
||||
const url = this.activatedRoute.snapshot.url.map(s => s.path);
|
||||
|
||||
if (url.includes('edit') && idParam) {
|
||||
if (url.includes('edit') && idParam !== null) {
|
||||
const id = Number.parseInt(idParam);
|
||||
this.editMode.set(true);
|
||||
this.applicationId.set(+idParam);
|
||||
this.loadCandidate(+idParam);
|
||||
this.applicationId.set(id);
|
||||
this.loadCandidate(id);
|
||||
} else {
|
||||
this.editMode.set(false);
|
||||
this.applicationId.set(null);
|
||||
@@ -87,9 +89,9 @@ export class RegistrationComponent implements OnInit {
|
||||
hobbies: candidate.hobbies,
|
||||
justification: candidate.justification,
|
||||
});
|
||||
|
||||
if (candidate.profileImageUrl) {
|
||||
this.previewUrl = candidate.profileImageUrl;
|
||||
if (candidate.profileImage) {
|
||||
this.originalImageUrl = candidate.profileImage;
|
||||
this.previewUrl = candidate.profileImage;
|
||||
this.form.get('profileImage')?.clearValidators();
|
||||
this.form.get('profileImage')?.updateValueAndValidity();
|
||||
}
|
||||
@@ -150,7 +152,7 @@ export class RegistrationComponent implements OnInit {
|
||||
this.socketService.socket.emit('candidateUpdated', updatedCandidate);
|
||||
this.router.navigate(['/application-list']);
|
||||
},
|
||||
error: err => console.error('Error updating application', err),
|
||||
error: err => alert('Error updating application'),
|
||||
});
|
||||
} else {
|
||||
this.dataService.submitCandidateForm(formData).subscribe({
|
||||
@@ -163,10 +165,13 @@ export class RegistrationComponent implements OnInit {
|
||||
this.socketService.socket.emit('candidateRegistered', newCandidate);
|
||||
this.form.reset();
|
||||
},
|
||||
error: err => console.error('Error submitting form', err),
|
||||
error: err => alert('Error submitting form'),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
cancelEdit() {
|
||||
this.previewUrl = this.originalImageUrl;
|
||||
this.router.navigate(['/application-list']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
/* You can add global styles to this file, and also import other style files */
|
||||
|
||||
// @use './colors/variables' as *;
|
||||
// @use './colors/mixins' as *;
|
||||
// @use './colors/base' as *;
|
||||
html, body { height: 100%; }
|
||||
body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
|
||||
|
||||
Reference in New Issue
Block a user