diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 22271f7d..0f785054 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -4,6 +4,8 @@ import {Component, ViewEncapsulation} from '@angular/core'; import {RouteConfig} from '@angular/router-deprecated'; import {Pages} from './pages'; +import {Login} from './pages/login'; +import {Register} from './pages/register'; import {AppState} from './app.state'; import {BaThemeConfigProvider, BaThemeConfig} from './theme'; import {BaThemeRun} from './theme/directives'; @@ -36,6 +38,16 @@ import {layoutPaths} from './theme/theme.constants'; component: Pages, useAsDefault: true }, + { + path: '/login', + name: 'Login', + component: Login + }, + { + path: '/register', + name: 'Register', + component: Register + }, // handle any non-registered route // and simply redirects back to dashboard page // you can specify any customer 404 page while it's not built in ito ng2-admin diff --git a/src/app/app.menu.ts b/src/app/app.menu.ts index 7749e602..a2ca736a 100644 --- a/src/app/app.menu.ts +++ b/src/app/app.menu.ts @@ -105,6 +105,23 @@ export const menuItems = [ } ] }, + { + title: 'Pages', + icon: 'ion-ios-location-outline', + selected: false, + expanded: false, + order: 650, + subMenu: [ + { + title: 'Login', + url: '/#/login', + }, + { + title: 'Register', + url: '/#/register', + } + ] + }, { title: 'Menu Level 1', icon: 'ion-ios-more', diff --git a/src/app/pages/login/index.ts b/src/app/pages/login/index.ts new file mode 100644 index 00000000..69c16441 --- /dev/null +++ b/src/app/pages/login/index.ts @@ -0,0 +1 @@ +export * from './login.component'; diff --git a/src/app/pages/login/login.component.ts b/src/app/pages/login/login.component.ts new file mode 100644 index 00000000..63eea4f8 --- /dev/null +++ b/src/app/pages/login/login.component.ts @@ -0,0 +1,35 @@ +import {Component, ViewEncapsulation} from '@angular/core'; +import {FORM_DIRECTIVES, FormBuilder, ControlGroup, Validators, AbstractControl} from '@angular/common'; + +@Component({ + selector: 'login', + encapsulation: ViewEncapsulation.None, + directives: [], + styles: [require('./login.scss')], + template: require('./login.html'), +}) +export class Login { + + public form:ControlGroup; + public email:AbstractControl; + public password:AbstractControl; + public submitted:boolean = false; + + constructor(fb:FormBuilder) { + this.form = fb.group({ + 'email': ['', Validators.compose([Validators.required, Validators.minLength(4)])], + 'password': ['', Validators.compose([Validators.required, Validators.minLength(4)])] + }); + + this.email = this.form.controls['email']; + this.password = this.form.controls['password']; + } + + public onSubmit(values:Object):void { + this.submitted = true; + if (this.form.valid) { + // your code goes here + // console.log(values); + } + } +} diff --git a/src/app/pages/login/login.html b/src/app/pages/login/login.html new file mode 100644 index 00000000..9bedac1a --- /dev/null +++ b/src/app/pages/login/login.html @@ -0,0 +1,39 @@ +
+
+

Sign in to ng2-admin

