├── .editorconfig ├── .gitattributes ├── .gitignore ├── README.md ├── angular.json ├── e2e ├── protractor.conf.js ├── src │ ├── app.e2e-spec.ts │ └── app.po.ts └── tsconfig.e2e.json ├── ngsw-config.json ├── package.json ├── run.sh ├── screenshots ├── Screenshot (86).png ├── Screenshot (87).png └── Screenshot (88).png ├── src ├── app │ ├── app.component.html │ ├── app.component.scss │ ├── app.component.spec.ts │ ├── app.component.ts │ ├── app.module.ts │ ├── app.routing.ts │ ├── index │ │ ├── footer │ │ │ ├── footer.component.html │ │ │ ├── footer.component.scss │ │ │ └── footer.component.ts │ │ ├── index.component.html │ │ ├── index.component.scss │ │ ├── index.component.ts │ │ ├── index.module.ts │ │ ├── index.routing.ts │ │ ├── login │ │ │ ├── login.component.html │ │ │ ├── login.component.scss │ │ │ └── login.component.ts │ │ └── navbar │ │ │ ├── navbar.component.html │ │ │ ├── navbar.component.scss │ │ │ └── navbar.component.ts │ ├── layouts │ │ ├── product │ │ │ ├── add-product │ │ │ │ ├── add-product.component.html │ │ │ │ ├── add-product.component.scss │ │ │ │ └── add-product.component.ts │ │ │ ├── best-product │ │ │ │ ├── best-product.component.html │ │ │ │ ├── best-product.component.scss │ │ │ │ └── best-product.component.ts │ │ │ ├── cart-calculator │ │ │ │ ├── cart-calculator.component.html │ │ │ │ ├── cart-calculator.component.scss │ │ │ │ └── cart-calculator.component.ts │ │ │ ├── cart-products │ │ │ │ ├── cart-products.component.html │ │ │ │ ├── cart-products.component.scss │ │ │ │ └── cart-products.component.ts │ │ │ ├── checkout │ │ │ │ ├── checkout-navbar │ │ │ │ │ ├── checkout-navbar.component.html │ │ │ │ │ ├── checkout-navbar.component.scss │ │ │ │ │ ├── checkout-navbar.component.spec.ts │ │ │ │ │ └── checkout-navbar.component.ts │ │ │ │ ├── checkout.component.html │ │ │ │ ├── checkout.component.scss │ │ │ │ ├── checkout.component.ts │ │ │ │ ├── checkout.module.ts │ │ │ │ ├── checkout.routing.ts │ │ │ │ └── products │ │ │ │ │ ├── products.component.html │ │ │ │ │ ├── products.component.scss │ │ │ │ │ ├── products.component.spec.ts │ │ │ │ │ └── products.component.ts │ │ │ ├── favourite-products │ │ │ │ ├── favourite-products.component.html │ │ │ │ ├── favourite-products.component.scss │ │ │ │ └── favourite-products.component.ts │ │ │ ├── product-detail │ │ │ │ ├── product-detail.component.html │ │ │ │ ├── product-detail.component.scss │ │ │ │ └── product-detail.component.ts │ │ │ ├── product-list │ │ │ │ ├── product-list.component.html │ │ │ │ ├── product-list.component.scss │ │ │ │ └── product-list.component.ts │ │ │ ├── product.component.html │ │ │ ├── product.component.scss │ │ │ ├── product.component.ts │ │ │ ├── product.module.ts │ │ │ └── product.routing.ts │ │ ├── task-board │ │ │ ├── task-board.component.html │ │ │ ├── task-board.component.scss │ │ │ ├── task-board.component.ts │ │ │ ├── task-board.module.ts │ │ │ └── task.routing.ts │ │ └── user │ │ │ ├── user-account │ │ │ ├── user-account.component.html │ │ │ ├── user-account.component.scss │ │ │ └── user-account.component.ts │ │ │ ├── user.component.html │ │ │ ├── user.component.scss │ │ │ ├── user.component.ts │ │ │ ├── user.module.ts │ │ │ └── user.routing.ts │ └── shared │ │ ├── animations │ │ └── fadeIntRoute.ts │ │ ├── components │ │ ├── card-loader │ │ │ ├── card-loader.component.html │ │ │ ├── card-loader.component.scss │ │ │ ├── card-loader.component.spec.ts │ │ │ └── card-loader.component.ts │ │ ├── no-access │ │ │ ├── no-access.component.html │ │ │ ├── no-access.component.scss │ │ │ └── no-access.component.ts │ │ ├── no-products-found │ │ │ ├── no-products-found.component.html │ │ │ ├── no-products-found.component.scss │ │ │ └── no-products-found.component.ts │ │ └── page-not-found │ │ │ ├── page-not-found.component.html │ │ │ ├── page-not-found.component.scss │ │ │ └── page-not-found.component.ts │ │ ├── models │ │ ├── product.ts │ │ └── user.ts │ │ ├── moke_data │ │ └── tasks.ts │ │ ├── pipes │ │ ├── filterByBrand.pipe.ts │ │ ├── moment-time-ago.pipe.ts │ │ └── translate.pipe.ts │ │ ├── services │ │ ├── admin-gaurd.ts │ │ ├── auth.service.ts │ │ ├── auth_gaurd.ts │ │ ├── product.service.ts │ │ ├── task.service.spec.ts │ │ ├── task.service.ts │ │ ├── theme.service.ts │ │ ├── toastr.service.ts │ │ ├── translate.service.ts │ │ └── user.service.ts │ │ └── shared.module.ts ├── assets │ ├── .gitkeep │ ├── banner_img │ │ ├── img1.jpg │ │ ├── img2.jpg │ │ ├── img3.jpg │ │ ├── img_1.jpg │ │ ├── img_2.jpg │ │ ├── img_3.jpg │ │ ├── img_3.png │ │ └── img_4.jpg │ ├── i18n │ │ ├── en.json │ │ ├── fa.json │ │ ├── fr.json │ │ ├── hin.json │ │ └── ja.json │ ├── icons │ │ ├── icon-128x128.png │ │ ├── icon-144x144.png │ │ ├── icon-152x152.png │ │ ├── icon-192x192.png │ │ ├── icon-384x384.png │ │ ├── icon-512x512.png │ │ ├── icon-72x72.png │ │ └── icon-96x96.png │ ├── img │ │ ├── loader.svg │ │ └── malecostume-512.png │ └── theme │ │ ├── colors.scss │ │ └── functions.scss ├── browserslist ├── environments │ ├── environment.prod.ts │ ├── environment.ts │ └── firebaseConfig.ts ├── favicon.ico ├── index.html ├── karma.conf.js ├── main.ts ├── manifest.json ├── polyfills.ts ├── styles.scss ├── test.ts ├── tsconfig.app.json ├── tsconfig.spec.json └── tslint.json ├── tsconfig.json └── tslint.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://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 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.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 | 8 | # dependencies 9 | /node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.sass-cache 29 | /connect.lock 30 | /coverage 31 | /libpeerconnection.log 32 | npm-debug.log 33 | yarn-error.log 34 | testem.log 35 | /typings 36 | 37 | # System Files 38 | .DS_Store 39 | Thumbs.db 40 | 41 | 42 | #Personal Config 43 | /src/environments/firebaseConfigDummy.ts 44 | firebase.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular8 - Angular Blogging App + MDBootstrap + Firebase 2 | 3 | 4 | 5 | Developing a **Blogging App (Education) Application using Angular8**. 6 | 7 | **Live Demo** : [Angular-shopping-cart](https://blog-app-3cda4.firebaseapp.com/) 8 | 9 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.1.1. 10 | 11 | 12 | ## Functionalities 13 | 14 | 1. User Registration using Firebase Authentication (using Email/Password | Google Authentication ) 15 | 2. CRUD Operations like 16 | 17 | - User can add blog to his List. 18 | - Admin can add Blog to the Blog list 19 | - Admin can edit/delete the Blog. 20 | 21 | 22 | 23 | 1. Security 24 | 25 | - Implmented Authentication and Authorization 26 | 27 | ## Tools and Technologies 28 | 29 | - Technology: HTML, MDBootstrap, CSS, Angular-7, Firebase, i18n, Drag & Drop, Progressive Web Application, jsPDF (to download Receipt as PDF). 30 | - Database : Angular Firebase. 31 | 32 | #### This Projects covers all fundamentals of Angular 33 | 34 | - Multiple Modules 35 | - Components, Template and DataBinding 36 | - Form Validation 37 | - HttpClient 38 | - Animations 39 | - Dependency Injection 40 | - Routing & Navigation 41 | - Service Workers 42 | - Pipes 43 | - Gaurds etc.. 44 | 45 | # Installation 46 | 47 | 1. Angular CLI 48 | - [Download Angular CLI](https://cli.angular.io/) 49 | 2. NodeJs 50 | - [Download Nodejs](https://nodejs.org/en/download/) 51 | 3. Package Manager - NPM / Yarn 52 | 4. Clone the repository and run `npm install` if you use **npm** as package manager or `yarn install` if you use **yarn** as package manager. 53 | 5. Angular + Firebase Tutorial - [Angular + Firebase + Typescript — Step by step tutorial](https://medium.com/factory-mind/angular-firebase-typescript-step-by-step-tutorial-2ef887fc7d71) 54 | 6. Activate Firebase Authentication Providers 55 | 56 | `Authentication -> Sign-in-method -> Enable Email/Password & Google provider` 57 | 58 | 7. Update the Firebase Database Rules 59 | 60 | `Database -> Rules` 61 | 62 | ``` 63 | { 64 | "rules": { 65 | ".read":true, 66 | ".write": true 67 | } 68 | } 69 | ``` 70 | 71 | 8. Configure your firebase configuration `src/environments/firebaseConfig.ts` 72 | 73 | ``` 74 | export const FireBaseConfig = { 75 | apiKey: "YOUR_API_KEY", 76 | authDomain: "YOUR_AUTH_DOMAIN", 77 | databaseURL: "YOUR_DATABASE_URL", 78 | projectId: "YOUR_PROJECT_ID", 79 | storageBucket: "YOUR_STORAGE_BUCKET", 80 | messagingSenderId: "YOUR_SENDER_ID" 81 | }; 82 | ``` 83 | 84 | 9. For Admin Role `Register or SignIn with Google Auth` 85 | 86 | your registered data will be saved inside the firebase **clients** table. 87 | 88 | ``` 89 | -clients 90 | -LRSkWxGAKQAFZmyfsx6 91 | -createdOn: "1542046725" 92 | -email: "<>" 93 | -isAdmin: false <--- Change this to true 94 | ... 95 | ``` 96 | 97 | Now you can able to access the Admin Privileges like `Creating Product, Removing Product, etc..` 98 | 99 | 10. Run the Server. 100 | 101 | ## Screenshots: 102 | 103 | ### Home Page: 104 | 105 | ![Alt text](https://github.com/mehulk05/Angular-Blogging-App/blob/master/screenshots/Screenshot%20(86).png "Home Page") 106 | 107 | ### Blog List Page: 108 | 109 | ![Alt text](https://github.com/mehulk05/Angular-Blogging-App/blob/master/screenshots/Screenshot%20(87).png "blog Page") 110 | 111 | ### Blog: 112 | 113 | ![Alt text](https://github.com/mehulk05/Angular-Blogging-App/blob/master/screenshots/Screenshot%20(88).png "blog Page") 114 | 115 | ## How can I support the developer ? 116 | 117 | * Star my Github repo ⭐ 118 | * Create pull requests, submit bugs, suggest new features or documentation updates 🛠 119 | 120 | ## Development server 121 | 122 | 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. 123 | 124 | ## Code scaffolding 125 | 126 | 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`. 127 | 128 | ## Build 129 | 130 | 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. 131 | 132 | ## Running unit tests 133 | 134 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 135 | 136 | ## Running end-to-end tests 137 | 138 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 139 | 140 | ## Further help 141 | 142 | 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). 143 | 144 | 145 | ## Somethings wrong!! 146 | 147 | - If you find that something's wrong with this package, you can let me know by raising an issue on the GitHub issue tracker 148 | 149 | 150 | -------------------------------------------------------------------------------- /angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "angularShop": { 7 | "root": "", 8 | "sourceRoot": "src", 9 | "projectType": "application", 10 | "prefix": "app", 11 | "schematics": { 12 | "@schematics/angular:component": { 13 | "styleext": "scss" 14 | } 15 | }, 16 | "architect": { 17 | "build": { 18 | "builder": "@angular-devkit/build-angular:browser", 19 | "options": { 20 | "outputPath": "dist/angularShop", 21 | "index": "src/index.html", 22 | "main": "src/main.ts", 23 | "polyfills": "src/polyfills.ts", 24 | "tsConfig": "src/tsconfig.app.json", 25 | "assets": [ 26 | "src/favicon.ico", 27 | "src/assets", 28 | "src/manifest.json" 29 | ], 30 | "styles": [ 31 | "node_modules/font-awesome/scss/font-awesome.scss", 32 | "node_modules/angular-bootstrap-md/scss/bootstrap/bootstrap.scss", 33 | "node_modules/angular-bootstrap-md/scss/mdb-free.scss", 34 | "node_modules/owl.carousel/dist/assets/owl.carousel.min.css", 35 | "node_modules/owl.carousel/dist/assets/owl.theme.default.min.css", 36 | "node_modules/animate.css/animate.min.css", 37 | "node_modules/toastr/build/toastr.min.css", 38 | "src/styles.scss" 39 | ], 40 | "scripts": [ 41 | "node_modules/jquery/dist/jquery.js", 42 | "node_modules/tether/dist/js/tether.js", 43 | "node_modules/chart.js/dist/Chart.js", 44 | "node_modules/bootstrap/dist/js/bootstrap.min.js", 45 | "node_modules/owl.carousel/dist/owl.carousel.min.js", 46 | "node_modules/moment/min/moment.min.js", 47 | "node_modules/toastr/build/toastr.min.js" 48 | ] 49 | }, 50 | "configurations": { 51 | "production": { 52 | "fileReplacements": [ 53 | { 54 | "replace": "src/environments/environment.ts", 55 | "with": "src/environments/environment.prod.ts" 56 | } 57 | ], 58 | "optimization": true, 59 | "outputHashing": "all", 60 | "sourceMap": false, 61 | "extractCss": true, 62 | "namedChunks": false, 63 | "aot": true, 64 | "extractLicenses": true, 65 | "vendorChunk": false, 66 | "buildOptimizer": true, 67 | "serviceWorker": true 68 | } 69 | } 70 | }, 71 | "serve": { 72 | "builder": "@angular-devkit/build-angular:dev-server", 73 | "options": { 74 | "browserTarget": "angularShop:build" 75 | }, 76 | "configurations": { 77 | "production": { 78 | "browserTarget": "angularShop:build:production" 79 | } 80 | } 81 | }, 82 | "extract-i18n": { 83 | "builder": "@angular-devkit/build-angular:extract-i18n", 84 | "options": { 85 | "browserTarget": "angularShop:build" 86 | } 87 | }, 88 | "test": { 89 | "builder": "@angular-devkit/build-angular:karma", 90 | "options": { 91 | "main": "src/test.ts", 92 | "polyfills": "src/polyfills.ts", 93 | "tsConfig": "src/tsconfig.spec.json", 94 | "karmaConfig": "src/karma.conf.js", 95 | "styles": [ 96 | "src/styles.scss" 97 | ], 98 | "scripts": [], 99 | "assets": [ 100 | "src/favicon.ico", 101 | "src/assets", 102 | "src/manifest.json" 103 | ] 104 | } 105 | }, 106 | "lint": { 107 | "builder": "@angular-devkit/build-angular:tslint", 108 | "options": { 109 | "tsConfig": [ 110 | "src/tsconfig.app.json", 111 | "src/tsconfig.spec.json" 112 | ], 113 | "exclude": [ 114 | "**/node_modules/**" 115 | ] 116 | } 117 | } 118 | } 119 | }, 120 | "angularShop-e2e": { 121 | "root": "e2e/", 122 | "projectType": "application", 123 | "architect": { 124 | "e2e": { 125 | "builder": "@angular-devkit/build-angular:protractor", 126 | "options": { 127 | "protractorConfig": "e2e/protractor.conf.js", 128 | "devServerTarget": "angularShop:serve" 129 | }, 130 | "configurations": { 131 | "production": { 132 | "devServerTarget": "angularShop:serve:production" 133 | } 134 | } 135 | }, 136 | "lint": { 137 | "builder": "@angular-devkit/build-angular:tslint", 138 | "options": { 139 | "tsConfig": "e2e/tsconfig.e2e.json", 140 | "exclude": [ 141 | "**/node_modules/**" 142 | ] 143 | } 144 | } 145 | } 146 | } 147 | }, 148 | "defaultProject": "angularShop" 149 | } -------------------------------------------------------------------------------- /e2e/protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require("jasmine-spec-reporter"); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: ["./src/**/*.e2e-spec.ts"], 9 | capabilities: { 10 | browserName: "chrome" 11 | }, 12 | directConnect: true, 13 | baseUrl: "http://localhost:4200/", 14 | framework: "jasmine", 15 | jasmineNodeOpts: { 16 | showColors: true, 17 | defaultTimeoutInterval: 30000, 18 | print: function() {} 19 | }, 20 | onPrepare() { 21 | require("ts-node").register({ 22 | project: require("path").join(__dirname, "./tsconfig.e2e.json") 23 | }); 24 | jasmine 25 | .getEnv() 26 | .addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from "./app.po"; 2 | 3 | describe("workspace-project App", () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it("should display welcome message", () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual("Welcome to angularShop!"); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from "protractor"; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get("/"); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css("app-root h1")).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /ngsw-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": "/index.html", 3 | "assetGroups": [ 4 | { 5 | "name": "app", 6 | "installMode": "prefetch", 7 | "resources": { 8 | "files": [ 9 | "/favicon.ico", 10 | "/index.html", 11 | "/*.css", 12 | "/*.js" 13 | ] 14 | } 15 | }, 16 | { 17 | "name": "assets", 18 | "installMode": "lazy", 19 | "updateMode": "prefetch", 20 | "resources": { 21 | "files": [ 22 | "/assets/**", 23 | "/*.(eot|svg|cur|jpg|png|webp|gif|otf|ttf|woff|woff2|ani)" 24 | ] 25 | } 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular-shop", 3 | "version": "1.2.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "ng": "ng", 7 | "start": "ng serve", 8 | "build": "ng build", 9 | "test": "ng test", 10 | "lint": "ng lint", 11 | "e2e": "ng e2e" 12 | }, 13 | "engines": { 14 | "node": "10.13.0", 15 | "npm": "6.2.0" 16 | }, 17 | "private": true, 18 | "dependencies": { 19 | "@agm/core": "^1.0.0-beta.5", 20 | "@angular/animations": "^7.2.4", 21 | "@angular/cdk": "^7.3.2", 22 | "@angular/common": "^7.2.4", 23 | "@angular/compiler": "^7.2.4", 24 | "@angular/core": "^7.2.4", 25 | "@angular/fire": "^5.1.1", 26 | "@angular/forms": "^7.2.4", 27 | "@angular/http": "^7.2.4", 28 | "@angular/platform-browser": "^7.2.4", 29 | "@angular/platform-browser-dynamic": "^7.2.4", 30 | "@angular/pwa": "0.12", 31 | "@angular/router": "^7.2.4", 32 | "@angular/service-worker": "^7.2.4", 33 | "@ckeditor/ckeditor5-angular": "^1.1.0", 34 | "@ckeditor/ckeditor5-basic-styles": "^11.0.0", 35 | "@ckeditor/ckeditor5-build-classic": "^12.0.0", 36 | "angular-bootstrap-md": "^7.0.0", 37 | "angular2-toaster": "^7.0.0", 38 | "animate.css": "^3.7.0", 39 | "bootstrap": "^4.1.3", 40 | "chart.js": "^2.7.3", 41 | "core-js": "^2.5.4", 42 | "express": "^4.16.4", 43 | "firebase": "5.6.0", 44 | "font-awesome": "^4.7.0", 45 | "html2canvas": "^1.0.0-alpha.12", 46 | "jquery": "^3.3.1", 47 | "jspdf": "^1.4.1", 48 | "lodash": "^4.17.11", 49 | "moment": "^2.22.2", 50 | "ngx-bootstrap": "^5.2.0", 51 | "ngx-content-loading": "^0.1.3", 52 | "ngx-editor": "^4.1.0", 53 | "ngx-owl-carousel": "^2.0.7", 54 | "ngx-pagination": "^3.2.1", 55 | "node-sass": "^4.10.0", 56 | "owl.carousel": "^2.3.4", 57 | "primeng": "^7.0.0", 58 | "rxjs": "^6.4.0", 59 | "shortid": "^2.2.14", 60 | "tether": "^1.4.5", 61 | "toastr": "^2.1.4", 62 | "web-animations-js": "^2.3.1", 63 | "zone.js": "^0.8.29" 64 | }, 65 | "devDependencies": { 66 | "@angular-devkit/build-angular": "^0.12.4", 67 | "@angular/cli": "~7.3.1", 68 | "@angular/compiler-cli": "^7.2.4", 69 | "@angular/language-service": "^7.2.4", 70 | "@types/jasmine": "~3.3.1", 71 | "@types/jasminewd2": "~2.0.6", 72 | "@types/node": "~10.12.12", 73 | "codelyzer": "~4.5.0", 74 | "concurrently": "^4.1.0", 75 | "jasmine-core": "~3.3.0", 76 | "jasmine-spec-reporter": "~4.2.1", 77 | "karma": "^4.3.0", 78 | "karma-chrome-launcher": "~2.2.0", 79 | "karma-coverage-istanbul-reporter": "~2.0.4", 80 | "karma-jasmine": "~2.0.1", 81 | "karma-jasmine-html-reporter": "^1.4.0", 82 | "protractor": "^5.4.1", 83 | "ts-node": "~7.0.1", 84 | "tslint": "~5.11.0", 85 | "typescript": "~3.2.4" 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH=$PATH:$(npm bin) 3 | set -x 4 | # Production build 5 | ng build --prod 6 | # Serve 7 | cd dist/angularShop 8 | http-server 9 | -------------------------------------------------------------------------------- /screenshots/Screenshot (86).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/screenshots/Screenshot (86).png -------------------------------------------------------------------------------- /screenshots/Screenshot (87).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/screenshots/Screenshot (87).png -------------------------------------------------------------------------------- /screenshots/Screenshot (88).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/screenshots/Screenshot (88).png -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 |
6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
-------------------------------------------------------------------------------- /src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | :host { 2 | main { 3 | position: relative; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from "@angular/core/testing"; 2 | import { RouterTestingModule } from "@angular/router/testing"; 3 | import { AppComponent } from "./app.component"; 4 | describe("AppComponent", () => { 5 | beforeEach(async(() => { 6 | TestBed.configureTestingModule({ 7 | imports: [RouterTestingModule], 8 | declarations: [AppComponent] 9 | }).compileComponents(); 10 | })); 11 | it("should create the app", async(() => { 12 | const fixture = TestBed.createComponent(AppComponent); 13 | const app = fixture.debugElement.componentInstance; 14 | expect(app).toBeTruthy(); 15 | })); 16 | it(`should have as title 'app'`, async(() => { 17 | const fixture = TestBed.createComponent(AppComponent); 18 | const app = fixture.debugElement.componentInstance; 19 | expect(app.title).toEqual("app"); 20 | })); 21 | it("should render title in a h1 tag", async(() => { 22 | const fixture = TestBed.createComponent(AppComponent); 23 | fixture.detectChanges(); 24 | const compiled = fixture.debugElement.nativeElement; 25 | expect(compiled.querySelector("h1").textContent).toContain( 26 | "Welcome to angularShop!" 27 | ); 28 | })); 29 | }); 30 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | import { UserService } from "./shared/services/user.service"; 3 | import { fadeAnimation } from "./shared/animations/fadeIntRoute"; 4 | declare var $: any; 5 | 6 | @Component({ 7 | selector: "app-root", 8 | templateUrl: "./app.component.html", 9 | styleUrls: ["./app.component.scss"], 10 | animations: [fadeAnimation] 11 | }) 12 | export class AppComponent implements OnInit { 13 | title = "app"; 14 | 15 | constructor(private userService: UserService) {} 16 | 17 | ngOnInit() { 18 | $(document).ready(function() { 19 | $(".banner").owlCarousel({ 20 | autoHeight: true, 21 | center: true, 22 | nav: true, 23 | items: 1, 24 | margin: 30, 25 | loop: true, 26 | autoplay: true, 27 | autoplayTimeout: 3000, 28 | autoplayHoverPause: true 29 | }); 30 | }); 31 | 32 | if (navigator.geolocation) { 33 | navigator.geolocation.getCurrentPosition(this.setGeoLocation.bind(this)); 34 | } 35 | } 36 | 37 | setGeoLocation(position: any) { 38 | this.userService.setLocation( 39 | position["coords"].latitude, 40 | position["coords"].longitude 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule, NO_ERRORS_SCHEMA, APP_INITIALIZER } from '@angular/core'; 3 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 4 | import { AppComponent } from './app.component'; 5 | import { IndexModule } from './index/index.module'; 6 | import { SharedModule } from './shared/shared.module'; 7 | import { RouterModule } from '@angular/router'; 8 | import { AppRoutes } from './app.routing'; 9 | import { TranslateService } from './shared/services/translate.service'; 10 | import { ProductModule } from './layouts/product/product.module'; 11 | import { UserModule } from './layouts/user/user.module'; 12 | import { ServiceWorkerModule } from '@angular/service-worker'; 13 | import { environment } from '../environments/environment'; 14 | 15 | /* to load and set en.json as the default application language */ 16 | export function setupTranslateFactory(service: TranslateService): Function { 17 | return () => service.use('en'); 18 | } 19 | 20 | @NgModule({ 21 | declarations: [ AppComponent ], 22 | imports: [ 23 | BrowserModule, 24 | BrowserAnimationsModule, 25 | IndexModule, 26 | ProductModule, 27 | UserModule, 28 | SharedModule, 29 | RouterModule.forRoot(AppRoutes), 30 | ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }) 31 | ], 32 | providers: [ 33 | TranslateService, 34 | { 35 | provide: APP_INITIALIZER, 36 | useFactory: setupTranslateFactory, 37 | deps: [ TranslateService ], 38 | multi: true 39 | } 40 | ], 41 | bootstrap: [ AppComponent ], 42 | schemas: [ NO_ERRORS_SCHEMA ] 43 | }) 44 | export class AppModule {} 45 | -------------------------------------------------------------------------------- /src/app/app.routing.ts: -------------------------------------------------------------------------------- 1 | import { Routes } from '@angular/router'; 2 | import { IndexComponent } from './index/index.component'; 3 | import { NoAccessComponent } from './shared/components/no-access/no-access.component'; 4 | import { PageNotFoundComponent } from './shared/components/page-not-found/page-not-found.component'; 5 | 6 | export const AppRoutes: Routes = [ 7 | { 8 | path: '', 9 | children: [ 10 | { 11 | path: '', 12 | loadChildren: './index/index.module#IndexModule' 13 | }, 14 | { 15 | path: 'products', 16 | loadChildren: './layouts/product/product.module#ProductModule' 17 | }, 18 | { 19 | path: 'users', 20 | loadChildren: './layouts/user/user.module#UserModule' 21 | }, 22 | { 23 | path: 'task-board', 24 | loadChildren: './layouts/task-board/task-board.module#TaskBoardModule' 25 | } 26 | ] 27 | }, 28 | { path: 'no-access', component: NoAccessComponent }, 29 | { path: '**', component: PageNotFoundComponent } 30 | ]; 31 | -------------------------------------------------------------------------------- /src/app/index/footer/footer.component.html: -------------------------------------------------------------------------------- 1 | 2 | 18 | -------------------------------------------------------------------------------- /src/app/index/footer/footer.component.scss: -------------------------------------------------------------------------------- 1 | .page-footer { 2 | bottom: 0; 3 | } 4 | -------------------------------------------------------------------------------- /src/app/index/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 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /src/app/index/index.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | 61 | 62 |
63 | 64 | 65 | 66 |
-------------------------------------------------------------------------------- /src/app/index/index.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/app/index/index.component.scss -------------------------------------------------------------------------------- /src/app/index/index.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: "app-index", 5 | templateUrl: "./index.component.html", 6 | styleUrls: ["./index.component.scss"] 7 | }) 8 | export class IndexComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /src/app/index/index.module.ts: -------------------------------------------------------------------------------- 1 | // Core Dependencies 2 | import { RouterModule } from '@angular/router'; 3 | import { NgModule, NO_ERRORS_SCHEMA } from '@angular/core'; 4 | import { CommonModule } from '@angular/common'; 5 | 6 | import { IndexRoutes } from './index.routing'; 7 | 8 | import { ProductModule } from '../layouts/product/product.module'; 9 | 10 | // Components 11 | import { IndexComponent } from './index.component'; 12 | import { LoginComponent } from './login/login.component'; 13 | import { FooterComponent } from './footer/footer.component'; 14 | import { NavbarComponent } from './navbar/navbar.component'; 15 | import { SharedModule } from '../shared/shared.module'; 16 | 17 | @NgModule({ 18 | imports: [ CommonModule, ProductModule, SharedModule, RouterModule.forChild(IndexRoutes) ], 19 | declarations: [ IndexComponent, NavbarComponent, LoginComponent, FooterComponent ], 20 | schemas: [ NO_ERRORS_SCHEMA ], 21 | exports: [ NavbarComponent, FooterComponent ], 22 | providers: [] 23 | }) 24 | export class IndexModule {} 25 | -------------------------------------------------------------------------------- /src/app/index/index.routing.ts: -------------------------------------------------------------------------------- 1 | import { LoginComponent } from "./login/login.component"; 2 | import { Routes } from "@angular/router"; 3 | import { IndexComponent } from "./index.component"; 4 | 5 | export const IndexRoutes: Routes = [ 6 | { 7 | path: "", 8 | children: [ 9 | { 10 | path: "", 11 | component: IndexComponent 12 | }, 13 | { 14 | path: "login", 15 | component: LoginComponent 16 | } 17 | ] 18 | } 19 | ]; 20 | -------------------------------------------------------------------------------- /src/app/index/login/login.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 |
6 |
7 |

