first commit
This commit is contained in:
@@ -0,0 +1,249 @@
|
||||
<div class="content ml-2">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card" style="padding: 20px">
|
||||
<div class="card-header">
|
||||
<h5 class="title">Company Information</h5>
|
||||
</div>
|
||||
<div class="card-body all-icons">
|
||||
<div class="card-child-content">
|
||||
<div class="font-icon-list box mr-3">
|
||||
<div class="font-icon-detail px-3">
|
||||
<i class="bi bi-person-vcard-fill"></i>
|
||||
<h2 class="fw-bolder">Company Information</h2>
|
||||
</div>
|
||||
<div class="card-child-contentOne">
|
||||
<div>
|
||||
<p><strong>Name:</strong> {{ company.name }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p><strong>Email:</strong> {{ company.email }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p><strong>Company Phone:</strong> {{ company.phone }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p><strong>Address:</strong> {{ company.phone }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<strong>Staging URL:</strong>
|
||||
<a> {{ company.stagingUrl }}</a>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<strong>Production URL:</strong>
|
||||
<a> {{ company.productionUrl }}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="font-icon-list box">
|
||||
<div class="font-icon-detail px-3">
|
||||
<i class="bi bi-pc-display"></i>
|
||||
<h2 class="fw-bolder">Hosting Information</h2>
|
||||
</div>
|
||||
|
||||
<div class="card-child-contentTwo">
|
||||
<div>
|
||||
<p>
|
||||
<strong>Hosting Provider:</strong>
|
||||
{{ hostingInfo.provider }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<strong>Server Type:</strong>
|
||||
<span class="text-capitalize">{{
|
||||
hostingInfo.serverType
|
||||
}}</span>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<strong> Disk Space (GB) :</strong>
|
||||
{{ hostingInfo.diskSpaceGB }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<strong> Bandwidth (GB) :</strong>
|
||||
{{ hostingInfo.bandwidthGB }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<strong>Username:</strong> {{ hostingInfo.username }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p><strong>Password:</strong> {{ hostingInfo.password }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<strong>Server Location: </strong>
|
||||
{{ hostingInfo.serverLocation }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<strong>Expiration Date: </strong>
|
||||
{{ timeDiff }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="font-icon-list box">
|
||||
<div class="font-icon-detail px-3">
|
||||
<i class="bi bi-hdd-rack"></i>
|
||||
<h2 class="fw-bolder">Server Information</h2>
|
||||
</div>
|
||||
|
||||
<div class="card-child-contentThree">
|
||||
<div>
|
||||
<p>
|
||||
<strong>Server Type:</strong>
|
||||
<span class="text-capitalize">{{
|
||||
serverInfo.serverType
|
||||
}}</span>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<strong>Operating System:</strong>
|
||||
{{ serverInfo.operatingSystem }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p><strong>CPU:</strong> PROCESSOR</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<strong>Storage (GB):</strong> {{ serverInfo.storageGB }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p><strong>RAM (GB): </strong> {{ serverInfo.ramGB }}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
<strong>Bandwidth (GB): </strong>
|
||||
{{ serverInfo.bandwidthGB }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
<strong>Monthly Cost (USD): </strong>
|
||||
{{ serverInfo.monthlyCostUSD }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p><strong>Location: </strong> {{ serverInfo.location }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="font-icon-list box">
|
||||
<div class="font-icon-detail px-3">
|
||||
<i class="bi bi-database"></i>
|
||||
<h2 class="fw-bolder">Database Information</h2>
|
||||
</div>
|
||||
|
||||
<div class="card-child-contentFour">
|
||||
<div>
|
||||
<p>
|
||||
<strong>Database Name:</strong>
|
||||
{{ databaseInfo.databaseName }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<strong>Database Type:</strong>
|
||||
{{ databaseInfo.databaseType }}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p>
|
||||
<strong>Bandwidth: </strong>
|
||||
{{ databaseInfo.bandwidthGB }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p><strong>Username:</strong> {{ databaseInfo.username }}</p>
|
||||
</div>
|
||||
<div>
|
||||
<p><strong>Password: </strong> {{ databaseInfo.password }}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
<strong>Database Host: </strong> {{ databaseInfo.host }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>
|
||||
<strong>Database Port Number: </strong>
|
||||
{{ databaseInfo.port }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="font-icon-list col-md-4 col-sm-6 col-xs-12">
|
||||
<div class="font-icon-detail">
|
||||
<i class="bi bi-telephone"></i>
|
||||
<p><strong>Phone:</strong> PHONE</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="font-icon-list col-md-4 col-sm-6 col-xs-12">
|
||||
<div class="font-icon-detail">
|
||||
<i class="bi bi-journal-richtext"></i>
|
||||
<p><strong>Description:</strong> About Company</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="font-icon-list col-md-4 col-sm-6 col-xs-12">
|
||||
<div class="font-icon-detail">
|
||||
<i class="bi bi-pin-map"></i>
|
||||
<p><strong>Address:</strong> ADDRESS</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="font-icon-list col-md-4 col-sm-6 col-xs-12">
|
||||
<div class="font-icon-detail">
|
||||
<i class="bi bi-buildings"></i>
|
||||
<p><strong>City:</strong> CITY</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="font-icon-list col-md-4 col-sm-6 col-xs-12">
|
||||
<div class="font-icon-detail">
|
||||
<i class="bi bi-link-45deg"></i>
|
||||
<p>
|
||||
<strong>Staging URL:</strong>
|
||||
<a href="#" target="_blank"> COMPANY URL </a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="font-icon-list col-md-4 col-sm-6 col-xs-12">
|
||||
<div class="font-icon-detail">
|
||||
<i class="bi bi-link-45deg"></i>
|
||||
<p>
|
||||
<strong>Production URL:</strong>
|
||||
<a href="#" target="_blank"> COMPANY URL </a>
|
||||
</p>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,23 @@
|
||||
.card-child-content {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-gap: 1rem;
|
||||
padding: 1rem;
|
||||
.box {
|
||||
border-radius: 10px !important;
|
||||
box-shadow: inset 5px 5px 5px rgba(0, 0, 0, 0.05),
|
||||
inset -5px -5px 5px rgba(255, 255, 255, 0.05),
|
||||
5px 5px 5px rgba(0, 0, 0, 0.05), -5px -5px 5px rgba(255, 255, 255, 0.05) !important;
|
||||
}
|
||||
|
||||
.card-child-contentOne,
|
||||
.card-child-contentTwo,
|
||||
.card-child-contentThree,
|
||||
.card-child-contentFour {
|
||||
padding: 15px;
|
||||
|
||||
strong {
|
||||
font-weight: 600 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CompanyInformationComponent } from './company-information.component';
|
||||
|
||||
describe('CompanyInformationComponent', () => {
|
||||
let component: CompanyInformationComponent;
|
||||
let fixture: ComponentFixture<CompanyInformationComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ CompanyInformationComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CompanyInformationComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,84 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { CompanyModel } from "../../models/company";
|
||||
import { HostingInfoModel } from "../../models/hosting-info";
|
||||
import { DatabaseInfoModel } from "../../models/database-info";
|
||||
import { ServerInfoModel } from "../../models/server-info";
|
||||
import { CompanyService } from "../../services/company.service";
|
||||
import { HostingInfoService } from "../../services/hosting-info.service";
|
||||
import { DatabaseInfoService } from "../../services/database-info.service";
|
||||
import { ServerInfoService } from "../../services/server-info.service";
|
||||
|
||||
@Component({
|
||||
selector: "app-company-information",
|
||||
templateUrl: "./company-information.component.html",
|
||||
styleUrls: ["./company-information.component.scss"],
|
||||
})
|
||||
export class CompanyInformationComponent implements OnInit {
|
||||
company: CompanyModel;
|
||||
hostingInfo: HostingInfoModel;
|
||||
databaseInfo: DatabaseInfoModel;
|
||||
serverInfo: ServerInfoModel;
|
||||
companyLocalStorage: any;
|
||||
timeDiff: any;
|
||||
|
||||
constructor(
|
||||
private companyService: CompanyService,
|
||||
private hostingInfoService: HostingInfoService,
|
||||
private databaseInfoService: DatabaseInfoService,
|
||||
private serverInfoService: ServerInfoService
|
||||
) {
|
||||
this.companyService.getCompanyById(1).subscribe((company) => {
|
||||
this.company = company;
|
||||
console.log("Company: ", this.company);
|
||||
});
|
||||
|
||||
this.hostingInfoService.getHostingInfoById(2).subscribe((hostingInfo) => {
|
||||
this.hostingInfo = hostingInfo;
|
||||
console.log("Hosting Info: ", this.hostingInfo);
|
||||
|
||||
this.timeDiff = this.calculateTimeDiff(this.hostingInfo.expirationDate);
|
||||
console.log("Time Diff: ", this.timeDiff);
|
||||
});
|
||||
|
||||
this.databaseInfoService
|
||||
.getDatabaseInfoById(1)
|
||||
.subscribe((databaseInfo) => {
|
||||
this.databaseInfo = databaseInfo;
|
||||
console.log("Database Info: ", this.databaseInfo);
|
||||
});
|
||||
|
||||
this.serverInfoService.getServerInfoById(1).subscribe((serverInfo) => {
|
||||
this.serverInfo = serverInfo;
|
||||
console.log("Server Info: ", this.serverInfo);
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
// Calculate time difference between current time and expiration time
|
||||
calculateTimeDiff(date: any) {
|
||||
const currentDate = new Date();
|
||||
const hostingInfoDate = new Date(date);
|
||||
const diff = hostingInfoDate.getTime() - currentDate.getTime();
|
||||
const resultInMinutes = Math.round(diff / 60000);
|
||||
const resultInHours = Math.round(diff / 3600000);
|
||||
const resultInDays = Math.round(diff / 86400000);
|
||||
const resultInWeeks = Math.round(diff / 604800000);
|
||||
const resultInMonths = Math.round(diff / 2628000000);
|
||||
const resultInYears = Math.round(diff / 31536000000);
|
||||
|
||||
if (resultInMinutes < 60) {
|
||||
return resultInMinutes + " minutes left";
|
||||
} else if (resultInHours < 24) {
|
||||
return resultInHours + " hours left";
|
||||
} else if (resultInDays < 7) {
|
||||
return resultInDays + " days left";
|
||||
} else if (resultInWeeks < 4) {
|
||||
return resultInWeeks + " weeks left";
|
||||
} else if (resultInMonths < 12) {
|
||||
return resultInMonths + " months left";
|
||||
} else {
|
||||
return resultInYears + " years left";
|
||||
}
|
||||
}
|
||||
}
|
||||
443
src/app/pages/company-profile/company-profile.component.html
Normal file
443
src/app/pages/company-profile/company-profile.component.html
Normal file
@@ -0,0 +1,443 @@
|
||||
<div class="companyProfile content">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header"><h5 class="title">Edit Profile</h5></div>
|
||||
<div class="card-body companyProfileBody">
|
||||
<form
|
||||
(ngSubmit)="updateInfo()"
|
||||
[formGroup]="updateInfoForm"
|
||||
novalidate
|
||||
>
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="form-group mb-5">
|
||||
<div
|
||||
class="institutionDashboard__editInfoFormGroup input-group inputField__uploadFile"
|
||||
>
|
||||
<input
|
||||
type="file"
|
||||
name="companyLogo"
|
||||
|
||||
style="display: none"
|
||||
id="avatar-image"
|
||||
accept="image/*"
|
||||
(change)="onFileChange($event)"
|
||||
/>
|
||||
<label
|
||||
for="avatar-image"
|
||||
style="
|
||||
background: linear-gradient(
|
||||
rgb(72, 0, 72, 0.8),
|
||||
rgb(192, 72, 72, 0.8)
|
||||
); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
|
||||
background-size: cover;
|
||||
border-radius: 50%;
|
||||
padding: 2px;
|
||||
width: 90px;
|
||||
height: 90px;
|
||||
filter: drop-shadow(2px 4px 6px black);
|
||||
"
|
||||
>
|
||||
<!-- <img
|
||||
class="image-avatar"
|
||||
style="
|
||||
height: 85px;
|
||||
width: 85px;
|
||||
border-radius: 50%;
|
||||
"
|
||||
[src]="imgSrc ? imgSrc : institutionData.image"
|
||||
alt="avatar"
|
||||
/> -->
|
||||
|
||||
<img
|
||||
class="image-avatar"
|
||||
style="height: 85px; width: 85px; border-radius: 50%"
|
||||
[src]="imgSrc"
|
||||
alt="avatar"
|
||||
/>
|
||||
<div
|
||||
class="upload__icon"
|
||||
style="
|
||||
position: absolute;
|
||||
left: 32%;
|
||||
bottom: 24%;
|
||||
color: white;
|
||||
filter: opacity(0.85);
|
||||
"
|
||||
>
|
||||
<i
|
||||
class="bi bi-upload fw-bolder"
|
||||
style="font-size: 2.2rem"
|
||||
></i>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="companyEditForm--error">
|
||||
<ng-container
|
||||
*ngIf="
|
||||
formControls.companyLogo.touched &&
|
||||
formControls.companyLogo.invalid
|
||||
"
|
||||
class="alert alert-danger"
|
||||
>
|
||||
<div *ngIf="formControls.companyLogo.errors?.required">
|
||||
Image file is required
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container
|
||||
*ngIf="imgFormatError"
|
||||
class="alert alert-danger"
|
||||
>
|
||||
<div
|
||||
id="imageError"
|
||||
aria-live="assertive"
|
||||
style="color: crimson; font-weight: 700"
|
||||
>
|
||||
File type not supported.
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="fileSizeError">
|
||||
<div
|
||||
id="imageError"
|
||||
style="color: crimson; font-weight: 700"
|
||||
>
|
||||
File size must be less than 2 MB.
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 pr-md-1">
|
||||
<div class="form-group">
|
||||
<label for="companyName"> Company (disabled) </label>
|
||||
<input
|
||||
class="form-control"
|
||||
disabled=""
|
||||
id="companyName"
|
||||
type="text"
|
||||
formControlName="companyName"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 px-md-1">
|
||||
<div class="form-group">
|
||||
<label for="companyUsername"> Username </label>
|
||||
<input
|
||||
class="form-control"
|
||||
disabled=""
|
||||
type="text"
|
||||
id="companyUsername"
|
||||
formControlName="companyUsername"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6 pr-md-1">
|
||||
<div class="form-group">
|
||||
<label for="companyName"> Company Name </label>
|
||||
<input
|
||||
id="companyName"
|
||||
class="form-control"
|
||||
placeholder="Company"
|
||||
type="text"
|
||||
formControlName="companyName"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="companyEditForm--error">
|
||||
<ng-container
|
||||
*ngIf="
|
||||
formControls.companyName.touched &&
|
||||
formControls.companyName.errors?.minlength
|
||||
"
|
||||
>
|
||||
<div id="instituionNameError" aria-live="assertive">
|
||||
<i class="bi bi-exclamation-octagon"></i>
|
||||
<span>Company Name must be at least 6 characters</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container
|
||||
*ngIf="
|
||||
formControls.companyName.errors?.required &&
|
||||
formControls.companyName?.touched
|
||||
"
|
||||
>
|
||||
<div id="institutionNameError" aria-live="assertive">
|
||||
<i class="bi bi-x"></i>
|
||||
<span>Company Name Required</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 pl-md-1">
|
||||
<div class="form-group">
|
||||
<label for="companyEmail"> Email Address </label>
|
||||
<input
|
||||
id="companyEmail"
|
||||
class="form-control"
|
||||
placeholder="Company Email"
|
||||
type="email"
|
||||
formControlName="companyEmail"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="companyEditForm--error mt-1">
|
||||
<ng-container
|
||||
*ngIf="
|
||||
formControls.companyEmail.invalid &&
|
||||
(formControls.companyEmail.dirty ||
|
||||
formControls.companyEmail.touched)
|
||||
"
|
||||
>
|
||||
<div id="emailError" aria-live="assertive">
|
||||
<i class="bi bi-x"> </i>
|
||||
<span>Email Required</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container
|
||||
*ngIf="formControls.companyEmail.errors?.pattern"
|
||||
>
|
||||
<div id="emailError" aria-live="assertive">
|
||||
<i class="bi bi-exclamation-octagon"></i>
|
||||
<span>Please enter a valid email</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="form-group">
|
||||
<label for="companyAddress"> Enter Address </label>
|
||||
<input
|
||||
class="form-control"
|
||||
placeholder="Company Address"
|
||||
type="text"
|
||||
id="companyAddress"
|
||||
formControlName="companyAddress"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="companyEditForm--error">
|
||||
<ng-container
|
||||
*ngIf="
|
||||
formControls.companyAddress.touched &&
|
||||
formControls.companyAddress.errors?.minlength
|
||||
"
|
||||
>
|
||||
<div id="addressError" aria-live="assertive">
|
||||
<i class="bi bi-exclamation-octagon"></i>
|
||||
<span>Company Address must be at least 6 characters</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container
|
||||
*ngIf="
|
||||
formControls.companyAddress.invalid &&
|
||||
(formControls.companyAddress.dirty ||
|
||||
formControls.companyAddress.touched)
|
||||
"
|
||||
>
|
||||
<div id="addressError" aria-live="assertive">
|
||||
<i class="bi bi-x"></i>
|
||||
<span>Company Address Required</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 pr-md-1">
|
||||
<div class="form-group">
|
||||
<label for="companyPhone">Phone </label>
|
||||
<input
|
||||
class="form-control"
|
||||
placeholder="Company Phone Number"
|
||||
type="text"
|
||||
id="companyPhone"
|
||||
formControlName="companyPhone"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="companyEditForm--error mt-1">
|
||||
<ng-container
|
||||
*ngIf="
|
||||
formControls.companyPhone.errors?.required &&
|
||||
formControls.companyPhone?.touched
|
||||
"
|
||||
class="alert alert-danger"
|
||||
>
|
||||
<div id="phoneNumberError" aria-live="assertive">
|
||||
<i class="bi bi-x"> </i>
|
||||
<span>Phone Number Required</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container
|
||||
*ngIf="formControls.companyPhone.errors?.minlength"
|
||||
>
|
||||
<div id="phoneNumberError" aria-live="assertive">
|
||||
<i class="bi bi-exclamation-octagon"></i>
|
||||
<span>Phone number must be at least 11 characters</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container
|
||||
*ngIf="formControls.companyPhone.errors?.pattern"
|
||||
>
|
||||
<div id="phoneNumberError" aria-live="assertive">
|
||||
<i class="bi bi-x"> </i>
|
||||
<span
|
||||
>Please enter a valid phone number (e.g.
|
||||
090321...)</span
|
||||
>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 pl-md-1">
|
||||
<div class="form-group">
|
||||
<label for="companyCity"> City </label>
|
||||
<input
|
||||
class="form-control"
|
||||
placeholder="City"
|
||||
type="text"
|
||||
id="companyCity"
|
||||
formControlName="companyCity"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="companyEditForm--error">
|
||||
<ng-container
|
||||
*ngIf="
|
||||
formControls.companyCity.touched &&
|
||||
formControls.companyCity.errors?.minlength
|
||||
"
|
||||
>
|
||||
<div id="addressError" aria-live="assertive">
|
||||
<i class="bi bi-exclamation-octagon"></i>
|
||||
<span>Company City must be at least 6 characters</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container
|
||||
*ngIf="
|
||||
formControls.companyCity.invalid &&
|
||||
(formControls.companyCity.dirty ||
|
||||
formControls.companyCity.touched)
|
||||
"
|
||||
>
|
||||
<div id="addressError" aria-live="assertive">
|
||||
<i class="bi bi-x"></i>
|
||||
<span>Company City Required</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="form-group">
|
||||
<label for="companyDescription"> About Company </label>
|
||||
<textarea
|
||||
class="form-control"
|
||||
placeholder="Company description"
|
||||
id="companyDescription"
|
||||
rows="4"
|
||||
formControlName="companyDescription"
|
||||
>
|
||||
</textarea>
|
||||
</div>
|
||||
|
||||
<div class="companyEditForm--error">
|
||||
<ng-container
|
||||
*ngIf="
|
||||
formControls.companyDescription.touched &&
|
||||
formControls.companyDescription.errors?.minlength
|
||||
"
|
||||
>
|
||||
<div id="descError" aria-live="assertive">
|
||||
<i class="bi bi-exclamation-octagon"></i>
|
||||
<span>
|
||||
Institution Description must be at least 10 characters
|
||||
</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container
|
||||
*ngIf="
|
||||
formControls.companyDescription.errors?.required &&
|
||||
formControls.companyDescription?.touched
|
||||
"
|
||||
>
|
||||
<div id="descError" aria-live="assertive">
|
||||
<i class="bi bi-x"></i>
|
||||
<span>Company Description Required</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="updateSaveBtn">
|
||||
<button class="btn btn-fill btn-save" type="submit">
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card card-user">
|
||||
<div class="card-body">
|
||||
<p class="card-text"></p>
|
||||
<div class="author">
|
||||
<div class="block block-one"></div>
|
||||
<div class="block block-two"></div>
|
||||
<div class="block block-three"></div>
|
||||
<div class="block block-four"></div>
|
||||
<a href="javascript:void(0)">
|
||||
<img alt="..." class="avatar" src="assets/img/emilyz.jpg" />
|
||||
|
||||
<h5 class="title">Mike Andrew</h5>
|
||||
</a>
|
||||
<p class="description">Ceo/Co-Founder</p>
|
||||
</div>
|
||||
<div class="card-description">
|
||||
Do not be scared of the truth because we need to restart the human
|
||||
foundation in truth And I love you like Kanye loves Kanye I love
|
||||
Rick Owens’ bed design but the back is...
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="button-container">
|
||||
<button class="btn btn-icon btn-round btn-facebook" href="#">
|
||||
<i class="bi bi-facebook"> </i>
|
||||
</button>
|
||||
<button class="btn btn-icon btn-round btn-twitter" href="#">
|
||||
<i class="bi bi-twitter"> </i>
|
||||
</button>
|
||||
<button class="btn btn-icon btn-round btn-linkedin" href="#">
|
||||
<i class="bi bi-linkedin"> </i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
169
src/app/pages/company-profile/company-profile.component.scss
Normal file
169
src/app/pages/company-profile/company-profile.component.scss
Normal file
@@ -0,0 +1,169 @@
|
||||
.companyProfile {
|
||||
.title {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.companyProfileBody {
|
||||
form {
|
||||
|
||||
|
||||
.inputField__uploadFile {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
i {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.institutionDashboard__editInfoFormGroup {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
// Input
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
font-size: 1rem;
|
||||
letter-spacing: 1px;
|
||||
border: 2px solid #cccccc;
|
||||
border-radius: 10px !important;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: -webkit-fill-available;
|
||||
outline: none;
|
||||
resize: none;
|
||||
font-size: 1rem;
|
||||
letter-spacing: 1px;
|
||||
border: 2px solid #cccccc;
|
||||
border-radius: 10px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.institutionsDashboard__editInfo__button {
|
||||
button {
|
||||
border: 1px solid #564794;
|
||||
background-color: white;
|
||||
|
||||
&:focus,
|
||||
&:hover {
|
||||
background-color: #564794;
|
||||
color: white;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
background-color: #cccccc !important;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Error message
|
||||
.companyEditForm--error {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
width: -webkit-fill-available;
|
||||
margin-top: -15px;
|
||||
font-weight: 600;
|
||||
row-gap: 3px;
|
||||
|
||||
.bi {
|
||||
font-size: 1.018rem;
|
||||
padding: 0 !important;
|
||||
|
||||
&::before {
|
||||
font-size: 1.4rem;
|
||||
font-weight: 900 !important;
|
||||
}
|
||||
}
|
||||
|
||||
#imageError {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#institutionEditError,
|
||||
#emailError,
|
||||
#phoneNumberError,
|
||||
#addressError,
|
||||
#descError,
|
||||
#institutionNameError,
|
||||
#imageError {
|
||||
color: crimson;
|
||||
width: -webkit-fill-available;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 0;
|
||||
margin-bottom: 10px;
|
||||
line-height: 1.1;
|
||||
|
||||
.bi-x {
|
||||
&::before {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.bi-exclamation-octagon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
color: crimson;
|
||||
|
||||
.bi-check {
|
||||
color: #564794 !important;
|
||||
}
|
||||
|
||||
.bi {
|
||||
font-size: 1.018rem;
|
||||
|
||||
&::before {
|
||||
font-size: 1.4rem;
|
||||
font-weight: 900 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.updateSaveBtn {
|
||||
.btn-save {
|
||||
background: #211069;
|
||||
background-image: -webkit-linear-gradient(
|
||||
to bottom left,
|
||||
#211069,
|
||||
#564794,
|
||||
#211069
|
||||
);
|
||||
background-image: -o-linear-gradient(
|
||||
to bottom left,
|
||||
#211069,
|
||||
#564794,
|
||||
#211069
|
||||
);
|
||||
background-image: -moz-linear-gradient(
|
||||
to bottom left,
|
||||
#211069,
|
||||
#564794,
|
||||
#211069
|
||||
);
|
||||
background-image: linear-gradient(
|
||||
to bottom left,
|
||||
#211069,
|
||||
#564794,
|
||||
#211069
|
||||
);
|
||||
background-size: 210% 210%;
|
||||
background-position: top right;
|
||||
background-color: #211069;
|
||||
transition: all 0.15s ease;
|
||||
box-shadow: none;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CompanyProfileComponent } from './company-profile.component';
|
||||
|
||||
describe('CompanyProfileComponent', () => {
|
||||
let component: CompanyProfileComponent;
|
||||
let fixture: ComponentFixture<CompanyProfileComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ CompanyProfileComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(CompanyProfileComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
119
src/app/pages/company-profile/company-profile.component.ts
Normal file
119
src/app/pages/company-profile/company-profile.component.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { FormBuilder, FormGroup, Validators } from "@angular/forms";
|
||||
import { ToastrService } from "ngx-toastr";
|
||||
import { CompanyService } from "src/app/services/company.service";
|
||||
|
||||
@Component({
|
||||
selector: "app-company-profile",
|
||||
templateUrl: "./company-profile.component.html",
|
||||
styleUrls: ["./company-profile.component.scss"],
|
||||
})
|
||||
export class CompanyProfileComponent implements OnInit {
|
||||
updateInfoForm: FormGroup;
|
||||
imgFile: any;
|
||||
fileName: any;
|
||||
imgSrc: any;
|
||||
institutionId!: number;
|
||||
imgFormatError: boolean = false;
|
||||
fileSizeError: boolean = false;
|
||||
company: any;
|
||||
|
||||
private emailPattern =
|
||||
"(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\\\[\x01-\x09\x0b\x0c\x0e-\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\\])";
|
||||
|
||||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private toastr: ToastrService,
|
||||
private companyService: CompanyService
|
||||
) {
|
||||
this.updateInfoForm = this.fb.group({
|
||||
companyName: ["", [Validators.required, Validators.minLength(6)]],
|
||||
companyUsername: ["", [Validators.required]],
|
||||
companyAddress: ["", [Validators.required, Validators.minLength(6)]],
|
||||
companyCity: ["", [Validators.required, Validators.minLength(3)]],
|
||||
companyPhone: [
|
||||
"",
|
||||
[
|
||||
Validators.required,
|
||||
Validators.minLength(11),
|
||||
Validators.pattern("^[0-9]*$"),
|
||||
],
|
||||
],
|
||||
companyEmail: [
|
||||
"",
|
||||
[Validators.required, Validators.pattern(this.emailPattern)],
|
||||
],
|
||||
companyDescription: ["", [Validators.required, Validators.minLength(10)]],
|
||||
companyLogo: ["", Validators.required],
|
||||
});
|
||||
|
||||
this.companyService.getCompanyById(1).subscribe((company) => {
|
||||
this.company = company;
|
||||
console.log(this.company);
|
||||
});
|
||||
}
|
||||
|
||||
get formControls() {
|
||||
return this.updateInfoForm.controls;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.updateInfoForm.patchValue({
|
||||
companyName: this.company.name,
|
||||
companyUsername: this.company.username,
|
||||
companyEmail: this.company.email,
|
||||
companyPhone: this.company.phone,
|
||||
companyAddress: this.company.address,
|
||||
companyCity: this.company.city,
|
||||
companyDescription: this.company.description,
|
||||
companyLogo: this.company.image,
|
||||
});
|
||||
}
|
||||
|
||||
// Check file type
|
||||
checkFileType(file: File): boolean {
|
||||
const imageTypes = ["image/jpeg", "image/png", "image/gif", "image/jpg"]; // Add more types if needed
|
||||
return imageTypes.includes(file.type);
|
||||
}
|
||||
|
||||
onFileChange(event: any) {
|
||||
this.imgFile = <File>event.target.files[0];
|
||||
this.fileName = this.imgFile.name;
|
||||
|
||||
console.log(this.imgFile);
|
||||
|
||||
if (this.checkFileType(this.imgFile)) {
|
||||
let reader = new FileReader();
|
||||
reader.readAsDataURL(event.target.files[0]);
|
||||
reader.onload = (event: any) => {
|
||||
this.imgSrc = event.target.result;
|
||||
this.updateInfoForm.patchValue({
|
||||
image: this.imgSrc,
|
||||
});
|
||||
};
|
||||
} else {
|
||||
// Use toastr service to show error message
|
||||
this.toastr.error("Please select correct image format", "Error", {
|
||||
timeOut: 3000,
|
||||
progressBar: true,
|
||||
progressAnimation: "increasing",
|
||||
closeButton: true,
|
||||
positionClass: "toast-top-center",
|
||||
});
|
||||
this.imgFormatError = true;
|
||||
}
|
||||
|
||||
/* checking file size here is greater than 2MB */
|
||||
if (this.imgFile.size > 2000000) {
|
||||
this.fileSizeError = true;
|
||||
} else {
|
||||
this.fileSizeError = false;
|
||||
}
|
||||
}
|
||||
|
||||
updateInfo() {
|
||||
if (this.updateInfoForm.invalid) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
441
src/app/pages/dashboard/dashboard.component.html
Normal file
441
src/app/pages/dashboard/dashboard.component.html
Normal file
@@ -0,0 +1,441 @@
|
||||
<!-- <div class="content">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card card-chart">
|
||||
<div class="card-header">
|
||||
<div class="row">
|
||||
<div class="col-sm-6 text-left">
|
||||
<h5 class="card-category">Total Shipments</h5>
|
||||
<h2 class="card-title">Performance</h2>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div
|
||||
class="btn-group btn-group-toggle float-right"
|
||||
data-toggle="buttons"
|
||||
>
|
||||
<label
|
||||
class="btn btn-sm btn-danger btn-simple"
|
||||
(click)="
|
||||
data = datasets[0];
|
||||
updateOptions();
|
||||
clicked = true;
|
||||
clicked1 = false;
|
||||
clicked2 = false
|
||||
"
|
||||
[ngClass]="{ active: clicked === true }"
|
||||
>
|
||||
<input checked="checked" name="options" type="radio" />
|
||||
|
||||
<span
|
||||
class="d-none d-sm-block d-md-block d-lg-block d-xl-block"
|
||||
>
|
||||
Accounts
|
||||
</span>
|
||||
<span class="d-block d-sm-none">
|
||||
<i class="tim-icons icon-single-02"> </i>
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="btn btn-sm btn-danger btn-simple"
|
||||
(click)="
|
||||
data = datasets[1];
|
||||
updateOptions();
|
||||
clicked = false;
|
||||
clicked1 = true;
|
||||
clicked2 = false
|
||||
"
|
||||
[ngClass]="{ active: clicked1 === true }"
|
||||
>
|
||||
<input class="d-none d-sm-none" name="options" type="radio" />
|
||||
|
||||
<span
|
||||
class="d-none d-sm-block d-md-block d-lg-block d-xl-block"
|
||||
>
|
||||
Purchases
|
||||
</span>
|
||||
<span class="d-block d-sm-none">
|
||||
<i class="tim-icons icon-gift-2"> </i>
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="btn btn-sm btn-danger btn-simple"
|
||||
(click)="
|
||||
data = datasets[2];
|
||||
updateOptions();
|
||||
clicked = false;
|
||||
clicked1 = false;
|
||||
clicked2 = true
|
||||
"
|
||||
[ngClass]="{ active: clicked2 === true }"
|
||||
>
|
||||
<input class="d-none" name="options" type="radio" />
|
||||
|
||||
<span
|
||||
class="d-none d-sm-block d-md-block d-lg-block d-xl-block"
|
||||
>
|
||||
Sessions
|
||||
</span>
|
||||
<span class="d-block d-sm-none">
|
||||
<i class="tim-icons icon-tap-02"> </i>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart-area"><canvas id="chartBig1"> </canvas></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<div class="card card-chart">
|
||||
<div class="card-header">
|
||||
<h5 class="card-category">Total Shipments</h5>
|
||||
<h3 class="card-title">
|
||||
<i class="tim-icons icon-bell-55 text-danger-states"> </i> 763,215
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart-area"><canvas id="chartLineRed"> </canvas></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="card card-chart">
|
||||
<div class="card-header">
|
||||
<h5 class="card-category">Daily Sales</h5>
|
||||
<h3 class="card-title">
|
||||
<i class="tim-icons icon-delivery-fast text-info"> </i> 3,500€
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart-area"><canvas id="CountryChart"> </canvas></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="card card-chart">
|
||||
<div class="card-header">
|
||||
<h5 class="card-category">Completed Tasks</h5>
|
||||
<h3 class="card-title">
|
||||
<i class="tim-icons icon-send text-success"> </i> 12,100K
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="chart-area"><canvas id="chartLineGreen"> </canvas></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-md-12">
|
||||
<div class="card card-tasks">
|
||||
<div class="card-header">
|
||||
<h6 class="title d-inline">Tasks(5)</h6>
|
||||
<p class="card-category d-inline">today</p>
|
||||
<div ngbDropdown>
|
||||
<button
|
||||
class="btn btn-link btn-icon"
|
||||
data-toggle="dropdown"
|
||||
ngbDropdownToggle
|
||||
type="button"
|
||||
>
|
||||
<i class="tim-icons icon-settings-gear-63"> </i>
|
||||
</button>
|
||||
<div
|
||||
aria-labelledby="dropdownMenuLink"
|
||||
class="dropdown-menu-right"
|
||||
ngbDropdownMenu
|
||||
>
|
||||
<a href="javascript:void(0)" ngbDropdownItem> Action </a>
|
||||
<a href="javascript:void(0)" ngbDropdownItem> Another action </a>
|
||||
<a href="javascript:void(0)" ngbDropdownItem> Something else </a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-full-width table-responsive">
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
value=""
|
||||
/>
|
||||
|
||||
<span class="form-check-sign">
|
||||
<span class="check"> </span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<p class="title">Update the Documentation</p>
|
||||
<p class="text-muted">Dwuamish Head, Seattle, WA 8:47 AM</p>
|
||||
</td>
|
||||
<td class="td-actions text-right">
|
||||
<button
|
||||
class="btn btn-link"
|
||||
type="button"
|
||||
placement="left"
|
||||
ngbTooltip="Edit Task"
|
||||
container="body"
|
||||
>
|
||||
<i class="tim-icons icon-pencil"> </i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input
|
||||
checked=""
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
value=""
|
||||
/>
|
||||
|
||||
<span class="form-check-sign">
|
||||
<span class="check"> </span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<p class="title">GDPR Compliance</p>
|
||||
<p class="text-muted">
|
||||
The GDPR is a regulation that requires businesses to
|
||||
protect the personal data and privacy of Europe citizens
|
||||
for transactions that occur within EU member states.
|
||||
</p>
|
||||
</td>
|
||||
<td class="td-actions text-right">
|
||||
<button
|
||||
class="btn btn-link"
|
||||
type="button"
|
||||
placement="left"
|
||||
ngbTooltip="Edit Task"
|
||||
container="body"
|
||||
>
|
||||
<i class="tim-icons icon-pencil"> </i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
value=""
|
||||
/>
|
||||
|
||||
<span class="form-check-sign">
|
||||
<span class="check"> </span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<p class="title">Solve the issues</p>
|
||||
<p class="text-muted">
|
||||
Fifty percent of all respondents said they would be more
|
||||
likely to shop at a company
|
||||
</p>
|
||||
</td>
|
||||
<td class="td-actions text-right">
|
||||
<button
|
||||
class="btn btn-link"
|
||||
type="button"
|
||||
placement="left"
|
||||
ngbTooltip="Edit Task"
|
||||
container="body"
|
||||
>
|
||||
<i class="tim-icons icon-pencil"> </i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
value=""
|
||||
/>
|
||||
|
||||
<span class="form-check-sign">
|
||||
<span class="check"> </span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<p class="title">Release v2.0.0</p>
|
||||
<p class="text-muted">
|
||||
Ra Ave SW, Seattle, WA 98116, SUA 11:19 AM
|
||||
</p>
|
||||
</td>
|
||||
<td class="td-actions text-right">
|
||||
<button
|
||||
class="btn btn-link"
|
||||
type="button"
|
||||
placement="left"
|
||||
ngbTooltip="Edit Task"
|
||||
container="body"
|
||||
>
|
||||
<i class="tim-icons icon-pencil"> </i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
value=""
|
||||
/>
|
||||
|
||||
<span class="form-check-sign">
|
||||
<span class="check"> </span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<p class="title">Export the processed files</p>
|
||||
<p class="text-muted">
|
||||
The report also shows that consumers will not easily
|
||||
forgive a company once a breach exposing their personal
|
||||
data occurs.
|
||||
</p>
|
||||
</td>
|
||||
<td class="td-actions text-right">
|
||||
<button
|
||||
class="btn btn-link"
|
||||
type="button"
|
||||
placement="left"
|
||||
ngbTooltip="Edit Task"
|
||||
container="body"
|
||||
>
|
||||
<i class="tim-icons icon-pencil"> </i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="form-check">
|
||||
<label class="form-check-label">
|
||||
<input
|
||||
class="form-check-input"
|
||||
type="checkbox"
|
||||
value=""
|
||||
/>
|
||||
|
||||
<span class="form-check-sign">
|
||||
<span class="check"> </span>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<p class="title">Arival at export process</p>
|
||||
<p class="text-muted">Capitol Hill, Seattle, WA 12:34 AM</p>
|
||||
</td>
|
||||
<td class="td-actions text-right">
|
||||
<button
|
||||
class="btn btn-link"
|
||||
type="button"
|
||||
placement="left"
|
||||
ngbTooltip="Edit Task"
|
||||
container="body"
|
||||
>
|
||||
<i class="tim-icons icon-pencil"> </i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6 col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="card-title">Simple Table</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table tablesorter" id="">
|
||||
<thead class="text-primary">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Country</th>
|
||||
<th>City</th>
|
||||
<th class="text-center">Salary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Dakota Rice</td>
|
||||
<td>Niger</td>
|
||||
<td>Oud-Turnhout</td>
|
||||
<td class="text-center">$36,738</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Minerva Hooper</td>
|
||||
<td>Curaçao</td>
|
||||
<td>Sinaai-Waas</td>
|
||||
<td class="text-center">$23,789</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sage Rodriguez</td>
|
||||
<td>Netherlands</td>
|
||||
<td>Baileux</td>
|
||||
<td class="text-center">$56,142</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Philip Chaney</td>
|
||||
<td>Korea, South</td>
|
||||
<td>Overland Park</td>
|
||||
<td class="text-center">$38,735</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Doris Greene</td>
|
||||
<td>Malawi</td>
|
||||
<td>Feldkirchen in Kärnten</td>
|
||||
<td class="text-center">$63,542</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mason Porter</td>
|
||||
<td>Chile</td>
|
||||
<td>Gloucester</td>
|
||||
<td class="text-center">$78,615</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Jon Porter</td>
|
||||
<td>Portugal</td>
|
||||
<td>Gloucester</td>
|
||||
<td class="text-center">$98,615</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
470
src/app/pages/dashboard/dashboard.component.ts
Normal file
470
src/app/pages/dashboard/dashboard.component.ts
Normal file
@@ -0,0 +1,470 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import Chart from 'chart.js';
|
||||
|
||||
@Component({
|
||||
selector: "app-dashboard",
|
||||
templateUrl: "dashboard.component.html"
|
||||
})
|
||||
export class DashboardComponent implements OnInit {
|
||||
public canvas : any;
|
||||
public ctx;
|
||||
public datasets: any;
|
||||
public data: any;
|
||||
public myChartData;
|
||||
public clicked: boolean = true;
|
||||
public clicked1: boolean = false;
|
||||
public clicked2: boolean = false;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {
|
||||
var gradientChartOptionsConfigurationWithTooltipBlue: any = {
|
||||
maintainAspectRatio: false,
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
|
||||
tooltips: {
|
||||
backgroundColor: '#f5f5f5',
|
||||
titleFontColor: '#333',
|
||||
bodyFontColor: '#666',
|
||||
bodySpacing: 4,
|
||||
xPadding: 12,
|
||||
mode: "nearest",
|
||||
intersect: 0,
|
||||
position: "nearest"
|
||||
},
|
||||
responsive: true,
|
||||
scales: {
|
||||
yAxes: [{
|
||||
barPercentage: 1.6,
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
color: 'rgba(29,140,248,0.0)',
|
||||
zeroLineColor: "transparent",
|
||||
},
|
||||
ticks: {
|
||||
suggestedMin: 60,
|
||||
suggestedMax: 125,
|
||||
padding: 20,
|
||||
fontColor: "#2380f7"
|
||||
}
|
||||
}],
|
||||
|
||||
xAxes: [{
|
||||
barPercentage: 1.6,
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
color: 'rgba(29,140,248,0.1)',
|
||||
zeroLineColor: "transparent",
|
||||
},
|
||||
ticks: {
|
||||
padding: 20,
|
||||
fontColor: "#2380f7"
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
var gradientChartOptionsConfigurationWithTooltipPurple: any = {
|
||||
maintainAspectRatio: false,
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
|
||||
tooltips: {
|
||||
backgroundColor: '#f5f5f5',
|
||||
titleFontColor: '#333',
|
||||
bodyFontColor: '#666',
|
||||
bodySpacing: 4,
|
||||
xPadding: 12,
|
||||
mode: "nearest",
|
||||
intersect: 0,
|
||||
position: "nearest"
|
||||
},
|
||||
responsive: true,
|
||||
scales: {
|
||||
yAxes: [{
|
||||
barPercentage: 1.6,
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
color: 'rgba(29,140,248,0.0)',
|
||||
zeroLineColor: "transparent",
|
||||
},
|
||||
ticks: {
|
||||
suggestedMin: 60,
|
||||
suggestedMax: 125,
|
||||
padding: 20,
|
||||
fontColor: "#9a9a9a"
|
||||
}
|
||||
}],
|
||||
|
||||
xAxes: [{
|
||||
barPercentage: 1.6,
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
color: 'rgba(225,78,202,0.1)',
|
||||
zeroLineColor: "transparent",
|
||||
},
|
||||
ticks: {
|
||||
padding: 20,
|
||||
fontColor: "#9a9a9a"
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
var gradientChartOptionsConfigurationWithTooltipRed: any = {
|
||||
maintainAspectRatio: false,
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
|
||||
tooltips: {
|
||||
backgroundColor: '#f5f5f5',
|
||||
titleFontColor: '#333',
|
||||
bodyFontColor: '#666',
|
||||
bodySpacing: 4,
|
||||
xPadding: 12,
|
||||
mode: "nearest",
|
||||
intersect: 0,
|
||||
position: "nearest"
|
||||
},
|
||||
responsive: true,
|
||||
scales: {
|
||||
yAxes: [{
|
||||
barPercentage: 1.6,
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
color: 'rgba(29,140,248,0.0)',
|
||||
zeroLineColor: "transparent",
|
||||
},
|
||||
ticks: {
|
||||
suggestedMin: 60,
|
||||
suggestedMax: 125,
|
||||
padding: 20,
|
||||
fontColor: "#9a9a9a"
|
||||
}
|
||||
}],
|
||||
|
||||
xAxes: [{
|
||||
barPercentage: 1.6,
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
color: 'rgba(233,32,16,0.1)',
|
||||
zeroLineColor: "transparent",
|
||||
},
|
||||
ticks: {
|
||||
padding: 20,
|
||||
fontColor: "#9a9a9a"
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
var gradientChartOptionsConfigurationWithTooltipOrange: any = {
|
||||
maintainAspectRatio: false,
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
|
||||
tooltips: {
|
||||
backgroundColor: '#f5f5f5',
|
||||
titleFontColor: '#333',
|
||||
bodyFontColor: '#666',
|
||||
bodySpacing: 4,
|
||||
xPadding: 12,
|
||||
mode: "nearest",
|
||||
intersect: 0,
|
||||
position: "nearest"
|
||||
},
|
||||
responsive: true,
|
||||
scales: {
|
||||
yAxes: [{
|
||||
barPercentage: 1.6,
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
color: 'rgba(29,140,248,0.0)',
|
||||
zeroLineColor: "transparent",
|
||||
},
|
||||
ticks: {
|
||||
suggestedMin: 50,
|
||||
suggestedMax: 110,
|
||||
padding: 20,
|
||||
fontColor: "#ff8a76"
|
||||
}
|
||||
}],
|
||||
|
||||
xAxes: [{
|
||||
barPercentage: 1.6,
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
color: 'rgba(220,53,69,0.1)',
|
||||
zeroLineColor: "transparent",
|
||||
},
|
||||
ticks: {
|
||||
padding: 20,
|
||||
fontColor: "#ff8a76"
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
var gradientChartOptionsConfigurationWithTooltipGreen: any = {
|
||||
maintainAspectRatio: false,
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
|
||||
tooltips: {
|
||||
backgroundColor: '#f5f5f5',
|
||||
titleFontColor: '#333',
|
||||
bodyFontColor: '#666',
|
||||
bodySpacing: 4,
|
||||
xPadding: 12,
|
||||
mode: "nearest",
|
||||
intersect: 0,
|
||||
position: "nearest"
|
||||
},
|
||||
responsive: true,
|
||||
scales: {
|
||||
yAxes: [{
|
||||
barPercentage: 1.6,
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
color: 'rgba(29,140,248,0.0)',
|
||||
zeroLineColor: "transparent",
|
||||
},
|
||||
ticks: {
|
||||
suggestedMin: 50,
|
||||
suggestedMax: 125,
|
||||
padding: 20,
|
||||
fontColor: "#9e9e9e"
|
||||
}
|
||||
}],
|
||||
|
||||
xAxes: [{
|
||||
barPercentage: 1.6,
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
color: 'rgba(0,242,195,0.1)',
|
||||
zeroLineColor: "transparent",
|
||||
},
|
||||
ticks: {
|
||||
padding: 20,
|
||||
fontColor: "#9e9e9e"
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var gradientBarChartConfiguration: any = {
|
||||
maintainAspectRatio: false,
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
|
||||
tooltips: {
|
||||
backgroundColor: '#f5f5f5',
|
||||
titleFontColor: '#333',
|
||||
bodyFontColor: '#666',
|
||||
bodySpacing: 4,
|
||||
xPadding: 12,
|
||||
mode: "nearest",
|
||||
intersect: 0,
|
||||
position: "nearest"
|
||||
},
|
||||
responsive: true,
|
||||
scales: {
|
||||
yAxes: [{
|
||||
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
color: 'rgba(29,140,248,0.1)',
|
||||
zeroLineColor: "transparent",
|
||||
},
|
||||
ticks: {
|
||||
suggestedMin: 60,
|
||||
suggestedMax: 120,
|
||||
padding: 20,
|
||||
fontColor: "#9e9e9e"
|
||||
}
|
||||
}],
|
||||
|
||||
xAxes: [{
|
||||
|
||||
gridLines: {
|
||||
drawBorder: false,
|
||||
color: 'rgba(29,140,248,0.1)',
|
||||
zeroLineColor: "transparent",
|
||||
},
|
||||
ticks: {
|
||||
padding: 20,
|
||||
fontColor: "#9e9e9e"
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
|
||||
this.canvas = document.getElementById("chartLineRed");
|
||||
this.ctx = this.canvas.getContext("2d");
|
||||
|
||||
var gradientStroke = this.ctx.createLinearGradient(0, 230, 0, 50);
|
||||
|
||||
gradientStroke.addColorStop(1, 'rgba(233,32,16,0.2)');
|
||||
gradientStroke.addColorStop(0.4, 'rgba(233,32,16,0.0)');
|
||||
gradientStroke.addColorStop(0, 'rgba(233,32,16,0)'); //red colors
|
||||
|
||||
var data = {
|
||||
labels: ['JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'],
|
||||
datasets: [{
|
||||
label: "Data",
|
||||
fill: true,
|
||||
backgroundColor: gradientStroke,
|
||||
borderColor: '#ec250d',
|
||||
borderWidth: 2,
|
||||
borderDash: [],
|
||||
borderDashOffset: 0.0,
|
||||
pointBackgroundColor: '#ec250d',
|
||||
pointBorderColor: 'rgba(255,255,255,0)',
|
||||
pointHoverBackgroundColor: '#ec250d',
|
||||
pointBorderWidth: 20,
|
||||
pointHoverRadius: 4,
|
||||
pointHoverBorderWidth: 15,
|
||||
pointRadius: 4,
|
||||
data: [80, 100, 70, 80, 120, 80],
|
||||
}]
|
||||
};
|
||||
|
||||
var myChart = new Chart(this.ctx, {
|
||||
type: 'line',
|
||||
data: data,
|
||||
options: gradientChartOptionsConfigurationWithTooltipRed
|
||||
});
|
||||
|
||||
|
||||
this.canvas = document.getElementById("chartLineGreen");
|
||||
this.ctx = this.canvas.getContext("2d");
|
||||
|
||||
|
||||
var gradientStroke = this.ctx.createLinearGradient(0, 230, 0, 50);
|
||||
|
||||
gradientStroke.addColorStop(1, 'rgba(66,134,121,0.15)');
|
||||
gradientStroke.addColorStop(0.4, 'rgba(66,134,121,0.0)'); //green colors
|
||||
gradientStroke.addColorStop(0, 'rgba(66,134,121,0)'); //green colors
|
||||
|
||||
var data = {
|
||||
labels: ['JUL', 'AUG', 'SEP', 'OCT', 'NOV'],
|
||||
datasets: [{
|
||||
label: "My First dataset",
|
||||
fill: true,
|
||||
backgroundColor: gradientStroke,
|
||||
borderColor: '#00d6b4',
|
||||
borderWidth: 2,
|
||||
borderDash: [],
|
||||
borderDashOffset: 0.0,
|
||||
pointBackgroundColor: '#00d6b4',
|
||||
pointBorderColor: 'rgba(255,255,255,0)',
|
||||
pointHoverBackgroundColor: '#00d6b4',
|
||||
pointBorderWidth: 20,
|
||||
pointHoverRadius: 4,
|
||||
pointHoverBorderWidth: 15,
|
||||
pointRadius: 4,
|
||||
data: [90, 27, 60, 12, 80],
|
||||
}]
|
||||
};
|
||||
|
||||
var myChart = new Chart(this.ctx, {
|
||||
type: 'line',
|
||||
data: data,
|
||||
options: gradientChartOptionsConfigurationWithTooltipGreen
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
var chart_labels = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC'];
|
||||
this.datasets = [
|
||||
[100, 70, 90, 70, 85, 60, 75, 60, 90, 80, 110, 100],
|
||||
[80, 120, 105, 110, 95, 105, 90, 100, 80, 95, 70, 120],
|
||||
[60, 80, 65, 130, 80, 105, 90, 130, 70, 115, 60, 130]
|
||||
];
|
||||
this.data = this.datasets[0];
|
||||
|
||||
|
||||
|
||||
this.canvas = document.getElementById("chartBig1");
|
||||
this.ctx = this.canvas.getContext("2d");
|
||||
|
||||
var gradientStroke = this.ctx.createLinearGradient(0, 230, 0, 50);
|
||||
|
||||
gradientStroke.addColorStop(1, 'rgba(233,32,16,0.2)');
|
||||
gradientStroke.addColorStop(0.4, 'rgba(233,32,16,0.0)');
|
||||
gradientStroke.addColorStop(0, 'rgba(233,32,16,0)'); //red colors
|
||||
|
||||
var config = {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: chart_labels,
|
||||
datasets: [{
|
||||
label: "My First dataset",
|
||||
fill: true,
|
||||
backgroundColor: gradientStroke,
|
||||
borderColor: '#ec250d',
|
||||
borderWidth: 2,
|
||||
borderDash: [],
|
||||
borderDashOffset: 0.0,
|
||||
pointBackgroundColor: '#ec250d',
|
||||
pointBorderColor: 'rgba(255,255,255,0)',
|
||||
pointHoverBackgroundColor: '#ec250d',
|
||||
pointBorderWidth: 20,
|
||||
pointHoverRadius: 4,
|
||||
pointHoverBorderWidth: 15,
|
||||
pointRadius: 4,
|
||||
data: this.data,
|
||||
}]
|
||||
},
|
||||
options: gradientChartOptionsConfigurationWithTooltipRed
|
||||
};
|
||||
this.myChartData = new Chart(this.ctx, config);
|
||||
|
||||
|
||||
this.canvas = document.getElementById("CountryChart");
|
||||
this.ctx = this.canvas.getContext("2d");
|
||||
var gradientStroke = this.ctx.createLinearGradient(0, 230, 0, 50);
|
||||
|
||||
gradientStroke.addColorStop(1, 'rgba(29,140,248,0.2)');
|
||||
gradientStroke.addColorStop(0.4, 'rgba(29,140,248,0.0)');
|
||||
gradientStroke.addColorStop(0, 'rgba(29,140,248,0)'); //blue colors
|
||||
|
||||
|
||||
var myChart = new Chart(this.ctx, {
|
||||
type: 'bar',
|
||||
responsive: true,
|
||||
legend: {
|
||||
display: false
|
||||
},
|
||||
data: {
|
||||
labels: ['USA', 'GER', 'AUS', 'UK', 'RO', 'BR'],
|
||||
datasets: [{
|
||||
label: "Countries",
|
||||
fill: true,
|
||||
backgroundColor: gradientStroke,
|
||||
hoverBackgroundColor: gradientStroke,
|
||||
borderColor: '#1f8ef1',
|
||||
borderWidth: 2,
|
||||
borderDash: [],
|
||||
borderDashOffset: 0.0,
|
||||
data: [53, 20, 10, 80, 100, 45],
|
||||
}]
|
||||
},
|
||||
options: gradientBarChartConfiguration
|
||||
});
|
||||
|
||||
}
|
||||
public updateOptions() {
|
||||
this.myChartData.data.datasets[0].data = this.data;
|
||||
this.myChartData.update();
|
||||
}
|
||||
}
|
||||
52
src/app/pages/invoices/invoices.component.html
Normal file
52
src/app/pages/invoices/invoices.component.html
Normal file
@@ -0,0 +1,52 @@
|
||||
<div class="content">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title font-weight-bolder">Invoices Details</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table tablesorter" id="">
|
||||
<thead class="text-primary">
|
||||
<tr>
|
||||
<th>S/N</th>
|
||||
<th>Invoice Number</th>
|
||||
<th>Date Issued</th>
|
||||
<th>Due Date</th>
|
||||
<th>Status</th>
|
||||
<th class="text-center">Amount</th>
|
||||
<th>Services Rendered</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let invoice of invoices; let i = index">
|
||||
<td>{{ i + 1 }}</td>
|
||||
<td>{{ invoice.invoiceNumber }}</td>
|
||||
|
||||
<td>
|
||||
{{
|
||||
invoice.dateIssued.toLocaleDateString("en-US", options)
|
||||
}}
|
||||
</td>
|
||||
<td>
|
||||
{{ invoice.dueDate.toLocaleDateString("en-US", options) }}
|
||||
</td>
|
||||
<td
|
||||
class="text-capitalize"
|
||||
style="font-weight: 600"
|
||||
[ngStyle]="{ 'color': getStatusColor(invoice.status) }"
|
||||
>
|
||||
{{ invoice.status }}
|
||||
</td>
|
||||
<td class="text-center">₦{{ invoice.amount }}</td>
|
||||
<td>{{ invoice.services[0].description }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
0
src/app/pages/invoices/invoices.component.scss
Normal file
0
src/app/pages/invoices/invoices.component.scss
Normal file
25
src/app/pages/invoices/invoices.component.spec.ts
Normal file
25
src/app/pages/invoices/invoices.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { InvoicesComponent } from './invoices.component';
|
||||
|
||||
describe('InvoicesComponent', () => {
|
||||
let component: InvoicesComponent;
|
||||
let fixture: ComponentFixture<InvoicesComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ InvoicesComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(InvoicesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
52
src/app/pages/invoices/invoices.component.ts
Normal file
52
src/app/pages/invoices/invoices.component.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { InvoiceModel } from "../../models/invoice";
|
||||
import { InvoiceService } from "../../services/invoice.service";
|
||||
|
||||
@Component({
|
||||
selector: "app-invoices",
|
||||
templateUrl: "./invoices.component.html",
|
||||
styleUrls: ["./invoices.component.scss"],
|
||||
})
|
||||
export class InvoicesComponent implements OnInit {
|
||||
invoices: InvoiceModel[];
|
||||
options: any;
|
||||
|
||||
constructor(private invoiceService: InvoiceService) {
|
||||
this.invoiceService
|
||||
.getInvoiceById(1)
|
||||
.subscribe((invoice: InvoiceModel[]) => {
|
||||
this.invoices = invoice;
|
||||
|
||||
for (let i = 0; i < invoice.length; i++) {
|
||||
let amountWithCommas = invoice[i].amount.replace(
|
||||
/\B(?=(\d{3})+(?!\d))/g,
|
||||
","
|
||||
);
|
||||
invoice[i].amount = amountWithCommas;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.options = {
|
||||
weekday: "short",
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
};
|
||||
}
|
||||
|
||||
// Get color status
|
||||
getStatusColor(status: string): string {
|
||||
switch (status) {
|
||||
case "pending":
|
||||
return "#FFC107";
|
||||
case "paid":
|
||||
return "#4CAF50";
|
||||
case "overdue":
|
||||
return "#DC143C";
|
||||
default:
|
||||
return "inherit";
|
||||
}
|
||||
}
|
||||
}
|
||||
96
src/app/pages/login/login.component.html
Normal file
96
src/app/pages/login/login.component.html
Normal file
@@ -0,0 +1,96 @@
|
||||
<div class="content ml-2 signinContainer overflow-hidden">
|
||||
<div class="logo">
|
||||
<img
|
||||
src="../../../assets/img/logo.png"
|
||||
class="img-fluid"
|
||||
height="150"
|
||||
width="150"
|
||||
alt="logo"
|
||||
style="width: 200px; height: 200px"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<section class="forms">
|
||||
<form (ngSubmit)="signin()" [formGroup]="loginForm" novalidate>
|
||||
<div class="forms__inputBox">
|
||||
<input
|
||||
type="email"
|
||||
formControlName="companyEmail"
|
||||
id="companyEmail"
|
||||
autocomplete="off"
|
||||
required
|
||||
/>
|
||||
<label for="companyEmail">Email</label>
|
||||
|
||||
<div class="signinForms--error">
|
||||
<ng-container
|
||||
*ngIf="
|
||||
formControls.companyEmail.errors?.required &&
|
||||
formControls.companyEmail?.touched
|
||||
"
|
||||
>
|
||||
<div id="emailError" aria-live="assertive">
|
||||
<i class="bi bi-x"> </i>
|
||||
<span>Email Required</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="formControls.companyEmail.errors?.pattern">
|
||||
<div id="emailError" aria-live="assertive">
|
||||
<i class="bi bi-exclamation-octagon"></i>
|
||||
<span>Please enter a valid email</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
<div class="forms__inputBox">
|
||||
<input
|
||||
type="password"
|
||||
[type]="hide ? 'password' : 'text'"
|
||||
formControlName="password"
|
||||
id="password"
|
||||
data-cy="signin-password"
|
||||
autocomplete="off"
|
||||
required
|
||||
/>
|
||||
<i
|
||||
[class]="hide ? 'bi bi-eye-slash' : 'bi bi-eye'"
|
||||
(click)="hide = !hide"
|
||||
></i>
|
||||
<label for="password">Password</label>
|
||||
|
||||
<div class="signinForms--error">
|
||||
<ng-container
|
||||
*ngIf="
|
||||
formControls.password.errors?.required &&
|
||||
formControls.password?.touched
|
||||
"
|
||||
>
|
||||
<div id="passwordError" aria-live="assertive">
|
||||
<i class="bi bi-x"></i>
|
||||
<span>Password Required</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="formControls.password.errors?.minlength">
|
||||
<div id="passwordError" aria-live="assertive">
|
||||
<i class="bi bi-exclamation-octagon"></i>
|
||||
<span>Password must be at least 6 characters</span>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="forgotPassw">
|
||||
<p>
|
||||
Forgot Password?
|
||||
<a routerLink="/request-reset-password">Reset password </a>
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="signinBtn">
|
||||
<button (click)="signin()" data-cy="signin-button">Sign In</button>
|
||||
</div>
|
||||
</div>
|
||||
134
src/app/pages/login/login.component.scss
Normal file
134
src/app/pages/login/login.component.scss
Normal file
@@ -0,0 +1,134 @@
|
||||
.signinContainer {
|
||||
.forms {
|
||||
// Sign in form
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
|
||||
.forms__inputBox {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
// Input
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
font-size: 1rem;
|
||||
letter-spacing: 1px;
|
||||
border: 2px solid #cccccc;
|
||||
border-radius: 10px;
|
||||
outline: none;
|
||||
|
||||
&:focus ~ label,
|
||||
&:valid ~ label {
|
||||
color: #564794;
|
||||
transform: translateX(10px) translateY(-7px);
|
||||
font-size: 0.65rem;
|
||||
padding: 0 10px;
|
||||
font-weight: 600;
|
||||
background-color: white;
|
||||
letter-spacing: 0.1px;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:valid {
|
||||
color: black;
|
||||
border: 2px solid #564794;
|
||||
}
|
||||
}
|
||||
|
||||
i.bi-eye,
|
||||
i.bi-eye-slash {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
padding: 10px;
|
||||
padding-top: 5px;
|
||||
font-size: 1.5rem;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
// Label
|
||||
label {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
padding: 10px;
|
||||
font-size: 1rem;
|
||||
letter-spacing: 1px;
|
||||
color: #7f7e7f;
|
||||
text-transform: uppercase;
|
||||
pointer-events: none;
|
||||
transition: 0.6s;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Forgot password
|
||||
.forgotPassw {
|
||||
margin-top: 0.6rem;
|
||||
p {
|
||||
margin-top: 5px !important;
|
||||
margin-bottom: 0 !important;
|
||||
|
||||
a {
|
||||
color: #564794;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Signin Error message
|
||||
.signinForms--error {
|
||||
width: -webkit-fill-available;
|
||||
font-weight: 600;
|
||||
|
||||
.bi {
|
||||
font-size: 1.018rem;
|
||||
padding: 0 !important;
|
||||
|
||||
&::before {
|
||||
font-size: 1.4rem;
|
||||
font-weight: 900 !important;
|
||||
}
|
||||
}
|
||||
|
||||
#emailError,
|
||||
#passwordError {
|
||||
color: crimson;
|
||||
width: -webkit-fill-available;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 6px;
|
||||
line-height: 1.1;
|
||||
|
||||
.bi-x {
|
||||
&::before {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
.bi-exclamation-octagon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sign in button
|
||||
.signinBtn {
|
||||
button {
|
||||
border: none;
|
||||
background-color: #211069;
|
||||
width: -webkit-fill-available;
|
||||
padding: 1rem 0;
|
||||
border-radius: 25px;
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
font-size: 1.07rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
25
src/app/pages/login/login.component.spec.ts
Normal file
25
src/app/pages/login/login.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LoginComponent } from './login.component';
|
||||
|
||||
describe('LoginComponent', () => {
|
||||
let component: LoginComponent;
|
||||
let fixture: ComponentFixture<LoginComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ LoginComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(LoginComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
49
src/app/pages/login/login.component.ts
Normal file
49
src/app/pages/login/login.component.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { FormGroup, FormBuilder, Validators } from "@angular/forms";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
|
||||
@Component({
|
||||
selector: "app-login",
|
||||
templateUrl: "./login.component.html",
|
||||
styleUrls: ["./login.component.scss"],
|
||||
})
|
||||
export class LoginComponent implements OnInit {
|
||||
private emailPattern =
|
||||
"(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|\"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\\\[\x01-\x09\x0b\x0c\x0e-\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\\])";
|
||||
loginForm: FormGroup;
|
||||
hide: boolean = true;
|
||||
|
||||
constructor(private fb: FormBuilder) {
|
||||
this.loginForm = this.fb.group({
|
||||
companyEmail: ["", [Validators.required, Validators.pattern(this.emailPattern)]],
|
||||
password: ["", [Validators.required, Validators.minLength(6)]],
|
||||
})
|
||||
}
|
||||
|
||||
get formControls() {
|
||||
return this.loginForm.controls;
|
||||
}
|
||||
|
||||
ngOnInit(): void {}
|
||||
|
||||
signin() {
|
||||
const email = this.loginForm.get('email')?.value;
|
||||
const password = this.loginForm.get('password')?.value;
|
||||
|
||||
if (this.loginForm.invalid) {
|
||||
console.log('Form error');
|
||||
return;
|
||||
}
|
||||
|
||||
this.loginForm.reset();
|
||||
// this.userService.signinUser(email, password);
|
||||
|
||||
// this.userService.signinMessage$.subscribe((msg) => {
|
||||
// console.log('message', msg);
|
||||
// this.signinMessage = msg;
|
||||
// setTimeout(() => {
|
||||
// this.signinMessage = msg;
|
||||
// }, 1000);
|
||||
// });
|
||||
}
|
||||
}
|
||||
182
src/app/pages/notifications/notifications.component.html
Normal file
182
src/app/pages/notifications/notifications.component.html
Normal file
@@ -0,0 +1,182 @@
|
||||
<div class=" content">
|
||||
<div class=" row">
|
||||
<div class=" col-md-6">
|
||||
<div class=" card">
|
||||
<div class=" card-header">
|
||||
<h4 class=" card-title">Notifications Style</h4>
|
||||
</div>
|
||||
<div class=" card-body">
|
||||
<ngb-alert [type]="'info'" [dismissible]="false">
|
||||
<span> This is a plain notification </span>
|
||||
</ngb-alert>
|
||||
<ngb-alert [type]="'info'" *ngIf="!staticAlertClosed" [dismissible]="false">
|
||||
<button type="button" aria-hidden="true" class="close" data-dismiss="alert" aria-label="Close" (click)="staticAlertClosed = true">
|
||||
<i class="tim-icons icon-simple-remove"></i>
|
||||
</button>
|
||||
<span> This is a notification with close button. </span>
|
||||
</ngb-alert>
|
||||
<ngb-alert
|
||||
class=" alert-with-icon"
|
||||
data-notify="container"
|
||||
[type]="'info'"*ngIf="!staticAlertClosed1" [dismissible]="false">
|
||||
<button type="button" aria-hidden="true" class="close" data-dismiss="alert" aria-label="Close" (click)="staticAlertClosed1 = true">
|
||||
<i class="tim-icons icon-simple-remove"></i>
|
||||
</button>
|
||||
<span class=" tim-icons icon-bell-55" data-notify="icon">
|
||||
</span>
|
||||
<span data-notify="message">
|
||||
This is a notification with close button and icon.
|
||||
</span>
|
||||
</ngb-alert>
|
||||
<ngb-alert
|
||||
class=" alert-with-icon"
|
||||
data-notify="container"
|
||||
[type]="'info'"
|
||||
*ngIf="!staticAlertClosed2" [dismissible]="false">
|
||||
<button type="button" aria-hidden="true" class="close" data-dismiss="alert" aria-label="Close" (click)="staticAlertClosed2 = true">
|
||||
<i class="tim-icons icon-simple-remove"></i>
|
||||
</button>
|
||||
<span class=" tim-icons icon-bell-55" data-notify="icon">
|
||||
</span>
|
||||
<span data-notify="message">
|
||||
This is a notification with close button and icon and have
|
||||
many lines. You can see that the icon and the close button
|
||||
are always vertically aligned. This is a beautiful
|
||||
notification. So you don't have to worry about the style.
|
||||
</span>
|
||||
</ngb-alert>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" col-md-6">
|
||||
<div class=" card">
|
||||
<div class=" card-header">
|
||||
<h4 class=" card-title">Notification states</h4>
|
||||
</div>
|
||||
<div class=" card-body">
|
||||
<ngb-alert [type]="'primary'" *ngIf="!staticAlertClosed3" [dismissible]="false">
|
||||
<button type="button" aria-hidden="true" class="close" data-dismiss="alert" aria-label="Close" (click)="staticAlertClosed3 = true">
|
||||
<i class="tim-icons icon-simple-remove"></i>
|
||||
</button>
|
||||
<span>
|
||||
<b> Primary - </b> This is a regular notification made
|
||||
with ".alert-primary"
|
||||
</span>
|
||||
</ngb-alert>
|
||||
<ngb-alert [type]="'info'" *ngIf="!staticAlertClosed4" [dismissible]="false">
|
||||
<button type="button" aria-hidden="true" class="close" data-dismiss="alert" aria-label="Close" (click)="staticAlertClosed4 = true">
|
||||
<i class="tim-icons icon-simple-remove"></i>
|
||||
</button>
|
||||
<span>
|
||||
<b> Info - </b> This is a regular notification made with
|
||||
".alert-info"
|
||||
</span>
|
||||
</ngb-alert>
|
||||
<ngb-alert [type]="'success'" *ngIf="!staticAlertClosed5" [dismissible]="false">
|
||||
<button type="button" aria-hidden="true" class="close" data-dismiss="alert" aria-label="Close" (click)="staticAlertClosed5 = true">
|
||||
<i class="tim-icons icon-simple-remove"></i>
|
||||
</button>
|
||||
<span>
|
||||
<b> Success - </b> This is a regular notification made
|
||||
with ".alert-success"
|
||||
</span>
|
||||
</ngb-alert>
|
||||
<ngb-alert [type]="'warning'" *ngIf="!staticAlertClosed6" [dismissible]="false">
|
||||
<button type="button" aria-hidden="true" class="close" data-dismiss="alert" aria-label="Close" (click)="staticAlertClosed6 = true">
|
||||
<i class="tim-icons icon-simple-remove"></i>
|
||||
</button>
|
||||
<span>
|
||||
<b> Warning - </b> This is a regular notification made
|
||||
with ".alert-warning"
|
||||
</span>
|
||||
</ngb-alert>
|
||||
<ngb-alert [type]="'danger'" *ngIf="!staticAlertClosed7" [dismissible]="false">
|
||||
<button type="button" aria-hidden="true" class="close" data-dismiss="alert" aria-label="Close" (click)="staticAlertClosed7 = true">
|
||||
<i class="tim-icons icon-simple-remove"></i>
|
||||
</button>
|
||||
<span>
|
||||
<b> Danger - </b> This is a regular notification made with
|
||||
".alert-danger"
|
||||
</span>
|
||||
</ngb-alert>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" col-md-12">
|
||||
<div class=" card">
|
||||
<div class=" card-body">
|
||||
<div class=" places-buttons">
|
||||
<div class=" row">
|
||||
<div class=" col-md-6 ml-auto mr-auto text-center">
|
||||
<h4 class=" card-title">Notifications Places</h4>
|
||||
<p class=" category">Click to view notifications</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" row">
|
||||
<div class=" col-lg-8 ml-auto mr-auto">
|
||||
<div class=" row">
|
||||
<div class=" col-md-4">
|
||||
<button
|
||||
class=" btn btn-danger btn-block"
|
||||
(click)="showNotification('top', 'left')"
|
||||
>
|
||||
Top Left
|
||||
</button>
|
||||
</div>
|
||||
<div class=" col-md-4">
|
||||
<button
|
||||
class=" btn btn-danger btn-block"
|
||||
(click)="showNotification('top', 'center')"
|
||||
>
|
||||
Top Center
|
||||
</button>
|
||||
</div>
|
||||
<div class=" col-md-4">
|
||||
<button
|
||||
class=" btn btn-danger btn-block"
|
||||
(click)="showNotification('top', 'right')"
|
||||
>
|
||||
Top Right
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" row">
|
||||
<div class=" col-lg-8 ml-auto mr-auto">
|
||||
<div class=" row">
|
||||
<div class=" col-md-4">
|
||||
<button
|
||||
class=" btn btn-danger btn-block"
|
||||
(click)="showNotification('bottom', 'left')"
|
||||
>
|
||||
Bottom Left
|
||||
</button>
|
||||
</div>
|
||||
<div class=" col-md-4">
|
||||
<button
|
||||
class=" btn btn-danger btn-block"
|
||||
(click)="
|
||||
showNotification('bottom', 'center')
|
||||
"
|
||||
>
|
||||
Bottom Center
|
||||
</button>
|
||||
</div>
|
||||
<div class=" col-md-4">
|
||||
<button
|
||||
class=" btn btn-danger btn-block"
|
||||
(click)="showNotification('bottom', 'right')"
|
||||
>
|
||||
Bottom Right
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
76
src/app/pages/notifications/notifications.component.ts
Normal file
76
src/app/pages/notifications/notifications.component.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
|
||||
@Component({
|
||||
selector: "app-notifications",
|
||||
templateUrl: "notifications.component.html"
|
||||
})
|
||||
export class NotificationsComponent implements OnInit {
|
||||
staticAlertClosed = false;
|
||||
staticAlertClosed1 = false;
|
||||
staticAlertClosed2 = false;
|
||||
staticAlertClosed3 = false;
|
||||
staticAlertClosed4 = false;
|
||||
staticAlertClosed5 = false;
|
||||
staticAlertClosed6 = false;
|
||||
staticAlertClosed7 = false;
|
||||
|
||||
constructor(private toastr: ToastrService) {}
|
||||
|
||||
showNotification(from, align){
|
||||
|
||||
const color = Math.floor((Math.random() * 5) + 1);
|
||||
|
||||
switch(color){
|
||||
case 1:
|
||||
this.toastr.info('<span class="tim-icons icon-bell-55" [data-notify]="icon"></span> Welcome to <b>Black Dashboard Angular</b> - a beautiful freebie for every web developer.', '', {
|
||||
disableTimeOut: true,
|
||||
closeButton: true,
|
||||
enableHtml: true,
|
||||
toastClass: "alert alert-info alert-with-icon",
|
||||
positionClass: 'toast-' + from + '-' + align
|
||||
});
|
||||
break;
|
||||
case 2:
|
||||
this.toastr.success('<span class="tim-icons icon-bell-55" [data-notify]="icon"></span> Welcome to <b>Black Dashboard Angular</b> - a beautiful freebie for every web developer.', '', {
|
||||
disableTimeOut: true,
|
||||
closeButton: true,
|
||||
enableHtml: true,
|
||||
toastClass: "alert alert-success alert-with-icon",
|
||||
positionClass: 'toast-' + from + '-' + align
|
||||
});
|
||||
break;
|
||||
case 3:
|
||||
this.toastr.warning('<span class="tim-icons icon-bell-55" [data-notify]="icon"></span> Welcome to <b>Black Dashboard Angular</b> - a beautiful freebie for every web developer.', '', {
|
||||
disableTimeOut: true,
|
||||
closeButton: true,
|
||||
enableHtml: true,
|
||||
toastClass: "alert alert-warning alert-with-icon",
|
||||
positionClass: 'toast-' + from + '-' + align
|
||||
});
|
||||
break;
|
||||
case 4:
|
||||
this.toastr.error('<span class="tim-icons icon-bell-55" [data-notify]="icon"></span> Welcome to <b>Black Dashboard Angular</b> - a beautiful freebie for every web developer.', '', {
|
||||
disableTimeOut: true,
|
||||
enableHtml: true,
|
||||
closeButton: true,
|
||||
toastClass: "alert alert-danger alert-with-icon",
|
||||
positionClass: 'toast-' + from + '-' + align
|
||||
});
|
||||
break;
|
||||
case 5:
|
||||
this.toastr.show('<span class="tim-icons icon-bell-55" [data-notify]="icon"></span> Welcome to <b>Black Dashboard Angular</b> - a beautiful freebie for every web developer.', '', {
|
||||
disableTimeOut: true,
|
||||
closeButton: true,
|
||||
enableHtml: true,
|
||||
toastClass: "alert alert-primary alert-with-icon",
|
||||
positionClass: 'toast-' + from + '-' + align
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {}
|
||||
}
|
||||
122
src/app/pages/payments/payments.component.html
Normal file
122
src/app/pages/payments/payments.component.html
Normal file
@@ -0,0 +1,122 @@
|
||||
<div class="content">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4 class="card-title">Payment Details</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table tablesorter">
|
||||
<thead class="text-primary">
|
||||
<tr>
|
||||
<th>S/N</th>
|
||||
<th>Payment Number</th>
|
||||
<th>Invoice Number</th>
|
||||
<th class="text-center">Payment Date</th>
|
||||
<th class="text-center">Amount</th>
|
||||
<th>Method</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let payment of payments; let i = index">
|
||||
<td>{{ i + 1 }}</td>
|
||||
<td>{{ payment.paymentNumber }}</td>
|
||||
<td>{{ payment.invoiceNumber }}</td>
|
||||
<td>
|
||||
{{
|
||||
payment.paymentDate.toLocaleDateString("en-US", options)
|
||||
}}
|
||||
</td>
|
||||
<td class="text-center">₦{{ payment.amount }}</td>
|
||||
<td
|
||||
class="text-capitalize"
|
||||
[ngStyle]="{ 'color': getMethodColor(payment.method) }"
|
||||
style="font-weight: 600;"
|
||||
>
|
||||
{{ payment.method }}
|
||||
</td>
|
||||
<td
|
||||
class="text-capitalize"
|
||||
style="font-weight: 600"
|
||||
[ngStyle]="{ 'color': getStatusColor(payment.status) }"
|
||||
>
|
||||
{{ payment.status }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class=" col-md-12">
|
||||
<div class=" card card-plain">
|
||||
<div class=" card-header">
|
||||
<h4 class=" card-title">Table on Plain Background</h4>
|
||||
<p class=" category">Here is a subtitle for this table</p>
|
||||
</div>
|
||||
<div class=" card-body">
|
||||
<div class=" table-responsive">
|
||||
<table class=" table tablesorter" id="">
|
||||
<thead class=" text-primary">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Country</th>
|
||||
<th>City</th>
|
||||
<th class=" text-center">Salary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Dakota Rice</td>
|
||||
<td>Niger</td>
|
||||
<td>Oud-Turnhout</td>
|
||||
<td class=" text-center">$36,738</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Minerva Hooper</td>
|
||||
<td>Curaçao</td>
|
||||
<td>Sinaai-Waas</td>
|
||||
<td class=" text-center">$23,789</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sage Rodriguez</td>
|
||||
<td>Netherlands</td>
|
||||
<td>Baileux</td>
|
||||
<td class=" text-center">$56,142</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Philip Chaney</td>
|
||||
<td>Korea, South</td>
|
||||
<td>Overland Park</td>
|
||||
<td class=" text-center">$38,735</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Doris Greene</td>
|
||||
<td>Malawi</td>
|
||||
<td>Feldkirchen in Kärnten</td>
|
||||
<td class=" text-center">$63,542</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mason Porter</td>
|
||||
<td>Chile</td>
|
||||
<td>Gloucester</td>
|
||||
<td class=" text-center">$78,615</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Jon Porter</td>
|
||||
<td>Portugal</td>
|
||||
<td>Gloucester</td>
|
||||
<td class=" text-center">$98,615</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
0
src/app/pages/payments/payments.component.scss
Normal file
0
src/app/pages/payments/payments.component.scss
Normal file
25
src/app/pages/payments/payments.component.spec.ts
Normal file
25
src/app/pages/payments/payments.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { PaymentsComponent } from './payments.component';
|
||||
|
||||
describe('PaymentsComponent', () => {
|
||||
let component: PaymentsComponent;
|
||||
let fixture: ComponentFixture<PaymentsComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ PaymentsComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(PaymentsComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
68
src/app/pages/payments/payments.component.ts
Normal file
68
src/app/pages/payments/payments.component.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { PaymentModel } from "../../models/payment";
|
||||
import { PaymentService } from "../../services/payment.service";
|
||||
|
||||
@Component({
|
||||
selector: "app-payments",
|
||||
templateUrl: "./payments.component.html",
|
||||
styleUrls: ["./payments.component.scss"],
|
||||
})
|
||||
export class PaymentsComponent implements OnInit {
|
||||
payments: PaymentModel[];
|
||||
options: any;
|
||||
|
||||
constructor(private paymentService: PaymentService) {
|
||||
this.paymentService
|
||||
.getPaymentById(1)
|
||||
.subscribe((payment: PaymentModel[]) => {
|
||||
this.payments = payment;
|
||||
|
||||
for (let i = 0; i < payment.length; i++) {
|
||||
let amountWithCommas = payment[i].amount.replace(
|
||||
/\B(?=(\d{3})+(?!\d))/g,
|
||||
","
|
||||
);
|
||||
payment[i].amount = amountWithCommas;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.options = {
|
||||
weekday: "short",
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
};
|
||||
}
|
||||
|
||||
// Get color status
|
||||
getStatusColor(status: string): string {
|
||||
switch (status) {
|
||||
case "pending":
|
||||
return "#FFC107";
|
||||
case "completed":
|
||||
return "#4CAF50";
|
||||
case "failed":
|
||||
return "#DC143C";
|
||||
default:
|
||||
return "inherit";
|
||||
}
|
||||
}
|
||||
|
||||
// Get color for methods
|
||||
getMethodColor(method: string): string {
|
||||
switch (method) {
|
||||
case "bank transfer":
|
||||
return "#0072c6";
|
||||
case "credit card":
|
||||
return "#ff6f00";
|
||||
case "cheque":
|
||||
return "#8bc34a";
|
||||
case "cash":
|
||||
return "#795548";
|
||||
default:
|
||||
return "inherit";
|
||||
}
|
||||
}
|
||||
}
|
||||
136
src/app/pages/tables/tables.component.html
Normal file
136
src/app/pages/tables/tables.component.html
Normal file
@@ -0,0 +1,136 @@
|
||||
|
||||
<div class=" content">
|
||||
<div class=" row">
|
||||
<div class=" col-md-12">
|
||||
<div class=" card">
|
||||
<div class=" card-header">
|
||||
<h4 class=" card-title">Simple Table</h4>
|
||||
</div>
|
||||
<div class=" card-body">
|
||||
<div class=" table-responsive">
|
||||
<table class=" table tablesorter" id="">
|
||||
<thead class=" text-primary">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Country</th>
|
||||
<th>City</th>
|
||||
<th class=" text-center">Salary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Dakota Rice</td>
|
||||
<td>Niger</td>
|
||||
<td>Oud-Turnhout</td>
|
||||
<td class=" text-center">$36,738</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Minerva Hooper</td>
|
||||
<td>Curaçao</td>
|
||||
<td>Sinaai-Waas</td>
|
||||
<td class=" text-center">$23,789</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sage Rodriguez</td>
|
||||
<td>Netherlands</td>
|
||||
<td>Baileux</td>
|
||||
<td class=" text-center">$56,142</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Philip Chaney</td>
|
||||
<td>Korea, South</td>
|
||||
<td>Overland Park</td>
|
||||
<td class=" text-center">$38,735</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Doris Greene</td>
|
||||
<td>Malawi</td>
|
||||
<td>Feldkirchen in Kärnten</td>
|
||||
<td class=" text-center">$63,542</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mason Porter</td>
|
||||
<td>Chile</td>
|
||||
<td>Gloucester</td>
|
||||
<td class=" text-center">$78,615</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Jon Porter</td>
|
||||
<td>Portugal</td>
|
||||
<td>Gloucester</td>
|
||||
<td class=" text-center">$98,615</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class=" col-md-12">
|
||||
<div class=" card card-plain">
|
||||
<div class=" card-header">
|
||||
<h4 class=" card-title">Table on Plain Background</h4>
|
||||
<p class=" category">Here is a subtitle for this table</p>
|
||||
</div>
|
||||
<div class=" card-body">
|
||||
<div class=" table-responsive">
|
||||
<table class=" table tablesorter" id="">
|
||||
<thead class=" text-primary">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Country</th>
|
||||
<th>City</th>
|
||||
<th class=" text-center">Salary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Dakota Rice</td>
|
||||
<td>Niger</td>
|
||||
<td>Oud-Turnhout</td>
|
||||
<td class=" text-center">$36,738</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Minerva Hooper</td>
|
||||
<td>Curaçao</td>
|
||||
<td>Sinaai-Waas</td>
|
||||
<td class=" text-center">$23,789</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Sage Rodriguez</td>
|
||||
<td>Netherlands</td>
|
||||
<td>Baileux</td>
|
||||
<td class=" text-center">$56,142</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Philip Chaney</td>
|
||||
<td>Korea, South</td>
|
||||
<td>Overland Park</td>
|
||||
<td class=" text-center">$38,735</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Doris Greene</td>
|
||||
<td>Malawi</td>
|
||||
<td>Feldkirchen in Kärnten</td>
|
||||
<td class=" text-center">$63,542</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Mason Porter</td>
|
||||
<td>Chile</td>
|
||||
<td>Gloucester</td>
|
||||
<td class=" text-center">$78,615</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Jon Porter</td>
|
||||
<td>Portugal</td>
|
||||
<td>Gloucester</td>
|
||||
<td class=" text-center">$98,615</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
11
src/app/pages/tables/tables.component.ts
Normal file
11
src/app/pages/tables/tables.component.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
|
||||
@Component({
|
||||
selector: "app-tables",
|
||||
templateUrl: "tables.component.html"
|
||||
})
|
||||
export class TablesComponent implements OnInit {
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
}
|
||||
Reference in New Issue
Block a user