Skip to content
This repository has been archived by the owner on Oct 14, 2022. It is now read-only.

Commit

Permalink
Merge pull request #33 from futureleadersupc/develop
Browse files Browse the repository at this point in the history
release: v0.1.0
  • Loading branch information
dalbitresb12 authored Jul 2, 2022
2 parents cdf7b4a + f824165 commit 8586d31
Show file tree
Hide file tree
Showing 11 changed files with 329 additions and 1 deletion.
32 changes: 32 additions & 0 deletions server/db.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,5 +175,37 @@
"salaryRange": "$135k-$157k",
"published": false
}
],
"companies": [
{
"id": 1,
"name": "Google Inc.",
"address": "Silicon Valley",
"email": "google@support.com"
},
{
"id": 2,
"name": "Microsoft Inc.",
"address": "Silicon Valley",
"email": "microsoft@support.com"
},
{
"id": 3,
"name": "Meta",
"address": "Silicon Valley",
"email": "meta@support.com"
},
{
"id": 4,
"name": "Apple Inc.",
"address": "Silicon Valley",
"email": "apple@support.com"
},
{
"id": 5,
"name": "Oracle",
"address": "Silicon Valley",
"email": "oracle@support.com"
}
]
}
2 changes: 2 additions & 0 deletions src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { JobsComponent } from "./jobs/pages/jobs/jobs.component";
import { JobsSearchComponent } from "./jobs/pages/jobs-search/jobs-search.component";
import { ResetpasswordComponent } from "./auth/pages/resetpassword/resetpassword.component";
import { ChangepasswordComponent } from "./auth/pages/changepassword/changepassword.component";
import { CompaniesComponent } from "./employers/pages/companies/companies.component";

