From 0bc3fcdbc770de0529940857db615077ac4fb126 Mon Sep 17 00:00:00 2001 From: your_name Date: Sun, 12 Mar 2023 10:45:44 +0100 Subject: [PATCH 01/11] Add Page Layout --- src/app/app-routing.module.ts | 12 +- .../categories/categories.component-module.ts | 11 ++ .../categories/categories.component.html | 0 .../categories/categories.component.scss | 0 .../categories/categories.component.ts | 11 ++ .../components/home/home.component-module.ts | 13 ++ src/app/components/home/home.component.html | 153 ++++++++++++++++++ src/app/components/home/home.component.scss | 0 src/app/components/home/home.component.ts | 21 +++ .../store/store.component-module.ts | 11 ++ src/app/components/store/store.component.html | 0 src/app/components/store/store.component.scss | 0 src/app/components/store/store.component.ts | 11 ++ src/app/models/category.model.ts | 5 + src/app/models/product.model.ts | 11 ++ src/app/models/store.model.ts | 7 + src/app/services/categories.service.ts | 14 ++ src/app/services/stores.service.ts | 14 ++ 18 files changed, 291 insertions(+), 3 deletions(-) create mode 100644 src/app/components/categories/categories.component-module.ts create mode 100644 src/app/components/categories/categories.component.html create mode 100644 src/app/components/categories/categories.component.scss create mode 100644 src/app/components/categories/categories.component.ts create mode 100644 src/app/components/home/home.component-module.ts create mode 100644 src/app/components/home/home.component.html create mode 100644 src/app/components/home/home.component.scss create mode 100644 src/app/components/home/home.component.ts create mode 100644 src/app/components/store/store.component-module.ts create mode 100644 src/app/components/store/store.component.html create mode 100644 src/app/components/store/store.component.scss create mode 100644 src/app/components/store/store.component.ts create mode 100644 src/app/models/category.model.ts create mode 100644 src/app/models/product.model.ts create mode 100644 src/app/models/store.model.ts create mode 100644 src/app/services/categories.service.ts create mode 100644 src/app/services/stores.service.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index f3daf250..bc7bd0d4 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -1,10 +1,16 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; +import { HomeComponent } from './components/home/home.component'; +import { CategoriesComponent } from './components/categories/categories.component'; +import { StoreComponent } from './components/store/store.component'; +import { HomeComponentModule } from './components/home/home.component-module'; +import { CategoriesComponentModule } from './components/categories/categories.component-module'; +import { StoreComponentModule } from './components/store/store.component-module'; -const routes: Routes = []; +const routes: Routes = [{ path: '', component: HomeComponent }, { path: 'categories/:categoryId', component: CategoriesComponent }, { path: 'stores/:storeId', component: StoreComponent }]; @NgModule({ - imports: [RouterModule.forRoot(routes)], + imports: [RouterModule.forRoot(routes), HomeComponentModule, CategoriesComponentModule, StoreComponentModule], exports: [RouterModule], }) -export class AppRoutingModule {} +export class AppRoutingModule { } diff --git a/src/app/components/categories/categories.component-module.ts b/src/app/components/categories/categories.component-module.ts new file mode 100644 index 00000000..8f9ddaa3 --- /dev/null +++ b/src/app/components/categories/categories.component-module.ts @@ -0,0 +1,11 @@ +import { NgModule } from '@angular/core'; +import { CategoriesComponent } from './categories.component'; + +@NgModule({ + imports: [], + declarations: [CategoriesComponent], + providers: [], + exports: [CategoriesComponent] +}) +export class CategoriesComponentModule { +} diff --git a/src/app/components/categories/categories.component.html b/src/app/components/categories/categories.component.html new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/categories/categories.component.scss b/src/app/components/categories/categories.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/categories/categories.component.ts b/src/app/components/categories/categories.component.ts new file mode 100644 index 00000000..e9cec03b --- /dev/null +++ b/src/app/components/categories/categories.component.ts @@ -0,0 +1,11 @@ +import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core'; + +@Component({ + selector: 'app-categories', + styleUrls: ['./categories.component.scss'], + templateUrl: './categories.component.html', + encapsulation: ViewEncapsulation.Emulated, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class CategoriesComponent { +} diff --git a/src/app/components/home/home.component-module.ts b/src/app/components/home/home.component-module.ts new file mode 100644 index 00000000..537d6867 --- /dev/null +++ b/src/app/components/home/home.component-module.ts @@ -0,0 +1,13 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; +import { HomeComponent } from './home.component'; + +@NgModule({ + imports: [CommonModule, RouterModule], + declarations: [HomeComponent], + providers: [], + exports: [HomeComponent] +}) +export class HomeComponentModule { +} diff --git a/src/app/components/home/home.component.html b/src/app/components/home/home.component.html new file mode 100644 index 00000000..6a1a49b6 --- /dev/null +++ b/src/app/components/home/home.component.html @@ -0,0 +1,153 @@ +
+

