first commit

This commit is contained in:
Kola92
2023-04-25 09:17:32 +01:00
commit c36c04def5
274 changed files with 55044 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { BrowserModule } from "@angular/platform-browser";
import { Routes, RouterModule } from "@angular/router";
import { AdminLayoutComponent } from "./layouts/admin-layout/admin-layout.component";
import { AuthLayoutComponent } from './layouts/auth-layout/auth-layout.component';
const routes: Routes = [
{
path: "",
redirectTo: "company-information",
pathMatch: "full"
},
{
path: "",
component: AdminLayoutComponent,
children: [
{
path: "",
loadChildren: () => import ("./layouts/admin-layout/admin-layout.module").then(m => m.AdminLayoutModule)
}
]
}, {
path: "",
component: AuthLayoutComponent,
children: [
{
path: "",
loadChildren: () => import ("./layouts/auth-layout/auth-layout.module").then(m => m.AuthLayoutModule)
}
]
},
{
path: "**",
redirectTo: "company-information"
}
];
@NgModule({
imports: [
CommonModule,
BrowserModule,
RouterModule.forRoot(routes, {
useHash: true
})
],
exports: [RouterModule]
})
export class AppRoutingModule {}

View File

@@ -0,0 +1,3 @@
<!--The content below is only a placeholder and can be replaced.-->
<router-outlet></router-outlet>

View File

View File

@@ -0,0 +1,33 @@
import { TestBed, async } from "@angular/core/testing";
import { RouterTestingModule } from "@angular/router/testing";
import { AppComponent } from "./app.component";
describe("AppComponent", () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [AppComponent]
}).compileComponents();
}));
it("should create the app", () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'black-dashboard-angular'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.debugElement.componentInstance;
expect(app.title).toEqual("black-dashboard-angular");
});
it("should render title in a h1 tag", () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector("h1").textContent).toContain(
"Welcome to black-dashboard-angular!"
);
});
});

10
src/app/app.component.ts Normal file
View File

@@ -0,0 +1,10 @@
import { Component } from "@angular/core";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"]
})
export class AppComponent {
title = "black-dashboard-angular";
}

34
src/app/app.module.ts Normal file
View File