const routes: Routes = [
{ path: "", redirectTo: "account/profile", pathMatch: "full" },
Expand All @@ -17,6 +18,7 @@ const routes: Routes = [
{ path: "account/search", component: JobsSearchComponent },
{ path: "account/resetpassword", component: ResetpasswordComponent },
{ path: "account/changepassword", component: ChangepasswordComponent },
{ path: "account/companies", component: CompaniesComponent },
];

@NgModule({
Expand Down
6 changes: 5 additions & 1 deletion src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import { JobsSearchComponent } from "./jobs/pages/jobs-search/jobs-search.compon
import { JobConfirmationDialogComponent } from "./jobs/components/job-confirmation-dialog/job-confirmation-dialog.component";
import { ChangepasswordComponent } from "./auth/pages/changepassword/changepassword.component";
import { ResetpasswordComponent } from "./auth/pages/resetpassword/resetpassword.component";
import { CompaniesComponent } from "./employers/pages/companies/companies.component";
import { FooterComponent } from "./common/components/footer/footer.component";

import { MatToolbarModule } from "@angular/material/toolbar";
import { MatIconModule } from "@angular/material/icon";
Expand All @@ -32,7 +34,7 @@ import { MatMenuModule } from "@angular/material/menu";
import { MatDialogModule } from "@angular/material/dialog";
import { MatSnackBarModule } from "@angular/material/snack-bar";
import { MatProgressBarModule } from "@angular/material/progress-bar";
import { FooterComponent } from "./common/components/footer/footer.component";
import { MatCardModule } from "@angular/material/card";

export const imports: NonNullable<NgModule["imports"]> = [
AppRoutingModule,
Expand All @@ -55,6 +57,7 @@ export const imports: NonNullable<NgModule["imports"]> = [
MatDialogModule,
MatSnackBarModule,
MatProgressBarModule,
MatCardModule,
];

@NgModule({
Expand All @@ -70,6 +73,7 @@ export const imports: NonNullable<NgModule["imports"]> = [
ResetpasswordComponent,
ChangepasswordComponent,
FooterComponent,
CompaniesComponent,
],
imports: [BrowserModule, ...imports],
providers: [],
Expand Down
6 changes: 6 additions & 0 deletions src/app/common/components/header/header.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ export class HeaderComponent extends UseUser implements OnInit, OnDestroy {
icon: "person",
visible: () => this.user !== null,
},
{
label: "Companies",
path: "account/companies",
icon: "apartment",
visible: () => this.user !== null,
},
{
label: "Settings",
path: "/account/settings",
Expand Down
6 changes: 6 additions & 0 deletions src/app/employers/model/company.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface Company {
id: number;
name: string;
address: string;
email: string;
}
Empty file.
84 changes: 84 additions & 0 deletions src/app/employers/pages/companies/companies.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<h1 class="my-8 text-center text-2xl font-semibold">Associate Companies</h1>
<section class="flex m-4 justify-center">
<h2 class="text-center font-medium text-lg py-8">
{{ isEditMode ? "Edit company information" : "Add new company" }}
</h2>
<form #companiesForm="ngForm" (submit)="handleSubmit()">
<mat-form-field appearance="fill" class="p-4">
<mat-label>Name</mat-label>
<input
matInput
#input
maxlength="100"
type="text"
name="name"
required
[(ngModel)]="this.currentCompany.name" />
<mat-hint align="start">
Max characters: {{ input.value?.length || 0 }}/100
</mat-hint>
</mat-form-field>
<mat-form-field appearance="fill" class="p-4">
<mat-label>Address</mat-label>
<input
matInput
maxlength="256"
type="text"
name="address"
[(ngModel)]="this.currentCompany.address" />
</mat-form-field>
<mat-form-field appearance="fill" class="p-4">
<mat-label>Email</mat-label>
<input
matInput
maxlength="256"
type="email"
name="email"
required
[(ngModel)]="this.currentCompany.email" />
</mat-form-field>
<button
mat-raised-button
class="box-border h-12 w-28"
type="submit"
color="primary"
aria-label="Button that displays a tooltip when focused or hovered over update or add icon"
[matTooltip]="(isEditMode ? 'Update' : 'Add') + ' company'">
{{ isEditMode ? "Update" : "Add" }}
</button>
<button
class="box-border h-12 w-28"
mat-raised-button
color="warn"
*ngIf="this.isEditMode"
(click)="this.cancelEdit()"
aria-label="Cancel company information edit"
matTooltip="Cancel company information edit">
Cancel
</button>
</form>
</section>
<div class="grid md:grid-cols-2 grid-cols-1 gap-4 m-4">
<div *ngFor="let item of dataSource">
<mat-card class="mat-elevation-z4">
<mat-card-title class="text-center"> {{ item.name }}</mat-card-title>
<mat-card-subtitle class="text-center">
{{ item.email }}
</mat-card-subtitle>
<mat-card-content class="font-medium text-lg">
{{ item.address }}
</mat-card-content>
<mat-card-actions align="end">
<button mat-icon-button (click)="this.editCompany(item)">
<mat-icon>edit</mat-icon>
</button>
<button
mat-icon-button
color="warn"
(click)="this.deleteCompany(item.id)">
<mat-icon>delete</mat-icon>
</button>
</mat-card-actions>
</mat-card>
</div>
</div>
27 changes: 27 additions & 0 deletions src/app/employers/pages/companies/companies.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ComponentFixture, TestBed } from "@angular/core/testing";

import { CompaniesComponent } from "./companies.component";

import { imports } from "src/app/app.module";

describe("CompaniesComponent", () => {
let component: CompaniesComponent;
let fixture: ComponentFixture<CompaniesComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [...imports],
declarations: [CompaniesComponent],
}).compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(CompaniesComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it("should create", () => {
expect(component).toBeTruthy();
});
});
74 changes: 74 additions & 0 deletions src/app/employers/pages/companies/companies.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { Component, OnInit, ViewChild } from "@angular/core";
import { NgForm } from "@angular/forms";
import { Company } from "../../model/company";
import { CompaniesService } from "../../services/companies.service";

@Component({
selector: "app-companies",
templateUrl: "./companies.component.html",
styleUrls: ["./companies.component.css"],
})
export class CompaniesComponent implements OnInit {
currentCompany: Partial<Company> = {};
dataSource: Company[] = [];

@ViewChild("companiesForm", { static: false })
companiesForm!: NgForm;

constructor(private companiesService: CompaniesService) {}

get isEditMode() {
return !!this.currentCompany.id;
}

ngOnInit() {
this.getAll();
}

getAll() {
this.companiesService.getAll().subscribe(response => {
this.dataSource = response;
});
}

createCompany(company: Company) {
this.companiesService.create(company).subscribe(response => {
this.dataSource = [...this.dataSource, response];
});
}

editCompany(company: Company) {
this.currentCompany = { ...company };
}

cancelEdit() {
this.currentCompany = {};
this.companiesForm.resetForm();
}

updateCompany(id: number, company: Company) {
this.companiesService.update(id, company).subscribe(response => {
this.dataSource = this.dataSource.map(current => {
if (current.id === id) return response;
return current;
});
});
}

deleteCompany(id: number) {
this.companiesService.delete(id).subscribe(() => {
this.dataSource = this.dataSource.filter(current => current.id !== id);
});
}

handleSubmit() {
if (!this.companiesForm.form.valid) return;
const company = this.currentCompany as Company;
if (this.isEditMode) {
this.updateCompany(company.id, company);
} else {
this.createCompany(company);
}
this.cancelEdit();
}
}
19 changes: 19 additions & 0 deletions src/app/employers/services/companies.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { HttpClientModule } from "@angular/common/http";
import { TestBed } from "@angular/core/testing";

import { CompaniesService } from "./companies.service";

describe("CompaniesService", () => {
let service: CompaniesService;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientModule],
});
service = TestBed.inject(CompaniesService);
});

it("should be created", () => {
expect(service).toBeTruthy();
});
});
74 changes: 74 additions & 0 deletions src/app/employers/services/companies.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {
HttpClient,
HttpErrorResponse,
HttpHeaders,
} from "@angular/common/http";
import { Injectable } from "@angular/core";
import { catchError, Observable, retry, throwError } from "rxjs";
import { environment } from "src/environments/environment";
import { Company } from "../model/company";

