feat: add product overview component with styling and product listing

This commit is contained in:
itsscb 2025-03-10 21:03:03 +01:00
parent 765e0ae521
commit a5fcb20296
4 changed files with 195 additions and 0 deletions

View File

@ -0,0 +1,97 @@
.container {
display: flex;
column-gap: 2rem;
row-gap: 2rem;
flex-wrap: wrap;
justify-content: space-around;
margin-top: 20px;
color: var(--primary-text-color);
max-width: 25rem;
}
.item {
width: 25rem;
flex-shrink: 0;
}
li > p {
margin: 0;
}
h3 {
font-weight: 600;
font-size: 1.5rem;
}
h2 {
font-weight: 600;
font-size: 1.2rem;
}
h3, h2 {
margin: 0;
}
.product-header {
display: flex;
flex-direction: row;
justify-content: space-between;
column-gap: 0.5rem;
align-items: center;
}
.product-info {
position: relative;
cursor: pointer;
}
.info-box {
display: none;
position: absolute;
right: 0;
top: 100%;
width: 300px;
background-color: #333;
color: var(--primary-text-color);
padding: 1rem;
border-radius: 0.5rem;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
z-index: 10;
white-space: pre-line;
text-align: left;
font-size: 0.9rem;
}
.product-info:hover .info-box {
display: block;
}
.product {
background-color: #1a1a1a;
width: 100%;
padding-top: 0.8rem;
padding-bottom: 0.8rem;
border-radius: 0.5rem;
}
.product-light {
background-color: rgba(132, 129, 122, 1.0);
}
.product-standard {
background-color: rgba(33, 140, 116, 1.0);
}
.product-premium {
background-color: rgba(34, 112, 147, 1.0);
}
.item > ul > li {
list-style-type: none;
text-align: start;
display: flex;
flex-direction: row;
justify-content: start;
align-items: center;
column-gap: 1rem;
}

View File

@ -0,0 +1,39 @@
<div class="container">
<div class="item" *ngFor="let product of products">
<div class="product-header">
<div class="product" [ngClass]="product.class">
<h3>{{ product.name }}</h3>
<h2>{{ product.price }} Euro / einmalig</h2>
</div>
<div class="product-info">
<svg xmlns="http://www.w3.org/2000/svg" height="2rem" viewBox="0 -960 960 960" width="2rem"
fill="rgba(51, 217, 178,1.0)">
<path d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/>
</svg>
<div class="info-box" *ngIf="product.info">
{{ product.info }}
</div>
</div>
<!-- <div class="product-info">-->
<!-- <svg xmlns="http://www.w3.org/2000/svg" height="2rem" viewBox="0 -960 960 960" width="2rem"-->
<!-- fill="rgba(51, 217, 178,1.0)">-->
<!-- <path d="M440-280h80v-240h-80v240Zm40-320q17 0 28.5-11.5T520-640q0-17-11.5-28.5T480-680q-17 0-28.5 11.5T440-640q0 17 11.5 28.5T480-600Zm0 520q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/>-->
<!-- </svg>-->
<!-- &lt;!&ndash; <p>{{ product.info }}</p>&ndash;&gt;-->
<!-- </div>-->
</div>
<ul>
<li *ngFor="let feature of product.features">
<svg xmlns="http://www.w3.org/2000/svg" height="2rem" viewBox="0 -960 960 960" width="2rem"
fill="rgba(64, 64, 122,1.0)">
<path d="m424-296 282-282-56-56-226 226-114-114-56 56 170 170Zm56 216q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/>
</svg>
<!-- <img src="/public/assets/digitaler-frieden_logo.svg" style="width: 2rem; height: 2rem;">-->
<p>
{{ feature }}
</p>
<!-- </div>-->
</li>
</ul>
</div>
</div>

View File

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ProductOverviewComponent } from './product-overview.component';
describe('ProductOverviewComponent', () => {
let component: ProductOverviewComponent;
let fixture: ComponentFixture<ProductOverviewComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ProductOverviewComponent]
})
.compileComponents();
fixture = TestBed.createComponent(ProductOverviewComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,36 @@
import {Component} from '@angular/core';
import {NgClass, NgForOf, NgIf} from "@angular/common";
@Component({
selector: 'atomic-product-overview',
imports: [
NgForOf,
NgClass,
NgIf
],
templateUrl: './product-overview.component.html',
styleUrl: './product-overview.component.css'
})
export class ProductOverviewComponent {
products: any[] = [
{name: 'Light', price: 119, features: ['Abfrage bei 100 Anbietern'], info: '', class: 'product-light'},
{
name: 'Standard',
price: 179,
features: ['Abfrage bei 300 Anbietern', 'Abfrage bei Banken'],
info: '',
class: 'product-standard'
},
{
name: 'Premium Plus',
price: 199,
features: ['Abfrage bei 400 Anbietern', 'Abfrage bei Banken', 'Löschen von Personenbezogenen Daten', 'Löschen von E-Mail Adressen aus E-Mail Verteilern', 'MyDF Dashboard'],
info: 'Wir suchen bei über 400 Anbietern nach Anmeldungen/Konten oder Registrierungen im Auftrag der Erben von Verstorbenen.\n' +
'Eine Übersicht über den aktuellen Stand sehen Sie in Ihrem MYDF-Dashboard.\n' +
'Dieses listet Ihnen alle gefundenen Anbieter mit Interaktion auf.\n' +
'Per Klick einfach und übersichtlich Spuren löschen.\n' +
'KEINE WERBUNG mehr nach Jahren. KEINE STÖRUNG.'
, class: 'product-premium'
},
];
}