@@ -0,0 +1,34 @@
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
import { NgModule } from "@angular/core";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { HttpClientModule } from "@angular/common/http";
import { RouterModule } from "@angular/router";
import { ToastrModule } from "ngx-toastr";
import { AppComponent } from "./app.component";
import { AdminLayoutComponent } from "./layouts/admin-layout/admin-layout.component";
import { AuthLayoutComponent } from "./layouts/auth-layout/auth-layout.component";
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
import { AppRoutingModule } from "./app-routing.module";
import { ComponentsModule } from "./components/components.module";
import { LoginComponent } from './pages/login/login.component';
@NgModule({
imports: [
BrowserAnimationsModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
ComponentsModule,
NgbModule,
RouterModule,
AppRoutingModule,
ToastrModule.forRoot(),
],
declarations: [AppComponent, AdminLayoutComponent, AuthLayoutComponent, LoginComponent],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}

View File

@@ -0,0 +1,15 @@
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { RouterModule } from "@angular/router";
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
import { FooterComponent } from "./footer/footer.component";
import { NavbarComponent } from "./navbar/navbar.component";
import { SidebarComponent } from "./sidebar/sidebar.component";
@NgModule({
imports: [CommonModule, RouterModule, NgbModule],
declarations: [FooterComponent, NavbarComponent, SidebarComponent],
exports: [FooterComponent, NavbarComponent, SidebarComponent]
})
export class ComponentsModule {}

View File

@@ -0,0 +1,28 @@
<footer class="footer">
<div class="container-fluid">
<ul class="nav">
<!-- <li class="nav-item">
<a class="nav-link" href="https://www.creative-tim.com?ref=bda-footer">
Creative Tim
</a>
</li> -->
<li class="nav-item">
<a
class="nav-link"
href="https://talenttic.com"
>
About Us
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://blog.talenttic.com">
Blog
</a>
</li>
</ul>
<div class="copyright">
&copy; {{ test | date : "yyyy" }} Powered by
<a href="https://talenttic.com" target="_blank"> Talenttic Tech Hub</a>
</div>
</div>
</footer>

View File

@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
import { FooterComponent } from "./footer.component";
describe("FooterComponent", () => {
let component: FooterComponent;
let fixture: ComponentFixture<FooterComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [FooterComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(FooterComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it("should create", () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,14 @@
import { Component, OnInit } from "@angular/core";
@Component({
selector: "app-footer",
templateUrl: "./footer.component.html",
styleUrls: ["./footer.component.css"]
})
export class FooterComponent implements OnInit {
test: Date = new Date();
constructor() {}
ngOnInit() {}
}

View File

@@ -0,0 +1,137 @@
<nav class=" navbar navbar-expand-lg navbar-absolute navbar-transparent">
<div class=" container-fluid">
<div class=" navbar-wrapper">
<div class=" navbar-toggle d-inline">
<button class=" navbar-toggler" type="button" (click)="sidebarToggle()">
<span class=" navbar-toggler-bar bar1"> </span>
<span class=" navbar-toggler-bar bar2"> </span>
<span class=" navbar-toggler-bar bar3"> </span>
</button>
</div>
<a class=" navbar-brand" href="javascript:void(0)"> {{ getTitle() }} </a>
</div>
<button
aria-label="Toggle navigation"
class=" navbar-toggler"
(click)="collapse()"
[attr.aria-expanded]="!isCollapsed"
aria-controls="collapseExample"
id="navigation"
type="button"
>
<span class=" navbar-toggler-bar navbar-kebab"> </span>
<span class=" navbar-toggler-bar navbar-kebab"> </span>
<span class=" navbar-toggler-bar navbar-kebab"> </span>
</button>
<div class=" navbar-collapse" [ngbCollapse]="isCollapsed" id="navigation">
<ul class=" navbar-nav ml-auto">
<li class=" search-bar input-group">
<button
class=" btn btn-link"
data-target="#searchModal"
data-toggle="modal"
(click)="open(content)"
id="search-button"
>
<i class=" tim-icons icon-zoom-split"> </i>
<span class=" d-lg-none d-md-block"> Search </span>
</button>
</li>
<li class=" nav-item" ngbDropdown>
<a
class=" nav-link"
data-toggle="dropdown"
href="javascript:void(0)"
ngbDropdownToggle
>
<div class=" notification d-none d-lg-block d-xl-block"></div>
<i class=" tim-icons icon-sound-wave"> </i>
<p class=" d-lg-none">Notifications</p>
</a>
<ul class=" dropdown-menu-right dropdown-navbar" ngbDropdownMenu>
<li class=" nav-link">
<a class=" nav-item" href="javascript:void(0)" ngbDropdownItem>
Mike John responded to your email
</a>
</li>
<li class=" nav-link">
<a class=" nav-item" href="javascript:void(0)" ngbDropdownItem>
You have 5 more tasks
</a>
</li>
<li class=" nav-link">
<a class=" nav-item" href="javascript:void(0)" ngbDropdownItem>
Your friend Michael is in town
</a>
</li>
<li class=" nav-link">
<a class=" nav-item" href="javascript:void(0)" ngbDropdownItem>
Another notification
</a>
</li>
<li class=" nav-link">
<a class=" nav-item" href="javascript:void(0)" ngbDropdownItem>
Another one
</a>
</li>
</ul>
</li>
<li class=" nav-item" ngbDropdown>
<a
class=" nav-link"
data-toggle="dropdown"
href="javascript:void(0)"
ngbDropdownToggle
>
<div class=" photo">
<img alt="Profile Photo" src="assets/img/anime3.png" />
</div>
<b class=" caret d-none d-lg-block d-xl-block"> </b>
<p class=" d-lg-none">Log out</p>
</a>
<ul class=" dropdown-navbar" ngbDropdownMenu>
<li class=" nav-link">
<a class=" nav-item" href="javascript:void(0)" ngbDropdownItem>
Profile
</a>
</li>
<li class=" nav-link">
<a class=" nav-item" href="javascript:void(0)" ngbDropdownItem>
Settings
</a>
</li>
<li class=" dropdown-divider"></li>
<li class=" nav-link">
<a class=" nav-item" href="javascript:void(0)" ngbDropdownItem>
Log out
</a>
</li>
</ul>
</li>
<li class=" separator d-lg-none"></li>
</ul>
</div>
</div>
</nav>
<ng-template #content let-modal>
<div class=" modal-header">
<input
class=" form-control"
id="inlineFormInputGroup"
placeholder="SEARCH"
type="text"
/>
<button
aria-label="Close"
class=" close"
data-dismiss="modal"
type="button"
(click)="modal.dismiss('Cross click')"
>
<i class=" tim-icons icon-simple-remove"> </i>
</button>
</div>
</ng-template>

View File

@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
import { NavbarComponent } from "./navbar.component";
describe("NavbarComponent", () => {
let component: NavbarComponent;
let fixture: ComponentFixture<NavbarComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [NavbarComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NavbarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it("should create", () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,196 @@
import { Component, OnInit, ElementRef, OnDestroy } from "@angular/core";
import { ROUTES } from "../sidebar/sidebar.component";
import { Location } from "@angular/common";
import { Router } from "@angular/router";
import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: "app-navbar",
templateUrl: "./navbar.component.html",
styleUrls: ["./navbar.component.css"]
})
export class NavbarComponent implements OnInit, OnDestroy {
private listTitles: any[];
location: Location;
mobile_menu_visible: any = 0;
private toggleButton: any;
private sidebarVisible: boolean;
public isCollapsed = true;
closeResult: string;
constructor(
location: Location,
private element: ElementRef,
private router: Router,
private modalService: NgbModal
) {
this.location = location;
this.sidebarVisible = false;
}
// function that adds color white/transparent to the navbar on resize (this is for the collapse)
updateColor = () => {
var navbar = document.getElementsByClassName('navbar')[0];
if (window.innerWidth < 993 && !this.isCollapsed) {
navbar.classList.add('bg-white');
navbar.classList.remove('navbar-transparent');
} else {
navbar.classList.remove('bg-white');
navbar.classList.add('navbar-transparent');
}
};
ngOnInit() {
window.addEventListener("resize", this.updateColor);
this.listTitles = ROUTES.filter(listTitle => listTitle);
const navbar: HTMLElement = this.element.nativeElement;
this.toggleButton = navbar.getElementsByClassName("navbar-toggler")[0];
this.router.events.subscribe(event => {
this.sidebarClose();
var $layer: any = document.getElementsByClassName("close-layer")[0];
if ($layer) {
$layer.remove();
this.mobile_menu_visible = 0;
}
});
}
collapse() {
this.isCollapsed = !this.isCollapsed;
const navbar = document.getElementsByTagName("nav")[0];
if (!this.isCollapsed) {
navbar.classList.remove("navbar-transparent");
navbar.classList.add("bg-white");
} else {
navbar.classList.add("navbar-transparent");
navbar.classList.remove("bg-white");
}
}
sidebarOpen() {
const toggleButton = this.toggleButton;
const mainPanel = <HTMLElement>(
document.getElementsByClassName("main-panel")[0]
);
const html = document.getElementsByTagName("html")[0];
if (window.innerWidth < 991) {
mainPanel.style.position = "fixed";
}
setTimeout(function() {
toggleButton.classList.add("toggled");
}, 500);
html.classList.add("nav-open");
this.sidebarVisible = true;
}
sidebarClose() {
const html = document.getElementsByTagName("html")[0];
this.toggleButton.classList.remove("toggled");
const mainPanel = <HTMLElement>(
document.getElementsByClassName("main-panel")[0]
);
if (window.innerWidth < 991) {
setTimeout(function() {
mainPanel.style.position = "";
}, 500);
}
this.sidebarVisible = false;
html.classList.remove("nav-open");
}
sidebarToggle() {
// const toggleButton = this.toggleButton;
// const html = document.getElementsByTagName('html')[0];
var $toggle = document.getElementsByClassName("navbar-toggler")[0];
if (this.sidebarVisible === false) {
this.sidebarOpen();
} else {
this.sidebarClose();
}
const html = document.getElementsByTagName("html")[0];
if (this.mobile_menu_visible == 1) {
// $('html').removeClass('nav-open');
html.classList.remove("nav-open");
if ($layer) {
$layer.remove();
}
setTimeout(function() {
$toggle.classList.remove("toggled");
}, 400);
this.mobile_menu_visible = 0;
} else {
setTimeout(function() {
$toggle.classList.add("toggled");
}, 430);
var $layer = document.createElement("div");
$layer.setAttribute("class", "close-layer");
if (html.querySelectorAll(".main-panel")) {
document.getElementsByClassName("main-panel")[0].appendChild($layer);
} else if (html.classList.contains("off-canvas-sidebar")) {
document
.getElementsByClassName("wrapper-full-page")[0]
.appendChild($layer);
}
setTimeout(function() {
$layer.classList.add("visible");
}, 100);
$layer.onclick = function() {
//asign a function
html.classList.remove("nav-open");
this.mobile_menu_visible = 0;
$layer.classList.remove("visible");
setTimeout(function() {
$layer.remove();
$toggle.classList.remove("toggled");
}, 400);
}.bind(this);
html.classList.add("nav-open");
this.mobile_menu_visible = 1;
}
}
getTitle() {
var title = this.location.prepareExternalUrl(this.location.path());
if (title.charAt(0) === "#") {
title = title.slice(1);
}
for (var item = 0; item < this.listTitles.length; item++) {
if (this.listTitles[item].path === title) {
return this.listTitles[item].title;
}
}
return "Dashboard";
}
open(content) {
this.modalService.open(content, {windowClass: 'modal-search'}).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
}, (reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
});
}
private getDismissReason(reason: any): string {
if (reason === ModalDismissReasons.ESC) {
return 'by pressing ESC';
} else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
return 'by clicking on a backdrop';
} else {
return `with: ${reason}`;
}
}
ngOnDestroy(){
window.removeEventListener("resize", this.updateColor);
}
}

View File

@@ -0,0 +1,25 @@
<div class="logo">
<a routerLink="dashboard" class="simple-text logo-mini">
<div class="logo-img">
<img src="../../../assets/img/logo.png" />
</div>
</a>
<a routerLink="company-information" class="simple-text logo-normal">
Talenttic Tech Hub CRM
</a>
</div>
<div class="sidebar-wrapper">
<ul class="nav">
<li
routerLinkActive="active"
*ngFor="let menuItem of menuItems"
class="{{ menuItem.class }} nav-item"
>
<a [routerLink]="[menuItem.path]">
<i class="bi {{ menuItem.icon }}"></i>
<p>{{ menuItem.title }}</p>
</a>
</li>
</ul>
</div>

View File

@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
import { SidebarComponent } from "./sidebar.component";
describe("SidebarComponent", () => {
let component: SidebarComponent;
let fixture: ComponentFixture<SidebarComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [SidebarComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SidebarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it("should create", () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,68 @@
import { Component, OnInit } from "@angular/core";
declare interface RouteInfo {
path: string;
title: string;
icon: string;
class: string;
}
export const ROUTES: RouteInfo[] = [
// {
// path: "/dashboard",
// title: "Dashboard",
// icon: "bi-speedometer",
// class: "",
// },
{
path: "/company-information",
title: "Company Information",
icon: "bi-person-vcard",
class: "",
},
{
path: "/notifications",
title: "Notifications",
icon: "bi-bell",
class: "",
},
{
path: "/company-profile",
title: "Company Profile",
icon: "bi-person-lines-fill",
class: "",
},
{
path: "/invoices",
title: "Invoices",
icon: "bi-receipt-cutoff",
class: "",
},
{
path: "/payments",
title: "Payments",
icon: "bi-credit-card",
class: "",
},
];
@Component({
selector: "app-sidebar",
templateUrl: "./sidebar.component.html",
styleUrls: ["./sidebar.component.css"],
})
export class SidebarComponent implements OnInit {
menuItems: any[];
constructor() {}
ngOnInit() {
this.menuItems = ROUTES.filter((menuItem) => menuItem);
}
isMobileMenu() {
if (window.innerWidth > 991) {
return false;
}
return true;
}
}

154
src/app/data/company.ts Normal file
View File

@@ -0,0 +1,154 @@
import { CompanyModel } from "../models/company";
export const company: CompanyModel[] = [
{
id: 1,
name: "Stark Industries",
username: "starkindustries",
email: "info@starkindustries.com",
phone: "09055784625",
image:
"https://webtoolfeed.files.wordpress.com/2012/05/the-union-repoman.jpg",
description:
"A multinational technology company specializing in weapons manufacturing, led by Tony Stark.",
address: "200 Park Ave, New York, NY 10166",
city: "New York City, NY ",
stagingUrl: "stage.starkindustries.com",
productionUrl: "starkindustries.com",
},
{
id: 2,
name: "Wayne Enterprises",
username: "wayneenterprises",
email: "info@wayneenterprises.com",
phone: "0812012234",
image:
"https://www.thesun.co.uk/wp-content/uploads/2019/07/NINTCHDBPICT000491000000.jpg?strip=all&w=960",
description:
"A multinational conglomerate holding company headquartered in Gotham City, led by Bruce Wayne.",
address: "10 Wayne Tower, Gotham City, NJ 07102",
city: "Gotham City, NJ ",
stagingUrl: "stage.wayneenterprises.com",
productionUrl: "wayneenterprises.com",
},
{
id: 3,
name: "LexCorp",
username: "lexcorp",
email: "info@lexcorp.com",
phone: "08174361092",
image:
"https://www.shutterstock.com/image-vector/young-smiling-woman-mia-avatar-600w-2127358541.jpg",
description:
"LexCorp is a multinational conglomerate that operates in various industries, including technology, finance, and media. Founded by billionaire businessman and philanthropist Lex Luthor.",
address: "LexCorp Tower, Metropolis, NY 10001",
city: "Metropolis, NY",
stagingUrl: "stage.lexcorp.com",
productionUrl: "lexcorp.com",
},
{
id: 4,
name: "Sahara Security & Investigation Ltd.",
username: "saharasecurity_ng",
email: "info@saharasecurity.ng",
phone: "08120122347",
image:
"https://www.shutterstock.com/image-vector/young-smiling-man-adam-avatar-600w-2107967969.jpg",
description:
"Sahara Security & Investigation is a leading provider of security and investigation services for businesses and individuals across Nigeria. With a team of highly trained professionals and state-of-the-art equipment, we are committed to protecting our clients' assets and interests.",
address: "5, Bode Thomas Street, Surulere, Lagos State",
city: "Lagos, Nigeria",
stagingUrl: "stage.saharasecurity.com",
productionUrl: "saharasecurity.ng",
},
{
id: 5,
name: "Umbrella Corporation",
username: "umbrellacorporation",
email: "info@umbrellacorp.com",
phone: "07073214806",
image:
"https://www.shutterstock.com/image-vector/young-smiling-man-adam-avatar-600w-2107967969.jpg",
description:
"Umbrella Corporation is a pharmaceutical company that specializes in bioweapons and bioengineering.",
address: "Umbrella Corporation, Raccoon City, NY 10001",
city: "Raccoon City, NY",
stagingUrl: "stage.umbrellacorp.com",
productionUrl: "umbrellacorp.com",
},
{
id: 6,
name: "Aperture Science",
username: "aperturescience",
email: "aperturescience@info.com",
phone: "08033567890",
image:
"https://www.shutterstock.com/image-vector/young-smiling-man-adam-avatar-600w-2107967969.jpg",
description:
"Aperture Science is a science and technology company that specializes in the development of advanced research facilities and the manufacturing of consumer products.",
address: "Aperture Science, New York City, NY 10001",
city: "New York City, NY",
stagingUrl: "stage.aperturescience.com",
productionUrl: "aperturescience.com",
},
{
id: 7,
name: "Stellar Airways Nigeria Ltd.",
username: "stellarairways_ng",
email: "info@stellarairways.ng",
phone: "07084849673",
image:
"https://www.shutterstock.com/image-vector/young-smiling-woman-mia-avatar-600w-2127358541.jpg",
description:
"Stellar Airways Nigeria is a premier airline that provides domestic and international travel services to individuals and businesses across Nigeria. With a focus on safety, comfort, and convenience, we are dedicated to providing exceptional travel experiences to our customers.",
address: "Murtala Muhammed International Airport, Ikeja, Lagos State",
city: "Lagos, Nigeria",
stagingUrl: "stage.stellarairways.com",
productionUrl: "stellarairways.ng",
},
{
id: 8,
name: "Deltacore Technologies Ltd.",
username: "deltacore_ng",
email: "info@deltacore.ng",
phone: "09022345109",
image:
"https://www.shutterstock.com/image-vector/young-smiling-woman-mia-avatar-600w-2127358541.jpg",
description:
"Deltacore Technologies is a leading provider of software and hardware solutions for businesses and individuals across Nigeria. With a focus on innovation and quality, we provide cutting-edge technology products and services to help our clients stay ahead of the competition.",
address: "23, Adeyemo Alakija Street, Victoria Island, Lagos State",
city: "Lagos, Nigeria",
stagingUrl: "stage.deltacore.com",
productionUrl: "deltacore.ng",
},
{
id: 9,
name: "Goldmine Oil & Gas Ltd.",
username: "goldmineoilgas_ng",
email: "info@goldmineoilgas.ng",
phone: "0911250021",
image:
"https://www.shutterstock.com/image-vector/young-smiling-man-adam-avatar-600w-2107967969.jpg",
description:
"Goldmine Oil & Gas is a leading exploration and production company that operates in the Nigerian oil and gas industry. With a focus on sustainability and innovation, we are committed to maximizing the potential of Nigeria's natural resources while minimizing our environmental impact.",
address: "14, Marina Road, Warri South, Delta State",
city: "Warri, Nigeria",
stagingUrl: "stage.goldmineoilgas.com",
productionUrl: "goldmineoilgas.ng",
},
{
id: 10,
name: "Cedarwood Construction & Engineering Ltd.",
username: "cedarwoodconstruction_ng",
email: "info@cedarwoodconstruction.ng",
phone: "0911250021",
image:
"https://thumbs.dreamstime.com/b/male-avatar-icon-flat-style-male-user-icon-cartoon-man-avatar-hipster-vector-stock-91462914.jpg",
description:
"Cedarwood Construction & Engineering is a leading construction company that provides innovative solutions for residential, commercial, and industrial projects across Nigeria. With a team of skilled professionals and state-of-the-art equipment, we are committed to delivering high-quality projects on time and within budget.",
address: "9, Adeniyi Jones Avenue, Ikeja, Lagos State",
city: "Lagos, Nigeria",
stagingUrl: "stage.cedarwoodconstruction.com",
productionUrl: "cedarwoodconstruction.ng",
},
];

View File

@@ -0,0 +1,124 @@
import { DatabaseInfoModel } from "../models/database-info";
export const databaseInfo: DatabaseInfoModel[] = [
{
id: 1,
serverId: 1,
companyId: 1,
databaseName: "database1",
databaseType: "MySQL",
bandwidthGB: 1,
username: "user123",
password: "password123",
host: "localhost",
port: 3306,
},
{
id: 2,
serverId: 2,
companyId: 2,
databaseName: "database2",
databaseType: "PostgreSQL",
bandwidthGB: 10,
username: "dbuser2",
password: "dbpassword2",
host: "db-host-1a3c.example.com",
port: 5432,
},
{
id: 3,
serverId: 3,
companyId: 3,
databaseName: "database3",
databaseType: "MongoDB",
bandwidthGB: 100,
username: "dbuser3",
password: "dbpassword3",
host: "db2-4f8d.example.org",
port: 27017,
},
{
id: 4,
serverId: 4,
companyId: 4,
databaseName: "database4",
databaseType: "SQLite",
bandwidthGB: 1000,
username: "dbuser4",
password: "dbpassword4",
host: "random-db-12a5.example.net",
port: 3306,
},
{
id: 5,
serverId: 5,
companyId: 5,
databaseName: "database5",
databaseType: "MySQL",
bandwidthGB: 2000,
username: "dbuser5",
password: "dbpassword5",
host: "host-9c5b.example.net",
port: 5432,
},
{
id: 6,
serverId: 6,
companyId: 6,
databaseName: "database6",
databaseType: "PostgreSQL",
bandwidthGB: 3000,
username: "dbuser6",
password: "dbpassword6",
host: "db-server-7e2f.example.com",
port: 27017,
},
{
id: 7,
serverId: 8,
companyId: 8,
databaseName: "database7",
databaseType: "MongoDB",
bandwidthGB: 4000,
username: "dbuser7",
password: "dbpassword7",
host: "mydb-1f4a.example.net",
port: 3306,
},
{
id: 8,
serverId: 7,
companyId: 7,
databaseName: "database8",
databaseType: "SQLite",
bandwidthGB: 5000,
username: "dbuser8",
password: "dbpassword8",
host: "db-1f4a.example.net",
port: 5432,
},
{
id: 9,
serverId: 9,
companyId: 9,
databaseName: "database9",
databaseType: "MySQL",
bandwidthGB: 400,
username: "dbuser9",
password: "dbpassword9",
host: "dbhost-5b9c.example.org",
port: 27017,
},
{
id: 10,
serverId: 10,
companyId: 10,
databaseName: "database10",
databaseType: "PostgreSQL",
bandwidthGB: 300,
username: "dbuser10",
password: "dbpassword10",
host: "randomdb-3e8d.example.com",
port: 3306,
},
];

View File

@@ -0,0 +1,124 @@
import { HostingInfoModel } from "../models/hosting-info";
export const hostingInfo: HostingInfoModel[] = [
{
id: 1,
companyId: 1,
provider: "Digital Ocean",
serverType: "VPS",
diskSpaceGB: 100,
bandwidthGB: 1000,
username: "user123",
password: "password123",
serverLocation: "United States",
expirationDate: new Date("2025-12-31"),
},
{
id: 2,
companyId: 2,
provider: "Bluehost",
serverType: "shared",
diskSpaceGB: 150,
bandwidthGB: 500,
username: "user456",
password: "password456",
serverLocation: "United States",
expirationDate: new Date("2024-02-31"),
},
{
id: 3,
companyId: 3,
provider: "SiteGround",
serverType: "dedicated",
diskSpaceGB: 500,
bandwidthGB: 5000,
username: "user789",
password: "password789",
serverLocation: "United Kingdom",
expirationDate: new Date("2023-03-31"),
},
{
id: 4,
companyId: 4,
provider: "HostGator",
serverType: "shared",
diskSpaceGB: 200,
bandwidthGB: 1000,
username: "user101",
password: "password101",
serverLocation: "Canada",
expirationDate: new Date("2022-04-31"),
},
{
id: 5,
companyId: 5,
provider: "DreamHost",
serverType: "shared",
diskSpaceGB: 50,
bandwidthGB: 500,
username: "user111",
password: "password111",
serverLocation: "United States",
expirationDate: new Date("2023-05-11"),
},
{
id: 6,
companyId: 6,
provider: "GoDaddy",
serverType: "VPS",
diskSpaceGB: 100,
bandwidthGB: 1000,
username: "user121",
password: "password121",
serverLocation: "United States",
expirationDate: new Date("2022-06-21"),
},
{
id: 7,
companyId: 7,
provider: "Hostinger",
serverType: "shared",
diskSpaceGB: 500,
bandwidthGB: 5000,
username: "user131",
password: "password131",
serverLocation: "Singapore",
expirationDate: new Date("2025-04-08"),
},
{
id: 8,
companyId: 8,
provider: "InMotion Hosting",
serverType: "dedicated",
diskSpaceGB: 2000,
bandwidthGB: 20000,
username: "user141",
password: "password141",
serverLocation: "United States",
expirationDate: new Date("2024-07-21"),
},
{
id: 9,
companyId: 9,
provider: "Namecheap",
serverType: "shared",
diskSpaceGB: 100,
bandwidthGB: 1000,
username: "user151",
password: "password151",
serverLocation: "Netherlands",
expirationDate: new Date("2023-10-01"),
},
{
id: 10,
companyId: 10,
provider: "A2 Hosting",
serverType: "VPS",
diskSpaceGB: 500,
bandwidthGB: 5000,
username: "user161",
password: "password161",
serverLocation: "United Kingdom",
expirationDate: new Date("2022-11-11"),
},
];

238
src/app/data/invoice.ts Normal file
View File

@@ -0,0 +1,238 @@
import { InvoiceModel } from "../models/invoice";
export const invoice: InvoiceModel[] = [
{
id: 1,
invoiceNumber: "INV-0001",
companyId: 2,
dateIssued: new Date("2023-03-15"),
dueDate: new Date("2023-03-30"),
status: "paid",
amount: "100000",
currency: "₦",
services: [
{
description: "Custom Website Development",
service: 1,
unitPrice: 100000,
total: 100000,
},
],
},
{
id: 2,
invoiceNumber: "INV-0002",
companyId: 3,
dateIssued: new Date("2023-03-20"),
dueDate: new Date("2023-04-10"),
status: "pending",
amount: "300000",
currency: "₦",
services: [
{
description: "Custom Mobile App Development",
service: 1,
unitPrice: 300000,
total: 300000,
},
],
},
{
id: 3,
invoiceNumber: "INV-0003",
companyId: 1,
dateIssued: new Date("2023-03-25"),
dueDate: new Date("2023-04-15"),
status: "pending",
amount: "200000",
currency: "₦",
services: [
{
description: "E-commerce Website Development",
service: 1,
unitPrice: 200000,
total: 200000,
},
],
},
{
id: 4,
invoiceNumber: "INV-0004",
companyId: 5,
dateIssued: new Date("2023-03-30"),
dueDate: new Date("2023-04-20"),
status: "paid",
amount: "500000",
currency: "₦",
services: [
{
description: "Website Redesign",
service: 1,
unitPrice: 500000,
total: 500000,
},
],
},
{
id: 5,
invoiceNumber: "INV-0005",
companyId: 6,
dateIssued: new Date("2023-04-05"),
dueDate: new Date("2023-04-25"),
status: "overdue",
amount: "250000",
currency: "₦",
services: [
{
description: "Website Maintenance",
service: 1,
unitPrice: 250000,
total: 250000,
},
],
},
{
id: 6,
invoiceNumber: "INV-0006",
companyId: 7,
dateIssued: new Date("2023-04-10"),
dueDate: new Date("2023-04-30"),
status: "paid",
amount: "100000",
currency: "₦",
services: [
{
description: "Website Hosting",
service: 1,
unitPrice: 100000,
total: 100000,
},
],
},
{
id: 7,
invoiceNumber: "INV-0007",
companyId: 4,
dateIssued: new Date("2023-04-15"),
dueDate: new Date("2023-05-05"),
status: "paid",
amount: "200000",
currency: "₦",
services: [
{
description: "Custom Software Development",
service: 1,
unitPrice: 200000,
total: 200000,
},
],
},
{
id: 8,
invoiceNumber: "INV-0008",
companyId: 8,
dateIssued: new Date("2023-04-15"),
dueDate: new Date("2023-05-05"),
status: "paid",
amount: "200000",
currency: "₦",
services: [
{
description: "Custom Software Development",
service: 1,
unitPrice: 200000,
total: 200000,
},
],
},
{
id: 9,
invoiceNumber: "INV-0009",
companyId: 9,
dateIssued: new Date("2023-04-20"),
dueDate: new Date("2023-05-10"),
status: "paid",
amount: "300000",
currency: "₦",
services: [
{
description: "Website Security Audit",
service: 1,
unitPrice: 300000,
total: 300000,
},
],
},
{
id: 10,
invoiceNumber: "INV-00010",
companyId: 10,
dateIssued: new Date("2023-04-20"),
dueDate: new Date("2023-05-10"),
status: "paid",
amount: "150000",
currency: "₦",
services: [
{
description: "Website Optimization",
service: 1,
unitPrice: 150000,
total: 150000,
},
],
},
{
id: 11,
invoiceNumber: "INV-00011",
companyId: 1,
dateIssued: new Date("2023-03-10"),
dueDate: new Date("2023-06-15"),
status: "paid",
amount: "100000",
currency: "₦",
services: [
{
description: "Website Hosting",
service: 1,
unitPrice: 100000,
total: 100000,
},
],
},
{
id: 12,
invoiceNumber: "INV-00012",
companyId: 1,
dateIssued: new Date("2023-05-05"),
dueDate: new Date("2024-07-15"),
status: "overdue",
amount: "250000",
currency: "₦",
services: [
{
description: "Website Maintenance",
service: 1,
unitPrice: 250000,
total: 250000,
},
],
},
{
id: 13,
invoiceNumber: "INV-00013",
companyId: 1,
dateIssued: new Date("2023-03-21"),
dueDate: new Date("2023-05-15"),
status: "pending",
amount: "70000",
currency: "₦",
services: [
{
description: "Website Security Audit",
service: 1,
unitPrice: 70000,
total: 70000,
},
],
},
];

View File

172
src/app/data/payment.ts Normal file
View File

@@ -0,0 +1,172 @@
import { PaymentModel } from "../models/payment";
export const payment: PaymentModel[] = [
{
id: 1,
invoiceId: 1,
companyId: 1,
invoiceNumber: "INV-001",
paymentNumber: "PAY-001",
paymentDate: new Date("2023-03-10"),
amount: "100000",
currency: "₦",
method: "bank transfer",
status: "pending",
},
{
id: 2,
invoiceId: 2,
companyId: 2,
invoiceNumber: "INV-002",
paymentNumber: "PAY-002",
paymentDate: new Date("2023-03-15"),
amount: "100000",
currency: "₦",
method: "credit card",
status: "completed",
},
{
id: 3,
invoiceId: 3,
companyId: 3,
invoiceNumber: "INV-003",
paymentNumber: "PAY-003",
paymentDate: new Date("2023-03-20"),
amount: "300000",
currency: "₦",
method: "bank transfer",
status: "completed",
},
{
id: 4,
invoiceId: 4,
companyId: 5,
invoiceNumber: "INV-004",
paymentNumber: "PAY-004",
paymentDate: new Date("2023-04-10"),
amount: "500000",
currency: "₦",
method: "cheque",
status: "failed",
},
{
id: 5,
invoiceId: 5,
companyId: 6,
invoiceNumber: "INV-005",
paymentNumber: "PAY-005",
paymentDate: new Date("2023-04-15"),
amount: "250000",
currency: "₦",
method: "bank transfer",
status: "completed",
},
{
id: 6,
invoiceId: 6,
companyId: 7,
invoiceNumber: "INV-006",
paymentNumber: "PAY-006",
paymentDate: new Date("2023-04-17"),
amount: "100000",
currency: "₦",
method: "credit card",
status: "pending",
},
{
id: 7,
invoiceId: 7,
companyId: 4,
invoiceNumber: "INV-007",
paymentNumber: "PAY-007",
paymentDate: new Date("2023-04-22"),
amount: "200000",
currency: "₦",
method: "cash",
status: "completed",
},
{
id: 8,
invoiceId: 8,
companyId: 8,
invoiceNumber: "INV-008",
paymentNumber: "PAY-008",
paymentDate: new Date("2023-04-25"),
amount: "200000",
currency: "₦",
method: "cash",
status: "completed",
},
{
id: 9,
invoiceId: 9,
companyId: 9,
invoiceNumber: "INV-009",
paymentNumber: "PAY-009",
paymentDate: new Date("2023-04-30"),
amount: "300000",
currency: "₦",
method: "cheque",
status: "failed",
},
{
id: 10,
invoiceId: 10,
companyId: 10,
invoiceNumber: "INV-010",
paymentNumber: "PAY-010",
paymentDate: new Date("2023-05-05"),
amount: "300000",
currency: "₦",
method: "bank transfer",
status: "pending",
},
{
id: 11,
invoiceId: 11,
companyId: 1,
invoiceNumber: "INV-011",
paymentNumber: "PAY-011",
paymentDate: new Date("2023-05-10"),
amount: "100000",
currency: "₦",
method: "credit card",
status: "completed",
},
{
id: 12,
invoiceId: 12,
companyId: 1,
invoiceNumber: "INV-012",
paymentNumber: "PAY-012",
paymentDate: new Date("2023-05-15"),
amount: "100000",
currency: "₦",
method: "bank transfer",
status: "pending",
},
{
id: 13,
invoiceId: 13,
companyId: 1,
invoiceNumber: "INV-013",
paymentNumber: "PAY-013",
paymentDate: new Date("2023-05-20"),
amount: "300000",
currency: "₦",
method: "cheque",
status: "failed",
},
{
id: 14,
invoiceId: 14,
companyId: 1,
invoiceNumber: "INV-014",
paymentNumber: "PAY-014",
paymentDate: new Date("2023-05-25"),
amount: "500000",
currency: "₦",
method: "cash",
status: "completed",
},
];

144
src/app/data/server-info.ts Normal file
View File

@@ -0,0 +1,144 @@
import { ServerInfoModel } from "../models/server-info";
export const serverInfo: ServerInfoModel[] = [
{
id: 1,
companyId: 1,
databaseId: 1,
provider: "DigitalOcean",
serverType: "shared",
operatingSystem: "Ubuntu 20.04 LTS",
cpu: "Intel Xeon 2.3 GHz",
storageGB: 100,
ramGB: 4,
bandwidthGB: 4,
monthlyCostUSD: 10,
location: "New York, USA",
},
{
id: 2,
companyId: 2,
databaseId: 2,
provider: "Amazon Web Services",
serverType: "VPS",
operatingSystem: "Amazon Linux 2",
cpu: "Intel Xeon 2.5 GHz",
storageGB: 500,
ramGB: 16,
bandwidthGB: 10,
monthlyCostUSD: 80,
location: "North Virginia, USA",
},
{
id: 3,
companyId: 3,
databaseId: 4,
provider: "Google Cloud Platform",
serverType: "dedicated",
operatingSystem: "CentOS 7",
cpu: "Intel Xeon 2.4 GHz",
storageGB: 200,
ramGB: 8,
bandwidthGB: 5,
monthlyCostUSD: 30,
location: "Oregon, USA",
},
{
id: 4,
companyId: 4,
databaseId: 3,
provider: "Vultr",
serverType: "shared",
operatingSystem: "Ubuntu 18.04 LTS",
cpu: "AMD Ryzen 2.2 GHz",
storageGB: 250,
ramGB: 12,
bandwidthGB: 8,
monthlyCostUSD: 50,
location: "Singapore",
},
{
id: 5,
companyId: 5,
databaseId: 8,
provider: "Linode",
serverType: "VPS",
operatingSystem: "Debian 10",
cpu: "AMD EPYC 2.4 GHz",
storageGB: 300,
ramGB: 16,
bandwidthGB: 6,
monthlyCostUSD: 40,
location: "Dallas, USA",
},
{
id: 6,
companyId: 6,
databaseId: 6,
provider: "Hostinger",
serverType: "shared",
operatingSystem: "CentOS 8",
cpu: "Intel Xeon 2.0 GHz",
storageGB: 150,
ramGB: 6,
bandwidthGB: 3,
monthlyCostUSD: 15,
location: "Lithuania",
},
{
id: 7,
companyId: 7,
databaseId: 7,
provider: "Hetzner",
serverType: "dedicated",
operatingSystem: "Ubuntu 16.04 LTS",
cpu: "Intel Xeon 2.2 GHz",
storageGB: 400,
ramGB: 12,
bandwidthGB: 10,
monthlyCostUSD: 60,
location: "Falkenstein, Germany",
},
{
id: 8,
companyId: 8,
databaseId: 5,
provider: "OVH",
serverType: "shared",
operatingSystem: "Ubuntu 20.04 LTS",
cpu: "Intel Xeon 2.3 GHz",
storageGB: 100,
ramGB: 4,
bandwidthGB: 4,
monthlyCostUSD: 10,
location: "France",
},
{
id: 9,
companyId: 9,
databaseId: 9,
provider: "AWS",
serverType: "VPS",
operatingSystem: "Amazon Linux 2",
cpu: "2 vCPUs",
storageGB: 40,
ramGB: 4,
bandwidthGB: 10,
monthlyCostUSD: 50,
location: "Sydney, Australia",
},
{
id: 10,
companyId: 10,
databaseId: 10,
provider: "AWS",
serverType: "dedicated",
operatingSystem: "Red Hat Enterprise Linux 8",
cpu: "4 vCPUs",
storageGB: 100,
ramGB: 8,
bandwidthGB: 20,
monthlyCostUSD: 200,
location: "Mumbai, India",
},
];

View File

@@ -0,0 +1,44 @@
<div class="wrapper">
<div class="sidebar"><app-sidebar></app-sidebar></div>
<div class="main-panel">
<app-navbar></app-navbar>
<router-outlet></router-outlet>
<app-footer></app-footer>
</div>
</div>
<div class=" fixed-plugin">
<div class=" show-dropdown" ngbDropdown>
<a data-toggle="dropdown" ngbDropdownToggle>
<i class=" fa fa-cog fa-2x"> </i>
</a>
<ul ngbDropdownMenu>
<li class=" header-title">Sidebar Background</li>
<li class=" adjustments-line">
<a class=" switch-trigger background-color" href="javascript:void(0)">
<div class=" badge-colors text-center">
<span
class=" badge filter badge-danger"
[ngClass]="{'active':sidebarColor==='red'}" (click)="changeSidebarColor('red')"
>
</span>
<span
class=" badge filter badge-primary"
[ngClass]="{'active':sidebarColor==='primary'}" (click)="changeSidebarColor('primary')"
>
</span>
<span class=" badge filter badge-info" [ngClass]="{'active':sidebarColor==='blue'}" (click)="changeSidebarColor('blue')"> </span>
<span class=" badge filter badge-success" [ngClass]="{'active':sidebarColor==='green'}" (click)="changeSidebarColor('green')">
</span>
</div>
<div class=" clearfix"></div>
</a>
</li>
<li class=" adjustments-line text-center color-change">
<span class=" color-label"> LIGHT MODE </span>
<span class=" badge light-badge mr-2" (click)="changeDashboardColor('white-content')"> </span>
<span class=" badge dark-badge ml-2" (click)="changeDashboardColor('black-content')"> </span>
<span class=" color-label"> DARK MODE </span>
</li>
</ul>
</div>
</div>

View File

@@ -0,0 +1,24 @@
import { async, ComponentFixture, TestBed } from "@angular/core/testing";
import { AdminLayoutComponent } from "./admin-layout.component";
describe("AdminLayoutComponent", () => {
let component: AdminLayoutComponent;
let fixture: ComponentFixture<AdminLayoutComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AdminLayoutComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AdminLayoutComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it("should create", () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,35 @@
import { Component, OnInit } from "@angular/core";
@Component({
selector: "app-admin-layout",
templateUrl: "./admin-layout.component.html",
styleUrls: ["./admin-layout.component.scss"]
})
export class AdminLayoutComponent implements OnInit {
public sidebarColor: string = "red";
constructor() {}
changeSidebarColor(color){
var sidebar = document.getElementsByClassName('sidebar')[0];
var mainPanel = document.getElementsByClassName('main-panel')[0];
this.sidebarColor = color;
if(sidebar != undefined){
sidebar.setAttribute('data',color);
}
if(mainPanel != undefined){
mainPanel.setAttribute('data',color);
}
}
changeDashboardColor(color){
var body = document.getElementsByTagName('body')[0];
if (body && color === 'white-content') {
body.classList.add(color);
}
else if(body.classList.contains('white-content')) {
body.classList.remove('white-content');
}
}
ngOnInit() {}
}

View File

@@ -0,0 +1,35 @@
import { NgModule } from "@angular/core";
import { HttpClientModule } from "@angular/common/http";
import { RouterModule } from "@angular/router";
import { CommonModule } from "@angular/common";
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { AdminLayoutRoutes } from "./admin-layout.routing";
// import { DashboardComponent } from "../../pages/dashboard/dashboard.component";
import { CompanyInformationComponent } from "../../pages/company-information/company-information.component";
import { CompanyProfileComponent } from "../../pages/company-profile/company-profile.component";
import { InvoicesComponent } from "../../pages/invoices/invoices.component";
import { PaymentsComponent } from "../../pages/payments/payments.component";
import { NotificationsComponent } from "../../pages/notifications/notifications.component";
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(AdminLayoutRoutes),
FormsModule,
ReactiveFormsModule,
HttpClientModule,
NgbModule,
],
declarations: [
// DashboardComponent,
CompanyInformationComponent,
CompanyProfileComponent,
InvoicesComponent,
PaymentsComponent,
NotificationsComponent,
],
})
export class AdminLayoutModule {}

View File

@@ -0,0 +1,20 @@
import { Routes } from "@angular/router";
import { DashboardComponent } from "../../pages/dashboard/dashboard.component";
import { CompanyInformationComponent } from "../../pages/company-information/company-information.component";
import { CompanyProfileComponent } from "../../pages/company-profile/company-profile.component";
import { InvoicesComponent } from "../../pages/invoices/invoices.component";
import { PaymentsComponent } from "../../pages/payments/payments.component";
import { LoginComponent } from "src/app/pages/login/login.component";
import { NotificationsComponent } from "../../pages/notifications/notifications.component";
export const AdminLayoutRoutes: Routes = [
{ path: "dashboard", component: DashboardComponent },
{ path: "company-information", component: CompanyInformationComponent },
{ path: "company-profile", component: CompanyProfileComponent },
{ path: "invoices", component: InvoicesComponent },
{ path: "payments", component: PaymentsComponent },
{ path: "notifications", component: NotificationsComponent },
{ path: "login", component: LoginComponent}
];

View File

@@ -0,0 +1,307 @@
<div class="wrapper">
<div class="sidebar">
<div class="logo">
<a
href="https://www.creative-tim.com?ref=bda-auth-layout-sidebar-logo"
class="simple-text logo-mini"
>
<div class="logo-img">
<img src="./assets/img/angular2-logo-white.png" />
</div>
</a>
<a
href="https://www.creative-tim.com?ref=bda-auth-layout-sidebar-logo"
class="simple-text logo-normal"
>
الإبداعية تيم
</a>
</div>
<div class="sidebar-wrapper">
<ul class="nav">
<li
routerLinkActive="active"
*ngFor="let menuItem of menuItems"
class="{{ menuItem.class }} nav-item"
>
<a [routerLink]="[menuItem.path]">
<i class="tim-icons {{ menuItem.icon }}"></i>
<p>{{ menuItem.rtlTitle }}</p>
</a>
</li>
</ul>
</div>
</div>
<div class="main-panel">
<nav class="navbar navbar-expand-lg navbar-absolute navbar-transparent">
<div class="container-fluid">
<div class="navbar-wrapper">
<div class="navbar-toggle d-inline">
<button
class="navbar-toggler"
type="button"
(click)="sidebarToggle()"
>
<span class="navbar-toggler-bar bar1"> </span>
<span class="navbar-toggler-bar bar2"> </span>
<span class="navbar-toggler-bar bar3"> </span>
</button>
</div>
<a class="navbar-brand" href="javascript:void(0)"> ار تي ال </a>
</div>
<button
aria-label="Toggle navigation"
class="navbar-toggler"
(click)="collapse()"
[attr.aria-expanded]="!isCollapsed"
aria-controls="collapseExample"
id="navigation"
type="button"
>
<span class="navbar-toggler-bar navbar-kebab"> </span>
<span class="navbar-toggler-bar navbar-kebab"> </span>
<span class="navbar-toggler-bar navbar-kebab"> </span>
</button>
<div
class="navbar-collapse"
[ngbCollapse]="isCollapsed"
id="navigation"
>
<ul class="navbar-nav mr-auto">
<li class="search-bar input-group">
<button
class="btn btn-link"
data-target="#searchModal"
data-toggle="modal"
(click)="open(content)"
id="search-button"
>
<i class="tim-icons icon-zoom-split"> </i>
<span class="d-lg-none d-md-block"> بحث </span>
</button>
</li>
<li class="nav-item" ngbDropdown>
<a class="nav-link" data-toggle="dropdown" ngbDropdownToggle>
<div class="notification d-none d-lg-block d-xl-block"></div>
<i class="tim-icons icon-sound-wave"> </i>
<p class="d-lg-none">إخطارات</p>
</a>
<ul class="dropdown-menu-right dropdown-navbar" ngbDropdownMenu>
<li class="nav-link">
<a class="nav-item" href="javascript:void(0)" ngbDropdownItem>
ورد مايك جون على بريدك الإلكتروني
</a>
</li>
<li class="nav-link">
<a class="nav-item" href="javascript:void(0)" ngbDropdownItem>
لديك 5 مهام أخرى
</a>
</li>
<li class="nav-link">
<a class="nav-item" href="javascript:void(0)" ngbDropdownItem>
صديقك مايكل في المدينة
</a>
</li>
<li class="nav-link">
<a class="nav-item" href="javascript:void(0)" ngbDropdownItem>
إشعار آخر
</a>
</li>
<li class="nav-link">
<a class="nav-item" href="javascript:void(0)" ngbDropdownItem>
واحدة أخرى
</a>
</li>
</ul>
</li>
<li class="nav-item" ngbDropdown>
<a class="nav-link" data-toggle="dropdown" ngbDropdownToggle>
<div class="photo">
<img alt="Profile Photo" src="assets/img/anime3.png" />
</div>
<b class="caret d-none d-lg-block d-xl-block"> </b>
<p class="d-lg-none">الخروج</p>
</a>
<ul class="dropdown-navbar" ngbDropdownMenu>
<li class="nav-link">
<a class="nav-item" href="javascript:void(0)" ngbDropdownItem>
الملف الشخصي
</a>
</li>
<li class="nav-link">
<a class="nav-item" href="javascript:void(0)" ngbDropdownItem>
الإعدادات
</a>
</li>
<li class="dropdown-divider"></li>
<li class="nav-link">
<a class="nav-item" href="javascript:void(0)" ngbDropdownItem>
الخروج
</a>
</li>
</ul>
</li>
<li class="separator d-lg-none"></li>
</ul>
</div>
</div>
</nav>
<router-outlet></router-outlet>
<footer class="footer">
<div class="container-fluid">
<ul class="nav">
<li class="nav-item">
<a
class="nav-link"
href="https://www.creative-tim.com?ref=bda-auth-layout-footer"
>
تيم الإبداعية
</a>
</li>
<li class="nav-item">
<a
class="nav-link"
href="https://www.creative-tim.com/about-us?ref=bda-auth-layout-footer"
>
معلومات عنا
</a>
</li>
<li class="nav-item">
<a
class="nav-link"
href="http://blog.creative-tim.com?ref=bda-auth-layout-footer"
>
مدونة
</a>
</li>
</ul>
<div class="copyright">
&copy; {{ test | date : "yyyy" }} مصنوع من
<i class="tim-icons icon-heart-2"> </i> بواسطة
<a
href="https://www.creative-tim.com?ref=bda-auth-layout-footer"
target="_blank"
>
تيم الإبداعية
</a>
من أجل شبكة أفضل.
</div>
</div>
</footer>
</div>
</div>
<div class="fixed-plugin">
<div class="show-dropdown" ngbDropdown>
<a data-toggle="dropdown" ngbDropdownToggle>
<i class="fa fa-cog fa-2x"> </i>
</a>
<ul ngbDropdownMenu>
<li class="header-title">خلفية الشريط الجانبي</li>
<li class="adjustments-line">
<a class="switch-trigger background-color" href="javascript:void(0)">
<div class="badge-colors text-center">
<span
class="badge filter badge-danger"
[ngClass]="{ active: sidebarColor === 'red' }"
(click)="changeSidebarColor('red')"
>
</span>
<span
class="badge filter badge-primary"
data-color="primary"
[ngClass]="{ active: sidebarColor === 'primary' }"
(click)="changeSidebarColor('primary')"
>
</span>
<span
class="badge filter badge-info"
[ngClass]="{ active: sidebarColor === 'blue' }"
(click)="changeSidebarColor('blue')"
>
</span>
<span
class="badge filter badge-success"
[ngClass]="{ active: sidebarColor === 'green' }"
(click)="changeSidebarColor('green')"
>
</span>
</div>
<div class="clearfix"></div>
</a>
</li>
<li class="adjustments-line text-center color-change">
<span class="color-label"> وضع الضوء </span>
<span
class="badge light-badge mr-2"
(click)="changeDashboardColor('white-content')"
>
</span>
<span
class="badge dark-badge ml-2"
(click)="changeDashboardColor('black-content')"
>
</span>
<span class="color-label"> وضع الظلام</span>
</li>
<li class="button-container">
<a
class="btn btn-primary btn-block btn-round"
href="https://www.creative-tim.com/product/black-dashboard-angular?ref=bda-auth-layout-fixed-plugin"
target="_blank"
>
التحميل الان
</a>
<a
class="btn btn-default btn-block btn-round"
href="https://demos.creative-tim.com/black-dashboard-angular/#/documentation/tutorial?ref=bda-auth-layout-fixed-plugin"
target="_blank"
>
كابل بيانات
</a>
</li>
<li class="header-title">شكرا لك على 95 سهم!</li>
<li class="button-container text-center">
<button class="btn btn-round btn-info" id="twitter">
<i class="fab fa-twitter"> </i> · 45
</button>
<button class="btn btn-round btn-info" id="facebook">
<i class="fab fa-facebook-f"> </i> · 50
</button>
<br />
<br />
<a
aria-label="Star ntkme/github-buttons on GitHub"
class="github-button"
data-icon="octicon-star"
data-show-count="true"
data-size="large"
href="https://github.com/creativetimofficial/black-dashboard-angular?ref=bda-auth-layout-fixed-plugin"
>
نجمة
</a>
</li>
</ul>
</div>
</div>
<ng-template #content let-modal>
<div class="modal-header">
<input
class="form-control"
id="inlineFormInputGroup"
placeholder="بحث"
type="text"
/>
<button
aria-label="Close"
class="close"
data-dismiss="modal"
type="button"
(click)="modal.dismiss('Cross click')"
>
<i class="tim-icons icon-simple-remove"> </i>
</button>
</div>
</ng-template>

View File

@@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AuthLayoutComponent } from './auth-layout.component';
describe('AuthLayoutComponent', () => {
let component: AuthLayoutComponent;
let fixture: ComponentFixture<AuthLayoutComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AuthLayoutComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AuthLayoutComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,212 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { ROUTES } from '../../components/sidebar/sidebar.component';
import { NgbModal, ModalDismissReasons } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'app-auth-layout',
templateUrl: './auth-layout.component.html',
styleUrls: ['./auth-layout.component.scss']
})
export class AuthLayoutComponent implements OnInit, OnDestroy {
public menuItems: any[];
test: Date = new Date();
closeResult: string;
public sidebarColor: string = "red";
public isCollapsed = true;
mobile_menu_visible: any = 0;
private toggleButton: any;
private sidebarVisible: boolean;
constructor(private router: Router, private modalService: NgbModal) { }
changeSidebarColor(color){
var sidebar = document.getElementsByClassName('sidebar')[0];
var mainPanel = document.getElementsByClassName('main-panel')[0];
this.sidebarColor = color;
if(sidebar != undefined){
sidebar.setAttribute('data',color);
}
if(mainPanel != undefined){
mainPanel.setAttribute('data',color);
}
}
changeDashboardColor(color){
var body = document.getElementsByTagName('body')[0];
if (body && color === 'white-content') {
body.classList.add(color);
}
else if(body.classList.contains('white-content')) {
body.classList.remove('white-content');
}
}
// function that adds color white/transparent to the navbar on resize (this is for the collapse)
updateColor = () => {
var navbar = document.getElementsByClassName('navbar')[0];
if (window.innerWidth < 993 && !this.isCollapsed) {
navbar.classList.add('bg-white');
navbar.classList.remove('navbar-transparent');
} else {
navbar.classList.remove('bg-white');
navbar.classList.add('navbar-transparent');
}
};
ngOnInit() {
var navbar = document.getElementsByClassName('navbar')[0];
window.addEventListener("resize", this.updateColor);
this.toggleButton = navbar.getElementsByClassName("navbar-toggler")[0];
this.router.events.subscribe(event => {
this.sidebarClose();
var $layer: any = document.getElementsByClassName("close-layer")[0];
if ($layer) {
$layer.remove();
this.mobile_menu_visible = 0;
}
});
this.menuItems = ROUTES.filter(menuItem => menuItem);
// on this page, we need on the body tag the classes .rtl and .menu-on-right
document.body.classList.add("rtl", "menu-on-right");
// we also need the rtl bootstrap
// so we add it dynamically to the head
let head = document.head;
let link = document.createElement("link");
link.type = "text/css";
link.rel = "stylesheet";
link.id = "rtl-id";
link.href =
"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-rtl/3.4.0/css/bootstrap-rtl.css";
head.appendChild(link);
}
ngOnDestroy() {
// when we exit this page, we need to delete the classes .rtl and .menu-on-right
// from the body tag
document.body.classList.remove("rtl", "menu-on-right");
// we also need to delete the rtl bootstrap, so it does not break the other pages
// that do not make use of rtl
document.getElementById("rtl-id").remove();
}
collapse() {
this.isCollapsed = !this.isCollapsed;
const navbar = document.getElementsByTagName("nav")[0];
if (!this.isCollapsed) {
navbar.classList.remove("navbar-transparent");
navbar.classList.add("bg-white");
} else {
navbar.classList.add("navbar-transparent");
navbar.classList.remove("bg-white");
}
}
sidebarOpen() {
const toggleButton = this.toggleButton;
const mainPanel = <HTMLElement>(
document.getElementsByClassName("main-panel")[0]
);
const html = document.getElementsByTagName("html")[0];
if (window.innerWidth < 991) {
mainPanel.style.position = "fixed";
}
setTimeout(function() {
toggleButton.classList.add("toggled");
}, 500);
html.classList.add("nav-open");
this.sidebarVisible = true;
}
sidebarClose() {
const html = document.getElementsByTagName("html")[0];
this.toggleButton.classList.remove("toggled");
const mainPanel = <HTMLElement>(
document.getElementsByClassName("main-panel")[0]
);
if (window.innerWidth < 991) {
setTimeout(function() {
mainPanel.style.position = "";
}, 500);
}
this.sidebarVisible = false;
html.classList.remove("nav-open");
}
sidebarToggle() {
// const toggleButton = this.toggleButton;
// const html = document.getElementsByTagName('html')[0];
var $toggle = document.getElementsByClassName("navbar-toggler")[0];
if (this.sidebarVisible === false) {
this.sidebarOpen();
} else {
this.sidebarClose();
}
const html = document.getElementsByTagName("html")[0];
if (this.mobile_menu_visible == 1) {
// $('html').removeClass('nav-open');
html.classList.remove("nav-open");
if ($layer) {
$layer.remove();
}
setTimeout(function() {
$toggle.classList.remove("toggled");
}, 400);
this.mobile_menu_visible = 0;
} else {
setTimeout(function() {
$toggle.classList.add("toggled");
}, 430);
var $layer = document.createElement("div");
$layer.setAttribute("class", "close-layer");
if (html.querySelectorAll(".main-panel")) {
document.getElementsByClassName("main-panel")[0].appendChild($layer);
} else if (html.classList.contains("off-canvas-sidebar")) {
document
.getElementsByClassName("wrapper-full-page")[0]
.appendChild($layer);
}
setTimeout(function() {
$layer.classList.add("visible");
}, 100);
$layer.onclick = function() {
//asign a function
html.classList.remove("nav-open");
this.mobile_menu_visible = 0;
$layer.classList.remove("visible");
setTimeout(function() {
$layer.remove();
$toggle.classList.remove("toggled");
}, 400);
}.bind(this);
html.classList.add("nav-open");
this.mobile_menu_visible = 1;
}
}
open(content) {
this.modalService.open(content, {windowClass: 'modal-search'}).result.then((result) => {
this.closeResult = `Closed with: ${result}`;
}, (reason) => {
this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
});
}
private getDismissReason(reason: any): string {
if (reason === ModalDismissReasons.ESC) {
return 'by pressing ESC';
} else if (reason === ModalDismissReasons.BACKDROP_CLICK) {
return 'by clicking on a backdrop';
} else {
return `with: ${reason}`;
}
}
}

View File

@@ -0,0 +1,21 @@
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { AuthLayoutRoutes } from './auth-layout.routing';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { HttpClientModule } from "@angular/common/http";
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(AuthLayoutRoutes),
FormsModule,
HttpClientModule,
NgbModule
],
declarations: [
]
})
export class AuthLayoutModule { }

View File

@@ -0,0 +1,5 @@
import { Routes } from "@angular/router";
export const AuthLayoutRoutes: Routes = [
// { path: 'rtl', component: RtlComponent },
];

26
src/app/models/company.ts Normal file
View File

@@ -0,0 +1,26 @@
export interface CompanyModel {
id: number;
name: string;
username: string;
email: string;
phone: string;
image: string;
description: string;
address: string;
city: string;
stagingUrl: string;
productionUrl: string;
}
// export interface CompanyProfileModel {
// id: number;
// username: string;
// name: string;
// email: string;
// phone: string;
// description: string;
// address: string;
// city: string;
// stagingUrl: string;
// productionUrl: string;
// }

View File

@@ -0,0 +1,12 @@
export interface DatabaseInfoModel {
id: number;
companyId: number;
serverId: number;
databaseName: string;
databaseType: 'MySQL' | 'PostgreSQL' | 'MongoDB' | 'SQLite';
bandwidthGB: number;
username: string;
password: string;
host: string;
port: number;
}

View File

@@ -0,0 +1,12 @@
export interface HostingInfoModel {
id: number;
companyId: number;
provider: string;
serverType: 'shared' | 'VPS' | 'dedicated';
diskSpaceGB: number;
bandwidthGB: number;
username: string;
password: string;
serverLocation: string;
expirationDate: Date;
}

18
src/app/models/invoice.ts Normal file
View File

@@ -0,0 +1,18 @@
export interface InvoiceModel {
id: number; // unique ID for the invoice
invoiceNumber: string; // invoice number
companyId: number; // ID of the company to which this invoice belongs
dateIssued: Date; // date the invoice was issued
dueDate: Date; // date the invoice is due
amount: string; // total amount due
currency: string; // currency in which the invoice is billed
status: 'pending' | 'paid' | 'overdue'; // current status of the invoice
services: InvoiceService[]; // an array of individual items on the invoice
}
export interface InvoiceService {
description: string; // description of the service
service: number; // number of service rendered
unitPrice: number; // price of each unit service
total: number; // total cost of the services
}

View File

@@ -0,0 +1,9 @@
export interface NotificationModel {
header: string;
source: string;
time: string;
message: string;
user_id?: number;
date: Date;
timestamp: string;
}

12
src/app/models/payment.ts Normal file
View File

@@ -0,0 +1,12 @@
export interface PaymentModel {
id: number; // unique ID for the payment
invoiceId: number; // ID of the invoice to which this payment applies
companyId: number; // ID of the company to which this payment belongs
invoiceNumber: string; // invoice number
paymentNumber: string; // unique payment number
paymentDate: Date; // date the payment was made
amount: string; // amount of the payment
currency: string; // currency in which the payment was made
method: "credit card" | "bank transfer" | "cash" | "cheque"; // payment method used
status: "completed" | "pending" | "failed"; // status of the payment
}

View File

@@ -0,0 +1,14 @@
export interface ServerInfoModel {
id: number;
companyId: number;
databaseId: number;
provider: string;
serverType: 'shared' | 'VPS' | 'dedicated';
operatingSystem: string;
cpu: string;
storageGB: number;
ramGB: number;
bandwidthGB: number;
monthlyCostUSD: number;
location: string;
}

View File

@@ -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>

View File

@@ -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;
}
}
}

View File

@@ -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();
});
});