+ New to ng2-admin? Sign up! + +
+
+ + +
+ +
+
+
+ + +
+ +
+
+
+
+ + Forgot password? +
+
+
+ +
or Sign in with one click
+ + +
+
diff --git a/src/app/pages/login/login.scss b/src/app/pages/login/login.scss new file mode 100644 index 00000000..cb03e3ee --- /dev/null +++ b/src/app/pages/login/login.scss @@ -0,0 +1 @@ +@import '../../theme/sass/auth'; diff --git a/src/app/pages/register/index.ts b/src/app/pages/register/index.ts new file mode 100644 index 00000000..55388b6e --- /dev/null +++ b/src/app/pages/register/index.ts @@ -0,0 +1 @@ +export * from './register.component'; diff --git a/src/app/pages/register/register.component.ts b/src/app/pages/register/register.component.ts new file mode 100644 index 00000000..1d06b645 --- /dev/null +++ b/src/app/pages/register/register.component.ts @@ -0,0 +1,48 @@ +import {Component, ViewEncapsulation} from '@angular/core'; +import {FORM_DIRECTIVES, FormBuilder, ControlGroup, Validators, AbstractControl} from '@angular/common'; +import {EmailValidator, EqualPasswordsValidator} from '../../theme/validators'; + +@Component({ + selector: 'register', + encapsulation: ViewEncapsulation.None, + directives: [], + styles: [require('./register.scss')], + template: require('./register.html'), +}) +export class Register { + + public form:ControlGroup; + public name:AbstractControl; + public email:AbstractControl; + public password:AbstractControl; + public repeatPassword:AbstractControl; + public passwords:ControlGroup; + + public submitted:boolean = false; + + constructor(fb:FormBuilder) { + + this.form = fb.group({ + 'name': ['', Validators.compose([Validators.required, Validators.minLength(4)])], + 'email': ['', Validators.compose([Validators.required, EmailValidator.validate])], + 'passwords': fb.group({ + 'password': ['', Validators.compose([Validators.required, Validators.minLength(4)])], + 'repeatPassword': ['', Validators.compose([Validators.required, Validators.minLength(4)])] + }, {validator: EqualPasswordsValidator.validate('password', 'repeatPassword')}) + }); + + this.name = this.form.controls['name']; + this.email = this.form.controls['email']; + this.passwords = this.form.controls['passwords']; + this.password = this.passwords.controls['password']; + this.repeatPassword = this.passwords.controls['repeatPassword']; + } + + public onSubmit(values:Object):void { + this.submitted = true; + if (this.form.valid) { + // your code goes here + // console.log(values); + } + } +} diff --git a/src/app/pages/register/register.html b/src/app/pages/register/register.html new file mode 100644 index 00000000..ee1e0007 --- /dev/null +++ b/src/app/pages/register/register.html @@ -0,0 +1,53 @@ +
+
+

Sign up to ng2-admin

+ Already have an ng2-admin account? Sign in! + +
+
+ + +
+ +
+
+
+ + +
+ +
+
+
+ + +
+ +
+
+
+ + +
+ + Password don't match. +
+
+
+
+ +
+
+
+ +
or Sign up with one click
+ + +
+
diff --git a/src/app/pages/register/register.scss b/src/app/pages/register/register.scss new file mode 100644 index 00000000..cb03e3ee --- /dev/null +++ b/src/app/pages/register/register.scss @@ -0,0 +1 @@ +@import '../../theme/sass/auth'; diff --git a/src/app/theme/sass/_auth.scss b/src/app/theme/sass/_auth.scss new file mode 100644 index 00000000..b848a417 --- /dev/null +++ b/src/app/theme/sass/_auth.scss @@ -0,0 +1,141 @@ +@import 'conf/conf'; + +main { + min-height: 520px; + height: 100%; +} + +$text-color: #ffffff; + +.form-control, .form-control:focus { + @include placeholderStyle($text-color, 0.9); + background-color: rgba(0, 0, 0, .4); + border-radius: 5px; + color: $text-color; +} +.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { + @include placeholderStyle($text-color, 0.6); +} + +.auth-main { + display: flex; + align-items: center; + height: 100%; + width: 100%; + position: relative; +} + +.auth-block { + width: 540px; + margin: 0 auto; + border-radius: 5px; + @include bg-translucent-dark(0.55); + color: #fff; + padding: 32px; + h1 { + font-weight: $font-light; + margin-bottom: 28px; + text-align: center; + } + p { + font-size: 16px; + } + a { + text-decoration: none; + outline: none; + transition: all 0.2s ease; + color: $primary; + &:hover { + color: $primary-dark; + } + } + + .control-label { + padding-top: 11px; + color: $text-color; + } + + .form-group { + margin-bottom: 12px; + } +} + +.auth-input { + width: 300px; + margin-bottom: 24px; + input { + display: block; + width: 100%; + border: none; + font-size: 16px; + padding: 4px 10px; + outline: none; + } +} + +a.forgot-pass { + display: block; + text-align: right; + margin-bottom: -20px; + float: right; + z-index: 2; + position: relative; +} + +.auth-link { + display: block; + font-size: 16px; + text-align: center; + margin-bottom: 33px; +} + +.auth-sep { + margin-top: 36px; + margin-bottom: 24px; + line-height: 20px; + font-size: 16px; + text-align: center; + display: block; + position: relative; + & > span { + display: table-cell; + width: 30%; + white-space: nowrap; + padding: 0 24px; + color: $text-color; + & > span { + margin-top: -12px; + display: block; + } + } + &:before, &:after { + border-top: solid 1px $text-color; + content: ""; + height: 1px; + width: 35%; + display: table-cell; + } +} + +.al-share-auth { + text-align: center; + .al-share { + float: none; + margin: 0; + padding: 0; + display: inline-block; + li { + margin-left: 24px; + &:first-child { + margin-left: 0; + } + i { + font-size: 24px; + } + } + } +} + +.btn-auth { + color: #ffffff!important; +} diff --git a/src/app/theme/validators/email.validator.ts b/src/app/theme/validators/email.validator.ts new file mode 100644 index 00000000..f31fc8fa --- /dev/null +++ b/src/app/theme/validators/email.validator.ts @@ -0,0 +1,14 @@ +import {Control} from '@angular/common'; + +export class EmailValidator { + + public static validate(c: Control) { + let EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i; + + return EMAIL_REGEXP.test(c.value) ? null : { + validateEmail: { + valid: false + } + }; + } +} \ No newline at end of file diff --git a/src/app/theme/validators/equalPasswords.validator.ts b/src/app/theme/validators/equalPasswords.validator.ts new file mode 100644 index 00000000..d843f3c6 --- /dev/null +++ b/src/app/theme/validators/equalPasswords.validator.ts @@ -0,0 +1,16 @@ +import {Control, ControlGroup} from '@angular/common'; + +export class EqualPasswordsValidator { + + public static validate(firstField, secondField) { + + return (c: ControlGroup) => { + + return (c.controls && c.controls[firstField].value == c.controls[secondField].value) ? null : { + passwordsEqual: { + valid: false + } + }; + } + } +} \ No newline at end of file diff --git a/src/app/theme/validators/index.ts b/src/app/theme/validators/index.ts new file mode 100644 index 00000000..f1bab666 --- /dev/null +++ b/src/app/theme/validators/index.ts @@ -0,0 +1,2 @@ +export * from './email.validator'; +export * from './equalPasswords.validator'; \ No newline at end of file