[Feat] Create Reusable Component and Add Workspace Links (#8383)

* feat: export social links

* feat: create a shared logo component

* feat: create a shared social links component

* feat: add reusable patterns to constants

* feat: add link to magic workspace signin and use reusable logo, links and switch

* feat: SwitchThemeModule, LogoComponent, and SocialLinksComponent to NgxLoginModule
This commit is contained in:
Kifungo A
2024-10-10 22:38:54 +02:00
committed by GitHub
parent 4cb550b4ae
commit afb5d20f8c
12 changed files with 140 additions and 32 deletions
@@ -12,7 +12,7 @@ export * from './auth.guard';
export * from './no-auth.guard';
const environment = injector.get(GAUZY_ENV);
const socialLinks = [
export const socialLinks = [
{
url: environment?.GOOGLE_AUTH_LINK,
icon: 'google-outline',
@@ -17,3 +17,11 @@ export const injector = Injector.create({
export const API_ACTIVITY_WATCH_PREFIX = '/buckets';
export const AUTO_REFRESH_DELAY = 60 * 10 * 1000; // milliseconds
export const patterns = {
websiteUrl: /^((?:https?:\/\/)[^./]+(?:\.[^./]+)+(?:\/.*)?)$/,
imageUrl: /^(http)?s?:?(\/\/[^"']*\.(?:png|jpg|jpeg|gif|png|svg))/,
email: /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@(([^<>()[\]\.,;:\s@"]+\.)+[^<>()[\]\.,;:\s@"]{2,})$/i,
host: /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])$/,
passwordNoSpaceEdges: /^(?!\s).*[^\s]$/
};
@@ -1,7 +1,8 @@
<section class="login-container">
<div class="login-wrapper">
<div class="svg-wrapper">
<img [src]="logoUrl" class="ever-logo-svg" />
<gauzy-logo></gauzy-logo>
<gauzy-switch-theme></gauzy-switch-theme>
</div>
<div class="headings">
<div class="headings-inner">
@@ -125,26 +126,21 @@
</div>
</div>
<div class="login-magic-wrapper">
<a routerLink="/auth/login-magic">
{{ 'LOGIN_PAGE.LOGIN_MAGIC.TITLE' | translate }}
</a>
</div>
</form>
<div class="hr-div-soft"></div>
<section *ngIf="socialLinks && socialLinks.length > 0" class="links" aria-label="Social sign in">
{{ 'LOGIN_PAGE.OR_SIGN_IN_WITH' | translate }}
<div class="socials">
<ng-container *ngFor="let socialLink of socialLinks">
<a *ngIf="socialLink.link" [routerLink]="socialLink.link" [attr.target]="socialLink.target"
class="social-link">
<nb-icon *ngIf="socialLink.icon; else title" [icon]="socialLink.icon"></nb-icon>
<ng-template #title>{{ socialLink.title }}</ng-template>
</a>
<a *ngIf="socialLink.url" [attr.href]="socialLink.url" [attr.target]="socialLink.target"
class="social-link">
<nb-icon *ngIf="socialLink.icon; else title" [icon]="socialLink.icon"></nb-icon>
<ng-template #title>{{ socialLink.title }}</ng-template>
</a>
</ng-container>
</div>
</section>
<ngx-social-links></ngx-social-links>
<div class="hr-div-soft"></div>
<section class="another-action" aria-label="Sign In Workspace">
{{ 'WORKSPACES.UNKNOWN_WORKSPACE' | translate }}
<a class="text-link" routerLink="/auth/login-workspace">
{{ 'WORKSPACES.FIND_WORKSPACE' | translate }}
</a>
</section>
<section class="another-action" aria-label="Register">
{{ 'LOGIN_PAGE.DO_NOT_HAVE_ACCOUNT_TITLE' | translate }}
<a class="text-link" (click)="register()">
@@ -27,6 +27,7 @@
& .svg-wrapper {
display: flex;
justify-content: space-between;
width: 100%;
& .ever-logo-svg {
margin-bottom: 40px;
@@ -325,7 +326,7 @@
& .login-wrapper {
width: 100%;
padding: 30px 2px;
padding: 1rem 0;
& .headings {
& .headings-inner {
@@ -1,9 +1,7 @@
import { ChangeDetectorRef, Component, Inject, OnInit } from '@angular/core';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { NB_AUTH_OPTIONS, NbAuthService, NbLoginComponent } from '@nebular/auth';
import { UntilDestroy } from '@ngneat/until-destroy';
import { GAUZY_ENV } from '../constants/app.constants';
import { ElectronService } from '../electron/services';
import { LanguageElectronService } from '../language/language-electron.service';
@@ -23,10 +21,7 @@ export class NgxLoginComponent extends NbLoginComponent implements OnInit {
public readonly cdr: ChangeDetectorRef,
public readonly router: Router,
@Inject(NB_AUTH_OPTIONS)
options: any,
private readonly _domSanitizer: DomSanitizer,
@Inject(GAUZY_ENV)
private readonly _environment: any
options: any
) {
super(nbAuthService, options, cdr, router);
}
@@ -42,8 +37,4 @@ export class NgxLoginComponent extends NbLoginComponent implements OnInit {
public register(): void {
this.electronService.shell.openExternal('https://app.gauzy.co/#/auth/register');
}
public get logoUrl(): SafeResourceUrl {
return this._domSanitizer.bypassSecurityTrustResourceUrl(this._environment.PLATFORM_LOGO);
}
}
@@ -14,7 +14,10 @@ import {
} from '@nebular/theme';
import { DesktopDirectiveModule } from '../directives/desktop-directive.module';
import { LanguageModule } from '../language/language.module';
import { SwitchThemeModule } from '../theme-selector/switch-theme/switch-theme.module';
import { NgxLoginComponent } from './login.component';
import { LogoComponent } from './shared/ui/logo/logo.component';
import { SocialLinksComponent } from './shared/ui/social-links/social-links.component';
@NgModule({
imports: [
@@ -30,9 +33,10 @@ import { NgxLoginComponent } from './login.component';
NbInputModule,
NbFormFieldModule,
DesktopDirectiveModule,
LanguageModule.forChild()
LanguageModule.forChild(),
SwitchThemeModule
],
declarations: [NgxLoginComponent],
declarations: [NgxLoginComponent, SocialLinksComponent, LogoComponent],
exports: [NgxLoginComponent]
})
export class NgxLoginModule {}
@@ -0,0 +1,3 @@
<div class="svg-wrapper">
<img [src]="logoUrl" class="ever-logo-svg" />
</div>
@@ -0,0 +1,9 @@
.svg-wrapper {
display: flex;
justify-content: space-between;
& .ever-logo-svg {
margin-bottom: 40px;
height: 25px;
}
}
@@ -0,0 +1,20 @@
import { Component, Inject } from '@angular/core';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { GAUZY_ENV } from '../../../../constants';
@Component({
selector: 'gauzy-logo',
templateUrl: './logo.component.html',
styleUrls: ['./logo.component.scss']
})
export class LogoComponent {
constructor(
private readonly _domSanitizer: DomSanitizer,
@Inject(GAUZY_ENV)
private readonly _environment: any
) {}
public get logoUrl(): SafeResourceUrl {
return this._domSanitizer.bypassSecurityTrustResourceUrl(this._environment.PLATFORM_LOGO);
}
}
@@ -0,0 +1,27 @@
<ng-container *ngIf="socialLinks$ | async as socialLinks">
<ng-container *ngIf="socialLinks.length > 0">
<div class="links" aria-label="Social SignIn">
{{ 'LOGIN_PAGE.OR_SIGN_IN_WITH' | translate }}
<div class="socials">
<ng-container *ngFor="let socialLink of socialLinks">
<ng-container *ngIf="socialLink.link">
<a [routerLink]="socialLink.link" [attr.target]="socialLink.target" class="social-link">
<nb-icon *ngIf="socialLink.icon; else title" [icon]="socialLink.icon"></nb-icon>
<ng-template #title>
{{ socialLink.title }}
</ng-template>
</a>
</ng-container>
<ng-container *ngIf="socialLink.url">
<a [attr.href]="socialLink.url" [attr.target]="socialLink.target" class="social-link">
<nb-icon *ngIf="socialLink.icon; else title" [icon]="socialLink.icon"></nb-icon>
<ng-template #title>
{{ socialLink.title }}
</ng-template>
</a>
</ng-container>
</ng-container>
</div>
</div>
</ng-container>
</ng-container>
@@ -0,0 +1,10 @@
@import '@shared/reusable';
.links {
margin-top: 21px;
@include social-links-style;
& .socials {
margin-top: 15px;
margin-bottom: 25px;
}
}
@@ -0,0 +1,39 @@
import { Component, OnInit } from '@angular/core';
import { UntilDestroy } from '@ngneat/until-destroy';
import { Observable, of } from 'rxjs';
import { socialLinks } from '../../../../auth';
/**
* Interface representing a social link.
*/
export interface ISocialLink {
/** The URL of the social link. */
url: string;
/** The icon associated with the social link. */
icon: string;
/** (Optional) The target attribute for the link. */
target?: string;
/** (Optional) The link attribute for the link. */
link?: string;
/** (Optional) The title attribute for the link. */
title?: string;
}
@UntilDestroy({ checkProperties: true })
@Component({
selector: 'ngx-social-links',
templateUrl: './social-links.component.html',
styleUrls: ['./social-links.component.scss']
})
export class SocialLinksComponent implements OnInit {
/** */
public socialLinks$: Observable<ISocialLink[]>; // Observable for an array of social links
/**
* Lifecycle hook called after Angular has initialized all data-bound properties of a directive.
* Called once after the first ngOnChanges().
*/
ngOnInit(): void {
this.socialLinks$ = of(socialLinks);
}
}