<file_sep>import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpResponse, HttpErrorResponse } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { catchError, map, tap } from 'rxjs/operators';
import { KJUR } from 'jsrsasign';

import { environment } from '../../environments/environment';

import { Game } from '../_models/game';
import { User } from '../_models/user';
import { Comment } from '../_models/comment';

const headers =  new HttpHeaders({ 'Content-Type': 'application/json' });

@Injectable()
export class GameService {

  private apiUrl = environment.url;

  constructor(
    private http: HttpClient
  ) { }

  /** POST: create a new game */
  makeGame (username: string, game_date: string, des: string, min_rank: number, loc_id: number): Observable<HttpResponse<any>> {
    const url = `${this.apiUrl}/new-game`;
    const body = {
      locationID: loc_id,
      date_of_game: game_date,
      description: des,
      creator_username: username,
      minimum_rank: min_rank
    };
    return this.http.post<Response>(url, body, {observe: 'response'}).pipe(
      tap(res => console.log(`added game w/ description=${des}`))
    );
  }

  /** POST: rsvp to the game */
  rsvp (username: string, game_id: number): Observable<HttpResponse<any>> {
    const url = `${this.apiUrl}/rsvp`;
    return this.http.post<Response>(url,
      {
        GameID : game_id,
        username : username
      },
      {observe: 'response'}).pipe(
      tap(res => console.log(`added rsvp to game w/ if=${game_id}`))
    );
  }

  /** DELETE: delete rsvp to the game */
  deleteRSVP (username: string, game_id: number): Observable<HttpResponse<any>> {
    const url = `${this.apiUrl}/delete-rsvp/${username}/${game_id}`;
    return this.http.delete<any>(url).pipe(
      tap(res => console.log(`deleted rsvp to game w/ if=${game_id}`))
    );
  }

  /** GET: return array of all games */
  getAllGames (): Observable<Game[]> {
    const url = `${this.apiUrl}/games`;
    return this.http.get<Game[]>(url).pipe(
      tap(res => console.log(`found all games`))
    );
  }

  /** GET: return array of all games user rsvp'd to */
  getRSVPGames (username: string): Observable<Game[]> {
    const url = `${this.apiUrl}/rsvp/user/${username}`;
    return this.http.get<Game[]>(url).pipe(
      tap(res => console.log(`found games rsvp'd to`))
    );
  }

  /** GET: return array of all rsvps a game has */
  getGameRSVPs (gameid: number): Observable<User[]> {
    const url = `${this.apiUrl}/rsvp/game/${gameid}`;
    return this.http.get<User[]>(url).pipe(
      tap(res => console.log(`found user rsvp'd to this game`))
    );
  }

  /** GET: return specific game */
  getGame (game_id: number): Observable<Game> {
    const url = `${this.apiUrl}/game/${game_id}`;
    return this.http.get<Game>(url).pipe(
      tap(res => console.log(`found game with id=${game_id}`))
    );
  }
}
<file_sep>import { Component, Input, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { GameService } from '../../_services/game.service';
import { ProfileService } from '../../_services/profile.service';

import { Game } from '../../_models/game';

@Component({
  selector: 'app-games-list-page',
  templateUrl: './games-list-page.component.html',
  styleUrls: ['./games-list-page.component.scss']
})

export class GamesListPageComponent implements OnInit {

  allGamesActive: boolean = true;
	allGames: Game[] = [];
	attendingGames: Game[] = [];

	constructor(
    private router: Router,
    private gameService: GameService,
    private profileService: ProfileService
  ) {
	}

	ngOnInit() {
    this.getAllGames();
    this.getAttendingGames();
	}

  getAllGames() {
    this.gameService.getAllGames().subscribe(
      games => {
        this.allGames = games;
      },
      err => {
        console.log("Error getting all games");
      }
    );
  }

  getAttendingGames() {
    var currentUser = this.profileService.getCurrentUser();
    this.gameService.getRSVPGames(currentUser).subscribe(
      games => {
        this.attendingGames = games;
      },
      err => {
        console.log("Error getting rsvp'd games");
      }
    );
  }

  openNewGamePage() {
    this.router.navigate(['/dashboard/gameSubmit']);
  }

	allGamesToggle(){
		this.allGamesActive = true;
	}

	attendingGamesToggle(){
		this.allGamesActive = false;
	}

}
<file_sep><?php

header('Content-type: application/json');
use Slim\Http\Request;
use Slim\Http\Response;

// update a profile

$app->put('/profile-update/[{id}]', function(Request $request, Response $response, array $args){
  $pdo = $this->db->prepare("SELECT * FROM users  WHERE username=:id");
  $pdo->bindParam("id", $args["id"]);
  $pdo->execute();
  $info = $pdo->fetch();
  $first_name = $info['first_name'];
  $last_name = $info['last_name'];
  $email = $info['email'];
  $year = $info['year'];
  $pic_url = $infor['pic_url'];
 
        $data = json_decode(file_get_contents("php://input"));

   //$input = $request->getParsedBody();
   if (!empty($data->first_name)) {
        $first_name = $data->first_name;
        }
   if (!empty($data->last_name)) {
        $last_name = $data->last_name;
        }
   if (!empty($data->email)) {
        $email = $data->email;
        }
   if (!empty($data->year)) {
        $year = $data->year;
        }
   if (!empty($data->pic_url)) {
        $pic_url = $data->pic_url;
        }
   $sql = "UPDATE users SET first_name=:fn, last_name=:ln, email=:em, year=:yr,last_updated=CURRENT_TIMESTAMP, pic_url=:pic WHERE username=:id";
   $sth = $this->db->prepare($sql);
   $sth->bindParam("id", $args['id']);
   $sth->bindParam("fn", $first_name);
   $sth->bindParam("ln", $last_name);
   $sth->bindParam("em", $email);
   $sth->bindParam("yr", $year);
   $sth->bindParam("pic", $pic_url);
        $sth->execute();
//        return $response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
});
                                                                                                                                                                                                        
<file_sep># Hooplife

SMU Fall 2017 DB/GUI Project

## Dev Environment

Instructions for running the project locally

### Setup

Install dependencies, build frontend project, and get project ready for the docker containers

```
npm install
cd frontend
ng build --prod
cd ../
npm run setup
```

### Docker Scripts

These commands are to be run in the top level 'endlist' folder. Docker and docker-compose must be installed for this to work

`npm run docker-start`: Starts the docker containers. The frontend can be accessed from http://localhost:80. The backend can be accessed from http://localhost:80/backend/public.

`npm run docker-stop`: Stops the docker containers.

`npm run docker-prod`: Starts the docker containers in production mode. The frontend is configured to be accessed from http://endlist.fun and the backend from http://api.endlist.fun.

### Testing

`npm test`: Runs tests for both the fronend and backend.

`npm run test-frontend`: Runs tests for the frontend using jest.

`npm run test-backend`: Runs tests for the backend using phpunit.
<file_sep>import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import { ProfileService } from '../../_services/profile.service';

import { User } from '../../_models/user';
import { Comment } from '../../_models/comment';

import { UserPublicComponent } from '../../components/user-public/user-public.component';
import { UserPrivateComponent } from '../../components/user-private/user-private.component'

@Component({
  selector: 'app-user-page',
  templateUrl: './user-page.component.html',
  styleUrls: ['./user-page.component.css']
})

export class UserPageComponent implements OnInit {

	isPublic: boolean;
  userFound: boolean = false;
  user: User;
  comments: Comment[];

	constructor(
    private route: ActivatedRoute,
    private profileService: ProfileService
  ) {
		this.isPublic = true;
	}

	ngOnInit() {
    this.getUser();
    this.getComments();
	}

  getUser() {
    const username = this.route.snapshot.paramMap.get('username');
    this.profileService.getUser(username).subscribe(
      user => {
        this.user = user;
        var currentUser = this.profileService.getCurrentUser();
        this.isPublic = (username === currentUser) ? false : true;
        this.userFound = true;
      },
      err => {
        this.user = new User();
      }
    );
  }

  getComments() {
    const username = this.route.snapshot.paramMap.get('username');
    this.profileService.getComments("user", username).subscribe(
      comments => {
        this.comments = comments;
      },
      err => {
        this.comments = [];
      }
    );
  }

}
<file_sep><?php

header('Content-type: application/json');
use Slim\Http\Request;
use Slim\Http\Response;

$app->delete('/location-delete/[{locationID}]', function (Request $request, Response $response, array $args) {
  $pdo = $this->db->prepare("DELETE FROM location WHERE locationID=:locationID");
  $pdo->bindParam("locationID", $args["locationID"]);
  $pdo->execute();
   // return $this->response->withJson($response->getStatusCode());
//   return $response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
});
<file_sep>import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { MatSnackBar } from '@angular/material';

import { AuthService } from '../../_services/auth.service';
import { Login } from '../../_models/login';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {

  auth: Login = new Login();
  username: string;

  constructor(
    private authService: AuthService,
    private router: Router,
    private snackBar: MatSnackBar
  ) { }

  ngOnInit() {
  }

  submit() {
    this.username = this.auth.username;
    this.authService.login(this.auth).subscribe(
      res => {
        this.checkAuth(res.status);
      },
      err => {
        this.snackBar.open('Login failed, please try again', '', {
          duration: 5000
        });
      }
    );
  }

  checkAuth(status) {
    if(status == 200) {
      localStorage.setItem('auth', this.authService.getJWT({user: this.username}));
    } else {
      this.snackBar.open('Login failed, please try again', '', {
        duration: 5000
      });
      return;
    }

    this.router.navigate(['/dashboard']);
  }

}
<file_sep><?php
if (PHP_SAPI == 'cli-server') {
    // To help the built-in PHP dev server, check if the request was actually
    // for something which should probably be served as a static file
    $url  = parse_url($_SERVER['REQUEST_URI']);
    $file = __DIR__ . $url['path'];
    if (is_file($file)) {
        return false;
    }
}

require __DIR__ . '/../vendor/autoload.php';

//session_start();

// Instantiate the app
$settings = require __DIR__ . '/../src/settings.php';
$app = new \Slim\App($settings);

// Set up dependencies
require __DIR__ . '/../src/dependencies.php';

// Register middleware
require __DIR__ . '/../src/middleware.php';

// Register routes -------------------------------------------------------------
// IMPORTANT: Require dynamic routes after static ones
//require __DIR__ . '/../src/routes.php';
require __DIR__ . '/../src/login.php';
require __DIR__ . '/../src/registration.php';
require __DIR__ . '/../src/games.php';
require __DIR__ . '/../src/get_profile.php';
require __DIR__ . '/../src/game_detail.php';
require __DIR__ . '/../src/delete_game.php';
require __DIR__ . '/../src/post_location.php';
require __DIR__ . '/../src/get_location.php';
require __DIR__ . '/../src/rsvp.php';
require __DIR__ . '/../src/approve_admin.php';
require __DIR__ . '/../src/approve_location.php';
require __DIR__ . '/../src/pofile-update.php';
require __DIR__ . '/../src/stats-update.php';
require __DIR__ . '/../src/change_password.php';
require __DIR__ . '/../src/comments.php';
require __DIR__ . '/../src/location-update.php';
require __DIR__ . '/../src/delete_location.php';
require __DIR__ . '/../src/email_validation.php';

// Add dynamic ones below this line --------------------------------------------i

// Run app
$app->run();

<file_sep>import { InMemoryDbService } from 'angular-in-memory-web-api';

export class InMemoryDataService implements InMemoryDbService {
  createDb() {
    const users = [
      {
        firstName: 'Jenn',
        lastName: 'Le',
        username: 'Thakugan',
        email: '<EMAIL>',
        password: '<PASSWORD>',
        dateCreated: new Date(),
        comments: [],
        rating: 5,
        year: 'Junior',
        gamesPlayed: 0,
        wins: 0,
        losses: 0
      }
    ];

    const login = [
    ]

    const locations = [
      {
        name: '<NAME>',
        photoName: 'temp.jpg',
        address: 'SMU',
        description: 'Only midly disgusting',
        comments: [],
        rating: 3
      }
    ]

    return {users, login, locations};
  }
}
<file_sep>import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { MatSnackBar } from '@angular/material';

import { LocationService } from '../../_services/location.service';
import { ProfileService } from '../../_services/profile.service';

import { Location } from '../../_models/location';
import { Comment } from '../../_models/comment';

@Component({
  selector: 'app-location-details-page',
  templateUrl: './location-details-page.component.html',
  styleUrls: ['./location-details-page.component.scss']
})
export class LocationDetailsPageComponent implements OnInit {

  place: Location;
  comments: Comment[];
  displayComments: boolean = true;
  hasRated: boolean;
  hasCommented: boolean;

  newComment: Comment = new Comment();

  constructor(
    private route: ActivatedRoute,
    private router: Router,
    private locationService: LocationService,
    private profileService: ProfileService,
    private snackBar: MatSnackBar
  ) { }

  ngOnInit() {
    this.getLocation();
    this.getComments();
  }

  getLocation() {
    const loc = +this.route.snapshot.paramMap.get('locID');
    this.locationService.getLocation(loc).subscribe(
      location => {
        this.place = location[0];
      },
      err => {
        alert("something went wrong");
      }
    );
  }

  getComments() {
    const loc = +this.route.snapshot.paramMap.get('locID');
    this.profileService.getComments("location", loc).subscribe(
      comments => {
        this.comments = comments;
      },
      err => {
        this.comments = [];
      }
    );
  }

  addComment(){
    const loc = this.route.snapshot.paramMap.get('locID');
    const currentUser = this.profileService.getCurrentUser();
    this.profileService.createComment(currentUser, this.newComment.Comment, 'location', loc, this.newComment.rating).subscribe(
      res => {
        this.router.navigate(['/dashboard/location/' + loc])
      },
      err => {
        this.snackBar.open('Comment submition failed, please try again.', '', { duration: 5000 });
      }
    );
	}

  onRated(num: number){
    this.newComment.rating = num;
    this.hasRated = true;
  }
}
<file_sep><?php

header('Content-type: application/json');
use \Firebase\JWT\JWT;
use Slim\Http\Request;
use Slim\Http\Response;

//session set up with login template implimented 
/**
$app->get('/login',function (Request $request, Response $response, array $args) {

    if(session_id() == ''){

    session_start(); // Starting Session
    }

   //check if there is a session with the particular user
   if(isset($_session['username'])){
   
   return $response->withRedirect('/');
   }
   
});
**/

//in the begingin we were planing on using user sessions but we changed to using JWT and the front end handels that part

//login as post for protecting credentials
$app->post('/login', function (Request $request, Response $response, array $args){
    //if(session_id() == ''){

   // session_start(); // Starting Session
    //}
    
    if ($_SERVER['REQUEST_METHOD'] == 'POST')
    {
    $data = json_decode(file_get_contents("php://input"));
    $username = $data->username;
    $password = $<PASSWORD>-><PASSWORD>;
    }
    $pdo = $this->db;   
    $hash_password= md5($password); 

    $stmt = $pdo->prepare('SELECT *  FROM users WHERE username=:username AND password=:password');
    $stmt->bindParam("username", $username);
    $stmt->bindParam("password", $hash_password);
    $stmt->execute();
    $row = $stmt->rowCount();

   if ($row < 1)
	{
	return $response->withStatus(404);
}
   else {
	//session_start();
	  $payload = [  'username' => $username,    ];
          $token = JWT::encode($payload, $_SERVER['SESSION_PASS']);
          $json = json_encode(array( "jwt" => $token  ));
          $stmt = $pdo->prepare('UPDATE users SET last_login=CURRENT_TIMESTAMP WHERE username=:username');
          $stmt->bindParam("username", $username);
          $stmt->execute();
          return $response->withJson($json, 200);
	//return $response->withStatus(200);
}


   

});



<file_sep>#!/usr/bin/env bash
docker-compose -f $1 stop
<file_sep><?php

header('Content-type: application/json');
use Slim\Http\Request;
use Slim\Http\Response;

// update a location

$app->put('/location-update/[{id}]', function(Request $request, Response $response, array $args){
  $pdo = $this->db->prepare("SELECT * FROM location  WHERE locationID=:id");
  $pdo->bindParam("id", $args["id"]);
  $pdo->execute();
  $info = $pdo->fetch();
  $picture_url = $info['picture_url'];
  $address = $info['address'];
  $des = $info['description'];
  $rating = $info['rating'];
 
        $data = json_decode(file_get_contents("php://input"));

   //$input = $request->getParsedBody();
   if (!empty($data->picture_url)) {
        $picture_url = $data->picture_url;
        }
   if (!empty($data->address)) {
        $address = $data->address;
        }
   if (!empty($data->des)) {
        $des = $data->des;
        }
   if (!empty($data->rating)) {
        $rating = $data->rating;
        }

   $sql = "UPDATE location SET picture_url=:pic, address=:address, description=:des, rating=:rating WHERE locationID=:id";
   $sth = $this->db->prepare($sql);
   $sth->bindParam("id", $args['id']);
   $sth->bindParam("pic", $picture_url);
   $sth->bindParam("address", $address);
   $sth->bindParam("des", $des);
   $sth->bindParam("rating", $rating);
        $sth->execute();
        return $response->withStatus(200);

});
                                                                                                                                                                                                        
<file_sep>import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpResponse, HttpErrorResponse } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { catchError, map, tap } from 'rxjs/operators';
import { KJUR } from 'jsrsasign';

