mirror of
https://github.com/richard-loafle/fuse-angular.git
synced 2025-01-10 04:25:08 +00:00
invoice pages
This commit is contained in:
parent
1c66ccd9e2
commit
e0253cd8d2
|
@ -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'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
59
src/app/fuse-fake-db/invoice.ts
Normal file
59
src/app/fuse-fake-db/invoice.ts
Normal file
|
@ -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'
|
||||
};
|
||||
}
|
147
src/app/main/pages/invoices/compact/compact.component.html
Normal file
147
src/app/main/pages/invoices/compact/compact.component.html
Normal file
|
@ -0,0 +1,147 @@
|
|||
<div id="invoice" class="compact page-layout blank" fxLayout="row" perfect-scrollbar>
|
||||
|
||||
<div class="invoice-container">
|
||||
|
||||
<!-- INVOICE -->
|
||||
<div class="card">
|
||||
|
||||
<div class="header">
|
||||
<div class="invoice-date">{{invoice.date}}</div>
|
||||
|
||||
<div fxLayout="row" fxLayoutAlign="space-between stretch">
|
||||
<div class="client">
|
||||
<div class="invoice-number" fxLayout="row" fxLayoutAlign="start center">
|
||||
<span class="title">INVOICE</span>
|
||||
<span class="number">{{invoice.number}}</span>
|
||||
</div>
|
||||
|
||||
<div class="due-date" fxLayout="row" fxLayoutAlign="start center">
|
||||
<span class="title">DUE DATE</span>
|
||||
<span class="date">{{invoice.dueDate}}</span>
|
||||
</div>
|
||||
|
||||
<div class="info">
|
||||
<div class="title">{{invoice.client.title}}</div>
|
||||
<div *ngIf="invoice?.client.address" class="address">{{invoice.client.address}}</div>
|
||||
<div *ngIf="invoice?.client.phone" class="phone">{{invoice.client.phone}}</div>
|
||||
<div *ngIf="invoice?.client.email" class="email">{{invoice.client.email}}</div>
|
||||
<div *ngIf="invoice?.client.website" class="website">{{invoice.client.website}}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="issuer md-accent-bg" fxLayout="row" fxLayoutAlign="start center">
|
||||
<div class="logo" fxLayout="row" fxLayoutAlign="center center">
|
||||
<span>F</span>
|
||||
</div>
|
||||
|
||||
<div class="info">
|
||||
<div class="title">{{invoice.from.title}}</div>
|
||||
<div *ngIf="invoice?.from.address" class="address">{{invoice.from.address}}</div>
|
||||
<div *ngIf="invoice?.from.phone" class="phone">{{invoice.from.phone}}</div>
|
||||
<div *ngIf="invoice?.from.email" class="email">{{invoice.from.email}}</div>
|
||||
<div *ngIf="invoice?.from.website" class="website">{{invoice.from.website}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<table class="simple invoice-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>SERVICE</th>
|
||||
<th>UNIT</th>
|
||||
<th class="text-right">UNIT PRICE</th>
|
||||
<th class="text-right">QUANTITY</th>
|
||||
<th class="text-right">TOTAL</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let service of invoice.services">
|
||||
<td>
|
||||
<div class="title">
|
||||
{{service.title}}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{{service.unit}}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
{{service.unitPrice | currency:'USD':true}}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
{{service.quantity}}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
{{service.total | currency:'USD':true}}
|
||||
</td>
|
||||
</tr>
|
||||
<!-- Double the invoice data for demo purposes -->
|
||||
<tr *ngFor="let service of invoice.services">
|
||||
<td>
|
||||
<div class="title">
|
||||
{{service.title}}
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{{service.unit}}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
{{service.unitPrice | currency:'USD':true}}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
{{service.quantity}}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
{{service.total | currency:'USD':true}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="simple invoice-table-footer">
|
||||
<tbody>
|
||||
<tr class="subtotal">
|
||||
<td>SUBTOTAL</td>
|
||||
<td>{{invoice.subtotal | currency:'USD':true}}</td>
|
||||
</tr>
|
||||
<tr class="tax">
|
||||
<td>TAX</td>
|
||||
<td>{{invoice.tax | currency:'USD':true}}</td>
|
||||
</tr>
|
||||
<tr class="discount">
|
||||
<td>DISCOUNT</td>
|
||||
<td>-{{invoice.discount | currency:'USD':true}}</td>
|
||||
</tr>
|
||||
<tr class="total">
|
||||
<td>TOTAL</td>
|
||||
<td>{{invoice.total | currency:'USD':true}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<div class="note">Please pay within 15 days. Thank you for your business.</div>
|
||||
<div fxLayout="row" fxLayoutAlign="start start">
|
||||
<div class="logo md-accent-bg" fxLayout="row" fxLayoutAlign="center center">
|
||||
<div>F</div>
|
||||
</div>
|
||||
<div class="small-note">
|
||||
In condimentum malesuada efficitur. Mauris volutpat placerat auctor. Ut ac congue dolor. Quisque
|
||||
scelerisque lacus sed feugiat fermentum. Cras aliquet facilisis pellentesque. Nunc hendrerit
|
||||
quam at leo commodo, a suscipit tellus dapibus. Etiam at felis volutpat est mollis lacinia.
|
||||
Mauris placerat sem sit amet velit mollis, in porttitor ex finibus. Proin eu nibh id libero
|
||||
tincidunt lacinia et eget eros.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / INVOICE -->
|
||||
|
||||
<!-- Use the following element to add breaks to your pages -->
|
||||
<!-- This will make sure that the section after this element will be printed on a new page -->
|
||||
<div class="page-break"></div>
|
||||
|
||||
</div>
|
||||
</div>
|
358
src/app/main/pages/invoices/compact/compact.component.scss
Normal file
358
src/app/main/pages/invoices/compact/compact.component.scss
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
21
src/app/main/pages/invoices/compact/compact.component.ts
Normal file
21
src/app/main/pages/invoices/compact/compact.component.ts
Normal file
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
53
src/app/main/pages/invoices/invoice.service.ts
Normal file
53
src/app/main/pages/invoices/invoice.service.ts
Normal file
|
@ -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<any>
|
||||
{
|
||||
invoice: any;
|
||||
|
||||
invoiceOnChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
||||
|
||||
constructor(private http: Http)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve
|
||||
* @param {ActivatedRouteSnapshot} route
|
||||
* @param {RouterStateSnapshot} state
|
||||
* @returns {Observable<any> | Promise<any> | any}
|
||||
*/
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
Promise.all([
|
||||
this.getInvoice()
|
||||
]).then(
|
||||
() => {
|
||||
resolve();
|
||||
},
|
||||
reject
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get invoice
|
||||
*/
|
||||
getInvoice(): Promise<any[]>
|
||||
{
|
||||
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);
|
||||
});
|
||||
}
|
||||
}
|
169
src/app/main/pages/invoices/modern/modern.component.html
Normal file
169
src/app/main/pages/invoices/modern/modern.component.html
Normal file
|
@ -0,0 +1,169 @@
|
|||
<div id="invoice" class="modern page-layout blank" fxLayout="row" perfect-scrollbar>
|
||||
|
||||
<div class="invoice-container">
|
||||
|
||||
<!-- INVOICE -->
|
||||
<div class="card">
|
||||
|
||||
<div class="header" fxLayout="row" fxLayoutAlign="space-between start">
|
||||
|
||||
<div class="ids" fxLayout="column">
|
||||
|
||||
<div fxLayout="row" class="seller" fxLayoutAlign="start center">
|
||||
<div class="logo md-accent-bg" fxLayout="row" fxLayoutAlign="center center">
|
||||
<div>F</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="detail">
|
||||
<div class="title">{{invoice.from.title}}</div>
|
||||
<div *ngIf="invoice?.from.address" class="address">
|
||||
{{invoice.from.address}}
|
||||
</div>
|
||||
<div *ngIf="invoice?.from.phone" class="phone">
|
||||
<span>Phone:</span>
|
||||
{{invoice.from.phone}}
|
||||
</div>
|
||||
<div *ngIf="invoice?.from.email" class="email">
|
||||
<span>Email:</span>
|
||||
{{invoice.from.email}}
|
||||
</div>
|
||||
<div *ngIf="invoice?.from.website" class="website">
|
||||
<span>Web:</span>
|
||||
{{invoice.from.website}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div fxLayout="row" class="client" fxLayoutAlign="start center">
|
||||
<div class="label" fxLayout="row" fxLayoutAlign="end center">
|
||||
<div>CLIENT</div>
|
||||
</div>
|
||||
|
||||
<div class="divider"></div>
|
||||
|
||||
<div class="detail">
|
||||
<div class="title">{{invoice.client.title}}</div>
|
||||
<div *ngIf="invoice?.client.address" class="address">
|
||||
{{invoice.client.address}}
|
||||
</div>
|
||||
<div *ngIf="invoice?.client.phone" class="phone">
|
||||
<span>Phone:</span>
|
||||
{{invoice.client.phone}}
|
||||
</div>
|
||||
<div *ngIf="invoice?.client.email" class="email">
|
||||
<span>Email:</span>
|
||||
{{invoice.client.email}}
|
||||
</div>
|
||||
<div *ngIf="invoice?.client.website" class="website">
|
||||
<span>Web:</span>
|
||||
{{invoice.client.website}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="summary">
|
||||
<tr class="code">
|
||||
<td class="label">INVOICE</td>
|
||||
<td class="value">{{invoice.number}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="label">INVOICE DATE</td>
|
||||
<td class="value">{{invoice.date}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="label">DUE DATE</td>
|
||||
<td class="value">{{invoice.dueDate}}</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="label">TOTAL DUE</td>
|
||||
<td class="value">{{invoice.total | currency:'USD':true}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<table class="simple invoice-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>SERVICE</th>
|
||||
<th>UNIT</th>
|
||||
<th class="text-right">UNIT PRICE</th>
|
||||
<th class="text-right">QUANTITY</th>
|
||||
<th class="text-right">TOTAL</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let service of invoice.services">
|
||||
<td>
|
||||
<div class="title">{{service.title}}</div>
|
||||
<div class="detail">{{service.detail}}</div>
|
||||
</td>
|
||||
<td>
|
||||
{{service.unit}}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
{{service.unitPrice | currency:'USD':true}}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
{{service.quantity}}
|
||||
</td>
|
||||
<td class="text-right">
|
||||
{{service.total | currency:'USD':true}}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<table class="simple invoice-table-footer">
|
||||
<tbody>
|
||||
<tr class="subtotal">
|
||||
<td>SUBTOTAL</td>
|
||||
<td>{{invoice.subtotal | currency:'USD':true}}</td>
|
||||
</tr>
|
||||
<tr class="tax">
|
||||
<td>TAX</td>
|
||||
<td>{{invoice.tax | currency:'USD':true}}</td>
|
||||
</tr>
|
||||
<tr class="discount">
|
||||
<td>DISCOUNT</td>
|
||||
<td>-{{invoice.discount | currency:'USD':true}}</td>
|
||||
</tr>
|
||||
<tr class="total">
|
||||
<td>TOTAL</td>
|
||||
<td>{{invoice.total | currency:'USD':true}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="footer">
|
||||
<div class="note">Please pay within 15 days. Thank you for your business.</div>
|
||||
<div fxLayout="row" fxLayoutAlign="start start">
|
||||
<div class="logo md-accent-bg" fxLayout="row" fxLayoutAlign="center center">
|
||||
<div>F</div>
|
||||
</div>
|
||||
<div class="small-note">
|
||||
In condimentum malesuada efficitur. Mauris volutpat placerat auctor. Ut ac congue dolor. Quisque
|
||||
scelerisque lacus sed feugiat fermentum. Cras aliquet facilisis pellentesque. Nunc hendrerit
|
||||
quam at leo commodo, a suscipit tellus dapibus. Etiam at felis volutpat est mollis lacinia.
|
||||
Mauris placerat sem sit amet velit mollis, in porttitor ex finibus. Proin eu nibh id libero
|
||||
tincidunt lacinia et eget eros.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / INVOICE -->
|
||||
|
||||
<!-- Use the following element to add breaks to your pages -->
|
||||
<!-- This will make sure that the section after this element will be printed on a new page -->
|
||||
<div class="page-break"></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
359
src/app/main/pages/invoices/modern/modern.component.scss
Normal file
359
src/app/main/pages/invoices/modern/modern.component.scss
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
21
src/app/main/pages/invoices/modern/modern.component.ts
Normal file
21
src/app/main/pages/invoices/modern/modern.component.ts
Normal file
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
]
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue
Block a user