Skip to content
This repository has been archived by the owner on Sep 27, 2022. It is now read-only.

Commit

Permalink
some refactoring and basic authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
criticalbh committed May 18, 2017
1 parent 7e57754 commit 5e8b228
Show file tree
Hide file tree
Showing 11 changed files with 534 additions and 159 deletions.
69 changes: 69 additions & 0 deletions client/auth/authentication.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
export class Authentication {
constructor() {
if (!Authentication.inst) {
Authentication.inst = this;
} else {
throw new Error('use instance');
}

var unparsedAuth = localStorage.getItem('auth');
if (unparsedAuth) {
this._auth = JSON.parse(unparsedAuth);
}
this._callbacks = [];
return Authentication.inst;
}

get auth() {
if (this._auth) {
var unparsedAuth = localStorage.getItem('auth');
if (unparsedAuth) {
this._auth = JSON.parse(unparsedAuth);
}
}
return JSON.parse(localStorage.getItem('auth'));
}

set auth(value) {
localStorage.setItem('auth', JSON.stringify(value));
}

onAuthenticate(callback) {
this._callbacks.push(callback);
}


doAuthentication(email, password) {
let user = {
'user': {
'email': email, 'password': password
}
};
return new Promise((resolve, reject) => {
fetch('https://conduit.productionready.io/api/users/login', {
method: 'post',
headers: {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json'
},
body: JSON.stringify(user)
}).then(res=>res.json()).then(res => {
if (res.user) {
this.auth = res.user;
resolve(res.user);
setTimeout(() => {
this._callbacks.forEach(callback => callback(res.user))
});
} else {
reject(res.errors)
}
});
});

}

static get instance() {
return Authentication.inst;
}
}
Authentication.inst = null;
10 changes: 5 additions & 5 deletions client/components/article.comp.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import {RouterHandler} from "../router/router-handler";
"use strict";