import { environment } from '../../environments/environment';

import { Location } from '../_models/location';
import { Comment } from '../_models/comment';

const headers =  new HttpHeaders({ 'Content-Type': 'application/json' });

@Injectable()
export class LocationService {

  private apiUrl = environment.url;

  constructor(
    private http: HttpClient
  ) { }

  /** POST: request a new location */
  requestLoc (username: string, address: string, description: string, pic?: string): Observable<HttpResponse<any>> {
    const url = `${this.apiUrl}/new-location`;
    const body = pic ? {
      creator_username: username,
      address: address,
      descriptions: description,
      picture_url: pic
    } :
    {
      creator_username: username,
      address: address,
      descriptions: description
    };
    return this.http.post<Response>(url,
      body,
      {observe: 'response'}).pipe(
      tap(res => console.log(`added location w/ description=${description}`))
    );
  }

  /** GET: return array of all approved locations */
  getApprovedLocations (): Observable<Location[]> {
    const url = `${this.apiUrl}/approved-location`;
    return this.http.get<Location[]>(url).pipe(
      tap(res => console.log(`found games`))
    );
  }

  /** GET: return array of all approved locations */
  getUnapprovedLocations (): Observable<Location[]> {
    const url = `${this.apiUrl}/non-approved-location`;
    return this.http.get<Location[]>(url).pipe(
      tap(res => console.log(`found games`))
    );
  }

  /** GET: return specific location */
  getLocation (id: number): Observable<Location> {
    const url = `${this.apiUrl}/location/${id}`;
    return this.http.get<Location>(url).pipe(
      tap(res => console.log(`found location with id=${id}`))
    );
  }

  approveLocation(admin: string, loc: number): Observable<Location> {
    const url = `${this.apiUrl}/locapprove/${admin}/${loc}`;
    return this.http.get<Location>(url).pipe(
      tap(res => console.log(`found games`))
    );
  }

  denyLocation(loc: number): Observable<Location> {
    const url = `${this.apiUrl}/location-delete/${loc}`;
    return this.http.delete<Location>(url).pipe(
      tap(res => console.log(`found games`))
    );
  }
}
<file_sep><?php

use Slim\Http\Request;
use Slim\Http\Response;

