Skip to content

Commit

Permalink
UPDATE: Creation the main functionnalities
Browse files Browse the repository at this point in the history
* Creating Card & CardList component
* Auth page
* Nearby shops page
* Favorite shops page
  • Loading branch information
ouladck committed Sep 17, 2018
1 parent 11f62b7 commit a41dece
Show file tree
Hide file tree
Showing 24 changed files with 367 additions and 51 deletions.
18 changes: 15 additions & 3 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,15 @@
"src/assets"
],
"styles": [
"node_modules/font-awesome/css/font-awesome.min.css",
"node_modules/bootstrap/dist/css/bootstrap.css",
"node_modules/ngx-toastr/toastr.css",
"src/styles.css"
],
"scripts": []
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/bootstrap/dist/js/bootstrap.js"
]
},
"configurations": {
"production": {
Expand Down Expand Up @@ -72,9 +78,15 @@
"tsConfig": "src/tsconfig.spec.json",
"karmaConfig": "src/karma.conf.js",
"styles": [
"node_modules/font-awesome/css/font-awesome.min.css",
"node_modules/bootstrap/dist/css/bootstrap.css",
"node_modules/ngx-toastr/toastr.css",
"src/styles.css"
],
"scripts": [],
"scripts": [
"node_modules/jquery/dist/jquery.min.js",
"node_modules/bootstrap/dist/js/bootstrap.js"
],
"assets": [
"src/favicon.ico",
"src/assets"
Expand Down Expand Up @@ -124,4 +136,4 @@
}
},
"defaultProject": "nearby-shops-front"
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
},
"private": true,
"dependencies": {
"@angular/animations": "^6.1.1",
"@angular/animations": "^6.1.7",
"@angular/common": "^6.1.1",
"@angular/compiler": "^6.1.1",
"@angular/core": "^6.1.1",
Expand All @@ -28,6 +28,7 @@
"font-awesome": "^4.7.0",
"jquery": "^3.3.1",
"ngx-auth": "^4.1.0",
"ngx-bootstrap": "^3.0.1",
"ngx-toastr": "^9.0.2",
"popper.js": "^1.14.4",
"rxjs": "^6.0.0",
Expand Down
8 changes: 7 additions & 1 deletion src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,22 @@ import { Routes, RouterModule } from '@angular/router';
import { AuthComponent } from './components/layouts/auth/auth.component';
import { AppComponent } from './components/layouts/app/app.component';
import { PublicGuard, ProtectedGuard } from 'ngx-auth';
import {LogoutComponent} from './modules/auth/components/logout/logout.component';

const routes: Routes = [
{
path: 'auth',
component: AuthComponent,
canActivate: [PublicGuard],
children: [
{
path: '',
canActivate: [PublicGuard],
loadChildren: './modules/auth/auth.module#AuthModule'
},
{
path: 'logout',
canActivate: [ProtectedGuard],
component: LogoutComponent
}
],
},
Expand Down
25 changes: 13 additions & 12 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {CUSTOM_ELEMENTS_SCHEMA, NgModule, NO_ERRORS_SCHEMA} from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CardComponent } from './components/card/card.component';
import { CardListComponent } from './components/card-list/card-list.component';
import { AuthModule as AppAuthModule } from './modules/auth/auth.module';
import { ShopsModule } from './modules/shops/shops.module';
import { AuthComponent } from './components/layouts/auth/auth.component';
import { AppComponent as LayoutAppComponent } from './components/layouts/app/app.component';
import {HTTP_INTERCEPTORS, HttpClientModule} from '@angular/common/http';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { TokenInterceptor } from './interceptors/token.interceptors';
import {ProtectedGuard, PublicGuard, AuthModule, PROTECTED_FALLBACK_PAGE_URI, PUBLIC_FALLBACK_PAGE_URI, AUTH_SERVICE} from 'ngx-auth';
import {AuthenticationService} from './services/authentication.service';
import {HttpModule} from '@angular/http';
import { AuthModule, PROTECTED_FALLBACK_PAGE_URI, PUBLIC_FALLBACK_PAGE_URI, AUTH_SERVICE } from 'ngx-auth';
import { AuthenticationService } from './services/authentication.service';
import { HttpModule } from '@angular/http';
import { ToastrModule } from 'ngx-toastr';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
declarations: [
AppComponent,
CardComponent,
CardListComponent,
AuthComponent,
LayoutAppComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
AppRoutingModule,
HttpModule,
HttpClientModule,
AppAuthModule,
ToastrModule.forRoot(),
AuthModule,
ShopsModule
],
Expand All @@ -37,10 +37,11 @@ import {HttpModule} from '@angular/http';
useClass: TokenInterceptor,
multi: true
},
{ provide: PROTECTED_FALLBACK_PAGE_URI, useValue: '/' },
{ provide: PUBLIC_FALLBACK_PAGE_URI, useValue: '/login' },
{ provide: AUTH_SERVICE, useClass: AuthenticationService }
{ provide: PROTECTED_FALLBACK_PAGE_URI, useValue: '/shops/nearby' },
{ provide: PUBLIC_FALLBACK_PAGE_URI, useValue: '/auth/login' },
{ provide: AUTH_SERVICE, useClass: AuthenticationService }
],
schemas: [CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA],
bootstrap: [AppComponent]
})
export class AppModule { }
13 changes: 10 additions & 3 deletions src/app/components/card-list/card-list.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
<p>
card-list works!
</p>
<div class="card-deck">
<app-card *ngFor="let shop of data" [shop]="shop" (liked)="updateShops($event)" [is_favorite]="is_favorite"></app-card>
</div>

