diff --git a/README.md b/README.md
index 96842c6..464fdfe 100644
--- a/README.md
+++ b/README.md
@@ -55,5 +55,18 @@ ng e2e
Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
## Additional Resources
-
+## TODO
For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
+-fix picture upload
+-implement picture loader
+-use leaflet for map implementation
+-implement websockets
+-implement graph
+-implement total visits
+-search and filters (by name, city, age, etc.)
+-navigation between candidates (next/previous) (signals)
+-edit page
+-implement live update
+
+****animations transitions (prev next cards)
+------
diff --git a/angular.json b/angular.json
index 662396c..7ea7792 100644
--- a/angular.json
+++ b/angular.json
@@ -63,6 +63,17 @@
"with": "src/environments/environment.development.ts"
}
]
+ },
+ "remote-api": {
+ "optimization": false,
+ "extractLicenses": false,
+ "sourceMap": true,
+ "fileReplacements": [
+ {
+ "replace": "src/environments/environment.ts",
+ "with": "src/environments/environment.remote-api.ts"
+ }
+ ]
}
},
"defaultConfiguration": "production"
@@ -75,6 +86,9 @@
},
"development": {
"buildTarget": "IISA_web:build:development"
+ },
+ "remote-api": {
+ "buildTarget": "IISA_web:build:remote-api"
}
},
"defaultConfiguration": "development"
diff --git a/package.json b/package.json
index 6652cc0..dc542af 100644
--- a/package.json
+++ b/package.json
@@ -4,6 +4,7 @@
"scripts": {
"ng": "ng",
"start": "ng serve",
+ "start:remote-api":"ng serve --configuration=remote-api",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts
index 3b98114..f436384 100644
--- a/src/app/app.routes.ts
+++ b/src/app/app.routes.ts
@@ -1,7 +1,15 @@
import { Routes } from '@angular/router';
import { RegistrationComponent } from './registration/registration.component';
+import { LandingComponent } from './landing/landing.component';
+import { ApplicationListComponent } from './application-list/application-list.component';
+import { ApplicationComponent } from './application/application.component';
export const routes: Routes = [
- { path: 'register', component: RegistrationComponent },
- { path: '', redirectTo: '/register', pathMatch: 'full' },
+ { path: 'landing', component: LandingComponent },
+ { path: 'registration', component: RegistrationComponent },
+ { path: 'application-list', component: ApplicationListComponent },
+ { path: 'application/:id', component: ApplicationComponent },
+ { path: '', redirectTo: '/landing', pathMatch: 'full' },
+ { path: '**', redirectTo: '/landing' },
+ // component: PageNotFoundComponent
];
diff --git a/src/app/application-list/application-list.component.html b/src/app/application-list/application-list.component.html
new file mode 100644
index 0000000..2ce37fd
--- /dev/null
+++ b/src/app/application-list/application-list.component.html
@@ -0,0 +1,5 @@
+@for(application of this.applicationList; track application.id){
+
+
{{application.fullName}}
+
+}
\ No newline at end of file
diff --git a/src/app/application-list/application-list.component.scss b/src/app/application-list/application-list.component.scss
new file mode 100644
index 0000000..aa84483
--- /dev/null
+++ b/src/app/application-list/application-list.component.scss
@@ -0,0 +1,9 @@
+.listItem {
+ margin: 2rem;
+ background-color: aquamarine;
+ padding: 1rem;
+ &:hover{
+ cursor: pointer;
+ background-color: aqua;
+ }
+}
\ No newline at end of file
diff --git a/src/app/application-list/application-list.component.ts b/src/app/application-list/application-list.component.ts
new file mode 100644
index 0000000..db74ea0
--- /dev/null
+++ b/src/app/application-list/application-list.component.ts
@@ -0,0 +1,23 @@
+import { Component, inject, OnInit } from '@angular/core';
+import { CandidateDataService } from '../candidate-data.service';
+import { RouterLink } from '@angular/router';
+
+@Component({
+ selector: 'app-application-list',
+ imports: [RouterLink],
+ templateUrl: './application-list.component.html',
+ styleUrl: './application-list.component.scss'
+})
+export class ApplicationListComponent implements OnInit {
+
+ dataService = inject(CandidateDataService);
+ applicationList: any[] = [];
+
+ ngOnInit(): void {
+ this.dataService.loadCandidateList().subscribe((data) => {
+ this.applicationList = data;
+ });
+
+ }
+
+}
diff --git a/src/app/application/application.component.html b/src/app/application/application.component.html
new file mode 100644
index 0000000..a94ee3c
--- /dev/null
+++ b/src/app/application/application.component.html
@@ -0,0 +1 @@
+{{this.application}}
\ No newline at end of file
diff --git a/src/app/application/application.component.scss b/src/app/application/application.component.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/application/application.component.ts b/src/app/application/application.component.ts
new file mode 100644
index 0000000..44fb9c7
--- /dev/null
+++ b/src/app/application/application.component.ts
@@ -0,0 +1,28 @@
+import { Component, inject, OnInit } from '@angular/core';
+import { CandidateDataService } from '../candidate-data.service';
+import { ActivatedRoute, RouterModule } from '@angular/router';
+
+@Component({
+ selector: 'app-application',
+ imports: [RouterModule],
+ templateUrl: './application.component.html',
+ styleUrl: './application.component.scss'
+})
+export class ApplicationComponent implements OnInit {
+ dataService = inject(CandidateDataService);
+ activatedRoute = inject(ActivatedRoute);
+ application: any = {};
+
+ ngOnInit(): void {
+ const id = this.activatedRoute.snapshot.paramMap.get('id');
+ if (!id) {
+ alert('invalid route');
+ return;
+ }
+ const applicationId = Number.parseInt(id, 10);
+ this.dataService.getApplicationDetails(applicationId).subscribe((data) => {
+ this.application = JSON.stringify(data);
+ })
+ }
+
+}
diff --git a/src/app/candidate-data.service.ts b/src/app/candidate-data.service.ts
index 5b9ec89..17e33ad 100644
--- a/src/app/candidate-data.service.ts
+++ b/src/app/candidate-data.service.ts
@@ -1,5 +1,6 @@
import { HttpClient } from "@angular/common/http";
import { inject, Injectable } from "@angular/core";
+import { environment } from "../environments/environment.development";
@Injectable({
providedIn: 'root'
@@ -7,13 +8,16 @@ import { inject, Injectable } from "@angular/core";
export class CandidateDataService {
httpClient = inject(HttpClient)
- response: any | null = null;
- error: any | null = null;
- sendRequest() {
- this.httpClient.get('http://localhost:3000/app/candidates').subscribe({
- next: (res) => this.response = JSON.stringify(res),
- error: err => this.error = JSON.stringify(err)
- })
+ loadCandidateList() {
+ return this.httpClient.get(`${environment.hostUrl}/app/candidates`);
}
+ getApplicationDetails(id: number) {
+ return this.httpClient.get(`${environment.hostUrl}/app/candidate/${id}`)
+ }
+ submitCandidateForm(formData: Object) {
+ return this.httpClient.post(`${environment.hostUrl}/app/register`, formData);
+ }
+
+
}
\ No newline at end of file
diff --git a/src/app/landing/landing.component.html b/src/app/landing/landing.component.html
new file mode 100644
index 0000000..0fbbd11
--- /dev/null
+++ b/src/app/landing/landing.component.html
@@ -0,0 +1,7 @@
+landing works!
+
+
\ No newline at end of file
diff --git a/src/app/landing/landing.component.scss b/src/app/landing/landing.component.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/landing/landing.component.ts b/src/app/landing/landing.component.ts
new file mode 100644
index 0000000..a2026cb
--- /dev/null
+++ b/src/app/landing/landing.component.ts
@@ -0,0 +1,15 @@
+import { Component } from '@angular/core';
+import { MatButtonModule } from '@angular/material/button';
+import { RouterLink } from '@angular/router';
+import { RouterLinkActive } from "../../../node_modules/@angular/router/router_module.d-Bx9ArA6K";
+
+@Component({
+ selector: 'app-landing',
+ imports: [MatButtonModule, RouterLink,],
+ templateUrl: './landing.component.html',
+ styleUrl: './landing.component.scss'
+})
+export class LandingComponent {
+
+
+}
diff --git a/src/app/registration/registration.component.html b/src/app/registration/registration.component.html
index 7029104..2a71816 100644
--- a/src/app/registration/registration.component.html
+++ b/src/app/registration/registration.component.html
@@ -13,7 +13,7 @@
-->
-
+
Full Name
@@ -37,13 +37,13 @@
Phone Number
-
- @if (form.get('phone')?.hasError('required')) {
+
+ @if (form.get('phoneNumber')?.hasError('required')) {
Phone number is required
}
- @if (form.get('phone')?.hasError('pattern')){
+ @if (form.get('phoneNumber')?.hasError('pattern')){
Invalid phone number
@@ -62,8 +62,8 @@
City / Region
-
- @if (form.get('city')?.hasError('required')) {
+
+ @if (form.get('cityOrRegion')?.hasError('required')) {
Field is required
@@ -82,13 +82,13 @@
Why I am the perfect candidate
-
- @if (form.get('reason')?.hasError('required')) {
+
+ @if (form.get('justification')?.hasError('required')) {
Field is required
}
- @if (form.get('reason')?.hasError('maxLength')) {
+ @if (form.get('justification')?.hasError('maxLength')) {
Maximum length is 300 characters
diff --git a/src/app/registration/registration.component.ts b/src/app/registration/registration.component.ts
index 14aefa5..b47572d 100644
--- a/src/app/registration/registration.component.ts
+++ b/src/app/registration/registration.component.ts
@@ -7,6 +7,7 @@ import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatFormFieldModule } from '@angular/material/form-field';
import { ImageInputComponent } from "../image-input/image-input.component";
+import { CandidateDataService } from '../candidate-data.service';
const israeliPhoneRegex = /^(?:(?:(\+?972|\(\+?972\)|\+?\(972\))(?:\s|\.|-)?([1-9]\d?))|(0[23489]{1})|(0[57]{1}[0-9]))(?:\s|\.|-)?([^0\D]{1}\d{2}(?:\s|\.|-)?\d{4})$/;
@Component({
@@ -19,24 +20,24 @@ const israeliPhoneRegex = /^(?:(?:(\+?972|\(\+?972\)|\+?\(972\))(?:\s|\.|-)?([1-
MatCardModule,
MatFormFieldModule,
ImageInputComponent
-],
+ ],
templateUrl: './registration.component.html',
styleUrls: ['./registration.component.scss'],
})
export class RegistrationComponent implements OnInit {
-
+ dataService = inject(CandidateDataService);
fb = inject(FormBuilder);
previewUrl: string | ArrayBuffer | null = null;
form = this.fb.group({
fullName: ['', [Validators.required, Validators.minLength(3)]],
email: ['', [Validators.required, Validators.email]],
- phone: ['', [Validators.required, Validators.pattern(israeliPhoneRegex)]],
+ phoneNumber: ['', [Validators.required, Validators.pattern(israeliPhoneRegex)]],
age: [0, [Validators.required, Validators.min(18), Validators.max(70)]],
- city: ['', Validators.required],
+ cityOrRegion: ['', Validators.required],
hobbies: ['', [Validators.maxLength(300)]],
- reason: ['', [Validators.required, Validators.maxLength(300)]],
- profileImage: this.fb.control(null, Validators.required),
+ justification: ['', [Validators.required, Validators.maxLength(300)]],
+ // profileImage: this.fb.control(null, Validators.required),
});
ngOnInit(): void {
@@ -53,31 +54,29 @@ export class RegistrationComponent implements OnInit {
}
}
- onFileSelected(event: any) {
- const file = event.target.files[0];
- if (file) {
- const reader = new FileReader();
- reader.onload = () => {
- if (typeof reader.result === 'string') {
- this.previewUrl = reader.result;
- this.form.patchValue({ profileImage: reader.result });
- }
- };
- reader.readAsDataURL(file);
- }
- }
+ // onFileSelected(event: any) {
+ // const file = event.target.files[0];
+ // if (file) {
+ // const reader = new FileReader();
+ // reader.onload = () => {
+ // if (typeof reader.result === 'string') {
+ // this.previewUrl = reader.result;
+ // this.form.patchValue({ profileImage: reader.result });
+ // }
+ // };
+ // reader.readAsDataURL(file);
+ // }
+ // }
onSubmit() {
- if (this.form.valid) {
- localStorage.setItem(
- 'registration',
- JSON.stringify({
- data: this.form.value,
- timestamp: Date.now(),
- })
- );
- alert('✅ Application saved! You can re-edit within 3 days.');
+ if (!this.form.valid) {
+ alert("Invalid Form");
+ return;
}
+ console.log(JSON.stringify(this.form.value));
+ this.dataService.submitCandidateForm(this.form.value).subscribe(() => {
+ alert('✅ Application saved! You can re-edit within 3 days.')
+ });
}
onCheckErrors() {
diff --git a/src/environments/environment.development.ts b/src/environments/environment.development.ts
index f274e5e..3a769d3 100644
--- a/src/environments/environment.development.ts
+++ b/src/environments/environment.development.ts
@@ -1 +1,3 @@
-export const environment = {};
+export const environment = {
+ hostUrl: 'http://localhost:3000'
+};
diff --git a/src/environments/environment.remote-api.ts b/src/environments/environment.remote-api.ts
new file mode 100644
index 0000000..647037f
--- /dev/null
+++ b/src/environments/environment.remote-api.ts
@@ -0,0 +1,3 @@
+export const environment = {
+ hostUrl: 'https://iisa.novikov.click'
+};
diff --git a/src/environments/environment.ts b/src/environments/environment.ts
index f274e5e..839370b 100644
--- a/src/environments/environment.ts
+++ b/src/environments/environment.ts
@@ -1 +1,3 @@
-export const environment = {};
+export const environment = {
+ hostUrl: ''
+};
diff --git a/src/main.ts b/src/main.ts
index 35b00f3..fb4555f 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,6 +1,7 @@
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';
+import { environment } from './environments/environment';
-bootstrapApplication(AppComponent, appConfig)
+bootstrapApplication(AppComponent, appConfig).then(()=>{console.log(JSON.stringify(environment))})
.catch((err) => console.error(err));