$app->post('/new-location', function (Request $request, Response $response, array $args) {

    $pdo = $this->db;
    

    if ($_SERVER['REQUEST_METHOD'] == 'POST')
	{ 

    $data = json_decode(file_get_contents("php://input"));
    $creator_username = $data->creator_username;
    $picture_url = $data->picture_url;
    $des = $data->descriptions;
    $address = $data->address;
}

if( !isset($creator_username) || !isset($address) || !isset($des) ||
 empty($creator_username) || empty($des) || empty($address)) {
   
      //error message forbidden
      return $response->withStatus(403);
    }
if (empty($picture_url)){
    $picture_url ="null";
}
   
   // Check if the user  exists
   $stmt = $pdo->prepare('SELECT * FROM users WHERE username=:creator_username');
   $stmt->bindParam("creator_username", $creator_username);
   $stmt->execute();
   $row = $stmt->fetch(PDO::FETCH_ASSOC);
   if($row== 0)
   {
  
    //error message bad request
   return $response->withStatus(400);
   }

     //Check if the address already exsists
     $stmt = $pdo->prepare('SELECT * FROM location WHERE address=:address');
     $stmt->bindParam("address", $address);
     $stmt->execute();
     $row = $stmt->fetch(PDO::FETCH_ASSOC);
     if($row)

     {
     //error message bad reqest
     return $response->withStatus(400);
     }

    //primary key locationid
    $stmt = $pdo->prepare(
      "INSERT INTO location (
        picture_url, 
        address, 
        description,
        date_created, 
        creator_username,
        approved)
    VALUES(:picture_url, :address, :des, CURRENT_TIMESTAMP, :creator_username, 0)"
    );
   
 // Add the entry to the array once all the fields have been verified
    $stmt->bindParam("picture_url", $picture_url);
    $stmt->bindParam("address", $address);
    $stmt->bindParam("des", $des);
    $stmt->bindParam("creator_username", $creator_username);
    $stmt->execute();

 //	return $response->withStatus(200);
	$data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);

});

<file_sep>#!/usr/bin/env bash
docker-compose -f $1 build
docker-compose -f $1 up -d --force-recreate
<file_sep><?php
use Slim\Http\Request;
use Slim\Http\Response;


//user regisration 
//tested and complete
//email verification not fully functional
//some of the codes for registration were implimented partly based another php implementation of a registration
//this helped me make sure evverything was working properly and that I could cover the edge cases
$app->post('/registration', function ($request,$response, array $args) {

    $pdo = $this->db;
    //$json = $request->getBody();
    //$data = json_decode($json);
    //$username = $_POST['username'];
    //$first_name = $_POST['first_name'];
   // $last_name = $_POST['last_name'];
    //$email = $_POST['email'];
    //$plain_password = $_POST['password'];
    if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
  $data = json_decode(file_get_contents("php://input"));
    $username = $data->username;
    $first_name = $data->first_name;
    $last_name = $data->last_name;
    $email = $data->email;
    $plain_password = $<PASSWORD>-><PASSWORD>;
    $year = $data->year;
}


    //when building html form, using ajax or js to prevent non-value params
    // checkinig for empty fields
    if( !isset($username) || !isset($email)|| !isset($last_name) || !isset($year) || !isset($first_name) || !isset($plain_password) ||
      empty($username) || empty($year) || empty($first_name) || empty($last_name) || empty($email) || empty($plain_password)) {

      //error message forbidden
      return $response->withStatus(403);
    }

    // username duplicaiton change
   $stmt = $pdo->prepare('SELECT * FROM users WHERE username=:username');
   $stmt->bindParam("username", $username);
   $stmt->execute();
   $row = $stmt->fetch(PDO::FETCH_ASSOC);
   if($row)
   {
   //error message bad request
   return $response->withStatus(400);
   }

     //email duplication check 
     $stmt = $pdo->prepare('SELECT * FROM users WHERE email=:email');
     $stmt->bindParam("email", $email);
     $stmt->execute();
     $row = $stmt->fetch(PDO::FETCH_ASSOC);
     if($row)
     {
     //error message bad reqest
     return $response->withStatus(400);
     }

    // md5 used to hash the passwords
    $password = md5($plain_password);

    //primary key userid
    //forigne key groupid
    $stmt = $pdo->prepare(
      "INSERT INTO users (
        username, 
        first_name , 
        last_name , 
        email ,
        password, 
        groupid,
        verified, 
        date_joined , 
        last_updated , 
        num_of_games_played,
        isAdmin,
        wins,
	losses,
	year)
    VALUES(:username, :first_name, :last_name, :email, :password, 2, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 0, 0, 0, 0, :year)"
    );

    $stmt->bindParam("username", $username);
    $stmt->bindParam("first_name", $first_name);
    $stmt->bindParam("last_name", $last_name);
    $stmt->bindParam("email", $email);
    $stmt->bindParam("password", $<PASSWORD>);
    $stmt->bindParam("year", $year);
    $stmt->execute();
	
    $pdo = $this->db->prepare("SELECT * FROM users  WHERE username=:username");
    $pdo->bindParam("username", $username);
    $pdo->execute();
    $info = $pdo->fetch();
    $uid = $info['uid'];
   // email_verification($email, $last_name, $first_name, $username, $uid);
 
//    return $response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
});

<file_sep>import { Component, Input, OnInit } from '@angular/core';

import { LocationService } from '../../_services/location.service';

import { Location } from '../../_models/location';

import { LocationBrowserComponent } from '../../components/location-browser/location-browser.component';

@Component({
  selector: 'app-location-browse-page',
  templateUrl: './location-browse-page.component.html',
  styleUrls: ['./location-browse-page.component.scss']
})

export class LocationBrowsePageComponent implements OnInit {

	loadPage: boolean = true;
  locations: Location[];

	constructor(
    private locationService: LocationService
  ) {
	}

	ngOnInit() {
    this.getApprovedLocations();
	}

  getApprovedLocations() {
    this.locationService.getApprovedLocations().subscribe(
      locations => {
        this.locations = locations;
      }
    );
  }

}
<file_sep><div class="games-list mt-4">
	<button type="button" class="btn btn-info" [disabled]="allGamesActive" (click)="allGamesToggle()">All Games</button>
	<button type="button" class="btn btn-info" [disabled]="!allGamesActive" (click)="attendingGamesToggle()">Games I'm Attending</button>
  <button type="button" class="btn btn-outline-dark float-right" (click)="openNewGamePage()">NEW GAME</button>
	<hr />
	<div *ngIf="allGamesActive" class="clearfix">
		<div *ngFor="let game of allGames">
			<div class="card w-100">
				<div class="card-body">
						<a [routerLink]="'/dashboard/game/' + game.GameID"><h4>{{game.description}}</h4></a>
						<p>Organizer: <a [routerLink]="'/dashboard/user/' + game.creator_username">{{game.creator_username}}</a></p>
						<!-- <p>{{game.location.address}}</p> -->
						<p>Minimum Rating: {{game.minimum_rank ? game.minimum_rank : 'N/A'}}</p>
				</div>
			</div>
		</div>
	</div>
	<div *ngIf="!allGamesActive">
		<div *ngFor="let game of attendingGames">
			<div class="card w-100">
				<div class="card-body">
						<a [routerLink]="'/dashboard/game/' + game.GameID"><h4>{{game.description}}</h4></a>
						<p>Organizer: <a [routerLink]="'/dashboard/user/' + game.creator_username">{{game.creator_username}}</a></p>
						<!-- <p>{{game.location.address}}</p> -->
						<p>Minimum Rating: {{game.minimum_rank ? game.minimum_rank : 'N/A'}}</p>
				</div>
			</div>
		</div>
</div>
<file_sep>import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';

import { SharedModule } from '../../_modules/shared/shared.module';

import { UserPageComponent } from '../../pages/user-page/user-page.component';
import { UserPrivateComponent } from '../../components/user-private/user-private.component';
import { UserPublicComponent } from '../../components/user-public/user-public.component';
import { ApproveLocationsComponent } from '../../components/approve-locations/approve-locations.component';

@NgModule({
  declarations: [
    UserPrivateComponent,
    UserPublicComponent,
    UserPageComponent,
    ApproveLocationsComponent
  ],
  imports: [
    CommonModule,
    HttpClientModule,
    FormsModule,
    SharedModule
  ],
  providers: [
  ]
})
export class ProfileModule { }
<file_sep><?php

header('Content-type: application/json');
use Slim\Http\Request;
use Slim\Http\Response;


//show a specfic rsvp for a user
$app->get('/rsvp/user/[{username}]', function(Request $request, Response $response, array $args){
 // $pdo = $this->db->prepare("SELECT * FROM rsvp WHERE userid=:userid");
  $pdo = $this->db->prepare("SELECT * FROM games natural join rsvp
				WHERE username = :username");
  $pdo->bindParam("username", $args["username"]);
  $pdo->execute();
  $rsvpGame = $pdo->fetchAll();
if (!$rsvpGame)
        {
        return $response->withStatus(404);
}
   else {
        return $this->response->withJson($rsvpGame);
}
});


//show a specfic rsvp for a user
$app->get('/rsvp/game/[{GameID}]', function(Request $request, Response $response, array $args){
 // $pdo = $this->db->prepare("SELECT * FROM rsvp WHERE userid=:userid");
 // $pdo = $this->db->prepare("SELECT * FROM games natural join rsvp
 //                               WHERE GameID = :GameID");
   $pdo = $this->db->prepare("SELECT username FROM rsvp WHERE GameID=:GameID");
  $pdo->bindParam("GameID", $args["GameID"]);
  $pdo->execute();
  $rsvpGame = $pdo->fetchAll();
if (!$rsvpGame)
        {
        return $response->withStatus(404);
}
   else {
        return $this->response->withJson($rsvpGame);
}
});


//deletes a specifice RSVP 
$app->delete('/delete-rsvp/{username}/{GameID}', function(Request $request, Response $response, array $args){

  $pdo = $this->db->prepare("DELETE FROM rsvp WHERE GameID=:GameID AND username=:username");
  $pdo->bindParam("GameID", $args["GameID"]);
  $pdo->bindParam("username", $args["username"]);
  $pdo->execute();
  $count = $pdo->rowCount();

  if ($count > 0) {
//    return $this->response->withStatus(200);

	 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);

 } else {

    return $this->response->withStatus(404);

  }



});