<div class="row">
<div class="col-xs-12 col-12">
<pagination [totalItems]="shops.total" [(ngModel)]="shops.current_page" [maxSize]="5" [boundaryLinks]="true" [itemsPerPage]="12" (pageChanged)="pageChanged($event)"></pagination>
</div>
</div>

48 changes: 45 additions & 3 deletions src/app/components/card-list/card-list.component.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,57 @@
import { Component, OnInit } from '@angular/core';
import {Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core';
import {ShopsService} from '../../services/shops.service';
import {ToastrService} from 'ngx-toastr';

@Component({
selector: 'app-card-list',
templateUrl: './card-list.component.html',
styleUrls: ['./card-list.component.css']
})
export class CardListComponent implements OnInit {
export class CardListComponent implements OnInit, OnChanges {

constructor() { }
@Input() shops: any;
@Input() is_favorite: boolean;
@Output() paginate = new EventEmitter<number>();
data: object[];

constructor(public shopsService: ShopsService,
public toastr: ToastrService) {
this.data = [];
this.is_favorite = false;
}

ngOnInit() {
this.data = this.shops.data;
}

ngOnChanges() {
this.data = this.shops.data;
}

/**
* Function to be used in trackBy for ngForOf
* @param index
* @param shop
*/
trackShop(index: number, shop: any) {
return shop ? shop.id : undefined;
}

/**
* Paginate to the page
* @param event
*/
pageChanged(event: any): void {
this.paginate.emit(event.page);
}

/**
* Update list of Shops after liking or disliking a shop ;-)
* @param update
*/
updateShops(update) {
if (update) {
this.pageChanged(this.shops.current_page);
}
}
}
15 changes: 12 additions & 3 deletions src/app/components/card/card.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
<p>
card works!
</p>
<div class="card" style="width: 18rem;">
<img class="card-img-top" src="{{ shop.picture }}" alt="Card image cap">
<div class="card-body">
<h5 class="card-title">{{ shop.name }}</h5>
<p class="card-text"><span class="">Email: {{ shop.email }}</span> <span class="">City: {{ shop.city }}</span></p>
</div>
<div class="card-body">
<button (click)="like(shop.id)" *ngIf="!is_favorite" class="card-link" ngClass="btn btn-success"><i class="fa fa-thumbs-up"></i> Like</button>
<button (click)="delete(shop.id)" *ngIf="is_favorite" class="card-link" ngClass="btn btn-warning"><i class="fa fa-times"></i> Delete</button>
<button class="card-link" *ngIf="!is_favorite" (click)="dislike(shop.id)" class="btn btn-danger pull-right"><i class="fa fa-thumbs-down"></i> Dislike</button>
</div>
</div>
37 changes: 35 additions & 2 deletions src/app/components/card/card.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Component, OnInit } from '@angular/core';
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {ShopsService} from '../../services/shops.service';
import {ToastrService} from 'ngx-toastr';

@Component({
selector: 'app-card',
Expand All @@ -7,9 +9,40 @@ import { Component, OnInit } from '@angular/core';
})
export class CardComponent implements OnInit {

constructor() { }
@Input() shop: any;
@Input() is_favorite: boolean;
@Output() liked = new EventEmitter<boolean>();
constructor(public shopsService: ShopsService,
public toastr: ToastrService) {
}

ngOnInit() {
}

like = (id) => {
const data = { id: id, is_liked: true };
this.shopsService.likeOrDislike(data).subscribe(d => {
this.liked.emit(true);
this.toastr.success(d.message);
}, error1 => this.toastr.warning('Shop not liked!'));
}

dislike = (id) => {
const data = { id: id, is_liked: false };
this.shopsService.likeOrDislike(data).subscribe(d => {
this.liked.emit(true);
this.toastr.success(d.message);
}, error1 => this.toastr.warning('I think maybe you love this shop!'));
}

delete = (id) => {
this.shopsService.remove(id).subscribe(d => {
this.liked.emit(true);
if (d.message !== 'Shop still in your favorite list!') {
this.toastr.success(d.message);
} else {
this.toastr.error(d.message);
}
}, error1 => this.toastr.warning('I think you really love this shop!'));
}
}
4 changes: 2 additions & 2 deletions src/app/interceptors/token.interceptors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ export class TokenInterceptor implements HttpInterceptor {
}

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.auth.getAccessToken()) {
if (this.auth.getToken()) {
const headers = {
Authorization: `Bearer ${this.auth.getAccessToken()}`,
Authorization: `Bearer ${this.auth.getToken()}`,
charset: 'UTF-8'
};
request = request.clone({
Expand Down
8 changes: 6 additions & 2 deletions src/app/modules/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ import { CommonModule } from '@angular/common';
import { AuthRoutingModule } from './auth-routing.module';
import { RegisterComponent } from './components/register/register.component';
import { LoginComponent } from './components/login/login.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { LogoutComponent } from './components/logout/logout.component';

@NgModule({
imports: [
CommonModule,
AuthRoutingModule
AuthRoutingModule,
ReactiveFormsModule,
FormsModule,
],
declarations: [RegisterComponent, LoginComponent]
declarations: [RegisterComponent, LoginComponent, LogoutComponent]
})
export class AuthModule { }
35 changes: 32 additions & 3 deletions src/app/modules/auth/components/login/login.component.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
<p>
login works!
</p>
<div class="">
<div class="container">
<div class="row">
<div class="col-md-6 offset-md-3">
<img src="assets/images/hidden-founders.png" alt="Hidden Founders logo">
<form name="form" (ngSubmit)="f.form.valid && onSubmit()" #f="ngForm" novalidate>
<div class="form-group">
<label for="email">Email</label>
<input type="text" class="form-control" name="email" [(ngModel)]="model.email"
#email="ngModel" [ngClass]="{ 'is-invalid': f.submitted && email.invalid }" required email />
<div *ngIf="f.submitted && email.invalid" class="invalid-feedback">
<div *ngIf="email.errors.required">Email is required</div>
<div *ngIf="email.errors.email">Email must be a valid email address</div>
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" name="password" [(ngModel)]="model.password"
#password="ngModel" [ngClass]="{ 'is-invalid': f.submitted && password.invalid }" required minlength="6" />
<div *ngIf="f.submitted && password.invalid" class="invalid-feedback">
<div *ngIf="password.errors.required">Password is required</div>
<div *ngIf="password.errors.minlength">Password must be at least 6 characters</div>
</div>
</div>
<div class="form-group">
<button class="btn btn-primary">Register</button>
</div>
</form>
</div>
</div>
</div>
</div>
24 changes: 23 additions & 1 deletion src/app/modules/auth/components/login/login.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { AuthenticationService } from '../../../../services/authentication.service';
import { ToastrService } from 'ngx-toastr';
import { Router } from '@angular/router';

@Component({
selector: 'app-login',
Expand All @@ -7,9 +10,28 @@ import { Component, OnInit } from '@angular/core';
})
export class LoginComponent implements OnInit {

constructor() { }
model: any = {};


constructor(public auth: AuthenticationService,
public toastr: ToastrService,
public router: Router) { }

ngOnInit() {
}


onSubmit() {
const email = this.model.email;
const password = this.model.password;
this.auth.login(email, password).subscribe((d: any) => {
const user = d.success.user;
localStorage.setItem('accessToken', d.success.token);
this.toastr.success(`Hello ${user.name.toUpperCase()}`);
this.router.navigate(['/shops/nearby']);
}, error1 => {
this.toastr.error('Email or Password are incorrect!');
});
}

}
Loading

0 comments on commit a41dece

Please sign in to comment.