View File

@@ -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";
}
}
}

View 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>

View 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;
}
}
}
}
}

View File

@@ -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();
});
});

View 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;
}
}
}

View 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> -->

View 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();
}
}

View 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>

View 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();
});
});

View 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";
}
}
}

View 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>

View 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;
}
}
}

View 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();
});
});

View 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);
// });
}
}

View 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>

View 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() {}
}

View 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>

View 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();
});
});

View 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";
}
}
}

View 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>

View 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() {}
}

View File

@@ -0,0 +1,27 @@
import { Injectable } from "@angular/core";
import { Observable, map } from "rxjs";
import { CompanyModel } from "../models/company";
import { company } from "../data/company";
@Injectable({
providedIn: "root",
})
export class CompanyService {
constructor() {}
companyData = new Observable<CompanyModel[]>((subscriber) => {
subscriber.next(company);
});
// Get all companies
getAllCompanies(): Observable<CompanyModel[]> {
return this.companyData;
}
// Get a company based on id
getCompanyById(id: number): Observable<CompanyModel> {
return this.companyData.pipe(
map((companies) => companies.find((company) => company.id === id))
);
}
}

View File

@@ -0,0 +1,29 @@
import { Injectable } from "@angular/core";
import { Observable, map } from "rxjs";
import { DatabaseInfoModel } from "../models/database-info";
import { databaseInfo } from "../data/database-info";
@Injectable({
providedIn: "root",
})
export class DatabaseInfoService {
constructor() {}
databaseInfoData = new Observable<DatabaseInfoModel[]>((subscriber) => {
subscriber.next(databaseInfo);
});
// Get all database info
getAllDatabaseInfo(): Observable<DatabaseInfoModel[]> {
return this.databaseInfoData;
}
// Get a database info based on id
getDatabaseInfoById(id: number): Observable<DatabaseInfoModel> {
return this.databaseInfoData.pipe(
map((databaseInfo) =>
databaseInfo.find((databaseInfo) => databaseInfo.id === id)
)
);
}
}