//get a specifiv rsvp 
$app->get('/rsvp/[{rsvpid}]', function(Request $request, Response $response, array $args){
 // $pdo = $this->db->prepare("SELECT * FROM rsvp WHERE userid=:userid");
 // $pdo = $this->db->prepare("SELECT r.*, g.* 
   //				FROM rsvp as r INNER JOIN games as g
  //                              WHERE rsvpid = :rsvpid");
 $pdo = $this->db->prepare("SELECT r.GameID, g.*
                                FROM rsvp as r natural join games as g
                                WHERE rsvpid = :rsvpid"); 
 $pdo->bindParam("rsvpid", $args["rsvpid"]);
  $pdo->execute();
  $rsvpGamebyID = $pdo->fetchAll();
if (!$rsvpGamebyID)
        {
        return $response->withStatus(404);
}
   else {
        return $this->response->withJson($rsvpGamebyID);
}
});

//post reservation
$app->post('/rsvp', function(Request $request, Response $response, array $args){

 // $pdo = $this->db->prepare("SELECT * FROM rsvp WHERE userid=:userid");
     
 if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
  $data = json_decode(file_get_contents("php://input"));
    $gameid = $data->GameID;
    $username = $data->username;
}
  $check = $this->db->prepare("SELECT * FROM rsvp where GameID=:gameid AND username=:username");
  $check->bindParam("gameid", $gameid);
  $check->bindParam("username", $username);
  $check->execute();
  $row = $check->rowCount();

 if ($row) {
    
	return $response->withStatus(401); }
 else {
  $pdo = $this->db->prepare("INSERT INTO rsvp(GameID, username) VALUES (:gameid, :username)");
  $pdo->bindParam("username", $username);
  $pdo->bindParam("gameid", $gameid);
  $pdo->execute();

//  return $response->withStatus(200);}
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
}
});


<file_sep>import { Component, OnInit } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { Router } from '@angular/router';
import { MatSnackBar } from '@angular/material';

import { AuthService } from '../../_services/auth.service';

import { User } from '../../_models/user';

@Component({
  selector: 'app-registration',
  templateUrl: './registration.component.html',
  styleUrls: ['./registration.component.scss']
})
export class RegistrationComponent implements OnInit {

  tempUser: User = new User();
  pass: string;
  passConfirmation: string;

  constructor(
    private authService: AuthService,
    private router: Router,
    private snackBar: MatSnackBar
  ) { }

  ngOnInit() {
  }

  submit() {
    if(this.pass != this.passConfirmation) {
      this.snackBar.open('Passwords do not match, please try again', '', {
        duration: 5000
      });
      return;
    }

    this.authService.addUser(this.tempUser, this.pass).subscribe(
      res => {
        this.checkRegistration(res.status);
      },
      err => {
        this.snackBar.open('Registration failed, please try again', '', {
          duration: 5000
        });
      }
    );
  }

  checkRegistration(status) {
    if(status == 200) {
      localStorage.setItem('auth', this.authService.getJWT({user: this.tempUser.username}));
    } else {
      this.snackBar.open('Registration failed, please try again', '', {
        duration: 5000
      });
      return;
    }

    this.tempUser = new User();
    this.router.navigate(['/dashboard']);
  }
}
<file_sep>FROM php:7-apache

RUN apt-get update -y && apt-get install -y libpng-dev curl git libcurl4-openssl-dev npm

RUN docker-php-ext-install pdo pdo_mysql gd curl

RUN a2enmod rewrite
RUN service apache2 restart
<file_sep>export class CloudinaryResponse{
	public_id?: string;
	version?: string;
	width?: number;
	height?: number;
	format?: string;
	created_at?: string;
	resource_type?: string;
	tags?: any[];
	bytes?: number; 
	type?: string;
	etag?: string; 
	url?: string;
	secure_url?: string;
	signature?: string;
	original_filename?: string;
}<file_sep><?php

header('Content-type: application/json');

use Slim\Http\Request;
use Slim\Http\Response;

// Show list of approved location
$app->get('/approved-location', function(Request $request, Response $response, array $args){
  $pdo = $this->db->prepare("SELECT * FROM location where approved =1 ORDER BY date_created");
  $pdo->execute();
  $locations = $pdo->fetchAll();
  
  return $this->response->withJson($locations);
});

// Show list of un-approved location
$app->get('/non-approved-location', function(Request $request, Response $response, array $args){
  $pdo = $this->db->prepare("SELECT * FROM location where approved =0 ORDER BY date_created");
  $pdo->execute();
  $locations = $pdo->fetchAll();
  
  return $this->response->withJson($locations);
        
});


// Show specific location
$app->get('/location/{locationID}', function(Request $request, Response $response, array $args){
  $pdo = $this->db->prepare("SELECT * FROM location WHERE locationID=:locationID");
  
  $pdo->bindParam("locationID", $args["locationID"]);
  $pdo->execute();
  $location = $pdo->fetchAll();
if (!$location)
        {
        return $response->withStatus(404);
}
   else {
        return $this->response->withJson($location);
}


});
<file_sep>FROM php:7-apache

RUN apt-get update -y && apt-get install -y libpng-dev curl git libcurl4-openssl-dev nodejs

RUN docker-php-ext-install pdo pdo_mysql gd curl

RUN a2enmod rewrite
# RUN a2enmod headers
RUN service apache2 restart
<file_sep>/* The authentication service includes registration and login routes. This also
includes jwt operations for user authentication, working in conjunction with
the authentication guard. */

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpResponse, HttpErrorResponse } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { catchError, map, tap } from 'rxjs/operators';
import { KJUR } from 'jsrsasign';

import { environment } from '../../environments/environment';

import { User } from '../_models/user';
import { Comment } from '../_models/comment';

const headers =  new HttpHeaders({ 'Content-Type': 'application/json' });

@Injectable()
export class ProfileService {

  private apiUrl = environment.url;

  constructor(
    private http: HttpClient
  ) { }

  /** POST: create a comment */
  createComment (username: string, comment: string, type: string, target: any, rating: number): Observable<HttpResponse<any>> {
    const url = `${this.apiUrl}/newcomment`;
    return this.http.post<Response>(url,
      {
        username: username,
        Comment: comment,
        type: type,
        id: target,
        rating: rating
      },
      {observe: 'response'}).pipe(
      tap(res => console.log(`added comment from user=${username}`))
    );
  }

  /** GET: find a user */
  getUser (username: string): Observable<User> {
    const url = `${this.apiUrl}/profile/${username}`;
    console.log(url);
    return this.http.get<User>(url).pipe(
      tap(res => console.log(`found user w/ username=${username}`))
    );
  }

  // getUserComments (username: string): Observable<User> {
  //   const url = `${this.apiUrl}/profile/${username}`;
  //   console.log(url);
  //   return this.http.get<User>(url).pipe(
  //     tap(res => console.log(`found user w/ username=${username}`))
  //   );
  // }

  /** TODO POST: change username or email */
  updateUser (username: string): Observable<User> {
    const url = `${this.apiUrl}/profile/${username}`;
    console.log(url);
    return this.http.get<User>(url).pipe(
      tap(res => console.log(`found user w/ username=${username}`))
    );
  }

  getComments(type: string, target: any): Observable<Comment[]> {
    const url = `${this.apiUrl}/${type}/${target}/comments`;
    console.log(url);
    return this.http.get<Comment[]>(url).pipe(
      tap(res => console.log(`found comments`))
    );
  }

  getCurrentUser(): string {
    var currentUser = KJUR.jws.JWS.parse(localStorage.getItem('auth')).payloadObj.user;
    return currentUser;
  }
}
<file_sep>import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { MatSnackBar } from '@angular/material';

import { LocationService } from '../../_services/location.service';
import { ProfileService } from '../../_services/profile.service';

import { Location } from '../../_models/location';

@Component({
  	selector: 'approve-locations',
  	templateUrl: './approve-locations.component.html',
  	styleUrls: ['./approve-locations.component.scss']
})

export class ApproveLocationsComponent implements OnInit{

	locations: Location[] = [];
	numOfLocations: number = 0;

	constructor(
    private locationService: LocationService,
    private profileService: ProfileService,
    private route: ActivatedRoute,
    private router: Router,
    private snackBar: MatSnackBar
  ){

	}

	ngOnInit(){
    this.getUnapprovedLocations();
	}

  getUnapprovedLocations() {
    this.locationService.getUnapprovedLocations().subscribe(
      res => {
        this.locations = res;
        this.numOfLocations = this.locations.length;
      }
    )
  }

	approveLocation(loc_id: number){
    var currUser = this.profileService.getCurrentUser();
    this.locationService.approveLocation(currUser, loc_id).subscribe(
      res => this.router.navigate(['/dashboard/user/' + currUser]), err => this.snackBar.open('Error occured, please try again', '', {
        duration: 5000
      })
    );
	}

	denyLocation(loc_id: number){
    var currUser = this.profileService.getCurrentUser();
    this.locationService.denyLocation(loc_id).subscribe(
      res => this.router.navigate(['/dashboard/user/' + currUser]), err => this.snackBar.open('Error occured, please try again', '', {
        duration: 5000
      })
    );
	}

}
<file_sep><?php

header('Content-type: application/json');
use Slim\Http\Request;
use Slim\Http\Response;

$app->delete('/delete-game/{GameID}', function (Request $request, Response $response, array $args) {
  $pdo = $this->db->prepare("DELETE FROM games WHERE GameID=:GameID");
  $pdo->bindParam("GameID", $args["GameID"]);
  $pdo->execute();
  $count = $pdo->rowCount();
  if ($count > 0) {
//    return $this->response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200); 
 } else {
    return $this->response->withStatus(404);
  }
});
<file_sep>export class Location {
	locationID?: number;
	picture_url?: string;
	address?: string;
	description?: string;
	date_created?: Date;
	creator_username?: string;
	approved?: number;
	rating?: number;
}
<file_sep>import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';

import { SharedModule } from '../../_modules/shared/shared.module';

import { GameService } from '../../_services/game.service';

import { LocationDetailsPageComponent } from '../../pages/location-details-page/location-details-page.component';
import { LocationSubmitComponent } from '../../components/location-submit/location-submit.component';
import { LocationBrowserComponent } from '../../components/location-browser/location-browser.component';
import { LocationSubmitPageComponent } from '../../pages/location-submit-page/location-submit-page.component';
import { LocationBrowsePageComponent } from '../../pages/location-browse-page/location-browse-page.component';
import { GameCreateComponent } from '../../components/game-create/game-create.component';
import { GamePageComponent } from '../../pages/game-page/game-page.component';
import { GameCreatePageComponent } from '../../pages/game-create-page/game-create-page.component';
import { GamesListPageComponent } from '../../pages/games-list-page/games-list-page.component';

