mirror of
https://github.com/Mueller-Patrick/Betterzon.git
synced 2026-04-27 07:40:10 +00:00
BETTERZON-42: Restructuring, creating necessary components, design of Product detail component
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<p>header works!</p>
|
||||
+6
-6
@@ -1,20 +1,20 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { LandingpageComponent } from './landingpage.component';
|
||||
import { HeaderComponent } from './header.component';
|
||||
|
||||
describe('LandingpageComponent', () => {
|
||||
let component: LandingpageComponent;
|
||||
let fixture: ComponentFixture<LandingpageComponent>;
|
||||
describe('HeaderComponent', () => {
|
||||
let component: HeaderComponent;
|
||||
let fixture: ComponentFixture<HeaderComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ LandingpageComponent ]
|
||||
declarations: [ HeaderComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(LandingpageComponent);
|
||||
fixture = TestBed.createComponent(HeaderComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-header',
|
||||
templateUrl: './header.component.html',
|
||||
styleUrls: ['./header.component.css']
|
||||
})
|
||||
export class HeaderComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
<app-product-list numberOfProducts="20" showProductPicture="true"></app-product-list>
|
||||
<app-footer></app-footer>
|
||||
@@ -1,15 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-landingpage',
|
||||
templateUrl: './landingpage.component.html',
|
||||
styleUrls: ['./landingpage.component.css']
|
||||
})
|
||||
export class LandingpageComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<p>newest-prices-list works!</p>
|
||||
+6
-6
@@ -1,20 +1,20 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ProductDetailPageComponent } from './product-detail-page.component';
|
||||
import { NewestPricesListComponent } from './newest-prices-list.component';
|
||||
|
||||
describe('ProductDetailPageComponent', () => {
|
||||
let component: ProductDetailPageComponent;
|
||||
let fixture: ComponentFixture<ProductDetailPageComponent>;
|
||||
describe('NewestPricesListComponent', () => {
|
||||
let component: NewestPricesListComponent;
|
||||
let fixture: ComponentFixture<NewestPricesListComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ProductDetailPageComponent ]
|
||||
declarations: [ NewestPricesListComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ProductDetailPageComponent);
|
||||
fixture = TestBed.createComponent(NewestPricesListComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-newest-prices-list',
|
||||
templateUrl: './newest-prices-list.component.html',
|
||||
styleUrls: ['./newest-prices-list.component.css']
|
||||
})
|
||||
export class NewestPricesListComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
<app-product-details></app-product-details>
|
||||
<app-footer></app-footer>
|
||||
@@ -1,15 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-product-detail-page',
|
||||
templateUrl: './product-detail-page.component.html',
|
||||
styleUrls: ['./product-detail-page.component.css']
|
||||
})
|
||||
export class ProductDetailPageComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/* Div that contains each product */
|
||||
.productItem {
|
||||
padding: .25em;
|
||||
margin: auto;
|
||||
margin-bottom: .5em;
|
||||
display: grid;
|
||||
grid-template-columns: 20% 50% 30%;
|
||||
grid-template-areas:
|
||||
'image title priceChart'
|
||||
'image description priceChart'
|
||||
'image priceAlarm bestPrice';
|
||||
}
|
||||
|
||||
/* Image div */
|
||||
.productImageContainer {
|
||||
grid-area: image;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Product Image */
|
||||
.productImage {
|
||||
max-width: 300px;
|
||||
max-height: 300px;
|
||||
display:block;
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
/* Title div */
|
||||
.productTitle {
|
||||
grid-area: title;
|
||||
font-size: 2em;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
/* Price div */
|
||||
.priceChart {
|
||||
grid-area: priceChart;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
/* Description div */
|
||||
.productDescription {
|
||||
grid-area: description;
|
||||
}
|
||||
|
||||
/* Price alarm div */
|
||||
.priceAlarm {
|
||||
grid-area: priceAlarm;
|
||||
border-style: solid;
|
||||
border-color: dimgrey;
|
||||
padding: .25em;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
/* Best price div */
|
||||
.bestPrice {
|
||||
grid-area: bestPrice;
|
||||
border-style: solid;
|
||||
border-color: dimgrey;
|
||||
padding: .25em;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
@@ -1 +1,30 @@
|
||||
<p>product-details works!</p>
|
||||
<meta charset="UTF-8">
|
||||
<div class="productItem">
|
||||
<div class="productImageContainer">
|
||||
<img class="productImage" src="https://www.mueller-patrick.tech/betterzon/images/{{product.image_guid}}.jpg"/>
|
||||
</div>
|
||||
<div class="productTitle">
|
||||
<b>{{product.name}}</b>
|
||||
</div>
|
||||
<div class="priceChart">
|
||||
<div style="text-align:center">
|
||||
<apx-chart
|
||||
[series]="chartOptions.series"
|
||||
[chart]="chartOptions.chart"
|
||||
[xaxis]="chartOptions.xaxis"
|
||||
[title]="chartOptions.title"
|
||||
></apx-chart>
|
||||
</div>
|
||||
</div>
|
||||
<div class="productDescription">
|
||||
<div>
|
||||
{{product.short_description}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="priceAlarm">
|
||||
Set Price Alarm
|
||||
</div>
|
||||
<div class="bestPrice">
|
||||
5€
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +1,69 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {Component, Input, OnInit, ViewChild} from '@angular/core';
|
||||
import {Product} from '../../models/product';
|
||||
import {ApiService} from '../../services/api.service';
|
||||
import {
|
||||
ChartComponent,
|
||||
ApexAxisChartSeries,
|
||||
ApexChart,
|
||||
ApexXAxis,
|
||||
ApexTitleSubtitle, ApexStroke
|
||||
} from 'ng-apexcharts';
|
||||
|
||||
export type ChartOptions = {
|
||||
series: ApexAxisChartSeries;
|
||||
chart: ApexChart;
|
||||
xaxis: ApexXAxis;
|
||||
title: ApexTitleSubtitle;
|
||||
stroke: ApexStroke;
|
||||
};
|
||||
|
||||
@Component({
|
||||
selector: 'app-product-details',
|
||||
templateUrl: './product-details.component.html',
|
||||
styleUrls: ['./product-details.component.css']
|
||||
selector: 'app-product-details',
|
||||
templateUrl: './product-details.component.html',
|
||||
styleUrls: ['./product-details.component.css']
|
||||
})
|
||||
export class ProductDetailsComponent implements OnInit {
|
||||
@Input() productId: number;
|
||||
product: Product;
|
||||
@ViewChild('chart') chart: ChartComponent;
|
||||
public chartOptions: ChartOptions;
|
||||
|
||||
constructor() { }
|
||||
constructor(
|
||||
private apiService: ApiService
|
||||
) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
ngOnInit(): void {
|
||||
this.getProduct();
|
||||
this.getChartData();
|
||||
}
|
||||
|
||||
getProduct(): void {
|
||||
this.apiService.getProduct(this.productId).subscribe(product => this.product = product);
|
||||
}
|
||||
|
||||
getChartData(): void {
|
||||
this.chartOptions = {
|
||||
series: [
|
||||
{
|
||||
name: 'Lowest Price',
|
||||
data: [1061.20, 1060, 1070, 1040, 1061.20, 1061, 1100, 1070, 1061.20]
|
||||
}
|
||||
],
|
||||
chart: {
|
||||
height: 350,
|
||||
type: 'area'
|
||||
},
|
||||
title: {
|
||||
text: 'Lowest price'
|
||||
},
|
||||
xaxis: {
|
||||
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep']
|
||||
},
|
||||
stroke: {
|
||||
curve: 'stepline'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,55 @@
|
||||
/* Div that contains each product */
|
||||
.productItem {
|
||||
border-style: solid;
|
||||
border-color: dimgrey;
|
||||
border-radius: .5em;
|
||||
padding: .25em;
|
||||
margin: auto;
|
||||
margin-bottom: .5em;
|
||||
max-width: 50em;
|
||||
display: grid;
|
||||
grid-template-columns: 10% 80% 10%;
|
||||
grid-template-areas:
|
||||
'image title price'
|
||||
'image description price';
|
||||
}
|
||||
|
||||
/* Image div */
|
||||
.productImageContainer {
|
||||
grid-area: image;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Product Image */
|
||||
.productImage {
|
||||
max-width: 50px;
|
||||
max-height: 50px;
|
||||
display:block;
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
/* Title div */
|
||||
.productTitle {
|
||||
grid-area: title;
|
||||
}
|
||||
|
||||
/* Price div */
|
||||
.productPrice {
|
||||
grid-area: price;
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
/* Price text */
|
||||
.productPrice * {
|
||||
}
|
||||
|
||||
/* Description div */
|
||||
.productDescription {
|
||||
grid-area: description;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,20 @@
|
||||
<meta charset="UTF-8">
|
||||
<p class="productItem" *ngFor="let product of products" (click)="clickedProduct(product)">
|
||||
{{product.name}}
|
||||
</p>
|
||||
<div *ngIf="showProductPicture">
|
||||
Test
|
||||
<div class="productItem" *ngFor="let product of products" (click)="clickedProduct(product)">
|
||||
<div class="productImageContainer" *ngIf="showProductPicture===true">
|
||||
<img class="productImage" src="https://www.mueller-patrick.tech/betterzon/images/{{product.image_guid}}.jpg"/>
|
||||
</div>
|
||||
<div class="productTitle">
|
||||
<b>{{product.name}}</b>
|
||||
</div>
|
||||
<div class="productPrice">
|
||||
5€
|
||||
</div>
|
||||
<div class="productDescription">
|
||||
<div *ngIf="product.short_description.length > 300">
|
||||
{{product.short_description.substring(0, 300) + "..."}}
|
||||
</div>
|
||||
<div *ngIf="product.short_description.length <= 300">
|
||||
{{product.short_description}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -12,6 +12,7 @@ export class ProductListComponent implements OnInit {
|
||||
products: Product[];
|
||||
@Input() numberOfProducts: number;
|
||||
@Input() showProductPicture: boolean;
|
||||
type: string;
|
||||
|
||||
constructor(
|
||||
private apiService: ApiService,
|
||||
@@ -28,6 +29,7 @@ export class ProductListComponent implements OnInit {
|
||||
if (!this.showProductPicture) {
|
||||
this.showProductPicture = false;
|
||||
}
|
||||
this.type = 'PLP';
|
||||
}
|
||||
|
||||
getProducts(): void {
|
||||
@@ -35,7 +37,7 @@ export class ProductListComponent implements OnInit {
|
||||
}
|
||||
|
||||
clickedProduct(product: Product): void {
|
||||
this.router.navigate([('/helloworld/' + product.product_id)]);
|
||||
this.router.navigate([('/product/' + product.product_id)]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user