+ + FreshCart +

+ +
+ diff --git a/src/app/components/home/home.component.scss b/src/app/components/home/home.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/home/home.component.ts b/src/app/components/home/home.component.ts new file mode 100644 index 00000000..8e729332 --- /dev/null +++ b/src/app/components/home/home.component.ts @@ -0,0 +1,21 @@ +import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core'; +import { Observable, of } from 'rxjs'; +import { CategoryModel } from '../../models/category.model'; +import { StoreModel } from '../../models/store.model'; +import { CategoriesService } from '../../services/categories.service'; +import { StoresService } from '../../services/stores.service'; + +@Component({ + selector: 'app-home', + styleUrls: ['./home.component.scss'], + templateUrl: './home.component.html', + encapsulation: ViewEncapsulation.Emulated, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class HomeComponent { + readonly categoriesList$: Observable = this._categoriesService.getAll(); + readonly storeList$: Observable = this._storesService.getAll(); +readonly GetToKnowUs$: Observable = of (['Company', 'About', 'Blog', 'Help Center', 'Our Value']); + constructor(private _categoriesService: CategoriesService, private _storesService: StoresService) { + } +} diff --git a/src/app/components/store/store.component-module.ts b/src/app/components/store/store.component-module.ts new file mode 100644 index 00000000..f1a11a35 --- /dev/null +++ b/src/app/components/store/store.component-module.ts @@ -0,0 +1,11 @@ +import { NgModule } from '@angular/core'; +import { StoreComponent } from './store.component'; + +@NgModule({ + imports: [], + declarations: [StoreComponent], + providers: [], + exports: [StoreComponent] +}) +export class StoreComponentModule { +} diff --git a/src/app/components/store/store.component.html b/src/app/components/store/store.component.html new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/store/store.component.scss b/src/app/components/store/store.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/store/store.component.ts b/src/app/components/store/store.component.ts new file mode 100644 index 00000000..2abcb3bf --- /dev/null +++ b/src/app/components/store/store.component.ts @@ -0,0 +1,11 @@ +import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core'; + +@Component({ + selector: 'app-store', + styleUrls: ['./store.component.scss'], + templateUrl: './store.component.html', + encapsulation: ViewEncapsulation.Emulated, + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class StoreComponent { +} diff --git a/src/app/models/category.model.ts b/src/app/models/category.model.ts new file mode 100644 index 00000000..ea47a9cb --- /dev/null +++ b/src/app/models/category.model.ts @@ -0,0 +1,5 @@ +export interface CategoryModel { + readonly name: string; + readonly imageUrl: string; + readonly id: string; +} diff --git a/src/app/models/product.model.ts b/src/app/models/product.model.ts new file mode 100644 index 00000000..4824dd61 --- /dev/null +++ b/src/app/models/product.model.ts @@ -0,0 +1,11 @@ +export interface ProductModel { + readonly name: string; + readonly price: string; + readonly categoryId: string; + readonly ratingValue: string; + readonly ratingCount: string; + readonly imageUrl: string; + readonly featureValues: string; + readonly storeIds: string[]; + readonly id: string; +} diff --git a/src/app/models/store.model.ts b/src/app/models/store.model.ts new file mode 100644 index 00000000..b20eafa0 --- /dev/null +++ b/src/app/models/store.model.ts @@ -0,0 +1,7 @@ +export interface StoreModel { + readonly name: string; + readonly logoUrl: string; + readonly distanceInMeters: string; + readonly tagIds: string[]; + readonly id: string; +} diff --git a/src/app/services/categories.service.ts b/src/app/services/categories.service.ts new file mode 100644 index 00000000..d67e6040 --- /dev/null +++ b/src/app/services/categories.service.ts @@ -0,0 +1,14 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { CategoryModel } from '../models/category.model'; + +@Injectable({ providedIn: 'root' }) +export class CategoriesService { + constructor(private _httpClient: HttpClient) { + } + + getAll(): Observable { + return this._httpClient.get("https://6384fca14ce192ac60696c4b.mockapi.io/freshcart-categories"); + } +} diff --git a/src/app/services/stores.service.ts b/src/app/services/stores.service.ts new file mode 100644 index 00000000..c36e56c4 --- /dev/null +++ b/src/app/services/stores.service.ts @@ -0,0 +1,14 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { StoreModel } from '../models/store.model'; + +@Injectable({ providedIn: 'root' }) +export class StoresService { + constructor(private _httpClient: HttpClient) { + } + + getAll(): Observable { + return this._httpClient.get("https://6384fca14ce192ac60696c4b.mockapi.io/freshcart-stores"); + } +} From 1a38971745a473caaabe1d06533d8473c5a8cc3c Mon Sep 17 00:00:00 2001 From: your_name Date: Sun, 12 Mar 2023 11:14:35 +0100 Subject: [PATCH 02/11] add shop by category and stores --- src/app/components/home/home.component.html | 90 +++++++++++++++++++-- 1 file changed, 83 insertions(+), 7 deletions(-) diff --git a/src/app/components/home/home.component.html b/src/app/components/home/home.component.html index 6a1a49b6..c429d5c2 100644 --- a/src/app/components/home/home.component.html +++ b/src/app/components/home/home.component.html @@ -11,29 +11,105 @@

+ +
+
+
+
+
+

Shop by Category

+
+
+
+ + +
+
+
+
+
+
+
+

Stores

+
+
+
+ + +
+
-
Categories - -
- - +
Categories
+
Stores
- +
Get to know us
- +
From 4c0d3ca704e244853a7628c76bba2d07685c3d10 Mon Sep 17 00:00:00 2001 From: your_name Date: Sun, 12 Mar 2023 12:24:33 +0100 Subject: [PATCH 03/11] tags store --- coding-standards.json | 50 ++ src/app/components/home/home.component.html | 431 +++++++++++------- src/app/components/home/home.component.ts | 99 +++- src/app/models/product.model.ts | 2 +- src/app/models/store.model.ts | 2 +- src/app/models/tag-store.model.ts | 4 + .../store-with-tags.query-model.ts | 10 + src/app/services/products.service.ts | 14 + src/app/services/stores.service.ts | 5 + 9 files changed, 448 insertions(+), 169 deletions(-) create mode 100644 coding-standards.json create mode 100644 src/app/models/tag-store.model.ts create mode 100644 src/app/query-models/store-with-tags.query-model.ts create mode 100644 src/app/services/products.service.ts diff --git a/coding-standards.json b/coding-standards.json new file mode 100644 index 00000000..de1c0a42 --- /dev/null +++ b/coding-standards.json @@ -0,0 +1,50 @@ +{ + "entityRelations": { + "component": { + "model": ["PROPERTY"], + "service": ["CONSTRUCTOR"], + "router": ["CONSTRUCTOR"], + "activatedRoute": ["CONSTRUCTOR"] + }, + "service": { + "httpClient": ["CONSTRUCTOR"], + "model": ["PARAMETER", "RETURN"] + } + }, + "external": { + "httpClient": { + "type": "HttpClient", + "module": "@angular/common/http" + }, + "router": { + "type": "Router", + "module": "@angular/router" + }, + "activatedRoute": { + "type": "ActivatedRoute", + "module": "@angular/router" + } + }, + "entities": { + "component": { + "type": "ANGULAR_COMPONENT", + "folder": "components/$name$", + "config": { + "stylesExtension": "none", + "viewEncapsulation": "None", + "selector": "generated", + "changeDetectionStrategy": "OnPush" + } + }, + "model": { + "type": "DATA_STRUCTURE" + }, + "queryModel": { + "type": "DATA_STRUCTURE" + }, + "service": { + "type": "ANGULAR_SERVICE" + } + } + } + \ No newline at end of file diff --git a/src/app/components/home/home.component.html b/src/app/components/home/home.component.html index c429d5c2..9ffd2c41 100644 --- a/src/app/components/home/home.component.html +++ b/src/app/components/home/home.component.html @@ -41,189 +41,300 @@

Shop by Category

-
-
-
-
-

Stores

+
+
+
+
+

Fruits & Vegetables

+
+
+
+ +
+
+ +
+
+
+ +
+

+ {{ + product.name + }} +

+ +
+
+ {{ product.price | currency }} +
+
+
+
+ +
+
+
+
+ +
+ +
+
+
+
+
+

Stores

+
+
+ +
+
+
+
+ We have + {{ stores.length }} vendors now +
- -
-
- -
-
- - -
{{ item.name }}
+
+ +
+
+
+
+ +
+ +
+
+ {{ + item.name + }} +
+
+ + {{ tags.name }} + + + +
+
+
+ {{ item.distanceInMeters }} km
- +
-
+
+
-
-
-
-
-
Categories
+
+
+
+
+
Categories
+ +
+
+
+
+
Stores
+
-
-
-
-
Stores
-
- -
-
-
-
Get to know us
-
- -
-
-
-
-
-
    -
  • Payment Partners
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - -
  • -
  • - +
    +
    +
    Get to know us
    +
    +
    -
    -
      -
    • - Get deliveries with FreshCart -
    • -
    • - - -
    • -
    • - - -
    • -
    +
    +
    +
    +
    +
      +
    • Payment Partners
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    +
    +
    +
      +
    • + Get deliveries with FreshCart +
    • +
    • + + +
    • +
    • + + +
    • +
    +
    -
-
-
-
- +
+
+
+ +
-
-
+
+ diff --git a/src/app/components/home/home.component.ts b/src/app/components/home/home.component.ts index 8e729332..2f3fdef8 100644 --- a/src/app/components/home/home.component.ts +++ b/src/app/components/home/home.component.ts @@ -1,21 +1,106 @@ -import { ChangeDetectionStrategy, Component, ViewEncapsulation } from '@angular/core'; -import { Observable, of } from 'rxjs'; +import { + ChangeDetectionStrategy, + Component, + ViewEncapsulation, +} from '@angular/core'; +import { Observable, of, switchMap, map, combineLatest } from 'rxjs'; import { CategoryModel } from '../../models/category.model'; import { StoreModel } from '../../models/store.model'; +import { ProductModel } from '../../models/product.model'; import { CategoriesService } from '../../services/categories.service'; import { StoresService } from '../../services/stores.service'; +import { ProductsService } from '../../services/products.service'; +import { TagStoreModel } from 'src/app/models/tag-store.model'; +import { StoreWithTagsQueryModel } from 'src/app/query-models/store-with-tags.query-model'; @Component({ selector: 'app-home', styleUrls: ['./home.component.scss'], templateUrl: './home.component.html', encapsulation: ViewEncapsulation.Emulated, - changeDetection: ChangeDetectionStrategy.OnPush + changeDetection: ChangeDetectionStrategy.OnPush, }) export class HomeComponent { - readonly categoriesList$: Observable = this._categoriesService.getAll(); - readonly storeList$: Observable = this._storesService.getAll(); -readonly GetToKnowUs$: Observable = of (['Company', 'About', 'Blog', 'Help Center', 'Our Value']); - constructor(private _categoriesService: CategoriesService, private _storesService: StoresService) { + readonly categoriesList$: Observable = + this._categoriesService.getAll(); + readonly storeList$: Observable = combineLatest([ + this._storesService.getAll(), + this._storesService.getAllTags(), + +]).pipe( + map(([stores, tags]) => this.mapTagStore(tags, stores))); + + + + + readonly GetToKnowUs$: Observable = of([ + 'Company', + 'About', + 'Blog', + 'Help Center', + 'Our Value', + ]); + readonly productsList$: Observable = + this._productsService.getAll(); + + + readonly fruitId$: Observable = of('5'); + + readonly FruitList$: Observable = + this.fruitId$.pipe( + switchMap((categoryId) => + this.productsList$.pipe( + map((products) => + products + .filter((products) => products.categoryId === categoryId) + .sort((a, b) => b.featureValues - a.featureValues) + .slice(0, 5) + ) + ) + ) + ); + + readonly fruitCategory$: Observable = + combineLatest([this.fruitId$, this.FruitList$]).pipe( + map(([catId, categories]) => categories.find((c) => c.id === catId)) + ) + + readonly SnackId$: Observable = of('2'); + readonly SnackList$: Observable = + this.SnackId$.pipe( + switchMap((categoryId) => + this.productsList$.pipe( + map((products) => + products + .filter((products) => products.categoryId === categoryId) + .sort((a, b) => b.featureValues - a.featureValues) + .slice(0, 5) + ) + ) + ) + ); + + constructor( + private _categoriesService: CategoriesService, + private _storesService: StoresService, + private _productsService: ProductsService + ) {} + + + mapTagStore ( + tags: TagStoreModel[], + stores: StoreModel[] + ): StoreWithTagsQueryModel[] { + const tagMap = tags.reduce((a, c) => ({ ...a, [c.id]: c }), {}) as Record< + string, + TagStoreModel + >; + return stores.map((store) => ({ + id: store.id, + name: store.name, + logoUrl: store.logoUrl, + distanceInMeters: store.distanceInMeters, + tags: store.tagIds.map((tagId) => tagMap[tagId]) as TagStoreModel[], + })); } } diff --git a/src/app/models/product.model.ts b/src/app/models/product.model.ts index 4824dd61..ad396df2 100644 --- a/src/app/models/product.model.ts +++ b/src/app/models/product.model.ts @@ -5,7 +5,7 @@ export interface ProductModel { readonly ratingValue: string; readonly ratingCount: string; readonly imageUrl: string; - readonly featureValues: string; + readonly featureValues: number; readonly storeIds: string[]; readonly id: string; } diff --git a/src/app/models/store.model.ts b/src/app/models/store.model.ts index b20eafa0..1e4e04e1 100644 --- a/src/app/models/store.model.ts +++ b/src/app/models/store.model.ts @@ -1,7 +1,7 @@ export interface StoreModel { readonly name: string; readonly logoUrl: string; - readonly distanceInMeters: string; + readonly distanceInMeters: number; readonly tagIds: string[]; readonly id: string; } diff --git a/src/app/models/tag-store.model.ts b/src/app/models/tag-store.model.ts new file mode 100644 index 00000000..924c63bb --- /dev/null +++ b/src/app/models/tag-store.model.ts @@ -0,0 +1,4 @@ +export interface TagStoreModel { + readonly name: string; + readonly id: string; +} diff --git a/src/app/query-models/store-with-tags.query-model.ts b/src/app/query-models/store-with-tags.query-model.ts new file mode 100644 index 00000000..4e771bc5 --- /dev/null +++ b/src/app/query-models/store-with-tags.query-model.ts @@ -0,0 +1,10 @@ +import { TagStoreModel } from "../models/tag-store.model"; + +export interface StoreWithTagsQueryModel { + + readonly id: string; + readonly name: string; + readonly logoUrl: string; + readonly distanceInMeters: number; + readonly tags: TagStoreModel[]; +} diff --git a/src/app/services/products.service.ts b/src/app/services/products.service.ts new file mode 100644 index 00000000..60809e25 --- /dev/null +++ b/src/app/services/products.service.ts @@ -0,0 +1,14 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { ProductModel } from '../models/product.model'; + +@Injectable({ providedIn: 'root' }) +export class ProductsService { + constructor(private _httpClient: HttpClient) { + } + + getAll(): Observable { + return this._httpClient.get('https://6384fca14ce192ac60696c4b.mockapi.io/freshcart-products'); + } +} diff --git a/src/app/services/stores.service.ts b/src/app/services/stores.service.ts index c36e56c4..ebcad029 100644 --- a/src/app/services/stores.service.ts +++ b/src/app/services/stores.service.ts @@ -2,6 +2,7 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { StoreModel } from '../models/store.model'; +import { TagStoreModel } from '../models/tag-store.model'; @Injectable({ providedIn: 'root' }) export class StoresService { @@ -11,4 +12,8 @@ export class StoresService { getAll(): Observable { return this._httpClient.get("https://6384fca14ce192ac60696c4b.mockapi.io/freshcart-stores"); } + + getAllTags(): Observable { + return this._httpClient.get("https://6384fca14ce192ac60696c4b.mockapi.io/freshcart-store-tags"); + } } From 316b9f2efa4455e4de55cba5068c6b5c5a04f7bd Mon Sep 17 00:00:00 2001 From: your_name Date: Sun, 12 Mar 2023 12:36:08 +0100 Subject: [PATCH 04/11] home page done --- src/app/components/home/home.component.html | 365 ++++++++++---------- 1 file changed, 187 insertions(+), 178 deletions(-) diff --git a/src/app/components/home/home.component.html b/src/app/components/home/home.component.html index 9ffd2c41..e0ac4317 100644 --- a/src/app/components/home/home.component.html +++ b/src/app/components/home/home.component.html @@ -5,7 +5,7 @@

+ Pick Location + + + + + + - \ No newline at end of file + + + + + + + diff --git a/src/app/components/head/head.component.ts b/src/app/components/head/head.component.ts index 775b5859..eb6cb0c2 100644 --- a/src/app/components/head/head.component.ts +++ b/src/app/components/head/head.component.ts @@ -24,9 +24,11 @@ export class HeadComponent { 'Help Center', 'Our Value', ]); + constructor(private _categoriesService: CategoriesService, private _storesService: StoresService) { } + ShowHamburger() { this.Hamburger$.pipe(take(1), tap(() => this._hamburgerSubject.next(true)) From b34ce31408ef035826241fb14b8d3b92f8b10fc2 Mon Sep 17 00:00:00 2001 From: your_name Date: Mon, 20 Mar 2023 14:33:17 +0100 Subject: [PATCH 11/11] about us --- .../about-us/about-us.component.html | 4 +-- src/app/components/head/head.component.html | 31 ++++++++++--------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/app/components/about-us/about-us.component.html b/src/app/components/about-us/about-us.component.html index 4e8f95a6..a4ea08aa 100644 --- a/src/app/components/about-us/about-us.component.html +++ b/src/app/components/about-us/about-us.component.html @@ -160,8 +160,8 @@

650+
- -

Our Leadership

+ +
diff --git a/src/app/components/head/head.component.html b/src/app/components/head/head.component.html index 9a6d0855..8f9a988d 100644 --- a/src/app/components/head/head.component.html +++ b/src/app/components/head/head.component.html @@ -9,7 +9,8 @@