mirror of
https://github.com/akveo/ngx-admin.git
synced 2025-12-17 16:00:14 +01:00
feat: add product hunt banner (#2003)
This commit is contained in:
parent
f719641e6d
commit
0cf96be6d8
13 changed files with 205 additions and 126 deletions
82
docs/app/pages/home/banner/banner.component.scss
Normal file
82
docs/app/pages/home/banner/banner.component.scss
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
/**
|
||||||
|
* @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';
|
||||||
|
|
||||||
|
:host {
|
||||||
|
position: fixed;
|
||||||
|
@include nb-ltr(right, 10px);
|
||||||
|
@include nb-rtl(left, 10px);
|
||||||
|
top: 80px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background-color: #dc5425;
|
||||||
|
box-shadow: 0 2px 4px 0 rgba(189, 93, 60, 0.54);
|
||||||
|
z-index: 99999999;
|
||||||
|
|
||||||
|
.heading-with-icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
height: auto;
|
||||||
|
width: 77px;
|
||||||
|
margin: 0 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner-heading {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin: 0;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner-content {
|
||||||
|
padding-top: 36px;
|
||||||
|
padding-bottom: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-button {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-bottom: auto;
|
||||||
|
padding: 10px;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nb-close {
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta {
|
||||||
|
margin: 8px 0 0;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-link {
|
||||||
|
font-size: 10px;
|
||||||
|
border-radius: 2px;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 4px 16px;
|
||||||
|
margin: 0 10px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 700;
|
||||||
|
background: #ffffff;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 991px) {
|
||||||
|
top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
63
docs/app/pages/home/banner/banner.component.ts
Normal file
63
docs/app/pages/home/banner/banner.component.ts
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Akveo. All Rights Reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component, HostBinding, Inject, OnInit } from '@angular/core';
|
||||||
|
import { NB_WINDOW } from '@nebular/theme';
|
||||||
|
|
||||||
|
const HIDE_BANNER_KEY = 'HIDE_PRODUCT_HUNT_BANNER';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'ngx-release-banner',
|
||||||
|
template: `
|
||||||
|
<div class="heading-with-icon">
|
||||||
|
<img class="icon" src="/assets/img/product-hunt-cat.png" alt="Product Hunt">
|
||||||
|
<div class="banner-content">
|
||||||
|
<h2 class="banner-heading">ngx-admin is on Product Hunt today!</h2>
|
||||||
|
<p class="cta">Please
|
||||||
|
<a class="cta-link"
|
||||||
|
href="https://www.producthunt.com/posts/ngx-admin"
|
||||||
|
target="_blank">
|
||||||
|
share
|
||||||
|
</a>
|
||||||
|
your feedback :)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<button class="close-button" aria-label="close" (click)="closeBanner()">
|
||||||
|
<span class="nb-close"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
styleUrls: ['./banner.component.scss'],
|
||||||
|
})
|
||||||
|
export class BannerComponent implements OnInit {
|
||||||
|
|
||||||
|
storage: Storage;
|
||||||
|
|
||||||
|
@HostBinding('attr.hidden')
|
||||||
|
isHidden: true | null = null;
|
||||||
|
|
||||||
|
@HostBinding('attr.dir')
|
||||||
|
dir = 'ltr';
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@Inject(NB_WINDOW) private window,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.storage = this.window.localStorage;
|
||||||
|
|
||||||
|
this.isHidden = this.storage && this.storage.getItem(HIDE_BANNER_KEY)
|
||||||
|
? true
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
closeBanner() {
|
||||||
|
if (this.storage) {
|
||||||
|
this.storage.setItem(HIDE_BANNER_KEY, 'true');
|
||||||
|
}
|
||||||
|
this.isHidden = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
<nb-layout-column>
|
<nb-layout-column>
|
||||||
<ngx-landing-sections-container></ngx-landing-sections-container>
|
<ngx-landing-sections-container></ngx-landing-sections-container>
|
||||||
<ngx-landing-ribbon></ngx-landing-ribbon>
|
<ngx-release-banner></ngx-release-banner>
|
||||||
</nb-layout-column>
|
</nb-layout-column>
|
||||||
|
|
||||||
<nb-layout-footer class="footer" fixed>
|
<nb-layout-footer class="footer" fixed>
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import { ContactSectionComponent } from './contact-section/contact-section.compo
|
||||||
import { OurProjectsSectionComponent } from './our-projects-section/our-projects-section.component';
|
import { OurProjectsSectionComponent } from './our-projects-section/our-projects-section.component';
|
||||||
import { LandingHomeRoutingModule } from './landing-home-routing.module';
|
import { LandingHomeRoutingModule } from './landing-home-routing.module';
|
||||||
import { NgxLandingSectionsContainerComponent } from './sections-container/ngx-landing-sections-container.component';
|
import { NgxLandingSectionsContainerComponent } from './sections-container/ngx-landing-sections-container.component';
|
||||||
import { RibbonComponent } from './ribbon/ribbon.component';
|
import { BannerComponent } from './banner/banner.component';
|
||||||
// components
|
// components
|
||||||
|
|
||||||
const COMPONENTS = [
|
const COMPONENTS = [
|
||||||
|
|
@ -37,7 +37,7 @@ const COMPONENTS = [
|
||||||
OurProjectsSectionComponent,
|
OurProjectsSectionComponent,
|
||||||
SocialSectionComponent,
|
SocialSectionComponent,
|
||||||
ContactSectionComponent,
|
ContactSectionComponent,
|
||||||
RibbonComponent,
|
BannerComponent,
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
<div class="ribbon-dont-hunt">
|
|
||||||
<svg style="padding-right:8px;" width="30" height="30" viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<g fill="none" fill-rule="evenodd">
|
|
||||||
<path d="M40 20c0 11.046-8.954 20-20 20S0 31.046 0 20 8.954 0 20 0s20 8.954 20 20" fill="#DA552F"></path>
|
|
||||||
<path d="M22.667 20H17v-6h5.667a3 3 0 0 1 0 6m0-10H13v20h4v-6h5.667a7 7 0 1 0 0-14" fill="#FFF"></path>
|
|
||||||
</g>
|
|
||||||
</svg>Please, don't hunt me!
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
.ribbon-dont-hunt {
|
|
||||||
display: inline-flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
font-weight: 700;
|
|
||||||
font-size: 11px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
|
||||||
width: 300px;
|
|
||||||
color: rgb(218, 85, 47);
|
|
||||||
background: rgb(255, 255, 255);
|
|
||||||
position: fixed;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 40px;
|
|
||||||
transform: rotate(40deg);
|
|
||||||
box-shadow: rgba(50, 69, 93, 0.15) 0px 4px 7px 0px, rgba(0, 0, 0, 0.08) 0px -1px 4px 0px;
|
|
||||||
top: 55px;
|
|
||||||
right: -60px;
|
|
||||||
}
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
/**
|
|
||||||
* @license
|
|
||||||
* Copyright Akveo. All Rights Reserved.
|
|
||||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import { Component } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'ngx-landing-ribbon',
|
|
||||||
templateUrl: './ribbon.component.html',
|
|
||||||
styleUrls: ['./ribbon.component.scss'],
|
|
||||||
})
|
|
||||||
export class RibbonComponent {
|
|
||||||
}
|
|
||||||
BIN
docs/assets/img/product-hunt-cat.png
Normal file
BIN
docs/assets/img/product-hunt-cat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
|
|
@ -1,26 +0,0 @@
|
||||||
@import '../../styles/themes';
|
|
||||||
|
|
||||||
@mixin ngx-release-banner-component {
|
|
||||||
ngx-release-banner {
|
|
||||||
background-color: nb-theme(release-banner-bg);
|
|
||||||
color: nb-theme(release-banner-fg);
|
|
||||||
|
|
||||||
.heading-with-icon {
|
|
||||||
border-bottom-color: nb-theme(release-banner-separator);
|
|
||||||
}
|
|
||||||
|
|
||||||
.banner-heading,
|
|
||||||
.close-button {
|
|
||||||
color: nb-theme(release-banner-fg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.cta {
|
|
||||||
color: nb-theme(release-banner-cta);
|
|
||||||
}
|
|
||||||
|
|
||||||
.cta-link {
|
|
||||||
background: nb-theme(release-banner-fg);
|
|
||||||
color: nb-theme(release-banner-bg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,32 +1,43 @@
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Akveo. All Rights Reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*/
|
||||||
|
|
||||||
@import '../../styles/themes';
|
@import '../../styles/themes';
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
@include nb-ltr(right, 1.5rem);
|
@include nb-ltr(right, 1.5rem);
|
||||||
@include nb-rtl(left, 1.5rem);
|
@include nb-rtl(left, 1.5rem);
|
||||||
top: 40vh;
|
top: 20vh;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
box-shadow: 0 5px 12px 0 rgba(0, 32, 128, 0.14);
|
background-color: #dc5425;
|
||||||
|
box-shadow: 0 2px 4px 0 rgba(189, 93, 60, 0.54);
|
||||||
z-index: 99999999;
|
z-index: 99999999;
|
||||||
|
|
||||||
.heading-with-icon {
|
.heading-with-icon {
|
||||||
border-bottom-width: 1px;
|
|
||||||
border-bottom-style: solid;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
height: auto;
|
height: auto;
|
||||||
width: 4rem;
|
width: 77px;
|
||||||
margin: 0 1.625rem;
|
margin: 0 26px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.banner-heading {
|
.banner-heading {
|
||||||
font-size: 1.5rem;
|
font-size: 14px;
|
||||||
line-height: 1.5;
|
line-height: 20px;
|
||||||
font-weight: 600;
|
font-weight: 700;
|
||||||
margin: 1.625rem 0;
|
margin: 0;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner-content {
|
||||||
|
padding-top: 36px;
|
||||||
|
padding-bottom: 36px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.close-button {
|
.close-button {
|
||||||
|
|
@ -34,29 +45,34 @@
|
||||||
border: none;
|
border: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-bottom: auto;
|
margin-bottom: auto;
|
||||||
padding: 0.625rem;
|
padding: 10px;
|
||||||
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nb-close {
|
.nb-close {
|
||||||
font-size: 1.5rem;
|
font-size: 24px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cta {
|
.cta {
|
||||||
margin: 0;
|
margin: 8px 0 0;
|
||||||
text-align: center;
|
font-size: 14px;
|
||||||
|
color: #ffffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cta-link {
|
.cta-link {
|
||||||
border-radius: 1.8px;
|
font-size: 10px;
|
||||||
|
border-radius: 2px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0.5rem 1rem;
|
padding: 4px 16px;
|
||||||
margin: 0.725rem 0.8rem;
|
margin: 0 10px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-weight: 600;
|
font-weight: 700;
|
||||||
|
background: #ffffff;
|
||||||
|
color: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 63rem) {
|
@media screen and (max-width: 767px) {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,40 @@
|
||||||
import { Component, HostBinding, Inject, OnDestroy, OnInit } from '@angular/core';
|
/**
|
||||||
import { NB_WINDOW, NbThemeService } from '@nebular/theme';
|
* @license
|
||||||
import { takeWhile } from 'rxjs/operators';
|
* Copyright Akveo. All Rights Reserved.
|
||||||
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||||
|
*/
|
||||||
|
|
||||||
const HIDE_BANNER_KEY = 'HIDE_RELEASE_2_BANNER';
|
import { Component, HostBinding, Inject, OnInit } from '@angular/core';
|
||||||
|
import { NB_WINDOW } from '@nebular/theme';
|
||||||
|
|
||||||
|
const HIDE_BANNER_KEY = 'HIDE_PRODUCT_HUNT_BANNER';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ngx-release-banner',
|
selector: 'ngx-release-banner',
|
||||||
template: `
|
template: `
|
||||||
<div class="heading-with-icon">
|
<div class="heading-with-icon">
|
||||||
<img class="icon" [src]="getBellPath()" alt="bell">
|
<img class="icon" src="/assets/images/product-hunt-cat.png" alt="Product Hunt">
|
||||||
<h1 class="banner-heading">Nebular 3.0 stable <br> with 30+ components is out!</h1>
|
<div class="banner-content">
|
||||||
|
<h2 class="banner-heading">ngx-admin is on Product Hunt today!</h2>
|
||||||
|
<p class="cta">Please
|
||||||
|
<a class="cta-link"
|
||||||
|
href="https://www.producthunt.com/posts/ngx-admin"
|
||||||
|
target="_blank">
|
||||||
|
share
|
||||||
|
</a>
|
||||||
|
your feedback :)
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
<button class="close-button" aria-label="close" (click)="closeBanner()">
|
<button class="close-button" aria-label="close" (click)="closeBanner()">
|
||||||
<span class="nb-close"></span>
|
<span class="nb-close"></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<p class="cta">
|
|
||||||
Don't forget to
|
|
||||||
<a class="cta-link"
|
|
||||||
href="https://akveo.github.io/nebular?utm_source=ngx-admin-demo&utm_medium=banner"
|
|
||||||
target="_blank">
|
|
||||||
check out
|
|
||||||
</a>
|
|
||||||
and star our repo :)
|
|
||||||
</p>
|
|
||||||
`,
|
`,
|
||||||
styleUrls: ['./banner.component.scss'],
|
styleUrls: ['./banner.component.scss'],
|
||||||
})
|
})
|
||||||
export class BannerComponent implements OnInit, OnDestroy {
|
export class BannerComponent implements OnInit {
|
||||||
|
|
||||||
private alive = true;
|
|
||||||
storage: Storage;
|
storage: Storage;
|
||||||
isDarkTheme: boolean;
|
|
||||||
|
|
||||||
@HostBinding('attr.hidden')
|
@HostBinding('attr.hidden')
|
||||||
isHidden: true | null = null;
|
isHidden: true | null = null;
|
||||||
|
|
@ -40,7 +44,6 @@ export class BannerComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(NB_WINDOW) private window,
|
@Inject(NB_WINDOW) private window,
|
||||||
private themeService: NbThemeService,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
|
@ -49,11 +52,6 @@ export class BannerComponent implements OnInit, OnDestroy {
|
||||||
this.isHidden = this.storage && this.storage.getItem(HIDE_BANNER_KEY)
|
this.isHidden = this.storage && this.storage.getItem(HIDE_BANNER_KEY)
|
||||||
? true
|
? true
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
this.isDarkTheme = this.themeService.currentTheme === 'cosmic';
|
|
||||||
this.themeService.onThemeChange()
|
|
||||||
.pipe(takeWhile(() => this.alive))
|
|
||||||
.subscribe(({ name }) => this.isDarkTheme = name === 'cosmic');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
closeBanner() {
|
closeBanner() {
|
||||||
|
|
@ -62,12 +60,4 @@ export class BannerComponent implements OnInit, OnDestroy {
|
||||||
}
|
}
|
||||||
this.isHidden = true;
|
this.isHidden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getBellPath() {
|
|
||||||
return `assets/images/bell${this.isDarkTheme ? '' : '-white'}.svg`;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.alive = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,6 @@
|
||||||
|
|
||||||
@import './bootstrap-rtl';
|
@import './bootstrap-rtl';
|
||||||
|
|
||||||
@import '../components/banner/banner.component.theme';
|
|
||||||
|
|
||||||
// install the framework and custom global styles
|
// install the framework and custom global styles
|
||||||
@include nb-install() {
|
@include nb-install() {
|
||||||
|
|
||||||
|
|
@ -28,8 +26,6 @@
|
||||||
// loading progress bar
|
// loading progress bar
|
||||||
@include ngx-pace-theme();
|
@include ngx-pace-theme();
|
||||||
|
|
||||||
@include ngx-release-banner-component();
|
|
||||||
|
|
||||||
// fixed in rc.9 and can be removed after upgrade
|
// fixed in rc.9 and can be removed after upgrade
|
||||||
.custom-control .custom-control-indicator {
|
.custom-control .custom-control-indicator {
|
||||||
border-radius: 50%; // TODO: quickfix for https://github.com/akveo/nebular/issues/275
|
border-radius: 50%; // TODO: quickfix for https://github.com/akveo/nebular/issues/275
|
||||||
|
|
|
||||||
BIN
src/assets/images/product-hunt-cat.png
Normal file
BIN
src/assets/images/product-hunt-cat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Loading…
Add table
Add a link
Reference in a new issue