Skip to content

Commit a07621e

Browse files
committed
feat(avatar): default user avatar
1 parent 84ce5e0 commit a07621e

File tree

12 files changed

+137
-10
lines changed

12 files changed

+137
-10
lines changed

src/api/db/migrations.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export function create(): Promise<null> {
1111
t.string('fullname').notNullable();
1212
t.string('password').notNullable();
1313
t.boolean('admin').notNullable().defaultTo(false);
14-
t.string('avatar').notNullable().defaultTo('images/avatars/user.png');
14+
t.string('avatar').notNullable().defaultTo('avatars/user.png');
1515
t.timestamps();
1616
})
1717
.then(() => schema.createTableIfNotExists('repositories', (t: knex.TableBuilder) => {

src/api/db/user.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,24 @@ export function getUser(id: number): Promise<any> {
1313
});
1414
}
1515

16+
export function getUsers(): Promise<any> {
17+
return new Promise((resolve, reject) => {
18+
new User().fetchAll().then(users => {
19+
if (!users) {
20+
reject(users);
21+
} else {
22+
let data = users.toJSON();
23+
data = data.map(user => {
24+
delete user.password;
25+
return user;
26+
});
27+
28+
resolve(data);
29+
}
30+
});
31+
});
32+
}
33+
1634
export function updateUser(data: any): Promise<any> {
1735
return new Promise((resolve, reject) => {
1836
new User({ id: data.id }).save(data, { method: 'update', require: false })

src/api/server-routes.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@ import { Observable } from 'rxjs';
77
import { exists } from './fs';
88
import { getFilePath } from './utils';
99
import { reinitializeDatabase } from './db/migrations';
10-
import { usersExists, createUser, login, getUser, updateUser, updateUserPassword } from './db/user';
10+
import {
11+
usersExists,
12+
createUser,
13+
login,
14+
getUser,
15+
updateUser,
16+
updateUserPassword,
17+
getUsers
18+
} from './db/user';
1119
import { addRepository, getRepositories, getRepository, getRepositoryBadge } from './db/repository';
1220
import { getBuilds, getBuild } from './db/build';
1321
import { getJob } from './db/job';
@@ -20,6 +28,7 @@ export function webRoutes(): express.Router {
2028
router.use('/js', express.static(resolve(__dirname, '../app/js'), { index: false }));
2129
router.use('/images', express.static(resolve(__dirname, '../app/images'), { index: false }));
2230
router.use('/css/fonts', express.static(resolve(__dirname, '../app/fonts'), { index: false }));
31+
router.use('/avatars', express.static(getFilePath('avatars'), { index: false }));
2332

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

73+
router.get('/', (req: express.Request, res: express.Response) => {
74+
getUsers().then(users => {
75+
return res.status(200).json({ data: users });
76+
}).catch(err => {
77+
return res.status(200).json({ err: err });
78+
});
79+
});
80+
6481
router.post('/login', (req: express.Request, res: express.Response) => {
6582
login(req.body).then(credentials => {
6683
res.status(200).json({ data: credentials });

src/api/utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ export function initSetup(): Promise<null> {
3737
const srcDir = resolve(__dirname, '../../src/files');
3838
const destDir = getFilePath('docker-files');
3939
return copyFile(srcDir, destDir);
40+
})
41+
.then(() => {
42+
const avatarDir = resolve(__dirname, '../../src/avatars');
43+
const destDir = getFilePath('avatars');
44+
return copyFile(avatarDir, destDir);
4045
});
4146
}
4247

src/app/components/app-header/app-header.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
</div>
1616
<div class="nav-right">
1717
<a class="nav-item user-item" (click)="toggleMenu()">
18-
<img class="nav-avatar" src="https://avatars0.githubusercontent.com/u/1796022?v=3&s=460">
18+
<img class="nav-avatar" [src]="user.avatar">
1919
<div class="nav-dropdown" *ngIf="menuDropped">
2020
<a class="nav-dropdown-item" routerLink="/settings">
2121
Settings

src/app/components/app-header/app-header.component.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
import { Component, HostListener, ElementRef } from '@angular/core';
1+
import { Component, HostListener, ElementRef, OnInit } from '@angular/core';
22
import { Router, NavigationEnd } from '@angular/router';
33
import { AuthService } from '../../services/auth.service';
4+
import { ConfigService } from '../../services/config.service';
45

56
@Component({
67
selector: 'app-header',
78
templateUrl: 'app-header.component.html'
89
})
9-
export class AppHeaderComponent {
10+
export class AppHeaderComponent implements OnInit {
1011
menuDropped: boolean;
12+
user: any;
1113

1214
constructor(
1315
private authService: AuthService,
1416
private router: Router,
15-
private elementRef: ElementRef
17+
private elementRef: ElementRef,
18+
private config: ConfigService
1619
) {
1720
this.router.events.subscribe(event => {
1821
if (event instanceof NavigationEnd) {
@@ -21,6 +24,11 @@ export class AppHeaderComponent {
2124
});
2225
}
2326

27+
ngOnInit() {
28+
this.user = this.authService.getData();
29+
this.user.avatar = this.config.url + '/' + this.user.avatar;
30+
}
31+
2432
toggleMenu() {
2533
this.menuDropped = !this.menuDropped;
2634
}

src/app/components/app-settings/app-settings.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ <h1>My Settings</h1>
2525
<div class="columns is-multiline">
2626
<div class="column is-4">
2727
<figure class="image profile-image">
28-
<img src="https://avatars0.githubusercontent.com/u/1796022?v=3&s=460">
28+
<img [src]="avatarUrl">
2929
</figure>
3030
</div>
3131
<div class="column is-8">

src/app/components/app-settings/app-settings.component.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Component, OnInit } from '@angular/core';
22
import { ApiService } from '../../services/api.service';
33
import { AuthService } from '../../services/auth.service';
4+
import { ConfigService } from '../../services/config.service';
45

56
export interface IUser {
67
id: number;
@@ -26,8 +27,9 @@ export class AppSettingsComponent implements OnInit {
2627
user: IUser;
2728
userPasswordSaved: boolean;
2829
userPass: IUserPass;
30+
avatarUrl: string;
2931

30-
constructor(private api: ApiService, private auth: AuthService) { }
32+
constructor(private api: ApiService, private auth: AuthService, private config: ConfigService) { }
3133

3234
ngOnInit() {
3335
const data: any = this.auth.getData();
@@ -44,6 +46,8 @@ export class AppSettingsComponent implements OnInit {
4446
password: '',
4547
repeat_password: ''
4648
};
49+
50+
this.avatarUrl = this.config.url + '/' + data.avatar;
4751
}
4852

4953
updateProfile(e: MouseEvent): void {

src/app/components/app-team/app-team.component.html

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,46 @@ <h1>Team</h1>
1919
<div class="columns">
2020
<div class="column is-12">
2121
<div class="content">
22+
<div *ngIf="loading">
23+
<img src="images/icons/flickr.svg" class="main-loader">
24+
</div>
2225

26+
<div class="columns is-multiline" *ngIf="!loading">
27+
<div class="column is-12" *ngIf="!users || !users.length">
28+
<div class="notification is-info">
29+
No users found.
30+
</div>
31+
</div>
32+
33+
<div class="column is-12" *ngIf="users && users.length">
34+
<div class="columns list-item list-item-slim" *ngFor="let user of users; let i = index;">
35+
<div class="column is-3">
36+
<span class="icon">
37+
<img src="images/icons/git-repository.svg">
38+
</span>
39+
<span class="bold">{{ user.full_name }}</span>
40+
</div>
41+
<div class="column is-5">
42+
<span class="icon">
43+
<img src="images/icons/github-white.svg">
44+
</span>
45+
<span>{{ user.email }}</span>
46+
</div>
47+
<div class="column is-2">
48+
<span class="icon">
49+
<img src="images/icons/git-branch.svg">
50+
</span>
51+
<span>{{ user.id }}</span>
52+
</div>
53+
<div class="column is-2 justify-end">
54+
<!-- <img [src]="repo.status_badge"> -->
55+
</div>
56+
</div>
57+
</div>
58+
59+
</div>
2360
</div>
2461
</div>
2562
</div>
2663
</div>
64+
Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,29 @@
1-
import { Component } from '@angular/core';
1+
import { Component, OnInit } from '@angular/core';
2+
import { ApiService } from '../../services/api.service';
3+
import { AuthService } from '../../services/auth.service';
24

35
@Component({
46
selector: 'app-team',
57
templateUrl: 'app-team.component.html'
68
})
7-
export class AppTeamComponent { }
9+
export class AppTeamComponent implements OnInit {
10+
loading: boolean;
11+
users: any[];
12+
13+
constructor(private api: ApiService, private auth: AuthService) {
14+
this.loading = true;
15+
this.users = [];
16+
}
17+
18+
ngOnInit() {
19+
this.fetch();
20+
}
21+
22+
fetch(): void {
23+
this.loading = true;
24+
this.api.getUsers().subscribe(event => {
25+
this.users = event;
26+
this.loading = false;
27+
});
28+
}
29+
}

0 commit comments

Comments
 (0)