feat(demo): add landing page with docs (#1951)

This commit is contained in:
Dmitry Nehaychik 2018-12-26 15:17:57 +03:00 committed by Sergey Andrievskiy
parent 67c9587b87
commit 43cc3a1556
190 changed files with 15425 additions and 21 deletions

View file

@ -0,0 +1,46 @@
<ngx-landing-section-title>
What ngx-lovers are saying?
</ngx-landing-section-title>
<div class="carousel-container">
<div class="swiper-container reviews" [swiper]="swiperConfig">
<div class="swiper-wrapper">
<div *ngFor="let review of reviews" class="review-card swiper-slide">
<div class="header-card">
<div class="social-icon">
<i [innerHTML]="review.socialIcon | eva: { width: 26, height: 26, fill: '#3b5998' }"></i>
</div>
<div class="avatar">
<img alt="Reviewer Avatar"
data-src="{{ review.avatar }}"
class="swiper-lazy"/>
</div>
<div class="personal-info">
<div class="name">{{ review.firstName }}</div>
<div class="surname">{{ review.lastName }}</div>
</div>
</div>
<div class="body-card">
{{ review.review }}
</div>
<div class="footer-card">
<a class="go-to-button"
href="{{ review.link }}"
target="_blank">
Go to comment
<i [innerHTML]="'arrow-ios-forward' | eva: { width: 24, height: 24, fill: '#e5e5e5' }"></i>
</a>
</div>
</div>
</div>
<div class="swiper-pagination"></div>
<div class="swiper-button-prev">
<i [innerHTML]="'arrow-ios-back' | eva: { width: 36, height: 36, fill: '#00db92' }"></i>
</div>
<div class="swiper-button-next">
<i [innerHTML]="'arrow-ios-forward' | eva: { width: 36, height: 36, fill: '#00db92' }"></i>
</div>
</div>
</div>

View file

@ -0,0 +1,184 @@
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
@import '../../../@theme/styles/themes';
@import '~@nebular/theme/styles/global/breakpoints';
@include nb-install-component() {
display: block;
padding-top: 6rem;
padding-bottom: 7.875rem;
.carousel-container {
position: relative;
}
.reviews {
max-width: 55.125rem;
display: flex;
margin: 0 auto;
margin-top: 4.625rem;
}
.review-card {
background-color: #ffffff;
box-shadow: nb-theme(shadow-default);
&:first-child {
margin-left: 0;
}
.header-card {
display: flex;
position: relative;
padding-top: 1rem;
padding-left: 1rem;
padding-right: 3.125rem;
overflow: hidden;
}
.social-icon {
position: absolute;
right: 1.375rem;
top: 1.875rem;
}
.avatar {
max-width: 3.375rem;
height: 3.375rem;
border-radius: 50%;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
.personal-info {
font-family: nb-theme(font-main), sans-serif;
margin-left: 1.25rem;
margin-top: 0.5rem;
color: #000000;
word-break: break-all;
}
.body-card {
font-family: nb-theme(font-secondary), sans-serif;
color: #000000;
padding: 0 1rem;
margin-top: 1.75rem;
line-height: 1.8;
height: 10.375rem;
}
.footer-card {
border-top: 1px solid #eaeaea;
}
}
.go-to-button {
display: block;
font-family: nb-theme(font-main), sans-serif;
color: nb-theme(color-active-fg);
padding: 1rem;
cursor: pointer;
position: relative;
text-decoration: none;
i {
position: absolute;
right: 1.375rem;
top: 1rem;
}
}
.swiper-container {
position: static;
}
.swiper-button-prev, .swiper-button-next {
display: flex;
justify-content: center;
align-items: center;
background-image: none;
height: 5rem;
width: 5rem;
border-radius: 50%;
background-color: #ffffff;
box-shadow: nb-theme(shadow-default);
top: 9rem;
&:hover {
box-shadow: nb-theme(shadow-hover-btn);
}
&:active {
box-shadow: nb-theme(shadow-active-btn);
}
}
.swiper-button-prev {
left: 8.125rem;
}
.swiper-button-next {
right: 8.125rem;
}
.swiper-pagination {
top: 110%;
/deep/ span {
height: 0.75rem;
width: 0.75rem;
opacity: 0.08;
background-color: #000000;
&.swiper-pagination-bullet-active {
opacity: 1;
background: nb-theme(color-active-bg);
}
}
}
@include media-breakpoint-down(xl) {
.swiper-button-prev {
left: 5%;
}
.swiper-button-next {
right: 5%;
}
}
@include media-breakpoint-down(lg) {
.swiper-button-prev, .swiper-button-next {
display: none;
}
}
@include media-breakpoint-down(is) {
padding-top: 4rem;
padding-bottom: 4.375rem;
.reviews {
margin-top: 2.25rem;
}
.swiper-pagination {
top: 108%;
}
.swiper-button-prev, .swiper-button-next {
display: none;
}
.swiper-slide {
width: 80%;
}
}
}

View file

@ -0,0 +1,99 @@
/**
* @license
* Copyright Akveo. All Rights Reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*/
import { Component, OnDestroy } from '@angular/core';
import { SwiperConfigInterface } from 'ngx-swiper-wrapper';
import { NbMediaBreakpointsService, NbThemeService } from '@nebular/theme';
import { takeWhile } from 'rxjs/operators';
import { Review, ReviewsService } from '../../../@core/data/service/reviews.service';
@Component({
selector: 'ngx-landing-reviews-section',
templateUrl: './reviews-section.component.html',
styleUrls: ['./reviews-section.component.scss'],
})
export class ReviewsSectionComponent implements OnDestroy {
private alive = true;
private desktopSwiperConfig: SwiperConfigInterface = {
slidesPerView: 3,
keyboard: true,
navigation: true,
};
private tabletSwiperConfig: SwiperConfigInterface = {
...this.desktopSwiperConfig,
slidesPerView: 2,
};
private mobileSwiperConfig: SwiperConfigInterface = {
slidesPerView: 'auto',
centeredSlides: true,
keyboard: false,
navigation: false,
};
swiperConfig: SwiperConfigInterface = {
direction: 'horizontal',
spaceBetween: 24,
mousewheel: false,
lazy: true,
loop: true,
autoplay: true,
pagination: {
el: '.swiper-pagination',
clickable: true,
hideOnClick: false,
},
};
breakpoints: any;
reviews: Review[];
constructor(private themeService: NbThemeService,
private breakpointService: NbMediaBreakpointsService,
private reviewsService: ReviewsService) {
this.breakpoints = this.breakpointService.getBreakpointsMap();
this.themeService.onMediaQueryChange()
.pipe(takeWhile(() => this.alive))
.subscribe(([oldValue, newValue]) => {
this.changeSwiperConfig(newValue.width);
});
this.reviewsService.getReviews()
.pipe(takeWhile(() => this.alive))
.subscribe((reviews) => this.reviews = reviews);
}
changeSwiperConfig(currentWidth: number): void {
if (this.isMobile(currentWidth)) {
this.swiperConfig = {
...this.swiperConfig,
...this.mobileSwiperConfig,
};
} else {
const desktopOrTabletConfig = this.isTablet(currentWidth) ? this.tabletSwiperConfig : this.desktopSwiperConfig;
this.swiperConfig = {
...this.swiperConfig,
...desktopOrTabletConfig,
};
}
}
private isMobile(currentWidth: number): boolean {
return currentWidth <= this.breakpoints.is;
}
private isTablet(currentWidth: number): boolean {
return currentWidth <= this.breakpoints.sm;
}
ngOnDestroy() {
this.alive = false;
}
}