feat(demo): new layout for demo header, add call-to-action cards (#1979)

This commit is contained in:
Vladislav Ahmetvaliev 2019-01-16 14:52:20 +03:00 committed by Sergey Andrievskiy
parent 43cc3a1556
commit a71c8281ab
8 changed files with 270 additions and 80 deletions

View file

@ -9,7 +9,6 @@
</div> </div>
<div class="header-container"> <div class="header-container">
<ngx-layout-direction-switcher></ngx-layout-direction-switcher>
<nb-actions <nb-actions
size="medium" size="medium"
[class.right]="position === 'normal'" [class.right]="position === 'normal'"
@ -18,24 +17,27 @@
<nb-user [nbContextMenu]="userMenu" [name]="user?.name" [picture]="user?.picture"></nb-user> <nb-user [nbContextMenu]="userMenu" [name]="user?.name" [picture]="user?.picture"></nb-user>
</nb-action> </nb-action>
<nb-action class="control-item notifications" disabled icon="nb-notifications"></nb-action> <nb-action class="control-item notifications" disabled icon="nb-notifications"></nb-action>
<nb-action class="control-item email" icon="nb-email"></nb-action>
<nb-action class="control-item search"> <nb-action class="control-item search">
<nb-search type="rotate-layout" (click)="startSearch()"></nb-search> <nb-search type="rotate-layout" (click)="startSearch()"></nb-search>
</nb-action> </nb-action>
<nb-action class="control-item email-text text-success">
<a href="mailto:contact@akveo.com" (click)="trackEmailClick()" class="btn btn-outline-primary btn-with-icon">
<i class="nb-email"></i>
<span>contact@akveo.com</span>
</a>
</nb-action>
<nb-action class="control-item download-count">
<i class="icon" [innerHTML]="'download' | eva"></i>
<span>167.000</span>
</nb-action>
<nb-action class="control-item github-start"> <nb-action class="control-item github-start">
<iframe src="https://ghbtns.com/github-btn.html?user=akveo&repo=ngx-admin&type=star&count=true" frameborder="0" scrolling="0" width="170px" height="20px"></iframe> <span>Support us: </span>
<iframe src="https://ghbtns.com/github-btn.html?user=akveo&repo=ngx-admin&type=star&count=true"
frameborder="0"
scrolling="0"
width="170px"
height="20px">
</iframe>
</nb-action> </nb-action>
<nb-action class="control-item email-text" *ngIf="!hireTextVariant"> </nb-actions>
<strong>Need some help? <a (click)="trackEmailClick()" href="mailto:contact@akveo.com">contact@akveo.com</a></strong>
</nb-action>
<nb-action class="control-item email-text text-success" *ngIf="hireTextVariant === 'highlight-hire'">
<strong>Need some help? <a (click)="trackEmailClick()" href="mailto:contact@akveo.com">contact@akveo.com</a></strong>
</nb-action>
<nb-action class="control-item email-text text-success" *ngIf="hireTextVariant === 'developers-hire'">
<strong>Looking for developers for your project? <a (click)="trackEmailClick()" href="mailto:contact@akveo.com">contact@akveo.com</a></strong>
</nb-action>
<nb-action class="control-item email-text text-success" *ngIf="hireTextVariant === 'solution-hire'">
<strong>Need a custom solution? <a (click)="trackEmailClick()" href="mailto:contact@akveo.com">contact@akveo.com</a></strong>
</nb-action>
</nb-actions>
</div> </div>

View file

@ -12,12 +12,10 @@
width: 100%; width: 100%;
order: 0; order: 0;
flex-direction: row; flex-direction: row;
flex: 1;
} }
.right { .right {
order: 1; order: 1;
flex-direction: row-reverse; flex-direction: row-reverse;
flex: 1.5;
} }
.logo-containter { .logo-containter {
@ -27,21 +25,61 @@
} }
.control-item { .control-item {
display: block; display: flex;
font-weight: 500;
&.email-text { &.email-text {
height: auto; display: flex;
a { a {
text-decoration: underline; font-size: 1.1428rem;
font-weight: 700;
font-family: nb-theme(font-main);
text-transform: none;
vertical-align: middle;
padding: 0.55rem 1.1rem 0.55rem 0.8rem;
background-color: nb-theme(header-button-background);
color: nb-theme(header-button-color);
border-color: nb-theme(header-button-outline);
&:hover {
background-color: nb-theme(header-button-background-hover);
}
}
i {
font-size: 2rem;
vertical-align: middle;
margin-right: 0.6rem;
} }
} }
&.github-start { &.github-start {
width: 140px; width: 245px;
display: flex; display: flex;
font-size: 1.285rem;
iframe { iframe {
width: 100px; width: 100px;
@include nb-ltr(margin-left, 1rem);
@include nb-rtl(margin-right, 1rem);
}
}
&.download-count {
display: flex;
font-size: 1.285rem;
font-family: nb-theme(font-secondary);
.icon {
fill: nb-theme(color-white);
@include nb-ltr(margin-right, 0.5rem);
@include nb-rtl(margin-left, 0.5rem);
font-size: 0;
@include nb-for-theme(default) {
fill: #bfc7cf;
}
} }
} }
} }
@ -173,13 +211,21 @@
@include media-breakpoint-down(xl) { @include media-breakpoint-down(xl) {
.control-item.email, .control-item.notifications { .control-item.search, .control-item.notifications, .control-item.github-start span {
display: none; display: none;
} }
.control-item.github-start {
width: auto;
iframe {
margin: 0;
}
}
} }
@include media-breakpoint-down(lg) { @include media-breakpoint-down(lg) {
.control-item.search {
nb-user /deep/ .user-name, .control-item.download-count {
display: none; display: none;
} }
} }
@ -190,6 +236,10 @@
border: none; border: none;
} }
ngx-theme-switcher {
display: none;
}
.control-item { .control-item {
display: none; display: none;
} }
@ -209,11 +259,7 @@
@include media-breakpoint-down(sm) { @include media-breakpoint-down(sm) {
nb-user /deep/ .user-name { .control-item.email-text {
display: none;
}
.control-item.github-start {
display: none; display: none;
} }

View file

@ -1,11 +1,8 @@
import { Component, Input, OnDestroy, OnInit } from '@angular/core'; import { Component, Input, OnInit } from '@angular/core';
import { NbMenuService, NbSidebarService } from '@nebular/theme'; import { NbMenuService, NbSidebarService } from '@nebular/theme';
import { UserData } from '../../../@core/data/users'; import { UserData } from '../../../@core/data/users';
import { AnalyticsService } from '../../../@core/utils/analytics.service'; import { AnalyticsService } from '../../../@core/utils';
import { takeWhile } from 'rxjs/operators/takeWhile';
import { fromEvent as observableFromEvent } from 'rxjs/observable/fromEvent';
import { AbService } from '../../../@core/utils/ab.service';
import { LayoutService } from '../../../@core/utils'; import { LayoutService } from '../../../@core/utils';
@Component({ @Component({
@ -13,44 +10,23 @@ import { LayoutService } from '../../../@core/utils';
styleUrls: ['./header.component.scss'], styleUrls: ['./header.component.scss'],
templateUrl: './header.component.html', templateUrl: './header.component.html',
}) })
export class HeaderComponent implements OnInit , OnDestroy { export class HeaderComponent implements OnInit {
@Input() position = 'normal'; @Input() position = 'normal';
user: any; user: any;
hireTextVariant: string = 'solution-hire';
userMenu = [{ title: 'Profile' }, { title: 'Log out' }];
private alive = true; userMenu = [{ title: 'Profile' }, { title: 'Log out' }];
constructor(private sidebarService: NbSidebarService, constructor(private sidebarService: NbSidebarService,
private menuService: NbMenuService, private menuService: NbMenuService,
private userService: UserData, private userService: UserData,
private analytics: AnalyticsService, private analytics: AnalyticsService,
private abService: AbService, private layoutService: LayoutService) {}
private layoutService: LayoutService) {
observableFromEvent(document, 'mouseup')
.pipe(takeWhile(() => this.alive))
.subscribe(() => {
let selection: any;
if (window.getSelection) {
selection = window.getSelection();
} else if ((<any> document).selection) {
selection = (<any> document).selection.createRange();
}
if (selection && selection.toString() === 'contact@akveo.com') {
this.analytics.trackEvent('clickContactEmail', 'select');
}
});
}
ngOnInit() { ngOnInit() {
this.userService.getUsers() this.userService.getUsers()
.subscribe((users: any) => this.user = users.nick); .subscribe((users: any) => this.user = users.nick);
this.listenForVariants();
} }
toggleSidebar(): boolean { toggleSidebar(): boolean {
@ -71,23 +47,4 @@ export class HeaderComponent implements OnInit , OnDestroy {
trackEmailClick() { trackEmailClick() {
this.analytics.trackEvent('clickContactEmail', 'click'); this.analytics.trackEvent('clickContactEmail', 'click');
} }
ngOnDestroy() {
this.alive = false;
}
listenForVariants() {
const variants = [
AbService.VARIANT_DEVELOPERS_HIRE,
AbService.VARIANT_HIGHLIGHT_HIRE,
AbService.VARIANT_SOLUTION_HIRE,
];
this.abService.onAbEvent()
.subscribe((e: { name: string }) => {
if (variants.includes(e.name)) {
this.hireTextVariant = e.name;
}
});
}
} }

View file

@ -11,6 +11,7 @@ $nb-themes: nb-register-theme((
sidebar-header-gap: 2rem, sidebar-header-gap: 2rem,
sidebar-header-height: initial, sidebar-header-height: initial,
layout-content-width: 1400px, layout-content-width: 1400px,
header-height: 5.45rem,
font-main: Roboto, font-main: Roboto,
font-secondary: Exo, font-secondary: Exo,
@ -19,6 +20,11 @@ $nb-themes: nb-register-theme((
switcher-background-percentage: 50%, switcher-background-percentage: 50%,
drops-icon-line-gadient: -webkit-linear-gradient(#01dbb5, #0bbb79), drops-icon-line-gadient: -webkit-linear-gradient(#01dbb5, #0bbb79),
header-button-background: #f5f7fa,
header-button-background-hover: #ebeff5,
header-button-color: #2a2a2a,
header-button-outline: #42db7d,
list-item-border-width: 1px, list-item-border-width: 1px,
slide-out-container-width: 30%, slide-out-container-width: 30%,
@ -46,6 +52,7 @@ $nb-themes: nb-register-theme((
sidebar-header-gap: 2rem, sidebar-header-gap: 2rem,
sidebar-header-height: initial, sidebar-header-height: initial,
layout-content-width: 1400px, layout-content-width: 1400px,
header-height: 5.45rem,
font-main: Roboto, font-main: Roboto,
font-secondary: Exo, font-secondary: Exo,
@ -54,6 +61,11 @@ $nb-themes: nb-register-theme((
switcher-background-percentage: 14%, switcher-background-percentage: 14%,
drops-icon-line-gadient: -webkit-linear-gradient(#a258fe, #7958fa), drops-icon-line-gadient: -webkit-linear-gradient(#a258fe, #7958fa),
header-button-background: #4e41a5,
header-button-background-hover: #675cb2,
header-button-color: #ffffff,
header-button-outline: #7659ff,
list-item-border-width: 1px, list-item-border-width: 1px,
slide-out-container-width: 30%, slide-out-container-width: 30%,
@ -81,6 +93,7 @@ $nb-themes: nb-register-theme((
sidebar-header-gap: 2rem, sidebar-header-gap: 2rem,
sidebar-header-height: initial, sidebar-header-height: initial,
layout-content-width: 1400px, layout-content-width: 1400px,
header-height: 5.45rem,
font-main: Roboto, font-main: Roboto,
font-secondary: Exo, font-secondary: Exo,
@ -89,6 +102,11 @@ $nb-themes: nb-register-theme((
switcher-background-percentage: 14%, switcher-background-percentage: 14%,
drops-icon-line-gadient: -webkit-linear-gradient(#e9e8eb, #a7a2be), drops-icon-line-gadient: -webkit-linear-gradient(#e9e8eb, #a7a2be),
header-button-background: #2b2d34,
header-button-background-hover: #494a50,
header-button-color: #ffffff,
header-button-outline: #a4abb3,
list-item-border-width: 1px, list-item-border-width: 1px,
slide-out-container-width: 30%, slide-out-container-width: 30%,

View file

@ -0,0 +1,99 @@
@import '../../../@theme/styles/themes';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
nb-card {
flex-direction: row;
align-items: center;
height: 6rem;
overflow: visible;
$shadow: nb-theme(btn-hero-shadow);
box-shadow: $shadow;
.icon-container {
height: 100%;
padding: 0;
@include nb-for-theme(cosmic) {
background-image: linear-gradient(to right, #a054fe 0%, #7a58ff 100%);
}
@include nb-for-theme(corporate) {
background-image: linear-gradient(to right, #ff9f6f 0%, #ff9f6f 100%);
}
@include nb-for-theme(default) {
background-image: linear-gradient(to right, #ff4c6f 0%, #ff4c9f 100%);
}
@include nb-ltr(border-radius, nb-theme(card-border-radius) 0 0 nb-theme(card-border-radius));
@include nb-rtl(border-radius, 0 nb-theme(card-border-radius) nb-theme(card-border-radius) 0);
@include media-breakpoint-down(lg) {
display: none;
}
}
.icon {
display: flex;
align-items: center;
justify-content: center;
width: 7rem;
height: 100%;
font-size: 3.2rem;
border-radius: nb-theme(card-border-radius);
transition: width 0.4s ease;
transform: translate3d(0, 0, 0);
-webkit-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
/deep/ svg {
width: 2.6rem;
height: 2.6rem;
vertical-align: middle;
fill: nb-theme(color-white);
}
}
.details {
flex: 1 1 auto;
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;
@include nb-ltr(padding, 0 0.5rem 0 1.15rem);
@include nb-rtl(padding, 0 1.15rem 0 0.5rem);
border-left: 1px solid transparent;
}
.title {
font-family: nb-theme(font-secondary);
font-size: 1.25rem;
font-weight: nb-theme(font-weight-bold);
color: nb-theme(card-fg-heading);
}
.status {
font-size: 1rem;
font-weight: nb-theme(font-weight-light);
text-transform: uppercase;
color: nb-theme(card-fg);
}
.actions {
@include nb-ltr(padding, 0 1.15rem 0 0.5rem);
@include nb-rtl(padding, 0 0.5rem 0 1.15rem);
}
[nbButton] {
padding-top: 1rem;
padding-bottom: 1rem;
min-width: 11.4rem;
font-weight: 800;
font-size: 1.15rem;
text-shadow: 0 0 16px rgba(0, 0, 0, 0.16);
box-shadow: none;
}
}
}

View file

@ -0,0 +1,50 @@
import { Component, Input, OnDestroy } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators';
@Component({
selector: 'ngx-call-action-card',
styleUrls: ['./call-action-card.component.scss'],
template: `
<nb-card>
<div class="icon-container hidden-sm-down">
<div class="icon" [innerHTML]="type | eva">
</div>
</div>
<div class="details">
<div class="title">{{ title }}</div>
</div>
<div class="actions">
<a nbButton size="large" hero href="{{ link }}" [ngClass]="{
'btn-primary': currentTheme === 'cosmic',
'btn-warning': currentTheme === 'corporate',
'btn-danger': currentTheme === 'default'
}">{{ linkTitle }}</a>
</div>
</nb-card>
`,
})
export class CallActionCardComponent implements OnDestroy {
private alive = true;
@Input() title: string;
@Input() type: string;
@Input() link: string;
@Input() linkTitle: string;
currentTheme: string;
constructor(private themeService: NbThemeService) {
this.themeService.getJsTheme()
.pipe(takeWhile(() => this.alive))
.subscribe(theme => {
this.currentTheme = theme.name;
});
}
ngOnDestroy() {
this.alive = false;
}
}

View file

@ -1,3 +1,19 @@
<div class="row">
<div class="col-12 col-md-6">
<ngx-call-action-card [title]="'Need a custom solution?'"
[type]="'pantone'"
[link]="'https://www.akveo.com/contacts?utm_source=ngx_admin_demo&utm_medium=contact_card'"
[linkTitle]="'Contact us'">
</ngx-call-action-card>
</div>
<div class="col-12 col-md-6">
<ngx-call-action-card [title]="'Why ngx-admin works for you?'"
[type]="'briefcase'"
[link]="'https://akveo.github.io/ngx-admin?utm_source=ngx_admin_demo&utm_medium=contact_card'"
[linkTitle]="'Learn more'">
</ngx-call-action-card>
</div>
</div>
<div class="row"> <div class="row">
<div class="col-xxl-5"> <div class="col-xxl-5">
<div class="row"> <div class="row">

View file

@ -4,6 +4,7 @@ import { NgxChartsModule } from '@swimlane/ngx-charts';
import { ThemeModule } from '../../@theme/theme.module'; import { ThemeModule } from '../../@theme/theme.module';
import { ECommerceComponent } from './e-commerce.component'; import { ECommerceComponent } from './e-commerce.component';
import { CallActionCardComponent } from './call-action-card/call-action-card.component';
import { ProfitCardComponent } from './profit-card/profit-card.component'; import { ProfitCardComponent } from './profit-card/profit-card.component';
import { ECommerceChartsPanelComponent } from './charts-panel/charts-panel.component'; import { ECommerceChartsPanelComponent } from './charts-panel/charts-panel.component';
import { OrdersChartComponent } from './charts-panel/charts/orders-chart.component'; import { OrdersChartComponent } from './charts-panel/charts/orders-chart.component';
@ -56,6 +57,7 @@ import { EarningLiveUpdateChartComponent } from './earning-card/front-side/earni
], ],
declarations: [ declarations: [
ECommerceComponent, ECommerceComponent,
CallActionCardComponent,
StatsCardFrontComponent, StatsCardFrontComponent,
StatsAreaChartComponent, StatsAreaChartComponent,
StatsBarAnimationChartComponent, StatsBarAnimationChartComponent,