@NgModule({
  declarations: [
    LocationDetailsPageComponent,
    LocationSubmitComponent,
    LocationBrowserComponent,
    LocationSubmitPageComponent,
    LocationBrowsePageComponent,
    GamePageComponent,
    GameCreateComponent,
    GameCreatePageComponent,
    GamesListPageComponent
  ],
  imports: [
    CommonModule,
    HttpClientModule,
    FormsModule,
    SharedModule
  ],
  providers: [
    GameService
  ]
})
export class GamesModule { }
<file_sep>import { Component, OnInit, Input } from '@angular/core';

import { User } from '../../_models/user';
import { Location } from '../../_models/location';
import { Comment } from '../../_models/comment';

@Component({
  	selector: 'app-user-private',
  	templateUrl: './user-private.component.html',
  	styleUrls: ['./user-private.component.css']
})

export class UserPrivateComponent {

	displayComments: boolean = false;
	@Input() user: User;
  @Input() locations: Location[];
  @Input() comments: Comment[];

	newUsername: string;
	newEmail: string;

	constructor(){ }

	updateUser(){
		this.user.username = this.newUsername;
		this.user.email = this.newEmail;
	}

}
<file_sep>import { Component, Input, OnInit } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { MatSnackBar } from '@angular/material';

import { GameService } from '../../_services/game.service';
import { ProfileService } from '../../_services/profile.service';
import { LocationService } from '../../_services/location.service';

import { User } from '../../_models/user';
import { Game } from '../../_models/game';
import { Comment } from '../../_models/comment';
import { Location } from '../../_models/location';

@Component({
  selector: 'app-game-page',
  templateUrl: './game-page.component.html',
  styleUrls: ['./game-page.component.scss']
})

export class GamePageComponent implements OnInit {

  user: User;
  game: Game;
  player: boolean;
  players: User[];
  comments: Comment[];
  location: Location;

  newComment: Comment = new Comment();

	constructor(
    private route: ActivatedRoute,
    private router: Router,
    private gameService: GameService,
    private profileService: ProfileService,
    private locationService: LocationService,
    private snackBar: MatSnackBar
  ) {
	}

	ngOnInit() {
    this.getUser();
    this.getGame();
    this.isPlayer();
    this.getPlayers();
    this.getComments();
	}

  getUser() {
    var currentUser = this.profileService.getCurrentUser();
    this.profileService.getUser(currentUser).subscribe(
      user => {
        this.user = user;
      },
      err => {
        this.user = new User();
      }
    );
  }

  getGame() {
    const gameid = +this.route.snapshot.paramMap.get('gameid');
    this.gameService.getGame(gameid).subscribe(
      game => {
        this.game = game[0];
        console.log(JSON.stringify(this.game));
        console.log(this.game.locationID);
        this.getLocation(this.game.locationID);
      },
      err => {
        this.game = new Game();
      }
    );
  }

  isPlayer() {
    const gameid = +this.route.snapshot.paramMap.get('gameid');
    const currentUser = this.profileService.getCurrentUser();
    this.gameService.getRSVPGames(currentUser).subscribe(
      games => {
        for(var game of games) {
          if(game.GameID == gameid) {
            this.player = true;
            return;
          }
        }

        this.player = false;
      },
      err => {
        this.player = false;
        console.log('User does not have any rsvps');
      }
    );
  }

  getPlayers() {
    const gameid = +this.route.snapshot.paramMap.get('gameid');
    this.gameService.getGameRSVPs(gameid).subscribe(
      players => {
        this.players = players;
      },
      err => {
        this.players = [];
      }
    );
  }

  getComments() {
    const gameid = +this.route.snapshot.paramMap.get('gameid');
    this.profileService.getComments("game", gameid).subscribe(
      comments => {
        this.comments = comments;
      },
      err => {
        this.comments = [];
      }
    );
  }

  getLocation(id: number) {
    this.locationService.getLocation(id).subscribe(
      res => {
        this.location = res;
      },
      err => {
        this.location = new Location();
        console.log("could not find location");
      }
    )
  }

  addComment(){
    const gameid = this.route.snapshot.paramMap.get('gameid');
    this.profileService.createComment(this.user.username, this.newComment.Comment, 'game', gameid, 0).subscribe(
      res => {
        this.router.navigate(['/dashboard/game/' + gameid])
      },
      err => {
        this.snackBar.open('Comment submition failed, please try again.', '', { duration: 5000 });
      }
    );
	}

  handlePlayer(){
    if(this.player){
      this.gameService.deleteRSVP(this.user.username, this.game.GameID).subscribe(
        res => {
          this.player = false;
          const gameid = +this.route.snapshot.paramMap.get('gameid');
          this.router.navigate([`/dashboard/game/${gameid}`]);
          this.snackBar.open("You have canceled your rsvp to this game", '', {
            duration: 5000
          });
        },
        err => {
          this.snackBar.open('Could not delete rsvp, please try again', '', {
            duration: 5000
          });
        }
      );
    }
    else{
      this.gameService.rsvp(this.user.username, this.game.GameID).subscribe(
        res => {
          this.player = true;
          const gameid = +this.route.snapshot.paramMap.get('gameid');
          this.router.navigate([`/dashboard/game/${gameid}`]);
          this.snackBar.open("You have rsvp'd to this game", '', {
            duration: 5000
          });
        },
        err => {
          this.snackBar.open('Could not rsvp, please try again', '', {
            duration: 5000
          });
        }
      );
    }
  }
}
<file_sep><?php

header('Content-type: application/json');
require '../vendor/autoload.php';
use \Mailgun\Mailgun;
use Slim\Http\Request;
use Slim\Http\Response;

//Email verification works but  had a problem with setting up our site domain so that email sent for verification would say username@hooplife 
//but we were not able to figur it out intime the program
//the email verification works verywell with emails that are registerd as Authorized recipients on the mailgun platform 
 
function email_verification($email, $last_name, $first_name, $username, $uid){

	define('MAILGUN_PUBKEY','<KEY>' );
 
 	 
 	 $link = 'http://172.16.58.3:8080/verfy/' . $uid;
  
         $mgClient = new \Mailgun\Mailgun('key-8e43115292421ce6aacc3a9660ff8ab2', new \Http\Adapter\Guzzle6\Client());
 	 $domain = "sandboxebd7f04a98f44fce89d21ec452133e47.mailgun.org";
  
	 $send = $mgClient->sendMessage($domain, array(
      'from'    => 'hooplife <<EMAIL>@<EMAIL>>',
      'to'      => $first_name . ' ' . $last_name . ' <' . $email . '>',
      'subject' => 'Hooplife Yants You Verfy Your Account',
      'html'    =>' <body>

		<p>Dear ' .$first_name. '
		<br><br>
		<br>We are excited to have you as part of the hooplife family<br>
		<br>Please veryfy you email address by clicking on the following link<br>
		<br> '. $link .' <br>

		<br>With regards<br>

		<br>Team Hooplife<br>
		</p>

		</body>
		</html>',
  ));

	


}


// Validating a user's email
$app->get('/verfy/{username}', function ($request, $response, $args) {

    $pdo = $this->db;

   // $update = $pdo->prepare('UPDATE users SET verified='1' WHERE username=:username');
   // $update->bindParam("username", $username);
   // $update->execute();

   // return $response->withStatus(200);
  $check = $this->db->prepare("UPDATE users SET verified='1' WHERE userid=:username ");
  $check->bindParam("username", $args['username']);
  $check->execute();

  echo "Thank you for Validating you email";
//  return $response->withStatus(200);
});





<file_sep>import { Component, OnInit } from '@angular/core';
import { Router, RouterLink, NavigationEnd } from '@angular/router';
import { Page } from '../../_models/page';

import { AuthService } from '../../_services/auth.service';
import { ProfileService } from '../../_services/profile.service';

@Component({
  selector: 'app-navigation',
  templateUrl: './navigation.component.html',
  styleUrls: ['./navigation.component.scss']
})
export class NavigationComponent implements OnInit {
  pages: Page[];

  constructor(
    private authService: AuthService,
    private profileService: ProfileService,
    private router: Router
  ) {
    this.router.routeReuseStrategy.shouldReuseRoute = function(){
        return false;
     }

     this.router.events.subscribe((evt) => {
        if (evt instanceof NavigationEnd) {
           // trick the Router into believing it's last link wasn't previously loaded
           this.router.navigated = false;
           // if you need to scroll back to top, here is the right place
           window.scrollTo(0, 0);
        }
    });
  }

  ngOnInit() {
    var currentUser = this.profileService.getCurrentUser();
    this.pages = [
      {
        "name": "profile",
        "url": `user/${currentUser}`
      },
      {
        "name": "games",
        "url": "games"
      },
      {
        "name": "locations",
        "url": "locations"
      }
    ]
  }

  logout() {
    this.authService.logout();
  }

}
<file_sep>import { Component, ElementRef, Input, EventEmitter, Output, OnChanges } from '@angular/core';
import { CloudinaryResponse } from '../../_models/cloudinary-response';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from "rxjs/Rx";

@Component({
    selector: 'image-upload',
    template: '<form><input type="file" accept="image/*" (change)="uploadFile($event)"></form>'
})

export class ImageUploadComponent {

    @Input() public public_id: string;
    @Output() public uploaded: EventEmitter<boolean> = new EventEmitter<boolean>();

    constructor(private http: HttpClient) {}

    uploadFile(fileInput: any){
        this.upload(fileInput).subscribe(x => {
            if(!x.public_id){
                this.uploaded.emit(false);
            } else {
                this.uploaded.emit(true);
            }
        });
    }