View File

@@ -0,0 +1,29 @@
import { Injectable } from "@angular/core";
import { Observable, map } from "rxjs";
import { HostingInfoModel } from "../models/hosting-info";
import { hostingInfo } from "../data/hosting-info";
@Injectable({
providedIn: "root",
})
export class HostingInfoService {
constructor() {}
hostingInfoData = new Observable<HostingInfoModel[]>((subscriber) => {
subscriber.next(hostingInfo);
});
// Get all hosting info
getAllHostingInfo(): Observable<HostingInfoModel[]> {
return this.hostingInfoData;
}
// Get a hosting info based on id
getHostingInfoById(id: number): Observable<HostingInfoModel> {
return this.hostingInfoData.pipe(
map((hostingInfo) =>
hostingInfo.find((hostingInfo) => hostingInfo.id === id)
)
);
}
}

View File

@@ -0,0 +1,27 @@
import { Injectable } from "@angular/core";
import { Observable, map } from "rxjs";
import { InvoiceModel } from "../models/invoice";
import { invoice } from "../data/invoice";
@Injectable({
providedIn: "root",
})
export class InvoiceService {
invoiceData = new Observable<InvoiceModel[]>((subscriber) => {
subscriber.next(invoice);
});
// Get all invoices
getAllInvoices(): Observable<InvoiceModel[]> {
return this.invoiceData;
}
// Get an invoice based on id
getInvoiceById(companyId: number): Observable<InvoiceModel[]> {
return this.invoiceData.pipe(
map((invoice) =>
invoice.filter((invoice) => invoice.companyId === companyId)
)
);
}
}