@Injectable({
providedIn: "root",
})
export class CompaniesService {
private basePath = `${environment.apiUrlBase}/companies`;

private httpOptions = {
headers: new HttpHeaders({
"Content-Type": "application/json",
}),
};

constructor(private http: HttpClient) {}

handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
console.error(
`An error ocurred ${error.status}, body was ${error.error}`
);
} else {
console.error(
`Backend returned code ${error.status}, body was: ${error.error}`
);
}
return throwError(
() =>
new Error("Something happened with request, please try again later.")
);
}

create(company: Company): Observable<Company> {
return this.http
.post<Company>(this.basePath, JSON.stringify(company), this.httpOptions)
.pipe(retry(2), catchError(this.handleError));
}

getAll(): Observable<Company[]> {
return this.http
.get<Company[]>(this.basePath, this.httpOptions)
.pipe(retry(2), catchError(this.handleError));
}

getById(id: number): Observable<Company> {
return this.http
.get<Company>(`${this.basePath}/${id}`, this.httpOptions)
.pipe(retry(2), catchError(this.handleError));
}

update(id: number, item: Company): Observable<Company> {
return this.http
.put<Company>(
`${this.basePath}/${id}`,
JSON.stringify(item),
this.httpOptions
)
.pipe(retry(2), catchError(this.handleError));
}

delete(id: number) {
return this.http
.delete(`${this.basePath}/${id}`, this.httpOptions)
.pipe(retry(2), catchError(this.handleError));
}
}

0 comments on commit 8586d31

Please sign in to comment.