├── src ├── assets │ ├── .gitkeep │ ├── images │ │ ├── ball.png │ │ ├── logo.png │ │ ├── ball@2x.png │ │ ├── blank.png │ │ └── logo@2x.png │ └── fonts │ │ ├── ps │ │ ├── 400.ttf │ │ ├── 400i.ttf │ │ ├── 700.ttf │ │ ├── 700i.ttf │ │ ├── 900.ttf │ │ └── 900i.ttf │ │ └── feather │ │ ├── feather.eot │ │ ├── feather.ttf │ │ ├── feather.woff │ │ └── feather.svg ├── app │ ├── app.component.scss │ ├── home │ │ ├── home.component.scss │ │ ├── home.component.spec.ts │ │ ├── home.component.ts │ │ └── home.component.html │ ├── app.component.html │ ├── app.utility.ts │ ├── global │ │ ├── footer │ │ │ ├── footer.component.scss │ │ │ ├── footer.component.html │ │ │ ├── footer.component.ts │ │ │ └── footer.component.spec.ts │ │ ├── header │ │ │ ├── header.component.html │ │ │ ├── header.component.ts │ │ │ ├── header.component.spec.ts │ │ │ └── header.component.scss │ │ └── global.module.ts │ ├── app.component.ts │ ├── shared │ │ ├── shared.module.ts │ │ └── image │ │ │ ├── image.component.html │ │ │ ├── image.component.spec.ts │ │ │ ├── image.component.scss │ │ │ └── image.component.ts │ ├── service │ │ ├── pokemon.service.spec.ts │ │ └── pokemon.service.ts │ ├── app-routing.module.ts │ ├── pokemon │ │ ├── pokemon.component.spec.ts │ │ ├── pokemon.component.scss │ │ ├── pokemon.component.ts │ │ └── pokemon.component.html │ ├── app.module.ts │ └── app.component.spec.ts ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── styles.scss ├── favicon.ico ├── index.html ├── main.ts ├── styles │ ├── _fonts.scss │ ├── _variables.scss │ ├── mixin │ │ ├── _helpers.scss │ │ └── _grid.scss │ ├── pokemon.scss │ └── _icons.scss ├── test.ts └── polyfills.ts ├── .editorconfig ├── e2e ├── src │ ├── app.po.ts │ └── app.e2e-spec.ts ├── tsconfig.json └── protractor.conf.js ├── tsconfig.app.json ├── tsconfig.spec.json ├── tsconfig.json ├── .gitignore ├── .browserslistrc ├── README.md ├── karma.conf.js ├── package.json ├── tslint.json └── angular.json /src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/home/home.component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/favicon.ico -------------------------------------------------------------------------------- /src/assets/images/ball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/assets/images/ball.png -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/assets/fonts/ps/400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/assets/fonts/ps/400.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ps/400i.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/assets/fonts/ps/400i.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ps/700.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/assets/fonts/ps/700.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ps/700i.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/assets/fonts/ps/700i.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ps/900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/assets/fonts/ps/900.ttf -------------------------------------------------------------------------------- /src/assets/fonts/ps/900i.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/assets/fonts/ps/900i.ttf -------------------------------------------------------------------------------- /src/assets/images/ball@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/assets/images/ball@2x.png -------------------------------------------------------------------------------- /src/assets/images/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/assets/images/blank.png -------------------------------------------------------------------------------- /src/assets/images/logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/assets/images/logo@2x.png -------------------------------------------------------------------------------- /src/assets/fonts/feather/feather.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/assets/fonts/feather/feather.eot -------------------------------------------------------------------------------- /src/assets/fonts/feather/feather.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/assets/fonts/feather/feather.ttf -------------------------------------------------------------------------------- /src/assets/fonts/feather/feather.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devfestindia/Fiery-Pokemon-DevFestIndia/HEAD/src/assets/fonts/feather/feather.woff -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 | 6 | -------------------------------------------------------------------------------- /src/app/app.utility.ts: -------------------------------------------------------------------------------- 1 | export function hs(str: string) { 2 | const _arr: Array = str.split('-'); 3 | return _arr 4 | .map((a: string) => `${a.charAt(0).toUpperCase()}${a.slice(1, a.length)}`) 5 | .join(' '); 6 | } 7 | -------------------------------------------------------------------------------- /src/app/global/footer/footer.component.scss: -------------------------------------------------------------------------------- 1 | @import "../../../styles/variables"; 2 | 3 | footer { 4 | padding-bottom: rem(64px); 5 | 6 | .px18 { 7 | margin-top: rem(12px); 8 | color: $dark-grey; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.scss'] 7 | }) 8 | export class AppComponent { 9 | title = 'Pokemon'; 10 | } 11 | -------------------------------------------------------------------------------- /src/app/global/footer/footer.component.html: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see https://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.ts] 12 | quote_type = single 13 | 14 | [*.md] 15 | max_line_length = off 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { ImageComponent } from './image/image.component'; 4 | 5 | @NgModule({ 6 | declarations: [ImageComponent], 7 | imports: [CommonModule], 8 | exports: [ImageComponent], 9 | }) 10 | export class SharedModule {} 11 | -------------------------------------------------------------------------------- /src/app/shared/image/image.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 |
6 | 7 | 8 |
9 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Pokemon 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo(): Promise { 5 | return browser.get(browser.baseUrl) as Promise; 6 | } 7 | 8 | getTitleText(): Promise { 9 | return element(by.css('app-root .content span')).getText() as Promise; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "../tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "../out-tsc/e2e", 6 | "module": "commonjs", 7 | "target": "es2018", 8 | "types": [ 9 | "jasmine", 10 | "jasminewd2", 11 | "node" 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /tsconfig.app.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/app", 6 | "types": [] 7 | }, 8 | "files": [ 9 | "src/main.ts", 10 | "src/polyfills.ts" 11 | ], 12 | "include": [ 13 | "src/**/*.d.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /src/app/global/footer/footer.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-footer', 5 | templateUrl: './footer.component.html', 6 | styleUrls: ['./footer.component.scss'] 7 | }) 8 | export class FooterComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit(): void { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/app/global/header/header.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 | 7 |
8 | 9 |
10 |
11 |
12 |
13 |
14 |
15 | -------------------------------------------------------------------------------- /tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "extends": "./tsconfig.json", 4 | "compilerOptions": { 5 | "outDir": "./out-tsc/spec", 6 | "types": [ 7 | "jasmine" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "src/**/*.spec.ts", 16 | "src/**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.error(err)); 13 | -------------------------------------------------------------------------------- /src/styles/_fonts.scss: -------------------------------------------------------------------------------- 1 | @font-face { 2 | @include font-ttf("Product Sans", "/assets/fonts/ps/400", 400, normal); 3 | } 4 | 5 | @font-face { 6 | @include font-ttf("Product Sans", "/assets/fonts/ps/700", 700, normal); 7 | } 8 | 9 | @font-face { 10 | @include font-ttf("Product Sans", "/assets/fonts/ps/900", 900, normal); 11 | } 12 | 13 | @font-face { 14 | @include font("Feather", "/assets/fonts/feather/feather", 400, normal); 15 | } 16 | -------------------------------------------------------------------------------- /src/app/global/header/header.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-header', 5 | templateUrl: './header.component.html', 6 | styleUrls: ['./header.component.scss'], 7 | }) 8 | export class HeaderComponent implements OnInit { 9 | shown: boolean = false; 10 | 11 | constructor() {} 12 | 13 | ngOnInit(): void {} 14 | 15 | toggle() { 16 | this.shown = !this.shown; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/app/service/pokemon.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | 3 | import { PokemonService } from './pokemon.service'; 4 | 5 | describe('PokemonService', () => { 6 | let service: PokemonService; 7 | 8 | beforeEach(() => { 9 | TestBed.configureTestingModule({}); 10 | service = TestBed.inject(PokemonService); 11 | }); 12 | 13 | it('should be created', () => { 14 | expect(service).toBeTruthy(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/global/global.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { HeaderComponent } from './header/header.component'; 5 | import { FooterComponent } from './footer/footer.component'; 6 | import { RouterModule } from '@angular/router'; 7 | 8 | @NgModule({ 9 | declarations: [HeaderComponent, FooterComponent], 10 | imports: [CommonModule, RouterModule], 11 | exports: [HeaderComponent, FooterComponent], 12 | }) 13 | export class GlobalModule {} 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */ 2 | { 3 | "compileOnSave": false, 4 | "compilerOptions": { 5 | "baseUrl": "./", 6 | "outDir": "./dist/out-tsc", 7 | "sourceMap": true, 8 | "declaration": false, 9 | "downlevelIteration": true, 10 | "experimentalDecorators": true, 11 | "moduleResolution": "node", 12 | "importHelpers": true, 13 | "target": "es2015", 14 | "module": "es2020", 15 | "lib": [ 16 | "es2018", 17 | "dom" 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { Routes, RouterModule } from '@angular/router'; 3 | import { HomeComponent } from './home/home.component'; 4 | import { PokemonComponent } from './pokemon/pokemon.component'; 5 | 6 | const routes: Routes = [ 7 | { 8 | path: '', component : HomeComponent 9 | }, 10 | { 11 | path: 'pokemon/:id', component : PokemonComponent 12 | }, 13 | ]; 14 | 15 | @NgModule({ 16 | imports: [ 17 | RouterModule.forRoot(routes, { scrollPositionRestoration: 'enabled' }), 18 | ], 19 | exports: [RouterModule], 20 | }) 21 | export class AppRoutingModule {} 22 | -------------------------------------------------------------------------------- /src/app/home/home.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HomeComponent } from './home.component'; 4 | 5 | describe('HomeComponent', () => { 6 | let component: HomeComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ HomeComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(HomeComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /src/app/shared/image/image.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { ImageComponent } from './image.component'; 4 | 5 | describe('ImageComponent', () => { 6 | let component: ImageComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ ImageComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(ImageComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | import { browser, logging } from 'protractor'; 3 | 4 | describe('workspace-project App', () => { 5 | let page: AppPage; 6 | 7 | beforeEach(() => { 8 | page = new AppPage(); 9 | }); 10 | 11 | it('should display welcome message', () => { 12 | page.navigateTo(); 13 | expect(page.getTitleText()).toEqual('devfest-india-web-track app is running!'); 14 | }); 15 | 16 | afterEach(async () => { 17 | // Assert that there are no errors emitted from the browser 18 | const logs = await browser.manage().logs().get(logging.Type.BROWSER); 19 | expect(logs).not.toContain(jasmine.objectContaining({ 20 | level: logging.Level.SEVERE, 21 | } as logging.Entry)); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /src/app/global/footer/footer.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { FooterComponent } from './footer.component'; 4 | 5 | describe('FooterComponent', () => { 6 | let component: FooterComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ FooterComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(FooterComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/global/header/header.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { HeaderComponent } from './header.component'; 4 | 5 | describe('HeaderComponent', () => { 6 | let component: HeaderComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ HeaderComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(HeaderComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/pokemon/pokemon.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { PokemonComponent } from './pokemon.component'; 4 | 5 | describe('PokemonComponent', () => { 6 | let component: PokemonComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async () => { 10 | await TestBed.configureTestingModule({ 11 | declarations: [ PokemonComponent ] 12 | }) 13 | .compileComponents(); 14 | }); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(PokemonComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { HttpClientModule } from '@angular/common/http'; 4 | 5 | import { AppRoutingModule } from './app-routing.module'; 6 | import { AppComponent } from './app.component'; 7 | 8 | import { GlobalModule } from './global/global.module'; 9 | import { HomeComponent } from './home/home.component'; 10 | import { PokemonComponent } from './pokemon/pokemon.component'; 11 | import { SharedModule } from './shared/shared.module'; 12 | 13 | @NgModule({ 14 | declarations: [AppComponent, HomeComponent, PokemonComponent], 15 | imports: [BrowserModule, AppRoutingModule, HttpClientModule, GlobalModule, SharedModule], 16 | providers: [], 17 | bootstrap: [AppComponent], 18 | }) 19 | export class AppModule {} 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | # Only exists if Bazel was run 8 | /bazel-out 9 | 10 | # dependencies 11 | /node_modules 12 | 13 | # profiling files 14 | chrome-profiler-events*.json 15 | speed-measure-plugin*.json 16 | 17 | # IDEs and editors 18 | /.idea 19 | .project 20 | .classpath 21 | .c9/ 22 | *.launch 23 | .settings/ 24 | *.sublime-workspace 25 | 26 | # IDE - VSCode 27 | .vscode/* 28 | !.vscode/settings.json 29 | !.vscode/tasks.json 30 | !.vscode/launch.json 31 | !.vscode/extensions.json 32 | .history/* 33 | 34 | # misc 35 | /.sass-cache 36 | /connect.lock 37 | /coverage 38 | /libpeerconnection.log 39 | npm-debug.log 40 | yarn-error.log 41 | testem.log 42 | /typings 43 | 44 | # System Files 45 | .DS_Store 46 | Thumbs.db 47 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: { 11 | context(path: string, deep?: boolean, filter?: RegExp): { 12 | keys(): string[]; 13 | (id: string): T; 14 | }; 15 | }; 16 | 17 | // First, initialize the Angular testing environment. 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting() 21 | ); 22 | // Then we find all the tests. 23 | const context = require.context('./', true, /\.spec\.ts$/); 24 | // And load the modules. 25 | context.keys().map(context); 26 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below. 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | 5 | # For the full list of supported browsers by the Angular framework, please see: 6 | # https://angular.io/guide/browser-support 7 | 8 | # You can see what browsers were selected by your queries by running: 9 | # npx browserslist 10 | 11 | last 1 Chrome version 12 | last 1 Firefox version 13 | last 2 Edge major versions 14 | last 2 Safari major versions 15 | last 2 iOS major versions 16 | Firefox ESR 17 | not IE 9-10 # Angular support for IE 9-10 has been deprecated and will be removed as of Angular v11. To opt-in, remove the 'not' prefix on this line. 18 | not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. 19 | -------------------------------------------------------------------------------- /src/app/global/header/header.component.scss: -------------------------------------------------------------------------------- 1 | @import "../../../styles/variables"; 2 | 3 | header { 4 | padding: rem(18px) 0; 5 | background-color: $white; 6 | 7 | .logo { 8 | display: inline-block; 9 | width: rem(91px); 10 | height: rem(34px); 11 | background-image: url(../../../assets/images/logo@2x.png); 12 | background-repeat: no-repeat; 13 | background-position: center center; 14 | background-size: cover; 15 | } 16 | 17 | .flex { 18 | align-items: center; 19 | } 20 | 21 | .info { 22 | width: rem(28px); 23 | height: rem(28px); 24 | cursor: pointer; 25 | position: relative; 26 | 27 | i { 28 | position: absolute; 29 | top: 50%; 30 | left: 50%; 31 | transform: translate(-50%, -50%); 32 | color: $blue; 33 | font-size: rem(24px); 34 | line-height: 0; 35 | } 36 | } 37 | 38 | .about { 39 | padding-top: rem(32px); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/styles/_variables.scss: -------------------------------------------------------------------------------- 1 | $transition: all 0.3s linear !default; 2 | 3 | $screen-sm: 767px; 4 | $screen-md: 991px; 5 | $screen-lg: 1200px; 6 | 7 | @function strip-unit($number) { 8 | @if type-of($number) == "number" and not unitless($number) { 9 | @return $number/($number * 0 + 1); 10 | } 11 | 12 | @return $number; 13 | } 14 | 15 | @function rem($value) { 16 | @return #{strip-unit($value) / 14}rem; 17 | } 18 | 19 | $section-padding: rem(85px) 0; 20 | 21 | $blue: #3a7abf; 22 | $yellow: #fbd631; 23 | $white: #ffffff; 24 | $black: #000000; 25 | $dark-grey: #404040; 26 | $grey: #7f7f7f; 27 | $light-grey: #b2b2b2; 28 | $off-white: #f2f2f2; 29 | 30 | $weights: (400, 700, 900) !default; 31 | 32 | $font-sizes: ( 33 | "72": 5.1428571429, 34 | "32": 2.2857142857, 35 | "24": 1.7142857143, 36 | "18": 1.2857142857, 37 | "14": 1, 38 | ) !default; 39 | 40 | $radius: 3px !default; 41 | $default-weight: 400 !default; 42 | 43 | $transition: all 0.3s linear !default; 44 | -------------------------------------------------------------------------------- /src/app/service/pokemon.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { Observable } from 'rxjs'; 4 | import { map } from 'rxjs/operators'; 5 | 6 | export interface PokemonList { 7 | name: string; 8 | url: string; 9 | } 10 | 11 | @Injectable({ 12 | providedIn: 'root' 13 | }) 14 | export class PokemonService { 15 | 16 | constructor(private http: HttpClient) { } 17 | 18 | list(page: number = 0, limit: number = 20): Observable> { 19 | return this.http.get(`https://pokeapi.co/api/v2/pokemon?offset=${page}&limit=${limit}`) 20 | .pipe( 21 | map((response: any) => response.results) 22 | ); 23 | } 24 | 25 | details(id): Observable { 26 | return this.http.get(`https://pokeapi.co/api/v2/pokemon/${id}`); 27 | } 28 | 29 | about(id: string): Observable { 30 | return this.http 31 | .get(`https://pokeapi.co/api/v2/pokemon-species/${id}`); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/styles/mixin/_helpers.scss: -------------------------------------------------------------------------------- 1 | @mixin font($family, $path, $weight, $style){ 2 | font-family: $family; 3 | src:url($path + ".svg"); 4 | src:url($path + ".eot?#iefix") format("embedded-opentype"), 5 | url($path + ".woff") format("woff"), 6 | url($path + ".ttf") format("truetype"), 7 | url($path + ".svg#dripicons-v2") format("svg"); 8 | font-weight: $weight; 9 | font-style: $style; 10 | } 11 | 12 | @mixin font-ttf($family, $path, $weight, $style){ 13 | font-family: $family; 14 | src:url($path + ".ttf") format("opentype"); 15 | font-weight: $weight; 16 | font-style: $style; 17 | } 18 | 19 | @mixin weight(){ 20 | @each $weight in $weights{ 21 | .weight#{$weight} { 22 | font-weight: $weight !important; 23 | } 24 | } 25 | } 26 | 27 | @mixin font-sizes(){ 28 | @each $name, $size in $font-sizes { 29 | .px#{$name} { 30 | font-size: #{$size}rem; 31 | line-height: #{$size + ($size / 2)}rem; 32 | margin-bottom: #{$size / 2}rem; 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // Protractor configuration file, see link for more information 3 | // https://github.com/angular/protractor/blob/master/lib/config.ts 4 | 5 | const { SpecReporter, StacktraceOption } = require('jasmine-spec-reporter'); 6 | 7 | /** 8 | * @type { import("protractor").Config } 9 | */ 10 | exports.config = { 11 | allScriptsTimeout: 11000, 12 | specs: [ 13 | './src/**/*.e2e-spec.ts' 14 | ], 15 | capabilities: { 16 | browserName: 'chrome' 17 | }, 18 | directConnect: true, 19 | baseUrl: 'http://localhost:4200/', 20 | framework: 'jasmine', 21 | jasmineNodeOpts: { 22 | showColors: true, 23 | defaultTimeoutInterval: 30000, 24 | print: function() {} 25 | }, 26 | onPrepare() { 27 | require('ts-node').register({ 28 | project: require('path').join(__dirname, './tsconfig.json') 29 | }); 30 | jasmine.getEnv().addReporter(new SpecReporter({ 31 | spec: { 32 | displayStacktrace: StacktraceOption.PRETTY 33 | } 34 | })); 35 | } 36 | }; -------------------------------------------------------------------------------- /src/app/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Router } from '@angular/router'; 3 | import { 4 | PokemonService, 5 | PokemonList, 6 | } from 'src/app/service/pokemon.service'; 7 | 8 | @Component({ 9 | selector: 'app-home', 10 | templateUrl: './home.component.html', 11 | styleUrls: ['./home.component.scss'], 12 | }) 13 | export class HomeComponent implements OnInit { 14 | constructor( 15 | private pokemon: PokemonService, 16 | private router: Router) { } 17 | 18 | result: Array = []; 19 | page: number = 0; 20 | limit: number = 50; 21 | 22 | loading: boolean = false; 23 | 24 | ngOnInit(): void { 25 | this.fetch(); 26 | } 27 | 28 | private fetch() { 29 | this.loading = true; 30 | 31 | this.pokemon.list(this.page, this.limit).subscribe(res => { 32 | this.loading = false; 33 | this.result = res; 34 | }); 35 | } 36 | 37 | details(id: string) { 38 | this.router.navigateByUrl(`/pokemon/${id}`); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DevfestIndiaWebTrack 2 | 3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.1.3. 4 | 5 | ## Development server 6 | 7 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 8 | 9 | ## Code scaffolding 10 | 11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 12 | 13 | ## Build 14 | 15 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. 16 | 17 | ## Running unit tests 18 | 19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 20 | 21 | ## Running end-to-end tests 22 | 23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 24 | 25 | ## Further help 26 | 27 | To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 28 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client: { 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, './coverage/devfest-india-web-track'), 20 | reports: ['html', 'lcovonly', 'text-summary'], 21 | fixWebpackSourcePaths: true 22 | }, 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false, 30 | restartOnFileChange: true 31 | }); 32 | }; 33 | -------------------------------------------------------------------------------- /src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed } from '@angular/core/testing'; 2 | import { RouterTestingModule } from '@angular/router/testing'; 3 | import { AppComponent } from './app.component'; 4 | 5 | describe('AppComponent', () => { 6 | beforeEach(async () => { 7 | await TestBed.configureTestingModule({ 8 | imports: [ 9 | RouterTestingModule 10 | ], 11 | declarations: [ 12 | AppComponent 13 | ], 14 | }).compileComponents(); 15 | }); 16 | 17 | it('should create the app', () => { 18 | const fixture = TestBed.createComponent(AppComponent); 19 | const app = fixture.componentInstance; 20 | expect(app).toBeTruthy(); 21 | }); 22 | 23 | it(`should have as title 'devfest-india-web-track'`, () => { 24 | const fixture = TestBed.createComponent(AppComponent); 25 | const app = fixture.componentInstance; 26 | expect(app.title).toEqual('devfest-india-web-track'); 27 | }); 28 | 29 | it('should render title', () => { 30 | const fixture = TestBed.createComponent(AppComponent); 31 | fixture.detectChanges(); 32 | const compiled = fixture.nativeElement; 33 | expect(compiled.querySelector('.content span').textContent).toContain('devfest-india-web-track app is running!'); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /src/app/shared/image/image.component.scss: -------------------------------------------------------------------------------- 1 | @import "../../../styles/variables"; 2 | 3 | .image { 4 | position: relative; 5 | width: 100%; 6 | 7 | > img { 8 | width: 100%; 9 | } 10 | 11 | .main { 12 | position: relative; 13 | z-index: 2; 14 | } 15 | 16 | .blurred { 17 | position: absolute; 18 | z-index: 1; 19 | left: rem(10px); 20 | top: rem(10px); 21 | filter: blur(15px); 22 | } 23 | 24 | .loader { 25 | position: absolute; 26 | top: 50%; 27 | left: 50%; 28 | width: rem(32px); 29 | height: rem(32px); 30 | transform: translate(-50%, -50%); 31 | z-index: 9; 32 | 33 | img { 34 | position: absolute; 35 | width: rem(40px); 36 | 37 | &:last-child { 38 | z-index: 2; 39 | border-radius: 50%; 40 | } 41 | 42 | &:first-child { 43 | animation: scale 1s linear infinite; 44 | } 45 | } 46 | } 47 | } 48 | 49 | @keyframes rotate { 50 | 0% { 51 | transform: rotate(0deg); 52 | } 53 | 54 | 100% { 55 | transform: rotate(360deg); 56 | } 57 | } 58 | 59 | @keyframes scale { 60 | 0% { 61 | transform: scale(0.5); 62 | filter: blur(10px); 63 | } 64 | 50% { 65 | transform: scale(2); 66 | filter: blur(20px); 67 | } 68 | 100% { 69 | transform: scale(0.5); 70 | filter: blur(10px); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/app/home/home.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

6 | Showing 7 | 1050 Pokemons 8 |

9 | 10 |
11 |
12 |
13 |
14 |
15 | 21 |
22 |
23 | #{{ pokemon.url.split("/")[6] }} 26 |

{{ pokemon.name }}

27 | 28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "devfest-india-web-track", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "ng": "ng", 6 | "start": "ng serve", 7 | "build": "ng build", 8 | "test": "ng test", 9 | "lint": "ng lint", 10 | "e2e": "ng e2e" 11 | }, 12 | "private": true, 13 | "dependencies": { 14 | "@angular/animations": "~10.1.3", 15 | "@angular/common": "~10.1.3", 16 | "@angular/compiler": "~10.1.3", 17 | "@angular/core": "~10.1.3", 18 | "@angular/forms": "~10.1.3", 19 | "@angular/platform-browser": "~10.1.3", 20 | "@angular/platform-browser-dynamic": "~10.1.3", 21 | "@angular/router": "~10.1.3", 22 | "rxjs": "~6.6.0", 23 | "tslib": "^2.0.0", 24 | "zone.js": "~0.10.2" 25 | }, 26 | "devDependencies": { 27 | "@angular-devkit/build-angular": "~0.1001.3", 28 | "@angular/cli": "~10.1.3", 29 | "@angular/compiler-cli": "~10.1.3", 30 | "@types/node": "^12.11.1", 31 | "@types/jasmine": "~3.5.0", 32 | "@types/jasminewd2": "~2.0.3", 33 | "codelyzer": "^6.0.0", 34 | "jasmine-core": "~3.6.0", 35 | "jasmine-spec-reporter": "~5.0.0", 36 | "karma": "~5.0.0", 37 | "karma-chrome-launcher": "~3.1.0", 38 | "karma-coverage-istanbul-reporter": "~3.0.2", 39 | "karma-jasmine": "~4.0.0", 40 | "karma-jasmine-html-reporter": "^1.5.0", 41 | "protractor": "~7.0.0", 42 | "ts-node": "~8.3.0", 43 | "tslint": "~6.1.0", 44 | "typescript": "~4.0.2" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/app/shared/image/image.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Component, 3 | ElementRef, 4 | Input, 5 | OnInit, 6 | ViewChild, 7 | AfterViewInit, 8 | } from '@angular/core'; 9 | @Component({ 10 | selector: 'app-image', 11 | templateUrl: './image.component.html', 12 | styleUrls: ['./image.component.scss'], 13 | }) 14 | export class ImageComponent implements OnInit, AfterViewInit { 15 | @Input('src') src: string; 16 | @Input('alt') alt: string; 17 | 18 | @Input('shadow') shadow: boolean = true; 19 | 20 | @ViewChild('image') image: ElementRef; 21 | 22 | loaded: boolean = false; 23 | img: string = '../../../assets/images/blank.png'; 24 | 25 | constructor() {} 26 | 27 | ngOnInit(): void {} 28 | 29 | ngAfterViewInit() { 30 | const observer: IntersectionObserver = new IntersectionObserver( 31 | this.inview.bind(this), 32 | { 33 | threshold: 1.0, 34 | rootMargin: '100px', 35 | } 36 | ); 37 | 38 | observer.observe(this.image.nativeElement); 39 | } 40 | 41 | private inview( 42 | entries: IntersectionObserverEntry[], 43 | observer: IntersectionObserver 44 | ) { 45 | entries.forEach((entry: IntersectionObserverEntry) => { 46 | if (entry.intersectionRatio) { 47 | entry.target.addEventListener('load', (event: any) => { 48 | if (event.target.complete) { 49 | this.loaded = true; 50 | this.img = this.src; 51 | } 52 | }); 53 | 54 | entry.target['src'] = this.src; 55 | observer.unobserve(entry.target); 56 | } 57 | }); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/app/pokemon/pokemon.component.scss: -------------------------------------------------------------------------------- 1 | @import "../../styles/variables"; 2 | 3 | .details { 4 | .link { 5 | margin-bottom: rem(32px); 6 | display: inline-block; 7 | position: relative; 8 | z-index: 9; 9 | font-size: rem(16px); 10 | font-weight: 700; 11 | cursor: pointer; 12 | } 13 | 14 | .box { 15 | background-color: $white; 16 | margin-top: rem(80px); 17 | box-shadow: 0 0 rem(5px) rgba($black, 0.16); 18 | border-radius: rem(3px); 19 | padding-bottom: rem(24px); 20 | 21 | label { 22 | font-weight: 900; 23 | color: $light-grey; 24 | } 25 | 26 | .info { 27 | padding: rem(18px) rem(24px) 0 rem(24px); 28 | 29 | h1 { 30 | font-size: rem(52px); 31 | text-transform: capitalize; 32 | margin-top: rem(14px); 33 | } 34 | } 35 | } 36 | 37 | .image { 38 | position: relative; 39 | margin-top: rem(-132px); 40 | width: 100%; 41 | 42 | img { 43 | width: 100%; 44 | } 45 | 46 | .shadow { 47 | background: $black; 48 | height: 30px; 49 | border-radius: 50%; 50 | filter: blur(15px); 51 | width: 80%; 52 | opacity: 0.5; 53 | margin: 0 auto; 54 | } 55 | } 56 | 57 | .block { 58 | margin-top: rem(24px); 59 | 60 | label { 61 | margin-bottom: rem(8px); 62 | display: block; 63 | } 64 | 65 | span { 66 | display: inline-block; 67 | margin-right: 1.5em; 68 | position: relative; 69 | 70 | &:last-child { 71 | margin-right: 0; 72 | 73 | &::after { 74 | content: none; 75 | } 76 | } 77 | 78 | &::after { 79 | position: absolute; 80 | content: "●"; 81 | right: -1.9em; 82 | top: 0; 83 | color: $light-grey; 84 | font-size: 0.5em; 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/app/pokemon/pokemon.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { ActivatedRoute, Params } from '@angular/router'; 3 | 4 | import { PokemonService } from '../service/pokemon.service'; 5 | import { hs } from '../app.utility'; 6 | 7 | @Component({ 8 | selector: 'app-pokemon', 9 | templateUrl: './pokemon.component.html', 10 | styleUrls: ['./pokemon.component.scss'], 11 | }) 12 | export class PokemonComponent implements OnInit { 13 | constructor(private route: ActivatedRoute, private pokemon: PokemonService) { } 14 | 15 | id: string; 16 | details: any = {}; 17 | about: Array = []; 18 | stat: any = {}; 19 | shape: string = ''; 20 | growthRate: string = ''; 21 | 22 | ngOnInit(): void { 23 | this.route.params.forEach((params: Params) => { 24 | const { id } = params; 25 | 26 | this.id = id; 27 | this.fetch(); 28 | }); 29 | } 30 | 31 | private fetch() { 32 | 33 | this.pokemon.details(this.id).subscribe( 34 | res => { 35 | this.details = res; 36 | } 37 | ); 38 | 39 | this.pokemon.about(this.id).subscribe( 40 | res => { 41 | const _arr: Array = []; 42 | this.shape = res.shape.name; 43 | this.growthRate = hs(res.growth_rate.name); 44 | 45 | const name: string = `${res.name.charAt(0).toUpperCase()}${res.name.slice( 46 | 1, 47 | res.name.length 48 | )}`; 49 | 50 | res.flavor_text_entries.forEach((entry: any) => { 51 | if (entry.language.name === 'en') { 52 | _arr.push( 53 | entry.flavor_text 54 | .replace(/\./gi, '. ') 55 | .replace('\n', ' ') 56 | .replace(/\s\s+/g, ' ') 57 | .replace('POKéMON', 'Pokemon') 58 | .replace(new RegExp(name.toUpperCase(), 'g'), name) 59 | ); 60 | } 61 | }); 62 | 63 | this.about = [...new Set(_arr.slice(0, 5))]; 64 | }); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/styles/mixin/_grid.scss: -------------------------------------------------------------------------------- 1 | $gutter: 30px; 2 | $columns: 12; 3 | 4 | $container: ( 5 | "xs": 546, 6 | "sm": 738, 7 | "md": 972, 8 | "lg": 1170, 9 | ) !default; 10 | 11 | $breakpoints: ( 12 | "xs": 0, 13 | "sm": strip-unit($screen-sm), 14 | "md": strip-unit($screen-md), 15 | "lg": strip-unit($screen-lg), 16 | ) !default; 17 | 18 | @mixin clearfix() { 19 | &:before, 20 | &:after { 21 | content: " "; // 1 22 | display: table; // 2 23 | } 24 | &:after { 25 | clear: both; 26 | } 27 | } 28 | 29 | @mixin grid { 30 | .container-fluid { 31 | width: 100%; 32 | margin-left: auto; 33 | margin-right: auto; 34 | padding-left: $gutter / 2; 35 | padding-right: $gutter / 2; 36 | 37 | [class*="col-"] { 38 | position: relative; 39 | width: 100%; 40 | padding-right: $gutter / 2; 41 | padding-left: $gutter / 2; 42 | } 43 | } 44 | 45 | .container { 46 | margin-left: auto; 47 | margin-right: auto; 48 | padding-left: $gutter / 2; 49 | padding-right: $gutter / 2; 50 | 51 | @each $slug, $size in $breakpoints { 52 | @if ($size != 0) { 53 | @media screen and (min-width: $size + 0px) { 54 | width: map-get($container, $slug) + 0px; 55 | } 56 | } @else { 57 | padding-left: $gutter; 58 | padding-right: $gutter; 59 | } 60 | } 61 | 62 | [class*="col-"] { 63 | position: relative; 64 | width: 100%; 65 | padding-right: $gutter / 2; 66 | padding-left: $gutter / 2; 67 | } 68 | } 69 | 70 | @include row(); 71 | 72 | @include columns(); 73 | } 74 | 75 | @mixin mq($breakpoint, $minMax) { 76 | @if ($breakpoint == 0) { 77 | @content; 78 | } @else { 79 | @media screen and (#{$minMax}-width: $breakpoint + 0px) { 80 | @content; 81 | } 82 | } 83 | } 84 | 85 | @mixin columns() { 86 | @each $slug, $size in $breakpoints { 87 | @include mq($size, "min") { 88 | @for $i from 1 through $columns { 89 | @if ($slug != "") { 90 | .col-#{$slug}-#{$i} { 91 | flex-basis: (100 / ($columns / $i)) * 1%; 92 | } 93 | 94 | .col-#{$slug}-offset-#{$i} { 95 | margin-left: (100 / ($columns / $i)) * 1%; 96 | } 97 | } 98 | } 99 | } 100 | } 101 | } 102 | 103 | @mixin row { 104 | .row { 105 | display: flex; 106 | flex-wrap: wrap; 107 | margin-right: -$gutter / 2; 108 | margin-left: -$gutter / 2; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/guide/browser-support 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 22 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 23 | 24 | /** 25 | * Web Animations `@angular/platform-browser/animations` 26 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 27 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 28 | */ 29 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 30 | 31 | /** 32 | * By default, zone.js will patch all possible macroTask and DomEvents 33 | * user can disable parts of macroTask/DomEvents patch by setting following flags 34 | * because those flags need to be set before `zone.js` being loaded, and webpack 35 | * will put import in the top of bundle, so user need to create a separate file 36 | * in this directory (for example: zone-flags.ts), and put the following flags 37 | * into that file, and then add the following code before importing zone.js. 38 | * import './zone-flags'; 39 | * 40 | * The flags allowed in zone-flags.ts are listed here. 41 | * 42 | * The following flags will work for all browsers. 43 | * 44 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 45 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 46 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 47 | * 48 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 49 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 50 | * 51 | * (window as any).__Zone_enable_cross_context_check = true; 52 | * 53 | */ 54 | 55 | /*************************************************************************************************** 56 | * Zone JS is required by default for Angular itself. 57 | */ 58 | import 'zone.js/dist/zone'; // Included with Angular CLI. 59 | 60 | 61 | /*************************************************************************************************** 62 | * APPLICATION IMPORTS 63 | */ 64 | -------------------------------------------------------------------------------- /src/styles/pokemon.scss: -------------------------------------------------------------------------------- 1 | @import "./variables"; 2 | @import "./mixin/grid"; 3 | @import "./mixin/helpers"; 4 | @import "./fonts"; 5 | @import "./icons"; 6 | 7 | :root { 8 | font-size: 14px; 9 | } 10 | 11 | @media screen and (max-width: $screen-sm) { 12 | :root { 13 | font-size: 14px; 14 | } 15 | } 16 | 17 | @media screen and (min-width: $screen-sm + 1) and (max-width: $screen-md - 1) { 18 | :root { 19 | font-size: 14px; 20 | } 21 | } 22 | 23 | @media screen and (min-width: $screen-md + 1) and (max-width: $screen-lg - 1) { 24 | :root { 25 | font-size: 16px; 26 | } 27 | } 28 | 29 | @media screen and (min-width: $screen-lg) { 30 | :root { 31 | font-size: 16px; 32 | } 33 | } 34 | 35 | @include grid(); 36 | @include weight(); 37 | @include font-sizes(); 38 | 39 | *, 40 | html { 41 | box-sizing: border-box; 42 | padding: 0; 43 | margin: 0; 44 | font-family: "Product Sans", sans-serif; 45 | list-style: none; 46 | text-decoration: none; 47 | box-sizing: border-box; 48 | -webkit-font-smoothing: antialiased; 49 | -moz-osx-font-smoothing: grayscale; 50 | } 51 | 52 | html, 53 | body { 54 | background: #fafafa; 55 | font-family: "Product Sans", sans-serif; 56 | color: $black; 57 | font-size: rem(14px); 58 | } 59 | 60 | h1, 61 | h2, 62 | h3 { 63 | font-weight: 900; 64 | color: $black; 65 | } 66 | 67 | .flex { 68 | display: flex; 69 | 70 | &.sb { 71 | justify-content: space-between; 72 | } 73 | } 74 | 75 | .clg { 76 | color: $light-grey; 77 | } 78 | 79 | .capitalize { 80 | text-transform: capitalize; 81 | } 82 | 83 | section { 84 | padding: rem(64px) 0; 85 | 86 | &.first { 87 | padding-top: rem(32px); 88 | } 89 | } 90 | 91 | .pcard { 92 | width: 100%; 93 | margin-top: rem(32px); 94 | cursor: pointer; 95 | transition: $transition; 96 | 97 | .info { 98 | background-color: $white; 99 | padding: rem(180px) rem(24px) rem(24) rem(24px); 100 | margin-top: rem(-170px); 101 | box-shadow: 0 0 rem(2px) rgba($black, 0.16); 102 | transition: $transition; 103 | border-radius: $radius; 104 | position: relative; 105 | 106 | h2 { 107 | text-transform: capitalize; 108 | margin-top: rem(12px); 109 | } 110 | 111 | .ico { 112 | position: absolute; 113 | right: rem(18px); 114 | bottom: rem(20px); 115 | font-size: rem(24px); 116 | opacity: 0; 117 | transition: $transition; 118 | color: $light-grey; 119 | } 120 | } 121 | 122 | &:hover { 123 | transform: translateY(-10px); 124 | 125 | .info { 126 | box-shadow: 0 0 rem(16px) rgba($black, 0.16); 127 | } 128 | 129 | .ico { 130 | opacity: 1; 131 | } 132 | } 133 | } 134 | 135 | input[type="range"] { 136 | width: 100%; 137 | 138 | &:focus { 139 | outline: none; 140 | } 141 | } 142 | 143 | .input { 144 | padding: rem(8px) 0; 145 | border: none; 146 | border-bottom: 1px solid $light-grey; 147 | width: 100%; 148 | font-size: rem(18px); 149 | outline: none; 150 | } 151 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint:recommended", 3 | "rulesDirectory": [ 4 | "codelyzer" 5 | ], 6 | "rules": { 7 | "align": { 8 | "options": [ 9 | "parameters", 10 | "statements" 11 | ] 12 | }, 13 | "array-type": false, 14 | "arrow-return-shorthand": true, 15 | "curly": true, 16 | "deprecation": { 17 | "severity": "warning" 18 | }, 19 | "eofline": true, 20 | "import-blacklist": [ 21 | true, 22 | "rxjs/Rx" 23 | ], 24 | "import-spacing": true, 25 | "indent": { 26 | "options": [ 27 | "spaces" 28 | ] 29 | }, 30 | "max-classes-per-file": false, 31 | "max-line-length": [ 32 | true, 33 | 140 34 | ], 35 | "member-ordering": [ 36 | true, 37 | { 38 | "order": [ 39 | "static-field", 40 | "instance-field", 41 | "static-method", 42 | "instance-method" 43 | ] 44 | } 45 | ], 46 | "no-console": [ 47 | true, 48 | "debug", 49 | "info", 50 | "time", 51 | "timeEnd", 52 | "trace" 53 | ], 54 | "no-empty": false, 55 | "no-inferrable-types": [ 56 | true, 57 | "ignore-params" 58 | ], 59 | "no-non-null-assertion": true, 60 | "no-redundant-jsdoc": true, 61 | "no-switch-case-fall-through": true, 62 | "no-var-requires": false, 63 | "object-literal-key-quotes": [ 64 | true, 65 | "as-needed" 66 | ], 67 | "quotemark": [ 68 | true, 69 | "single" 70 | ], 71 | "semicolon": { 72 | "options": [ 73 | "always" 74 | ] 75 | }, 76 | "space-before-function-paren": { 77 | "options": { 78 | "anonymous": "never", 79 | "asyncArrow": "always", 80 | "constructor": "never", 81 | "method": "never", 82 | "named": "never" 83 | } 84 | }, 85 | "typedef": [ 86 | true, 87 | "call-signature" 88 | ], 89 | "typedef-whitespace": { 90 | "options": [ 91 | { 92 | "call-signature": "nospace", 93 | "index-signature": "nospace", 94 | "parameter": "nospace", 95 | "property-declaration": "nospace", 96 | "variable-declaration": "nospace" 97 | }, 98 | { 99 | "call-signature": "onespace", 100 | "index-signature": "onespace", 101 | "parameter": "onespace", 102 | "property-declaration": "onespace", 103 | "variable-declaration": "onespace" 104 | } 105 | ] 106 | }, 107 | "variable-name": { 108 | "options": [ 109 | "ban-keywords", 110 | "check-format", 111 | "allow-pascal-case" 112 | ] 113 | }, 114 | "whitespace": { 115 | "options": [ 116 | "check-branch", 117 | "check-decl", 118 | "check-operator", 119 | "check-separator", 120 | "check-type", 121 | "check-typecast" 122 | ] 123 | }, 124 | "component-class-suffix": true, 125 | "contextual-lifecycle": true, 126 | "directive-class-suffix": true, 127 | "no-conflicting-lifecycle": true, 128 | "no-host-metadata-property": true, 129 | "no-input-rename": true, 130 | "no-inputs-metadata-property": true, 131 | "no-output-native": true, 132 | "no-output-on-prefix": true, 133 | "no-output-rename": true, 134 | "no-outputs-metadata-property": true, 135 | "template-banana-in-box": true, 136 | "template-no-negated-async": true, 137 | "use-lifecycle-interface": true, 138 | "use-pipe-transform-interface": true, 139 | "directive-selector": [ 140 | true, 141 | "attribute", 142 | "app", 143 | "camelCase" 144 | ], 145 | "component-selector": [ 146 | true, 147 | "element", 148 | "app", 149 | "kebab-case" 150 | ] 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "devfest-india-web-track": { 7 | "projectType": "application", 8 | "schematics": { 9 | "@schematics/angular:component": { 10 | "style": "scss" 11 | } 12 | }, 13 | "root": "", 14 | "sourceRoot": "src", 15 | "prefix": "app", 16 | "architect": { 17 | "build": { 18 | "builder": "@angular-devkit/build-angular:browser", 19 | "options": { 20 | "outputPath": "dist/devfest-india-web-track", 21 | "index": "src/index.html", 22 | "main": "src/main.ts", 23 | "polyfills": "src/polyfills.ts", 24 | "tsConfig": "tsconfig.app.json", 25 | "aot": true, 26 | "assets": [ 27 | "src/favicon.ico", 28 | "src/assets" 29 | ], 30 | "styles": [ 31 | "src/styles/pokemon.scss" 32 | ], 33 | "scripts": [] 34 | }, 35 | "configurations": { 36 | "production": { 37 | "fileReplacements": [ 38 | { 39 | "replace": "src/environments/environment.ts", 40 | "with": "src/environments/environment.prod.ts" 41 | } 42 | ], 43 | "optimization": true, 44 | "outputHashing": "all", 45 | "sourceMap": false, 46 | "extractCss": true, 47 | "namedChunks": false, 48 | "extractLicenses": true, 49 | "vendorChunk": false, 50 | "buildOptimizer": true, 51 | "budgets": [ 52 | { 53 | "type": "initial", 54 | "maximumWarning": "2mb", 55 | "maximumError": "5mb" 56 | }, 57 | { 58 | "type": "anyComponentStyle", 59 | "maximumWarning": "6kb", 60 | "maximumError": "10kb" 61 | } 62 | ] 63 | } 64 | } 65 | }, 66 | "serve": { 67 | "builder": "@angular-devkit/build-angular:dev-server", 68 | "options": { 69 | "browserTarget": "devfest-india-web-track:build" 70 | }, 71 | "configurations": { 72 | "production": { 73 | "browserTarget": "devfest-india-web-track:build:production" 74 | } 75 | } 76 | }, 77 | "extract-i18n": { 78 | "builder": "@angular-devkit/build-angular:extract-i18n", 79 | "options": { 80 | "browserTarget": "devfest-india-web-track:build" 81 | } 82 | }, 83 | "test": { 84 | "builder": "@angular-devkit/build-angular:karma", 85 | "options": { 86 | "main": "src/test.ts", 87 | "polyfills": "src/polyfills.ts", 88 | "tsConfig": "tsconfig.spec.json", 89 | "karmaConfig": "karma.conf.js", 90 | "assets": [ 91 | "src/favicon.ico", 92 | "src/assets" 93 | ], 94 | "styles": [ 95 | "src/styles.scss" 96 | ], 97 | "scripts": [] 98 | } 99 | }, 100 | "lint": { 101 | "builder": "@angular-devkit/build-angular:tslint", 102 | "options": { 103 | "tsConfig": [ 104 | "tsconfig.app.json", 105 | "tsconfig.spec.json", 106 | "e2e/tsconfig.json" 107 | ], 108 | "exclude": [ 109 | "**/node_modules/**" 110 | ] 111 | } 112 | }, 113 | "e2e": { 114 | "builder": "@angular-devkit/build-angular:protractor", 115 | "options": { 116 | "protractorConfig": "e2e/protractor.conf.js", 117 | "devServerTarget": "devfest-india-web-track:serve" 118 | }, 119 | "configurations": { 120 | "production": { 121 | "devServerTarget": "devfest-india-web-track:serve:production" 122 | } 123 | } 124 | } 125 | } 126 | }}, 127 | "defaultProject": "devfest-india-web-track" 128 | } 129 | -------------------------------------------------------------------------------- /src/app/pokemon/pokemon.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | Back to list 8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | 22 |
23 |
24 |
25 |
26 |
27 | 28 |

{{ details.name }}

29 | 30 |
31 | 32 |

{{ about.join("") }}

33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |

Stats

41 | 42 |
43 |
44 |
45 | 46 |

{{ stat.hp }}

47 |
48 |
49 |
50 |
51 | 52 |

{{ stat.attack }}

53 |
54 |
55 |
56 |
57 | 58 |

{{ stat.defense }}

59 |
60 |
61 |
62 |
63 | 64 |

{{ stat.speed }}

65 |
66 |
67 |
68 |
69 | 70 |

{{ stat["special-attack"] }}

71 |
72 |
73 |
74 |
75 | 76 |

{{ stat["special-defense"] }}

77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 | 86 |

87 | {{ move.move.name }} 92 |

93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 | 104 |

{{ details.weight }}

105 |
106 |
107 |
108 |
109 | 110 |

{{ details.height }}

111 |
112 |
113 |
114 |
115 | 116 |

{{ details.base_experience }}

117 |
118 |
119 |
120 |
121 | 122 |

{{ shape }}

123 |
124 |
125 |
126 |
127 |
128 |
129 | 130 |

131 | {{ type.type.name }} 136 |

137 |
138 |
139 |
140 |
141 |
142 |
143 | 144 |

145 | {{ ability.ability.name }} 150 |

151 |
152 |
153 |
154 |
155 |
156 |
157 | 158 |

159 | {{ growthRate }} 160 |

161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 | -------------------------------------------------------------------------------- /src/styles/_icons.scss: -------------------------------------------------------------------------------- 1 | [class^="icon-"], 2 | [class*=" icon-"] { 3 | display: inline-block; 4 | width: 1em; 5 | height: 1em; 6 | position: relative; 7 | } 8 | 9 | [class^="icon-"]:before, 10 | [class*=" icon-"]:before { 11 | position: absolute; 12 | top: 50%; 13 | left: 50%; 14 | transform: translate(-50%, -50%); 15 | font-family: "Feather" !important; 16 | font-style: normal !important; 17 | font-weight: normal !important; 18 | font-variant: normal !important; 19 | text-transform: none !important; 20 | speak: none; 21 | -webkit-font-smoothing: antialiased; 22 | -moz-osx-font-smoothing: grayscale; 23 | margin-top: 0.1em; 24 | } 25 | 26 | .icon-activity:before { 27 | content: "\61"; 28 | } 29 | .icon-airplay:before { 30 | content: "\62"; 31 | } 32 | .icon-alert-circle:before { 33 | content: "\63"; 34 | } 35 | .icon-alert-octagon:before { 36 | content: "\64"; 37 | } 38 | .icon-alert-triangle:before { 39 | content: "\65"; 40 | } 41 | .icon-align-center:before { 42 | content: "\67"; 43 | } 44 | .icon-align-justify:before { 45 | content: "\69"; 46 | } 47 | .icon-align-left:before { 48 | content: "\6b"; 49 | } 50 | .icon-align-right:before { 51 | content: "\6d"; 52 | } 53 | .icon-anchor:before { 54 | content: "\6e"; 55 | } 56 | .icon-aperture:before { 57 | content: "\6f"; 58 | } 59 | .icon-archive:before { 60 | content: "\70"; 61 | } 62 | .icon-arrow-down:before { 63 | content: "\71"; 64 | } 65 | .icon-arrow-down-circle:before { 66 | content: "\72"; 67 | } 68 | .icon-arrow-down-left:before { 69 | content: "\73"; 70 | } 71 | .icon-arrow-down-right:before { 72 | content: "\74"; 73 | } 74 | .icon-arrow-left:before { 75 | content: "\75"; 76 | } 77 | .icon-arrow-left-circle:before { 78 | content: "\76"; 79 | } 80 | .icon-arrow-right:before { 81 | content: "\77"; 82 | } 83 | .icon-arrow-right-circle:before { 84 | content: "\78"; 85 | } 86 | .icon-arrow-up:before { 87 | content: "\79"; 88 | } 89 | .icon-arrow-up-circle:before { 90 | content: "\7a"; 91 | } 92 | .icon-arrow-up-left:before { 93 | content: "\41"; 94 | } 95 | .icon-arrow-up-right:before { 96 | content: "\42"; 97 | } 98 | .icon-at-sign:before { 99 | content: "\43"; 100 | } 101 | .icon-award:before { 102 | content: "\44"; 103 | } 104 | .icon-bar-chart:before { 105 | content: "\45"; 106 | } 107 | .icon-bar-chart-2:before { 108 | content: "\46"; 109 | } 110 | .icon-battery:before { 111 | content: "\47"; 112 | } 113 | .icon-battery-charging:before { 114 | content: "\48"; 115 | } 116 | .icon-bell:before { 117 | content: "\49"; 118 | } 119 | .icon-bell-off:before { 120 | content: "\4a"; 121 | } 122 | .icon-bluetooth:before { 123 | content: "\4b"; 124 | } 125 | .icon-bold:before { 126 | content: "\4c"; 127 | } 128 | .icon-book:before { 129 | content: "\4d"; 130 | } 131 | .icon-book-open:before { 132 | content: "\4e"; 133 | } 134 | .icon-bookmark:before { 135 | content: "\4f"; 136 | } 137 | .icon-box:before { 138 | content: "\50"; 139 | } 140 | .icon-briefcase:before { 141 | content: "\51"; 142 | } 143 | .icon-calendar:before { 144 | content: "\52"; 145 | } 146 | .icon-camera:before { 147 | content: "\53"; 148 | } 149 | .icon-camera-off:before { 150 | content: "\54"; 151 | } 152 | .icon-cast:before { 153 | content: "\55"; 154 | } 155 | .icon-check:before { 156 | content: "\56"; 157 | } 158 | .icon-check-circle:before { 159 | content: "\57"; 160 | } 161 | .icon-check-square:before { 162 | content: "\58"; 163 | } 164 | .icon-chevron-down:before { 165 | content: "\59"; 166 | } 167 | .icon-chevron-left:before { 168 | content: "\5a"; 169 | } 170 | .icon-chevron-right:before { 171 | content: "\30"; 172 | } 173 | .icon-chevron-up:before { 174 | content: "\31"; 175 | } 176 | .icon-chevrons-down:before { 177 | content: "\32"; 178 | } 179 | .icon-chevrons-left:before { 180 | content: "\33"; 181 | } 182 | .icon-chevrons-right:before { 183 | content: "\34"; 184 | } 185 | .icon-chevrons-up:before { 186 | content: "\35"; 187 | } 188 | .icon-chrome:before { 189 | content: "\36"; 190 | } 191 | .icon-circle:before { 192 | content: "\37"; 193 | } 194 | .icon-clipboard:before { 195 | content: "\38"; 196 | } 197 | .icon-clock:before { 198 | content: "\39"; 199 | } 200 | .icon-cloud:before { 201 | content: "\21"; 202 | } 203 | .icon-cloud-drizzle:before { 204 | content: "\22"; 205 | } 206 | .icon-cloud-lightning:before { 207 | content: "\23"; 208 | } 209 | .icon-cloud-off:before { 210 | content: "\24"; 211 | } 212 | .icon-cloud-rain:before { 213 | content: "\25"; 214 | } 215 | .icon-cloud-snow:before { 216 | content: "\26"; 217 | } 218 | .icon-code:before { 219 | content: "\27"; 220 | } 221 | .icon-codepen:before { 222 | content: "\28"; 223 | } 224 | .icon-codesandbox:before { 225 | content: "\29"; 226 | } 227 | .icon-coffee:before { 228 | content: "\2a"; 229 | } 230 | .icon-columns:before { 231 | content: "\2b"; 232 | } 233 | .icon-command:before { 234 | content: "\2c"; 235 | } 236 | .icon-compass:before { 237 | content: "\2d"; 238 | } 239 | .icon-copy:before { 240 | content: "\2e"; 241 | } 242 | .icon-corner-down-left:before { 243 | content: "\2f"; 244 | } 245 | .icon-corner-down-right:before { 246 | content: "\3a"; 247 | } 248 | .icon-corner-left-down:before { 249 | content: "\3b"; 250 | } 251 | .icon-corner-left-up:before { 252 | content: "\3c"; 253 | } 254 | .icon-corner-right-down:before { 255 | content: "\3d"; 256 | } 257 | .icon-corner-right-up:before { 258 | content: "\3e"; 259 | } 260 | .icon-corner-up-left:before { 261 | content: "\3f"; 262 | } 263 | .icon-corner-up-right:before { 264 | content: "\40"; 265 | } 266 | .icon-cpu:before { 267 | content: "\5b"; 268 | } 269 | .icon-credit-card:before { 270 | content: "\5d"; 271 | } 272 | .icon-crop:before { 273 | content: "\5e"; 274 | } 275 | .icon-crosshair:before { 276 | content: "\5f"; 277 | } 278 | .icon-database:before { 279 | content: "\60"; 280 | } 281 | .icon-delete:before { 282 | content: "\7b"; 283 | } 284 | .icon-disc:before { 285 | content: "\7c"; 286 | } 287 | .icon-dollar-sign:before { 288 | content: "\7d"; 289 | } 290 | .icon-download:before { 291 | content: "\7e"; 292 | } 293 | .icon-download-cloud:before { 294 | content: "\5c"; 295 | } 296 | .icon-droplet:before { 297 | content: "\e000"; 298 | } 299 | .icon-edit:before { 300 | content: "\e001"; 301 | } 302 | .icon-edit-2:before { 303 | content: "\e002"; 304 | } 305 | .icon-edit-3:before { 306 | content: "\e003"; 307 | } 308 | .icon-external-link:before { 309 | content: "\e004"; 310 | } 311 | .icon-eye:before { 312 | content: "\e005"; 313 | } 314 | .icon-eye-off:before { 315 | content: "\e006"; 316 | } 317 | .icon-f-like-filled:before { 318 | content: "\e007"; 319 | } 320 | .icon-facebook:before { 321 | content: "\e008"; 322 | } 323 | .icon-fast-forward:before { 324 | content: "\e009"; 325 | } 326 | .icon-feather:before { 327 | content: "\e00a"; 328 | } 329 | .icon-figma:before { 330 | content: "\e00b"; 331 | } 332 | .icon-file:before { 333 | content: "\e00c"; 334 | } 335 | .icon-file-minus:before { 336 | content: "\e00d"; 337 | } 338 | .icon-file-plus:before { 339 | content: "\e00e"; 340 | } 341 | .icon-file-text:before { 342 | content: "\e00f"; 343 | } 344 | .icon-film:before { 345 | content: "\e010"; 346 | } 347 | .icon-filter:before { 348 | content: "\e011"; 349 | } 350 | .icon-flag:before { 351 | content: "\e012"; 352 | } 353 | .icon-folder:before { 354 | content: "\e013"; 355 | } 356 | .icon-folder-minus:before { 357 | content: "\e014"; 358 | } 359 | .icon-folder-plus:before { 360 | content: "\e015"; 361 | } 362 | .icon-framer:before { 363 | content: "\e016"; 364 | } 365 | .icon-frown:before { 366 | content: "\e017"; 367 | } 368 | .icon-gift:before { 369 | content: "\e018"; 370 | } 371 | .icon-git-branch:before { 372 | content: "\e019"; 373 | } 374 | .icon-git-commit:before { 375 | content: "\e01a"; 376 | } 377 | .icon-git-merge:before { 378 | content: "\e01b"; 379 | } 380 | .icon-git-pull-request:before { 381 | content: "\e01c"; 382 | } 383 | .icon-github:before { 384 | content: "\e01d"; 385 | } 386 | .icon-gitlab:before { 387 | content: "\e01e"; 388 | } 389 | .icon-globe:before { 390 | content: "\e01f"; 391 | } 392 | .icon-grid:before { 393 | content: "\e020"; 394 | } 395 | .icon-hard-drive:before { 396 | content: "\e021"; 397 | } 398 | .icon-hash:before { 399 | content: "\e022"; 400 | } 401 | .icon-headphones:before { 402 | content: "\e023"; 403 | } 404 | .icon-heart:before { 405 | content: "\e024"; 406 | } 407 | .icon-help-circle:before { 408 | content: "\e025"; 409 | } 410 | .icon-hexagon:before { 411 | content: "\e026"; 412 | } 413 | .icon-home:before { 414 | content: "\e027"; 415 | } 416 | .icon-i-comment:before { 417 | content: "\e028"; 418 | } 419 | .icon-i-like:before { 420 | content: "\e029"; 421 | } 422 | .icon-i-like-filled:before { 423 | content: "\e02a"; 424 | } 425 | .icon-i-share:before { 426 | content: "\e02b"; 427 | } 428 | .icon-image:before { 429 | content: "\e02c"; 430 | } 431 | .icon-inbox:before { 432 | content: "\e02d"; 433 | } 434 | .icon-info:before { 435 | content: "\e02e"; 436 | } 437 | .icon-instagram:before { 438 | content: "\e02f"; 439 | } 440 | .icon-italic:before { 441 | content: "\e030"; 442 | } 443 | .icon-key:before { 444 | content: "\e031"; 445 | } 446 | .icon-layer-back:before { 447 | content: "\e032"; 448 | } 449 | .icon-layer-backward:before { 450 | content: "\e033"; 451 | } 452 | .icon-layer-forward:before { 453 | content: "\e034"; 454 | } 455 | .icon-layer-front:before { 456 | content: "\e035"; 457 | } 458 | .icon-layers:before { 459 | content: "\e036"; 460 | } 461 | .icon-layout:before { 462 | content: "\e037"; 463 | } 464 | .icon-life-buoy:before { 465 | content: "\e038"; 466 | } 467 | .icon-link:before { 468 | content: "\e039"; 469 | } 470 | .icon-link-2:before { 471 | content: "\e03a"; 472 | } 473 | .icon-linkedin:before { 474 | content: "\e03b"; 475 | } 476 | .icon-list:before { 477 | content: "\e03c"; 478 | } 479 | .icon-list-num:before { 480 | content: "\e03d"; 481 | } 482 | .icon-loader:before { 483 | content: "\e03e"; 484 | } 485 | .icon-lock:before { 486 | content: "\e03f"; 487 | } 488 | .icon-log-in:before { 489 | content: "\e040"; 490 | } 491 | .icon-log-out:before { 492 | content: "\e041"; 493 | } 494 | .icon-mail:before { 495 | content: "\e042"; 496 | } 497 | .icon-map:before { 498 | content: "\e043"; 499 | } 500 | .icon-map-pin:before { 501 | content: "\e044"; 502 | } 503 | .icon-maximise-3:before { 504 | content: "\e045"; 505 | } 506 | .icon-maximize:before { 507 | content: "\e046"; 508 | } 509 | .icon-maximize-2:before { 510 | content: "\e047"; 511 | } 512 | .icon-meh:before { 513 | content: "\e048"; 514 | } 515 | .icon-menu:before { 516 | content: "\e049"; 517 | } 518 | .icon-message-circle:before { 519 | content: "\e04a"; 520 | } 521 | .icon-message-square:before { 522 | content: "\e04b"; 523 | } 524 | .icon-mic:before { 525 | content: "\e04c"; 526 | } 527 | .icon-mic-off:before { 528 | content: "\e04d"; 529 | } 530 | .icon-minimize:before { 531 | content: "\e04e"; 532 | } 533 | .icon-minimize-2:before { 534 | content: "\e04f"; 535 | } 536 | .icon-minimize-3:before { 537 | content: "\e050"; 538 | } 539 | .icon-minus:before { 540 | content: "\e051"; 541 | } 542 | .icon-minus-circle:before { 543 | content: "\e052"; 544 | } 545 | .icon-minus-square:before { 546 | content: "\e053"; 547 | } 548 | .icon-monitor:before { 549 | content: "\e054"; 550 | } 551 | .icon-moon:before { 552 | content: "\e055"; 553 | } 554 | .icon-more-horizontal:before { 555 | content: "\e056"; 556 | } 557 | .icon-more-vertical:before { 558 | content: "\e057"; 559 | } 560 | .icon-mouse-pointer:before { 561 | content: "\e058"; 562 | } 563 | .icon-move:before { 564 | content: "\e059"; 565 | } 566 | .icon-music:before { 567 | content: "\e05a"; 568 | } 569 | .icon-navigation:before { 570 | content: "\e05b"; 571 | } 572 | .icon-navigation-2:before { 573 | content: "\e05c"; 574 | } 575 | .icon-octagon:before { 576 | content: "\e05d"; 577 | } 578 | .icon-package:before { 579 | content: "\e05e"; 580 | } 581 | .icon-paperclip:before { 582 | content: "\e05f"; 583 | } 584 | .icon-pause:before { 585 | content: "\e060"; 586 | } 587 | .icon-pause-circle:before { 588 | content: "\e061"; 589 | } 590 | .icon-pen-tool:before { 591 | content: "\e062"; 592 | } 593 | .icon-percent:before { 594 | content: "\e063"; 595 | } 596 | .icon-phone:before { 597 | content: "\e064"; 598 | } 599 | .icon-phone-call:before { 600 | content: "\e065"; 601 | } 602 | .icon-phone-forwarded:before { 603 | content: "\e066"; 604 | } 605 | .icon-phone-incoming:before { 606 | content: "\e067"; 607 | } 608 | .icon-phone-missed:before { 609 | content: "\e068"; 610 | } 611 | .icon-phone-off:before { 612 | content: "\e069"; 613 | } 614 | .icon-phone-outgoing:before { 615 | content: "\e06a"; 616 | } 617 | .icon-pie-chart:before { 618 | content: "\e06b"; 619 | } 620 | .icon-play:before { 621 | content: "\e06c"; 622 | } 623 | .icon-play-circle:before { 624 | content: "\e06d"; 625 | } 626 | .icon-plus:before { 627 | content: "\e06e"; 628 | } 629 | .icon-plus-circle:before { 630 | content: "\e06f"; 631 | } 632 | .icon-plus-square:before { 633 | content: "\e070"; 634 | } 635 | .icon-pocket:before { 636 | content: "\e071"; 637 | } 638 | .icon-position-bottom:before { 639 | content: "\e072"; 640 | } 641 | .icon-position-center:before { 642 | content: "\e073"; 643 | } 644 | .icon-position-left:before { 645 | content: "\e074"; 646 | } 647 | .icon-position-middle:before { 648 | content: "\e075"; 649 | } 650 | .icon-position-right:before { 651 | content: "\e076"; 652 | } 653 | .icon-position-top:before { 654 | content: "\e077"; 655 | } 656 | .icon-power:before { 657 | content: "\e078"; 658 | } 659 | .icon-printer:before { 660 | content: "\e079"; 661 | } 662 | .icon-radio:before { 663 | content: "\e07a"; 664 | } 665 | .icon-refresh-ccw:before { 666 | content: "\e07b"; 667 | } 668 | .icon-refresh-cw:before { 669 | content: "\e07c"; 670 | } 671 | .icon-repeat:before { 672 | content: "\e07d"; 673 | } 674 | .icon-rewind:before { 675 | content: "\e07e"; 676 | } 677 | .icon-rotate-ccw:before { 678 | content: "\e07f"; 679 | } 680 | .icon-rotate-cw:before { 681 | content: "\e080"; 682 | } 683 | .icon-rss:before { 684 | content: "\e081"; 685 | } 686 | .icon-save:before { 687 | content: "\e082"; 688 | } 689 | .icon-scissors:before { 690 | content: "\e083"; 691 | } 692 | .icon-search:before { 693 | content: "\e084"; 694 | } 695 | .icon-send:before { 696 | content: "\e085"; 697 | } 698 | .icon-server:before { 699 | content: "\e086"; 700 | } 701 | .icon-settings:before { 702 | content: "\e087"; 703 | } 704 | .icon-share:before { 705 | content: "\e088"; 706 | } 707 | .icon-share-2:before { 708 | content: "\e089"; 709 | } 710 | .icon-shield:before { 711 | content: "\e08a"; 712 | } 713 | .icon-shield-off:before { 714 | content: "\e08b"; 715 | } 716 | .icon-shopping-bag:before { 717 | content: "\e08c"; 718 | } 719 | .icon-shopping-cart:before { 720 | content: "\e08d"; 721 | } 722 | .icon-shuffle:before { 723 | content: "\e08e"; 724 | } 725 | .icon-sidebar:before { 726 | content: "\e08f"; 727 | } 728 | .icon-skip-back:before { 729 | content: "\e090"; 730 | } 731 | .icon-skip-forward:before { 732 | content: "\e091"; 733 | } 734 | .icon-slack:before { 735 | content: "\e092"; 736 | } 737 | .icon-slash:before { 738 | content: "\e093"; 739 | } 740 | .icon-sliders:before { 741 | content: "\e094"; 742 | } 743 | .icon-smartphone:before { 744 | content: "\e095"; 745 | } 746 | .icon-smile:before { 747 | content: "\e096"; 748 | } 749 | .icon-sort-down:before { 750 | content: "\e097"; 751 | } 752 | .icon-sort-up:before { 753 | content: "\e098"; 754 | } 755 | .icon-speaker:before { 756 | content: "\e099"; 757 | } 758 | .icon-square:before { 759 | content: "\e09a"; 760 | } 761 | .icon-star:before { 762 | content: "\e09b"; 763 | } 764 | .icon-stop-circle:before { 765 | content: "\e09c"; 766 | } 767 | .icon-sun:before { 768 | content: "\e09d"; 769 | } 770 | .icon-sunrise:before { 771 | content: "\e09e"; 772 | } 773 | .icon-sunset:before { 774 | content: "\e09f"; 775 | } 776 | .icon-t-like:before { 777 | content: "\e0a0"; 778 | } 779 | .icon-t-like-filled:before { 780 | content: "\e0a1"; 781 | } 782 | .icon-t-reply:before { 783 | content: "\e0a2"; 784 | } 785 | .icon-t-retweet:before { 786 | content: "\e0a3"; 787 | } 788 | .icon-tablet:before { 789 | content: "\e0a4"; 790 | } 791 | .icon-tag:before { 792 | content: "\e0a5"; 793 | } 794 | .icon-target:before { 795 | content: "\e0a6"; 796 | } 797 | .icon-terminal:before { 798 | content: "\e0a7"; 799 | } 800 | .icon-thermometer:before { 801 | content: "\e0a8"; 802 | } 803 | .icon-thumbs-down:before { 804 | content: "\e0a9"; 805 | } 806 | .icon-thumbs-up:before { 807 | content: "\e0aa"; 808 | } 809 | .icon-toggle-left:before { 810 | content: "\e0ab"; 811 | } 812 | .icon-toggle-right:before { 813 | content: "\e0ac"; 814 | } 815 | .icon-tool:before { 816 | content: "\e0ad"; 817 | } 818 | .icon-trash:before { 819 | content: "\e0ae"; 820 | } 821 | .icon-trash-2:before { 822 | content: "\e0af"; 823 | } 824 | .icon-trello:before { 825 | content: "\e0b0"; 826 | } 827 | .icon-trending-down:before { 828 | content: "\e0b1"; 829 | } 830 | .icon-trending-up:before { 831 | content: "\e0b2"; 832 | } 833 | .icon-triangle:before { 834 | content: "\e0b3"; 835 | } 836 | .icon-truck:before { 837 | content: "\e0b4"; 838 | } 839 | .icon-tv:before { 840 | content: "\e0b5"; 841 | } 842 | .icon-twitch:before { 843 | content: "\e0b6"; 844 | } 845 | .icon-twitter:before { 846 | content: "\e0b7"; 847 | } 848 | .icon-type:before { 849 | content: "\e0b8"; 850 | } 851 | .icon-umbrella:before { 852 | content: "\e0b9"; 853 | } 854 | .icon-underline:before { 855 | content: "\e0ba"; 856 | } 857 | .icon-unlock:before { 858 | content: "\e0bb"; 859 | } 860 | .icon-upload:before { 861 | content: "\e0bc"; 862 | } 863 | .icon-upload-cloud:before { 864 | content: "\e0bd"; 865 | } 866 | .icon-user:before { 867 | content: "\e0be"; 868 | } 869 | .icon-user-check:before { 870 | content: "\e0bf"; 871 | } 872 | .icon-user-minus:before { 873 | content: "\e0c0"; 874 | } 875 | .icon-user-plus:before { 876 | content: "\e0c1"; 877 | } 878 | .icon-user-x:before { 879 | content: "\e0c2"; 880 | } 881 | .icon-users:before { 882 | content: "\e0c3"; 883 | } 884 | .icon-valign-bottom:before { 885 | content: "\e0c4"; 886 | } 887 | .icon-valign-middle:before { 888 | content: "\e0c5"; 889 | } 890 | .icon-valign-top:before { 891 | content: "\e0c6"; 892 | } 893 | .icon-video:before { 894 | content: "\e0c7"; 895 | } 896 | .icon-video-off:before { 897 | content: "\e0c8"; 898 | } 899 | .icon-voicemail:before { 900 | content: "\e0c9"; 901 | } 902 | .icon-volume:before { 903 | content: "\e0ca"; 904 | } 905 | .icon-volume-1:before { 906 | content: "\e0cb"; 907 | } 908 | .icon-volume-2:before { 909 | content: "\e0cc"; 910 | } 911 | .icon-volume-x:before { 912 | content: "\e0cd"; 913 | } 914 | .icon-watch:before { 915 | content: "\e0ce"; 916 | } 917 | .icon-wifi:before { 918 | content: "\e0cf"; 919 | } 920 | .icon-wifi-off:before { 921 | content: "\e0d0"; 922 | } 923 | .icon-wind:before { 924 | content: "\e0d1"; 925 | } 926 | .icon-x:before { 927 | content: "\e0d2"; 928 | } 929 | .icon-x-circle:before { 930 | content: "\e0d3"; 931 | } 932 | .icon-x-octagon:before { 933 | content: "\e0d4"; 934 | } 935 | .icon-x-square:before { 936 | content: "\e0d5"; 937 | } 938 | .icon-youtube:before { 939 | content: "\e0d6"; 940 | } 941 | .icon-zap:before { 942 | content: "\e0d7"; 943 | } 944 | .icon-zap-off:before { 945 | content: "\e0d8"; 946 | } 947 | .icon-zoom-in:before { 948 | content: "\e0d9"; 949 | } 950 | .icon-zoom-out:before { 951 | content: "\e0da"; 952 | } 953 | .icon-sort:before { 954 | content: "\66"; 955 | } 956 | .icon-transparency:before { 957 | content: "\68"; 958 | } 959 | .icon-text-case:before { 960 | content: "\6a"; 961 | } 962 | -------------------------------------------------------------------------------- /src/assets/fonts/feather/feather.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by Fontastic.me 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | --------------------------------------------------------------------------------