View File

@@ -0,0 +1,27 @@
import { Injectable } from "@angular/core";
import { Observable, map } from "rxjs";
import { PaymentModel } from "../models/payment";
import { payment } from "../data/payment";
@Injectable({
providedIn: "root",
})
export class PaymentService {
constructor() {}
paymentData = new Observable<PaymentModel[]>((subscriber) => {
subscriber.next(payment);
});
// Get all payments
getAllPayments(): Observable<PaymentModel[]> {
return this.paymentData;
}
// Get a payment based on id
getPaymentById(companyId: number): Observable<PaymentModel[]> {
return this.paymentData.pipe(
map((payment) => payment.filter((payment) => payment.companyId === companyId))
);
}
}

View File

@@ -0,0 +1,29 @@
import { Injectable } from "@angular/core";
import { Observable, map } from "rxjs";
import { ServerInfoModel } from "../models/server-info";
import { serverInfo } from "../data/server-info";
@Injectable({
providedIn: "root",
})
export class ServerInfoService {
constructor() {}
serverInfoData = new Observable<ServerInfoModel[]>((subscriber) => {
subscriber.next(serverInfo);
});
// Get all server info
getAllServerInfo(): Observable<ServerInfoModel[]> {
return this.serverInfoData;
}
// Get a server info based on id
getServerInfoById(id: number): Observable<ServerInfoModel> {
return this.serverInfoData.pipe(
map((serverInfo) =>
serverInfo.find((serverInfo) => serverInfo.id === id)
)
);
}
}