    upload(fileInput: any): Observable<CloudinaryResponse> {
        let formData: FormData = new FormData();

        formData.append('file', fileInput.target.files[0]);
        formData.append('upload_preset', 'knlspx3g');

        return this.http.post<CloudinaryResponse>('https://api.cloudinary.com/v1_1/dwymiyvae/image/upload', formData, {headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')})
            .catch(x => this.handleException(x));
    }

    handleException(exception: any) {
        var message = `${exception.status} : ${exception.statusText}\r\n${exception.body.error}`;
        alert(message);
        this.uploaded.emit(false);
        return Observable.throw(message);
    }

}
<file_sep>import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { MatSnackBar } from '@angular/material';

import { LocationService } from '../../_services/location.service';
import { ProfileService } from '../../_services/profile.service';

@Component({
  	selector: 'app-location-submit',
  	templateUrl: './location-submit.component.html',
  	styleUrls: ['./location-submit.component.scss']
})

export class LocationSubmitComponent {

  currUser: string;
  address: string;
  description: string;
  pic: string;

  constructor(
    private router: Router,
    private profileService: ProfileService,
    private locationService: LocationService,
    private snackBar: MatSnackBar
  ) {}

  cancel() {
    this.router.navigate(['/dashboard/locations']);
  }

  submit() {
    this.currUser = this.profileService.getCurrentUser();
    this.locationService.requestLoc(this.currUser, this.address, this.description, this.pic).subscribe(
      res => {
        this.snackBar.open('Location request suceeded, it will show up in the list once approved', '', {
          duration: 5000
        });
      },
      err => {
        this.snackBar.open('Request failed, please try again. Descriptions and addresses must be unique', '', {
          duration: 5000
        });
      }
    );
  }
}
<file_sep>export class Comment {
	username: string;
	Date: Date;
	rating: number;
	Comment: string;
}
<file_sep>import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { MatSnackBarModule } from '@angular/material';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';

import { AppRoutingModule } from '../../_modules/app-routing/app-routing.module';

import { ProfileService } from '../../_services/profile.service';
import { LocationService } from '../../_services/location.service';

import { RatingComponent } from '../../components/rating/rating.component';
import { CommentComponent } from '../../components/comment/comment.component';
import { ImageUploadComponent } from '../../components/image-upload/image-upload.component';

@NgModule({
  declarations: [
    RatingComponent,
    CommentComponent,
    ImageUploadComponent
  ],
  imports: [
    CommonModule,
    HttpClientModule,
    MatSnackBarModule,
    NoopAnimationsModule,
    AppRoutingModule
  ],
  providers: [
    ProfileService,
    LocationService
  ],
  exports: [
    RatingComponent,
    CommentComponent,
    AppRoutingModule
  ]
})
export class SharedModule { }
<file_sep>export class User {
	username: string;
	userid: number;
	first_name: string;
	last_name: string;
	num_of_games_played: number;
	email: string;
	date_joined: Date;
	last_updated: Date;
	last_login: Date;
	year: string;
	isAdmin: number;
	ranking: string;
	rating: number;
	wins: number;
	losses: number;
	pic_url: string;
}
<file_sep><?php

header('Content-type: application/json');

use Slim\Http\Request;
use Slim\Http\Response;

//a user that is an admin can make another user admin
$app->get('/setadmin[/{AdminUsername}[/{username}]]', function($request, $response, $args){
  
  $check = $this->db->prepare("SELECT *  FROM users where username=:AdminUsername AND isAdmin='1'");
  $check->bindParam("AdminUsername", $args['AdminUsername']);
  $check->execute();
  $row = $check->rowCount();
 
  if (!$row) {
 	return $response->withStatus(403);
 }
  
  else
  
  $check = $this->db->prepare("UPDATE users SET isAdmin='1' WHERE username=:username ");
  $check->bindParam("username", $args['username']);
  $check->execute();
  
//  return $response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
});

<file_sep><?php

header('Content-type: application/json');

use Slim\Http\Request;
use Slim\Http\Response;

//changed from using user seesion to JWT
//comment part is commented out because I implimented it in its own route
$app->get('/profile/{username}', function (Request $request, Response $response, array $args){
	$db = $this->db;
	
        //Query users table for data on current user based on userID passed in
	//Query results will tie to $targetUser
	$userQuery = $db->prepare("SELECT username, userid, first_name, last_name, num_of_games_played, email, date_joined, last_updated, last_login, year, isAdmin, ranking, rating, wins, losses, pic_url  FROM users WHERE username=:username");
	$userQuery->bindParam("username", $args['username']);
	$userQuery->execute();
	$targetUser = $userQuery->fetchObject();
        $row = $userQuery->rowCount();

  	 if (!$row)
        {
        return $response->withStatus(404);
        }
  	
        //Fetch userid of current user to determine if user is viewing own page
	//Attach viewingOwnPage boolean to targetUser object
	//$sessionQuery = $db->prepare("SELECT userid FROM Sessions WHERE sessionid = :sid");
	//$sessionQuery->bindParam("sid", $args['sessionId']);
	//$sessionQuery->execute();
	//if ($targetUser->userid === $sessionQuery->fetchObject()->userid) 
	
	//	$targetUser->viewingOwnPage = true;
	
	//else
		//$targetUser->viewingOwnPage = false;
	//Fetch comments on the user's page
	
	//If there are comments, add them to the targetUser object
      //	$commentsQuery = $db->prepare("SELECT Comment, Date, username, target_id, target_username, URL FROM comments WHERE target_username =:username");
//	$commentsQuery->bindParam("username", $args['username']);
//	$commentsQuery->execute();
//	$numOfComments = $commentsQuery->rowCount();
//	
//	if ($numOfComments > 0)
//		$targetUser->comments = $commentsQuery->fetchAll();
//	
//	//Format user information into json and send response
	$jsonResponse = json_encode($targetUser);
	$this->response->getBody()->write($jsonResponse);
	
 	return $this->response;

});


<file_sep>/* The authentication service includes registration and login routes. This also
includes jwt operations for user authentication, working in conjunction with
the authentication guard. */

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { Router } from '@angular/router';

import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of';
import { catchError, map, tap } from 'rxjs/operators';
import { KJUR } from 'jsrsasign';

import { environment } from '../../environments/environment';

import { User } from '../_models/user';
import { Login } from '../_models/login';

const headers =  new HttpHeaders({ 'Content-Type': 'application/json' });

@Injectable()
export class AuthService {

  private apiUrl = environment.url;

  constructor(
    private http: HttpClient,
    private router: Router
  ) { }

  /** POST: add a new user to the server */
  addUser (user: User, pass: string): Observable<HttpResponse<any>> {
    const url = `${this.apiUrl}/registration`;
    return this.http.post<Response>(url,
      {
        username: user.username,
        first_name: user.first_name,
        last_name: user.last_name,
        email: user.email,
        year: user.year,
        password: <PASSWORD>
      },
      {observe: 'response'}).pipe(
      tap(res => console.log(`added user w/ username=${user.username}`))
    );
  }

  login(login: Login): Observable<HttpResponse<any>> {
    const url = `${this.apiUrl}/login`;
    return this.http.post<Response>(url,
      {
        username: login.username,
        password: login.password
      },
      {observe: 'response'}).pipe(
      tap(login => console.log(`check login`))
    );
  }

  /* TODO PUT: change password */
  changePass(username: string, oldPass: string, newPass: string): Observable<HttpResponse<any>> {
    const url = `${this.apiUrl}/change-password/${username}`;
    return this.http.put<Response>(url,
      {
        old_password: <PASSWORD>,
        new_password: <PASSWORD>
      },
      {observe: 'response'}).pipe(
      tap(login => console.log(`check login`))
    );
  }

  getJWT(payload) {
    var header = {alg: "HS256", typ: "JWT"};
    return KJUR.jws.JWS.sign("HS256", header, payload, {utf8: "secret"});
  }

  logout() {
    localStorage.removeItem('auth');
    this.router.navigate(['/login']);
  }
}
<file_sep><?php

header('Content-type: application/json');
use Slim\Http\Request;
use Slim\Http\Response;

// Show list of games nearby
$app->get('/games', function(Request $request, Response $response, array $args){
  $pdo = $this->db->prepare("SELECT * FROM games ORDER BY date_of_game");
  $pdo->execute();
  $games = $pdo->fetchAll();
  if(!empty($games)) {
    return $this->response->withJson($games);
  } else {
    return $this->response->withStatus(404);
  }
});


<file_sep><?php

header('Content-type: application/json');
use Slim\Http\Request;
use Slim\Http\Response;

// Show specific game
$app->get('/game/{id}', function(Request $request, Response $response, array $args){
  $pdo = $this->db->prepare("SELECT * FROM games WHERE GameID=:id");
  $pdo->bindParam("id", $args["id"]);
  $pdo->execute();
  $game = $pdo->fetchAll();

  if (!$game)
        {
        return $response->withStatus(404);
}
   else {

        return $this->response->withJson($game);
}

});

// Submit a new game
$app->post('/new-game', function(Request $request, Response $response){
  $input = $request->getParsedBody();
  $pdo = $this->db->prepare("INSERT INTO games (description, time_created, creator_username, date_of_game, minimum_rank, locationID) VALUES (:description, CURRENT_TIMESTAMP, :creator_username, :date_of_game, :minimum_rank, :locationID)");
 // $pdo->bindParam("picture_url", $input["picture_url"]);
  $pdo->bindParam("locationID", $input["locationID"]);
  $pdo->bindParam("date_of_game", $input["date_of_game"]);
  $pdo->bindParam("description", $input["description"]);
  $pdo->bindParam("creator_username", $input["creator_username"]);
  $pdo->bindParam("minimum_rank", $input["minimum_rank"]);
  $pdo->execute();
//        return $this->response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
});

// Update game details
$app->put('/game/{GameID}/edit', function(Request $request, Response $response, array $args) {
  $input = $request->getParsedBody();
  $pdo = $this->db->prepare("UPDATE games SET picture_url=:picture_url, locationID=:locationID, description=:description, time_created=CURRENT_TIMESTAMP, date_of_game=:date_of_game, minimum_rank=:minimum_rank  WHERE GameID=:GameID");
  $pdo->bindParam("GameID", $args["GameID"]);
  $pdo->bindParam("picture_url", $input["picture_url"]);
  $pdo->bindParam("locationID", $input["locationID"]);
  $pdo->bindParam("description", $input["description"]);
  $pdo->bindParam("date_of_game", $input["date_of_game"]);
  $pdo->bindParam("minimum_rank", $input["minimum_rank"]);
  $pdo->execute();
 //       return $this->response->withStatus(200); $data = array(‘success’ => ‘true’);

        $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
});
<file_sep><?php

header('Content-type: application/json');
use Slim\Http\Request;
use Slim\Http\Response;

// update a user ranking
$app->put('/rank-update/[{uid}]', function(Request $request, Response $response, array $args){                                                                                                        
  
  $data = json_decode(file_get_contents("php://input"));
  $ranking = $data->ranking;
  
 //  $input = $request->getParsedBody();
 //  $pdo->bindParam("ranking", $args["ranking"]);
  // $pdo->execute();
  // $input['ranking'] = $args['ranking'];
  if( !isset($ranking) || empty($ranking)){
  
  return $response->withStatus(403);
  }
  
  $pdo = $this->db->prepare('SELECT *  FROM users WHERE username=:uid');
  $pdo->bindParam("uid", $args['uid']);
  $pdo->execute();
  $row = $pdo->rowCount();
     
   if (!$row)
        {
        return $response->withStatus(404);
        }
  	else
	{
       $stmt = $this->db->prepare("UPDATE users SET ranking=:ranking WHERE username=:uid");
       $stmt->bindParam("uid", $args['uid']);
       $stmt->bindParam("ranking", $ranking);
       $stmt->execute();
//        return $response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
}
});


// update number of games played
$app->put('/games-played-update/[{uid}]', function(Request $request, Response $response, array $args){

  $data = json_decode(file_get_contents("php://input"));
  $num_of_games_played = $data->num_of_games_played;

 //  $input = $request->getParsedBody();
 //  $pdo->bindParam("ranking", $args["ranking"]);
  // $pdo->execute();
  // $input['ranking'] = $args['ranking'];
  if( !isset($num_of_games_played) || empty($num_of_games_played)){

  return $response->withStatus(403);
  }

  $pdo = $this->db->prepare('SELECT *  FROM users WHERE username=:uid');
  $pdo->bindParam("uid", $args['uid']);
  $pdo->execute();
  $row = $pdo->rowCount();

   if (!$row)
        {
        return $response->withStatus(404);
        }
        else
        {
       $stmt = $this->db->prepare("UPDATE users SET num_of_games_played=:num_of_games_played WHERE username=:uid");
       $stmt->bindParam("uid", $args['uid']);
       $stmt->bindParam("num_of_games_played", $num_of_games_played);
       $stmt->execute();

//        return $response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
}
});


// update player rating
$app->put('/rating-update/{type}/{uid}', function(Request $request, Response $response, array $args){

  $data = json_decode(file_get_contents("php://input"));
  $rating = $data->rating;

 //  $input = $request->getParsedBody();
 //  $pdo->bindParam("ranking", $args["ranking"]);
  // $pdo->execute();
  // $input['ranking'] = $args['ranking'];
  if( !isset($rating) || empty($rating)){

  return $response->withStatus(403);
  }
   
  // if ($args['type'] == "location") {
   // $stmt = "(update location SET rating=:rating Where locationID=:uid";
    // $stmt->bindParam("uid", $args['uid']);
     //  $stmt->bindParam("rating", $rating);
      // $stmt->execute();

    // $data = array(‘success’ => ‘true’);

//       return $response->withJson($data, 200);

  // }  
//    else 

if ($args['type'] == "user") {


  $pdo = $this->db->prepare('SELECT *  FROM users WHERE username=:uid');
  $pdo->bindParam("uid", $args['uid']);
  $pdo->execute();
  $row = $pdo->rowCount();

   if (!$row)
        {
        return $response->withStatus(404);
        }
        else
        {
       $stmt = $this->db->prepare("UPDATE users SET rating=:rating WHERE username=:uid");
       $stmt->bindParam("uid", $args['uid']);
       $stmt->bindParam("rating", $rating);
       $stmt->execute();
       // return $response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
}

}


});


// update player win/loss
$app->put('/wins-update/[{uid}]', function(Request $request, Response $response, array $args){

  $data = json_decode(file_get_contents("php://input"));
  $wins = $data->wins;

 //  $input = $request->getParsedBody();
 //  $pdo->bindParam("ranking", $args["ranking"]);
  // $pdo->execute();
  // $input['ranking'] = $args['ranking'];
  if( !isset($wins) || empty($wins)){

  return $response->withStatus(403);
  }

  $pdo = $this->db->prepare('SELECT *  FROM users WHERE username=:uid');
  $pdo->bindParam("uid", $args['uid']);
  $pdo->execute();
  $row = $pdo->rowCount();

   if (!$row)
        {
        return $response->withStatus(404);
        }
        else
        {
       $stmt = $this->db->prepare("UPDATE users SET wins=:wins WHERE username=:uid");
       $stmt->bindParam("uid", $args['uid']);
       $stmt->bindParam("wins", $wins);
       $stmt->execute();
       // return $response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
}
});

// update player loss
$app->put('/losses-update/[{uid}]', function(Request $request, Response $response, array $args){

  $data = json_decode(file_get_contents("php://input"));
  $losses = $data->losses;

 //  $input = $request->getParsedBody();
 //  $pdo->bindParam("ranking", $args["ranking"]);
  // $pdo->execute();
  // $input['ranking'] = $args['ranking'];
  if( !isset($losses) || empty($losses)){

  return $response->withStatus(403);
  }

  $pdo = $this->db->prepare('SELECT *  FROM users WHERE username=:uid');
  $pdo->bindParam("uid", $args['uid']);
  $pdo->execute();
  $row = $pdo->rowCount();

   if (!$row)
        {
        return $response->withStatus(404);
        }
        else
        {
       $stmt = $this->db->prepare("UPDATE users SET losses=:losses WHERE username=:uid");
       $stmt->bindParam("uid", $args['uid']);
       $stmt->bindParam("losses", $losses);
       $stmt->execute();

//        return $response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
}
});
<file_sep><?php

header('Content-type: application/json');
use Slim\Http\Request;
use Slim\Http\Response;

// change password
$app->put('/change-password/[{uid}]', function(Request $request, Response $response, array $args){

  $data = json_decode(file_get_contents("php://input"));
  $old_password = $data->old_password;
  $new_password = $data->new_password;

 //  $input = $request->getParsedBody();
 //  $pdo->bindParam("ranking", $args["ranking"]);
  // $pdo->execute();
  // $input['ranking'] = $args['ranking'];
  if( !isset($new_password) || empty($new_password) || !isset($old_password) || empty($old_password)){

  return $response->withStatus(403);
  }

  $hnew_password = md5($<PASSWORD>);
  $hold_password = md5($<PASSWORD>);

  $pdo = $this->db->prepare('SELECT *  FROM users WHERE username=:uid AND password=:<PASSWORD>');
  $pdo->bindParam("uid", $args['uid']);
  $pdo->bindParam("hold_password", $hold_<PASSWORD>);
  $pdo->execute();
  $row = $pdo->rowCount();

   if (!$row)
        {
        return $response->withStatus(403);
        }
        else
        {
      $stmt = $this->db->prepare("UPDATE users SET password=:<PASSWORD>, last_updated=CURRENT_TIMESTAMP WHERE username=:uid");
      $stmt->bindParam("uid", $args['uid']);
      $stmt->bindParam("hnew_password", $hnew_<PASSWORD>);
      $stmt->execute();
//        return $response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
}
});

<file_sep>import { Component, OnInit, Input } from '@angular/core';
import { Router, ActivatedRoute } from '@angular/router';
import { MatSnackBar } from '@angular/material';

import { User } from '../../_models/user'
import { Comment } from '../../_models/comment';

import { ProfileService } from '../../_services/profile.service';

@Component({
  	selector: 'app-user-public',
  	templateUrl: './user-public.component.html',
  	styleUrls: ['./user-public.component.css']
})

export class UserPublicComponent{

	displayComments: boolean = true;
	currentUser: string;
	hasCommented: boolean = false;
	hasRated: boolean = false;
	newComment: Comment = new Comment();

	@Input() public user: User;
  @Input() comments: Comment[];

	constructor(
    private route: ActivatedRoute,
    private router: Router,
    private profileService: ProfileService,
    private snackBar: MatSnackBar
  ){ }

  ngOnInit() {
    this.currentUser = this.profileService.getCurrentUser();
  }

	addComment() {
    const user = this.route.snapshot.paramMap.get('username');
    this.profileService.createComment(this.currentUser, this.newComment.Comment, 'user', user, this.newComment.rating).subscribe(
      res => {
        this.router.navigate(['/dashboard/user/' + user])
      },
      err => {
        this.snackBar.open('Comment submition failed, please try again.', '', { duration: 5000 });
      }
    );
  }

  onRated(num: number){
    this.newComment.rating = num;
    this.hasRated = true;
  }
}
<file_sep>import { Component, OnInit } from '@angular/core';
import { LocationSubmitComponent } from '../../components/location-submit/location-submit.component'

@Component({
  selector: 'app-location-submit-page',
  templateUrl: './location-submit-page.component.html',
  styleUrls: ['./location-submit-page.component.css']
})
export class LocationSubmitPageComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}
<file_sep>export const environment = {
  production: true,
  url: 'http://172.16.17.32'
};
<file_sep>import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';

import { AuthGuard } from '../../_guards/auth.guard';
import { LoginGuard } from '../../_guards/login.guard';

import { DashboardComponent } from '../../pages/dashboard/dashboard.component';
import { LoginComponent } from '../../components/login/login.component';
import { RegistrationComponent } from '../../components/registration/registration.component';
import { LocationDetailsPageComponent } from '../../pages/location-details-page/location-details-page.component';
import { UserPageComponent } from '../../pages/user-page/user-page.component';
import { LocationSubmitPageComponent } from '../../pages/location-submit-page/location-submit-page.component';
import { LocationBrowsePageComponent } from '../../pages/location-browse-page/location-browse-page.component';
import { GamePageComponent } from '../../pages/game-page/game-page.component';
import { GameCreatePageComponent } from '../../pages/game-create-page/game-create-page.component';
import { GamesListPageComponent } from '../../pages/games-list-page/games-list-page.component';
import { ApproveLocationsComponent } from '../../components/approve-locations/approve-locations.component';

const routes: Routes = [
  { path: '', redirectTo: '/dashboard/games', pathMatch: 'full' },
  { path: 'registration', component: RegistrationComponent, canActivate: [LoginGuard] },
  { path: 'login', component: LoginComponent, canActivate: [LoginGuard] },
  { path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard],
    children: [
      { path: '', redirectTo: 'games', pathMatch: 'full' },
      { path: 'games', component: GamesListPageComponent, canActivate: [AuthGuard] },
      { path: 'game/:gameid', component: GamePageComponent, canActivate: [AuthGuard] },
      { path: 'gameSubmit', component: GameCreatePageComponent, canActivate: [AuthGuard] },
      { path: 'locations', component: LocationBrowsePageComponent, canActivate: [AuthGuard] },
      { path: 'location/:locID', component: LocationDetailsPageComponent, canActivate: [AuthGuard] },
      { path: 'locationSubmit', component: LocationSubmitPageComponent, canActivate: [AuthGuard] },
      { path: 'user/:username', component: UserPageComponent, canActivate: [AuthGuard] },
      { path: 'approve-locations', component: ApproveLocationsComponent, canActivate: [AuthGuard] },
    ]
  },
  { path: '**', component: DashboardComponent }
]

