Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f2372cc08 | ||
|
|
6f315aa38e | ||
|
|
0653b5f36b | ||
|
|
f13120bc01 | ||
|
|
a6c56518bc | ||
|
|
ecae48f3d0 | ||
|
|
c74751e0f4 | ||
|
|
2b755fa669 | ||
|
|
ca0f46b414 | ||
|
|
528fa31df6 | ||
|
|
abfb2a6706 | ||
|
|
b1ab11393e | ||
|
|
786883eb10 |
749
package-lock.json
generated
50
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "fuse2",
|
||||
"version": "1.3.0",
|
||||
"version": "1.3.1",
|
||||
"license": "https://themeforest.net/licenses/terms/regular",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
@@ -16,24 +16,24 @@
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@agm/core": "1.0.0-beta.2",
|
||||
"@angular/animations": "5.1.1",
|
||||
"@angular/cdk": "5.0.1",
|
||||
"@angular/common": "5.1.1",
|
||||
"@angular/compiler": "5.1.1",
|
||||
"@angular/core": "5.1.1",
|
||||
"@angular/flex-layout": "2.0.0-beta.10-4905443",
|
||||
"@angular/forms": "5.1.1",
|
||||
"@angular/http": "5.1.1",
|
||||
"@angular/material": "5.0.1",
|
||||
"@angular/material-moment-adapter": "5.0.1",
|
||||
"@angular/platform-browser": "5.1.1",
|
||||
"@angular/platform-browser-dynamic": "5.1.1",
|
||||
"@angular/router": "5.1.1",
|
||||
"@ngx-translate/core": "9.0.1",
|
||||
"@angular/animations": "5.1.2",
|
||||
"@angular/cdk": "5.0.2",
|
||||
"@angular/common": "5.1.2",
|
||||
"@angular/compiler": "5.1.2",
|
||||
"@angular/core": "5.1.2",
|
||||
"@angular/flex-layout": "2.0.0-beta.12",
|
||||
"@angular/forms": "5.1.2",
|
||||
"@angular/http": "5.1.2",
|
||||
"@angular/material": "5.0.2",
|
||||
"@angular/material-moment-adapter": "5.0.2",
|
||||
"@angular/platform-browser": "5.1.2",
|
||||
"@angular/platform-browser-dynamic": "5.1.2",
|
||||
"@angular/router": "5.1.2",
|
||||
"@ngx-translate/core": "9.0.2",
|
||||
"@swimlane/ngx-charts": "7.0.1",
|
||||
"@swimlane/ngx-datatable": "11.1.5",
|
||||
"@swimlane/ngx-datatable": "11.1.7",
|
||||
"@swimlane/ngx-dnd": "3.1.0",
|
||||
"angular-calendar": "0.22.1",
|
||||
"angular-calendar": "0.23.0",
|
||||
"angular-in-memory-web-api": "0.5.2",
|
||||
"angular2-markdown": "1.6.0",
|
||||
"classlist.js": "1.1.20150312",
|
||||
@@ -42,34 +42,34 @@
|
||||
"hammerjs": "2.0.8",
|
||||
"highlight.js": "9.12.0",
|
||||
"intl": "1.2.5",
|
||||
"moment": "2.19.3",
|
||||
"moment": "2.20.1",
|
||||
"@ngrx/effects": "4.1.1",
|
||||
"@ngrx/router-store": "4.1.1",
|
||||
"@ngrx/store": "4.1.1",
|
||||
"@ngrx/store-devtools": "4.1.1",
|
||||
"ngrx-store-freeze": "0.2.0",
|
||||
"ngx-color-picker": "5.1.0",
|
||||
"ngx-color-picker": "5.3.0",
|
||||
"ngx-cookie-service": "1.0.9",
|
||||
"perfect-scrollbar": "1.3.0",
|
||||
"rxjs": "5.5.5",
|
||||
"rxjs": "5.5.6",
|
||||
"web-animations-js": "2.3.1",
|
||||
"zone.js": "0.8.18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/cli": "1.6.1",
|
||||
"@angular/compiler-cli": "5.1.1",
|
||||
"@angular/language-service": "5.1.1",
|
||||
"@angular/cli": "1.6.2",
|
||||
"@angular/compiler-cli": "5.1.2",
|
||||
"@angular/language-service": "5.1.2",
|
||||
"@angularclass/hmr": "2.1.3",
|
||||
"@types/jasmine": "2.5.54",
|
||||
"@types/jasminewd2": "2.0.3",
|
||||
"@types/node": "6.0.94",
|
||||
"@types/node": "6.0.95",
|
||||
"codelyzer": "4.0.2",
|
||||
"jasmine-core": "2.6.4",
|
||||
"jasmine-spec-reporter": "4.1.1",
|
||||
"karma": "1.7.1",
|
||||
"karma-chrome-launcher": "2.1.1",
|
||||
"karma-cli": "1.0.1",
|
||||
"karma-coverage-istanbul-reporter": "1.3.0",
|
||||
"karma-coverage-istanbul-reporter": "1.3.1",
|
||||
"karma-jasmine": "1.1.1",
|
||||
"karma-jasmine-html-reporter": "0.2.2",
|
||||
"protractor": "5.1.2",
|
||||
|
||||
@@ -44,6 +44,10 @@ const appRoutes: Routes = [
|
||||
path : 'apps/e-commerce',
|
||||
loadChildren: './main/content/apps/e-commerce/e-commerce.module#FuseEcommerceModule'
|
||||
},
|
||||
{
|
||||
path : 'apps/academy',
|
||||
loadChildren: './main/content/apps/academy/academy.module#FuseAcademyModule'
|
||||
},
|
||||
{
|
||||
path : 'apps/todo',
|
||||
loadChildren: './main/content/apps/todo/todo.module#FuseTodoModule'
|
||||
|
||||
@@ -76,6 +76,53 @@ export const fuseAnimations = [
|
||||
transition('0 => 1', animate('300ms ease-in'))
|
||||
]),
|
||||
|
||||
trigger('slideIn', [
|
||||
transition('void => left', [
|
||||
style({
|
||||
transform: 'translateX(100%)'
|
||||
}),
|
||||
animate('300ms ease-in',
|
||||
style({
|
||||
transform: 'translateX(0)'
|
||||
})
|
||||
)
|
||||
]
|
||||
),
|
||||
transition('left => void', [
|
||||
style({
|
||||
transform: 'translateX(0)'
|
||||
}),
|
||||
animate('300ms ease-in',
|
||||
style({
|
||||
transform: 'translateX(-100%)'
|
||||
})
|
||||
)
|
||||
]
|
||||
),
|
||||
transition('void => right', [
|
||||
style({
|
||||
transform: 'translateX(-100%)'
|
||||
}),
|
||||
animate('300ms ease-in',
|
||||
style({
|
||||
transform: 'translateX(0)'
|
||||
})
|
||||
)
|
||||
]
|
||||
),
|
||||
transition('right => void', [
|
||||
style({
|
||||
transform: 'translateX(0)'
|
||||
}),
|
||||
animate('300ms ease-in',
|
||||
style({
|
||||
transform: 'translateX(100%)'
|
||||
})
|
||||
)
|
||||
]
|
||||
),
|
||||
]),
|
||||
|
||||
trigger('slideInLeft', [
|
||||
state('void', style({
|
||||
transform: 'translateX(-100%)',
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Platform } from '@angular/cdk/platform';
|
||||
@Directive({
|
||||
selector: '[fusePerfectScrollbar]'
|
||||
})
|
||||
export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnDestroy
|
||||
export class FusePerfectScrollbarDirective implements AfterViewInit, OnDestroy
|
||||
{
|
||||
onSettingsChanged: Subscription;
|
||||
isDisableCustomScrollbars = false;
|
||||
@@ -16,7 +16,7 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD
|
||||
ps;
|
||||
|
||||
constructor(
|
||||
private element: ElementRef,
|
||||
public element: ElementRef,
|
||||
private fuseConfig: FuseConfigService,
|
||||
private platform: Platform
|
||||
)
|
||||
@@ -35,11 +35,6 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ngAfterViewInit()
|
||||
{
|
||||
if ( this.isMobile || this.isDisableCustomScrollbars )
|
||||
@@ -49,7 +44,9 @@ export class FusePerfectScrollbarDirective implements OnInit, AfterViewInit, OnD
|
||||
}
|
||||
|
||||
// Initialize the perfect-scrollbar
|
||||
this.ps = new PerfectScrollbar(this.element.nativeElement);
|
||||
this.ps = new PerfectScrollbar(this.element.nativeElement, {
|
||||
wheelPropagation: true
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
|
||||
@@ -34,7 +34,7 @@ export class FuseConfigService
|
||||
footer : 'mat-fuse-dark-900-bg'
|
||||
},
|
||||
customScrollbars: true,
|
||||
routerAnimation : 'fadeIn' // fadeIn, slideUp, slideDown, slideRight, slideLeft
|
||||
routerAnimation : 'fadeIn' // fadeIn, slideUp, slideDown, slideRight, slideLeft, none
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
773
src/app/fuse-fake-db/academy.ts
Normal file
@@ -0,0 +1,773 @@
|
||||
export class AcademyFakeDb
|
||||
{
|
||||
public static courses = [
|
||||
{
|
||||
'id' : '15459251a6d6b397565',
|
||||
'title' : 'Basics of Angular',
|
||||
'slug' : 'basics-of-angular',
|
||||
'category': 'web',
|
||||
'length' : 30,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '154588a0864d2881124',
|
||||
'title' : 'Basics of TypeScript',
|
||||
'slug' : 'basics-of-typeScript',
|
||||
'category': 'web',
|
||||
'length' : 60,
|
||||
'updated' : 'Nov 01, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '15453ba60d3baa5daaf',
|
||||
'title' : 'Android N: Quick Settings',
|
||||
'slug' : 'android-n-quick-settings',
|
||||
'category': 'android',
|
||||
'length' : 120,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '15453a06c08fb021776',
|
||||
'title' : 'Keep Sensitive Data Safe and Private',
|
||||
'slug' : 'keep-sensitive-data-safe-and-private',
|
||||
'category': 'android',
|
||||
'length' : 45,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '15427f4c1b7f3953234',
|
||||
'title' : 'Building a gRPC Service with Java',
|
||||
'slug' : 'building-a-grpc-service-with-java',
|
||||
'category': 'cloud',
|
||||
'length' : 30,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1542d75d929a603125',
|
||||
'title' : 'Build a PWA Using Workbox',
|
||||
'slug' : 'build-a-pwa-using-workbox',
|
||||
'category': 'web',
|
||||
'length' : 120,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1543ee3a5b43e0f9f45',
|
||||
'title' : 'Build an App for the Google Assistant with Firebase and Dialogflow',
|
||||
'slug' : 'build-an-app-for-the-google-assistant-with-firebase-and-dialogflow',
|
||||
'category': 'firebase',
|
||||
'length' : 30,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1543cc4515df3146112',
|
||||
'title' : 'Cloud Functions for Firebase',
|
||||
'slug' : 'cloud-functions-for-firebase',
|
||||
'category': 'firebase',
|
||||
'length' : 45,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '154398a4770d7aaf9a2',
|
||||
'title' : 'Manage Your Pivotal Cloud Foundry App\'s Using Apigee Edge',
|
||||
'slug' : 'manage-your-pivotal-cloud-foundry-apps-using-apigee-Edge',
|
||||
'category': 'cloud',
|
||||
'length' : 90,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '15438351f87dcd68567',
|
||||
'title' : 'Building Beautiful UIs with Flutter',
|
||||
'your' : 'building-beautiful-uis-with-flutter',
|
||||
'category': 'web',
|
||||
'length' : 90,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1544e43dcdae6ebf876',
|
||||
'title' : 'Cloud Firestore',
|
||||
'slug' : 'cloud-firestore',
|
||||
'category': 'firebase',
|
||||
'length' : 90,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1541ca7af66da284177',
|
||||
'title' : 'Customize Network Topology with Subnetworks',
|
||||
'slug' : 'customize-network-topology-with-subnetworks',
|
||||
'category': 'web',
|
||||
'length' : 45,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '154297167e781781745',
|
||||
'title' : 'Looking at Campaign Finance with BigQuery',
|
||||
'slug' : 'looking-at-campaign-finance-with-bigquery',
|
||||
'category': 'cloud',
|
||||
'length' : 60,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '154537435d5b32bf11a',
|
||||
'title' : 'Firebase Android',
|
||||
'slug' : 'firebase-android',
|
||||
'category': 'android',
|
||||
'length' : 45,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '154204e45a59b168453',
|
||||
'title' : 'Simulating a Thread Network Using OpenThread',
|
||||
'slug' : 'simulating-a-thread-network-using-openthread',
|
||||
'category': 'web',
|
||||
'length' : 45,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1541dd1e05dfc439216',
|
||||
'title' : 'Your First Progressive Web App',
|
||||
'slug' : 'your-first-progressive-web-app',
|
||||
'category': 'web',
|
||||
'length' : 30,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1532dfc67e704e48515',
|
||||
'title' : 'Launch Cloud Datalab',
|
||||
'slug' : 'launch-cloud-datalab',
|
||||
'category': 'cloud',
|
||||
'length' : 60,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
},
|
||||
{
|
||||
'id' : '1542e43dfaae6ebf226',
|
||||
'title' : 'Personalize Your iOS App with Firebase User Management',
|
||||
'slug' : 'personalize-your-ios-app-with-firebase-user-management',
|
||||
'category': 'firebase',
|
||||
'length' : 90,
|
||||
'updated' : 'Jun 28, 2017'
|
||||
}
|
||||
];
|
||||
|
||||
public static categories = [
|
||||
{
|
||||
'id' : 0,
|
||||
'value': 'web',
|
||||
'label': 'Web'
|
||||
},
|
||||
{
|
||||
'id' : 1,
|
||||
'value': 'firebase',
|
||||
'label': 'Firebase'
|
||||
},
|
||||
{
|
||||
'id' : 2,
|
||||
'value': 'cloud',
|
||||
'label': 'Cloud'
|
||||
},
|
||||
{
|
||||
'id' : 3,
|
||||
'value': 'android',
|
||||
'label': 'Android'
|
||||
}
|
||||
];
|
||||
|
||||
private static demoSteps = [
|
||||
{
|
||||
'title' : 'Introduction',
|
||||
'content': '<h1>Step 1 - Introduction</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Get the sample code',
|
||||
'content': '<h1>Step 2 - Get the sample code</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Create a Firebase project and Set up your app',
|
||||
'content': '<h1>Step 3 - Create a Firebase project and Set up your app</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Install the Firebase Command Line Interface',
|
||||
'content': '<h1>Step 4 - Install the Firebase Command Line Interface</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Deploy and run the web app',
|
||||
'content': '<h1>Step 5 - Deploy and run the web app</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'The Functions Directory',
|
||||
'content': '<h1>Step 6 - The Functions Directory</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Import the Cloud Functions and Firebase Admin modules',
|
||||
'content': '<h1>Step 7 - Import the Cloud Functions and Firebase Admin modules</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Welcome New Users',
|
||||
'content': '<h1>Step 8 - Welcome New Users</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Images moderation',
|
||||
'content': '<h1>Step 9 - Images moderation</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'New Message Notifications',
|
||||
'content': '<h1>Step 10 - New Message Notifications</h1>' +
|
||||
'<br>' +
|
||||
'This is an example step of the course. You can put anything in here from example codes to videos.' +
|
||||
'<br><br>' +
|
||||
'To install the CLI you need to have installed <b>npm</b> which typically comes with <b>NodeJS</b>.' +
|
||||
'To install or upgrade the CLI run the following <b>npm</b> command:' +
|
||||
'<br><br>' +
|
||||
'<code>npm -g install @angular/cli</code>' +
|
||||
'<br><br>' +
|
||||
'To verify that the CLI has been installed correctly, open a console and run:' +
|
||||
'<br><br>' +
|
||||
'<code>ng version</code>' +
|
||||
'<br><br>' +
|
||||
'<h2>Install dependencies</h2>' +
|
||||
'<br>' +
|
||||
'To moderate the images we\'ll need a few Node.js packages:' +
|
||||
'<br><br>' +
|
||||
'<ul>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Vision Client Library for Node.js: @google-cloud/vision to run the image through the Cloud Vision API to detect inappropriate images.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'The Google Cloud Storage Client Library for Node.js: @google-cloud/storage to download and upload the images from Cloud Storage.' +
|
||||
'</li>' +
|
||||
'<br>' +
|
||||
'<li>' +
|
||||
'A Node.js library allowing us to run processes: child-process-promise to run ImageMagick since the ImageMagick command-line tool comes pre-installed on all Functions instances.' +
|
||||
'</li>' +
|
||||
'</ul>' +
|
||||
'<br>' +
|
||||
'To install these three packages into your Cloud Functions app, run the following npm install --save command. Make sure that you do this from the functions directory.' +
|
||||
'<br><br>' +
|
||||
'<code>npm install --save @google-cloud/vision @google-cloud/storage child-process-promise</code>' +
|
||||
'<br><br>' +
|
||||
'This will install the three packages locally and add them as declared dependencies in your package.js file.'
|
||||
},
|
||||
{
|
||||
'title' : 'Congratulations!',
|
||||
'content': '<h1>Step 11 - Congratulations!</h1>' +
|
||||
'<br>' +
|
||||
'You\'ve built a full-fidelity, offline-capable progressive web app by leveraging the power of reusable Web Components and Firebase. Why bother with a native app when you know how to do all that?!'
|
||||
}
|
||||
];
|
||||
|
||||
public static course = [
|
||||
{
|
||||
'id' : '15459251a6d6b397565',
|
||||
'title' : 'Basics of Angular',
|
||||
'slug' : 'basics-of-angular',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'web',
|
||||
'length' : 30,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '154588a0864d2881124',
|
||||
'title' : 'Basics of TypeScript',
|
||||
'slug' : 'basics-of-typeScript',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'web',
|
||||
'length' : 60,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Nov 01, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '15453ba60d3baa5daaf',
|
||||
'title' : 'Android N: Quick Settings',
|
||||
'slug' : 'android-n-quick-settings',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'android',
|
||||
'length' : 120,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '15453a06c08fb021776',
|
||||
'title' : 'Keep Sensitive Data Safe and Private',
|
||||
'slug' : 'keep-sensitive-data-safe-and-private',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'android',
|
||||
'length' : 45,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '15427f4c1b7f3953234',
|
||||
'title' : 'Building a gRPC Service with Java',
|
||||
'slug' : 'building-a-grpc-service-with-java',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'cloud',
|
||||
'length' : 30,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1542d75d929a603125',
|
||||
'title' : 'Build a PWA Using Workbox',
|
||||
'slug' : 'build-a-pwa-using-workbox',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'web',
|
||||
'length' : 120,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1543ee3a5b43e0f9f45',
|
||||
'title' : 'Build an App for the Google Assistant with Firebase and Dialogflow',
|
||||
'slug' : 'build-an-app-for-the-google-assistant-with-firebase-and-dialogflow',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'firebase',
|
||||
'length' : 30,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1543cc4515df3146112',
|
||||
'title' : 'Cloud Functions for Firebase',
|
||||
'slug' : 'cloud-functions-for-firebase',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'firebase',
|
||||
'length' : 45,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '154398a4770d7aaf9a2',
|
||||
'title' : 'Manage Your Pivotal Cloud Foundry App\'s Using Apigee Edge',
|
||||
'slug' : 'manage-your-pivotal-cloud-foundry-apps-using-apigee-Edge',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'cloud',
|
||||
'length' : 90,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '15438351f87dcd68567',
|
||||
'title' : 'Building Beautiful UIs with Flutter',
|
||||
'your' : 'building-beautiful-uis-with-flutter',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'web',
|
||||
'length' : 90,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1544e43dcdae6ebf876',
|
||||
'title' : 'Cloud Firestore',
|
||||
'slug' : 'cloud-firestore',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'firebase',
|
||||
'length' : 90,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1541ca7af66da284177',
|
||||
'title' : 'Customize Network Topology with Subnetworks',
|
||||
'slug' : 'customize-network-topology-with-subnetworks',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'web',
|
||||
'length' : 45,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '154297167e781781745',
|
||||
'title' : 'Looking at Campaign Finance with BigQuery',
|
||||
'slug' : 'looking-at-campaign-finance-with-bigquery',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'cloud',
|
||||
'length' : 60,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '154537435d5b32bf11a',
|
||||
'title' : 'Firebase Android',
|
||||
'slug' : 'firebase-android',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'android',
|
||||
'length' : 45,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '154204e45a59b168453',
|
||||
'title' : 'Simulating a Thread Network Using OpenThread',
|
||||
'slug' : 'simulating-a-thread-network-using-openthread',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'web',
|
||||
'length' : 45,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1541dd1e05dfc439216',
|
||||
'title' : 'Your First Progressive Web App',
|
||||
'slug' : 'your-first-progressive-web-app',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'web',
|
||||
'length' : 30,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1532dfc67e704e48515',
|
||||
'title' : 'Launch Cloud Datalab',
|
||||
'slug' : 'launch-cloud-datalab',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'cloud',
|
||||
'length' : 60,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
},
|
||||
{
|
||||
'id' : '1542e43dfaae6ebf226',
|
||||
'title' : 'Personalize Your iOS App with Firebase User Management',
|
||||
'slug' : 'personalize-your-ios-app-with-firebase-user-management',
|
||||
'description': 'Commits that need to be pushed lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
'category' : 'firebase',
|
||||
'length' : 90,
|
||||
'totalSteps' : 11,
|
||||
'updated' : 'Jun 28, 2017',
|
||||
'steps' : AcademyFakeDb.demoSteps
|
||||
}
|
||||
];
|
||||
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import { ScrumboardFakeDb } from './scrumboard';
|
||||
import { FaqFakeDb } from './faq';
|
||||
import { KnowledgeBaseFakeDb } from './knowledge-base';
|
||||
import { ECommerceFakeDb } from './e-commerce';
|
||||
import { AcademyFakeDb } from './academy';
|
||||
|
||||
export class FuseFakeDbService implements InMemoryDbService
|
||||
{
|
||||
@@ -52,7 +53,10 @@ export class FuseFakeDbService implements InMemoryDbService
|
||||
'knowledge-base' : KnowledgeBaseFakeDb.data,
|
||||
'e-commerce-dashboard' : ECommerceFakeDb.dashboard,
|
||||
'e-commerce-products' : ECommerceFakeDb.products,
|
||||
'e-commerce-orders' : ECommerceFakeDb.orders
|
||||
'e-commerce-orders' : ECommerceFakeDb.orders,
|
||||
'academy-categories' : AcademyFakeDb.categories,
|
||||
'academy-courses' : AcademyFakeDb.courses,
|
||||
'academy-course' : AcademyFakeDb.course
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
47
src/app/main/content/apps/academy/academy.module.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { SharedModule } from '../../../../core/modules/shared.module';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { FuseAcademyCoursesComponent } from './courses/courses.component';
|
||||
import { FuseAcademyCourseComponent } from './course/course.component';
|
||||
import { AcademyCoursesService } from './courses.service';
|
||||
import { AcademyCourseService } from './course.service';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path : 'courses',
|
||||
component: FuseAcademyCoursesComponent,
|
||||
resolve : {
|
||||
academy: AcademyCoursesService
|
||||
}
|
||||
},
|
||||
{
|
||||
path : 'courses/:courseId/:courseSlug',
|
||||
component: FuseAcademyCourseComponent,
|
||||
resolve : {
|
||||
academy: AcademyCourseService
|
||||
}
|
||||
},
|
||||
{
|
||||
path : '**',
|
||||
redirectTo: 'courses'
|
||||
}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
imports : [
|
||||
SharedModule,
|
||||
RouterModule.forChild(routes)
|
||||
],
|
||||
declarations: [
|
||||
FuseAcademyCoursesComponent,
|
||||
FuseAcademyCourseComponent
|
||||
],
|
||||
providers : [
|
||||
AcademyCoursesService,
|
||||
AcademyCourseService
|
||||
]
|
||||
})
|
||||
export class FuseAcademyModule
|
||||
{
|
||||
}
|
||||
49
src/app/main/content/apps/academy/course.service.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
|
||||
@Injectable()
|
||||
export class AcademyCourseService implements Resolve<any>
|
||||
{
|
||||
onCourseChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
||||
|
||||
constructor(private http: HttpClient)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* The Academy App Main Resolver
|
||||
*
|
||||
* @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.getCourse(route.params.courseId, route.params.courseSlug)
|
||||
]).then(
|
||||
() => {
|
||||
resolve();
|
||||
},
|
||||
reject
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getCourse(courseId, courseSlug): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this.http.get('api/academy-course/' + courseId + '/' + courseSlug)
|
||||
.subscribe((response: any) => {
|
||||
this.onCourseChanged.next(response);
|
||||
resolve(response);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
100
src/app/main/content/apps/academy/course/course.component.html
Normal file
@@ -0,0 +1,100 @@
|
||||
<div id="academy-course" class="page-layout simple left-sidenav">
|
||||
|
||||
<mat-sidenav-container>
|
||||
|
||||
<!-- SIDENAV -->
|
||||
<mat-sidenav class="sidenav" align="start" opened="true" mode="side"
|
||||
fuseMatSidenavHelper="academy-left-sidenav" mat-is-locked-open="gt-md">
|
||||
|
||||
<div class="sidenav-content" fusePerfectScrollbar>
|
||||
|
||||
<div class="steps">
|
||||
|
||||
<div class="step"
|
||||
*ngFor="let step of course.steps; let i = index; let last = last; let first = first"
|
||||
(click)="gotoStep(i)"
|
||||
[ngClass]="{'current': currentStep === i, 'completed': currentStep > i, 'last': last, 'first': first}">
|
||||
<div class="index">
|
||||
<span>{{i + 1}}</span>
|
||||
</div>
|
||||
<div class="title">{{step.title}}</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</mat-sidenav>
|
||||
<!-- / SIDENAV -->
|
||||
|
||||
<!-- CENTER -->
|
||||
<div class="center">
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-24" fxLayout="row" fxLayoutAlign="start center">
|
||||
|
||||
<button mat-button class="mat-icon-button mr-16 sidenav-toggle"
|
||||
fuseMatSidenavToggler="academy-left-sidenav" fxHide.gt-md>
|
||||
<mat-icon>menu</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-button class="mat-icon-button mr-16" [routerLink]="'/apps/academy/courses'">
|
||||
<mat-icon>arrow_back</mat-icon>
|
||||
</button>
|
||||
|
||||
<div>
|
||||
<h2>{{course.title}}</h2>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div id="course-content" class="content">
|
||||
|
||||
<ng-container *ngFor="let step of course.steps; let i = index;">
|
||||
|
||||
<div class="course-step" fusePerfectScrollbar
|
||||
*ngIf="currentStep === i"
|
||||
[@slideIn]="animationDirection">
|
||||
|
||||
<div id="course-step-content" class="course-step-content" [innerHTML]="step.content"></div>
|
||||
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
<div class="step-navigation">
|
||||
|
||||
<button mat-fab class="previous mat-accent white-fg"
|
||||
(click)="gotoPreviousStep()"
|
||||
[disabled]="currentStep === 0"
|
||||
[fxHide]="currentStep === 0">
|
||||
<mat-icon>chevron_left</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-fab class="next mat-accent white-fg"
|
||||
(click)="gotoNextStep()"
|
||||
[disabled]="currentStep === course.totalSteps - 1"
|
||||
[fxHide]="currentStep === course.totalSteps - 1">
|
||||
<mat-icon>chevron_right</mat-icon>
|
||||
</button>
|
||||
|
||||
<button mat-fab class="done mat-green-600-bg"
|
||||
routerLink="/apps/academy/courses"
|
||||
[disabled]="currentStep !== course.totalSteps - 1"
|
||||
[fxShow]="currentStep === course.totalSteps - 1">
|
||||
<mat-icon>check</mat-icon>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / CENTER -->
|
||||
|
||||
</mat-sidenav-container>
|
||||
|
||||
</div>
|
||||
202
src/app/main/content/apps/academy/course/course.component.scss
Normal file
@@ -0,0 +1,202 @@
|
||||
@import "src/app/core/scss/fuse";
|
||||
|
||||
#academy-course {
|
||||
|
||||
.mat-drawer-container {
|
||||
flex: 1 !important;
|
||||
|
||||
> .mat-drawer-content {
|
||||
flex: 1 !important;
|
||||
|
||||
@include media-breakpoint-up('lg') {
|
||||
z-index: 52;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidenav {
|
||||
|
||||
.steps {
|
||||
padding: 16px 0;
|
||||
|
||||
.step {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: 16px;
|
||||
cursor: pointer;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
|
||||
&.current {
|
||||
background: mat-color($mat-blue, 50);
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
|
||||
.index {
|
||||
|
||||
span {
|
||||
border: 2px solid mat-color($mat-blue, 500);
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
&.completed {
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
|
||||
.index {
|
||||
|
||||
span {
|
||||
border: 2px solid mat-color($mat-blue, 500);
|
||||
}
|
||||
|
||||
&:after {
|
||||
border-left-color: mat-color($mat-blue, 500);
|
||||
}
|
||||
}
|
||||
|
||||
+ .step {
|
||||
|
||||
.index {
|
||||
|
||||
&:before {
|
||||
border-left-color: mat-color($mat-blue, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.first {
|
||||
|
||||
.index {
|
||||
|
||||
&:before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.last {
|
||||
|
||||
.index {
|
||||
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.index {
|
||||
display: flex;
|
||||
margin-right: 12px;
|
||||
|
||||
span {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
width: 28px;
|
||||
min-width: 28px;
|
||||
max-width: 28px;
|
||||
height: 28px;
|
||||
background: white;
|
||||
border-radius: 100%;
|
||||
border: 2px solid mat-color($mat-grey, 500);
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
content: ' ';
|
||||
border-left: 1px solid mat-color($mat-grey, 300);
|
||||
width: 1px;
|
||||
height: 50%;
|
||||
left: 29px;
|
||||
z-index: 8;
|
||||
}
|
||||
|
||||
&:before {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&:after {
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
position: relative;
|
||||
|
||||
.header {
|
||||
height: 72px;
|
||||
min-height: 72px;
|
||||
max-height: 72px;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
background: mat-color($mat-grey, 200);
|
||||
|
||||
.course-step {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 48px;
|
||||
|
||||
@media (max-width: 720px) {
|
||||
padding: 0 0 120px 0;
|
||||
}
|
||||
|
||||
.course-step-content {
|
||||
padding: 24px;
|
||||
max-width: 720px;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
background: white;
|
||||
@include mat-elevation(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.step-navigation {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
bottom: 32px;
|
||||
max-width: 944px;
|
||||
padding: 0 24px;
|
||||
width: 100%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
.previous {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.next,
|
||||
.done {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
101
src/app/main/content/apps/academy/course/course.component.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { AfterViewInit, ChangeDetectorRef, Component, OnDestroy, OnInit, QueryList, ViewChildren, ViewEncapsulation } from '@angular/core';
|
||||
import { AcademyCourseService } from '../course.service';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { FusePerfectScrollbarDirective } from '../../../../../core/directives/fuse-perfect-scrollbar/fuse-perfect-scrollbar.directive';
|
||||
import { fuseAnimations } from '../../../../../core/animations';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-academy-course',
|
||||
templateUrl : './course.component.html',
|
||||
styleUrls : ['./course.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
animations : fuseAnimations
|
||||
})
|
||||
export class FuseAcademyCourseComponent implements OnInit, OnDestroy, AfterViewInit
|
||||
{
|
||||
course: any;
|
||||
courseSubscription: Subscription;
|
||||
currentStep = 0;
|
||||
courseStepContent;
|
||||
animationDirection: 'left' | 'right' | 'none' = 'none';
|
||||
@ViewChildren(FusePerfectScrollbarDirective) fuseScrollbarDirectives: QueryList<FusePerfectScrollbarDirective>;
|
||||
|
||||
constructor(
|
||||
private courseService: AcademyCourseService,
|
||||
private changeDetectorRef: ChangeDetectorRef
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
// Subscribe to courses
|
||||
this.courseSubscription =
|
||||
this.courseService.onCourseChanged
|
||||
.subscribe(course => {
|
||||
this.course = course;
|
||||
});
|
||||
}
|
||||
|
||||
ngAfterViewInit()
|
||||
{
|
||||
this.courseStepContent = this.fuseScrollbarDirectives.find((fuseScrollbarDirective) => {
|
||||
return fuseScrollbarDirective.element.nativeElement.id === 'course-step-content';
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
{
|
||||
this.courseSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
gotoStep(step)
|
||||
{
|
||||
// Decide the animation direction
|
||||
this.animationDirection = this.currentStep < step ? 'left' : 'right';
|
||||
|
||||
// Run change detection so the change
|
||||
// in the animation direction registered
|
||||
this.changeDetectorRef.detectChanges();
|
||||
|
||||
// Set the current step
|
||||
this.currentStep = step;
|
||||
}
|
||||
|
||||
gotoNextStep()
|
||||
{
|
||||
if ( this.currentStep === this.course.totalSteps - 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the animation direction
|
||||
this.animationDirection = 'left';
|
||||
|
||||
// Run change detection so the change
|
||||
// in the animation direction registered
|
||||
this.changeDetectorRef.detectChanges();
|
||||
|
||||
// Increase the current step
|
||||
this.currentStep++;
|
||||
}
|
||||
|
||||
gotoPreviousStep()
|
||||
{
|
||||
if ( this.currentStep === 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the animation direction
|
||||
this.animationDirection = 'right';
|
||||
|
||||
// Run change detection so the change
|
||||
// in the animation direction registered
|
||||
this.changeDetectorRef.detectChanges();
|
||||
|
||||
// Decrease the current step
|
||||
this.currentStep--;
|
||||
}
|
||||
}
|
||||
62
src/app/main/content/apps/academy/courses.service.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
|
||||
@Injectable()
|
||||
export class AcademyCoursesService implements Resolve<any>
|
||||
{
|
||||
onCategoriesChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
||||
onCoursesChanged: BehaviorSubject<any> = new BehaviorSubject({});
|
||||
|
||||
constructor(private http: HttpClient)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* The Academy App Main Resolver
|
||||
*
|
||||
* @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.getCategories(),
|
||||
this.getCourses()
|
||||
]).then(
|
||||
() => {
|
||||
resolve();
|
||||
},
|
||||
reject
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getCategories(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this.http.get('api/academy-categories')
|
||||
.subscribe((response: any) => {
|
||||
this.onCategoriesChanged.next(response);
|
||||
resolve(response);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
getCourses(): Promise<any>
|
||||
{
|
||||
return new Promise((resolve, reject) => {
|
||||
this.http.get('api/academy-courses')
|
||||
.subscribe((response: any) => {
|
||||
this.onCoursesChanged.next(response);
|
||||
resolve(response);
|
||||
}, reject);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<div id="academy-courses" class="page-layout simple" fusePerfectScrollbar>
|
||||
|
||||
<!-- HEADER -->
|
||||
<div class="header mat-accent-bg p-16 p-sm-24" fxLayout="column" fxLayoutAlign="center center">
|
||||
|
||||
<div class="hero-text">
|
||||
<mat-icon class="hero-icon">school</mat-icon>
|
||||
<h1>WELCOME TO ACADEMY</h1>
|
||||
<h3>
|
||||
Our courses will step you through the process of building a small application, or adding a new feature
|
||||
to an existing application.
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / HEADER -->
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content p-24">
|
||||
|
||||
<div fxLayout="column" fxLayoutAlign="center">
|
||||
|
||||
<div class="filters" fxLayout="column" fxLayoutAlign="center center"
|
||||
fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="space-between center">
|
||||
|
||||
<mat-form-field class="course-search">
|
||||
|
||||
<input matInput placeholder="Search for a course" [(ngModel)]="searchTerm"
|
||||
(input)="filterCoursesByTerm()">
|
||||
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="category-selector">
|
||||
|
||||
<mat-select placeholder="Select Category" [(ngModel)]="currentCategory"
|
||||
(change)="filterCoursesByCategory()">
|
||||
<mat-option [value]="'all'">
|
||||
All
|
||||
</mat-option>
|
||||
<mat-option *ngFor="let category of categories" [value]="category.value">
|
||||
{{ category.label }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="courses" fxLayout="row" fxLayoutAlign="center" fxLayoutWrap>
|
||||
|
||||
<div class="course" *ngFor="let course of filteredCourses" fxFlex="100" fxFlex.gt-xs="50"
|
||||
fxFlex.gt-sm="33" [ngClass]="course.category">
|
||||
|
||||
<div class="course-content" fxLayout="column">
|
||||
|
||||
<div class="header" fxLayout="row" fxLayoutAlign="center center"
|
||||
[ngClass]="course.category + '-bg'">
|
||||
|
||||
<div class="category" fxFlex>
|
||||
{{course.category}}
|
||||
</div>
|
||||
|
||||
<div class="length" fxLayout="row" fxLayoutAlign="center center">
|
||||
<mat-icon class="length-icon s-20">access_time</mat-icon>
|
||||
<div class="min">{{course.length}} min</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="content" fxLayout="column" fxLayoutAlign="center center" fxFlex>
|
||||
<div class="h1">{{course.title}}</div>
|
||||
<div class="updated">Updated {{course.updated}}</div>
|
||||
</div>
|
||||
|
||||
<div class="footer" fxLayout="row" fxLayoutAlign="center center">
|
||||
<button mat-button color="accent"
|
||||
[routerLink]="'/apps/academy/courses/' + course.id + '/' + course.slug">
|
||||
START
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="no-courses" *ngIf="filteredCourses.length === 0">
|
||||
No courses found!
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- / CONTENT -->
|
||||
|
||||
</div>
|
||||
188
src/app/main/content/apps/academy/courses/courses.component.scss
Normal file
@@ -0,0 +1,188 @@
|
||||
@import "src/app/core/scss/fuse";
|
||||
|
||||
#academy-courses {
|
||||
|
||||
.header {
|
||||
position: relative;
|
||||
flex: 1 0 auto;
|
||||
height: 280px;
|
||||
max-height: 280px;
|
||||
background: #1A237E;
|
||||
background: linear-gradient(to right, #0E2A3B 0%, #34306B 100%);
|
||||
text-align: center;
|
||||
|
||||
@include media-breakpoint('xs') {
|
||||
height: 240px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.hero-text {
|
||||
|
||||
.hero-icon {
|
||||
position: absolute;
|
||||
top: -64px;
|
||||
left: 0px;
|
||||
opacity: 0.04;
|
||||
font-size: 512px !important;
|
||||
width: 512px !important;
|
||||
height: 512px !important;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: white;
|
||||
font-size: 40px;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.01em;
|
||||
text-align: center;
|
||||
margin-top: 0;
|
||||
margin-bottom: 16px;
|
||||
|
||||
@include media-breakpoint-down('xs') {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
max-width: 480px;
|
||||
text-align: center;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.03em;
|
||||
margin: 0;
|
||||
|
||||
@include media-breakpoint-down('xs') {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
|
||||
.category-selector {
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.filters {
|
||||
width: 100%;
|
||||
max-width: 1040px;
|
||||
margin: 24px auto;
|
||||
padding: 0 20px;
|
||||
|
||||
@include media-breakpoint-down('xs') {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.course-search {
|
||||
width: 200px;
|
||||
|
||||
@include media-breakpoint-down('xs') {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up('sm') {
|
||||
margin-right: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.courses {
|
||||
width: 100%;
|
||||
max-width: 1040px;
|
||||
margin: 0 auto;
|
||||
|
||||
.no-courses {
|
||||
font-size: 24px;
|
||||
margin: 24px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.course {
|
||||
padding: 16px;
|
||||
|
||||
&:hover {
|
||||
|
||||
.course-content {
|
||||
@include mat-elevation(8);
|
||||
}
|
||||
}
|
||||
|
||||
.course-content {
|
||||
background: white;
|
||||
min-height: 240px;
|
||||
transition: box-shadow 150ms ease-in-out;
|
||||
|
||||
@include mat-elevation(1);
|
||||
|
||||
.header {
|
||||
color: white;
|
||||
padding: 16px 24px;
|
||||
height: 64px !important;
|
||||
min-height: 64px !important;
|
||||
max-height: 64px !important;
|
||||
|
||||
&.web-bg {
|
||||
background: mat-color($mat-blue, 500);
|
||||
}
|
||||
|
||||
&.android-bg {
|
||||
background: mat-color($mat-green, 500);
|
||||
}
|
||||
|
||||
&.firebase-bg {
|
||||
background: mat-color($mat-amber, 800);
|
||||
}
|
||||
|
||||
&.cloud-bg {
|
||||
background: mat-color($mat-blue-grey, 500);
|
||||
}
|
||||
|
||||
.category {
|
||||
text-transform: capitalize;
|
||||
text-align: left;
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
|
||||
.length {
|
||||
|
||||
.length-icon {
|
||||
margin-right: 8px;
|
||||
color: rgba(0, 0, 0, 0.54) !important;
|
||||
}
|
||||
|
||||
.min {
|
||||
font-size: 16px;
|
||||
color: rgba(0, 0, 0, 0.54);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 24px;
|
||||
|
||||
.h1 {
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.updated {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
margin-top: 4px;
|
||||
color: rgba(0, 0, 0, 0.37);
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
padding: 16px;
|
||||
height: 48px !important;
|
||||
min-height: 48px !important;
|
||||
max-height: 48px !important;
|
||||
box-shadow: inset 0 1px 0 0 rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { AcademyCoursesService } from '../courses.service';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-academy-courses',
|
||||
templateUrl: './courses.component.html',
|
||||
styleUrls : ['./courses.component.scss']
|
||||
})
|
||||
export class FuseAcademyCoursesComponent implements OnInit, OnDestroy
|
||||
{
|
||||
categories: any[];
|
||||
courses: any[];
|
||||
coursesFilteredByCategory: any[];
|
||||
filteredCourses: any[];
|
||||
|
||||
categoriesSubscription: Subscription;
|
||||
coursesSubscription: Subscription;
|
||||
|
||||
currentCategory = 'all';
|
||||
searchTerm = '';
|
||||
|
||||
constructor(
|
||||
private coursesService: AcademyCoursesService
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
// Subscribe to categories
|
||||
this.categoriesSubscription =
|
||||
this.coursesService.onCategoriesChanged
|
||||
.subscribe(categories => {
|
||||
this.categories = categories;
|
||||
});
|
||||
|
||||
// Subscribe to courses
|
||||
this.coursesSubscription =
|
||||
this.coursesService.onCoursesChanged
|
||||
.subscribe(courses => {
|
||||
this.filteredCourses = this.coursesFilteredByCategory = this.courses = courses;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy()
|
||||
{
|
||||
this.categoriesSubscription.unsubscribe();
|
||||
this.coursesSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
filterCoursesByCategory()
|
||||
{
|
||||
// Filter
|
||||
if ( this.currentCategory === 'all' )
|
||||
{
|
||||
this.coursesFilteredByCategory = this.courses;
|
||||
this.filteredCourses = this.courses;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.coursesFilteredByCategory = this.courses.filter((course) => {
|
||||
return course.category === this.currentCategory;
|
||||
});
|
||||
|
||||
this.filteredCourses = [...this.coursesFilteredByCategory];
|
||||
|
||||
}
|
||||
|
||||
// Re-filter by search term
|
||||
this.filterCoursesByTerm();
|
||||
}
|
||||
|
||||
filterCoursesByTerm()
|
||||
{
|
||||
const searchTerm = this.searchTerm.toLowerCase();
|
||||
|
||||
// Search
|
||||
if ( searchTerm === '' )
|
||||
{
|
||||
this.filteredCourses = this.coursesFilteredByCategory;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.filteredCourses = this.coursesFilteredByCategory.filter((course) => {
|
||||
return course.title.toLowerCase().includes(searchTerm);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -217,35 +217,35 @@
|
||||
|
||||
&.Jan {
|
||||
background-image: url('/assets/images/backgrounds/winter.jpg');
|
||||
background-position: 0 65%;
|
||||
background-position: 0 85%;
|
||||
}
|
||||
&.Feb {
|
||||
background-image: url('/assets/images/backgrounds/winter.jpg');
|
||||
background-position: 0 65%;
|
||||
background-position: 0 85%;
|
||||
}
|
||||
&.Mar {
|
||||
background-image: url('/assets/images/backgrounds/spring.jpg');
|
||||
background-position: 0 19%;
|
||||
background-position: 0 40%;
|
||||
}
|
||||
&.Apr {
|
||||
background-image: url('/assets/images/backgrounds/spring.jpg');
|
||||
background-position: 0 19%;
|
||||
background-position: 0 40%;
|
||||
}
|
||||
&.May {
|
||||
background-image: url('/assets/images/backgrounds/spring.jpg');
|
||||
background-position: 0 19%;
|
||||
background-position: 0 40%;
|
||||
}
|
||||
&.Jun {
|
||||
background-image: url('/assets/images/backgrounds/summer.jpg');
|
||||
background-position: 0 91%;
|
||||
background-position: 0 80%;
|
||||
}
|
||||
&.Jul {
|
||||
background-image: url('/assets/images/backgrounds/summer.jpg');
|
||||
background-position: 0 91%;
|
||||
background-position: 0 80%;
|
||||
}
|
||||
&.Aug {
|
||||
background-image: url('/assets/images/backgrounds/summer.jpg');
|
||||
background-position: 0 91%;
|
||||
background-position: 0 80%;
|
||||
}
|
||||
&.Sep {
|
||||
background-image: url('/assets/images/backgrounds/autumn.jpg');
|
||||
@@ -261,7 +261,7 @@
|
||||
}
|
||||
&.Dec {
|
||||
background-image: url('/assets/images/backgrounds/winter.jpg');
|
||||
background-position: 0 65%;
|
||||
background-position: 0 85%;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
.orders-table {
|
||||
flex: 1 1 auto;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .12);
|
||||
overflow: auto;
|
||||
|
||||
.mat-header-row {
|
||||
min-height: 64px;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
.products-table {
|
||||
flex: 1 1 auto;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, .12);
|
||||
overflow: auto;
|
||||
|
||||
.mat-header-row {
|
||||
min-height: 64px;
|
||||
|
||||
@@ -8,6 +8,7 @@ import { locale as turkish } from './i18n/tr';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import * as fromStore from './store';
|
||||
import { FuseConfigService } from '../../../../core/services/config.service';
|
||||
|
||||
@Component({
|
||||
selector : 'fuse-mail',
|
||||
@@ -30,6 +31,7 @@ export class FuseMailNgrxComponent implements OnInit, OnDestroy
|
||||
selectedMailIds: string[];
|
||||
|
||||
constructor(
|
||||
private configService: FuseConfigService,
|
||||
private mailService: MailNgrxService,
|
||||
private translationLoader: FuseTranslationLoaderService,
|
||||
private store: Store<fromStore.MailAppState>,
|
||||
@@ -46,6 +48,10 @@ export class FuseMailNgrxComponent implements OnInit, OnDestroy
|
||||
this.searchText$ = this.store.select(fromStore.getSearchText);
|
||||
this.mails = [];
|
||||
this.selectedMailIds = [];
|
||||
|
||||
this.configService.setSettings({
|
||||
routerAnimation: 'none'
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
|
||||
@@ -28,7 +28,12 @@
|
||||
type="email" required>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<div class="show-hide-extra-fields" (click)="toggleExtraToFields()">
|
||||
<span [fxShow]="!showExtraToFields">Show CC & BCC</span>
|
||||
<span [fxShow]="showExtraToFields">Hide CC & BCC</span>
|
||||
</div>
|
||||
|
||||
<mat-form-field [fxShow]="showExtraToFields">
|
||||
<input matInput
|
||||
name="cc"
|
||||
placeholder="Cc"
|
||||
@@ -36,7 +41,7 @@
|
||||
type="email">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<mat-form-field [fxShow]="showExtraToFields">
|
||||
<input matInput
|
||||
name="bcc"
|
||||
placeholder="Bcc"
|
||||
@@ -51,11 +56,11 @@
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field>
|
||||
<textarea matInput name="message"
|
||||
placeholder="Message"
|
||||
formControlName="message"
|
||||
rows="6">
|
||||
</textarea>
|
||||
<textarea matInput name="message"
|
||||
placeholder="Message"
|
||||
formControlName="message"
|
||||
rows="6">
|
||||
</textarea>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="attachment-list">
|
||||
|
||||
@@ -1,7 +1,17 @@
|
||||
@import "src/app/core/scss/fuse";
|
||||
|
||||
.mail-compose-dialog {
|
||||
|
||||
@include media-breakpoint('xs') {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up('sm') {
|
||||
width: 640px;
|
||||
}
|
||||
|
||||
.mat-dialog-container {
|
||||
padding: 0;
|
||||
width: 720px;
|
||||
|
||||
.compose-form {
|
||||
|
||||
@@ -9,6 +19,12 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.show-hide-extra-fields {
|
||||
text-align: right;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.attachment-list {
|
||||
font-size: 13px;
|
||||
padding-top: 16px;
|
||||
|
||||
@@ -10,6 +10,7 @@ import { FormControl, FormGroup } from '@angular/forms';
|
||||
})
|
||||
export class FuseMailComposeDialogComponent implements OnInit
|
||||
{
|
||||
showExtraToFields = false;
|
||||
composeForm: FormGroup;
|
||||
|
||||
constructor(
|
||||
@@ -39,4 +40,8 @@ export class FuseMailComposeDialogComponent implements OnInit
|
||||
});
|
||||
}
|
||||
|
||||
toggleExtraToFields()
|
||||
{
|
||||
this.showExtraToFields = !this.showExtraToFields;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
</div>
|
||||
|
||||
<div class="title">RECOVER YOUR PASSWORD</div>
|
||||
<div class="description">Sed mollis velit facilisis facilisis viverra</div>
|
||||
|
||||
<form name="forgoPasswordForm" [formGroup]="forgotPasswordForm" novalidate>
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#forgot-password-intro {
|
||||
padding: 128px;
|
||||
color: white;
|
||||
|
||||
@include media-breakpoint('sm') {
|
||||
padding: 128px 64px;
|
||||
@@ -27,9 +28,10 @@
|
||||
}
|
||||
|
||||
.description {
|
||||
padding-top: 8px;
|
||||
padding-top: 16px;
|
||||
font-size: 14px;
|
||||
max-width: 600px;
|
||||
color: rgba(255, 255, 255, 0.54);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
</div>
|
||||
|
||||
<div class="title">LOGIN TO YOUR ACCOUNT</div>
|
||||
<div class="description">Sed mollis velit facilisis facilisis viverra</div>
|
||||
|
||||
<form name="loginForm" [formGroup]="loginForm" novalidate>
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#login-intro {
|
||||
padding: 128px;
|
||||
color: white;
|
||||
|
||||
@include media-breakpoint('sm') {
|
||||
padding: 128px 64px;
|
||||
@@ -27,9 +28,10 @@
|
||||
}
|
||||
|
||||
.description {
|
||||
padding-top: 8px;
|
||||
padding-top: 16px;
|
||||
font-size: 14px;
|
||||
max-width: 600px;
|
||||
color: rgba(255, 255, 255, 0.54);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
</div>
|
||||
|
||||
<div class="title">CREATE AN ACCOUNT</div>
|
||||
<div class="description">Sed mollis velit facilisis facilisis viverra</div>
|
||||
|
||||
<form name="registerForm" [formGroup]="registerForm" novalidate>
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#register-intro {
|
||||
padding: 128px;
|
||||
color: white;
|
||||
|
||||
@include media-breakpoint('sm') {
|
||||
padding: 128px 64px;
|
||||
@@ -27,9 +28,10 @@
|
||||
}
|
||||
|
||||
.description {
|
||||
padding-top: 8px;
|
||||
padding-top: 16px;
|
||||
font-size: 14px;
|
||||
max-width: 600px;
|
||||
color: rgba(255, 255, 255, 0.54);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
</div>
|
||||
|
||||
<div class="title">RESET YOUR PASSWORD</div>
|
||||
<div class="description">Sed mollis velit facilisis facilisis viverra</div>
|
||||
|
||||
<form name="resetPasswordForm" [formGroup]="resetPasswordForm" novalidate>
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#reset-password-intro {
|
||||
padding: 128px;
|
||||
color: white;
|
||||
|
||||
@include media-breakpoint('sm') {
|
||||
padding: 128px 64px;
|
||||
@@ -27,9 +28,10 @@
|
||||
}
|
||||
|
||||
.description {
|
||||
padding-top: 8px;
|
||||
padding-top: 16px;
|
||||
font-size: 14px;
|
||||
max-width: 600px;
|
||||
color: rgba(255, 255, 255, 0.54);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ fuse-navbar-vertical {
|
||||
|
||||
.logo-icon {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
}
|
||||
|
||||
.logo-text {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<mat-list class="date" cdk-focus-region-start>
|
||||
<mat-list class="date" cdkFocusRegionStart>
|
||||
|
||||
<h3 matSubheader cdk-focus-init>
|
||||
<h3 matSubheader cdkFocusInit>
|
||||
<span>Today</span>
|
||||
</h3>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</div>
|
||||
</mat-list>
|
||||
|
||||
<mat-divider cdk-focus-region-end></mat-divider>
|
||||
<mat-divider cdkFocusRegionEnd></mat-divider>
|
||||
|
||||
<mat-list>
|
||||
<h3 matSubheader>
|
||||
|
||||
@@ -6,6 +6,7 @@ export const locale = {
|
||||
'DASHBOARDS' : 'Dashboards',
|
||||
'CALENDAR' : 'Calendar',
|
||||
'ECOMMERCE' : 'E-Commerce',
|
||||
'ACADEMY' : 'Academy',
|
||||
'MAIL' : {
|
||||
'TITLE': 'Mail',
|
||||
'BADGE': '25'
|
||||
|
||||
@@ -6,6 +6,7 @@ export const locale = {
|
||||
'DASHBOARDS' : 'Kontrol Paneli',
|
||||
'CALENDAR' : 'Takvim',
|
||||
'ECOMMERCE' : 'E-Ticaret',
|
||||
'ACADEMY' : 'Akademi',
|
||||
'MAIL' : {
|
||||
'TITLE': 'Posta',
|
||||
'BADGE': '15'
|
||||
|
||||
@@ -80,6 +80,14 @@ export class FuseNavigationModel implements FuseNavigationModelInterface
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'id' : 'academy',
|
||||
'title' : 'Academy',
|
||||
'translate': 'NAV.ACADEMY',
|
||||
'type' : 'item',
|
||||
'icon' : 'school',
|
||||
'url' : '/apps/academy'
|
||||
},
|
||||
{
|
||||
'id' : 'mail',
|
||||
'title' : 'Mail',
|
||||
|
||||
|
Before Width: | Height: | Size: 250 KiB After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 363 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 274 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 280 KiB After Width: | Height: | Size: 104 KiB |