Sign in

8 | 9 |
10 | 11 | 13 |
14 |
15 | 16 | 18 |
19 | 20 |
21 | 22 | 23 | 27 | 28 |
29 |
30 |
31 |
32 |

New User ? 33 | Register here! 34 |

35 | 36 | 37 | 38 | 74 |
75 |
76 |
77 |
78 | -------------------------------------------------------------------------------- /src/app/index/login/login.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/app/index/login/login.component.scss -------------------------------------------------------------------------------- /src/app/index/login/login.component.ts: -------------------------------------------------------------------------------- 1 | import { ToastrService } from "./../../shared/services/toastr.service"; 2 | import { NgForm, EmailValidator } from "@angular/forms"; 3 | import { Component, OnInit } from "@angular/core"; 4 | import { Router, ActivatedRoute } from "@angular/router"; 5 | import { UserService } from "../../shared/services/user.service"; 6 | import { AuthService } from "../../shared/services/auth.service"; 7 | import { User } from "../../shared/models/user"; 8 | declare var $: any; 9 | @Component({ 10 | selector: "app-login", 11 | templateUrl: "./login.component.html", 12 | styleUrls: ["./login.component.scss"], 13 | providers: [EmailValidator] 14 | }) 15 | export class LoginComponent implements OnInit { 16 | user = { 17 | emailId: "", 18 | loginPassword: "" 19 | }; 20 | 21 | errorInUserCreate = false; 22 | errorMessage: any; 23 | createUser; 24 | 25 | constructor( 26 | private authService: AuthService, 27 | private userService: UserService, 28 | private toastService: ToastrService, 29 | private router: Router, 30 | private route: ActivatedRoute 31 | ) { 32 | this.createUser = new User(); 33 | } 34 | 35 | ngOnInit() { } 36 | 37 | addUser(userForm: NgForm) { 38 | userForm.value["isAdmin"] = false; 39 | this.authService 40 | .createUserWithEmailAndPassword(userForm.value["emailId"], userForm.value["password"]) 41 | .then((res) => { 42 | const user = { 43 | email: res.user.email, 44 | famil_name: res.user.displayName, 45 | uid: res.user.uid, 46 | verified_email: res.user.emailVerified, 47 | phoneNumber: res.user.phoneNumber, 48 | picture: res.user.photoURL 49 | }; 50 | 51 | this.userService.createUser(user); 52 | 53 | this.toastService.success("Registering", "User Registeration"); 54 | 55 | setTimeout((router: Router) => { 56 | $("#createUserForm").modal("hide"); 57 | this.router.navigate(["/"]); 58 | }, 1500); 59 | }) 60 | .catch((err) => { 61 | this.errorInUserCreate = true; 62 | this.errorMessage = err; 63 | this.toastService.error("Error while Creating User", err); 64 | }); 65 | } 66 | 67 | signInWithEmail(userForm: NgForm) { 68 | this.authService 69 | .signInRegular(userForm.value["emailId"], userForm.value["loginPassword"]) 70 | .then((res) => { 71 | this.toastService.success("Authentication Success", "Logging in please wait"); 72 | 73 | const returnUrl = this.route.snapshot.queryParamMap.get("returnUrl"); 74 | 75 | setTimeout((router: Router) => { 76 | this.router.navigate([returnUrl || "/"]); 77 | }, 1500); 78 | 79 | this.router.navigate(["/"]); 80 | }) 81 | .catch((err) => { 82 | this.toastService.error("Authentication Failed", "Invalid Credentials, Please Check your credentials"); 83 | }); 84 | } 85 | 86 | signInWithGoogle() { 87 | this.authService 88 | .signInWithGoogle() 89 | .then((res) => { 90 | if (res.additionalUserInfo.isNewUser) { 91 | this.userService.createUser(res.additionalUserInfo.profile); 92 | } 93 | this.router.navigate(['/']) 94 | //const returnUrl = this.route.snapshot.queryParamMap.get("returnUrl"); 95 | //location.reload(); 96 | 97 | }) 98 | .catch((err) => { 99 | this.toastService.error("Error Occured", "Please try again later"); 100 | }); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/app/index/navbar/navbar.component.html: -------------------------------------------------------------------------------- 1 | 2 | 137 | -------------------------------------------------------------------------------- /src/app/index/navbar/navbar.component.scss: -------------------------------------------------------------------------------- 1 | 2 | @import "../../../assets/theme/colors"; 3 | @import "../../../assets/theme/functions"; 4 | 5 | 6 | .navbar { 7 | top: 0; 8 | background: var(--navBackground) 9 | } 10 | 11 | 12 | .color-container { 13 | position: relative; 14 | cursor: pointer; 15 | width: 36px; 16 | height: 36px; 17 | margin: auto; 18 | border-radius: 50%; 19 | overflow: hidden; 20 | 21 | .colorDiv { 22 | position: absolute; 23 | top: 0; 24 | left: 0; 25 | width: 100%; 26 | height: 100%; 27 | box-sizing: border-box; 28 | border-radius: 50%; 29 | } 30 | 31 | .color-purple{ 32 | background: #9c27b0 33 | 34 | } 35 | .color-red{ 36 | background: #e91e63 37 | 38 | } 39 | .color-blue{ 40 | background: #3f51b5 41 | 42 | } 43 | .color-violet{ 44 | background: #673ab7 45 | 46 | } 47 | } 48 | 49 | 50 | /deep/ .dropdown-menu { 51 | margin-left: -6rem; 52 | } 53 | -------------------------------------------------------------------------------- /src/app/index/navbar/navbar.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Component, 3 | OnInit, 4 | VERSION 5 | } from "@angular/core"; 6 | import { Router } from "@angular/router"; 7 | import { AuthService } from "../../shared/services/auth.service"; 8 | import { ProductService } from "../../shared/services/product.service"; 9 | import { TranslateService } from "../../shared/services/translate.service"; 10 | import { ThemeService } from "src/app/shared/services/theme.service"; 11 | declare var $: any; 12 | 13 | @Component({ 14 | selector: "app-navbar", 15 | templateUrl: "./navbar.component.html", 16 | styleUrls: ["./navbar.component.scss"] 17 | }) 18 | export class NavbarComponent implements OnInit { 19 | 20 | 21 | constructor( 22 | public authService: AuthService, 23 | private router: Router, 24 | public productService: ProductService, 25 | public translate: TranslateService, 26 | private themeService: ThemeService 27 | ) { 28 | // console.log(translate.data); 29 | } 30 | 31 | ngOnInit() { } 32 | logout() { 33 | this.authService.logout(); 34 | 35 | this.router.navigate(["/"]); 36 | 37 | } 38 | 39 | // setLang(lang: string) { 40 | // // console.log("Language", lang); 41 | // this.translate.use(lang).then(() => { }); 42 | // } 43 | 44 | updateTheme(theme: string) { 45 | this.themeService.updateThemeUrl(theme); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/app/layouts/product/add-product/add-product.component.html: -------------------------------------------------------------------------------- 1 | 2 | 12 | 93 | -------------------------------------------------------------------------------- /src/app/layouts/product/add-product/add-product.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/app/layouts/product/add-product/add-product.component.scss -------------------------------------------------------------------------------- /src/app/layouts/product/add-product/add-product.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { NgForm } from '@angular/forms'; 3 | import { ProductService } from 'src/app/shared/services/product.service'; 4 | import { Product } from 'src/app/shared/models/product'; 5 | import * as ClassicEditor from '@ckeditor/ckeditor5-build-classic'; 6 | 7 | declare var $: any; 8 | declare var require: any; 9 | declare var toastr: any; 10 | const shortId = require('shortid'); 11 | const moment = require('moment'); 12 | 13 | @Component({ 14 | selector: 'app-add-product', 15 | templateUrl: './add-product.component.html', 16 | styleUrls: [ './add-product.component.scss' ] 17 | }) 18 | export class AddProductComponent implements OnInit { 19 | public Editor = ClassicEditor; 20 | ckeConfig: any; 21 | product: Product = new Product(); 22 | constructor(private productService: ProductService) {} 23 | 24 | ngOnInit() {} 25 | 26 | createProduct(productForm: NgForm) { 27 | productForm.value['productId'] = 'PROD_' + shortId.generate(); 28 | productForm.value['productAdded'] = moment().unix(); 29 | productForm.value['ratings'] = Math.floor(Math.random() * 5 + 1); 30 | if (productForm.value['productImageUrl'] === undefined) { 31 | productForm.value['productImageUrl'] = 'http://via.placeholder.com/640x360/007bff/ffffff'; 32 | } 33 | 34 | productForm.value['favourite'] = false; 35 | 36 | const date = productForm.value['productAdded']; 37 | 38 | this.productService.createProduct(productForm.value); 39 | 40 | this.product = new Product(); 41 | 42 | $('#exampleModalLong').modal('hide'); 43 | 44 | toastr.success('Blog ' + productForm.value['productName'] + 'is added successfully', 'Blog Creation'); 45 | } 46 | 47 | setEditorConfig() { 48 | this.ckeConfig = { 49 | removePlugins: ['ImageUpload', 'MediaEmbed'], 50 | heading: { 51 | options: [ 52 | { model: 'paragraph', title: 'Paragraph', class: 'ck-heading_paragraph' }, 53 | { model: 'heading1', view: 'h1', title: 'Heading 1', class: 'ck-heading_heading1' }, 54 | { model: 'heading2', view: 'h2', title: 'Heading 2', class: 'ck-heading_heading2' }, 55 | { model: 'heading3', view: 'h3', title: 'Heading 3', class: 'ck-heading_heading3' }, 56 | { model: 'heading4', view: 'h4', title: 'Heading 4', class: 'ck-heading_heading4' }, 57 | { model: 'heading5', view: 'h5', title: 'Heading 5', class: 'ck-heading_heading5' }, 58 | { model: 'heading6', view: 'h6', title: 'Heading 6', class: 'ck-heading_heading6' }, 59 | { model: 'Formatted', view: 'pre', title: 'Formatted' }, 60 | ] 61 | } 62 | }; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/app/layouts/product/best-product/best-product.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 |
5 |
6 |
7 |

{{translate.data["BESTPRODUCTS"] | translate}}

8 |
9 |
10 | 14 |
15 | 16 |
17 | 18 |
19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 |
27 | 28 | 29 | 30 | 36 | 37 | 38 | 39 | 40 |
41 | 42 | 43 |
{{ product.productCategory }}
44 |
45 |
46 | 47 | {{ product.productName }} 48 | 49 |
50 | 51 | 52 |

{{ product.productDescription }} 53 |

54 | 55 | 56 | 64 |
65 | 66 |
67 | 68 |
69 | 70 |
71 |
72 |
73 | 74 | -------------------------------------------------------------------------------- /src/app/layouts/product/best-product/best-product.component.scss: -------------------------------------------------------------------------------- 1 | @import "../../../../assets/theme/colors"; 2 | @import "../../../../assets/theme/functions"; 3 | 4 | .bq-title{ 5 | color: var(--productTitle) !important; 6 | } 7 | 8 | .bq-primary { 9 | border-left: 3px solid var(--productTitle) !important; 10 | } 11 | 12 | .btn-default { 13 | background-color: var(--navBackground) !important; 14 | } 15 | 16 | 17 | .section .section-heading { 18 | margin-top: 2rem; 19 | margin-bottom: 4rem; 20 | } 21 | .section-heading { 22 | text-align: center; 23 | } 24 | .section-description { 25 | margin-left: 5%; 26 | margin-right: 5%; 27 | } 28 | .section-description { 29 | color: #757575; 30 | margin-bottom: 4rem; 31 | margin-left: 15%; 32 | margin-right: 15%; 33 | text-align: center; 34 | } 35 | .section img { 36 | max-width: 100%; 37 | height: auto; 38 | } 39 | 40 | .card.card-cascade.narrower { 41 | margin-top: 20px; 42 | } 43 | .card.card-cascade { 44 | width: 100%; 45 | } 46 | .card:not([class*="card-outline-"]) { 47 | border: 0; 48 | } 49 | 50 | .card.card-cascade.narrower .view { 51 | margin-left: 4%; 52 | margin-right: 4%; 53 | margin-top: -20px; 54 | } 55 | .card.card-cascade .view { 56 | border-radius: 4px; 57 | } 58 | .btn-floating:hover, 59 | .card-overlay, 60 | .card.card-cascade .view, 61 | .colorful-select .dropdown-content li a:hover, 62 | .colorful-select .dropdown-content li span:hover, 63 | .comments-list img, 64 | .modal-dialog.cascading-modal.modal-avatar .modal-header img, 65 | .reply-form img, 66 | .testimonial-carousel .testimonial .avatar img, 67 | .z-depth-2 { 68 | -webkit-box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 69 | 0 6px 20px 0 rgba(0, 0, 0, 0.19); 70 | box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); 71 | } 72 | 73 | .card.card-cascade .card-body { 74 | padding-top: 1.8rem; 75 | } 76 | 77 | 78 | .card .card-body .card-title a{ 79 | color: var(--navBackground) !important; 80 | } 81 | 82 | .btn .fa, 83 | .card .card-body { 84 | position: relative; 85 | } 86 | .card .rating { 87 | color: #ffa000; 88 | } 89 | .rating { 90 | list-style-type: none; 91 | } 92 | .no-padding .fa, 93 | .rating { 94 | padding: 0; 95 | } 96 | .rating li { 97 | display: inline-block; 98 | } 99 | .no-padding .fa, 100 | .rating { 101 | padding: 0; 102 | } 103 | .card-text { 104 | line-height: 20px; 105 | height: 60px; 106 | overflow: hidden; 107 | } 108 | .card .card-footer { 109 | background-color: transparent; 110 | } 111 | 112 | .card .card-footer .left { 113 | float: left; 114 | } 115 | 116 | .card .card-footer .right { 117 | float: right; 118 | display: -webkit-box; 119 | display: -webkit-flex; 120 | display: -ms-flexbox; 121 | display: flex; 122 | } 123 | 124 | .card .card-footer .right a.active { 125 | color: #d50000; 126 | } 127 | .card .card-footer .right a { 128 | color: #757575; 129 | margin-left: 1rem; 130 | -webkit-transition: 0.4s; 131 | transition: 0.4s; 132 | } 133 | 134 | .card .card-footer .right a .fa-heart { 135 | color: var(--navBackground) !important; 136 | } 137 | -------------------------------------------------------------------------------- /src/app/layouts/product/best-product/best-product.component.ts: -------------------------------------------------------------------------------- 1 | import { TranslateService } from 'src/app/shared/services/translate.service'; 2 | import { Component, OnInit } from '@angular/core'; 3 | import { Product } from 'src/app/shared/models/product'; 4 | import { ProductService } from 'src/app/shared/services/product.service'; 5 | import { ToastrService } from 'src/app/shared/services/toastr.service'; 6 | 7 | @Component({ 8 | selector: 'app-best-product', 9 | templateUrl: './best-product.component.html', 10 | styleUrls: [ './best-product.component.scss' ] 11 | }) 12 | export class BestProductComponent implements OnInit { 13 | bestProducts: Product[] = []; 14 | options: any; 15 | loading = false; 16 | constructor( 17 | private productService: ProductService, 18 | private toasterService: ToastrService, 19 | public translate: TranslateService 20 | ) {} 21 | 22 | ngOnInit() { 23 | this.options = { 24 | dots: false, 25 | responsive: { 26 | '0': { items: 1, margin: 5 }, 27 | '430': { items: 2, margin: 5 }, 28 | '550': { items: 3, margin: 5 }, 29 | '670': { items: 4, margin: 5 } 30 | }, 31 | autoplay: true, 32 | loop: true, 33 | autoplayTimeout: 3000, 34 | lazyLoad: true 35 | }; 36 | this.getAllProducts(); 37 | } 38 | 39 | addFavourite(product: Product) { 40 | this.productService.addFavouriteProduct(product); 41 | } 42 | 43 | getAllProducts() { 44 | this.loading = true; 45 | const x = this.productService.getProducts(); 46 | x.snapshotChanges().subscribe( 47 | (product) => { 48 | this.loading = false; 49 | this.bestProducts = []; 50 | for (let i = 0; i < 5; i++) { 51 | const y = product[i].payload.toJSON(); 52 | y['$key'] = product[i].key; 53 | this.bestProducts.push(y as Product); 54 | } 55 | 56 | product.forEach(element => { 57 | const y = element.payload.toJSON(); 58 | y["$key"] = element.key; 59 | this.bestProducts.push(y as Product); 60 | }); 61 | }, 62 | 63 | 64 | 65 | 66 | (error) => { 67 | console.log(error); 68 | this.toasterService.error('Error while fetching Blogs', error); 69 | } 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/app/layouts/product/cart-calculator/cart-calculator.component.html: -------------------------------------------------------------------------------- 1 |

2 | Your Collections Of Read Later 3 | {{products.length}} 4 |

5 | -------------------------------------------------------------------------------- /src/app/layouts/product/cart-calculator/cart-calculator.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/app/layouts/product/cart-calculator/cart-calculator.component.scss -------------------------------------------------------------------------------- /src/app/layouts/product/cart-calculator/cart-calculator.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input, OnChanges, SimpleChange, SimpleChanges } from '@angular/core'; 2 | import { Product } from '../../../shared/models/product'; 3 | 4 | @Component({ 5 | selector: 'app-cart-calculator', 6 | templateUrl: './cart-calculator.component.html', 7 | styleUrls: [ './cart-calculator.component.scss' ] 8 | }) 9 | export class CartCalculatorComponent implements OnInit, OnChanges { 10 | @Input() products: Product[]; 11 | 12 | totalValue = 0; 13 | constructor() {} 14 | 15 | ngOnChanges(changes: SimpleChanges) { 16 | const dataChanges: SimpleChange = changes.products; 17 | 18 | const products: Product[] = dataChanges.currentValue; 19 | this.totalValue = 0; 20 | /* products.forEach((product) => { 21 | this.totalValue += product.productPrice; 22 | }); */ 23 | } 24 | 25 | ngOnInit() {} 26 | } 27 | -------------------------------------------------------------------------------- /src/app/layouts/product/cart-products/cart-products.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |
8 |
9 |
10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
{{ product.productCategory }}
32 |
33 |
34 | 35 | {{ product.productName }} 36 | 37 |
38 | 39 | 40 |

{{ product.productDescription }} 41 |

42 | 43 | 44 | 55 | 56 |
57 | 58 | 59 |
60 | 61 | 62 |
63 |
64 |
65 |
66 | 67 |
68 |
69 | 70 |
71 |
72 |
73 |
74 | 75 |
-------------------------------------------------------------------------------- /src/app/layouts/product/cart-products/cart-products.component.scss: -------------------------------------------------------------------------------- 1 | .section .section-heading { 2 | margin-top: 2rem; 3 | margin-bottom: 4rem; 4 | } 5 | .section-heading { 6 | text-align: center; 7 | } 8 | .section-description { 9 | margin-left: 5%; 10 | margin-right: 5%; 11 | } 12 | .section-description { 13 | color: #757575; 14 | margin-bottom: 4rem; 15 | margin-left: 15%; 16 | margin-right: 15%; 17 | text-align: center; 18 | } 19 | .section img { 20 | max-width: 100%; 21 | height: auto; 22 | } 23 | 24 | .card.card-cascade.narrower { 25 | margin-top: 10px; 26 | } 27 | .card.card-cascade { 28 | width: 100%; 29 | } 30 | .card:not([class*="card-outline-"]) { 31 | border: 0; 32 | } 33 | 34 | .card.card-cascade.narrower .view { 35 | margin-left: 4%; 36 | margin-right: 4%; 37 | margin-top: -20px; 38 | } 39 | .card.card-cascade .view { 40 | border-radius: 4px; 41 | } 42 | .btn-floating:hover, 43 | .card-overlay, 44 | .card.card-cascade .view, 45 | .colorful-select .dropdown-content li a:hover, 46 | .colorful-select .dropdown-content li span:hover, 47 | .comments-list img, 48 | .modal-dialog.cascading-modal.modal-avatar .modal-header img, 49 | .reply-form img, 50 | .testimonial-carousel .testimonial .avatar img, 51 | .z-depth-2 { 52 | -webkit-box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 53 | 0 6px 20px 0 rgba(0, 0, 0, 0.19); 54 | box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); 55 | } 56 | 57 | .card.card-cascade .card-body { 58 | padding-top: 1.8rem; 59 | } 60 | .btn .fa, 61 | .card .card-body { 62 | position: relative; 63 | } 64 | .card .rating { 65 | color: #ffa000; 66 | } 67 | .rating { 68 | list-style-type: none; 69 | } 70 | .no-padding .fa, 71 | .rating { 72 | padding: 0; 73 | } 74 | .rating li { 75 | display: inline-block; 76 | } 77 | .no-padding .fa, 78 | .rating { 79 | padding: 0; 80 | } 81 | 82 | .card-text { 83 | line-height: 20px; 84 | height: 60px; 85 | overflow: hidden; 86 | } 87 | 88 | .card .card-footer { 89 | background-color: transparent; 90 | } 91 | 92 | .card .card-footer .left { 93 | float: left; 94 | } 95 | 96 | .card .card-footer .right { 97 | float: right; 98 | display: -webkit-box; 99 | display: -webkit-flex; 100 | display: -ms-flexbox; 101 | display: flex; 102 | } 103 | 104 | .card .card-footer .right a.active { 105 | color: #d50000; 106 | } 107 | .card .card-footer .right a { 108 | color: #757575; 109 | margin-left: 1rem; 110 | -webkit-transition: 0.4s; 111 | transition: 0.4s; 112 | } 113 | -------------------------------------------------------------------------------- /src/app/layouts/product/cart-products/cart-products.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Product } from '../../../shared/models/product'; 3 | import { ProductService } from '../../../shared/services/product.service'; 4 | @Component({ 5 | selector: 'app-cart-products', 6 | templateUrl: './cart-products.component.html', 7 | styleUrls: [ './cart-products.component.scss' ] 8 | }) 9 | export class CartProductsComponent implements OnInit { 10 | cartProducts: Product[]; 11 | showDataNotFound = true; 12 | 13 | // Not Found Message 14 | messageTitle = 'No Products Found in Cart'; 15 | messageDescription = 'Please, Add Products to Cart'; 16 | 17 | constructor(private productService: ProductService) {} 18 | 19 | ngOnInit() { 20 | this.getCartProduct(); 21 | } 22 | 23 | removeCartProduct(product: Product) { 24 | this.productService.removeLocalCartProduct(product); 25 | 26 | // Recalling 27 | this.getCartProduct(); 28 | } 29 | 30 | getCartProduct() { 31 | this.cartProducts = this.productService.getLocalCartProducts(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/app/layouts/product/checkout/checkout-navbar/checkout-navbar.component.html: -------------------------------------------------------------------------------- 1 |

Checking Out Products

2 | 3 |
4 | 48 |
49 |
-------------------------------------------------------------------------------- /src/app/layouts/product/checkout/checkout-navbar/checkout-navbar.component.scss: -------------------------------------------------------------------------------- 1 | .board .nav-tabs { 2 | position: relative; 3 | margin: 40px auto; 4 | margin-bottom: 0; 5 | box-sizing: border-box; 6 | } 7 | .nav-tabs { 8 | border-bottom: 1px solid #ddd; 9 | } 10 | 11 | .nav { 12 | padding-left: 0; 13 | margin-bottom: 0; 14 | list-style: none; 15 | } 16 | .liner { 17 | height: 2px; 18 | background: #ddd; 19 | position: absolute; 20 | width: 78%; 21 | margin: 63px auto; 22 | left: 0; 23 | right: 0; 24 | z-index: 1; 25 | } 26 | .nav-tabs > li { 27 | width: 25%; 28 | } 29 | .nav-tabs > li { 30 | float: left; 31 | margin-bottom: -1px; 32 | } 33 | 34 | .nav > li { 35 | position: relative; 36 | display: block; 37 | } 38 | .nav-tabs > li a { 39 | width: 70px; 40 | height: 70px; 41 | margin: 20px auto; 42 | border-radius: 100%; 43 | padding: 0; 44 | } 45 | .nav-tabs > li > a { 46 | line-height: 1.42857143; 47 | border: 1px solid transparent; 48 | border-radius: 4px 4px 0 0; 49 | } 50 | 51 | .nav > li > a { 52 | position: relative; 53 | display: block; 54 | padding: 10px 15px; 55 | } 56 | a { 57 | color: #337ab7; 58 | text-decoration: none; 59 | } 60 | a { 61 | background-color: transparent; 62 | } 63 | #status-buttons a.active span.round-tabs.one { 64 | background: #22c222; 65 | color: #fff; 66 | } 67 | 68 | span.round-tabs.one { 69 | color: #22c222; 70 | border: 2px solid #22c222; 71 | } 72 | span.round-tabs.two { 73 | color: #febe29; 74 | border: 2px solid #febe29; 75 | } 76 | span.round-tabs.three { 77 | color: #3e5e9a; 78 | border: 2px solid #3e5e9a; 79 | } 80 | span.round-tabs.four { 81 | color: #f1685e; 82 | border: 2px solid #f1685e; 83 | } 84 | span.round-tabs { 85 | width: 70px; 86 | height: 70px; 87 | line-height: 70px; 88 | display: inline-block; 89 | border-radius: 100px; 90 | background: #fff; 91 | z-index: 2; 92 | position: absolute; 93 | left: 0; 94 | text-align: center; 95 | font-size: 25px; 96 | } 97 | -------------------------------------------------------------------------------- /src/app/layouts/product/checkout/checkout-navbar/checkout-navbar.component.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 3 | import { By } from '@angular/platform-browser'; 4 | import { DebugElement } from '@angular/core'; 5 | 6 | import { CheckoutNavbarComponent } from './checkout-navbar.component'; 7 | 8 | describe('CheckoutNavbarComponent', () => { 9 | let component: CheckoutNavbarComponent; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async(() => { 13 | TestBed.configureTestingModule({ 14 | declarations: [ CheckoutNavbarComponent ] 15 | }) 16 | .compileComponents(); 17 | })); 18 | 19 | beforeEach(() => { 20 | fixture = TestBed.createComponent(CheckoutNavbarComponent); 21 | component = fixture.componentInstance; 22 | fixture.detectChanges(); 23 | }); 24 | 25 | it('should create', () => { 26 | expect(component).toBeTruthy(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/app/layouts/product/checkout/checkout-navbar/checkout-navbar.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: "app-checkout-navbar", 5 | templateUrl: "./checkout-navbar.component.html", 6 | styleUrls: ["./checkout-navbar.component.scss"] 7 | }) 8 | export class CheckoutNavbarComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /src/app/layouts/product/checkout/checkout.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 |
13 | 14 |
15 | 16 | 17 | 18 |
19 |
-------------------------------------------------------------------------------- /src/app/layouts/product/checkout/checkout.component.scss: -------------------------------------------------------------------------------- 1 | .board { 2 | margin: 60px auto; 3 | height: 500px; 4 | background: #fff; 5 | } 6 | -------------------------------------------------------------------------------- /src/app/layouts/product/checkout/checkout.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: "app-checkout", 5 | templateUrl: "./checkout.component.html", 6 | styleUrls: ["./checkout.component.scss"] 7 | }) 8 | export class CheckoutComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /src/app/layouts/product/checkout/checkout.module.ts: -------------------------------------------------------------------------------- 1 | import { CheckoutRoutingModule } from './checkout.routing'; 2 | import { SharedModule } from '../../../shared/shared.module'; 3 | import { CheckoutNavbarComponent } from './checkout-navbar/checkout-navbar.component'; 4 | 5 | import { ProductsComponent } from './products/products.component'; 6 | 7 | import { NgModule } from '@angular/core'; 8 | import { CommonModule } from '@angular/common'; 9 | import { CheckoutComponent } from './checkout.component'; 10 | 11 | 12 | @NgModule({ 13 | imports: [ CommonModule, SharedModule, CheckoutRoutingModule ], 14 | declarations: [ 15 | CheckoutComponent, 16 | 17 | 18 | ProductsComponent, 19 | 20 | CheckoutNavbarComponent 21 | ], 22 | exports: [ CheckoutComponent ] 23 | }) 24 | export class CheckoutModule {} 25 | -------------------------------------------------------------------------------- /src/app/layouts/product/checkout/checkout.routing.ts: -------------------------------------------------------------------------------- 1 | import { CheckoutComponent } from './checkout.component'; 2 | 3 | import { ProductsComponent } from './products/products.component'; 4 | import { NgModule } from '@angular/core'; 5 | import { Routes, RouterModule } from '@angular/router'; 6 | import { AuthGuard } from '../../../shared/services/auth_gaurd'; 7 | 8 | export const checkoutRoutes: Routes = [ 9 | { 10 | path: 'checkouts', 11 | component: CheckoutComponent, 12 | canActivate: [ AuthGuard ], 13 | children: [ 14 | { 15 | path: '', 16 | component: ProductsComponent, 17 | outlet: 'checkOutlet' 18 | }, 19 | 20 | ] 21 | } 22 | ]; 23 | 24 | @NgModule({ 25 | imports: [ RouterModule.forChild(checkoutRoutes) ], 26 | exports: [ RouterModule ] 27 | }) 28 | export class CheckoutRoutingModule {} 29 | -------------------------------------------------------------------------------- /src/app/layouts/product/checkout/products/products.component.html: -------------------------------------------------------------------------------- 1 |
2 |
    3 |
  • 4 |
    5 | 6 |
    7 |
    8 |
    {{product.productName}}
    9 |

    Blog By : {{product.productSeller}}

    10 |
    11 | ₹ {{product.productPrice}} 12 |
  • 13 |
    14 | 18 | 19 |
20 |
21 | Next 22 |
23 | 24 |
-------------------------------------------------------------------------------- /src/app/layouts/product/checkout/products/products.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/app/layouts/product/checkout/products/products.component.scss -------------------------------------------------------------------------------- /src/app/layouts/product/checkout/products/products.component.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | import { async, ComponentFixture, TestBed } from "@angular/core/testing"; 3 | import { By } from "@angular/platform-browser"; 4 | import { DebugElement } from "@angular/core"; 5 | 6 | import { ProductsComponent } from "./products.component"; 7 | 8 | describe("ProductsComponent", () => { 9 | let component: ProductsComponent; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async(() => { 13 | TestBed.configureTestingModule({ 14 | declarations: [ProductsComponent] 15 | }).compileComponents(); 16 | })); 17 | 18 | beforeEach(() => { 19 | fixture = TestBed.createComponent(ProductsComponent); 20 | component = fixture.componentInstance; 21 | fixture.detectChanges(); 22 | }); 23 | 24 | it("should create", () => { 25 | expect(component).toBeTruthy(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /src/app/layouts/product/checkout/products/products.component.ts: -------------------------------------------------------------------------------- 1 | import { ProductService } from '../../../../shared/services/product.service'; 2 | import { Component, OnInit, ViewChild } from '@angular/core'; 3 | import { Product } from '../../../../shared/models/product'; 4 | 5 | @Component({ 6 | selector: 'app-products', 7 | templateUrl: './products.component.html', 8 | styleUrls: [ './products.component.scss' ] 9 | }) 10 | export class ProductsComponent implements OnInit { 11 | checkoutProducts: Product[]; 12 | 13 | totalPrice = 0; 14 | constructor(productService: ProductService) { 15 | document.getElementById('shippingTab').style.display = 'none'; 16 | document.getElementById('billingTab').style.display = 'none'; 17 | document.getElementById('resultTab').style.display = 'none'; 18 | 19 | const products = productService.getLocalCartProducts(); 20 | 21 | this.checkoutProducts = products; 22 | /* 23 | products.forEach((product) => { 24 | this.totalPrice += product.productPrice; 25 | }); */ 26 | } 27 | 28 | ngOnInit() {} 29 | } 30 | -------------------------------------------------------------------------------- /src/app/layouts/product/favourite-products/favourite-products.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |
8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 |
{{ product.productCategory }}
30 |
31 |
32 | 33 | {{ product.productName }} 34 | 35 |
36 | 37 | 38 |

{{ product.productDescription }} 39 |

40 | 41 | 42 | 53 | 54 |
55 | 56 | 57 |
58 | 59 | 60 |
61 |
62 |
63 |
64 |
65 | 66 |
67 | 68 | 69 |
70 | -------------------------------------------------------------------------------- /src/app/layouts/product/favourite-products/favourite-products.component.scss: -------------------------------------------------------------------------------- 1 | .section .section-heading { 2 | margin-top: 2rem; 3 | margin-bottom: 4rem; 4 | } 5 | .section-heading { 6 | text-align: center; 7 | } 8 | .section-description { 9 | margin-left: 5%; 10 | margin-right: 5%; 11 | } 12 | .section-description { 13 | color: #757575; 14 | margin-bottom: 4rem; 15 | margin-left: 15%; 16 | margin-right: 15%; 17 | text-align: center; 18 | } 19 | .section img { 20 | max-width: 100%; 21 | height: auto; 22 | } 23 | 24 | .card.card-cascade.narrower { 25 | margin-top: 10px; 26 | } 27 | .card.card-cascade { 28 | width: 100%; 29 | } 30 | .card:not([class*="card-outline-"]) { 31 | border: 0; 32 | } 33 | 34 | .card.card-cascade.narrower .view { 35 | margin-left: 4%; 36 | margin-right: 4%; 37 | margin-top: -20px; 38 | } 39 | .card.card-cascade .view { 40 | border-radius: 4px; 41 | } 42 | .btn-floating:hover, 43 | .card-overlay, 44 | .card.card-cascade .view, 45 | .colorful-select .dropdown-content li a:hover, 46 | .colorful-select .dropdown-content li span:hover, 47 | .comments-list img, 48 | .modal-dialog.cascading-modal.modal-avatar .modal-header img, 49 | .reply-form img, 50 | .testimonial-carousel .testimonial .avatar img, 51 | .z-depth-2 { 52 | -webkit-box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 53 | 0 6px 20px 0 rgba(0, 0, 0, 0.19); 54 | box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); 55 | } 56 | 57 | .card.card-cascade .card-body { 58 | padding-top: 1.8rem; 59 | } 60 | .btn .fa, 61 | .card .card-body { 62 | position: relative; 63 | } 64 | .card .rating { 65 | color: #ffa000; 66 | } 67 | .rating { 68 | list-style-type: none; 69 | } 70 | .no-padding .fa, 71 | .rating { 72 | padding: 0; 73 | } 74 | .rating li { 75 | display: inline-block; 76 | } 77 | .no-padding .fa, 78 | .rating { 79 | padding: 0; 80 | } 81 | 82 | .card-text { 83 | line-height: 20px; 84 | height: 60px; 85 | overflow: hidden; 86 | } 87 | 88 | .card .card-footer { 89 | background-color: transparent; 90 | } 91 | 92 | .card .card-footer .left { 93 | float: left; 94 | } 95 | 96 | .card .card-footer .right { 97 | float: right; 98 | display: -webkit-box; 99 | display: -webkit-flex; 100 | display: -ms-flexbox; 101 | display: flex; 102 | } 103 | 104 | .card .card-footer .right a.active { 105 | color: #d50000; 106 | } 107 | .card .card-footer .right a { 108 | color: #757575; 109 | margin-left: 1rem; 110 | -webkit-transition: 0.4s; 111 | transition: 0.4s; 112 | } 113 | 114 | body { 115 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABZ0RVh0Q3JlYXRpb24gVGltZQAxMC8yOS8xMiKqq3kAAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzVxteM2AAABHklEQVRIib2Vyw6EIAxFW5idr///Qx9sfG3pLEyJ3tAwi5EmBqRo7vHawiEEERHS6x7MTMxMVv6+z3tPMUYSkfTM/R0fEaG2bbMv+Gc4nZzn+dN4HAcREa3r+hi3bcuu68jLskhVIlW073tWaYlQ9+F9IpqmSfq+fwskhdO/AwmUTJXrOuaRQNeRkOd5lq7rXmS5InmERKoER/QMvUAPlZDHcZRhGN4CSeGY+aHMqgcks5RrHv/eeh455x5KrMq2yHQdibDO6ncG/KZWL7M8xDyS1/MIO0NJqdULLS81X6/X6aR0nqBSJcPeZnlZrzN477NKURn2Nus8sjzmEII0TfMiyxUuxphVWjpJkbx0btUnshRihVv70Bv8ItXq6Asoi/ZiCbU6YgAAAABJRU5ErkJggg==); 116 | } 117 | .error-template { 118 | padding: 40px 15px; 119 | text-align: center; 120 | } 121 | .error-actions { 122 | margin-top: 15px; 123 | margin-bottom: 15px; 124 | } 125 | .error-actions .btn { 126 | margin-right: 10px; 127 | } 128 | -------------------------------------------------------------------------------- /src/app/layouts/product/favourite-products/favourite-products.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Product } from '../../../shared/models/product'; 3 | import { ProductService } from '../../../shared/services/product.service'; 4 | @Component({ 5 | selector: 'app-favourite-products', 6 | templateUrl: './favourite-products.component.html', 7 | styleUrls: [ './favourite-products.component.scss' ] 8 | }) 9 | export class FavouriteProductsComponent implements OnInit { 10 | favoruiteProducts: Product[]; 11 | showDataNotFound = true; 12 | 13 | // Not Found Message 14 | messageTitle = 'No Favourite Products Found'; 15 | messageDescription = 'Please, choose your favourite products'; 16 | 17 | constructor(private productService: ProductService) {} 18 | 19 | ngOnInit() { 20 | this.getFavouriteProduct(); 21 | } 22 | removeFavourite(product: Product) { 23 | this.productService.removeLocalFavourite(product); 24 | 25 | this.getFavouriteProduct(); 26 | } 27 | 28 | getFavouriteProduct() { 29 | this.favoruiteProducts = this.productService.getLocalFavouriteProducts(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/app/layouts/product/product-detail/product-detail.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 |
7 | 8 |
9 |
10 |
    11 |
  • 12 |
    13 |
    blog Category
    14 |
    15 | {{product.productCategory}} 16 |
  • 17 |
  • 18 |
    19 |
    Blog by
    20 |
    21 | {{product.productSeller}} 22 |
  • 23 |
24 | 25 |
26 |
27 |
28 |
29 |
30 |
Blog Details
31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
Blog Name{{product.productName}}
View Full Blog On Medium{{product.productUrl}} 40 |
Blog Description{{product.productDescription}}
Blog Added on{{product.productAdded * 1000 | date}}
53 |
54 |
55 |
56 |
57 | -------------------------------------------------------------------------------- /src/app/layouts/product/product-detail/product-detail.component.scss: -------------------------------------------------------------------------------- 1 | .product-detail .product-head { 2 | padding: 10px; 3 | font-weight: 500; 4 | } 5 | 6 | .product-detail .table th { 7 | width: 152px; 8 | } 9 | 10 | .product-ship { 11 | height: 15rem; 12 | } 13 | -------------------------------------------------------------------------------- /src/app/layouts/product/product-detail/product-detail.component.ts: -------------------------------------------------------------------------------- 1 | import { Product } from '../../../shared/models/product'; 2 | import { Component, OnInit, OnDestroy } from '@angular/core'; 3 | import { ActivatedRoute } from '@angular/router'; 4 | import { ProductService } from '../../../shared/services/product.service'; 5 | import { ToastrService } from 'src/app/shared/services/toastr.service'; 6 | @Component({ 7 | selector: 'app-product-detail', 8 | templateUrl: './product-detail.component.html', 9 | styleUrls: [ './product-detail.component.scss' ] 10 | }) 11 | export class ProductDetailComponent implements OnInit, OnDestroy { 12 | private sub: any; 13 | product: Product; 14 | 15 | constructor( 16 | private route: ActivatedRoute, 17 | private productService: ProductService, 18 | private toastrService: ToastrService 19 | ) { 20 | this.product = new Product(); 21 | } 22 | 23 | ngOnInit() { 24 | this.sub = this.route.params.subscribe((params) => { 25 | const id = params['id']; // (+) converts string 'id' to a number 26 | this.getProductDetail(id); 27 | }); 28 | } 29 | 30 | getProductDetail(id: string) { 31 | // this.spinnerService.show(); 32 | const x = this.productService.getProductById(id); 33 | x.snapshotChanges().subscribe( 34 | (product) => { 35 | // this.spinnerService.hide(); 36 | const y = product.payload.toJSON() as Product; 37 | 38 | y['$key'] = id; 39 | this.product = y; 40 | }, 41 | (error) => { 42 | this.toastrService.error('Error while fetching Product Detail', error); 43 | } 44 | ); 45 | } 46 | 47 | addToCart(product: Product) { 48 | this.productService.addToCart(product); 49 | } 50 | 51 | ngOnDestroy() { 52 | this.sub.unsubscribe(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/app/layouts/product/product-list/product-list.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 | 9 | 10 | 13 | 14 | Add Blogs 15 |
16 |
17 |
18 | 19 | 20 |
21 | 30 |
31 | 32 |
33 | 34 |
35 | 36 |
37 |
38 |
39 | 40 |
41 | 42 | 43 | 49 | 50 | 51 | 52 |
53 | 54 | 55 |
{{ product.productCategory }}
56 |
57 |

58 | 59 | {{ 60 | product.productName }} 61 | 62 |

63 | 64 |

{{ product.productDescription }} 65 |

66 | 67 | 82 | 83 |
84 | 85 | 86 |
87 | 88 | 89 |
90 |
91 |
92 |
93 | 94 |
95 | 96 |
97 |
98 | 99 |
100 |
101 |
102 | 103 | -------------------------------------------------------------------------------- /src/app/layouts/product/product-list/product-list.component.scss: -------------------------------------------------------------------------------- 1 | @import "../../../../assets/theme/colors"; 2 | @import "../../../../assets/theme/functions"; 3 | 4 | 5 | .section .section-heading { 6 | margin-top: 2rem; 7 | margin-bottom: 4rem; 8 | } 9 | .section-heading { 10 | text-align: center; 11 | } 12 | .section-description { 13 | margin-left: 5%; 14 | margin-right: 5%; 15 | } 16 | .section-description { 17 | color: #757575; 18 | margin-bottom: 4rem; 19 | margin-left: 15%; 20 | margin-right: 15%; 21 | text-align: center; 22 | } 23 | .section img { 24 | max-width: 100%; 25 | height: auto; 26 | } 27 | 28 | .card.card-cascade.narrower { 29 | margin-top: 10px; 30 | } 31 | .card.card-cascade { 32 | width: 100%; 33 | } 34 | .card:not([class*="card-outline-"]) { 35 | border: 0; 36 | } 37 | 38 | .card.card-cascade.narrower .view { 39 | margin-left: 4%; 40 | margin-right: 4%; 41 | margin-top: -20px; 42 | } 43 | .card.card-cascade .view { 44 | border-radius: 4px; 45 | } 46 | .btn-floating:hover, 47 | .card-overlay, 48 | .card.card-cascade .view, 49 | .colorful-select .dropdown-content li a:hover, 50 | .colorful-select .dropdown-content li span:hover, 51 | .comments-list img, 52 | .modal-dialog.cascading-modal.modal-avatar .modal-header img, 53 | .reply-form img, 54 | .testimonial-carousel .testimonial .avatar img, 55 | .z-depth-2 { 56 | -webkit-box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 57 | 0 6px 20px 0 rgba(0, 0, 0, 0.19); 58 | box-shadow: 0 8px 17px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); 59 | } 60 | 61 | .card.card-cascade .card-body { 62 | padding-top: 1.8rem; 63 | } 64 | .btn .fa, 65 | .card .card-body { 66 | position: relative; 67 | } 68 | 69 | .card .card-body .card-title a{ 70 | color: var(--navBackground) !important; 71 | } 72 | 73 | 74 | .card .rating { 75 | color: #ffa000; 76 | } 77 | .rating { 78 | list-style-type: none; 79 | } 80 | .no-padding .fa, 81 | .rating { 82 | padding: 0; 83 | } 84 | .rating li { 85 | display: inline-block; 86 | } 87 | .no-padding .fa, 88 | .rating { 89 | padding: 0; 90 | } 91 | 92 | .card-text { 93 | line-height: 20px; 94 | height: 60px; 95 | overflow: hidden; 96 | } 97 | 98 | .card .card-footer { 99 | background-color: transparent; 100 | } 101 | 102 | .card .card-footer .left { 103 | float: left; 104 | } 105 | 106 | .card .card-footer .right { 107 | float: right; 108 | display: -webkit-box; 109 | display: -webkit-flex; 110 | display: -ms-flexbox; 111 | display: flex; 112 | } 113 | 114 | .card .card-footer .right a.active { 115 | color: #d50000; 116 | } 117 | .card .card-footer .right a { 118 | color: #757575; 119 | margin-left: 1rem; 120 | -webkit-transition: 0.4s; 121 | transition: 0.4s; 122 | } 123 | 124 | .card .card-footer .right a .fa-heart { 125 | color: var(--navBackground) !important; 126 | } 127 | -------------------------------------------------------------------------------- /src/app/layouts/product/product-list/product-list.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Product } from '../../../shared/models/product'; 3 | import { AuthService } from '../../../shared/services/auth.service'; 4 | import { ProductService } from '../../../shared/services/product.service'; 5 | import { ToastrService } from 'src/app/shared/services/toastr.service'; 6 | @Component({ 7 | selector: 'app-product-list', 8 | templateUrl: './product-list.component.html', 9 | styleUrls: ['./product-list.component.scss'] 10 | }) 11 | export class ProductListComponent implements OnInit { 12 | productList: Product[]; 13 | loading = false; 14 | 15 | selectedBrand: 'All'; 16 | 17 | page = 1; 18 | constructor( 19 | public authService: AuthService, 20 | private productService: ProductService, 21 | private toastrService: ToastrService 22 | ) { } 23 | 24 | ngOnInit() { 25 | this.getAllProducts(); 26 | } 27 | 28 | getAllProducts() { 29 | // this.spinnerService.show(); 30 | this.loading = true; 31 | const x = this.productService.getProducts(); 32 | x.snapshotChanges().subscribe( 33 | (product) => { 34 | this.loading = false; 35 | // this.spinnerService.hide(); 36 | this.productList = []; 37 | product.forEach((element) => { 38 | const y = element.payload.toJSON(); 39 | y['$key'] = element.key; 40 | this.productList.push(y as Product); 41 | }); 42 | }, 43 | (err) => { 44 | this.toastrService.error('Error while fetching Blogs', err); 45 | } 46 | ); 47 | } 48 | 49 | removeProduct(key: string) { 50 | this.productService.deleteProduct(key); 51 | } 52 | 53 | addFavourite(product: Product) { 54 | this.productService.addFavouriteProduct(product); 55 | } 56 | 57 | addToCart(product: Product) { 58 | this.productService.addToCart(product); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/app/layouts/product/product.component.html: -------------------------------------------------------------------------------- 1 |

2 | product works! 3 |

-------------------------------------------------------------------------------- /src/app/layouts/product/product.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/app/layouts/product/product.component.scss -------------------------------------------------------------------------------- /src/app/layouts/product/product.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: "app-product", 5 | templateUrl: "./product.component.html", 6 | styleUrls: ["./product.component.scss"] 7 | }) 8 | export class ProductComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /src/app/layouts/product/product.module.ts: -------------------------------------------------------------------------------- 1 | // Core Dependencies 2 | import { NgModule } from "@angular/core"; 3 | import { CommonModule } from "@angular/common"; 4 | import { RouterModule } from "@angular/router"; 5 | 6 | // configuration and services 7 | import { ProductRoutes } from "./product.routing"; 8 | 9 | // Components 10 | import { CheckoutModule } from "./checkout/checkout.module"; 11 | 12 | import { ProductComponent } from "./product.component"; 13 | import { BestProductComponent } from "./best-product/best-product.component"; 14 | import { ProductListComponent } from "./product-list/product-list.component"; 15 | import { AddProductComponent } from "./add-product/add-product.component"; 16 | import { ProductDetailComponent } from "./product-detail/product-detail.component"; 17 | import { SharedModule } from "../../shared/shared.module"; 18 | import { FavouriteProductsComponent } from "./favourite-products/favourite-products.component"; 19 | import { CartProductsComponent } from "./cart-products/cart-products.component"; 20 | import { CartCalculatorComponent } from "./cart-calculator/cart-calculator.component"; 21 | import { NgxEditorModule } from 'ngx-editor'; 22 | import { CKEditorModule } from '@ckeditor/ckeditor5-angular'; 23 | 24 | 25 | @NgModule({ 26 | imports: [CommonModule, 27 | RouterModule.forChild(ProductRoutes), 28 | SharedModule, CheckoutModule, 29 | NgxEditorModule , 30 | CKEditorModule], 31 | 32 | declarations: [ 33 | ProductComponent, 34 | BestProductComponent, 35 | ProductListComponent, 36 | AddProductComponent, 37 | ProductDetailComponent, 38 | FavouriteProductsComponent, 39 | CartProductsComponent, 40 | CartCalculatorComponent 41 | ], 42 | exports: [BestProductComponent] 43 | }) 44 | export class ProductModule { } 45 | -------------------------------------------------------------------------------- /src/app/layouts/product/product.routing.ts: -------------------------------------------------------------------------------- 1 | import { CartProductsComponent } from './cart-products/cart-products.component'; 2 | import { FavouriteProductsComponent } from './favourite-products/favourite-products.component'; 3 | import { ProductListComponent } from './product-list/product-list.component'; 4 | import { Routes } from '@angular/router'; 5 | import { IndexComponent } from '../../index/index.component'; 6 | import { ProductDetailComponent } from './product-detail/product-detail.component'; 7 | import { AddProductComponent } from './add-product/add-product.component'; 8 | import { AuthGuard } from 'src/app/shared/services/auth_gaurd'; 9 | 10 | export const ProductRoutes: Routes = [ 11 | { 12 | path: 'products', 13 | children: [ 14 | { 15 | path: 'add-products', 16 | component: AddProductComponent 17 | }, 18 | 19 | { 20 | path: 'all-products', 21 | component: ProductListComponent, 22 | 23 | }, 24 | { 25 | path: 'favourite-products', 26 | component: FavouriteProductsComponent, 27 | canActivate: [ AuthGuard ] 28 | 29 | }, 30 | { 31 | path: 'cart-items', 32 | component: CartProductsComponent, 33 | canActivate: [ AuthGuard ] 34 | }, 35 | { 36 | path: 'checkouts', 37 | loadChildren: './checkout/checkout.module#CheckoutModule' 38 | }, 39 | 40 | { 41 | path: 'product/:id', 42 | component: ProductDetailComponent 43 | } 44 | ] 45 | } 46 | ]; 47 | -------------------------------------------------------------------------------- /src/app/layouts/task-board/task-board.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/layouts/task-board/task-board.component.scss: -------------------------------------------------------------------------------- 1 | .example-container { 2 | max-width: 100%; 3 | margin: 0 25px 25px 0; 4 | display: inline-block; 5 | vertical-align: top; 6 | } 7 | 8 | .content { 9 | font-size: 16px; 10 | line-height: 28px; 11 | font-weight: 400; 12 | color: rgba(0, 0, 0, .87); 13 | margin: 12px; 14 | padding: 10px; 15 | } 16 | 17 | .example-list { 18 | padding: 6px; 19 | width: 300px; 20 | background: #f4f5f7; 21 | margin: 5px; 22 | border-radius: 4px; 23 | height: 450px; 24 | overflow: auto; 25 | } 26 | 27 | .example-box { 28 | box-shadow: 0px 1px 2px 0px rgba(9, 30, 66, 0.25); 29 | padding: 5px; 30 | margin: 0 0 6px 0; 31 | 32 | .d-flex { 33 | .edit-icon { 34 | display: none; 35 | } 36 | } 37 | } 38 | 39 | .example-box:hover { 40 | background-color: #f0f2f4; 41 | 42 | .d-flex { 43 | .edit-icon { 44 | display: block; 45 | position: absolute; 46 | right: 10px; 47 | } 48 | } 49 | } 50 | 51 | .card-body { 52 | padding: 0.8rem 53 | } 54 | 55 | .cdk-drag { 56 | cursor: pointer; 57 | } 58 | 59 | .cdk-drag-preview { 60 | box-sizing: border-box; 61 | border-radius: 4px; 62 | box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 63 | 0 8px 10px 1px rgba(0, 0, 0, 0.14), 64 | 0 3px 14px 2px rgba(0, 0, 0, 0.12); 65 | } 66 | 67 | .cdk-drag-placeholder { 68 | opacity: 0; 69 | } 70 | 71 | .cdk-drag-animating { 72 | transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); 73 | } 74 | 75 | .example-box:last-child { 76 | border: none; 77 | } 78 | 79 | .example-list.cdk-drop-list-dragging .example-box:not(.cdk-drag-placeholder) { 80 | transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); 81 | } 82 | -------------------------------------------------------------------------------- /src/app/layouts/task-board/task-board.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | import { 3 | CdkDragDrop, 4 | moveItemInArray, 5 | transferArrayItem 6 | } from "@angular/cdk/drag-drop"; 7 | import { TaskService } from "src/app/shared/services/task.service"; 8 | import * as _ from "lodash"; 9 | @Component({ 10 | selector: "app-task-board", 11 | templateUrl: "./task-board.component.html", 12 | styleUrls: ["./task-board.component.scss"] 13 | }) 14 | export class TaskBoardComponent implements OnInit { 15 | todo = new Array(); 16 | inProgress = new Array(); 17 | completed = new Array(); 18 | constructor(private taskService: TaskService) { } 19 | 20 | ngOnInit() { 21 | this.getAllTasks(); 22 | } 23 | 24 | getAllTasks() { 25 | this.taskService.getTasks().then(data => { 26 | const tasks: [] = data as []; 27 | tasks.forEach(task => { 28 | const boardId: string = task["boardId"]; 29 | // Pushing Task to board based on boardId 30 | switch (boardId) { 31 | case "IK_PROGRESS": 32 | this.inProgress.push(task); 33 | break; 34 | case "IK_COMPLETED": 35 | this.completed.push(task); 36 | break; 37 | default: 38 | this.todo.push(task); 39 | break; 40 | } 41 | // Sorting Board Cards based on columnIndex 42 | this.todo = _.sortBy(this.todo, ["columnIndex"]); 43 | this.inProgress = _.sortBy(this.inProgress, ["columnIndex"]); 44 | this.completed = _.sortBy(this.completed, ["columnIndex"]); 45 | }); 46 | }); 47 | } 48 | 49 | drop(event: CdkDragDrop) { 50 | console.log(event.container.data); 51 | if (event.previousContainer === event.container) { 52 | moveItemInArray(event.container.data, event.previousIndex, event.currentIndex); 53 | } else { 54 | transferArrayItem(event.previousContainer.data, 55 | event.container.data, 56 | event.previousIndex, 57 | event.currentIndex); 58 | } 59 | } 60 | onSelect(event) { 61 | console.log(event); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/app/layouts/task-board/task-board.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from "@angular/core"; 2 | import { CommonModule } from "@angular/common"; 3 | import { TaskBoardComponent } from "./task-board.component"; 4 | import { SharedModule } from "src/app/shared/shared.module"; 5 | import { TaskRoutes } from "./task.routing"; 6 | 7 | @NgModule({ 8 | imports: [ 9 | CommonModule, SharedModule, TaskRoutes], 10 | declarations: [TaskBoardComponent] 11 | }) 12 | export class TaskBoardModule { } 13 | -------------------------------------------------------------------------------- /src/app/layouts/task-board/task.routing.ts: -------------------------------------------------------------------------------- 1 | import { TaskBoardComponent } from "./task-board.component"; 2 | import { Routes, RouterModule } from "@angular/router"; 3 | import { AuthGuard } from "src/app/shared/services/auth_gaurd"; 4 | 5 | const routes: Routes = [{ 6 | path: "tasks", 7 | children: [ 8 | { 9 | path: '', 10 | component: TaskBoardComponent 11 | } 12 | ] 13 | }]; 14 | 15 | export const TaskRoutes = RouterModule.forChild(routes); 16 | -------------------------------------------------------------------------------- /src/app/layouts/user/user-account/user-account.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 | 6 |
7 | 8 |

{{loggedUser.userName}}

9 |
10 |
11 | 12 |

{{loggedUser.emailId}}

13 |
14 |
15 |
16 | -------------------------------------------------------------------------------- /src/app/layouts/user/user-account/user-account.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/app/layouts/user/user-account/user-account.component.scss -------------------------------------------------------------------------------- /src/app/layouts/user/user-account/user-account.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { User } from 'src/app/shared/models/user'; 3 | import { AuthService } from 'src/app/shared/services/auth.service'; 4 | 5 | @Component({ 6 | selector: 'app-user-account', 7 | templateUrl: './user-account.component.html', 8 | styleUrls: [ './user-account.component.scss' ] 9 | }) 10 | export class UserAccountComponent implements OnInit { 11 | loggedUser: User; 12 | // Enable Update Button 13 | 14 | constructor(private authService: AuthService) {} 15 | 16 | ngOnInit() { 17 | this.loggedUser = this.authService.getLoggedInUser(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/app/layouts/user/user.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 |
7 | 18 |
19 |
20 | 21 |
22 |
23 |
24 | -------------------------------------------------------------------------------- /src/app/layouts/user/user.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/app/layouts/user/user.component.scss -------------------------------------------------------------------------------- /src/app/layouts/user/user.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { AuthService } from 'src/app/shared/services/auth.service'; 3 | 4 | @Component({ 5 | selector: 'app-user', 6 | templateUrl: './user.component.html', 7 | styleUrls: [ './user.component.scss' ] 8 | }) 9 | export class UserComponent implements OnInit { 10 | constructor(public authService: AuthService) {} 11 | 12 | ngOnInit() {} 13 | } 14 | -------------------------------------------------------------------------------- /src/app/layouts/user/user.module.ts: -------------------------------------------------------------------------------- 1 | // Core Dependencies 2 | import { RouterModule } from "@angular/router"; 3 | import { NgModule, NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; 4 | import { CommonModule } from "@angular/common"; 5 | 6 | // Configuration and Services 7 | import { UserRoutes } from "./user.routing"; 8 | 9 | // Components 10 | import { UserComponent } from "./user.component"; 11 | import { UserAccountComponent } from "./user-account/user-account.component"; 12 | import { SharedModule } from "src/app/shared/shared.module"; 13 | 14 | @NgModule({ 15 | imports: [CommonModule, SharedModule, RouterModule.forChild(UserRoutes)], 16 | declarations: [UserComponent, UserAccountComponent], 17 | providers: [], 18 | schemas: [NO_ERRORS_SCHEMA, CUSTOM_ELEMENTS_SCHEMA] 19 | }) 20 | export class UserModule { } 21 | -------------------------------------------------------------------------------- /src/app/layouts/user/user.routing.ts: -------------------------------------------------------------------------------- 1 | import { UserComponent } from './user.component'; 2 | import { UserAccountComponent } from './user-account/user-account.component'; 3 | import { Routes, RouterModule } from '@angular/router'; 4 | import { AuthGuard } from 'src/app/shared/services/auth_gaurd'; 5 | import { CartProductsComponent } from '../product/cart-products/cart-products.component'; 6 | import { FavouriteProductsComponent } from '../product/favourite-products/favourite-products.component'; 7 | 8 | export const UserRoutes: Routes = [ 9 | { 10 | path: 'users', 11 | component: UserComponent, 12 | canActivate: [ AuthGuard ], 13 | children: [ 14 | { 15 | path: '', 16 | component: UserAccountComponent, 17 | outlet: 'profileOutlet' 18 | }, 19 | 20 | /* { 21 | path: 'products/cart-items', 22 | component: CartProductsComponent, 23 | 24 | }, 25 | 26 | { 27 | path: 'products/favourite-products', 28 | component: FavouriteProductsComponent, 29 | 30 | } */ 31 | ] 32 | } 33 | ]; 34 | -------------------------------------------------------------------------------- /src/app/shared/animations/fadeIntRoute.ts: -------------------------------------------------------------------------------- 1 | import { 2 | trigger, 3 | animate, 4 | transition, 5 | style, 6 | query 7 | } from "@angular/animations"; 8 | 9 | export const fadeAnimation = trigger("fadeAnimation", [ 10 | // The '* => *' will trigger the animation to change between any two states 11 | transition("* => *", [ 12 | // The query function has three params. 13 | // First is the event, so this will apply on entering or when the element is added to the DOM. 14 | // Second is a list of styles or animations to apply. 15 | // Third we add a config object with optional set to true, this is to signal 16 | // angular that the animation may not apply as it may or may not be in the DOM. 17 | query(":enter", [style({ opacity: 0 })], { optional: true }), 18 | query( 19 | ":leave", 20 | // here we apply a style and use the animate function to apply the style over 0.3 seconds 21 | [style({ opacity: 1 }), animate("0.3s", style({ opacity: 0 }))], 22 | { optional: true } 23 | ), 24 | query( 25 | ":enter", 26 | [style({ opacity: 0 }), animate("0.3s", style({ opacity: 1 }))], 27 | { optional: true } 28 | ) 29 | ]) 30 | ]); 31 | -------------------------------------------------------------------------------- /src/app/shared/components/card-loader/card-loader.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 | 6 |
7 |
8 | -------------------------------------------------------------------------------- /src/app/shared/components/card-loader/card-loader.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/app/shared/components/card-loader/card-loader.component.scss -------------------------------------------------------------------------------- /src/app/shared/components/card-loader/card-loader.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { CardLoaderComponent } from './card-loader.component'; 4 | 5 | describe('CardLoaderComponent', () => { 6 | let component: CardLoaderComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ CardLoaderComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(CardLoaderComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/shared/components/card-loader/card-loader.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: "app-card-loader", 5 | templateUrl: "./card-loader.component.html", 6 | styleUrls: ["./card-loader.component.scss"] 7 | }) 8 | export class CardLoaderComponent implements OnInit { 9 | @Input() loop: number; 10 | @Input() height: number; 11 | 12 | constructor() {} 13 | 14 | ngOnInit() {} 15 | 16 | arrayOne(n: number): any[] { 17 | return Array(n); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/app/shared/components/no-access/no-access.component.html: -------------------------------------------------------------------------------- 1 |

2 | no-access works! 3 |

-------------------------------------------------------------------------------- /src/app/shared/components/no-access/no-access.component.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/app/shared/components/no-access/no-access.component.scss -------------------------------------------------------------------------------- /src/app/shared/components/no-access/no-access.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: "app-no-access", 5 | templateUrl: "./no-access.component.html", 6 | styleUrls: ["./no-access.component.scss"] 7 | }) 8 | export class NoAccessComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /src/app/shared/components/no-products-found/no-products-found.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

5 | Oops!

6 |

7 | {{title}}

8 |
9 | {{description}} 10 |
11 | 18 |
19 |
20 |
21 | -------------------------------------------------------------------------------- /src/app/shared/components/no-products-found/no-products-found.component.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABZ0RVh0Q3JlYXRpb24gVGltZQAxMC8yOS8xMiKqq3kAAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzVxteM2AAABHklEQVRIib2Vyw6EIAxFW5idr///Qx9sfG3pLEyJ3tAwi5EmBqRo7vHawiEEERHS6x7MTMxMVv6+z3tPMUYSkfTM/R0fEaG2bbMv+Gc4nZzn+dN4HAcREa3r+hi3bcuu68jLskhVIlW073tWaYlQ9+F9IpqmSfq+fwskhdO/AwmUTJXrOuaRQNeRkOd5lq7rXmS5InmERKoER/QMvUAPlZDHcZRhGN4CSeGY+aHMqgcks5RrHv/eeh455x5KrMq2yHQdibDO6ncG/KZWL7M8xDyS1/MIO0NJqdULLS81X6/X6aR0nqBSJcPeZnlZrzN477NKURn2Nus8sjzmEII0TfMiyxUuxphVWjpJkbx0btUnshRihVv70Bv8ItXq6Asoi/ZiCbU6YgAAAABJRU5ErkJggg==); 3 | } 4 | 5 | .error-template { 6 | padding: 40px 15px; 7 | text-align: center; 8 | } 9 | 10 | .error-actions { 11 | margin-top: 15px; 12 | margin-bottom: 15px; 13 | } 14 | 15 | .error-actions .btn { 16 | margin-right: 10px; 17 | } 18 | -------------------------------------------------------------------------------- /src/app/shared/components/no-products-found/no-products-found.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: "app-no-products-found", 5 | templateUrl: "./no-products-found.component.html", 6 | styleUrls: ["./no-products-found.component.scss"] 7 | }) 8 | export class NoProductsFoundComponent implements OnInit { 9 | // tslint:disable-next-line:no-input-rename 10 | @Input("title") title: String; 11 | // tslint:disable-next-line:no-input-rename 12 | @Input("description") description: String; 13 | constructor() {} 14 | 15 | ngOnInit() {} 16 | } 17 | -------------------------------------------------------------------------------- /src/app/shared/components/page-not-found/page-not-found.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

6 | Oops!

7 |

8 | 404 Page Not Found

9 |
10 | Sorry, an error has occured, Requested page not found! 11 |
12 | 19 |
20 |
21 |
22 |
23 | -------------------------------------------------------------------------------- /src/app/shared/components/page-not-found/page-not-found.component.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABZ0RVh0Q3JlYXRpb24gVGltZQAxMC8yOS8xMiKqq3kAAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzVxteM2AAABHklEQVRIib2Vyw6EIAxFW5idr///Qx9sfG3pLEyJ3tAwi5EmBqRo7vHawiEEERHS6x7MTMxMVv6+z3tPMUYSkfTM/R0fEaG2bbMv+Gc4nZzn+dN4HAcREa3r+hi3bcuu68jLskhVIlW073tWaYlQ9+F9IpqmSfq+fwskhdO/AwmUTJXrOuaRQNeRkOd5lq7rXmS5InmERKoER/QMvUAPlZDHcZRhGN4CSeGY+aHMqgcks5RrHv/eeh455x5KrMq2yHQdibDO6ncG/KZWL7M8xDyS1/MIO0NJqdULLS81X6/X6aR0nqBSJcPeZnlZrzN477NKURn2Nus8sjzmEII0TfMiyxUuxphVWjpJkbx0btUnshRihVv70Bv8ItXq6Asoi/ZiCbU6YgAAAABJRU5ErkJggg==); 3 | } 4 | .error-template { 5 | padding: 40px 15px; 6 | text-align: center; 7 | } 8 | .error-actions { 9 | margin-top: 15px; 10 | margin-bottom: 15px; 11 | } 12 | .error-actions .btn { 13 | margin-right: 10px; 14 | } 15 | -------------------------------------------------------------------------------- /src/app/shared/components/page-not-found/page-not-found.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: "app-page-not-found", 5 | templateUrl: "./page-not-found.component.html", 6 | styleUrls: ["./page-not-found.component.scss"] 7 | }) 8 | export class PageNotFoundComponent implements OnInit { 9 | constructor() {} 10 | 11 | ngOnInit() {} 12 | } 13 | -------------------------------------------------------------------------------- /src/app/shared/models/product.ts: -------------------------------------------------------------------------------- 1 | export class Product { 2 | $key: string; 3 | productId: number; 4 | productName: string; 5 | productCategory: string; 6 | 7 | productDescription: string; 8 | productImageUrl: string; 9 | productUrl: string; 10 | productAdded: number; 11 | 12 | ratings: number; 13 | favourite: boolean; 14 | productSeller: string; 15 | } 16 | -------------------------------------------------------------------------------- /src/app/shared/models/user.ts: -------------------------------------------------------------------------------- 1 | export interface User1 { 2 | uid: string; 3 | email: string; 4 | displayName: string; 5 | photoURL: string; 6 | emailVerified: boolean; 7 | isAdmin: boolean; 8 | } 9 | export class User { 10 | $key: string; 11 | userName: string; 12 | emailId: string; 13 | password: string; 14 | location: { 15 | lat: number; 16 | lon: number; 17 | }; 18 | phoneNumber: string; 19 | createdOn: string; 20 | isAdmin: boolean; 21 | avatar: string; 22 | } 23 | 24 | export class UserDetail { 25 | $key: string; 26 | firstName: string; 27 | lastName: string; 28 | userName: string; 29 | emailId: string; 30 | address1: string; 31 | address2: string; 32 | country: string; 33 | state: string; 34 | zip: number; 35 | } 36 | -------------------------------------------------------------------------------- /src/app/shared/moke_data/tasks.ts: -------------------------------------------------------------------------------- 1 | export const tasks = [ 2 | { 3 | id: 0, 4 | guid: "f2d381ca-6f1c-4e68-ac72-fff973ab3701", 5 | boardId: "IK_TODO", 6 | description: "Incididunt aute anim culpa pariatur sint esse cupidatat. Ea veniam ullamco velit irure do. Laborum in elit excepteur cillum voluptate proident excepteur labore ullamco aliqua dolor mollit proident culpa. Occaecat dolor enim et consequat nulla elit ex veniam consectetur nulla est exercitation reprehenderit elit. Eiusmod magna ea pariatur magna sunt dolor.", 7 | name: "Haley assigned task to Salazar", 8 | dueDate: "2018-04-23T11:45:06.122Z", 9 | startDate: "2018-04-30T08:57:16.346Z", 10 | createdOn: "2018-10-21T21:14:50.261Z", 11 | columnIndex: 3, 12 | isDraggable: true, 13 | columnStatus: [ 14 | { 15 | column: "IK_TODO", 16 | dropedOn: "2018-10-26T02:27:31.553Z" 17 | } 18 | ], 19 | assignies: [ 20 | { 21 | userId: "bzf1920313" 22 | } 23 | ] 24 | }, 25 | { 26 | id: 1, 27 | guid: "4ebe8ada-d07a-45d0-8913-80f2468e7054", 28 | boardId: "IK_COMPLETED", 29 | description: "Laborum exercitation incididunt officia laborum culpa laborum velit. Ad eu nulla id consectetur esse elit ipsum anim. Ex laboris elit qui Lorem nisi. Sint est exercitation irure occaecat commodo id voluptate ut minim voluptate esse adipisicing labore ipsum. Ex aliquip sit Lorem non elit sint adipisicing amet aliquip culpa ad reprehenderit exercitation. Officia officia proident ut sint irure consectetur et dolore et cupidatat proident.", 30 | name: "Justine assigned task to Joyner", 31 | dueDate: "2018-09-04T15:03:37.554Z", 32 | startDate: "2018-06-10T06:40:29.062Z", 33 | createdOn: "2018-10-03T10:52:36.102Z", 34 | columnIndex: 1, 35 | isDraggable: false, 36 | assignies: [ 37 | { 38 | userId: "bzf1920314" 39 | }, 40 | { 41 | userId: "bzf1920312" 42 | } 43 | ] 44 | }, 45 | { 46 | id: 2, 47 | guid: "959af5fe-0508-4ab0-94bc-70d2c79d89d0", 48 | boardId: "IK_TODO", 49 | description: "Consequat Lorem cupidatat occaecat laborum labore esse mollit adipisicing. Velit officia occaecat ut laboris consequat commodo tempor est Lorem sunt. Mollit mollit aute eiusmod esse fugiat aliquip sint aliqua Lorem. Cillum elit dolor nulla minim aute labore ipsum irure id incididunt fugiat quis laboris enim. Elit dolore ex est nostrud consequat quis id.", 50 | name: "Margaret assigned task to Russo", 51 | dueDate: "2018-07-12T07:40:01.101Z", 52 | startDate: "2018-08-19T07:40:43.169Z", 53 | createdOn: "2018-10-27T13:32:14.084Z", 54 | columnIndex: 0, 55 | isDraggable: true, 56 | "assignies": [ 57 | { 58 | "userId": "bzf1920314" 59 | } 60 | ] 61 | }, 62 | { 63 | id: 3, 64 | guid: "be74010e-19ac-4525-afdb-68a8a9c1c842", 65 | boardId: "IK_PROGRESS", 66 | description: "Dolor quis excepteur est incididunt. Proident cillum ex sunt excepteur eu et velit Lorem occaecat mollit dolore sint. Consequat laborum deserunt fugiat ullamco laboris id ad enim magna ex excepteur do ipsum irure. Aliqua eu duis adipisicing cillum reprehenderit deserunt eu pariatur.", 67 | name: "Carla assigned task to Fischer", 68 | dueDate: "2018-03-29T17:52:07.172Z", 69 | startDate: "2018-07-10T09:18:39.733Z", 70 | createdOn: "2018-10-30T14:29:10.719Z", 71 | columnIndex: 1, 72 | isDraggable: false, 73 | assignies: [ 74 | { 75 | userId: "bzf1920312" 76 | }, 77 | { 78 | userId: "bzf1920313" 79 | } 80 | ] 81 | }, 82 | { 83 | id: 5, 84 | guid: "a1526afc-a3f4-4969-8509-69c455d80427", 85 | boardId: "IK_COMPLETED", 86 | description: "Sunt aliquip aute non id nisi in excepteur consectetur enim. Lorem in proident Lorem do anim nostrud nisi irure et veniam nisi pariatur mollit sint. Veniam qui ut Lorem voluptate aliqua nostrud exercitation.", 87 | name: "Anderson assigned task to Phillips", 88 | dueDate: "2018-05-04T13:50:21.924Z", 89 | startDate: "2018-07-07T15:55:36.491Z", 90 | createdOn: "2018-10-06T19:09:52.025Z", 91 | columnIndex: 0, 92 | isDraggable: false, 93 | assignies: [ 94 | { 95 | "userId": "bzf1920312" 96 | } 97 | ] 98 | }, 99 | { 100 | id: 6, 101 | guid: "23903dea-e7f8-4d4e-af39-45ac69a1042f", 102 | boardId: "IK_PROGRESS", 103 | description: "Fugiat nisi aliqua eu excepteur proident quis consequat aliquip do sunt. Commodo enim tempor eu reprehenderit amet mollit nulla minim velit excepteur incididunt ex. Pariatur laborum irure irure ut. Quis laboris occaecat duis ex.", 104 | name: "Gamble assigned task to Sandoval", 105 | dueDate: "2018-06-16T00:10:43.727Z", 106 | startDate: "2018-02-07T02:32:51.995Z", 107 | createdOn: "2018-10-19T06:55:42.790Z", 108 | columnIndex: 0, 109 | isDraggable: false, 110 | assignies: [ 111 | { 112 | "userId": "bzf1920313" 113 | }, 114 | { 115 | "userId": "bzf1920313" 116 | } 117 | ] 118 | } 119 | ] -------------------------------------------------------------------------------- /src/app/shared/pipes/filterByBrand.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from "@angular/core"; 2 | 3 | @Pipe({ 4 | name: "filterByBrand" 5 | }) 6 | export class FilterByBrandPipe implements PipeTransform { 7 | transform(items: any, select?: any): any { 8 | if (select !== "All") { 9 | return select 10 | ? items.filter(item => item["productSeller"] === select) 11 | : items; 12 | } else { 13 | return items; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/app/shared/pipes/moment-time-ago.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from "@angular/core"; 2 | 3 | declare var moment: any; 4 | 5 | @Pipe({ 6 | name: "momentTimeAgo" 7 | }) 8 | export class MomentTimeAgoPipe implements PipeTransform { 9 | 10 | transform(value: any, args?: any): any { 11 | return ( 12 | moment(value) 13 | // .startOf("day") 14 | .from(new Date()) 15 | ); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/app/shared/pipes/translate.pipe.ts: -------------------------------------------------------------------------------- 1 | import { Pipe, PipeTransform } from "@angular/core"; 2 | import { TranslateService } from "../services/translate.service"; 3 | 4 | @Pipe({ 5 | name: "translate" 6 | }) 7 | export class TranslatePipe implements PipeTransform { 8 | constructor(private translate: TranslateService) {} 9 | 10 | transform(key: any): any { 11 | return this.translate.data[key] || key; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/app/shared/services/admin-gaurd.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { Router, CanActivate } from "@angular/router"; 3 | import { AuthService } from "./auth.service"; 4 | 5 | @Injectable() 6 | export class AdminGaurd implements CanActivate { 7 | constructor(private router: Router, private authService: AuthService) {} 8 | 9 | canActivate() { 10 | if (this.authService.isLoggedIn() && this.authService.isAdmin) { 11 | return true; 12 | } 13 | this.router.navigate(["no-access"]); 14 | return false; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/app/shared/services/auth.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable, NgZone } from "@angular/core"; 2 | import * as firebase from "firebase/app"; 3 | import { Observable } from "rxjs"; 4 | import { User, User1 } from "../models/user"; 5 | import { AngularFireAuth } from "@angular/fire/auth"; 6 | import { Router } from "@angular/router"; 7 | import { UserService } from "./user.service"; 8 | import { AngularFirestoreDocument, AngularFirestore } from "@angular/fire/firestore"; 9 | import { auth } from "firebase/app"; 10 | 11 | @Injectable() 12 | export class AuthService { 13 | user: Observable; 14 | userDetails: firebase.User = null; 15 | loggedUser; 16 | dbUser; 17 | constructor( 18 | private firebaseAuth: AngularFireAuth, 19 | private router: Router, 20 | private userService: UserService 21 | ) { 22 | this.user = firebaseAuth.authState; 23 | this.dbUser = new User(); 24 | this.user.subscribe(user => { 25 | if (user) { 26 | 27 | this.userDetails = user; 28 | userService 29 | .isAdmin(this.userDetails.email) 30 | .snapshotChanges() 31 | .subscribe(data => { 32 | data.forEach(el => { 33 | const y = el.payload.toJSON(); 34 | this.dbUser = y; 35 | 36 | }); 37 | }); 38 | } else { 39 | this.userDetails = null; 40 | } 41 | }); 42 | } 43 | 44 | isLoggedIn(): boolean { 45 | if (this.userDetails !== null) { 46 | return true; 47 | } 48 | } 49 | 50 | logout() { 51 | this.loggedUser = null; 52 | this.firebaseAuth.auth.signOut().then(res => this.router.navigate(["/"])); 53 | } 54 | 55 | createUserWithEmailAndPassword(emailID: string, password: string) { 56 | return this.firebaseAuth.auth.createUserWithEmailAndPassword( 57 | emailID, 58 | password 59 | ); 60 | } 61 | 62 | getLoggedInUser(): User { 63 | const loggedUser: User = new User(); 64 | const user = this.firebaseAuth.auth.currentUser; 65 | 66 | if (user) { 67 | this.userDetails = user; 68 | if (user != null) { 69 | loggedUser.$key = user.uid; 70 | loggedUser.userName = user.displayName; 71 | loggedUser.emailId = user.email; 72 | loggedUser.phoneNumber = user.phoneNumber; 73 | loggedUser.avatar = user.photoURL; 74 | loggedUser.isAdmin = this.dbUser["isAdmin"]; 75 | } 76 | } else { 77 | this.userDetails = null; 78 | } 79 | 80 | return loggedUser; 81 | } 82 | 83 | isAdmin(): boolean { 84 | const user = this.getLoggedInUser(); 85 | // console.log("loggedUSer", user) 86 | if (user != null) { 87 | if (user.isAdmin === true) { 88 | return true; 89 | } 90 | } 91 | } 92 | 93 | signInRegular(email, password) { 94 | const credential = firebase.auth.EmailAuthProvider.credential( 95 | email, 96 | password 97 | ); 98 | return this.firebaseAuth.auth.signInWithEmailAndPassword(email, password); 99 | } 100 | 101 | signInWithGoogle() { 102 | return this.firebaseAuth.auth.signInWithPopup( 103 | new firebase.auth.GoogleAuthProvider() 104 | ); 105 | 106 | } 107 | 108 | } 109 | 110 | -------------------------------------------------------------------------------- /src/app/shared/services/auth_gaurd.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { Router, CanActivate, RouterStateSnapshot } from "@angular/router"; 3 | import { AuthService } from "./auth.service"; 4 | 5 | @Injectable() 6 | export class AuthGuard implements CanActivate { 7 | constructor(private router: Router, private authService: AuthService) { } 8 | 9 | canActivate(route, state: RouterStateSnapshot) { 10 | // console.log(this.authService.isLoggedIn()); 11 | if (this.authService.isLoggedIn()) { 12 | return true; 13 | } 14 | this.router.navigate(["/login"], { 15 | queryParams: { returnUrl: state.url } 16 | }); 17 | return false; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/app/shared/services/product.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { AngularFireDatabase, AngularFireList, AngularFireObject } from '@angular/fire/database' 3 | import { Product } from '../models/product'; 4 | import { AuthService } from './auth.service'; 5 | import { ToastrService } from './toastr.service'; 6 | 7 | @Injectable() 8 | export class ProductService { 9 | products: AngularFireList; 10 | product: AngularFireObject; 11 | 12 | // favouriteProducts 13 | favouriteProducts: AngularFireList; 14 | cartProducts: AngularFireList; 15 | 16 | // NavbarCounts 17 | navbarCartCount = 0; 18 | navbarFavProdCount = 0; 19 | 20 | constructor( 21 | private db: AngularFireDatabase, 22 | private authService: AuthService, 23 | private toastrService: ToastrService 24 | ) { 25 | this.calculateLocalFavProdCounts(); 26 | this.calculateLocalCartProdCounts(); 27 | } 28 | 29 | getProducts() { 30 | this.products = this.db.list('products'); 31 | return this.products; 32 | } 33 | 34 | createProduct(data: Product) { 35 | this.products.push(data); 36 | } 37 | 38 | getProductById(key: string) { 39 | this.product = this.db.object('products/' + key); 40 | return this.product; 41 | } 42 | 43 | updateProduct(data: Product) { 44 | this.products.update(data.$key, data); 45 | } 46 | 47 | deleteProduct(key: string) { 48 | this.products.remove(key); 49 | } 50 | 51 | /* 52 | ---------- Favourite Product Function ---------- 53 | */ 54 | 55 | // Get Favourite Product based on userId 56 | getUsersFavouriteProduct() { 57 | const user = this.authService.getLoggedInUser(); 58 | this.favouriteProducts = this.db.list('favouriteProducts', (ref) => 59 | ref.orderByChild('userId').equalTo(user.$key) 60 | ); 61 | return this.favouriteProducts; 62 | } 63 | 64 | // Adding New product to favourite if logged else to localStorage 65 | addFavouriteProduct(data: Product): void { 66 | let a: Product[]; 67 | a = JSON.parse(localStorage.getItem('avf_item')) || []; 68 | a.push(data); 69 | this.toastrService.wait('Adding Blog', 'Adding Blog as Favourite'); 70 | setTimeout(() => { 71 | localStorage.setItem('avf_item', JSON.stringify(a)); 72 | this.calculateLocalFavProdCounts(); 73 | }, 1500); 74 | } 75 | 76 | // Fetching unsigned users favourite proucts 77 | getLocalFavouriteProducts(): Product[] { 78 | const products: Product[] = JSON.parse(localStorage.getItem('avf_item')) || []; 79 | 80 | return products; 81 | } 82 | 83 | // Removing Favourite Product from Database 84 | removeFavourite(key: string) { 85 | this.favouriteProducts.remove(key); 86 | } 87 | 88 | // Removing Favourite Product from localStorage 89 | removeLocalFavourite(product: Product) { 90 | const products: Product[] = JSON.parse(localStorage.getItem('avf_item')); 91 | 92 | for (let i = 0; i < products.length; i++) { 93 | if (products[i].productId === product.productId) { 94 | products.splice(i, 1); 95 | break; 96 | } 97 | } 98 | // ReAdding the products after remove 99 | localStorage.setItem('avf_item', JSON.stringify(products)); 100 | 101 | this.calculateLocalFavProdCounts(); 102 | } 103 | 104 | // Returning Local Products Count 105 | calculateLocalFavProdCounts() { 106 | this.navbarFavProdCount = this.getLocalFavouriteProducts().length; 107 | } 108 | 109 | /* 110 | ---------- Cart Product Function ---------- 111 | */ 112 | 113 | // Adding new Product to cart db if logged in else localStorage 114 | addToCart(data: Product): void { 115 | let a: Product[]; 116 | 117 | a = JSON.parse(localStorage.getItem('avct_item')) || []; 118 | 119 | a.push(data); 120 | this.toastrService.wait('Adding Blog to Read Later', ''); 121 | setTimeout(() => { 122 | localStorage.setItem('avct_item', JSON.stringify(a)); 123 | this.calculateLocalCartProdCounts(); 124 | }, 500); 125 | } 126 | 127 | // Removing cart from local 128 | removeLocalCartProduct(product: Product) { 129 | const products: Product[] = JSON.parse(localStorage.getItem('avct_item')); 130 | 131 | for (let i = 0; i < products.length; i++) { 132 | if (products[i].productId === product.productId) { 133 | products.splice(i, 1); 134 | break; 135 | } 136 | } 137 | // ReAdding the products after remove 138 | localStorage.setItem('avct_item', JSON.stringify(products)); 139 | 140 | this.calculateLocalCartProdCounts(); 141 | } 142 | 143 | // Fetching Locat CartsProducts 144 | getLocalCartProducts(): Product[] { 145 | const products: Product[] = JSON.parse(localStorage.getItem('avct_item')) || []; 146 | 147 | return products; 148 | } 149 | 150 | // returning LocalCarts Product Count 151 | calculateLocalCartProdCounts() { 152 | this.navbarCartCount = this.getLocalCartProducts().length; 153 | } 154 | } 155 | 156 | export class FavouriteProduct { 157 | product: Product; 158 | productId: string; 159 | userId: string; 160 | } 161 | -------------------------------------------------------------------------------- /src/app/shared/services/task.service.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | 3 | import { TestBed, async, inject } from '@angular/core/testing'; 4 | import { TaskService } from './task.service'; 5 | 6 | describe('Service: Task', () => { 7 | beforeEach(() => { 8 | TestBed.configureTestingModule({ 9 | providers: [TaskService] 10 | }); 11 | }); 12 | 13 | it('should ...', inject([TaskService], (service: TaskService) => { 14 | expect(service).toBeTruthy(); 15 | })); 16 | }); 17 | -------------------------------------------------------------------------------- /src/app/shared/services/task.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { tasks } from '../moke_data/tasks'; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | export class TaskService { 8 | 9 | constructor() { } 10 | 11 | getTasks() { 12 | return new Promise((resolve, reject) => { 13 | resolve(tasks); 14 | }); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/app/shared/services/theme.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | @Injectable({ 4 | providedIn: 'root' 5 | }) 6 | export class ThemeService { 7 | 8 | constructor() { } 9 | 10 | updateThemeUrl(theme: string) { 11 | 12 | document.getElementsByTagName("body")[0].className = theme; 13 | 14 | localStorage.setItem("theme", JSON.stringify(theme)) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/app/shared/services/toastr.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | declare var toastr: any; 3 | @Injectable({ 4 | providedIn: 'root' 5 | }) 6 | export class ToastrService { 7 | constructor() {} 8 | 9 | success(title, msg) { 10 | toastr.success(msg, title); 11 | } 12 | info(title, msg) { 13 | toastr.info(msg, title); 14 | } 15 | warning(title, msg) { 16 | toastr.warning(msg, title); 17 | } 18 | error(title, msg) { 19 | toastr.error(msg, title); 20 | } 21 | 22 | wait(title, msg) { 23 | toastr.info(msg, title, { timeOut: 3000 }); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/app/shared/services/translate.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { HttpClient } from "@angular/common/http"; 3 | import { Title } from "@angular/platform-browser"; 4 | @Injectable({ 5 | providedIn: "root" 6 | }) 7 | export class TranslateService { 8 | data: any = {}; 9 | constructor(private http: HttpClient, private titleService: Title) {} 10 | 11 | use(lang: string): Promise<{}> { 12 | return new Promise<{}>((resolve, reject) => { 13 | const langPath = `assets/i18n/${lang || "en"}.json`; 14 | this.http.get<{}>(langPath).subscribe( 15 | translation => { 16 | this.data = Object.assign({}, translation || {}); 17 | this.titleService.setTitle(this.data["TITLE"]); 18 | resolve(this.data); 19 | }, 20 | error => { 21 | this.data = {}; 22 | console.log("Error"); 23 | resolve(this.data); 24 | } 25 | ); 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/app/shared/services/user.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { AngularFireDatabase, AngularFireList } from '@angular/fire/database' 3 | import * as moment from "moment"; 4 | import { User } from "../models/user"; 5 | 6 | @Injectable() 7 | export class UserService { 8 | selectedUser: User = new User(); 9 | users: AngularFireList; 10 | 11 | location = { 12 | lat: null, 13 | lon: null 14 | }; 15 | 16 | constructor(private db: AngularFireDatabase) { 17 | this.getUsers(); 18 | } 19 | 20 | getUsers() { 21 | this.users = this.db.list("clients"); 22 | return this.users; 23 | } 24 | 25 | createUser(data: any) { 26 | data.location = this.location; 27 | data.createdOn = moment(new Date()).format("X"); 28 | data.isAdmin = false; 29 | this.users.push(data); 30 | } 31 | 32 | isAdmin(emailId: string) { 33 | return this.db.list("clients", ref => 34 | ref.orderByChild("email").equalTo(emailId) 35 | ); 36 | } 37 | 38 | updateUser(user: User) { 39 | this.users.update(user.$key, user); 40 | } 41 | 42 | setLocation(lat, lon) { 43 | this.location.lat = lat; 44 | this.location.lon = lon; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/app/shared/shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from "@angular/core"; 2 | import { CommonModule } from "@angular/common"; 3 | import { NoProductsFoundComponent } from "./components/no-products-found/no-products-found.component"; 4 | import { MDBBootstrapModule } from "angular-bootstrap-md"; 5 | import { AngularFireModule } from '@angular/fire'; 6 | import { AngularFireAuthModule } from '@angular/fire/auth'; 7 | import { AngularFireDatabaseModule } from '@angular/fire/database' 8 | import { FormsModule, FormBuilder } from "@angular/forms"; 9 | import { RouterModule, Router } from "@angular/router"; 10 | import { OwlModule } from "ngx-owl-carousel"; 11 | import { NgxPaginationModule } from "ngx-pagination"; 12 | import { HttpClientModule } from "@angular/common/http"; 13 | import { AgmCoreModule } from "@agm/core"; 14 | import { NoAccessComponent } from "./components/no-access/no-access.component"; 15 | import { PageNotFoundComponent } from "./components/page-not-found/page-not-found.component"; 16 | import { FireBaseConfig } from "../../environments/firebaseConfig"; 17 | import { FilterByBrandPipe } from "./pipes/filterByBrand.pipe"; 18 | import { ProductService } from "./services/product.service"; 19 | import { AdminGaurd } from "./services/admin-gaurd"; 20 | import { AuthGuard } from "./services/auth_gaurd"; 21 | import { AuthService } from "./services/auth.service"; 22 | import { UserService } from "./services/user.service"; 23 | import { TranslatePipe } from "./pipes/translate.pipe"; 24 | import { NgxContentLoadingModule } from "ngx-content-loading"; 25 | import { CardLoaderComponent } from "./components/card-loader/card-loader.component"; 26 | import { MomentTimeAgoPipe } from "./pipes/moment-time-ago.pipe"; 27 | import { DragDropModule } from "@angular/cdk/drag-drop"; 28 | import { ScrollingModule } from "@angular/cdk/scrolling"; 29 | import { CdkTableModule } from "@angular/cdk/table"; 30 | import { CdkTreeModule } from "@angular/cdk/tree"; 31 | import { AngularFirestore } from "@angular/fire/firestore"; 32 | @NgModule({ 33 | imports: [ 34 | CommonModule, 35 | MDBBootstrapModule.forRoot(), 36 | AngularFireModule.initializeApp(FireBaseConfig), 37 | AngularFireDatabaseModule, 38 | AngularFireAuthModule, 39 | FormsModule, 40 | HttpClientModule, 41 | RouterModule, 42 | OwlModule, 43 | NgxPaginationModule, 44 | AgmCoreModule.forRoot({ 45 | apiKey: "AIzaSyDMbxW3MlwUP2vrAZVJyu7pYqZa1LthvTE" 46 | }), 47 | NgxContentLoadingModule 48 | ], 49 | declarations: [ 50 | NoProductsFoundComponent, 51 | FilterByBrandPipe, 52 | NoAccessComponent, 53 | PageNotFoundComponent, 54 | TranslatePipe, 55 | CardLoaderComponent, 56 | MomentTimeAgoPipe 57 | ], 58 | exports: [ 59 | NoProductsFoundComponent, 60 | FormsModule, 61 | MDBBootstrapModule, 62 | AngularFireModule, 63 | AngularFireAuthModule, 64 | AngularFireDatabaseModule, 65 | FormsModule, 66 | RouterModule, 67 | OwlModule, 68 | NgxPaginationModule, 69 | FilterByBrandPipe, 70 | AgmCoreModule, 71 | NoAccessComponent, 72 | PageNotFoundComponent, 73 | TranslatePipe, 74 | MomentTimeAgoPipe, 75 | NgxContentLoadingModule, 76 | CardLoaderComponent, 77 | CdkTableModule, 78 | CdkTreeModule, 79 | DragDropModule, ScrollingModule 80 | ], 81 | providers: [AngularFirestore,AuthService, AuthGuard, AdminGaurd, ProductService, UserService, FormBuilder] 82 | }) 83 | export class SharedModule { } 84 | -------------------------------------------------------------------------------- /src/assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/.gitkeep -------------------------------------------------------------------------------- /src/assets/banner_img/img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/banner_img/img1.jpg -------------------------------------------------------------------------------- /src/assets/banner_img/img2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/banner_img/img2.jpg -------------------------------------------------------------------------------- /src/assets/banner_img/img3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/banner_img/img3.jpg -------------------------------------------------------------------------------- /src/assets/banner_img/img_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/banner_img/img_1.jpg -------------------------------------------------------------------------------- /src/assets/banner_img/img_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/banner_img/img_2.jpg -------------------------------------------------------------------------------- /src/assets/banner_img/img_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/banner_img/img_3.jpg -------------------------------------------------------------------------------- /src/assets/banner_img/img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/banner_img/img_3.png -------------------------------------------------------------------------------- /src/assets/banner_img/img_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/banner_img/img_4.jpg -------------------------------------------------------------------------------- /src/assets/i18n/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "TITLE": "Angular Shopping Cart", 3 | "HOME": "Home", 4 | "PRODUCTS": "Our Products", 5 | "TASKBOARD": "Work Board", 6 | "CONTACT": "Contact", 7 | "SIGNIN": "SignIn/SignUp", 8 | "MYACCOUNT": "My Account", 9 | "LOGOUT": "Log Out", 10 | "BESTPRODUCTS": "Our Best Products", 11 | "VIEWALL": "See More" 12 | } 13 | -------------------------------------------------------------------------------- /src/assets/i18n/fa.json: -------------------------------------------------------------------------------- 1 | { 2 | "TITLE": "تجارت الکترونیک زاویه ای", 3 | "HOME": "خانه", 4 | "PRODUCTS": "محصولات ما", 5 | "TASKBOARD": "هیئت مدیره کار", 6 | "CONTACT": "تماس", 7 | "SIGNIN": "وارد شوید / ثبت نام کنید", 8 | "MYACCOUNT": "حساب من", 9 | "LOGOUT": "خروج", 10 | "BESTPRODUCTS": "بهترین محصولات ما", 11 | "VIEWALL": "بیشتر ببین" 12 | } 13 | -------------------------------------------------------------------------------- /src/assets/i18n/fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "TITLE": "Commerce électronique angulaire", 3 | "HOME": "Accueil", 4 | "PRODUCTS": "Nos Produits", 5 | "TASKBOARD": "Tableau de tâches", 6 | "CONTACT": "Contact", 7 | "SIGNIN": "Se connecter / s'inscrire", 8 | "MYACCOUNT": "Mon compte", 9 | "LOGOUT": "Déconnexion", 10 | "BESTPRODUCTS": "Nos meilleurs produits", 11 | "VIEWALL": "Voir plus" 12 | } 13 | -------------------------------------------------------------------------------- /src/assets/i18n/hin.json: -------------------------------------------------------------------------------- 1 | { 2 | "TITLE": "कोणीय खरीदारी गाड़ी", 3 | "HOME": "होम", 4 | "PRODUCTS": "हमारे उत्पाद", 5 | "TASKBOARD": "कार्य बोर्ड", 6 | "CONTACT": "संपर्क करें", 7 | "SIGNIN": "साइन इन / लॉग इन करें", 8 | "MYACCOUNT": "मेरा खाता", 9 | "LOGOUT": "लोग आउट", 10 | "BESTPRODUCTS": "हमारे सर्वोत्तम उत्पादों", 11 | "VIEWALL": "और देखें" 12 | } 13 | -------------------------------------------------------------------------------- /src/assets/i18n/ja.json: -------------------------------------------------------------------------------- 1 | { 2 | "TITLE": "ショッピングカート", 3 | "HOME": "自宅", 4 | "PRODUCTS": "当社の製品", 5 | "TASKBOARD": "タスクボード", 6 | "CONTACT": "接触", 7 | "SIGNIN": "サインイン/サインアップ", 8 | "MYACCOUNT": "マイアカウント", 9 | "LOGOUT": "ログアウト", 10 | "BESTPRODUCTS": "私たちの最高の製品", 11 | "VIEWALL": "続きを見る" 12 | } 13 | -------------------------------------------------------------------------------- /src/assets/icons/icon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/icons/icon-128x128.png -------------------------------------------------------------------------------- /src/assets/icons/icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/icons/icon-144x144.png -------------------------------------------------------------------------------- /src/assets/icons/icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/icons/icon-152x152.png -------------------------------------------------------------------------------- /src/assets/icons/icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/icons/icon-192x192.png -------------------------------------------------------------------------------- /src/assets/icons/icon-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/icons/icon-384x384.png -------------------------------------------------------------------------------- /src/assets/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/icons/icon-512x512.png -------------------------------------------------------------------------------- /src/assets/icons/icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/icons/icon-72x72.png -------------------------------------------------------------------------------- /src/assets/icons/icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/icons/icon-96x96.png -------------------------------------------------------------------------------- /src/assets/img/loader.svg: -------------------------------------------------------------------------------- 1 | 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 | -------------------------------------------------------------------------------- /src/assets/img/malecostume-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/assets/img/malecostume-512.png -------------------------------------------------------------------------------- /src/assets/theme/colors.scss: -------------------------------------------------------------------------------- 1 | .purple-theme { 2 | --navBackground: #9c27b0; 3 | --productTitle: #9c27b0; 4 | } 5 | 6 | .blue-theme { 7 | 8 | --navBackground: #3f51b5; 9 | --productTitle: #3f51b5; 10 | } 11 | 12 | .red-theme { 13 | --navBackground: #e91e63; 14 | --productTitle: #e91e63; 15 | } 16 | 17 | .violet-theme { 18 | --navBackground: #673ab7; 19 | --productTitle: #673ab7; 20 | } 21 | 22 | 23 | 24 | $variables: ( 25 | --navBackground: var(--navBackground), 26 | --productTitle: var(--productTitle) 27 | ); -------------------------------------------------------------------------------- /src/assets/theme/functions.scss: -------------------------------------------------------------------------------- 1 | @function var($variable) { 2 | @return map-get($variables, $variable); 3 | } -------------------------------------------------------------------------------- /src/browserslist: -------------------------------------------------------------------------------- 1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | # For IE 9-11 support, please uncomment the last line of the file and adjust as needed 5 | > 0.5% 6 | last 2 versions 7 | Firefox ESR 8 | not dead 9 | # IE 9-11 -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /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 | * In development mode, to ignore zone related error stack frames such as 11 | * `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can 12 | * import the following file, but please comment it out in production mode 13 | * because it will have performance impact when throw error 14 | */ 15 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 16 | -------------------------------------------------------------------------------- /src/environments/firebaseConfig.ts: -------------------------------------------------------------------------------- 1 | export const FireBaseConfig = { 2 | /* apiKey: "AIzaSyCd0wii8iVgaR8M5zpHraH7VrrHncjIjDE", 3 | authDomain: "blog-app-3cda4.firebaseapp.com", 4 | databaseURL: "https://blog-app-3cda4.firebaseio.com", 5 | projectId: "blog-app-3cda4", 6 | storageBucket: "blog-app-3cda4.appspot.com", 7 | messagingSenderId: "1045419816065", */ 8 | 9 | apiKey: "AIzaSyCd0wii8iVgaR8M5zpHraH7VrrHncjIjDE", 10 | authDomain: "blog-app-3cda4.firebaseapp.com", 11 | databaseURL: "https://blog-app-3cda4.firebaseio.com", 12 | projectId: "blog-app-3cda4", 13 | storageBucket: "blog-app-3cda4.appspot.com", 14 | messagingSenderId: "1045419816065", 15 | appId: "1:1045419816065:web:6de6e8117841a8322bc980", 16 | 17 | }; 18 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mehulk05/Angular-Blogging-App/b3906955e8f5fd2df89c319adccafb462dd28142/src/favicon.ico -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 14 | 15 | 16 | Angular MEhul's Blog Site 17 | 18 | 19 | 20 | 21 | 22 | 23 | 50 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 |
69 |
70 |
71 |

Loading Mehul's Blog

72 | 73 |
74 |
75 |
76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /src/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"), 20 | reports: ["html", "lcovonly"], 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 | }); 31 | }; 32 | -------------------------------------------------------------------------------- /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() 12 | .bootstrapModule(AppModule) 13 | .catch(err => console.log(err)); 14 | -------------------------------------------------------------------------------- /src/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angularShop", 3 | "short_name": "angularShop", 4 | "theme_color": "#1976d2", 5 | "background_color": "#fafafa", 6 | "display": "standalone", 7 | "scope": "/", 8 | "start_url": "/", 9 | "icons": [ 10 | { 11 | "src": "assets/icons/icon-72x72.png", 12 | "sizes": "72x72", 13 | "type": "image/png" 14 | }, 15 | { 16 | "src": "assets/icons/icon-96x96.png", 17 | "sizes": "96x96", 18 | "type": "image/png" 19 | }, 20 | { 21 | "src": "assets/icons/icon-128x128.png", 22 | "sizes": "128x128", 23 | "type": "image/png" 24 | }, 25 | { 26 | "src": "assets/icons/icon-144x144.png", 27 | "sizes": "144x144", 28 | "type": "image/png" 29 | }, 30 | { 31 | "src": "assets/icons/icon-152x152.png", 32 | "sizes": "152x152", 33 | "type": "image/png" 34 | }, 35 | { 36 | "src": "assets/icons/icon-192x192.png", 37 | "sizes": "192x192", 38 | "type": "image/png" 39 | }, 40 | { 41 | "src": "assets/icons/icon-384x384.png", 42 | "sizes": "384x384", 43 | "type": "image/png" 44 | }, 45 | { 46 | "src": "assets/icons/icon-512x512.png", 47 | "sizes": "512x512", 48 | "type": "image/png" 49 | } 50 | ] 51 | } -------------------------------------------------------------------------------- /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/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/weak-map'; 35 | // import 'core-js/es6/set'; 36 | 37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 38 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 39 | 40 | /** IE10 and IE11 requires the following for the Reflect API. */ 41 | import "core-js/es6/reflect"; 42 | 43 | /** Evergreen browsers require these. **/ 44 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. 45 | 46 | 47 | /** 48 | * Web Animations `@angular/platform-browser/animations` 49 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 50 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 51 | **/ 52 | import "web-animations-js"; // Run `npm install --save web-animations-js`. 53 | 54 | /** 55 | * By default, zone.js will patch all possible macroTask and DomEvents 56 | * user can disable parts of macroTask/DomEvents patch by setting following flags 57 | */ 58 | 59 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 60 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 61 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 62 | 63 | /* 64 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 65 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 66 | */ 67 | // (window as any).__Zone_enable_cross_context_check = true; 68 | 69 | /*************************************************************************************************** 70 | * Zone JS is required by default for Angular itself. 71 | */ 72 | import "zone.js/dist/zone"; // Included with Angular CLI. 73 | 74 | /*************************************************************************************************** 75 | * APPLICATION IMPORTS 76 | */ 77 | -------------------------------------------------------------------------------- /src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | @import "./assets/theme/colors"; 4 | @import "./assets/theme/functions"; 5 | 6 | 7 | router-outlet ~ * { 8 | position: absolute; 9 | width: 100%; 10 | height: 100%; 11 | } 12 | 13 | * { 14 | font-family: "Ubuntu", sans-serif; 15 | } 16 | -------------------------------------------------------------------------------- /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: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context("./", true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "module": "es2015", 6 | "types": [] 7 | }, 8 | "exclude": ["src/test.ts", "**/*.spec.ts"], 9 | "include": ["**/*.ts", "../node_modules/angular-bootstrap-md/index.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "module": "commonjs", 6 | "types": [ 7 | "jasmine", 8 | "node" 9 | ] 10 | }, 11 | "files": [ 12 | "test.ts", 13 | "polyfills.ts" 14 | ], 15 | "include": [ 16 | "**/*.spec.ts", 17 | "**/*.d.ts" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /src/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "app", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "app", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "outDir": "./dist/out-tsc", 6 | "sourceMap": true, 7 | "declaration": false, 8 | "moduleResolution": "node", 9 | "emitDecoratorMetadata": true, 10 | "experimentalDecorators": true, 11 | "target": "es5", 12 | "typeRoots": [ 13 | "node_modules/@types" 14 | ], 15 | "lib": [ 16 | "es2017", 17 | "dom" 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "arrow-return-shorthand": true, 7 | "callable-types": true, 8 | "class-name": true, 9 | "comment-format": [ 10 | true, 11 | "check-space" 12 | ], 13 | "curly": true, 14 | "deprecation": { 15 | "severity": "warn" 16 | }, 17 | "eofline": true, 18 | "forin": true, 19 | "import-blacklist": [ 20 | true, 21 | "rxjs/Rx" 22 | ], 23 | "import-spacing": true, 24 | "indent": [ 25 | true, 26 | "spaces" 27 | ], 28 | "interface-over-type-literal": true, 29 | "label-position": true, 30 | "max-line-length": [ 31 | true, 32 | 140 33 | ], 34 | "member-access": false, 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-arg": true, 47 | "no-bitwise": true, 48 | "no-console": [ 49 | true, 50 | "debug", 51 | "info", 52 | "time", 53 | "timeEnd", 54 | "trace" 55 | ], 56 | "no-construct": true, 57 | "no-debugger": true, 58 | "no-duplicate-super": true, 59 | "no-empty": false, 60 | "no-empty-interface": true, 61 | "no-eval": true, 62 | "no-inferrable-types": [ 63 | true, 64 | "ignore-params" 65 | ], 66 | "no-misused-new": true, 67 | "no-non-null-assertion": true, 68 | "no-shadowed-variable": true, 69 | "no-string-literal": false, 70 | "no-string-throw": true, 71 | "no-switch-case-fall-through": true, 72 | "no-trailing-whitespace": true, 73 | "no-unnecessary-initializer": true, 74 | "no-unused-expression": true, 75 | "no-use-before-declare": true, 76 | "no-var-keyword": true, 77 | "object-literal-sort-keys": false, 78 | "one-line": [ 79 | true, 80 | "check-open-brace", 81 | "check-catch", 82 | "check-else", 83 | "check-whitespace" 84 | ], 85 | "prefer-const": true, 86 | "quotemark": [ 87 | true, 88 | "double", "avoid-escape", "avoid-template" 89 | ], 90 | "radix": true, 91 | "semicolon": [ 92 | true, 93 | "always" 94 | ], 95 | "triple-equals": [ 96 | true, 97 | "allow-null-check" 98 | ], 99 | "typedef-whitespace": [ 100 | true, 101 | { 102 | "call-signature": "nospace", 103 | "index-signature": "nospace", 104 | "parameter": "nospace", 105 | "property-declaration": "nospace", 106 | "variable-declaration": "nospace" 107 | } 108 | ], 109 | "unified-signatures": true, 110 | "variable-name": false, 111 | "whitespace": [ 112 | true, 113 | "check-branch", 114 | "check-decl", 115 | "check-operator", 116 | "check-separator", 117 | "check-type" 118 | ], 119 | "no-output-on-prefix": true, 120 | "use-input-property-decorator": true, 121 | "use-output-property-decorator": true, 122 | "use-host-property-decorator": true, 123 | "no-input-rename": true, 124 | "no-output-rename": true, 125 | "use-life-cycle-interface": true, 126 | "use-pipe-transform-interface": true, 127 | "component-class-suffix": true, 128 | "directive-class-suffix": true 129 | } 130 | } 131 | --------------------------------------------------------------------------------