2 |
Search Products
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Active |
14 | |
15 |
16 |
17 |
18 |
19 | Product Name |
20 | {{element.productName}} |
21 |
22 |
23 |
24 |
25 | SKU |
26 | {{element.SKU}} |
27 |
28 |
29 |
30 |
31 | Created |
32 | {{element.created}} |
33 |
34 |
35 |
36 | Retail Price |
37 | {{element.retailPrice}} |
38 |
39 |
40 |
41 | Sale Price |
42 | {{element.salePrice}} |
43 |
44 |
45 |
46 | Lowest Price |
47 | {{element.lowestPrice}} |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/app/home/home.component.scss:
--------------------------------------------------------------------------------
1 | table {
2 | width: 100%;
3 | }
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/app/home/home.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { HomeComponent } from './home.component';
4 |
5 | describe('HomeComponent', () => {
6 | let component: HomeComponent;
7 | let fixture: ComponentFixture
;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [ HomeComponent ]
12 | })
13 | .compileComponents();
14 | });
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(HomeComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/app/home/home.component.ts:
--------------------------------------------------------------------------------
1 | import {Component, OnInit, AfterViewInit, ViewChild} from '@angular/core';
2 | import {MatPaginator} from '@angular/material/paginator';
3 | import {MatTableDataSource} from '@angular/material/table';
4 | import {MatDialog} from '@angular/material/dialog';
5 | import {AddProductComponent} from '../add-product/add-product.component';
6 | import {DataService} from "../shared/data.service";
7 |
8 | export interface ProductData {
9 | productId: number;
10 | productName: string;
11 | SKU: string;
12 | created: string;
13 | retailPrice: number;
14 | salePrice: number;
15 | lowestPrice: number;
16 | status:boolean;
17 | }
18 |
19 | @Component({
20 | selector: 'app-home',
21 | templateUrl: './home.component.html',
22 | styleUrls: ['./home.component.scss']
23 | })
24 |
25 |
26 | export class HomeComponent implements OnInit, AfterViewInit {
27 | displayedColumns: string[] = ['status','productName', 'SKU', 'created', 'retailPrice', 'salePrice', 'lowestPrice' ];
28 | dataSource: MatTableDataSource ;
29 | dataSourceService: any ;
30 |
31 | constructor(public dialog: MatDialog, data:DataService) {
32 | this.dataSource = new MatTableDataSource(data.getProductData());
33 | this.dataSourceService = data;
34 | }
35 |
36 | ngOnInit(): void {}
37 |
38 | @ViewChild(MatPaginator)
39 | paginator!: MatPaginator;
40 |
41 | ngAfterViewInit() {
42 | this.dataSource.paginator = this.paginator;
43 | }
44 |
45 | applyFilter(event: Event): void {
46 | this.dataSource.filter = (event.target as HTMLInputElement).value.trim().toLocaleLowerCase();
47 | }
48 |
49 | addNewProduct():void{
50 | const dialogRef = this.dialog.open(AddProductComponent, {
51 | width: '500px',
52 | height: '500px'
53 | });
54 |
55 | dialogRef.afterClosed().subscribe(result => {
56 | this.dataSource = this.dataSourceService.getProductData();
57 | });
58 | }
59 | }
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/app/login/login.component.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | height: 100%;
4 | }
5 |
6 | body {
7 | margin: 0;
8 | font-family: Roboto, "Helvetica Neue", sans-serif;
9 | min-height: 100vh;
10 | background: #e2e2e2;
11 | }
12 |
13 | .app-header {
14 | justify-content: space-between;
15 | position: fixed;
16 | top: 0;
17 | left: 0;
18 | right: 0;
19 | z-index: 2;
20 | box-shadow: 0 3px 5px -1px rgba(0, 0, 0, .2), 0 6px 10px 0 rgba(0, 0, 0, .14), 0 1px 18px 0 rgba(0, 0, 0, .12);
21 | }
22 |
23 | .login-wrapper {
24 | height: 100%;
25 | }
26 |
27 | .positronx {
28 | text-decoration: none;
29 | color: #ffffff;
30 | }
31 |
32 | .box {
33 | position: relative;
34 | top: 0;
35 | opacity: 1;
36 | float: left;
37 | padding: 60px 50px 40px 50px;
38 | width: 100%;
39 | background: #fff;
40 | border-radius: 10px;
41 | transform: scale(1);
42 | -webkit-transform: scale(1);
43 | -ms-transform: scale(1);
44 | z-index: 5;
45 | max-width: 330px;
46 | }
47 |
48 | .box.back {
49 | transform: scale(.95);
50 | -webkit-transform: scale(.95);
51 | -ms-transform: scale(.95);
52 | top: -20px;
53 | opacity: .8;
54 | z-index: -1;
55 | }
56 |
57 | .box:before {
58 | content: "";
59 | width: 100%;
60 | height: 30px;
61 | border-radius: 10px;
62 | position: absolute;
63 | top: -10px;
64 | background: rgba(255, 255, 255, .6);
65 | left: 0;
66 | transform: scale(.95);
67 | -webkit-transform: scale(.95);
68 | -ms-transform: scale(.95);
69 | z-index: -1;
70 | }
71 |
72 | .login-wrapper .example-form {
73 | min-width: 100%;
74 | max-width: 300px;
75 | width: 100%;
76 | }
77 |
78 | .login-wrapper .example-full-width,
79 | .login-wrapper .btn-block {
80 | width: 100%;
81 | }
82 |
83 | .login-wrapper mat-card-header {
84 | text-align: center;
85 | width: 100%;
86 | display: block;
87 | font-weight: 700;
88 | }
89 |
90 | .login-wrapper mat-card-header mat-card-title {
91 | font-size: 30px;
92 | margin: 0;
93 | }
94 |
95 | .login-wrapper .mat-card {
96 | padding: 40px 70px 50px;
97 | }
98 |
99 | .login-wrapper .mat-stroked-button {
100 | border: 1px solid currentColor;
101 | line-height: 54px;
102 | background: #FFF7FA;
103 | }
104 |
105 | .login-wrapper .mat-form-field-appearance-legacy .mat-form-field-infix {
106 | padding: 0.8375em 0;
107 | }
108 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/app/login/login.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Log in
6 |
7 |
8 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/app/login/login.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { LoginComponent } from './login.component';
4 |
5 | describe('LoginComponent', () => {
6 | let component: LoginComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [ LoginComponent ]
12 | })
13 | .compileComponents();
14 | });
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(LoginComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/app/login/login.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import {Router} from '@angular/router';
3 |
4 | interface User {
5 | email: string;
6 | password: string;
7 | }
8 |
9 |
10 | @Component({
11 | selector: 'app-login',
12 | templateUrl: './login.component.html',
13 | styleUrls: ['./login.component.css']
14 | })
15 | export class LoginComponent implements OnInit {
16 | user: User ;
17 | constructor(private route:Router) {
18 | this.user = {
19 | email: '',
20 | password: ''
21 | };
22 | }
23 |
24 | ngOnInit(): void {
25 | }
26 |
27 | loginUser() {
28 | if(this.user.email == "admin@gmail.com" && this.user.password == "admin") {
29 | this.route.navigate(['home']);
30 | } else {
31 | alert("Invalid Credentials");
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/app/shared/data.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 |
3 | import { DataService } from './data.service';
4 |
5 | describe('DataService', () => {
6 | let service: DataService;
7 |
8 | beforeEach(() => {
9 | TestBed.configureTestingModule({});
10 | service = TestBed.inject(DataService);
11 | });
12 |
13 | it('should be created', () => {
14 | expect(service).toBeTruthy();
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/app/shared/data.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import {ProductData} from "../home/home.component";
3 |
4 | @Injectable({
5 | providedIn: 'root'
6 | })
7 | export class DataService {
8 |
9 | constructor() { }
10 |
11 | getProductData() : ProductData[]{
12 | return productData;
13 | }
14 | }
15 |
16 | let productData: ProductData[] = [
17 | { productId: getRandomInt(1,1000), productName: 'Apple iPhone 12', SKU: randomString(10), created: randomDate() , retailPrice: getRandomInt(500,1000), salePrice: getRandomInt(500,1000), lowestPrice: getRandomInt(500,1000) ,status: false,},
18 | { productId: getRandomInt(1,1000), productName: 'Apple iPhone 11', SKU: randomString(10), created: randomDate() , retailPrice: getRandomInt(500,1000), salePrice: getRandomInt(500,1000), lowestPrice: getRandomInt(500,1000) ,status: true,},
19 | { productId: getRandomInt(1,1000), productName: 'Apple iPhone XR', SKU: randomString(10), created: randomDate() , retailPrice: getRandomInt(500,1000), salePrice: getRandomInt(500,1000), lowestPrice: getRandomInt(500,1000) ,status: true,},
20 | { productId: getRandomInt(1,1000), productName: 'Apple iPhone XS', SKU: randomString(10), created: randomDate() , retailPrice: getRandomInt(500,1000), salePrice: getRandomInt(500,1000), lowestPrice: getRandomInt(500,1000) ,status: true,},
21 | { productId: getRandomInt(1,1000), productName: 'Apple iPhone X', SKU: randomString(10), created: randomDate() , retailPrice: getRandomInt(500,1000), salePrice: getRandomInt(500,1000), lowestPrice: getRandomInt(500,1000) ,status: true,},
22 | { productId: getRandomInt(1,1000), productName: 'Apple iPhone 8', SKU: randomString(10), created: randomDate() , retailPrice: getRandomInt(500,1000), salePrice: getRandomInt(500,1000), lowestPrice: getRandomInt(500,1000) ,status: true,},
23 | { productId: getRandomInt(1,1000), productName: 'Apple iPhone 7', SKU: randomString(10), created: randomDate() , retailPrice: getRandomInt(500,1000), salePrice: getRandomInt(500,1000), lowestPrice: getRandomInt(500,1000) ,status: true,},
24 | { productId: getRandomInt(1,1000), productName: 'Apple iPhone 6', SKU: randomString(10), created: randomDate() , retailPrice: getRandomInt(500,1000), salePrice: getRandomInt(500,1000), lowestPrice: getRandomInt(500,1000) ,status: true,},
25 | { productId: getRandomInt(1,1000), productName: 'Apple iPhone 5', SKU: randomString(10), created: randomDate() , retailPrice: getRandomInt(500,1000), salePrice: getRandomInt(500,1000), lowestPrice: getRandomInt(500,1000) ,status: true,},
26 | { productId: getRandomInt(1,1000), productName: 'Apple iPhone 4', SKU: randomString(10), created: randomDate() , retailPrice: getRandomInt(500,1000), salePrice: getRandomInt(500,1000), lowestPrice: getRandomInt(500,1000) ,status: true,},
27 | { productId: getRandomInt(1,1000), productName: 'Apple iPhone 3', SKU: randomString(10), created: randomDate() , retailPrice: getRandomInt(500,1000), salePrice: getRandomInt(500,1000), lowestPrice: getRandomInt(500,1000) ,status: true,},
28 | { productId: getRandomInt(1,1000), productName: 'Apple iPhone 2', SKU: randomString(10), created: randomDate() , retailPrice: getRandomInt(500,1000), salePrice: getRandomInt(500,1000), lowestPrice: getRandomInt(500,1000) ,status: true,},
29 | { productId: getRandomInt(1,1000), productName: 'Apple iPhone 1', SKU: randomString(10), created: randomDate() , retailPrice: getRandomInt(500,1000), salePrice: getRandomInt(500,1000), lowestPrice: getRandomInt(500,1000) ,status: true,},
30 | ];
31 |
32 |
33 | //create a function to generate random string of length n
34 | function randomString(n:number){
35 | const randomChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
36 | let result = '';
37 | for (let i = 0; i < n; i++ ) {
38 | result += randomChars.charAt(Math.floor(Math.random() * randomChars.length));
39 | }
40 | return result;
41 | }
42 |
43 | //create a function to generate random number of length n
44 | function getRandomInt(min:number, max:number) : number{
45 | min = Math.ceil(min);
46 | max = Math.floor(max);
47 | return Math.floor(Math.random() * (max - min + 1)) + min;
48 | }
49 |
50 | //create a function to generate random date
51 | function randomDate(){
52 | let date = Math.floor(Math.random() * (31 - 1 + 1)) + 1;
53 | let month = Math.floor(Math.random() * (12 - 1 + 1)) + 1;
54 | let year = Math.floor(Math.random() * (2022 - 2018 + 1)) + 2018;
55 | return date + '/' + month + '/' + year;
56 | }
57 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/LeetCode.Solutions/5f7ee73b8cc1953f3b8d1b84369143531e4d11aa/Problem_03._CRUD_with_products/src/assets/.gitkeep
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // `ng build` replaces `environment.ts` with `environment.prod.ts`.
3 | // The list of file replacements can be found in `angular.json`.
4 |
5 | export const environment = {
6 | production: false
7 | };
8 |
9 | /*
10 | * For easier debugging in development mode, you can import the following file
11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
12 | *
13 | * This import should be commented out in production mode because it will have a negative impact
14 | * on performance if an error is thrown.
15 | */
16 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
17 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nirzaf/LeetCode.Solutions/5f7ee73b8cc1953f3b8d1b84369143531e4d11aa/Problem_03._CRUD_with_products/src/favicon.ico
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CemexHRM
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule)
12 | .catch(err => console.error(err));
13 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/guide/browser-support
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /**
22 | * IE11 requires the following for NgClass support on SVG elements
23 | */
24 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
25 |
26 | /**
27 | * Web Animations `@angular/platform-browser/animations`
28 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
29 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
30 | */
31 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
32 |
33 | /**
34 | * By default, zone.js will patch all possible macroTask and DomEvents
35 | * user can disable parts of macroTask/DomEvents patch by setting following flags
36 | * because those flags need to be set before `zone.js` being loaded, and webpack
37 | * will put import in the top of bundle, so user need to create a separate file
38 | * in this directory (for example: zone-flags.ts), and put the following flags
39 | * into that file, and then add the following code before importing zone.js.
40 | * import './zone-flags';
41 | *
42 | * The flags allowed in zone-flags.ts are listed here.
43 | *
44 | * The following flags will work for all browsers.
45 | *
46 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
47 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
48 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
49 | *
50 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
51 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
52 | *
53 | * (window as any).__Zone_enable_cross_context_check = true;
54 | *
55 | */
56 |
57 | /***************************************************************************************************
58 | * Zone JS is required by default for Angular itself.
59 | */
60 | import 'zone.js'; // Included with Angular CLI.
61 |
62 |
63 | /***************************************************************************************************
64 | * APPLICATION IMPORTS
65 | */
66 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/src/styles.scss:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
3 | html, body { height: 100%; }
4 | body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; }
5 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/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/testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } from '@angular/platform-browser-dynamic/testing';
9 |
10 | declare const require: {
11 | context(path: string, deep?: boolean, filter?: RegExp): {
12 | keys(): string[];
13 | (id: string): T;
14 | };
15 | };
16 |
17 | // First, initialize the Angular testing environment.
18 | getTestBed().initTestEnvironment(
19 | BrowserDynamicTestingModule,
20 | platformBrowserDynamicTesting()
21 | );
22 | // Then we find all the tests.
23 | const context = require.context('./', true, /\.spec\.ts$/);
24 | // And load the modules.
25 | context.keys().map(context);
26 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "./out-tsc/app",
6 | "types": []
7 | },
8 | "files": [
9 | "src/main.ts",
10 | "src/polyfills.ts"
11 | ],
12 | "include": [
13 | "src/**/*.d.ts"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/tsconfig.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "compileOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": "./",
6 | "outDir": "./dist/out-tsc",
7 | "forceConsistentCasingInFileNames": true,
8 | "strict": true,
9 | "noImplicitReturns": true,
10 | "noFallthroughCasesInSwitch": true,
11 | "sourceMap": true,
12 | "declaration": false,
13 | "downlevelIteration": true,
14 | "experimentalDecorators": true,
15 | "moduleResolution": "node",
16 | "importHelpers": true,
17 | "target": "es2017",
18 | "module": "es2020",
19 | "lib": [
20 | "es2018",
21 | "dom"
22 | ]
23 | },
24 | "angularCompilerOptions": {
25 | "enableI18nLegacyMessageIdFormat": false,
26 | "strictInjectionParameters": true,
27 | "strictInputAccessModifiers": true,
28 | "strictTemplates": true
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Problem_03._CRUD_with_products/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "outDir": "./out-tsc/spec",
6 | "types": [
7 | "jasmine"
8 | ]
9 | },
10 | "files": [
11 | "src/test.ts",
12 | "src/polyfills.ts"
13 | ],
14 | "include": [
15 | "src/**/*.spec.ts",
16 | "src/**/*.d.ts"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------