View File

@@ -0,0 +1,548 @@
/* --------------------------------
Nucleo Outline Web Font - nucleoapp.com/
License - nucleoapp.com/license/
Created using IcoMoon - icomoon.io
-------------------------------- */
@font-face {
font-family: "Nucleo";
src: url("../fonts/nucleo.eot");
src: url("../fonts/nucleo.eot") format("embedded-opentype"),
url("../fonts/nucleo.woff2") format("woff2"),
url("../fonts/nucleo.woff") format("woff"),
url("../fonts/nucleo.ttf") format("truetype");
font-weight: normal;
font-style: normal;
}
/*------------------------
base class definition
-------------------------*/
.tim-icons {
display: inline-block;
font: normal normal normal 1em/1 "Nucleo";
vertical-align: middle;
speak: none;
text-transform: none;
/* Better Font Rendering */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.font-icon-detail {
text-align: center;
padding: 45px 0 30px;
/* border: 1px solid #e44cc4; */
border-radius: 0.1875rem;
margin: 15px 0;
min-height: 168px;
box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px,
rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
}
.font-icon-detail i {
color: #ffffff;
font-size: 1.8em;
}
.font-icon-detail p {
color: #e44cc4 !important;
padding: 0 10px;
font-size: 0.9rem;
margin-top: 15px;
}
/*------------------------
change icon size
-------------------------*/
.tim-icons-sm {
font-size: 0.8em;
}
.tim-icons-lg {
font-size: 1.2em;
}
/* absolute units */
.tim-icons-16 {
font-size: 16px;
}
.tim-icons-32 {
font-size: 32px;
}
/*----------------------------------
add a square/circle background
-----------------------------------*/
.tim-icons-bg-square,
.tim-icons-bg-circle {
padding: 0.35em;
}
.tim-icons-bg-circle {
border-radius: 50%;
}
/*------------------------
list icons
-------------------------*/
/*------------------------
spinning icons
-------------------------*/
.tim-icons-is-spinning {
-webkit-animation: tim-icons-spin 2s infinite linear;
-moz-animation: tim-icons-spin 2s infinite linear;
animation: tim-icons-spin 2s infinite linear;
}
@-webkit-keyframes tim-icons-spin {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
@-moz-keyframes tim-icons-spin {
0% {
-moz-transform: rotate(0deg);
}
100% {
-moz-transform: rotate(360deg);
}
}
@keyframes tim-icons-spin {
0% {
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-ms-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
/*------------------------
rotated/flipped icons
-------------------------*/
/*------------------------
icons
-------------------------*/
.icon-alert-circle-exc::before {
content: "\ea02";
}
.icon-align-center::before {
content: "\ea03";
}
.icon-align-left-2::before {
content: "\ea04";
}
.icon-app::before {
content: "\ea05";
}
.icon-atom::before {
content: "\ea06";
}
.icon-attach-87::before {
content: "\ea07";
}
.icon-badge::before {
content: "\ea08";
}
.icon-bag-16::before {
content: "\ea09";
}
.icon-bank::before {
content: "\ea0a";
}
.icon-basket-simple::before {
content: "\ea0b";
}
.icon-bell-55::before {
content: "\ea0c";
}
.icon-bold::before {
content: "\ea0d";
}
.icon-book-bookmark::before {
content: "\ea0e";
}
.icon-bulb-63::before {
content: "\ea0f";
}
.icon-bullet-list-67::before {
content: "\ea10";
}
.icon-bus-front-12::before {
content: "\ea11";
}
.icon-button-pause::before {
content: "\ea12";
}
.icon-button-power::before {
content: "\ea13";
}
.icon-calendar-60::before {
content: "\ea14";
}
.icon-camera-18::before {
content: "\ea15";
}
.icon-caps-small::before {
content: "\ea16";
}
.icon-cart::before {
content: "\ea17";
}
.icon-chart-bar-32::before {
content: "\ea18";
}
.icon-chart-pie-36::before {
content: "\ea19";
}
.icon-chat-33::before {
content: "\ea1a";
}
.icon-check-2::before {
content: "\ea1b";
}
.icon-cloud-download-93::before {
content: "\ea1c";
}
.icon-cloud-upload-94::before {
content: "\ea1d";
}
.icon-coins::before {
content: "\ea1e";
}
.icon-compass-05::before {
content: "\ea1f";
}
.icon-controller::before {
content: "\ea20";
}
.icon-credit-card::before {
content: "\ea21";
}
.icon-delivery-fast::before {
content: "\ea22";
}
.icon-double-left::before {
content: "\ea23";
}
.icon-double-right::before {
content: "\ea24";
}
.icon-email-85::before {
content: "\ea25";
}
.icon-gift-2::before {
content: "\ea26";
}
.icon-globe-2::before {
content: "\ea27";
}
.icon-headphones::before {
content: "\ea28";
}
.icon-heart-2::before {
content: "\ea29";
}
.icon-html5::before {
content: "\ea2a";
}
.icon-image-02::before {
content: "\ea2b";
}
.icon-istanbul::before {
content: "\ea2c";
}
.icon-key-25::before {
content: "\ea2d";
}
.icon-laptop::before {
content: "\ea2e";
}
.icon-light-3::before {
content: "\ea2f";
}
.icon-link-72::before {
content: "\ea30";
}
.icon-lock-circle::before {
content: "\ea31";
}
.icon-map-big::before {
content: "\ea32";
}
.icon-minimal-down::before {
content: "\ea33";
}
.icon-minimal-left::before {
content: "\ea34";
}
.icon-minimal-right::before {
content: "\ea35";
}
.icon-minimal-up::before {
content: "\ea36";
}
.icon-mobile::before {
content: "\ea37";
}
.icon-molecule-40::before {
content: "\ea38";
}
.icon-money-coins::before {
content: "\ea39";
}
.icon-notes::before {
content: "\ea3a";
}
.icon-palette::before {
content: "\ea3b";
}
.icon-paper::before {
content: "\ea3c";
}
.icon-pencil::before {
content: "\ea3d";
}
.icon-pin::before {
content: "\ea3e";
}
.icon-planet::before {
content: "\ea3f";
}
.icon-puzzle-10::before {
content: "\ea40";
}
.icon-satisfied::before {
content: "\ea41";
}
.icon-scissors::before {
content: "\ea42";
}
.icon-send::before {
content: "\ea43";
}
.icon-settings-gear-63::before {
content: "\ea44";
}
.icon-settings::before {
content: "\ea45";
}
.icon-simple-add::before {
content: "\ea46";
}
.icon-simple-delete::before {
content: "\ea47";
}
.icon-simple-remove::before {
content: "\ea48";
}
.icon-single-02::before {
content: "\ea49";
}
.icon-single-copy-04::before {
content: "\ea4a";
}
.icon-sound-wave::before {
content: "\ea4b";
}
.icon-spaceship::before {
content: "\ea4c";
}
.icon-square-pin::before {
content: "\ea4d";
}
.icon-support-17::before {
content: "\ea4e";
}
.icon-tablet-2::before {
content: "\ea4f";
}
.icon-tag::before {
content: "\ea50";
}
.icon-tap-02::before {
content: "\ea51";
}
.icon-tie-bow::before {
content: "\ea52";
}
.icon-time-alarm::before {
content: "\ea53";
}
.icon-trash-simple::before {
content: "\ea54";
}
.icon-triangle-right-17::before {
content: "\ea55";
}
.icon-trophy::before {
content: "\ea56";
}
.icon-tv-2::before {
content: "\ea57";
}
.icon-upload::before {
content: "\ea58";
}
.icon-user-run::before {
content: "\ea59";
}
.icon-vector::before {
content: "\ea5a";
}
.icon-video-66::before {
content: "\ea5b";
}
.icon-volume-98::before {
content: "\ea5c";
}
.icon-wallet-43::before {
content: "\ea5d";
}
.icon-watch-time::before {
content: "\ea5e";
}
.icon-wifi::before {
content: "\ea5f";
}
.icon-world::before {
content: "\ea60";
}
.icon-zoom-split::before {
content: "\ea61";
}
.icon-refresh-01::before {
content: "\ea62";
}
.icon-refresh-02::before {
content: "\ea63";
}
.icon-shape-star::before {
content: "\ea64";
}
.icon-components::before {
content: "\ea65";
}

77
src/assets/demo/demo.css Normal file
View File

@@ -0,0 +1,77 @@
/*
=========================================================
* Black Dashboard Angular - v1.2.0
=========================================================
* Product Page: https://www.creative-tim.com/product/black-dashboard-angular
* Copyright 2020 Creative Tim (https://www.creative-tim.com)
* Licensed under MIT (https://github.com/creativetimofficial/argon-dashboard/blob/master/LICENSE.md)
=========================================================
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
.tim-row {
margin-bottom: 20px;
}
.tim-white-buttons {
background-color: #777777;
}
.typography-line {
padding-left: 25%;
margin-bottom: 35px;
position: relative;
display: block;
width: 100%;
}
.typography-line span {
bottom: 10px;
color: #c0c1c2;
display: block;
font-weight: 400;
font-size: 13px;
line-height: 13px;
left: 0;
position: absolute;
width: 260px;
text-transform: none;
}
.tim-row {
padding-top: 60px;
}
.tim-row h3 {
margin-top: 0;
}
.offline-doc .page-header {
display: flex;
align-items: center;
}
.offline-doc .footer {
position: absolute;
width: 100%;
background: transparent;
bottom: 0;
color: #fff;
z-index: 1;
}
@media all and (min-width: 992px) {
.sidebar .nav>li.active-pro {
position: absolute;
width: 100%;
bottom: 10px;
}
}
.card.card-upgrade .card-category {
max-width: 530px;
margin: 0 auto;
}

BIN
src/assets/fonts/nucleo.eot Normal file

Binary file not shown.

BIN
src/assets/fonts/nucleo.ttf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/assets/img/angular.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
src/assets/img/anime3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
src/assets/img/anime6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
src/assets/img/bg5.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
src/assets/img/emilyz.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1 @@
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}

Some files were not shown because too many files have changed in this diff Show More