export class ArticleComponent extends HTMLElement {

//todo generate tag list
constructor() {
super();
this.model = {
author: '',
heart: 0
};
this.updateHearts = this.updateHearts.bind(this);
}

static get observedAttributes() {
Expand All @@ -20,15 +21,14 @@ export class ArticleComponent extends HTMLElement {
}

disconnectedCallback() {
console.log('disconnected');
const button = this.querySelector('#ion-heart');
button.removeEventListener('click', this.updateHearts.bind(this));
button.removeEventListener('click', this.updateHearts);
}

connectedCallback() {
this.innerHTML = this.render();
const button = this.querySelector('#ion-heart');
button.addEventListener('click', this.updateHearts.bind(this));
button.addEventListener('click', this.updateHearts);

const authorButton = this.querySelector('#author');
authorButton.addEventListener('click', (e) => {
Expand Down Expand Up @@ -70,7 +70,7 @@ export class ArticleComponent extends HTMLElement {
</div>
<a id="preview-link" href="#/article/${this.model.slug}" class="preview-link">
<h1>${this.model.title}</h1>
<p>${this.model.description}</p>
<p>${this.model.description ? this.model.description : ''}</p>
<span>Read more...</span>
<ul class="tag-list">
<li class="tag-default tag-pill tag-outline">
Expand Down
134 changes: 94 additions & 40 deletions client/components/layout/c-nav.comp.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
"use strict";

import {RouterHandler} from "../../router/router-handler";
import {Authentication} from "../../auth/authentication";


export class CNavComponent extends HTMLElement {
constructor() {
super();

this.navigate = this.navigate.bind(this);
this.$links = null;
this.$navUl = null;
this.$signin = null;
this.$signup = null;
}


Expand All @@ -18,54 +23,69 @@ export class CNavComponent extends HTMLElement {

}

disconnectedCallback() {
this.$links.forEach(link => {
link.removeEventListener('click', e => this.navigate(e, link));
});
}

connectedCallback() {
var template = `
<nav class="navbar navbar-light">
<div class="container">
<a class="navbar-brand" href="/" data-navigo >conduit</a>
<ul class="nav navbar-nav pull-xs-right">
<li class="nav-item">
<!-- Add "active" class when you're on that page" -->
<a href="/" data-navigo class="nav-link">Home</a>
</li>
<!--<li class="nav-item">-->
<!--<a class="nav-link" href="">-->
<!--<i class="ion-compose"></i>&nbsp;New Post-->
<!--</a>-->
<!--</li>-->
<!--<li class="nav-item">-->
<!--<a class="nav-link" href="">-->
<!--<i class="ion-gear-a"></i>&nbsp;Settings-->
<!--</a>-->
<!--</li>-->
<li class="nav-item">
<a href="/login" data-navigo class="nav-link">Sign in</a>
</li>
<li class="nav-item">
<a href="/register" data-navigo class="nav-link">Sign up</a>
</li>
</ul>
</div>
</nav>
`;
this.innerHTML = this.render();

this.innerHTML = template;
this.$navUl = this.querySelector('ul.nav');
this.$signin = this.querySelector('#signin');
this.$signup = this.querySelector('#signup');

let links = this.querySelectorAll('a.nav-link');
links.forEach(link => {
link.addEventListener('click', (e) => {
e.preventDefault();
var routingTo = link.getAttribute('href');
RouterHandler.getInstance.router.navigate(routingTo);
this.updateActive(routingTo);
});

if (Authentication.instance.auth) {
this.userAuthenticated(Authentication.instance.auth);
}

Authentication.instance.onAuthenticate((user) => {
this.setCurrentActive();
this.userAuthenticated(user);
});

this.$links = this.querySelectorAll('a.nav-link');
this.$links.forEach(link => {
link.addEventListener('click', e => this.navigate(e, link));
});
this.setCurrentActive();
}

userAuthenticated(user) {
this.removeGuestLinks();
this.createProfileLinks(user);
}

removeGuestLinks() {
this.$signin.parentNode.removeChild(this.$signin);
this.$signup.parentNode.removeChild(this.$signup);
}

createProfileLinks(user) {
let newArticle = this.createNavItemLink('/editor', '<i class="ion-compose"></i>&nbsp;New Post');
this.$navUl.appendChild(newArticle);

let settings = this.createNavItemLink('/settings', '<i class="ion-gear-a"></i>&nbsp;Settings');
this.$navUl.appendChild(settings);

let userProfile = this.createNavItemLink('/profile/' + user.username, user.username);
this.$navUl.appendChild(userProfile);
}

navigate(e, link) {
e.preventDefault();
var routingTo = link.getAttribute('href');
RouterHandler.getInstance.router.navigate(routingTo);
this.updateActive(routingTo);
}

setCurrentActive() {
let curUrl = location.hash;
curUrl = curUrl.substring(1);
console.log(curUrl);
this.updateActive(curUrl);

}

updateActive(route) {
Expand All @@ -79,6 +99,40 @@ export class CNavComponent extends HTMLElement {
});
}

createNavItemLink(href, content) {
const liNavItem = document.createElement('li');
liNavItem.className = 'nav-item';

const aNavLink = document.createElement('a');
aNavLink.classList = 'nav-link';
aNavLink.href = href;
aNavLink.innerHTML = content;

liNavItem.appendChild(aNavLink);
return liNavItem;
}

render() {
return `
<nav class="navbar navbar-light">
<div class="container">
<a class="navbar-brand" href="/" data-navigo >conduit</a>
<ul class="nav navbar-nav pull-xs-right">
<li class="nav-item">
<a href="/" data-navigo class="nav-link">Home</a>
</li>
<li id="signin" class="nav-item">
<a href="/login" data-navigo class="nav-link">Sign in</a>
</li>
<li id="signup" class="nav-item">
<a href="/register" data-navigo class="nav-link">Sign up</a>
</li>
</ul>
</div>
</nav>
`;
}


}

80 changes: 80 additions & 0 deletions client/components/popular-tags.comp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"use strict";

export class PopularTagsComponent extends HTMLElement {

constructor() {
super();
// var event = new CustomEvent('build', { 'detail': elem.dataset.time });
//
// // Listen for the event.
// elem.addEventListener('build', function (e) { ... }, false);
//
// // Dispatch the event.
// elem.dispatchEvent(event);
}

static get observedAttributes() {
return [];
}

attributeChangedCallback(name, oldValue, newValue) {

}

disconnectedCallback() {

}

connectedCallback() {
this.innerHTML = this.render();
this.popularTags();
}

popularTags() {
let tagList = this.querySelector('#tagList');

fetch('https://conduit.productionready.io/api/tags').then(function (response) {
return response.json();
}).then(r => {
if (tagList) {
while (tagList.firstChild) {
tagList.removeChild(tagList.firstChild);
}
}
r.tags.forEach(tag => {
let tagEl = this.createNewTagElement(tag);
tagEl.addEventListener('click', () => {
this.tagOnClick(tag);
});
tagList.appendChild(tagEl);
});
});
}

tagOnClick(tag) {
var event = new CustomEvent('filter', { 'detail': tag });
this.dispatchEvent(event);
}

createNewTagElement(tag) {
const tagEl = document.createElement('a');
tagEl.className = 'tag-pill tag-default';
tagEl.innerHTML = tag;
tagEl.href = '#/';
tagEl.style = "cursor: pointer;";
return tagEl;
}


render() {
return `
<div class="sidebar">
<p>Popular Tags</p>
<div id="tagList" class="tag-list">
Loading tags ...
</div>
</div>
`;
}

}
17 changes: 17 additions & 0 deletions client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@ import {RouterHandler} from "./router/router-handler";
import {ProfileComponent} from "./pages/profile.comp";
import {ArticlePreviewComponent} from "./pages/article-preview.comp";
import {CommentPreviewComponent} from "./components/comment-preview.comp";
import {Authentication} from "./auth/authentication";
import {EditorComponent} from "./pages/editor.comp";
import {SettingsComponent} from "./pages/settings.comp";
import {PopularTagsComponent} from "./components/popular-tags.comp";

class App {
constructor() {
new Authentication();
this.registerComponents();
RouterHandler.getInstance.init();
}
Expand Down Expand Up @@ -50,6 +55,18 @@ class App {
{
tagName: 'comment-preview',
component: CommentPreviewComponent
},
{
tagName: 'c-editor',
component: EditorComponent
},
{
tagName: 'c-settings',
component: SettingsComponent
},
{
tagName: 'popular-tags',
component: PopularTagsComponent
}
];
ComponentRegistry.register(components);
Expand Down
Loading

0 comments on commit 5e8b228

Please sign in to comment.