diff --git a/src/app/core/components/navigation/navigation.model.ts b/src/app/core/components/navigation/navigation.model.ts index b0f34e84..d3be6f63 100644 --- a/src/app/core/components/navigation/navigation.model.ts +++ b/src/app/core/components/navigation/navigation.model.ts @@ -162,7 +162,7 @@ export class FuseNavigation { 'title': 'Profile', 'type' : 'nav-item', - 'icon' : 'account', + 'icon' : 'person', 'url' : '/pages/profile' }, { diff --git a/src/app/core/scss/core.scss b/src/app/core/scss/core.scss index 422faa0c..9585f2d0 100644 --- a/src/app/core/scss/core.scss +++ b/src/app/core/scss/core.scss @@ -13,19 +13,8 @@ @include mat-core(); // Include theme styles for core and each component used in your app. -// Alternatively, you can import and @include the theme mixins for each component -// that you are using. @include angular-material-theme($theme); -// Override typography CSS classes (e.g., mat-h1, mat-display-1, mat-typography, etc.). -@include mat-base-typography($custom-typography); - -// Override typography for a specific Angular Material components. -@include mat-checkbox-typography($custom-typography); - -// Override typography for all Angular Material, including mat-base-typography and all components. -@include angular-material-typography($custom-typography); - // Partials @import "partials/reset"; @import "partials/normalize"; diff --git a/src/app/core/scss/partials/_reset.scss b/src/app/core/scss/partials/_reset.scss index 7170d080..f3c8935c 100644 --- a/src/app/core/scss/partials/_reset.scss +++ b/src/app/core/scss/partials/_reset.scss @@ -71,4 +71,11 @@ button { appearance: none; -moz-appearance: none; -webkit-appearance: none; +} + +img { + max-width: 100%; + height: auto; + vertical-align: top; + border: none; } \ No newline at end of file diff --git a/src/app/core/scss/variables/_theme.scss b/src/app/core/scss/variables/_theme.scss index e7a6803d..4586e614 100644 --- a/src/app/core/scss/variables/_theme.scss +++ b/src/app/core/scss/variables/_theme.scss @@ -1,17 +1,12 @@ @import '~@angular/material/theming'; +// Palettes $primary: mat-palette($mat-indigo); $accent: mat-palette($mat-blue, A200, A100, A400); - -// The warn palette is optional (defaults to red). $warn: mat-palette($mat-red); // Create the theme object (a Sass map containing all of the palettes). $theme: mat-light-theme($primary, $accent, $warn); -$custom-typography: mat-typography-config( - $font-family: 'Roboto, "Helvetica Neue", sans-serif' -); - $background: map-get($theme, background); $foreground: map-get($theme, foreground); \ No newline at end of file diff --git a/src/app/fuse-fake-db/fuse-fake-db.service.ts b/src/app/fuse-fake-db/fuse-fake-db.service.ts index 3e9d4f02..2080070f 100644 --- a/src/app/fuse-fake-db/fuse-fake-db.service.ts +++ b/src/app/fuse-fake-db/fuse-fake-db.service.ts @@ -1,39 +1,30 @@ import { InMemoryDbService } from 'angular-in-memory-web-api'; + import { MailFakeDb } from './mail'; import { ChatFakeDb } from './chat'; import { CalendarFakeDb } from './calendar'; import { TodoFakeDb } from './todo'; +import { ProfileFakeDb } from './profile'; export class FuseFakeDbService implements InMemoryDbService { createDb() { return { - 'mail-mails' : MailFakeDb.mails, - 'mail-folders' : MailFakeDb.folders, - 'mail-filters' : MailFakeDb.filters, - 'mail-labels' : MailFakeDb.labels, - 'chat-contacts': ChatFakeDb.contacts, - 'chat-chats' : ChatFakeDb.chats, - 'chat-user' : ChatFakeDb.user, - 'calendar' : CalendarFakeDb.data, - 'todo-todos' : TodoFakeDb.todos, - 'todo-filters' : TodoFakeDb.filters, - 'todo-tags' : TodoFakeDb.tags + 'mail-mails' : MailFakeDb.mails, + 'mail-folders' : MailFakeDb.folders, + 'mail-filters' : MailFakeDb.filters, + 'mail-labels' : MailFakeDb.labels, + 'chat-contacts' : ChatFakeDb.contacts, + 'chat-chats' : ChatFakeDb.chats, + 'chat-user' : ChatFakeDb.user, + 'calendar' : CalendarFakeDb.data, + 'todo-todos' : TodoFakeDb.todos, + 'todo-filters' : TodoFakeDb.filters, + 'todo-tags' : TodoFakeDb.tags, + 'profile-timeline' : ProfileFakeDb.timeline, + 'profile-photos-videos': ProfileFakeDb.photosVideos, + 'profile-about' : ProfileFakeDb.about }; } - - /*get(args): Observable - { - console.log(args); - - // return new Observable - - return Observable.create((observer: Observer) => - { - const response = new Response({id: '1111'}); - observer.next(response); - }); - - }*/ } diff --git a/src/app/fuse-fake-db/profile.ts b/src/app/fuse-fake-db/profile.ts new file mode 100644 index 00000000..61bc7076 --- /dev/null +++ b/src/app/fuse-fake-db/profile.ts @@ -0,0 +1,360 @@ +export class ProfileFakeDb +{ + public static timeline = { + activities: [ + { + 'user' : { + 'name' : 'Alice Freeman', + 'avatar': 'assets/images/avatars/alice.jpg' + }, + 'message': 'started following you.', + 'time' : '13 mins. ago' + }, + { + 'user' : { + 'name' : 'Andrew Green', + 'avatar': 'assets/images/avatars/andrew.jpg' + }, + 'message': 'sent you a message.', + 'time' : 'June 10,2015' + }, + { + 'user' : { + 'name' : 'Garry Newman', + 'avatar': 'assets/images/avatars/garry.jpg' + }, + 'message': 'shared a public post with your group.', + 'time' : 'June 9,2015' + }, + { + 'user' : { + 'name' : 'Carl Henderson', + 'avatar': 'assets/images/avatars/carl.jpg' + }, + 'message': 'wants to play Fallout Shelter with you.', + 'time' : 'June 8,2015' + }, + { + 'user' : { + 'name' : 'Jane Dean', + 'avatar': 'assets/images/avatars/jane.jpg' + }, + 'message': 'started following you.', + 'time' : 'June 7,2015' + }, + { + 'user' : { + 'name' : 'Juan Carpenter', + 'avatar': 'assets/images/avatars/james.jpg' + }, + 'message': 'sent you a message.', + 'time' : 'June 6,2015' + }, + { + 'user' : { + 'name' : 'Judith Burton', + 'avatar': 'assets/images/avatars/joyce.jpg' + }, + 'message': 'shared a photo with you.', + 'time' : 'June 5,2015' + }, + { + 'user' : { + 'name' : 'Vincent Munoz', + 'avatar': 'assets/images/avatars/vincent.jpg' + }, + 'message': 'shared a photo with you.', + 'time' : 'June 4,2015' + } + ], + posts : [ + { + 'user' : { + 'name' : 'Garry Newman', + 'avatar': 'assets/images/avatars/garry.jpg' + }, + 'message' : 'Remember the place we were talking about the other night? Found it!', + 'time' : '32 minutes ago', + 'type' : 'post', + 'like' : 5, + 'share' : 21, + 'media' : { + 'type' : 'image', + 'preview': 'assets/images/etc/early-sunrise.jpg' + }, + 'comments': [ + { + 'user' : { + 'name' : 'Alice Freeman', + 'avatar': 'assets/images/avatars/alice.jpg' + }, + 'time' : 'June 10, 2015', + 'message': 'That’s a wonderful place. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce et eleifend ligula. Fusce posuere in sapien ac facilisis. Etiam sit amet justo non felis ornare feugiat.' + } + ] + }, + { + 'user' : { + 'name' : 'Andrew Green', + 'avatar': 'assets/images/avatars/andrew.jpg' + }, + 'message' : 'Hey, man! Check this, it’s pretty awesome!', + 'time' : 'June 12, 2015', + 'type' : 'article', + 'like' : 98, + 'share' : 6, + 'article' : { + 'title' : 'The Fallout 4 Pip-Boy Edition Is Back In Stock Now', + 'subtitle': 'Kotaku', + 'excerpt' : 'The Fallout 4 Pip-Boy edition is back in stock at Gamestop, for all 3 platforms. Additionally, Walmart also has it in stock for the PS4 and Xbox One as of this writing, as does Best Buy.', + 'media' : { + 'type' : 'image', + 'preview': 'assets/images/etc/fallout.jpg' + } + }, + 'comments': [ + { + 'user' : { + 'name' : 'Alice Freeman', + 'avatar': 'assets/images/avatars/alice.jpg' + }, + 'time' : 'June 10, 2015', + 'message': 'That’s a wonderful place. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce et eleifend ligula. Fusce posuere in sapien ac facilisis. Etiam sit amet justo non felis ornare feugiat.' + } + ] + }, + { + 'user' : { + 'name' : 'Carl Henderson', + 'avatar': 'assets/images/avatars/carl.jpg' + }, + 'message': 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce et eleifend ligula. Fusce posuere in sapien ac facilisis. Etiam sit amet justo non felis ornare feugiat. Aenean lorem ex, ultrices sit amet ligula sed...', + 'time' : 'June 10, 2015', + 'type' : 'something', + 'like' : 4, + 'share' : 1 + } + ] + }; + + public static photosVideos = [ + { + 'name' : 'June 2015', + 'info' : '5 Photos', + 'media': [ + { + 'type' : 'photo', + 'title' : 'Mountain Sunset', + 'preview': 'assets/images/etc/mountain-sunset.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Mountain Lake', + 'preview': 'assets/images/etc/mountain-lake.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Hot air balloons', + 'preview': 'assets/images/etc/air-balloons.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Cactus', + 'preview': 'assets/images/etc/cactus.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Road Trip', + 'preview': 'assets/images/etc/road-trip.jpg' + } + ] + }, + { + 'name' : 'May 2015', + 'info' : '7 Photos, 3 Videos', + 'media': [ + { + 'type' : 'photo', + 'title' : 'Mountain Sunset', + 'preview': 'assets/images/etc/mountain-sunset.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Mountain Lake', + 'preview': 'assets/images/etc/mountain-lake.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Hot air balloons', + 'preview': 'assets/images/etc/air-balloons.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Cactus', + 'preview': 'assets/images/etc/cactus.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Road Trip', + 'preview': 'assets/images/etc/road-trip.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Mountain Sunset', + 'preview': 'assets/images/etc/mountain-sunset.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Mountain Lake', + 'preview': 'assets/images/etc/mountain-lake.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Hot air balloons', + 'preview': 'assets/images/etc/air-balloons.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Cactus', + 'preview': 'assets/images/etc/cactus.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Road Trip', + 'preview': 'assets/images/etc/road-trip.jpg' + } + ] + }, + { + 'name' : 'April 2015', + 'info' : '5 Photos', + 'media': [ + { + 'type' : 'photo', + 'title' : 'Mountain Sunset', + 'preview': 'assets/images/etc/mountain-sunset.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Mountain Lake', + 'preview': 'assets/images/etc/mountain-lake.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Hot air balloons', + 'preview': 'assets/images/etc/air-balloons.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Cactus', + 'preview': 'assets/images/etc/cactus.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Road Trip', + 'preview': 'assets/images/etc/road-trip.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Mountain Sunset', + 'preview': 'assets/images/etc/mountain-sunset.jpg' + }, + { + 'type' : 'photo', + 'title' : 'Mountain Lake', + 'preview': 'assets/images/etc/mountain-lake.jpg' + } + ] + } + ]; + + public static about = { + 'general': { + 'gender' : 'Female', + 'birthday' : 'May 8th, 1988', + 'locations': [ + 'Istanbul, Turkey', + 'New York, USA' + ], + 'about' : 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis eget pharetra felis, sed ullamcorper dui. Sed et elementum neque. Vestibulum pellente viverra ultrices. Etiam justo augue, vehicula ac gravida a, interdum sit amet nisl. Integer vitae nisi id nibh dictum mollis in vitae tortor.' + }, + 'work' : { + 'occupation': 'Developer', + 'skills' : 'C#, PHP, Javascript, Angular, JS, HTML, CSS', + 'jobs' : [ + { + 'company': 'Self-Employed', + 'date' : '2010 - Now' + }, + { + 'company': 'Google', + 'date' : '2008 - 2010' + } + ] + }, + 'contact': { + 'address' : 'Ut pharetra luctus est quis sodales. Duis nisi tortor, bibendum eget tincidunt, aliquam ac elit. Mauris nec euismod odio.', + 'tel' : [ + '+6 555 6600', + '+9 555 5255' + ], + 'websites': [ + 'withinpixels.com' + ], + 'emails' : [ + 'mail@withinpixels.com', + 'mail@creapond.com' + ] + }, + 'groups' : [ + { + 'logo' : 'assets/images/logos/android.png', + 'name' : 'Android', + 'category': 'Technology', + 'members' : '1.856.546' + }, + { + 'logo' : 'assets/images/logos/google.png', + 'name' : 'Google', + 'category': 'Web', + 'members' : '1.226.121' + }, + { + 'logo' : 'assets/images/logos/fallout.png', + 'name' : 'Fallout', + 'category': 'Games', + 'members' : '526.142' + } + ], + 'friends': [ + { + 'name' : 'Garry Newman', + 'avatar': 'assets/images/avatars/garry.jpg' + }, + { + 'name' : 'Carl Henderson', + 'avatar': 'assets/images/avatars/carl.jpg' + }, + { + 'name' : 'Jane Dean', + 'avatar': 'assets/images/avatars/jane.jpg' + }, + { + 'name' : 'Garry Arnold', + 'avatar': 'assets/images/avatars/garry.jpg' + }, + { + 'name' : 'Vincent Munoz', + 'avatar': 'assets/images/avatars/vincent.jpg' + }, + { + 'name' : 'Alice Freeman', + 'avatar': 'assets/images/avatars/alice.jpg' + }, + { + 'name' : 'Andrew Green', + 'avatar': 'assets/images/avatars/andrew.jpg' + } + ] + }; +} diff --git a/src/app/main/apps/mail/mail.component.ts b/src/app/main/apps/mail/mail.component.ts index a4812a2f..15d69170 100644 --- a/src/app/main/apps/mail/mail.component.ts +++ b/src/app/main/apps/mail/mail.component.ts @@ -2,7 +2,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { MailService } from './mail.service'; import { Subscription } from 'rxjs/Subscription'; import { FormControl } from '@angular/forms'; -import { FuseUtils } from '../../../core/fuseUtils'; @Component({ selector : 'fuse-mail', @@ -30,7 +29,6 @@ export class MailComponent implements OnInit, OnDestroy ngOnInit() { - this.onSelectedMailsChanged = this.mailService.onSelectedMailsChanged .subscribe(selectedMails => { diff --git a/src/app/main/apps/mail/mail.service.ts b/src/app/main/apps/mail/mail.service.ts index 9b85f6cc..d789da52 100644 --- a/src/app/main/apps/mail/mail.service.ts +++ b/src/app/main/apps/mail/mail.service.ts @@ -4,7 +4,7 @@ import { Observable } from 'rxjs/Observable'; import { Http } from '@angular/http'; import { Mail } from './mail.model'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; -import { FuseUtils } from "app/core/fuseUtils"; +import { FuseUtils } from 'app/core/fuseUtils'; @Injectable() export class MailService implements Resolve diff --git a/src/app/main/pages/maintenance/maintenance.component.html b/src/app/main/pages/maintenance/maintenance.component.html new file mode 100644 index 00000000..1f678977 --- /dev/null +++ b/src/app/main/pages/maintenance/maintenance.component.html @@ -0,0 +1,21 @@ +
+ +
+ +
+ + + +
Closed for scheduled maintenance!
+ +
+ We're sorry for the inconvenience.
Please check back later. +
+ +
+ +
+ +
\ No newline at end of file diff --git a/src/app/main/pages/maintenance/maintenance.component.scss b/src/app/main/pages/maintenance/maintenance.component.scss new file mode 100644 index 00000000..cbcd83b1 --- /dev/null +++ b/src/app/main/pages/maintenance/maintenance.component.scss @@ -0,0 +1,56 @@ +@import "src/app/core/scss/fuse"; + +:host { + + #maintenance { + height: 100%; + background: url('/assets/images/backgrounds/march.jpg') no-repeat; + background-size: cover; + + #maintenance-form-wrapper { + flex: 1 0 auto; + padding: 32px; + + @include media-breakpoint('xs') { + padding: 16px; + } + + #maintenance-form { + max-width: 384px; + padding: 32px; + background: #FFFFFF; + text-align: center; + @include mat-elevation(7); + + @include media-breakpoint('xs') { + padding: 24px; + width: 100%; + } + + .logo { + width: 128px; + height: 128px; + line-height: 128px; + font-size: 86px; + font-weight: 500; + margin: 32px auto; + color: rgba(255, 255, 255, 1); + border-radius: 2px; + background: mat-color($accent); + } + + .title { + font-size: 17px; + margin-top: 16px; + } + + .subtitle { + margin: 16px 0; + max-width: 300px; + color: rgba(0, 0, 0, 0.54); + font-size: 15px; + } + } + } + } +} \ No newline at end of file diff --git a/src/app/main/pages/maintenance/maintenance.component.ts b/src/app/main/pages/maintenance/maintenance.component.ts new file mode 100644 index 00000000..f0441be3 --- /dev/null +++ b/src/app/main/pages/maintenance/maintenance.component.ts @@ -0,0 +1,25 @@ +import { Component, OnInit } from '@angular/core'; + +import { FuseLayoutService } from '../../../core/services/layout.service'; + +@Component({ + selector : 'fuse-maintenance', + templateUrl: './maintenance.component.html', + styleUrls : ['./maintenance.component.scss'] +}) +export class MaintenanceComponent implements OnInit +{ + constructor(private layoutService: FuseLayoutService) + { + this.layoutService.setSettings({ + navigation: 'none', + toolbar : 'none', + footer : 'none' + }); + } + + ngOnInit() + { + + } +} diff --git a/src/app/main/pages/pages.module.ts b/src/app/main/pages/pages.module.ts index d2e6e16d..92070061 100644 --- a/src/app/main/pages/pages.module.ts +++ b/src/app/main/pages/pages.module.ts @@ -12,6 +12,10 @@ import { LockComponent } from './authentication/lock/lock.component'; import { ComingSoonComponent } from './coming-soon/coming-soon.component'; import { Error404Component } from './errors/404/error-404.component'; import { Error500Component } from './errors/500/error-500.component'; +import { MaintenanceComponent } from './maintenance/maintenance.component'; +import { ProfileComponent } from './profile/profile.component'; +import { ProfileModule } from './profile/profile.module'; +import { ProfileService } from './profile/profile.service'; const routes = [ { @@ -53,13 +57,25 @@ const routes = [ { path : 'pages/errors/error-500', component: Error500Component + }, + { + path : 'pages/maintenance', + component: MaintenanceComponent + }, + { + path : 'pages/profile', + component: ProfileComponent, + resolve : { + profile: ProfileService + } } ]; @NgModule({ imports : [ SharedModule, - RouterModule.forChild(routes) + RouterModule.forChild(routes), + ProfileModule ], declarations: [ LoginComponent, @@ -71,7 +87,11 @@ const routes = [ LockComponent, ComingSoonComponent, Error404Component, - Error500Component + Error500Component, + MaintenanceComponent + ], + providers : [ + ProfileService ] }) export class PagesModule diff --git a/src/app/main/pages/profile/profile.component.html b/src/app/main/pages/profile/profile.component.html new file mode 100644 index 00000000..0bcae18c --- /dev/null +++ b/src/app/main/pages/profile/profile.component.html @@ -0,0 +1,43 @@ +
+ + +
+ + + +
+ + +
+ +
+ + + +
+ + + + + + + + + + + + + + + + + +
+ + +
\ No newline at end of file diff --git a/src/app/main/pages/profile/profile.component.scss b/src/app/main/pages/profile/profile.component.scss new file mode 100644 index 00000000..a7e5e542 --- /dev/null +++ b/src/app/main/pages/profile/profile.component.scss @@ -0,0 +1,43 @@ +@import "src/app/core/scss/fuse"; + +:host { + + #profile { + + .header { + height: 320px; + min-height: 320px; + max-height: 320px; + background: url('/assets/images/backgrounds/march.jpg') no-repeat 0 45%; + background-size: 100% auto; + + .profile-image { + margin-right: 24px; + + @include media-breakpoint('sm') { + margin: 0 0 16px 0; + } + } + + .name { + font-size: 34px; + color: #FFFFFF; + + @include media-breakpoint('sm') { + margin-bottom: 32px; + } + } + + .actions { + + button { + text-transform: none; + padding: 0 16px; + height: 32px; + line-height: 32px; + margin: 0 0 0 8px; + } + } + } + } +} \ No newline at end of file diff --git a/src/app/main/pages/profile/profile.component.ts b/src/app/main/pages/profile/profile.component.ts new file mode 100644 index 00000000..0aba0970 --- /dev/null +++ b/src/app/main/pages/profile/profile.component.ts @@ -0,0 +1,20 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector : 'fuse-profile', + templateUrl: './profile.component.html', + styleUrls : ['./profile.component.scss'] +}) +export class ProfileComponent implements OnInit +{ + + constructor() + { + + } + + ngOnInit() + { + + } +} diff --git a/src/app/main/pages/profile/profile.module.ts b/src/app/main/pages/profile/profile.module.ts new file mode 100644 index 00000000..a9adca04 --- /dev/null +++ b/src/app/main/pages/profile/profile.module.ts @@ -0,0 +1,28 @@ +import { NgModule } from '@angular/core'; +import { SharedModule } from '../../../core/modules/shared.module'; + +import { ProfileComponent } from './profile.component'; +import { ProfileTimelineComponent } from './tabs/timeline/timeline.component'; +import { ProfileAboutComponent } from './tabs/about/about.component'; +import { ProfilePhotosVideosComponent } from './tabs/photos-videos/photos-videos.component'; + +@NgModule({ + imports : [ + SharedModule + ], + exports : [ + ProfileComponent, + ProfileTimelineComponent, + ProfileAboutComponent, + ProfilePhotosVideosComponent + ], + declarations: [ + ProfileComponent, + ProfileTimelineComponent, + ProfileAboutComponent, + ProfilePhotosVideosComponent + ] +}) +export class ProfileModule +{ +} diff --git a/src/app/main/pages/profile/profile.service.ts b/src/app/main/pages/profile/profile.service.ts new file mode 100644 index 00000000..f623648d --- /dev/null +++ b/src/app/main/pages/profile/profile.service.ts @@ -0,0 +1,92 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router'; +import { Observable } from 'rxjs/Observable'; +import { Http } from '@angular/http'; +import { BehaviorSubject } from 'rxjs/BehaviorSubject'; + +@Injectable() +export class ProfileService implements Resolve +{ + timeline: any; + about: any; + photosVideos: any; + + timelineOnChanged: BehaviorSubject = new BehaviorSubject({}); + aboutOnChanged: BehaviorSubject = new BehaviorSubject({}); + photosVideosOnChanged: BehaviorSubject = new BehaviorSubject({}); + + constructor(private http: Http) + { + } + + /** + * Resolve + * @param {ActivatedRouteSnapshot} route + * @param {RouterStateSnapshot} state + * @returns {Observable | Promise | any} + */ + resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable | Promise | any + { + return new Promise((resolve, reject) => { + Promise.all([ + this.getTimeline(), + this.getAbout(), + this.getPhotosVideos() + ]).then( + () => { + resolve(); + }, + reject + ); + }); + } + + /** + * Get timeline + */ + getTimeline(): Promise + { + return new Promise((resolve, reject) => { + + this.http.get('api/profile-timeline') + .subscribe(timeline => { + this.timeline = timeline.json().data; + this.timelineOnChanged.next(this.timeline); + resolve(this.timeline); + }, reject); + }); + } + + /** + * Get about + */ + getAbout(): Promise + { + return new Promise((resolve, reject) => { + + this.http.get('api/profile-about') + .subscribe(about => { + this.about = about.json().data; + this.aboutOnChanged.next(this.about); + resolve(this.about); + }, reject); + }); + } + + /** + * Get photos & videos + */ + getPhotosVideos(): Promise + { + return new Promise((resolve, reject) => { + + this.http.get('api/profile-photos-videos') + .subscribe(photosVideos => { + this.photosVideos = photosVideos.json().data; + this.photosVideosOnChanged.next(this.photosVideos); + resolve(this.photosVideos); + }, reject); + }); + } + +} diff --git a/src/app/main/pages/profile/tabs/about/about.component.html b/src/app/main/pages/profile/tabs/about/about.component.html new file mode 100644 index 00000000..2c5c18cc --- /dev/null +++ b/src/app/main/pages/profile/tabs/about/about.component.html @@ -0,0 +1,157 @@ +
+ +
+ +
+ +
+
General Information
+
+ +
+
+
Gender
+
{{about.general.gender}}
+
+ +
+
Birthday
+
{{about.general.birthday}}
+
+ +
+
Locations
+
+ {{location}} + location_on +
+
+ +
+
About Me
+
{{about.general.about}}
+
+
+ +
+ +
+ +
+
Work
+
+ +
+
+
Occupation
+
{{about.work.occupation}}
+
+ +
+
Skills
+
{{about.work.skills}}
+
+ +
+
Jobs
+ + + + + +
{{job.company}}{{job.date}}
+
+
+
+ +
+ +
+
Contact
+
+ +
+
+
Address
+
{{about.contact.address}}
+
+
+
Tel.
+
+ {{tel}} +
+
+
+
Website
+
+ {{website}} +
+
+
+
Emails
+
+ {{email}} +
+
+
+ +
+ +
+ +
+ +
+ +
+
Friends
+
+ See 454 more... +
+
+ +
+
+ +
+
+ +
+ +
+ +
+
Joined Groups
+
+ See 6 more... +
+
+ +
+ +
+ +
+ + + +
+
{{group.name}}
+
{{group.category}}
+
{{group.members}} people
+
+
+ + +
+
+ +
+ +
+ +
diff --git a/src/app/main/pages/profile/tabs/about/about.component.scss b/src/app/main/pages/profile/tabs/about/about.component.scss new file mode 100644 index 00000000..f6e48ded --- /dev/null +++ b/src/app/main/pages/profile/tabs/about/about.component.scss @@ -0,0 +1,139 @@ +@import "src/app/core/scss/fuse"; + +:host { + + #about { + max-width: 1200px; + + .about { + padding: 8px; + + .general { + + .location { + + md-icon { + line-height: 13px !important; + } + } + } + + .work { + + .job { + + .company { + padding: 0 16px 0 0; + font-weight: 500; + } + + .date { + color: rgba(0, 0, 0, 0.54); + } + } + } + } + + .about-sidebar { + padding: 8px 8px 8px 32px; + + @include media-breakpoint('sm') { + padding: 8px + } + + .friends { + + .content { + + .friend { + padding: 4px; + } + } + } + + .groups { + + .content { + + .group { + margin-bottom: 16px; + + &:last-child { + margin-bottom: 0; + } + + .logo { + border: 1px solid rgba(0, 0, 0, 0.12); + margin-right: 16px; + } + + .name { + font-weight: 500; + font-size: 15px; + } + + .category, + .members { + color: rgba(0, 0, 0, 0.54); + } + + .members { + margin-top: 16px; + } + } + } + } + } + } + + // Profile boxes + .profile-box { + margin-bottom: 16px; + @include mat-elevation(2); + + header { + padding: 16px; + background: mat-color($primary); + + .title { + font-size: 17px; + } + + .more { + cursor: pointer; + } + } + + .content { + padding: 16px; + background-color: #FFF; + } + + footer { + padding: 8px; + border-top: 1px solid rgba(0, 0, 0, 0.08); + background-color: rgba(0, 0, 0, 0.06); + } + + &.info-box { + + .info-line { + margin-bottom: 24px; + + .title { + font-size: 15px; + font-weight: 500; + padding-bottom: 4px; + } + + .info { + + } + + &:last-child { + margin-bottom: 0; + } + } + } + } +} \ No newline at end of file diff --git a/src/app/main/pages/profile/tabs/about/about.component.ts b/src/app/main/pages/profile/tabs/about/about.component.ts new file mode 100644 index 00000000..8cae6ac4 --- /dev/null +++ b/src/app/main/pages/profile/tabs/about/about.component.ts @@ -0,0 +1,24 @@ +import { Component, OnInit } from '@angular/core'; +import { ProfileService } from '../../profile.service'; + +@Component({ + selector : 'fuse-profile-about', + templateUrl: './about.component.html', + styleUrls : ['./about.component.scss'] +}) +export class ProfileAboutComponent implements OnInit +{ + about: any; + + constructor(private profileService: ProfileService) + { + this.profileService.aboutOnChanged.subscribe(about => { + this.about = about; + }); + } + + ngOnInit() + { + + } +} diff --git a/src/app/main/pages/profile/tabs/photos-videos/photos-videos.component.html b/src/app/main/pages/profile/tabs/photos-videos/photos-videos.component.html new file mode 100644 index 00000000..db4b2d40 --- /dev/null +++ b/src/app/main/pages/profile/tabs/photos-videos/photos-videos.component.html @@ -0,0 +1,15 @@ +
+
+
+ {{period.name}} + {{period.info}} +
+ +
+
+ +
{{media.title}}
+
+
+
+
diff --git a/src/app/main/pages/profile/tabs/photos-videos/photos-videos.component.scss b/src/app/main/pages/profile/tabs/photos-videos/photos-videos.component.scss new file mode 100644 index 00000000..b8beffbd --- /dev/null +++ b/src/app/main/pages/profile/tabs/photos-videos/photos-videos.component.scss @@ -0,0 +1,54 @@ +@import "src/app/core/scss/fuse"; + +:host { + + #photos-videos { + padding: 8px; + + .period { + + .period-title { + margin-bottom: 24px; + + .name { + font-size: 20px; + } + + .info { + margin-left: 16px; + font-size: 15px; + color: rgba(0, 0, 0, 0.54); + } + } + + .period-media { + margin-bottom: 16px; + + .media { + margin: 0 16px 16px 0; + position: relative; + + .preview { + width: 256px; + height: 256px; + display: block; + } + + .title { + position: absolute; + bottom: 0; + left: 0; + right: 0; + z-index: 10; + padding: 0 16px; + height: 48px; + line-height: 48px; + background: rgba(0, 0, 0, 0.54); + color: #FFF; + font-size: 15px; + } + } + } + } + } +} \ No newline at end of file diff --git a/src/app/main/pages/profile/tabs/photos-videos/photos-videos.component.ts b/src/app/main/pages/profile/tabs/photos-videos/photos-videos.component.ts new file mode 100644 index 00000000..6ecca1b0 --- /dev/null +++ b/src/app/main/pages/profile/tabs/photos-videos/photos-videos.component.ts @@ -0,0 +1,25 @@ +import { Component, OnInit } from '@angular/core'; + +import { ProfileService } from '../../profile.service'; + +@Component({ + selector : 'fuse-profile-photos-videos', + templateUrl: './photos-videos.component.html', + styleUrls : ['./photos-videos.component.scss'] +}) +export class ProfilePhotosVideosComponent implements OnInit +{ + photosVideos: any; + + constructor(private profileService: ProfileService) + { + this.profileService.photosVideosOnChanged.subscribe(photosVideos => { + this.photosVideos = photosVideos; + }); + } + + ngOnInit() + { + + } +} diff --git a/src/app/main/pages/profile/tabs/timeline/timeline.component.html b/src/app/main/pages/profile/tabs/timeline/timeline.component.html new file mode 100644 index 00000000..230832cd --- /dev/null +++ b/src/app/main/pages/profile/tabs/timeline/timeline.component.html @@ -0,0 +1,164 @@ +
+ +
+ +
+ +
+ + + +
+ +
+ + + + + + + +
+ + +
+ +
+ +
+ + + +
+ +
+
+ + +
+
+ {{post.user.name}} + posted on your timeline + shared something with you + shared a video with you + shared an article with you +
+
{{post.time}}
+
+
+ + +
+ +
+
+ {{post.message}} +
+ +
+ +
+
+ +
+
+ +
+
{{post.article.title}}
+
{{post.article.subtitle}}
+
{{post.article.excerpt}}
+
+ +
+ + +
+
+ +
+
+ {{post.comments.length}} comments + keyboard_arrow_down +
+ +
+ + +
+
+ {{comment.user.name}} + {{comment.time}} +
+
+ {{comment.message}} +
+
+ Reply + flag +
+
+
+ +
+ + +
+ + +
+
+
+
+
+ +
+ +
+
+
Latest Activity
+
See All
+
+ +
+
+
+ {{activity.user.name}} + +
+
+ {{activity.user.name}} + {{activity.message}} +
+ {{activity.time}} +
+
+
+
+
+
+ +
+ diff --git a/src/app/main/pages/profile/tabs/timeline/timeline.component.scss b/src/app/main/pages/profile/tabs/timeline/timeline.component.scss new file mode 100644 index 00000000..38b49cbb --- /dev/null +++ b/src/app/main/pages/profile/tabs/timeline/timeline.component.scss @@ -0,0 +1,311 @@ +@import "src/app/core/scss/fuse"; + +:host { + + #timeline { + max-width: 1200px; + + .timeline { + padding: 8px; + + .add-post { + margin-bottom: 0; + @include mat-elevation(2); + + textarea { + display: flex; + flex: 1 0 auto; + font-size: 13px; + width: 100%; + height: 140px; + border: none; + padding: 16px; + resize: vertical; + } + + footer { + padding: 8px; + border-top: 1px solid rgba(0, 0, 0, 0.08); + background: #F3F4F5; + + .post-button { + margin: 0; + width: 64px; + min-width: 64px; + height: 30px; + line-height: 30px; + min-height: 30px; + } + } + } + + md-divider { + border-top-width: 1px; + border-top-style: solid; + margin: 32px 0; + } + + .timeline-item { + margin-bottom: 32px; + overflow: hidden; + border-radius: 2px; + background: #FFFFFF; + @include mat-elevation(2); + + &:last-child { + margin-bottom: 0; + } + + header { + padding: 16px 0 8px 16px; + + .title { + font-weight: 500; + + .username { + margin-right: 2px; + color: mat-color($accent); + } + } + + .time { + color: rgba(0, 0, 0, 0.54); + } + } + + .content { + + .message { + padding: 16px; + } + + .media { + padding: 16px; + + img, iframe { + width: 100%; + } + + a { + color: inherit; + } + } + + .like-button, + .share-button { + padding: 4px 6px; + text-transform: inherit; + font-size: 13px; + font-weight: normal; + margin: 0 0 16px 8px; + min-width: inherit; + line-height: inherit; + + &:hover { + background-color: transparent; + } + + md-icon { + margin: 0 8px 0 0; + } + } + + .article { + border: 1px solid rgba(0, 0, 0, 0.12); + margin: 16px; + + .media { + padding: 0; + overflow: hidden; + border-bottom: 1px solid rgba(0, 0, 0, 0.12); + + img { + display: block; + padding: 0; + } + + } + + .title { + font-size: 15px; + padding: 16px 16px 4px 16px; + } + + .subtitle { + padding: 0 16px; + color: rgba(0, 0, 0, 0.54); + } + + .excerpt { + padding: 16px 16px; + } + } + } + + footer { + border-top: 1px solid rgba(0, 0, 0, 0.08); + background-color: rgba(0, 0, 0, 0.04); + padding: 16px; + + .comment-count { + margin-bottom: 16px; + cursor: pointer; + + md-icon { + margin-left: 8px; + } + } + + .comment { + margin-bottom: 24px !important; + + .username { + font-weight: 500; + margin-right: 4px; + } + + .message { + color: rgba(0, 0, 0, 0.87); + } + + .time { + color: rgba(0, 0, 0, 0.54); + } + + .actions { + margin-top: 8px; + + .reply-button { + margin-right: 16px; + cursor: pointer; + color: mat-color($accent); + } + + .report-button { + margin: 0; + cursor: pointer; + } + } + } + + .reply { + + form { + + textarea { + width: 100% !important; + min-height: 72px; + padding: 8px; + margin-bottom: 8px; + font-size: 13px; + border: 1px solid rgba(0, 0, 0, 0.12); + } + + .post-comment-button { + margin: 0; + text-transform: inherit; + font-weight: normal; + padding: 0 12px; + min-height: 30px; + min-width: inherit; + line-height: 30px; + } + } + } + } + } + } + + .timeline-sidebar { + padding: 8px 8px 8px 32px; + + @include media-breakpoint('sm') { + padding: 8px + } + + .latest-activity { + + header { + background: mat-color($primary); + } + + .content { + background-color: #FFF; + + .activities { + + .activity { + padding: 16px 0; + + .avatar { + margin-right: 16px; + } + + .username { + font-weight: 500; + color: mat-color($accent) + } + + .message { + font-weight: 500; + } + + .time { + } + } + } + } + } + } + } + + // Profile boxes + .profile-box { + margin-bottom: 16px; + @include mat-elevation(2); + + header { + padding: 16px; + + .title { + font-size: 17px; + } + + .more { + cursor: pointer; + } + } + + .content { + padding: 16px; + background-color: #FFF; + } + + footer { + padding: 8px; + border-top: 1px solid rgba(0, 0, 0, 0.08); + background-color: rgba(0, 0, 0, 0.06); + } + + &.info-box { + + .info-line { + margin-bottom: 24px; + + .title { + font-size: 15px; + font-weight: 500; + padding-bottom: 4px; + } + + .info { + + } + + &:last-child { + margin-bottom: 0; + } + } + } + } +} \ No newline at end of file diff --git a/src/app/main/pages/profile/tabs/timeline/timeline.component.ts b/src/app/main/pages/profile/tabs/timeline/timeline.component.ts new file mode 100644 index 00000000..5e30e50b --- /dev/null +++ b/src/app/main/pages/profile/tabs/timeline/timeline.component.ts @@ -0,0 +1,24 @@ +import { Component, OnInit } from '@angular/core'; +import { ProfileService } from '../../profile.service'; + +@Component({ + selector : 'fuse-profile-timeline', + templateUrl: './timeline.component.html', + styleUrls : ['./timeline.component.scss'] +}) +export class ProfileTimelineComponent implements OnInit +{ + timeline: any; + + constructor(private profileService: ProfileService) + { + this.profileService.timelineOnChanged.subscribe(timeline => { + this.timeline = timeline; + }); + } + + ngOnInit() + { + + } +}