feat: add material

This commit is contained in:
Sergey Andrievskiy 2020-03-30 16:23:05 +03:00
commit 576e369c92
67 changed files with 8144 additions and 7699 deletions

View file

@ -197,7 +197,7 @@
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.css",
"node_modules/nebular-icons/scss/nebular-icons.scss",
"node_modules/swiper/dist/css/swiper.min.css",
"node_modules/swiper/css/swiper.min.css",
"node_modules/highlight.js/styles/dracula.css",
"docs/app/@theme/styles/styles.scss"
]

View file

@ -29,8 +29,8 @@ export class CoreModule {
throwIfAlreadyLoaded(parentModule, 'CoreModule');
}
static forRoot(): ModuleWithProviders {
return <ModuleWithProviders>{
static forRoot(): ModuleWithProviders<CoreModule> {
return {
ngModule: CoreModule,
providers: [
...NB_CORE_PROVIDERS,

View file

@ -9,6 +9,7 @@
</div>
<div class="section middle">
<nb-menu [items]="headerMenu"></nb-menu>
<ng-content></ng-content>
<a routerLink="/" fragment="backend-bundles" class="backend-bundles eva-parent-hover">
<i [innerHTML]="'gift-outline' | eva: { width: 24, height: 24, fill: '#ff4d6b', animationType: 'shake' }"></i>
<span>Backend Bundles</span>

View file

@ -56,7 +56,8 @@ export class NgxStructureService {
}
if (item.block === 'markdown') {
item.children = this.textService.mdToSectionsHTML(require(`raw-loader!../../../articles/${item.source}`));
item.children = this.textService.mdToSectionsHTML(
require(`raw-loader!../../../articles/${item.source}`).default);
}
if (item.children) {

View file

@ -25,7 +25,7 @@ $grid-breakpoints: (
xxxl: 1600px
);
$nb-enabled-themes: (ngx-landing, docs-page);
$nb-enabled-themes: (ngx-landing, ngx-landing-material, docs-page);
/* stylelint-disable */
$nb-themes: nb-register-theme((
@ -127,6 +127,30 @@ $nb-themes: nb-register-theme((
), ngx-landing, corporate);
$nb-themes: nb-register-theme((
font-family-primary: unquote('Roboto, sans-serif'),
shadow: unquote('0 2px 1px -1px rgba(0,0,0,.2), 0 1px 1px 0 rgba(0,0,0,.14), 0 1px 3px 0 rgba(0,0,0,.12)'),
header-shadow: unquote(
'0 3px 5px -1px rgba(0,0,0,.2), 0 6px 10px 0 rgba(0,0,0,.14), 0 1px 18px 0 rgba(0,0,0,.12)'
),
shadow-default: shadow,
shadow-btn: shadow,
shadow-hover-btn: shadow,
shadow-active-btn: shadow,
shadow-hover-green-btn: shadow,
shadow-active-green-btn: shadow,
color-primary-default: #6200ee,
color-active-fg: color-primary-default,
color-active-bg: color-primary-default,
header-background-color: color-primary-default,
header-text-color: #ffffff !important,
menu-text-color: #ffffff !important,
footer-background-color: color-primary-default,
footer-text-color: #ffffff !important
), ngx-landing-material, ngx-landing);
/* stylelint-enable foo */
$nb-themes: nb-register-theme((
// custom

View file

@ -9,6 +9,17 @@ import { ModuleWithProviders, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { LazyLoadImageModule } from 'ng-lazyload-image';
import {
NbLayoutModule,
NbThemeModule,
NbMenuModule,
NbCheckboxModule,
NbCardModule,
NbSidebarModule,
NbTabsetModule,
} from '@nebular/theme';
import { LandingSharedModule } from '../shared/landing-shared.module';
// components
import {
@ -26,21 +37,6 @@ import {
import { ngxLandingServices } from './services';
// services
// pipes
import { EvaIconsPipe } from './pipes/eva-icons.pipe';
import { CapitalizePipe } from './pipes/capitalize.pipe';
// pipes
import {
NbLayoutModule,
NbThemeModule,
NbMenuModule,
NbCheckboxModule,
NbCardModule,
NbSidebarModule,
NbTabsetModule,
} from '@nebular/theme';
const BASE_MODULES = [
CommonModule,
FormsModule,
@ -67,14 +63,10 @@ const COMPONENTS = [
NgxDocsFooterComponent,
];
const PIPES = [
EvaIconsPipe,
CapitalizePipe,
];
@NgModule({
imports: [
RouterModule,
LandingSharedModule,
...BASE_MODULES,
@ -82,8 +74,6 @@ const PIPES = [
],
declarations: [
...COMPONENTS,
...PIPES,
],
exports: [
RouterModule,
@ -93,15 +83,11 @@ const PIPES = [
...NB_MODULES,
...COMPONENTS,
...PIPES,
],
entryComponents: [
],
})
export class NgxLandingThemeModule {
static forRoot(): ModuleWithProviders {
return <ModuleWithProviders>{
static forRoot(): ModuleWithProviders<NgxLandingThemeModule> {
return {
ngModule: NgxLandingThemeModule,
providers: [
...NbThemeModule.forRoot({ name: 'ngx-landing' }).providers,

View file

@ -13,6 +13,7 @@ import { NgxLandingThemeModule } from './@theme/theme.module';
import { CoreModule } from './@core/core.module';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { LandingSharedModule } from './shared/landing-shared.module';
import { DOCS, STRUCTURE } from './app.options';
const docs = require('../output.json');
@ -28,6 +29,7 @@ import { structure } from '../structure';
HttpClientModule,
AppRoutingModule,
LandingSharedModule,
NgxLandingThemeModule.forRoot(),
CoreModule.forRoot(),
],

View file

@ -1,7 +1,9 @@
<nb-layout>
<nb-layout-header fixed>
<div class="content-center">
<ngx-landing-header class="docs-header" [sidebarTag]="sidebarTag" [isDocs]="true"></ngx-landing-header>
<ngx-landing-header class="docs-header" [sidebarTag]="sidebarTag" [isDocs]="true">
<ngx-material-theme-link></ngx-material-theme-link>
</ngx-landing-header>
</div>
</nb-layout-header>
<nb-sidebar class="menu-sidebar" [tag]="sidebarTag" [responsive]="true" [compactedBreakpoints]="[]" [collapsedBreakpoints]="collapsedBreakpoints">

View file

@ -11,6 +11,7 @@ import { NgxLandingThemeModule } from '../../@theme/theme.module';
import { SwiperModule } from 'ngx-swiper-wrapper';
import { NgxBlocksModule } from '../../blocks/blocks.module';
import { LandingDocsRoutingModule } from './landing-docs-routing.module';
import { LandingSharedModule } from '../../shared/landing-shared.module';
// modules
// components
@ -32,6 +33,7 @@ const COMPONENTS = [
imports: [
NgxLandingThemeModule,
SwiperModule,
LandingSharedModule,
LandingDocsRoutingModule,
NgxBlocksModule,
],

View file

@ -0,0 +1,6 @@
<div class="contact">
<h1>Need customization?</h1>
<p>Thinking of building something outstanding based on ngx-admin or just need some Angular/React experts?</p>
<a class="btn btn-demo" href="https://hubs.ly/H0nJf_b0"
target="_blank">Contact us</a>
</div>

View file

@ -0,0 +1,53 @@
@import '../../../@theme/styles/themes';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
$color-active: nb-theme(color-active-fg);
.contact {
text-align: center;
margin-bottom: 4rem;
}
h1 {
font-family: 'Helvetica Neue Bold', sans-serif;
font-size: 2.5rem;
color: $color-active;
margin: 0;
}
p {
font-family: unquote('"Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'), sans-serif;
font-size: 1.5rem;
line-height: 1.5;
margin-top: 1.5rem;
margin-bottom: 1.5rem;
}
.btn {
font-family: nb-theme(font-main), sans-serif;
border-radius: 3px;
border: none;
background: #ffffff;
color: #000000;
box-shadow: nb-theme(shadow-default);
cursor: pointer;
text-transform: uppercase;
&.btn-demo {
margin-top: 0.375rem;
padding: 1.125rem 6.25rem;
color: #ffffff;
background-color: nb-theme(color-active-fg);
box-shadow: nb-theme(shadow-btn);
}
&:hover {
box-shadow: nb-theme(shadow-hover-green-btn);
}
&:active {
box-shadow: nb-theme(shadow-active-green-btn);
}
}
}

View file

@ -0,0 +1,13 @@
import {Component} from '@angular/core';
@Component({
selector: 'ngx-contact-form',
templateUrl: './contact.component.html',
styleUrls: ['./contact.component.scss'],
})
export class ContactFormComponent {
constructor() {
}
}

View file

@ -7,6 +7,7 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LandingHomeComponent } from './landing-home.component';
import { MaterialLandingComponent } from './material-landing/material-landing.component';
export const routes: Routes = [
@ -14,6 +15,14 @@ export const routes: Routes = [
path: '',
component: LandingHomeComponent,
},
{
path: 'material',
component: MaterialLandingComponent,
},
// {
// path: 'overview',
// component: OverviewComponent,
// },
];
@NgModule({

View file

@ -1,6 +1,8 @@
<nb-layout>
<nb-layout-header fixed>
<ngx-landing-header></ngx-landing-header>
<ngx-landing-header>
<ngx-material-theme-link withPopover></ngx-material-theme-link>
</ngx-landing-header>
</nb-layout-header>
<nb-layout-column>

View file

@ -37,7 +37,7 @@
::ng-deep nb-layout-header {
box-shadow: nb-theme(shadow-default);
background: nb-theme(header-bg);
nav {
ngx-landing-header {
max-width: calc(#{$content-width} - 8.125rem * 2);
margin: 0 auto;
}
@ -48,9 +48,9 @@
background-color: nb-theme(color-white);
box-shadow: nb-theme(shadow-default);
nav {
ngx-landing-footer {
max-width: $content-width;
width: 100%;
justify-content: space-evenly;
margin: 0 auto;
}
}

View file

@ -26,14 +26,24 @@ import { NgxLandingSectionsContainerComponent } from './sections-container/ngx-l
import { BackendBundlesSectionComponent } from './backend-bundles-section/backend-bundles-section.component';
import { LicensePipe } from './backend-bundles-section/license.pipe';
import { BackgroundImagePipe } from './backend-bundles-section/background-image.pipe';
import { MaterialLandingComponent } from './material-landing/material-landing.component';
import { LandingSharedModule } from '../../shared/landing-shared.module';
import {MaterialFeaturesSectionComponent} from './material-features/material-features.component';
import {DefaultAdminInfoComponent} from './main-info-section/default-admin-main-info/default-info.component';
import {MaterialAdminInfoComponent} from './main-info-section/material-admin-main-info/material-info.component';
import {ContactFormComponent} from './contact-form/contact.component';
import {NbButtonModule} from '@nebular/theme';
// components
const PIPES = [LicensePipe, BackgroundImagePipe];
const COMPONENTS = [
LandingHomeComponent,
MaterialLandingComponent,
NgxLandingSectionsContainerComponent,
MainInfoSectionComponent,
DefaultAdminInfoComponent,
MaterialAdminInfoComponent,
DescriptionSectionComponent,
ReasonSectionComponent,
ThemeSectionComponent,
@ -42,6 +52,8 @@ const COMPONENTS = [
SocialSectionComponent,
ContactSectionComponent,
BackendBundlesSectionComponent,
MaterialFeaturesSectionComponent,
ContactFormComponent,
];
@NgModule({
@ -53,6 +65,8 @@ const COMPONENTS = [
NgxLandingThemeModule,
SwiperModule,
LandingHomeRoutingModule,
LandingSharedModule,
NbButtonModule,
],
providers: [
...PIPES,

View file

@ -0,0 +1,16 @@
<div>
<h1>ngx-admin</h1>
<p class="description">
The most popular admin dashboard based on <strong>Angular 9+</strong> and
<a href="https://hubs.ly/H0n5N9P0" target="_blank">Nebular</a> with
<a href="https://hubs.ly/H0n5PKH0">Eva Design System</a> support.
Free and Open Source for personal and commercial purposes.
<br>
<span class="bundles">
Never start from scratch again.
<a href="https://hubs.ly/H0n5NVz0" target="_blank">
Integrate ready-made solution: ngx-admin with backend.
</a>
</span>
</p>
</div>

View file

@ -0,0 +1,9 @@
import { Component } from '@angular/core';
@Component({
selector: 'ngx-default-admin-info',
templateUrl: './default-info.component.html',
styleUrls: ['./../main-info-section.component.scss'],
})
export class DefaultAdminInfoComponent {
}

View file

@ -5,24 +5,18 @@
<img *ngIf="breakpoint.width >= breakpoints.md"
class="main-img"
defaultImage="assets/img/default.png"
lazyLoad="assets/img/ngx-admin.png"/>
[lazyLoad]="imageUrl"/>
</a>
</div>
<div class="main-inf">
<h1>ngx-admin</h1>
<p class="description">
The most popular admin dashboard based on <strong>Angular 8+</strong>, Bootstrap 4+ and
<a href="https://hubs.ly/H0n5N9P0" target="_blank">Nebular</a> with
<a href="https://hubs.ly/H0n5PKH0">Eva Design System</a> support.
Free and Open Source for personal and commercial purposes.
<br>
<span class="bundles">
Never start from scratch again.
<a href="https://hubs.ly/H0n5NVz0" target="_blank">
Integrate ready-made solution: ngx-admin with backend.
</a>
</span>
</p>
<ng-container *ngIf="forMaterialTheme === false">
<ngx-default-admin-info></ngx-default-admin-info>
</ng-container>
<ng-container *ngIf="forMaterialTheme !== false">
<ngx-material-admin-info></ngx-material-admin-info>
</ng-container>
<div class="mobile-main-img-container">
<img *ngIf="breakpoint.width <= breakpoints.sm" class="main-img" lazyLoad="assets/img/corporate-theme.png" alt="Light theme Dashboard"/>
</div>
@ -42,3 +36,4 @@
target="_blank">Demo</a>
</div>
</div>

View file

@ -70,6 +70,11 @@
margin: 4.625rem 9% 0 6%;
}
ngx-default-admin-info,
ngx-material-admin-info {
padding: 0;
}
h1 {
font-family: 'Helvetica Neue Bold', sans-serif;
font-size: 4rem;

View file

@ -4,7 +4,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import { Component, OnDestroy } from '@angular/core';
import { Component, OnDestroy, Input } from '@angular/core';
import { NbMediaBreakpoint, NbMediaBreakpointsService, NbThemeService } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators';
@ -14,24 +14,31 @@ import { takeWhile } from 'rxjs/operators';
styleUrls: ['./main-info-section.component.scss'],
})
export class MainInfoSectionComponent implements OnDestroy {
private alive = true;
breakpoint: NbMediaBreakpoint;
breakpoints: any;
constructor(private themeService: NbThemeService,
private breakpointService: NbMediaBreakpointsService) {
this.breakpoints = this.breakpointService.getBreakpointsMap();
this.themeService.onMediaQueryChange()
constructor(themeService: NbThemeService, breakpointService: NbMediaBreakpointsService) {
this.breakpoints = breakpointService.getBreakpointsMap();
themeService.onMediaQueryChange()
.pipe(takeWhile(() => this.alive))
.subscribe(([oldValue, newValue]) => {
this.breakpoint = newValue;
});
}
ngOnDestroy() {
private alive = true;
public forMaterialTheme: boolean = false;
public readonly breakpoints: any;
public breakpoint: NbMediaBreakpoint;
@Input() public set material(value: any) {
this.forMaterialTheme = (value);
}
public get imageUrl(): string {
return this.forMaterialTheme !== false
? 'assets/img/ngx-admin-material.png'
: 'assets/img/ngx-admin.png';
}
public ngOnDestroy() {
this.alive = false;
}
}

View file

@ -0,0 +1,18 @@
<div>
<h1>material ngx-admin</h1>
<p class="description">
Material admin theme based on the most popular Angular dashboard template - <a href="https://hubs.ly/H0nJjJ00"
target="_blank">ngx-admin</a>.
Included: <strong>Angular 9+</strong>,
<a href="https://hubs.ly/H0n5N9P0" target="_blank">Nebular</a> and
<a href="https://hubs.ly/H0n5PKH0">Eva Design System</a>.
Free for personal and commercial usage.
<br>
<span class="bundles">
Get material ngx-admin integrated with backend technology of your choice.
<a href="https://hubs.ly/H0nJfXB0" target="_blank">
Check out our store.
</a>
</span>
</p>
</div>

View file

@ -0,0 +1,9 @@
import { Component } from '@angular/core';
@Component({
selector: 'ngx-material-admin-info',
templateUrl: './material-info.component.html',
styleUrls: ['./../main-info-section.component.scss'],
})
export class MaterialAdminInfoComponent {
}

View file

@ -0,0 +1,31 @@
<ngx-landing-section-title>
Features and benefits
</ngx-landing-section-title>
<ul class="features">
<li class="feature">
<div class="number">1</div>
<div class="description">
The most popular and trusted Angular open source dashboard template is out there. Used by hundreds of thousands developers worldwide and Fortune 500 companies*
</div>
</li>
<li class="feature">
<div class="number">2</div>
<div class="description">
Over 40+ Angular Components and 60+ Usage Examples. Kick off your project and save money by using ngx-admin.
</div>
</li>
<li class="feature">
<div class="number">3</div>
<div class="description">
Already using ngx-admin and willing to switch to material theme? Material theme is backward-compatible. Check out the article describing how to do that
</div>
</li>
<li class="feature">
<div class="number">4</div>
<div class="description">
ngx-admin material works perfectly with Angular Material and Nebular. Take the best from both!
</div>
</li>
</ul>

View file

@ -0,0 +1,104 @@
@import '../../../@theme/styles/themes';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
$features-section-offset: 10.625rem;
display: block;
padding: 5.25rem 0;
.features {
width: calc(100% - #{$features-section-offset} * 2);
margin: -1.375rem auto 0;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
padding: 0;
.feature {
display: flex;
width: 50%;
list-style: none;
padding-right: 3.75rem;
padding-left: 0.25rem;
margin-top: 7.875rem;
&:nth-child(2n) {
padding-right: 0;
padding-left: 3.75rem;
}
}
.number {
font-family: 'Helvetica Neue Bold', sans-serif;
font-size: 8.75rem;
color: #ffffff;
text-shadow: 0 0.5rem 1rem #dae0eb;
line-height: 0.3;
}
.description {
&::before {
content: '';
display: block;
height: 0.25rem;
width: 3.5rem;
margin-bottom: 0.375rem;
background-color: nb-theme(color-active-bg);
}
font-family: nb-theme(font-secondary), sans-serif;
font-size: nb-theme(font-size-lg);
line-height: 1.5;
margin-left: 1.75rem;
}
.highlight {
font-family: nb-theme(font-main), sans-serif;
}
.active {
text-decoration: none;
font-family: nb-theme(font-main), sans-serif;
color: nb-theme(color-active-fg);
}
}
@include media-breakpoint-down(xl) {
.features {
width: 100%;
padding: 0 1rem;
margin: 0;
.number {
font-size: 6rem;
}
}
}
@include media-breakpoint-down(sm) {
padding-top: 2.625rem;
padding-bottom: 0;
.features {
flex-direction: column;
.feature {
width: 100%;
margin: 1.625rem 0 0.375rem;
padding: 0;
&:nth-child(2n) {
padding: 0;
}
}
.number {
font-size: 5rem;
line-height: 1.3;
}
}
}
}

View file

@ -0,0 +1,13 @@
import {Component} from '@angular/core';
@Component({
selector: 'ngx-material-features',
templateUrl: './material-features.component.html',
styleUrls: ['./material-features.component.scss'],
})
export class MaterialFeaturesSectionComponent {
constructor() {
}
}

View file

@ -0,0 +1,16 @@
<nb-layout>
<nb-layout-header fixed>
<ngx-landing-header></ngx-landing-header>
</nb-layout-header>
<nb-layout-column class="main-section">
<ngx-landing-main-info material></ngx-landing-main-info>
<ngx-material-features></ngx-material-features>
<ngx-landing-theme-section material></ngx-landing-theme-section>
<ngx-contact-form></ngx-contact-form>
</nb-layout-column>
<nb-layout-footer class="footer" fixed>
<ngx-landing-footer></ngx-landing-footer>
</nb-layout-footer>
</nb-layout>

View file

@ -0,0 +1,34 @@
@import '../../../@theme/styles/themes';
@include nb-install-component() {
$content-width: nb-theme(content-width);
::ng-deep {
.version {
color: nb-theme(color-basic-500) !important;
}
ngx-landing-footer{
.h6, .copy {
color: #ffffff !important;
}
}
}
.main-section {
background-color: nb-theme(gray-section-bg);
}
ngx-material-features {
max-width: $content-width;
margin: 0 auto;
}
@include media-breakpoint-down(is) {
ngx-material-features {
max-width: 100%;
}
}
}

View file

@ -0,0 +1,16 @@
import { Component } from '@angular/core';
import { NbThemeService } from '@nebular/theme';
@Component({
selector: 'ngx-material-landing',
templateUrl: './material-landing.component.html',
styleUrls: [
'./material-landing.component.scss',
'../landing-home.component.scss',
],
})
export class MaterialLandingComponent {
constructor(private themeService: NbThemeService) {
this.themeService.changeTheme('ngx-landing-material');
}
}

View file

@ -7,37 +7,57 @@
[swiper]="swiperConfig"
[(index)]="sliderIndex">
<div class="swiper-wrapper">
<a href="https://hubs.ly/H0n54_z0" target="_blank" class="image-container swiper-slide">
<a [href]="materialLightDemoUrl" target="_blank" class="image-container swiper-slide">
<img *ngIf="breakpoint.width <= breakpoints.sm"
data-src="assets/img/material-light-theme.png"
class="swiper-lazy"
alt="Material Light Theme" />
<img *ngIf="!(breakpoint.width <= breakpoints.sm)"
lazyLoad="assets/img/material-light-theme.png"
defaultImage="assets/img/default.png"
alt="Material Light Theme" />
</a>
<a [href]="materialDarkDemoUrl" target="_blank" class="image-container swiper-slide">
<img *ngIf="breakpoint.width <= breakpoints.sm"
data-src="assets/img/material-dark-theme.png"
class="swiper-lazy"
alt="Material Dark Theme" />
<img *ngIf="!(breakpoint.width <= breakpoints.sm)"
lazyLoad="assets/img/material-dark-theme.png"
defaultImage="assets/img/default.png"
alt="Material Dark Theme" />
</a>
<a [href]="lightDemoUrl" target="_blank" class="image-container swiper-slide">
<img *ngIf="breakpoint.width <= breakpoints.sm"
data-src="assets/img/light-theme.png"
class="swiper-lazy"
alt="Light Theme" />
alt="Eva Light Theme" />
<img *ngIf="!(breakpoint.width <= breakpoints.sm)"
lazyLoad="assets/img/light-theme.png"
defaultImage="assets/img/default.png"
alt="Light Theme" />
alt="Eva Light Theme" />
</a>
<a href="https://hubs.ly/H0n54SN0" target="_blank" class="image-container swiper-slide">
<a [href]="darkDemoUrl" target="_blank" class="image-container swiper-slide">
<img *ngIf="breakpoint.width <= breakpoints.sm"
data-src="assets/img/dark-theme.png"
class="swiper-lazy"
alt="Dark Theme" />
alt="Eva Dark Theme" />
<img *ngIf="!(breakpoint.width <= breakpoints.sm)"
lazyLoad="assets/img/dark-theme.png"
defaultImage="assets/img/default.png"
alt="Dark Theme" />
src="assets/img/dark-theme.png"
alt="Eva Dark Theme"
class="ng-lazyloaded" />
</a>
<a href="https://hubs.ly/H0n55cG0" target="_blank" class="image-container swiper-slide">
<a [href]="cosmicDemoUrl" target="_blank" class="image-container swiper-slide">
<img *ngIf="breakpoint.width <= breakpoints.sm"
data-src="assets/img/cosmic-theme.png"
class="swiper-lazy"
alt="Cosmic Theme" />
<img *ngIf="!(breakpoint.width <= breakpoints.sm)"
lazyLoad="assets/img/cosmic-theme.png"
defaultImage="assets/img/default.png"
alt="Cosmic Theme" />
src="assets/img/cosmic-theme.png"
alt="Cosmic Theme"
class="ng-lazyloaded"/>
</a>
<a href="https://hubs.ly/H0n55170" target="_blank" class="image-container swiper-slide">
<a [href]="corporateDemoUrl" target="_blank" class="image-container swiper-slide">
<img *ngIf="breakpoint.width <= breakpoints.sm"
data-src="assets/img/corporate-theme.png"
class="swiper-lazy"
@ -52,10 +72,10 @@
<div class="swiper-pagination"></div>
<div class="swiper-button-prev">
<i [innerHTML]="'arrow-ios-back' | eva: { width: 36, height: 36, fill: '#00db92' }"></i>
<i [innerHTML]="'arrow-ios-back' | eva: { width: 36, height: 36, fill: iconColor }"></i>
</div>
<div class="swiper-button-next">
<i [innerHTML]="'arrow-ios-forward' | eva: { width: 36, height: 36, fill: '#00db92' }"></i>
<i [innerHTML]="'arrow-ios-forward' | eva: { width: 36, height: 36, fill: iconColor }"></i>
</div>
</div>
</div>

View file

@ -55,6 +55,10 @@
&:active {
box-shadow: nb-theme(shadow-active-btn);
}
&::after {
content: '';
}
}
.swiper-button-prev {
@ -93,7 +97,7 @@
span {
display: inline-block;
padding: 0.75rem 3.5rem;
padding: 0.75rem 1.5rem;
width: 100%;
}
@ -205,6 +209,7 @@
span {
padding: 0.75rem 0;
white-space: pre;
}
&.swiper-pagination-bullet-active {

View file

@ -4,7 +4,8 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import { Component, OnDestroy } from '@angular/core';
import { Component, OnDestroy, Input } from '@angular/core';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { SwiperConfigInterface } from 'ngx-swiper-wrapper';
import { takeWhile } from 'rxjs/operators';
import {
@ -21,9 +22,12 @@ import {
export class ThemeSectionComponent implements OnDestroy {
private alive = true;
private forMaterialTheme: boolean = false;
private themes: string[] = [
'Light',
'Dark',
'Material\nLight',
'Material\nDark',
'Eva\nLight',
'Eva\nDark',
'Cosmic',
'Corporate',
];
@ -32,6 +36,7 @@ export class ThemeSectionComponent implements OnDestroy {
breakpoints: any;
sliderIndex: number = 1;
initialSwiperConfig: SwiperConfigInterface = {
initialSlide: 1,
direction: 'horizontal',
spaceBetween: 200,
slidesPerView: 'auto',
@ -55,9 +60,7 @@ export class ThemeSectionComponent implements OnDestroy {
renderBullet: (index, className) => {
return `
<span class="${className}">
<span>
${this.themes[index]}
</span>
<span>${this.themes[index]}</span>
</span>`;
},
},
@ -66,8 +69,54 @@ export class ThemeSectionComponent implements OnDestroy {
...this.initialSwiperConfig,
};
constructor(private themeService: NbThemeService,
private breakpointService: NbMediaBreakpointsService) {
@Input() public set material(value: any) {
this.forMaterialTheme = coerceBooleanProperty(value);
}
public get iconColor(): string {
return this.forMaterialTheme ? '#6200ee' : '#00db92';
}
public get materialLightDemoUrl(): string {
return this.forMaterialTheme
? 'https://www.akveo.com/ngx-admin/pages/dashboard?theme=material-light&utm_campaign=ngx_admin%20-%20demo%20-%20ngx_admin%20docs&utm_source=ngx_admin&utm_medium=referral&utm_content=ngx_admin_material_themes_material_light'
: 'https://www.akveo.com/ngx-admin/pages/dashboard?theme=material-light&utm_campaign=ngx_admin%20-%20demo%20-%20ngx_admin%20docs&utm_source=ngx_admin&utm_medium=referral&utm_content=ngx_admin_landing_themes_material_light';
}
public get materialDarkDemoUrl(): string {
return this.forMaterialTheme
? 'https://www.akveo.com/ngx-admin/pages/dashboard?theme=material-dark&utm_campaign=ngx_admin%20-%20demo%20-%20ngx_admin%20docs&utm_source=ngx_admin&utm_medium=referral&utm_content=ngx_admin_material_themes_material_dark'
: 'https://www.akveo.com/ngx-admin/pages/dashboard?theme=material-dark&utm_campaign=ngx_admin%20-%20demo%20-%20ngx_admin%20docs&utm_source=ngx_admin&utm_medium=referral&utm_content=ngx_admin_landing_themes_material_dark';
}
public get lightDemoUrl(): string {
return this.forMaterialTheme
? 'https://www.akveo.com/ngx-admin/pages/dashboard?theme=default&utm_campaign=ngx_admin%20-%20demo%20-%20ngx_admin%20docs&utm_source=ngx_admin&utm_medium=referral&utm_content=ngx_admin_material_themes_default'
: 'https://www.akveo.com/ngx-admin/pages/dashboard?theme=default&utm_campaign=ngx_admin%20-%20demo%20-%20ngx_admin%20docs&utm_source=ngx_admin&utm_medium=referral&utm_content=ngx_admin_landing_themes_default';
}
public get darkDemoUrl(): string {
return this.forMaterialTheme
? 'https://www.akveo.com/ngx-admin/pages/dashboard?theme=dark&utm_campaign=ngx_admin%20-%20demo%20-%20ngx_admin%20docs&utm_source=ngx_admin&utm_medium=referral&utm_content=ngx_admin_material_themes_dark'
: 'https://www.akveo.com/ngx-admin/pages/dashboard?theme=dark&utm_campaign=ngx_admin%20-%20demo%20-%20ngx_admin%20docs&utm_source=ngx_admin&utm_medium=referral&utm_content=ngx_admin_landing_themes_dark';
}
public get cosmicDemoUrl(): string {
return this.forMaterialTheme
? 'https://www.akveo.com/ngx-admin/pages/dashboard?theme=cosmic&utm_campaign=ngx_admin%20-%20demo%20-%20ngx_admin%20docs&utm_source=ngx_admin&utm_medium=referral&utm_content=ngx_admin_material_themes_cosmic'
: 'https://www.akveo.com/ngx-admin/pages/dashboard?theme=cosmic&utm_campaign=ngx_admin%20-%20demo%20-%20ngx_admin%20docs&utm_source=ngx_admin&utm_medium=referral&utm_content=ngx_admin_landing_themes_cosmic';
}
public get corporateDemoUrl(): string {
return this.forMaterialTheme
? 'https://www.akveo.com/ngx-admin/pages/dashboard?theme=corporate&utm_campaign=ngx_admin%20-%20demo%20-%20ngx_admin%20docs&utm_source=ngx_admin&utm_medium=referral&utm_content=ngx_admin_material_themes_corporate'
: 'https://www.akveo.com/ngx-admin/pages/dashboard?theme=corporate&utm_campaign=ngx_admin%20-%20demo%20-%20ngx_admin%20docs&utm_source=ngx_admin&utm_medium=referral&utm_content=ngx_admin_landing_themes_corporate';
}
constructor(
private themeService: NbThemeService,
private breakpointService: NbMediaBreakpointsService,
) {
this.breakpoints = this.breakpointService.getBreakpointsMap();
this.themeService.onMediaQueryChange()
.pipe(takeWhile(() => this.alive))

View file

@ -0,0 +1,15 @@
<a
routerLink="/material"
class="eva-parent-hover"
[nbPopover]="popoverContent"
nbPopoverPlacement="bottom"
nbPopoverTrigger="noop"
>
<i [innerHTML]="'color-palette-outline' | eva: { width: 24, height: 24, fill: '#ff4d6b', animationType: 'shake' }"
></i>
Material Theme
</a>
<ng-template #popoverContent>
<p class="material-theme-popover" (mouseover)="hidePopover()">New theme is available!</p>
</ng-template>

View file

@ -0,0 +1,22 @@
:host {
display: flex;
align-items: center;
padding-right: 32px;
}
a {
display: flex;
align-items: center;
}
i {
margin-right: 8px;
}
.material-theme-popover {
margin: 0;
padding: 1rem 2rem;
color: #ff4d6b;
font-weight: 600;
font-size: 1.1rem;
}

View file

@ -0,0 +1,26 @@
import { Component, ViewChild, AfterViewInit, Input } from '@angular/core';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { NbPopoverDirective } from '@nebular/theme';
@Component({
selector: 'ngx-material-theme-link',
templateUrl: './material-theme-link.component.html',
styleUrls: ['./material-theme-link.component.scss'],
})
export class MaterialThemeLinkComponent implements AfterViewInit {
public showPopover: boolean = false;
@Input() public set withPopover(value: any) {
this.showPopover = coerceBooleanProperty(value);
}
@ViewChild(NbPopoverDirective, { static: true }) public popover: NbPopoverDirective;
public ngAfterViewInit(): void {
this.showPopover && this.popover && this.popover.show();
}
public hidePopover(): void {
this.popover && this.popover.hide();
}
}

View file

@ -0,0 +1,16 @@
import { NgModule } from '@angular/core';
import { NbPopoverModule } from '@nebular/theme';
import { MaterialThemeLinkComponent } from './components/material-theme-link/material-theme-link.component';
import { CapitalizePipe } from './pipes/capitalize.pipe';
import { EvaIconsPipe } from './pipes/eva-icons.pipe';
import { RouterModule } from '@angular/router';
const component = [MaterialThemeLinkComponent];
const pipes = [CapitalizePipe, EvaIconsPipe];
@NgModule({
imports: [RouterModule, NbPopoverModule],
declarations: [...component, ...pipes],
exports: [NbPopoverModule, ...component, ...pipes],
})
export class LandingSharedModule {}

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View file

@ -1,19 +1,8 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"sourceMap": true,
"declaration": false,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"es2017",
"dom"
],
"outDir": "../out-tsc/app",
"module": "es2015",
"baseUrl": ".",
"types": []
"baseUrl": "."
},
"exclude": [
"test.ts",

8
docs/typings.d.ts vendored
View file

@ -5,9 +5,11 @@
*/
/* SystemJS module definition */
declare var module: {
declare var module: NodeModule;
interface NodeModule {
id: string;
};
declare var require: any;
}
declare var require: NodeRequire;
declare var structure: any;
declare var docs: any;

14573
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -48,30 +48,30 @@
"@angular/router": "^9.0.4",
"@asymmetrik/ngx-leaflet": "3.0.1",
"@nebular/auth": "5.0.0",
"@nebular/bootstrap": "5.0.0",
"@nebular/bootstrap": "^5.0.0",
"@nebular/eva-icons": "5.0.0",
"@nebular/security": "5.0.0",
"@nebular/theme": "5.0.0",
"@swimlane/ngx-charts": "^13.0.2",
"angular2-chartjs": "0.4.1",
"bootstrap": "4.3.1",
"bootstrap": "^4.4.1",
"chart.js": "2.7.1",
"ckeditor": "4.7.3",
"classlist.js": "1.1.20150312",
"core-js": "2.5.1",
"echarts": "^4.0.2",
"eva-icons": "^1.1.3",
"highlight.js": "^9.13.1",
"highlight.js": "^9.18.1",
"intl": "1.2.5",
"ionicons": "2.0.1",
"leaflet": "1.2.0",
"marked": "^0.5.2",
"nebular-icons": "1.1.0",
"ng-lazyload-image": "5.0.0",
"ng-lazyload-image": "^7.1.0",
"ng2-ckeditor": "^1.2.2",
"ng2-smart-table": "^1.6.0",
"ngx-echarts": "^4.2.2",
"ngx-swiper-wrapper": "^7.1.1",
"ngx-swiper-wrapper": "^9.0.1",
"node-sass": "^4.12.0",
"normalize.css": "6.0.0",
"pace-js": "1.0.2",
@ -79,7 +79,6 @@
"rxjs": "6.5.4",
"rxjs-compat": "6.3.0",
"socicon": "3.0.5",
"style-loader": "^1.1.3",
"tinymce": "4.5.7",
"tslib": "^1.10.0",
"typeface-exo": "0.0.22",
@ -99,7 +98,7 @@
"@types/jasminewd2": "2.0.3",
"@types/leaflet": "1.2.3",
"@types/node": "^12.11.1",
"angular-cli-ghpages": "0.5.0",
"angular-cli-ghpages": "^0.6.2",
"codelyzer": "^5.1.2",
"conventional-changelog-cli": "1.3.4",
"husky": "0.13.3",
@ -114,6 +113,7 @@
"npm-run-all": "4.0.2",
"protractor": "5.1.2",
"rimraf": "2.6.1",
"style-loader": "^1.1.3",
"stylelint": "7.13.0",
"ts-node": "3.2.2",
"tslint": "^5.7.0",

View file

@ -55,6 +55,8 @@ import { SecurityCamerasService } from './mock/security-cameras.service';
import { RippleService } from './utils/ripple.service';
import { MockDataModule } from './mock/mock-data.module';
import { AbService } from './utils/ab.service';
import {CurrentThemeService} from './utils/theme.service';
import {ThemeGuard} from './guard/theme.guard';
const socialLinks = [
{
@ -97,6 +99,10 @@ const DATA_SERVICES = [
{provide: MAT_RIPPLE_GLOBAL_OPTIONS, useExisting: RippleService},
];
const GUARDS = [
ThemeGuard,
];
export class NbSimpleRoleProvider extends NbRoleProvider {
getRole() {
// here you could provide any role based on any auth flow
@ -107,6 +113,7 @@ export class NbSimpleRoleProvider extends NbRoleProvider {
export const NB_CORE_PROVIDERS = [
...MockDataModule.forRoot().providers,
...DATA_SERVICES,
...GUARDS,
...NbAuthModule.forRoot({
strategies: [
@ -148,6 +155,7 @@ export const NB_CORE_PROVIDERS = [
SeoService,
StateService,
AbService,
CurrentThemeService,
];
@NgModule({

View file

@ -0,0 +1,26 @@
import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router';
import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';
import {CurrentThemeService} from '../utils/theme.service';
@Injectable()
export class ThemeGuard implements CanActivate {
constructor(private router: Router,
private currentThemeService: CurrentThemeService) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot,
): Observable<boolean> | Promise<boolean> | boolean {
return this.currentThemeService.currentTheme$.pipe(
map(theme => {
const currentThemeExpiration = JSON.parse(theme).expires_in;
const currentDate = new Date().getTime();
if (!theme || currentDate > currentThemeExpiration) {
this.router.navigate(['themes']);
}
return true;
}));
}
}

View file

@ -0,0 +1,33 @@
import {Injectable, OnDestroy} from '@angular/core';
import {Observable} from 'rxjs';
import {takeWhile} from 'rxjs/operators';
import {environment} from '../../../environments/environment';
@Injectable()
export class CurrentThemeService implements OnDestroy {
alive = true;
readonly currentTheme$: Observable<any> = new Observable(subscriber => {
subscriber.next(localStorage.theme);
}).pipe(takeWhile(() => this.alive));
setCurrentTheme(themeName: string): void {
const currentTheme = {
themeName: themeName,
expires_in: this.calculateExpiration(environment.currentThemeLife),
};
localStorage.setItem('theme', JSON.stringify(currentTheme));
}
calculateExpiration(iat: number): number {
const currentDate = new Date().getTime();
const timestamp = iat || Math.floor(Date.now() / 1000);
return Math.floor(timestamp + currentDate);
}
ngOnDestroy(): void {
this.alive = false;
}
}

View file

@ -38,7 +38,7 @@
<nb-icon icon="download"></nb-icon>
<span class="subtitle number">470.000</span>
</nb-action>
<nb-action class="control-item contact-us">
<nb-action class="control-item contact-us" matRipple [matRippleUnbounded]="false" [matRippleCentered]="true">
<a nbButton ghost href="mailto:contact@akveo.com" (click)="trackEmailClick()">
<nb-icon icon="email-outline" pack="eva"></nb-icon>
<span>contact@akveo.com</span>
@ -52,9 +52,9 @@
[matRippleCentered]="true">
</nb-search>
</nb-action>
<nb-action class="control-item email" icon="email-outline"></nb-action>
<nb-action class="control-item notifications" icon="bell-outline"></nb-action>
<nb-action class="user-action" *nbIsGranted="['view', 'user']" >
<nb-action class="control-item email" icon="email-outline" matRipple [matRippleUnbounded]="true" [matRippleCentered]="true"></nb-action>
<nb-action class="control-item notifications" icon="bell-outline" matRipple [matRippleUnbounded]="true" [matRippleCentered]="true"></nb-action>
<nb-action class="user-action" *nbIsGranted="['view', 'user']" matRipple [matRippleUnbounded]="false" [matRippleCentered]="true">
<nb-user [nbContextMenu]="userMenu"
[onlyPicture]="userPictureOnly"
[name]="user?.name"

View file

@ -6,6 +6,7 @@ import { AnalyticsService, LayoutService } from '../../../@core/utils';
import { map, takeUntil } from 'rxjs/operators';
import { Subject, Observable } from 'rxjs';
import { RippleService } from '../../../@core/utils/ripple.service';
import {CurrentThemeService} from '../../../@core/utils/theme.service';
@Component({
selector: 'ngx-header',
@ -57,6 +58,7 @@ export class HeaderComponent implements OnInit, OnDestroy {
private layoutService: LayoutService,
private breakpointService: NbMediaBreakpointsService,
private rippleService: RippleService,
private currentThemeService: CurrentThemeService,
private analytics: AnalyticsService,
) {
this.materialTheme$ = this.themeService.onThemeChange()
@ -98,6 +100,7 @@ export class HeaderComponent implements OnInit, OnDestroy {
}
changeTheme(themeName: string) {
this.currentThemeService.setCurrentTheme(themeName);
this.themeService.changeTheme(themeName);
}

View file

@ -8,16 +8,24 @@ import {
NbRequestPasswordComponent,
NbResetPasswordComponent,
} from '@nebular/auth';
import {ThemeGuard} from './@core/guard/theme.guard';
export const routes: Routes = [
{
path: 'pages',
canActivate: [ThemeGuard],
loadChildren: () => import('./pages/pages.module')
.then(m => m.PagesModule),
},
{
path: 'themes',
loadChildren: () => import('app/themes-screen/starter.module')
.then(m => m.StarterModule),
},
{
path: 'auth',
component: NbAuthComponent,
canActivate: [ThemeGuard],
children: [
{
path: '',
@ -45,8 +53,8 @@ export const routes: Routes = [
},
],
},
{ path: '', redirectTo: 'pages', pathMatch: 'full' },
{ path: '**', redirectTo: 'pages' },
{ path: '', redirectTo: 'themes', pathMatch: 'full' },
{ path: '**', redirectTo: 'themes' },
];
const config: ExtraOptions = {

View file

@ -0,0 +1,21 @@
import {NgModule} from '@angular/core';
import {RouterModule, Routes} from '@angular/router';
import {NgxStarterComponent} from './starter.component';
const routes: Routes = [{
path: '',
component: NgxStarterComponent,
children: [
{
path: '',
component: NgxStarterComponent,
},
],
}];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class StarterRoutingModule {
}

View file

@ -0,0 +1,53 @@
<nb-layout windowMode>
<nb-layout-header fixed>
<div class="header-container">
<div class="logo-container">
<p class="logo">ngx-<span>admin</span></p>
</div>
</div>
<div class="header-container">
<nb-actions size="small">
<nb-action class="control-item github-stars">
<span class="subtitle text">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 class="control-item downloads-count">
<nb-icon icon="download"></nb-icon>
<span class="subtitle number">470.000</span>
</nb-action>
<nb-action class="control-item contact-us" (click)="trackEmailClick()">
<a nbButton ghost href="mailto:contact@akveo.com">
<nb-icon icon="email-outline" pack="eva"></nb-icon>
<span>contact@akveo.com</span>
</a>
</nb-action>
</nb-actions>
</div>
</nb-layout-header>
<nb-layout-column>
<h4>Choose theme</h4>
<ng-container *ngFor="let theme of themes">
<nb-card (click)="navigate(theme.value)">
<nb-card-header>{{theme.name}}</nb-card-header>
<nb-card-body>
<img src="../../assets/images/{{theme.value}}-theme.png"
class="theme-preview"
alt="{{theme.name}} Theme"/>
</nb-card-body>
</nb-card>
</ng-container>
</nb-layout-column>
<nb-layout-footer fixed>
<ngx-footer></ngx-footer>
</nb-layout-footer>
</nb-layout>

View file

@ -0,0 +1,174 @@
@import '~bootstrap/scss/mixins/breakpoints';
@import '~@nebular/theme/styles/global/breakpoints';
@import '../@theme/styles/themes';
@include nb-install-component() {
img {
width: 100%;
object-fit: contain;
height: auto;
vertical-align: top;
}
h4 {
text-align: center;
width: 100%;
height: 35px;
margin-bottom: 36px;
}
nb-layout-column {
display: flex;
align-items: flex-start;
flex-wrap: wrap;
justify-content: space-between;
align-content: flex-start;
}
nb-card {
overflow: hidden;
cursor: pointer;
width: 32%;
}
nb-card-body {
padding: 0;
}
nb-layout-header {
display: flex;
justify-content: space-between;
width: 100%;
::ng-deep nav {
width: 100%;
justify-content: space-between;
}
.logo-container {
display: flex;
align-items: center;
width: calc(#{nb-theme(sidebar-width)} - #{nb-theme(header-padding)});
}
nb-action {
height: auto;
display: flex;
align-content: center;
}
.subtitle {
font-family: nb-theme(text-subtitle-font-family);
font-size: nb-theme(text-subtitle-font-size);
font-weight: nb-theme(text-subtitle-font-weight);
line-height: nb-theme(text-subtitle-line-height);
}
.downloads-count .number {
@include nb-ltr(margin-left, 0.5rem);
@include nb-rtl(margin-right, 0.5rem);
}
::ng-deep nb-search button {
padding: 0 !important;
}
.contact-us {
padding: 0;
nb-icon {
font-size: 1.25rem;
}
}
.header-container {
display: flex;
align-items: center;
width: auto;
.logo {
padding: 0 1.25rem;
font-size: 1.75rem;
margin-bottom: 0.5rem;
@include nb-rtl(border-right, 1px solid nb-theme(divider-color));
white-space: nowrap;
text-decoration: none;
}
}
.github-stars {
width: 245px;
display: flex;
iframe {
width: 100px;
@include nb-ltr(margin-left, 1rem);
@include nb-rtl(margin-right, 1rem);
}
}
@include media-breakpoint-down(xl) {
.control-item.github-stars .text {
display: none;
}
.control-item.github-stars {
width: auto;
iframe {
margin: 0;
}
}
}
@include media-breakpoint-down(lg) {
.downloads-count {
display: none;
}
}
@include media-breakpoint-down(md) {
}
@include media-breakpoint-down(sm) {
.contact-us {
display: none;
}
}
@include media-breakpoint-down(is) {
.github-stars {
display: none;
}
}
}
@include media-breakpoint-down(xl) {
}
@include media-breakpoint-down(lg) {
nb-card-header {
padding: 12px 20px;
}
nb-card {
width: 48%;
}
}
@include media-breakpoint-down(md) {
}
@include media-breakpoint-down(sm) {
nb-card-header {
padding: 10px 20px;
}
}
@include media-breakpoint-down(is) {
nb-card {
width: 100%;
}
}
}

View file

@ -0,0 +1,61 @@
import {Component, OnDestroy} from '@angular/core';
import {NbMediaBreakpoint, NbThemeService} from '@nebular/theme';
import {Router} from '@angular/router';
import {AnalyticsService} from '../@core/utils';
import {CurrentThemeService} from '../@core/utils/theme.service';
@Component({
selector: 'ngx-starter',
templateUrl: './starter.component.html',
styleUrls: ['./starter.component.scss'],
})
export class NgxStarterComponent implements OnDestroy {
breakpoint: NbMediaBreakpoint;
breakpoints: any;
themes = [
{
value: 'material-light',
name: 'Material Light',
},
{
value: 'dark',
name: 'Dark',
},
{
value: 'default',
name: 'Light',
},
{
value: 'material-dark',
name: 'Material Dark',
},
{
value: 'corporate',
name: 'Corporate',
},
{
value: 'cosmic',
name: 'Cosmic',
},
];
constructor(private router: Router,
private themeService: NbThemeService,
private currentThemeService: CurrentThemeService,
private analytics: AnalyticsService,
) {}
navigate(themeName: string) {
this.currentThemeService.setCurrentTheme(themeName);
this.themeService.changeTheme(themeName);
this.router.navigate(['/pages/dashboard'], {queryParams: {theme: themeName}});
}
trackEmailClick() {
this.analytics.trackEvent('clickContactEmail', 'click');
}
ngOnDestroy() {
}
}

View file

@ -0,0 +1,27 @@
import {NgModule} from '@angular/core';
import {StarterRoutingModule} from './starter-routing.module';
import {NgxStarterComponent} from './starter.component';
import {NbActionsModule, NbButtonModule, NbCardModule, NbIconModule, NbLayoutModule} from '@nebular/theme';
import {ThemeModule} from '../@theme/theme.module';
const NB_MODULES = [
NbIconModule,
NbLayoutModule,
NbCardModule,
NbButtonModule,
];
@NgModule({
imports: [
StarterRoutingModule,
...NB_MODULES,
ThemeModule,
NbActionsModule,
],
declarations: [
NgxStarterComponent,
NgxStarterComponent,
],
})
export class StarterModule {
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 958 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

View file

@ -5,4 +5,5 @@
*/
export const environment = {
production: true,
currentThemeLife: 604800000, // 1 week in milliseconds
};

View file

@ -10,4 +10,5 @@
export const environment = {
production: false,
currentThemeLife: 604800000, // 1 week in milliseconds
};