Merge pull request #22 from HideyoshiNakazone/devel
Devel - Implements Cookie Consent Popup
This commit is contained in:
@@ -32,11 +32,13 @@
|
||||
"styles": [
|
||||
"src/styles.css",
|
||||
"node_modules/bootstrap/dist/css/bootstrap.min.css",
|
||||
"node_modules/normalize.css/normalize.css"
|
||||
"node_modules/normalize.css/normalize.css",
|
||||
"node_modules/cookieconsent/build/cookieconsent.min.css"
|
||||
],
|
||||
"scripts": [
|
||||
"node_modules/jquery/dist/jquery.min.js",
|
||||
"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"
|
||||
"node_modules/bootstrap/dist/js/bootstrap.bundle.min.js",
|
||||
"node_modules/cookieconsent/build/cookieconsent.min.js"
|
||||
],
|
||||
"serviceWorker": true,
|
||||
"ngswConfigPath": "ngsw-config.json"
|
||||
|
||||
34
package-lock.json
generated
34
package-lock.json
generated
@@ -25,9 +25,12 @@
|
||||
"@fortawesome/free-regular-svg-icons": "^6.1.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.1.1",
|
||||
"bootstrap": "^4.6.2",
|
||||
"cookieconsent": "^3.1.1",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.18.1",
|
||||
"jquery": "^3.6.0",
|
||||
"ngx-cookie-service": "^16.0.1",
|
||||
"ngx-cookieconsent": "^4.0.2",
|
||||
"normalize.css": "^8.0.1",
|
||||
"rxjs": "~7.5.0",
|
||||
"ts-interface-checker": "^1.0.2",
|
||||
@@ -6711,6 +6714,11 @@
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
|
||||
},
|
||||
"node_modules/cookieconsent": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/cookieconsent/-/cookieconsent-3.1.1.tgz",
|
||||
"integrity": "sha512-v8JWLJcI7Zs9NWrs8hiVldVtm3EBF70TJI231vxn6YToBGj0c9dvdnYwltydkAnrbBMOM/qX1xLFrnTfm5wTag=="
|
||||
},
|
||||
"node_modules/copy-anything": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz",
|
||||
@@ -11381,6 +11389,32 @@
|
||||
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ngx-cookie-service": {
|
||||
"version": "16.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ngx-cookie-service/-/ngx-cookie-service-16.0.1.tgz",
|
||||
"integrity": "sha512-q8i5eX2b6SIIZcu9wy+lvOU65cLJhHD9EVz5TGGkKi8Y7X/aZbUyQ9U4CgNOfKDWtPUDFOMD8IW/cijoVKe59Q==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^16.0.0",
|
||||
"@angular/core": "^16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ngx-cookieconsent": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/ngx-cookieconsent/-/ngx-cookieconsent-4.0.2.tgz",
|
||||
"integrity": "sha512-KREGRd53LV0SrFlJsk1XwgzZIEf7GAeLD3/znYF/CzTYml+SFqWrYleXA3aMtFLGqUHwbGS/fMA6cHwpvxT5JA==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@angular/common": ">=14.0.0",
|
||||
"@angular/core": ">=14.0.0",
|
||||
"cookieconsent": "^3.1.1",
|
||||
"rxjs": "^7.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nice-napi": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/nice-napi/-/nice-napi-1.0.2.tgz",
|
||||
|
||||
@@ -32,9 +32,12 @@
|
||||
"@fortawesome/free-regular-svg-icons": "^6.1.1",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.1.1",
|
||||
"bootstrap": "^4.6.2",
|
||||
"cookieconsent": "^3.1.1",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.18.1",
|
||||
"jquery": "^3.6.0",
|
||||
"ngx-cookie-service": "^16.0.1",
|
||||
"ngx-cookieconsent": "^4.0.2",
|
||||
"normalize.css": "^8.0.1",
|
||||
"rxjs": "~7.5.0",
|
||||
"ts-interface-checker": "^1.0.2",
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import {Component, OnDestroy, OnInit} from '@angular/core';
|
||||
import { AuthService } from './shared/auth/auth.service';
|
||||
import {UpdateService} from "./shared/service-worker/update.service";
|
||||
import {
|
||||
NgcCookieConsentService,
|
||||
NgcInitializationErrorEvent,
|
||||
NgcInitializingEvent,
|
||||
NgcNoCookieLawEvent, NgcStatusChangeEvent
|
||||
} from "ngx-cookieconsent";
|
||||
import {Subscription} from "rxjs";
|
||||
import {CookieConsertService} from "./shared/cookie-consent/cookie-consert.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@@ -11,12 +19,34 @@ export class AppComponent implements OnInit {
|
||||
|
||||
title = 'frontend-hideyoshi.com';
|
||||
|
||||
constructor(private authService: AuthService, private serviceWorker: UpdateService) {
|
||||
cookieStatusChangeSubscription!: Subscription;
|
||||
|
||||
constructor(
|
||||
private authService: AuthService,
|
||||
private ccService: NgcCookieConsentService,
|
||||
private cookieConsentService: CookieConsertService,
|
||||
private serviceWorker: UpdateService) {
|
||||
this.serviceWorker.checkForUpdates();
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.authService.autoLogin();
|
||||
|
||||
let cookieConsentStatus = this.cookieConsentService.getCookieConsentStatusFromLocalStorage();
|
||||
|
||||
if (cookieConsentStatus) {
|
||||
this.ccService.fadeOut();
|
||||
}
|
||||
|
||||
this.cookieStatusChangeSubscription = this.ccService.statusChange$.subscribe(
|
||||
(event: NgcStatusChangeEvent) => {
|
||||
if (event.status === 'allow') {
|
||||
this.cookieConsentService.consent();
|
||||
} else if (event.status === 'deny') {
|
||||
this.cookieConsentService.decline();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,13 +46,19 @@
|
||||
<div class="col-lg-6 authentication-body">
|
||||
<button mat-button
|
||||
class="oauth-button d-flex justify-content-center align-items-center"
|
||||
[disabled]="isCookieBlocked"
|
||||
(click)="onGoogleLogin()">
|
||||
<mat-icon style="width: 50px; height:30px"
|
||||
<mat-icon *ngIf="!isCookieBlocked"
|
||||
style="width: 50px; height:30px"
|
||||
svgIcon="google-logo"></mat-icon>
|
||||
<mat-icon *ngIf="isCookieBlocked"
|
||||
style="width: 50px; height:30px"
|
||||
svgIcon="google-disabled-logo"></mat-icon>
|
||||
Login With Google
|
||||
</button>
|
||||
<button mat-button
|
||||
class="oauth-button d-flex justify-content-center align-items-center"
|
||||
[disabled]="isCookieBlocked"
|
||||
(click)="onGithubLogin()">
|
||||
<mat-icon style="width: 50px; height:30px"
|
||||
svgIcon="github-logo"></mat-icon>
|
||||
|
||||
@@ -12,9 +12,12 @@ import { User } from 'src/app/shared/model/user/user.model';
|
||||
import {animate, animateChild, group, query, state, style, transition, trigger} from "@angular/animations";
|
||||
import {ValidatePasswordValidator} from "../../../shared/validators/validate-password.validator";
|
||||
import {ValidateNotEmptyValidator} from "../../../shared/validators/validate-not-empty.validator";
|
||||
import {NgcCookieConsentService, NgcStatusChangeEvent} from "ngx-cookieconsent";
|
||||
import {CookieConsertService} from "../../../shared/cookie-consent/cookie-consert.service";
|
||||
|
||||
|
||||
const GOOGLE_LOGO_SVG = "assets/img/providers/google.svg";
|
||||
const GOOGLE_DISABLED_LOGO_SVG = "assets/img/providers/google-disabled.svg";
|
||||
const GITHUB_LOGO_SVG = "assets/img/providers/github.svg";
|
||||
|
||||
@Component({
|
||||
@@ -100,8 +103,12 @@ export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
authSubject!: Subscription;
|
||||
|
||||
cookieStatusChangeSubscription!: Subscription;
|
||||
|
||||
errorMessage!: string | null;
|
||||
|
||||
isCookieBlocked = false;
|
||||
|
||||
isShowErrorMessage = false;
|
||||
|
||||
_userIcon = faUser;
|
||||
@@ -110,6 +117,8 @@ export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
constructor(
|
||||
private authService: AuthService,
|
||||
private ccService: NgcCookieConsentService,
|
||||
private cookieConsentService: CookieConsertService,
|
||||
private changeDetectorRef: ChangeDetectorRef,
|
||||
private matIconRegistry: MatIconRegistry,
|
||||
private domSanitizer: DomSanitizer) {
|
||||
@@ -117,6 +126,10 @@ export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
"google-logo",
|
||||
this.domSanitizer.bypassSecurityTrustResourceUrl(GOOGLE_LOGO_SVG)
|
||||
);
|
||||
this.matIconRegistry.addSvgIcon(
|
||||
"google-disabled-logo",
|
||||
this.domSanitizer.bypassSecurityTrustResourceUrl(GOOGLE_DISABLED_LOGO_SVG)
|
||||
)
|
||||
this.matIconRegistry.addSvgIcon(
|
||||
"github-logo",
|
||||
this.domSanitizer.bypassSecurityTrustResourceUrl(GITHUB_LOGO_SVG)
|
||||
@@ -134,6 +147,17 @@ export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.validateLogin(res);
|
||||
}
|
||||
);
|
||||
|
||||
this.cookieStatusChangeSubscription = this.cookieConsentService.cookieStatusChangeSubscription.subscribe(
|
||||
(status: boolean) => {
|
||||
this.isCookieBlocked = !status;
|
||||
console.log("Cookie status: " + status);
|
||||
}
|
||||
);
|
||||
|
||||
if (this.isCookieBlocked) {
|
||||
this.ccService.fadeIn();
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
@@ -142,6 +166,7 @@ export class LoginComponent implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.authSubject.unsubscribe();
|
||||
this.cookieStatusChangeSubscription.unsubscribe();
|
||||
}
|
||||
|
||||
onStateChange(state: boolean) {
|
||||
|
||||
44
src/app/shared/cookie-consent/cookie-consent.module.ts
Normal file
44
src/app/shared/cookie-consent/cookie-consent.module.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import {NgModule} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {NgcCookieConsentConfig, NgcCookieConsentModule} from "ngx-cookieconsent";
|
||||
|
||||
|
||||
const cookieConfig: NgcCookieConsentConfig = {
|
||||
"cookie": {
|
||||
"domain": "tinesoft.github.io"
|
||||
},
|
||||
"position": "bottom-right",
|
||||
"theme": "classic",
|
||||
"palette": {
|
||||
"popup": {
|
||||
"background": "#4e4e4e",
|
||||
"text": "#ffffff",
|
||||
"link": "#ffffff"
|
||||
},
|
||||
"button": {
|
||||
"background": "#fa2f22",
|
||||
"text": "#ffffff",
|
||||
"border": "transparent"
|
||||
}
|
||||
},
|
||||
"type": "opt-in",
|
||||
"content": {
|
||||
"message": "This website uses cookies to ensure you get the best experience on our website.",
|
||||
"dismiss": "Got it!",
|
||||
"deny": "Refuse cookies",
|
||||
"link": "",
|
||||
"href": "",
|
||||
"policy": "Cookie Policy"
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [],
|
||||
imports: [
|
||||
CommonModule,
|
||||
NgcCookieConsentModule.forRoot(cookieConfig)
|
||||
]
|
||||
})
|
||||
export class CookieConsentModule {
|
||||
}
|
||||
16
src/app/shared/cookie-consent/cookie-consert.service.spec.ts
Normal file
16
src/app/shared/cookie-consent/cookie-consert.service.spec.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
|
||||
import { CookieConsertService } from './cookie-consert.service';
|
||||
|
||||
describe('CookieConsertService', () => {
|
||||
let service: CookieConsertService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(CookieConsertService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
||||
52
src/app/shared/cookie-consent/cookie-consert.service.ts
Normal file
52
src/app/shared/cookie-consent/cookie-consert.service.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import {Injectable} from '@angular/core';
|
||||
import {BehaviorSubject, Subject, Subscription} from "rxjs";
|
||||
import {CookieService} from "ngx-cookie-service";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class CookieConsertService {
|
||||
|
||||
private storage: Storage;
|
||||
|
||||
cookieStatusChangeSubscription!: BehaviorSubject<boolean>
|
||||
|
||||
constructor(private cookieService: CookieService) {
|
||||
this.storage = window.localStorage
|
||||
|
||||
this.cookieStatusChangeSubscription = new BehaviorSubject<boolean>(
|
||||
this.getCookieConsentStatusFromLocalStorage()
|
||||
);
|
||||
}
|
||||
|
||||
consent() {
|
||||
let status = true;
|
||||
|
||||
this.cookieStatusChangeSubscription.next(status);
|
||||
this.setCookieConsentStatusToLocalStorage(status);
|
||||
}
|
||||
|
||||
decline() {
|
||||
let status = false;
|
||||
|
||||
this.cookieStatusChangeSubscription.next(status);
|
||||
this.setCookieConsentStatusToLocalStorage(status);
|
||||
|
||||
this.cookieService.deleteAll();
|
||||
}
|
||||
|
||||
setCookieConsentStatusToLocalStorage(status: boolean) {
|
||||
this.storage.setItem('cookieConsentStatus', status.toString());
|
||||
}
|
||||
|
||||
getCookieConsentStatusFromLocalStorage(): boolean {
|
||||
let status = this.storage.getItem('cookieConsentStatus');
|
||||
|
||||
if (status === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return status === 'true';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { PopupComponent } from './components/popup/popup.component';
|
||||
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
||||
import {CookieConsentModule} from "./cookie-consent/cookie-consent.module";
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
@@ -18,6 +19,7 @@ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
||||
HttpClientModule,
|
||||
BrowserAnimationsModule,
|
||||
FontAwesomeModule,
|
||||
CookieConsentModule
|
||||
],
|
||||
exports: [
|
||||
ClickedOutsideDirective,
|
||||
|
||||
3
src/assets/img/providers/google-disabled.svg
Normal file
3
src/assets/img/providers/google-disabled.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="210px" width="210px" viewBox="0 0 210 210">
|
||||
<path d="M0,105C0,47.103,47.103,0,105,0c23.383,0,45.515,7.523,64.004,21.756l-24.4,31.696C133.172,44.652,119.477,40,105,40 c-35.841,0-65,29.159-65,65s29.159,65,65,65c28.867,0,53.398-18.913,61.852-45H105V85h105v20c0,57.897-47.103,105-105,105 S0,162.897,0,105z"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 370 B |
@@ -1,9 +1,4 @@
|
||||
<svg enable-background="new 0 0 533.5 544.3" version="1.1" viewBox="0 0 533.5 544.3" xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:ns="&ns_sfw;"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<svg viewBox="0 0 533.5 544.3" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="m533.5 278.4c0-18.5-1.5-37.1-4.7-55.3h-256.7v104.8h147c-6.1 33.8-25.7 63.7-54.4 82.7v68h87.7c51.5-47.4 81.1-117.4 81.1-200.2z" style="fill:#4285f4"/>
|
||||
<path d="m272.1 544.3c73.4 0 135.3-24.1 180.4-65.7l-87.7-68c-24.4 16.6-55.9 26-92.6 26-71 0-131.2-47.9-152.8-112.3h-90.5v70.1c46.2 91.9 140.3 149.9 243.2 149.9z" style="fill:#34a853"/>
|
||||
<path d="M119.3,324.3c-11.4-33.8-11.4-70.4,0-104.2V150H28.9c-38.6,76.9-38.6,167.5,0,244.4L119.3,324.3z" style="fill:#fbbc04"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 1008 B After Width: | Height: | Size: 747 B |
@@ -25,5 +25,4 @@
|
||||
<app-root></app-root>
|
||||
<noscript>Please enable JavaScript to continue using this application.</noscript>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user