diff --git a/src/app/core/components/navigation/navigation.model.ts b/src/app/core/components/navigation/navigation.model.ts index 88b2dd87..d34ed629 100644 --- a/src/app/core/components/navigation/navigation.model.ts +++ b/src/app/core/components/navigation/navigation.model.ts @@ -139,12 +139,12 @@ export class FuseNavigation { 'title': 'Modern', 'type' : 'nav-item', - 'url' : '/pages/invoice/modern' + 'url' : '/pages/invoices/modern' }, { - 'title': 'Classic', + 'title': 'Compact', 'type' : 'nav-item', - 'url' : '/pages/invoice/classic' + 'url' : '/pages/invoices/compact' } ] }, diff --git a/src/app/fuse-fake-db/fuse-fake-db.service.ts b/src/app/fuse-fake-db/fuse-fake-db.service.ts index 60efff5d..f0aadecc 100644 --- a/src/app/fuse-fake-db/fuse-fake-db.service.ts +++ b/src/app/fuse-fake-db/fuse-fake-db.service.ts @@ -6,6 +6,7 @@ import { CalendarFakeDb } from './calendar'; import { TodoFakeDb } from './todo'; import { ProfileFakeDb } from './profile'; import { ContactsFakeDb } from './contacts'; +import { InvoiceFakeDb } from './invoice'; export class FuseFakeDbService implements InMemoryDbService { @@ -26,7 +27,8 @@ export class FuseFakeDbService implements InMemoryDbService 'profile-timeline' : ProfileFakeDb.timeline, 'profile-photos-videos': ProfileFakeDb.photosVideos, 'profile-about' : ProfileFakeDb.about, - 'contacts' : ContactsFakeDb.contacts + 'contacts' : ContactsFakeDb.contacts, + 'invoice' : InvoiceFakeDb.invoice }; } } diff --git a/src/app/fuse-fake-db/invoice.ts b/src/app/fuse-fake-db/invoice.ts new file mode 100644 index 00000000..761fd6f4 --- /dev/null +++ b/src/app/fuse-fake-db/invoice.ts @@ -0,0 +1,59 @@ +export class InvoiceFakeDb +{ + public static invoice = { + 'from' : { + 'title' : 'Fuse Inc.', + 'address': '2810 Country Club Road Cranford, NJ 07016', + 'phone' : '+66 123 455 87', + 'email' : 'hello@fuseinc.com', + 'website': 'www.fuseinc.com' + }, + 'client' : { + 'title' : 'John Doe', + 'address': '9301 Wood Street Philadelphia, PA 19111', + 'phone' : '+55 552 455 87', + 'email' : 'johndoe@mail.com' + }, + 'number' : 'P9-0004', + 'date' : 'Jul 19, 2015', + 'dueDate' : 'Aug 24, 2015', + 'services': [ + { + 'title' : 'Prototype & Design', + 'detail' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus accumsan, quam sed eleifend imperdiet.', + 'unit' : 'Hour', + 'unitPrice': '12.00', + 'quantity' : '240', + 'total' : '2880' + }, + { + 'title' : 'Coding', + 'detail' : 'Vestibulum ligula sem, rutrum et libero id, porta vehicula metus. Cras dapibus neque sit amet laoreet vestibulum.', + 'unit' : 'Hour', + 'unitPrice': '10.50', + 'quantity' : '350', + 'total' : '3675' + }, + { + 'title' : 'Testing', + 'detail' : 'Pellentesque luctus efficitur neque in finibus. Integer ut nunc in augue maximus porttitor id id nulla. In vitae erat.', + 'unit' : 'Hour', + 'unitPrice': '4.00', + 'quantity' : '50', + 'total' : '200' + }, + { + 'title' : 'Documentation & Training', + 'detail' : 'Pellentesque luctus efficitur neque in finibus. Integer ut nunc in augue maximus porttitor id id nulla. In vitae erat.', + 'unit' : 'Hour', + 'unitPrice': '6.50', + 'quantity' : '260', + 'total' : '1690' + } + ], + 'subtotal': '8445', + 'tax' : '675.60', + 'discount': '120.60', + 'total' : '9000' + }; +} diff --git a/src/app/main/pages/invoices/compact/compact.component.html b/src/app/main/pages/invoices/compact/compact.component.html new file mode 100644 index 00000000..c4279c8b --- /dev/null +++ b/src/app/main/pages/invoices/compact/compact.component.html @@ -0,0 +1,147 @@ +
+ +
+ + +
+ +
+
{{invoice.date}}
+ +
+
+
+ INVOICE + {{invoice.number}} +
+ +
+ DUE DATE + {{invoice.dueDate}} +
+ +
+
{{invoice.client.title}}
+
{{invoice.client.address}}
+
{{invoice.client.phone}}
+ +
{{invoice.client.website}}
+
+
+ +
+ + +
+
{{invoice.from.title}}
+
{{invoice.from.address}}
+
{{invoice.from.phone}}
+ +
{{invoice.from.website}}
+
+
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
SERVICEUNITUNIT PRICEQUANTITYTOTAL
+
+ {{service.title}} +
+
+ {{service.unit}} + + {{service.unitPrice | currency:'USD':true}} + + {{service.quantity}} + + {{service.total | currency:'USD':true}} +
+
+ {{service.title}} +
+
+ {{service.unit}} + + {{service.unitPrice | currency:'USD':true}} + + {{service.quantity}} + + {{service.total | currency:'USD':true}} +
+ + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + +
+ +
+
\ No newline at end of file diff --git a/src/app/main/pages/invoices/compact/compact.component.scss b/src/app/main/pages/invoices/compact/compact.component.scss new file mode 100644 index 00000000..e3743eb4 --- /dev/null +++ b/src/app/main/pages/invoices/compact/compact.component.scss @@ -0,0 +1,358 @@ +@import "src/app/core/scss/fuse"; + +:host { + + #invoice { + + &.compact { + padding: 0; + overflow: auto; + + .invoice-container { + padding: 64px; + + .card { + width: 1020px; + min-width: 1020px; + max-width: 1020px; + padding: 64px 88px; + overflow: hidden; + background: #FFFFFF; + @include mat-elevation(7); + + .header { + + .invoice-date { + font-size: 14px; + color: rgba(0, 0, 0, 0.54); + margin-bottom: 32px; + } + + .client { + + .invoice-number { + font-size: 18px; + padding-bottom: 2px; + + .title { + color: rgba(0, 0, 0, 0.54); + } + + .number { + padding-left: 6px; + } + } + + .due-date { + font-size: 18px; + padding-bottom: 16px; + + .title { + color: rgba(0, 0, 0, 0.54); + } + + .date { + padding-left: 6px; + } + } + + .info { + color: rgba(0, 0, 0, 0.54); + line-height: 22px; + } + } + + .issuer { + margin-right: -88px; + padding-right: 66px; + + .logo { + width: 96px; + height: 96px; + font-size: 72px; + border-right: 1px solid rgba(255, 255, 255, 0.7); + } + + .info { + padding: 16px; + } + } + } + + .content { + + .invoice-table { + margin-top: 64px; + font-size: 15px; + + thead { + + tr { + + th { + + &:first-child { + padding-left: 8px; + } + + &:last-child { + padding-right: 8px; + } + } + } + } + + tbody { + + tr { + + td { + + &:first-child { + padding-left: 8px; + } + + &:last-child { + padding-right: 8px; + } + } + } + } + + .title { + font-size: 16px; + } + + .detail { + margin-top: 8px; + font-size: 12px; + color: rgba(0, 0, 0, 0.54); + max-width: 360px; + } + } + + .invoice-table-footer { + margin: 32px 0 72px 0; + + tr { + + td { + text-align: right; + font-size: 16px; + font-weight: 500; + color: rgba(0, 0, 0, 0.54); + border-bottom: none; + padding: 4px 8px; + + &:first-child { + text-align: left; + } + } + + &.discount { + + td { + padding-bottom: 32px; + } + } + + &.total { + + td { + padding: 24px 8px; + border-top: 1px solid rgba(0, 0, 0, 0.12); + font-size: 35px; + font-weight: 300; + color: rgba(0, 0, 0, 1); + } + } + } + } + } + + .footer { + + .note { + font-size: 15px; + font-weight: 500; + margin-bottom: 24px; + } + + // IE10 fix + .logo, .small-note { + -ms-flex: 0 1 auto; + } + + .logo { + width: 32px; + min-width: 32px; + height: 32px; + font-size: 17px; + font-weight: 500; + margin-right: 24px; + border-radius: 2px; + overflow: hidden; + } + + .small-note { + font-size: 12px; + font-weight: 500; + color: rgba(0, 0, 0, 0.54); + line-height: 18px; + } + } + } + } + } + } + + /* PRINT STYLES */ + @media print { + + /* Invoice Specific Styles */ + #invoice { + + &.compact { + + .invoice-container { + padding: 0; + + .card { + width: 100%; + min-width: 0; + background: none; + padding: 0; + box-shadow: none; + + .header { + + .invoice-date { + margin-bottom: 16pt; + } + + .issuer { + padding-right: 0; + margin-right: 0; + } + } + + .content { + + .invoice-table { + margin-top: 16pt; + + thead { + + tr { + + th { + font-size: 10pt; + max-width: 60pt; + + &:first-child { + padding-left: 0; + } + + &:last-child { + padding-right: 0; + } + } + } + } + + tbody { + + tr { + + td { + + &:first-child { + padding-left: 0; + } + + &:last-child { + padding-right: 0; + } + } + } + } + + .title { + font-size: 10pt; + } + + .detail { + margin-top: 4pt; + font-size: 9pt; + max-width: none; + } + } + + .invoice-table-footer { + margin: 16pt 0; + + tr { + + td { + font-size: 13pt; + padding: 4pt 4pt; + + &:first-child { + text-align: left; + padding-left: 0; + } + + &:last-child { + padding-right: 0; + } + } + + &.discount { + + td { + padding-bottom: 16pt; + } + } + + &.total { + + td { + padding: 16pt 4pt 0 4pt; + font-size: 16pt; + + &:first-child { + padding-left: 0; + } + + &:last-child { + padding-right: 0; + } + } + } + } + } + } + + .footer { + + .note { + font-size: 10pt; + margin-bottom: 8pt; + } + + .logo { + font-size: 14pt; + margin-right: 8pt; + } + + .small-note { + font-size: 8pt; + line-height: normal; + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/app/main/pages/invoices/compact/compact.component.ts b/src/app/main/pages/invoices/compact/compact.component.ts new file mode 100644 index 00000000..fd1b04cc --- /dev/null +++ b/src/app/main/pages/invoices/compact/compact.component.ts @@ -0,0 +1,21 @@ +import { Component } from '@angular/core'; +import { InvoiceService } from '../invoice.service'; + +@Component({ + selector : 'fuse-invoice-compact', + templateUrl: './compact.component.html', + styleUrls : ['./compact.component.scss'] +}) +export class InvoiceCompactComponent +{ + invoice: any; + + constructor(private invoiceService: InvoiceService) + { + this.invoiceService.invoiceOnChanged + .subscribe((invoice) => { + this.invoice = invoice; + }); + } + +} diff --git a/src/app/main/pages/invoices/invoice.service.ts b/src/app/main/pages/invoices/invoice.service.ts new file mode 100644 index 00000000..b9576806 --- /dev/null +++ b/src/app/main/pages/invoices/invoice.service.ts @@ -0,0 +1,53 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router'; +import { Observable } from 'rxjs/Observable'; +import { Http } from '@angular/http'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; + +@Injectable() +export class InvoiceService implements Resolve +{ + invoice: any; + + invoiceOnChanged: BehaviorSubject = new BehaviorSubject({}); + + constructor(private http: Http) + { + } + + /** + * Resolve + * @param {ActivatedRouteSnapshot} route + * @param {RouterStateSnapshot} state + * @returns {Observable | Promise | any} + */ + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | any + { + return new Promise((resolve, reject) => { + Promise.all([ + this.getInvoice() + ]).then( + () => { + resolve(); + }, + reject + ); + }); + } + + /** + * Get invoice + */ + getInvoice(): Promise + { + return new Promise((resolve, reject) => { + + this.http.get('api/invoice') + .subscribe(timeline => { + this.invoice = timeline.json().data; + this.invoiceOnChanged.next(this.invoice); + resolve(this.invoice); + }, reject); + }); + } +} diff --git a/src/app/main/pages/invoices/modern/modern.component.html b/src/app/main/pages/invoices/modern/modern.component.html new file mode 100644 index 00000000..1ed1c845 --- /dev/null +++ b/src/app/main/pages/invoices/modern/modern.component.html @@ -0,0 +1,169 @@ +
+ +
+ + +
+ +
+ +
+ +
+ + +
+ +
+
{{invoice.from.title}}
+
+ {{invoice.from.address}} +
+
+ Phone: + {{invoice.from.phone}} +
+ +
+ Web: + {{invoice.from.website}} +
+
+
+ +
+
+
CLIENT
+
+ +
+ +
+
{{invoice.client.title}}
+
+ {{invoice.client.address}} +
+
+ Phone: + {{invoice.client.phone}} +
+ +
+ Web: + {{invoice.client.website}} +
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
INVOICE{{invoice.number}}
INVOICE DATE{{invoice.date}}
DUE DATE{{invoice.dueDate}}
TOTAL DUE{{invoice.total | currency:'USD':true}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
SERVICEUNITUNIT PRICEQUANTITYTOTAL
+
{{service.title}}
+
{{service.detail}}
+
+ {{service.unit}} + + {{service.unitPrice | currency:'USD':true}} + + {{service.quantity}} + + {{service.total | currency:'USD':true}} +
+ + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + + +
+ +
+ +
\ No newline at end of file diff --git a/src/app/main/pages/invoices/modern/modern.component.scss b/src/app/main/pages/invoices/modern/modern.component.scss new file mode 100644 index 00000000..2d8c84b6 --- /dev/null +++ b/src/app/main/pages/invoices/modern/modern.component.scss @@ -0,0 +1,359 @@ +@import "src/app/core/scss/fuse"; + +:host { + + #invoice { + + &.modern { + padding: 0; + overflow: auto; + + .invoice-container { + padding: 64px; + + .card { + width: 1020px; + min-width: 1020px; + max-width: 1020px; + padding: 88px; + overflow: hidden; + background: #FFFFFF; + @include mat-elevation(7); + + .header { + + .ids { + line-height: 22px; + color: rgba(0, 0, 0, 0.54); + + .detail { + width: 160px; + } + + .seller { + margin-bottom: 80px; + + .logo { + width: 156px; + height: 156px; + font-size: 115px; + } + } + + .client { + + .label { + width: 156px; + font-size: 24px; + font-weight: 300; + } + } + + .divider { + width: 1px; + margin: 0 48px; + background-color: rgba(0, 0, 0, 0.12); + height: 144px; + } + } + + .summary { + font-size: 15px; + + .label { + color: rgba(0, 0, 0, 0.54); + text-align: right; + padding-right: 16px; + } + + .value { + color: rgba(0, 0, 0, 1); + } + + .code { + font-size: 35px; + font-weight: 300; + + td { + padding-bottom: 32px; + } + } + } + } + + .content { + + .invoice-table { + margin-top: 96px; + font-size: 15px; + + .title { + font-size: 17px; + } + + .detail { + margin-top: 8px; + font-size: 12px; + color: rgba(0, 0, 0, 0.54); + max-width: 360px; + } + } + + .invoice-table-footer { + margin: 32px 0 96px 0; + + tr { + + td { + text-align: right; + font-size: 17px; + font-weight: 500; + color: rgba(0, 0, 0, 0.54); + border-bottom: none; + padding: 8px 8px; + + &:first-child { + text-align: left; + } + } + + &.discount { + + td { + padding-bottom: 32px; + } + } + + &.total { + + td { + padding: 32px 8px; + border-top: 1px solid rgba(0, 0, 0, 0.12); + font-size: 35px; + font-weight: 300; + color: rgba(0, 0, 0, 1); + } + } + } + } + } + + .footer { + + .note { + font-size: 15px; + font-weight: 500; + margin-bottom: 24px; + } + + // IE10 fix + .logo, .small-note { + -ms-flex: 0 1 auto; + } + + .logo { + width: 32px; + min-width: 32px; + height: 32px; + font-size: 17px; + font-weight: 500; + margin-right: 24px; + border-radius: 2px; + overflow: hidden; + } + + .small-note { + font-size: 12px; + font-weight: 500; + color: rgba(0, 0, 0, 0.54); + line-height: 18px; + } + } + } + } + } + } + + /* PRINT STYLES */ + @media print { + + /* Invoice Specific Styles */ + #invoice { + + &.modern { + + .invoice-container { + padding: 0; + + .card { + width: 100%; + min-width: 0; + background: none; + padding: 0; + box-shadow: none; + + .header { + + .ids { + + .detail { + width: 120pt; + } + + .seller { + margin-bottom: 8pt; + + .logo { + width: 60pt; + height: 60pt; + font-size: 40pt; + } + } + + .client { + + .label { + width: 60pt; + font-size: 16pt; + } + } + + .divider { + margin: 0 12pt; + height: 100pt; + } + } + + .summary { + font-size: 10pt; + + .code { + font-size: 18pt; + + td { + padding-bottom: 10pt; + } + } + } + } + + .content { + + .invoice-table { + margin-top: 16pt; + + thead { + + tr { + + th { + font-size: 10pt; + max-width: 60pt; + + &:first-child { + padding-left: 0; + } + + &:last-child { + padding-right: 0; + } + } + } + } + + tbody { + + tr { + + td { + + &:first-child { + padding-left: 0; + } + + &:last-child { + padding-right: 0; + } + } + } + } + + .title { + font-size: 10pt; + } + + .detail { + margin-top: 4pt; + font-size: 9pt; + max-width: none; + } + } + + .invoice-table-footer { + margin: 16pt 0; + + tr { + + td { + font-size: 13pt; + padding: 4pt 4pt; + + &:first-child { + text-align: left; + padding-left: 0; + } + + &:last-child { + padding-right: 0; + } + } + + &.discount { + + td { + padding-bottom: 16pt; + } + } + + &.total { + + td { + padding: 16pt 4pt 0 4pt; + font-size: 16pt; + + &:first-child { + padding-left: 0; + } + + &:last-child { + padding-right: 0; + } + } + } + } + } + } + + .footer { + + .note { + font-size: 10pt; + margin-bottom: 8pt; + } + + .logo { + font-size: 14pt; + margin-right: 8pt; + } + + .small-note { + font-size: 8pt; + line-height: normal; + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/app/main/pages/invoices/modern/modern.component.ts b/src/app/main/pages/invoices/modern/modern.component.ts new file mode 100644 index 00000000..efba28b8 --- /dev/null +++ b/src/app/main/pages/invoices/modern/modern.component.ts @@ -0,0 +1,21 @@ +import { Component } from '@angular/core'; +import { InvoiceService } from '../invoice.service'; + +@Component({ + selector : 'fuse-invoice-modern', + templateUrl: './modern.component.html', + styleUrls : ['./modern.component.scss'] +}) +export class InvoiceModernComponent +{ + invoice: any; + + constructor(private invoiceService: InvoiceService) + { + this.invoiceService.invoiceOnChanged + .subscribe((invoice) => { + this.invoice = invoice; + }); + } + +} diff --git a/src/app/main/pages/pages.module.ts b/src/app/main/pages/pages.module.ts index 92070061..ea1472c8 100644 --- a/src/app/main/pages/pages.module.ts +++ b/src/app/main/pages/pages.module.ts @@ -12,10 +12,13 @@ import { LockComponent } from './authentication/lock/lock.component'; import { ComingSoonComponent } from './coming-soon/coming-soon.component'; import { Error404Component } from './errors/404/error-404.component'; import { Error500Component } from './errors/500/error-500.component'; +import { InvoiceModernComponent } from './invoices/modern/modern.component'; import { MaintenanceComponent } from './maintenance/maintenance.component'; import { ProfileComponent } from './profile/profile.component'; import { ProfileModule } from './profile/profile.module'; import { ProfileService } from './profile/profile.service'; +import { InvoiceCompactComponent } from './invoices/compact/compact.component'; +import { InvoiceService } from './invoices/invoice.service'; const routes = [ { @@ -58,6 +61,20 @@ const routes = [ path : 'pages/errors/error-500', component: Error500Component }, + { + path : 'pages/invoices/compact', + component: InvoiceCompactComponent, + resolve : { + invoice: InvoiceService + } + }, + { + path : 'pages/invoices/modern', + component: InvoiceModernComponent, + resolve : { + invoice: InvoiceService + } + }, { path : 'pages/maintenance', component: MaintenanceComponent @@ -88,9 +105,12 @@ const routes = [ ComingSoonComponent, Error404Component, Error500Component, + InvoiceCompactComponent, + InvoiceModernComponent, MaintenanceComponent ], providers : [ + InvoiceService, ProfileService ] })