Skip to content

Commit 00c5ec7

Browse files
committed
feat: add basic representation of mock products
1 parent 356c51b commit 00c5ec7

16 files changed

+286
-1
lines changed

src/app/app-routing.module.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import { NgModule } from '@angular/core';
22
import { RouterModule, Routes } from '@angular/router';
3+
import { ProductsComponent } from './products/products.component';
34

4-
const routes: Routes = [];
5+
const routes: Routes = [
6+
{
7+
path: '',
8+
component: ProductsComponent,
9+
},
10+
];
511

612
@NgModule({
713
imports: [RouterModule.forRoot(routes)],

src/app/app.component.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
<app-header></app-header>
2+
3+
<router-outlet></router-outlet>

src/app/app.module.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { MatButtonModule } from '@angular/material/button';
1010
import { MatIconModule } from '@angular/material/icon';
1111
import { MatMenuModule } from '@angular/material/menu';
1212
import { MatTooltipModule } from '@angular/material/tooltip';
13+
import { ProductsModule } from './products/products.module';
14+
import { HttpClientModule } from '@angular/common/http';
1315

1416
@NgModule({
1517
declarations: [AppComponent, HeaderComponent],
@@ -22,6 +24,8 @@ import { MatTooltipModule } from '@angular/material/tooltip';
2224
MatIconModule,
2325
MatMenuModule,
2426
MatTooltipModule,
27+
ProductsModule,
28+
HttpClientModule,
2529
],
2630
providers: [],
2731
bootstrap: [AppComponent],
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<mat-card>
2+
<div mat-card-image class="img-container">
3+
<div class="img-container__inner">
4+
<img src="https://source.unsplash.com/random?sig={{ index }}" alt="" />
5+
</div>
6+
</div>
7+
8+
<header>
9+
<mat-card-title>
10+
{{ product.title }}
11+
</mat-card-title>
12+
</header>
13+
14+
<mat-card-content>
15+
<p>{{ product.price | number: "1.2-2" | currency }}</p>
16+
</mat-card-content>
17+
18+
<mat-card-actions>
19+
<button
20+
color="accent"
21+
matTooltip="Add {{ product.title }} to cart"
22+
mat-icon-button
23+
>
24+
<mat-icon>shopping_cart</mat-icon>
25+
</button>
26+
</mat-card-actions>
27+
</mat-card>
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.img-container {
2+
padding-top: 50%;
3+
position: relative;
4+
5+
&__inner {
6+
position: absolute;
7+
top: 0;
8+
left: 0;
9+
width: 100%;
10+
height: 100%;
11+
}
12+
13+
img {
14+
object-fit: cover;
15+
width: 100%;
16+
height: 100%;
17+
object-position: center center;
18+
}
19+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { ProductItemComponent } from './product-item.component';
4+
5+
describe('ProductItemComponent', () => {
6+
let component: ProductItemComponent;
7+
let fixture: ComponentFixture<ProductItemComponent>;
8+
9+
beforeEach(async () => {
10+
await TestBed.configureTestingModule({
11+
declarations: [ProductItemComponent],
12+
}).compileComponents();
13+
});
14+
15+
beforeEach(() => {
16+
fixture = TestBed.createComponent(ProductItemComponent);
17+
component = fixture.componentInstance;
18+
fixture.detectChanges();
19+
});
20+
21+
it('should create', () => {
22+
expect(component).toBeTruthy();
23+
});
24+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Component, Input } from '@angular/core';
2+
import { Product } from '../product.interface';
3+
4+
@Component({
5+
selector: 'app-product-item',
6+
templateUrl: './product-item.component.html',
7+
styleUrls: ['./product-item.component.scss'],
8+
})
9+
export class ProductItemComponent {
10+
@Input() product!: Product;
11+
@Input() index!: number;
12+
}

src/app/products/product.interface.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export interface Product {
2+
count: number;
3+
description: string;
4+
id: string;
5+
price: number;
6+
title: string;
7+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<main class="container">
2+
<app-product-item
3+
*ngFor="let product of products$ | async; let i = index"
4+
[product]="product"
5+
[index]="i"
6+
>
7+
</app-product-item>
8+
</main>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
@import "~bootstrap/scss/functions";
2+
@import "~bootstrap/scss/variables";
3+
@import "~bootstrap/scss/mixins/breakpoints";
4+
5+
.container {
6+
--gap: 10px;
7+
8+
display: grid;
9+
grid-template-columns: 1fr;
10+
11+
grid-gap: var(--gap);
12+
padding: var(--gap);
13+
14+
@include media-breakpoint-up(md) {
15+
grid-template-columns: 1fr 1fr;
16+
--gap: 20px;
17+
}
18+
19+
@include media-breakpoint-up(lg) {
20+
grid-template-columns: 1fr 1fr 1fr;
21+
--gap: 30px;
22+
}
23+
}

0 commit comments

Comments
 (0)