Permalink
Browse files

feat(avatar): default user avatar

  • Loading branch information...
jkuri committed Jul 30, 2017
1 parent 84ce5e0 commit a07621eb1f38474505f7de6cdaff4e178805341f
@@ -11,7 +11,7 @@ export function create(): Promise<null> {
t.string('fullname').notNullable();
t.string('password').notNullable();
t.boolean('admin').notNullable().defaultTo(false);
t.string('avatar').notNullable().defaultTo('images/avatars/user.png');
t.string('avatar').notNullable().defaultTo('avatars/user.png');
t.timestamps();
})
.then(() => schema.createTableIfNotExists('repositories', (t: knex.TableBuilder) => {
@@ -13,6 +13,24 @@ export function getUser(id: number): Promise<any> {
});
}

export function getUsers(): Promise<any> {
return new Promise((resolve, reject) => {
new User().fetchAll().then(users => {
if (!users) {
reject(users);
} else {
let data = users.toJSON();
data = data.map(user => {
delete user.password;
return user;
});

resolve(data);
}
});
});
}

export function updateUser(data: any): Promise<any> {
return new Promise((resolve, reject) => {
new User({ id: data.id }).save(data, { method: 'update', require: false })
@@ -7,7 +7,15 @@ import { Observable } from 'rxjs';
import { exists } from './fs';
import { getFilePath } from './utils';
import { reinitializeDatabase } from './db/migrations';
import { usersExists, createUser, login, getUser, updateUser, updateUserPassword } from './db/user';
import {
usersExists,
createUser,
login,
getUser,
updateUser,
updateUserPassword,
getUsers
} from './db/user';
import { addRepository, getRepositories, getRepository, getRepositoryBadge } from './db/repository';
import { getBuilds, getBuild } from './db/build';
import { getJob } from './db/job';
@@ -20,6 +28,7 @@ export function webRoutes(): express.Router {
router.use('/js', express.static(resolve(__dirname, '../app/js'), { index: false }));
router.use('/images', express.static(resolve(__dirname, '../app/images'), { index: false }));
router.use('/css/fonts', express.static(resolve(__dirname, '../app/fonts'), { index: false }));
router.use('/avatars', express.static(getFilePath('avatars'), { index: false }));

router.get('/setup', index);
router.get('/login', index);
@@ -61,6 +70,14 @@ export function jobRoutes(): express.Router {
export function userRoutes(): express.Router {
const router = express.Router();

router.get('/', (req: express.Request, res: express.Response) => {
getUsers().then(users => {
return res.status(200).json({ data: users });
}).catch(err => {
return res.status(200).json({ err: err });
});
});

router.post('/login', (req: express.Request, res: express.Response) => {
login(req.body).then(credentials => {
res.status(200).json({ data: credentials });
@@ -37,6 +37,11 @@ export function initSetup(): Promise<null> {
const srcDir = resolve(__dirname, '../../src/files');
const destDir = getFilePath('docker-files');
return copyFile(srcDir, destDir);
})
.then(() => {
const avatarDir = resolve(__dirname, '../../src/avatars');
const destDir = getFilePath('avatars');
return copyFile(avatarDir, destDir);
});
}

@@ -15,7 +15,7 @@
</div>
<div class="nav-right">
<a class="nav-item user-item" (click)="toggleMenu()">
<img class="nav-avatar" src="https://avatars0.githubusercontent.com/u/1796022?v=3&s=460">
<img class="nav-avatar" [src]="user.avatar">
<div class="nav-dropdown" *ngIf="menuDropped">
<a class="nav-dropdown-item" routerLink="/settings">
Settings
@@ -1,18 +1,21 @@
import { Component, HostListener, ElementRef } from '@angular/core';
import { Component, HostListener, ElementRef, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { AuthService } from '../../services/auth.service';
import { ConfigService } from '../../services/config.service';

@Component({
selector: 'app-header',
templateUrl: 'app-header.component.html'
})
export class AppHeaderComponent {
export class AppHeaderComponent implements OnInit {
menuDropped: boolean;
user: any;

constructor(
private authService: AuthService,
private router: Router,
private elementRef: ElementRef
private elementRef: ElementRef,
private config: ConfigService
) {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
@@ -21,6 +24,11 @@ export class AppHeaderComponent {
});
}

ngOnInit() {
this.user = this.authService.getData();
this.user.avatar = this.config.url + '/' + this.user.avatar;
}

toggleMenu() {
this.menuDropped = !this.menuDropped;
}
@@ -25,7 +25,7 @@ <h1>My Settings</h1>
<div class="columns is-multiline">
<div class="column is-4">
<figure class="image profile-image">
<img src="https://avatars0.githubusercontent.com/u/1796022?v=3&s=460">
<img [src]="avatarUrl">
</figure>
</div>
<div class="column is-8">
@@ -1,6 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { ApiService } from '../../services/api.service';
import { AuthService } from '../../services/auth.service';
import { ConfigService } from '../../services/config.service';

export interface IUser {
id: number;
@@ -26,8 +27,9 @@ export class AppSettingsComponent implements OnInit {
user: IUser;
userPasswordSaved: boolean;
userPass: IUserPass;
avatarUrl: string;

constructor(private api: ApiService, private auth: AuthService) { }
constructor(private api: ApiService, private auth: AuthService, private config: ConfigService) { }

ngOnInit() {
const data: any = this.auth.getData();
@@ -44,6 +46,8 @@ export class AppSettingsComponent implements OnInit {
password: '',
repeat_password: ''
};

this.avatarUrl = this.config.url + '/' + data.avatar;
}

updateProfile(e: MouseEvent): void {
@@ -19,8 +19,46 @@ <h1>Team</h1>
<div class="columns">
<div class="column is-12">
<div class="content">
<div *ngIf="loading">
<img src="images/icons/flickr.svg" class="main-loader">
</div>

<div class="columns is-multiline" *ngIf="!loading">
<div class="column is-12" *ngIf="!users || !users.length">
<div class="notification is-info">
No users found.
</div>
</div>

<div class="column is-12" *ngIf="users && users.length">
<div class="columns list-item list-item-slim" *ngFor="let user of users; let i = index;">
<div class="column is-3">
<span class="icon">
<img src="images/icons/git-repository.svg">
</span>
<span class="bold">{{ user.full_name }}</span>
</div>
<div class="column is-5">
<span class="icon">
<img src="images/icons/github-white.svg">
</span>
<span>{{ user.email }}</span>
</div>
<div class="column is-2">
<span class="icon">
<img src="images/icons/git-branch.svg">
</span>
<span>{{ user.id }}</span>
</div>
<div class="column is-2 justify-end">
<!-- <img [src]="repo.status_badge"> -->
</div>
</div>
</div>

</div>
</div>
</div>
</div>
</div>

@@ -1,7 +1,29 @@
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { ApiService } from '../../services/api.service';
import { AuthService } from '../../services/auth.service';

@Component({
selector: 'app-team',
templateUrl: 'app-team.component.html'
})
export class AppTeamComponent { }
export class AppTeamComponent implements OnInit {
loading: boolean;
users: any[];

constructor(private api: ApiService, private auth: AuthService) {
this.loading = true;
this.users = [];
}

ngOnInit() {
this.fetch();
}

fetch(): void {
this.loading = true;
this.api.getUsers().subscribe(event => {
this.users = event;
this.loading = false;
});
}
}
@@ -59,6 +59,10 @@ export class ApiService {
return this.post(`${this.url}/setup/db/init`, {});
}

getUsers(): Observable<any> {
return this.get(`${this.url}/user`);
}

getUser(id: number): Observable<any> {
return this.get(`${this.url}/user/${id}`);
}
@@ -0,0 +1,11 @@
<svg width="37px" height="46px" viewBox="0 0 37 46" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="noun_839026_cc" transform="translate(-4.000000, 0.000000)" fill-rule="nonzero" fill="#FFFFFF">
<g id="Group" transform="translate(4.000000, 0.000000)">
<path d="M28.102,19.679 C29.313,19.42 30.43,18.419 30.612,16.199 C30.762,14.382 30.296,13.446 29.608,12.969 C31.518,5.184 26.25,3.66 26.25,3.66 C26.25,3.66 22.313,-3.019 14.632,1.668 C13.655,2.264 12.136,3.406 11.231,4.585 C9.778,6.131 8.789,8.644 8.634,12.714 C7.696,13.072 6.959,13.978 7.142,16.198 C7.334,18.519 8.545,19.507 9.819,19.709 C11.539,23.898 14.935,27.35 18.954,27.35 C22.982,27.35 26.385,23.882 28.102,19.679 Z M18.954,25.397 C14.307,25.397 10.565,19.087 10.565,13.862 C10.565,13.146 10.588,12.482 10.632,11.866 C17.429,12.163 21.449,9.438 23.637,7.074 C25.712,9.142 26.79,11.754 27.341,13.693 C27.341,13.749 27.342,13.804 27.342,13.861 C27.343,19.087 23.602,25.397 18.954,25.397 Z" id="Shape"></path>
<path d="M16.292,33.297 L16.83,31.07 C16.892,30.813 17.025,30.593 17.205,30.424 C17.15,30.385 17.096,30.344 17.043,30.301 L12.237,26.322 L9.312,27.006 C4.359,28.171 0.869,32.354 0.869,37.152 L0.869,43.452 C0.869,44.692 1.972,45.681 3.292,45.681 L15.673,45.681 L17.561,34.919 C16.713,34.908 16.092,34.125 16.292,33.297 Z" id="Shape"></path>
<path d="M28.42,27.006 L25.535,26.322 L20.734,30.301 C20.681,30.344 20.629,30.385 20.574,30.424 C20.755,30.593 20.888,30.813 20.951,31.07 L21.488,33.297 C21.689,34.124 21.068,34.908 20.219,34.92 L22.107,45.682 L34.488,45.682 C35.808,45.682 36.812,44.694 36.812,43.453 L36.812,37.153 C36.814,32.354 33.373,28.171 28.42,27.006 Z" id="Shape"></path>
</g>
</g>
</g>
</svg>

0 comments on commit a07621e

Please sign in to comment.