diff --git a/.gitignore b/.gitignore index 53a8849..555a06f 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ speed-measure-plugin*.json # IDEs and editors /.idea +/.vscode .project .classpath .c9/ diff --git a/package-lock.json b/package-lock.json index 58d20d9..0b1f668 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "form-builder-demo", "version": "0.0.1", "dependencies": { + "@abacritt/angularx-social-login": "^2.1.0", "@angular/animations": "^16.0.4", "@angular/cdk": "^16.0.3", "@angular/common": "^16.0.4", @@ -52,6 +53,18 @@ "typescript": "^4.9.5" } }, + "node_modules/@abacritt/angularx-social-login": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@abacritt/angularx-social-login/-/angularx-social-login-2.1.0.tgz", + "integrity": "sha512-wjKiwLhA0j/exrb17unRveAkjxYTf1qRYKXZqJfD4jSzHkODKjVpOVDmt7Q+T2m8fLJBGc304hRBuUVVEtl8xg==", + "dependencies": { + "tslib": ">=2.5.0" + }, + "peerDependencies": { + "@angular/common": ">=16.0.0", + "@angular/core": ">=16.0.0" + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", @@ -18529,6 +18542,14 @@ } }, "dependencies": { + "@abacritt/angularx-social-login": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@abacritt/angularx-social-login/-/angularx-social-login-2.1.0.tgz", + "integrity": "sha512-wjKiwLhA0j/exrb17unRveAkjxYTf1qRYKXZqJfD4jSzHkODKjVpOVDmt7Q+T2m8fLJBGc304hRBuUVVEtl8xg==", + "requires": { + "tslib": ">=2.5.0" + } + }, "@ampproject/remapping": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", diff --git a/package.json b/package.json index d62c2c4..13922f3 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ }, "private": true, "dependencies": { + "@abacritt/angularx-social-login": "^2.1.0", "@angular/animations": "^16.0.4", "@angular/cdk": "^16.0.3", "@angular/common": "^16.0.4", @@ -58,4 +59,4 @@ "karma-jasmine-html-reporter": "^1.5.0", "typescript": "^4.9.5" } -} \ No newline at end of file +} diff --git a/src/app/app.component.html b/src/app/app.component.html index 218ba2c..e542925 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,4 +1,7 @@ + + Form Builder Demo
- - + + - + + + + + +
+ + +
+
diff --git a/src/app/app.component.less b/src/app/app.component.less index 7aafa49..9a55b8a 100644 --- a/src/app/app.component.less +++ b/src/app/app.component.less @@ -28,23 +28,12 @@ transition: all .3s, padding 0s; } -.create-form-btn { - margin-right: 16px; - height: 48px; - width: 48px; - color: @green; - border-color: @green; - border-width: 1.6px; - line-height: 1; - - &:hover, &:focus { - background-color: fade(@green, 10%); - } +.sign-in-btn { + margin-right: 10px; +} - i { - font-size: 20px; - height: 20px; - } +.sign-up-btn, .sign-out-btn { + margin-right: 16px; } .trigger:hover { diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 9b240fb..f5e809f 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,10 +1,33 @@ -import { Component } from '@angular/core'; +import { ChangeDetectorRef, Component, OnInit, ViewChild } from '@angular/core'; +import { AuthComponent } from '@widgets/auth/auth.component'; @Component({ - selector: 'app-root', - templateUrl: './app.component.html', - styleUrls: ['./app.component.less'] + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.less'] }) -export class AppComponent { - isCollapsed = false; +export class AppComponent implements OnInit { + isCollapsed = false; + isSignedIn = false; + isSigningIn = false; + + @ViewChild(AuthComponent) signIn: AuthComponent; + + constructor(private cdr: ChangeDetectorRef) { } + + ngOnInit(): void { + this.isSignedIn = !!localStorage.getItem('token'); + } + + onSignedIn(): void { + this.isSignedIn = true; + this.isSigningIn = false; + } + + signOut(): void { + this.isSignedIn = false; + this.isSigningIn = true; + this.cdr.detectChanges(); + this.signIn.signOut(); + } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index f984fe7..8843e3d 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -2,6 +2,7 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; +import { AuthModule } from '@widgets/auth/auth.module'; import { FormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @@ -29,14 +30,17 @@ const ANT_DESIGN_MODULES = [ AppComponent ], imports: [ - BrowserModule, AppRoutingModule, + AuthModule, + BrowserModule, FormsModule, HttpClientModule, BrowserAnimationsModule, ANT_DESIGN_MODULES ], - providers: [{provide: NZ_I18N, useValue: en_US}], + providers: [ + { provide: NZ_I18N, useValue: en_US } + ], bootstrap: [AppComponent] }) export class AppModule { diff --git a/src/app/styles/global/_colors.less b/src/app/styles/global/_colors.less index 6b98c89..c8e1ee3 100644 --- a/src/app/styles/global/_colors.less +++ b/src/app/styles/global/_colors.less @@ -7,6 +7,5 @@ @dark-grey: #545454; @black: #000; @blue: #1890ff; -@green: #00cc66; @blueviolet: blueviolet; @red: red; diff --git a/src/app/widgets/auth/auth.component.html b/src/app/widgets/auth/auth.component.html new file mode 100644 index 0000000..af85840 --- /dev/null +++ b/src/app/widgets/auth/auth.component.html @@ -0,0 +1,9 @@ +
+

Sign In

+ + +
diff --git a/src/app/widgets/auth/auth.component.less b/src/app/widgets/auth/auth.component.less new file mode 100644 index 0000000..41914f1 --- /dev/null +++ b/src/app/widgets/auth/auth.component.less @@ -0,0 +1,26 @@ +@import '~app/styles/global/_colors.less'; + +:host { + position: absolute; + display: flex; + align-items: center; + z-index: 100; + width: 100%; + height: 100%; + background-color: @white; +} + +.container { + margin: 0 auto; + height: fit-content; + width: 360px; + padding: 30px; + border-radius: 6px; + border: 1px solid #e8e8e8; + box-shadow: 0 3px 3px 3px rgba(0, 0, 0, 0.05); +} + +.header { + margin-bottom: 20px; + border-bottom: 1px solid #e8e8e8; +} diff --git a/src/app/widgets/auth/auth.component.ts b/src/app/widgets/auth/auth.component.ts new file mode 100644 index 0000000..903c5fd --- /dev/null +++ b/src/app/widgets/auth/auth.component.ts @@ -0,0 +1,33 @@ +import { Component, EventEmitter, OnInit, Output } from '@angular/core'; +import { SocialAuthService, SocialUser } from '@abacritt/angularx-social-login'; + +@Component({ + selector: 'app-auth', + templateUrl: './auth.component.html', + styleUrls: ['./auth.component.less'] +}) +export class AuthComponent implements OnInit { + + @Output() signedIn = new EventEmitter(); + + constructor(private socialAuthService: SocialAuthService) { } + + ngOnInit() { + // TODO Add login by email + /*this.loginForm = this.formBuilder.group({ + email: ['', Validators.required], + password: ['', Validators.required], + });*/ + this.socialAuthService.authState.subscribe((user: SocialUser) => { + if (user && user.idToken != localStorage.getItem('token')) { + localStorage.setItem('token', user.idToken); + this.signedIn.emit(); + } + }); + } + + signOut(): void { + this.socialAuthService.signOut(); + localStorage.removeItem('token'); + } +} diff --git a/src/app/widgets/auth/auth.module.ts b/src/app/widgets/auth/auth.module.ts new file mode 100644 index 0000000..d40b22e --- /dev/null +++ b/src/app/widgets/auth/auth.module.ts @@ -0,0 +1,35 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { NzButtonModule } from 'ng-zorro-antd/button'; +import { AuthComponent } from './auth.component'; +import { GoogleLoginProvider, SocialAuthServiceConfig, SocialLoginModule, GoogleSigninButtonModule } from '@abacritt/angularx-social-login'; +import { environment } from './../../../environments/environment'; + +const ANT_DESIGN_MODULES = [NzButtonModule]; + +@NgModule({ + declarations: [AuthComponent], + imports: [ + CommonModule, + SocialLoginModule, + GoogleSigninButtonModule, + ANT_DESIGN_MODULES + ], + providers: [ + { + provide: 'SocialAuthServiceConfig', + useValue: { + autoLogin: false, + providers: [ + { + id: GoogleLoginProvider.PROVIDER_ID, + provider: new GoogleLoginProvider(environment.googleOAuthClientId), + }, + ], + } as SocialAuthServiceConfig + } + ], + exports: [AuthComponent] +}) +export class AuthModule { +} diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 3612073..87558c5 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -1,3 +1,4 @@ export const environment = { - production: true + production: true, + googleOAuthClientId: '666364708928-laj5k75go7q5dm985tjficnr78kggv4a.apps.googleusercontent.com' }; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 30d7bcc..2611b60 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -3,7 +3,8 @@ // The list of file replacements can be found in `angular.json`. export const environment = { - production: false + production: false, + googleOAuthClientId: '666364708928-laj5k75go7q5dm985tjficnr78kggv4a.apps.googleusercontent.com' }; /*