@NgModule({
  imports: [
    RouterModule.forRoot(routes)
  ],
  exports: [
    RouterModule
  ],
  providers: [
    AuthGuard,
    LoginGuard
  ]
})

export class AppRoutingModule { }
<file_sep>import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';

import { SharedModule } from './_modules/shared/shared.module';
import { AuthenticationModule } from './_modules/authentication/authentication.module';
import { ProfileModule } from './_modules/profile/profile.module';
import { GamesModule } from './_modules/games/games.module';

import { AppComponent } from './app.component';
import { DashboardComponent } from './pages/dashboard/dashboard.component';
import { NavigationComponent } from './components/navigation/navigation.component';

@NgModule({
  declarations: [
    AppComponent,
    DashboardComponent,
    NavigationComponent
  ],
  imports: [
    BrowserModule,
    RouterModule,
    HttpClientModule,
    FormsModule,
    SharedModule,
    AuthenticationModule,
    ProfileModule,
    GamesModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
<file_sep>import { Injectable } from '@angular/core';
import { Router, CanActivate } from '@angular/router';

import { KJUR } from 'jsrsasign';

@Injectable()
export class LoginGuard implements CanActivate {

  constructor(private router: Router) { }

  canActivate() {
    var jwt = localStorage.getItem('auth');
    if (jwt) {
      var isValid = KJUR.jws.JWS.verify(jwt, {utf8: "secret"}, ["HS256"]);

      if(isValid) {
        this.router.navigate(['/dashboard']);
        return true;
      }
    }

    // Not logged in so it's fine to stay on the login/registration page
    return true;
  }
}
<file_sep>#!/usr/bin/env bash
sudo docker-compose -f $1 stop
sudo docker-compose -f $1 build
sudo docker-compose -f $1 up -d
<file_sep>import { Component, Input, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { Location } from '../../_models/location';

@Component({
  selector: 'location-browser',
  templateUrl: './location-browser.component.html',
  styleUrls: ['./location-browser.component.scss']
})

export class LocationBrowserComponent implements OnInit {

  @Input() locations: Location[];

	constructor(
    private router: Router
  ) {
	}

	ngOnInit() {
	}

  openSubmitLocationPage() {
    this.router.navigate(['/dashboard/locationSubmit']);
  }

  goToLocation(id: number) {
    this.router.navigate([`/dashboard/location/${id}`]);
  }

}
<file_sep>import { Component, Input, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { Game } from '../../_models/game';
import { Location } from '../../_models/location';
import { LocationService } from '../../_services/location.service';
import { GameService } from '../../_services/game.service';
import { ProfileService } from '../../_services/profile.service';
import { Router } from '@angular/router';
import { MatSnackBar } from '@angular/material';

@Component({
  selector: 'game-create',
  templateUrl: './game-create.component.html',
  styleUrls: ['./game-create.component.scss']
})

export class GameCreateComponent implements OnInit {

  locations: Location[] = [];
  location_id: number;
  game_date: Date;
  hour: string;
  minute: string;
  amORpm: string;
  minimum_rank: number;
  description: string;

	constructor(
    private locationService: LocationService,
    private gameService: GameService,
    private profileService: ProfileService,
    private router: Router,
    private snackBar: MatSnackBar
  ) {}

  ngOnInit() {
    this.locationService.getApprovedLocations().subscribe(
      res => {
        this.locations = res;
      },
      err => {
        alert('what did you do');
      });
  }

  processRating(rank: number){
    this.minimum_rank = rank;
  }

  createGame(){

    const current_user = this.profileService.getCurrentUser();

    this.gameService.makeGame(
      current_user,
      this.game_date + ' ' + this.hour + ':' + this.minute + ' ' + this.amORpm,
      this.description,
      this.minimum_rank,
      this.location_id
    ).subscribe(
      res => {
        this.router.navigate(['/dashboard/games']);
      },
      err => {
        this.snackBar.open('Request failed, please try again.', '', { duration: 5000 });
      }
    );
  }
}
<file_sep><?php

header('Content-type: application/json');
use Slim\Http\Request;
use Slim\Http\Response;

//approve locatinon
$app->get('/locapprove[/{AdminUsername}[/{locid}]]', function($request, $response, $args){

  $check = $this->db->prepare("SELECT *  FROM users where username=:AdminUsername AND isAdmin='1'");
  $check->bindParam("AdminUsername", $args['AdminUsername']);
  $check->execute();
  $row = $check->rowCount();

  if (!$row) {
        return $response->withStatus(403);
 }

 if ($row) 
 {
  $check = $this->db->prepare("SELECT *  FROM location where locationID=:locid");
  $check->bindParam("locid", $args['locid']);
  $check->execute();
  $row1 = $check->rowCount();
  if (!$row1) 
   {
	return $response->withStatus(404);
   }

  else
  {
  $check = $this->db->prepare("UPDATE location SET approved='1' WHERE locationID=:locid ");
  $check->bindParam("locid", $args['locid']);
  $check->execute();
//  return $response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200); 
 }

  }

});
<file_sep>import { Component, Input, Output, OnInit, EventEmitter } from '@angular/core';

@Component({
  selector: 'rating',
  templateUrl: './rating.component.html',
  styleUrls: ['./rating.component.scss']
})

export class RatingComponent {

	stars: number;
	userHasRated: boolean;
	clickStars: boolean;

	@Input() public ratingValue: number;
	@Output() public onRated = new EventEmitter<number>();

	ngOnInit() {
		if(this.ratingValue === 0)
		{
			this.clickStars = true;
		}

		else
		{
			this.clickStars = false;
			this.stars = Math.round(this.ratingValue * 2)/2;
		}
	}

	public rated(num: number){
		this.onRated.emit(num);
		this.ratingValue = num;
	}
}
<file_sep><?php

header('Content-type: application/json');
use Slim\Http\Request;
use Slim\Http\Response;

// Show all comments for a game, location, or user
$app->get('/{type}/{id}/comments', function(Request $request, Response $response, array $args){
  if ($args['type'] == "game") {
    $sql = "SELECT username, comments.rating, Date, Comment, comments.GameID from comments JOIN games WHERE comments.GameID=games.GameID AND comments.GameID=:id ORDER BY Date";
  } else if ($args['type'] == "location") {
    $sql = "SELECT comments.username, comments.rating, Date, Comment, comments.locationID from comments JOIN location WHERE comments.locationID=location.locationID AND comments.locationID=:id ORDER BY Date";
  } else if ($args['type'] == "user") {
    $sql = "SELECT comments.username, comments.rating, Date, Comment, target_username FROM comments JOIN users WHERE comments.username=users.username AND comments.target_username=:id ORDER BY Date";
  } else {
    return $this->response->withStatus(404);
  }
  $pdo = $this->db->prepare($sql);
  $pdo->bindParam("id", $args['id']);
  $pdo->execute();
  $comments = $pdo->fetchAll();
	return $this->response->withJson($comments);
});

// Post a new comment
$app->post('/newcomment', function(Request $request, Response $response, array $args){
  $input = $request->getParsedBody();
  if ($input['type'] == "game") {
   $sql = "INSERT INTO comments (username, Comment, Date, GameID, rating) VALUES (:username, :Comment, CURRENT_TIMESTAMP, :id, :rating)";
  } else if ($input['type'] == "location") {
    $sql = "INSERT INTO comments (username, Comment, Date,  locationID, rating) VALUES (:username, :Comment, CURRENT_TIMESTAMP,  :id, :rating)";
  } else if ($input['type'] == "user") {
    $sql = "INSERT INTO comments (username, Comment, Date, target_username, rating) VALUES (:username, :Comment, CURRENT_TIMESTAMP, :id, :rating)";
  } else {
    return $this->response->withStatus(404);
  }
  $pdo = $this->db->prepare($sql);
  $pdo->bindParam("username", $input["username"]);
  $pdo->bindParam("Comment", $input["Comment"]);
  $pdo->bindParam("rating", $input["rating"]);
   // $pdo->bindParam("target_id", $input["target_id"]);
  $pdo->bindParam("id", $input["id"]);
  $pdo->execute();
//        return $this->response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
});

// Update a comment
$app->put('/{type}/{id}/comments/{CommentID}/edit', function(Request $request, Response $response, array $args){
  $input = $request->getParsedBody();
  $sql = "UPDATE comments SET Comment=:Comment WHERE CommentID=:CommentID";
  $pdo = $this->db->prepare($sql);
  $pdo->bindParam("Comment", $input["Comment"]);
  $pdo->bindParam("CommentID", $input["CommentID"]);
  $pdo->execute();
//        return $this->response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
});

// Delete a comment
$app->delete('/{type}/{id}/delete-comment/{CommentID}', function (Request $request, Response $response, array $args) {
  $pdo = $this->db->prepare("DELETE FROM comments WHERE CommentID=:CommentID");
  $pdo->bindParam("CommentID", $args["CommentID"]);
  $pdo->execute();
      //  return $this->response->withStatus(200);
 $data = array(‘success’ => ‘true’);

       return $response->withJson($data, 200);
});
<file_sep>export class Game {
	GameID: number;
	picture_url: string;
	locationID: number;
	description: string;
	time_created: Date;
	creator_username: number;
	date_of_game: string;
	minimum_rank: number;
}
