├── .github
├── Android.png
├── cordova.png
├── distFolder.png
├── electronnd.png
├── webnd.png
├── webpack-server.png
├── win10nd.png
├── win81nd.png
└── winMobile.png
├── .gitignore
├── Client
├── .vscode
│ └── settings.json
├── assets
│ ├── cordova
│ │ └── config.xml
│ ├── electron
│ │ ├── index.js
│ │ └── package.json
│ └── toggleHamburger.js
├── config
│ └── lite-prod-config.json
├── img
│ ├── background.jpg
│ ├── background_bak.jpg
│ └── windows
│ │ ├── Square150x150Logo.png
│ │ ├── Square310x310Logo.png
│ │ ├── Square44x44Logo.png
│ │ ├── Square70x70Logo.png
│ │ ├── Square71x71Logo.png
│ │ ├── Wide310x150Logo.png
│ │ ├── high.png
│ │ ├── smalllogo.png
│ │ ├── storelogo.png
│ │ └── wide.png
├── package-lock.json
├── package.json
├── src
│ ├── app
│ │ ├── about
│ │ │ ├── about.module.ts
│ │ │ ├── about.routes.js
│ │ │ ├── about.routes.js.map
│ │ │ ├── about.routes.ts
│ │ │ └── components
│ │ │ │ └── about
│ │ │ │ ├── about.component.html
│ │ │ │ └── about.component.ts
│ │ ├── account
│ │ │ ├── account.module.ts
│ │ │ ├── account.routes.js
│ │ │ ├── account.routes.js.map
│ │ │ ├── account.routes.ts
│ │ │ └── components
│ │ │ │ ├── login
│ │ │ │ ├── login.component.html
│ │ │ │ └── login.component.ts
│ │ │ │ └── register
│ │ │ │ ├── register.component.html
│ │ │ │ └── register.component.ts
│ │ ├── app.component.html
│ │ ├── app.component.ts
│ │ ├── app.module.ts
│ │ ├── app.routes.ts
│ │ ├── core
│ │ │ ├── core.module.ts
│ │ │ ├── factories
│ │ │ │ └── cameraFactory.ts
│ │ │ └── services
│ │ │ │ ├── authentication.service.ts
│ │ │ │ ├── camera.service.js
│ │ │ │ ├── camera.service.js.map
│ │ │ │ ├── camera.service.ts
│ │ │ │ ├── currentUser.service.ts
│ │ │ │ ├── desktopCamera.service.js
│ │ │ │ ├── desktopCamera.service.ts
│ │ │ │ ├── food-data.service.ts
│ │ │ │ ├── foodList-data.service.ts
│ │ │ │ ├── httpWrapper.service.ts
│ │ │ │ ├── mobileCamera.service.js
│ │ │ │ ├── mobileCamera.service.js.map
│ │ │ │ ├── mobileCamera.service.ts
│ │ │ │ ├── platformInformation.service.ts
│ │ │ │ └── storage.service.ts
│ │ ├── food
│ │ │ ├── components
│ │ │ │ ├── food
│ │ │ │ │ ├── food.component.html
│ │ │ │ │ └── food.component.ts
│ │ │ │ ├── foodListDetails
│ │ │ │ │ ├── foodListDetails.component.html
│ │ │ │ │ └── foodListDetails.component.ts
│ │ │ │ ├── foodListForm
│ │ │ │ │ ├── foodListForm.component.html
│ │ │ │ │ └── foodListForm.component.ts
│ │ │ │ └── foodlists
│ │ │ │ │ ├── foodlists.component.html
│ │ │ │ │ └── foodlists.component.ts
│ │ │ ├── food.module.ts
│ │ │ ├── food.routes.js
│ │ │ ├── food.routes.js.map
│ │ │ └── food.routes.ts
│ │ ├── home
│ │ │ ├── components
│ │ │ │ └── home
│ │ │ │ │ ├── home.component.html
│ │ │ │ │ └── home.component.ts
│ │ │ ├── home.module.ts
│ │ │ ├── home.routes.js
│ │ │ ├── home.routes.js.map
│ │ │ └── home.routes.ts
│ │ ├── layout
│ │ │ ├── components
│ │ │ │ └── header
│ │ │ │ │ ├── header.component.html
│ │ │ │ │ └── header.component.ts
│ │ │ └── layout.module.ts
│ │ ├── main-aot.js.map
│ │ ├── main.js.map
│ │ ├── polyfills.js.map
│ │ ├── shared
│ │ │ ├── app.constants.js
│ │ │ ├── app.constants.js.map
│ │ │ ├── app.constants.ts
│ │ │ ├── decorators
│ │ │ │ └── needsAuthentication.ts
│ │ │ ├── models
│ │ │ │ ├── foodItem.js
│ │ │ │ ├── foodItem.js.map
│ │ │ │ ├── foodItem.ts
│ │ │ │ ├── foodList.js
│ │ │ │ ├── foodList.js.map
│ │ │ │ ├── foodList.ts
│ │ │ │ ├── loginUser.js
│ │ │ │ ├── loginUser.js.map
│ │ │ │ ├── loginUser.ts
│ │ │ │ ├── token.js
│ │ │ │ ├── token.js.map
│ │ │ │ └── token.ts
│ │ │ └── shared.module.ts
│ │ └── vendor.js.map
│ ├── css
│ │ └── custom.css
│ ├── favicon.ico
│ ├── index.html
│ ├── main-aot.ts
│ ├── main.js
│ ├── main.js.map
│ ├── main.ts
│ ├── polyfills.js
│ ├── polyfills.js.map
│ ├── polyfills.ts
│ ├── vendor.js
│ ├── vendor.js.map
│ └── vendor.ts
├── tsconfig-aot.json
├── tsconfig.json
├── tslint.json
├── webpack.config.js
├── webpack.dev.js
├── webpack.prod.js
└── yarn.lock
├── README.MD
└── Server
├── FoodChooser.sln
└── FoodChooser
├── Configuration
└── AppSettings.cs
├── Controllers
├── AccountController.cs
├── FoodListsController.cs
└── FoodsController.cs
├── Dtos
├── FoodItemDto.cs
├── FoodListDto.cs
├── LinkDto.cs
└── SharedFoodListDto.cs
├── FoodChooser.csproj
├── FoodChooser.csproj.user
├── Helpers
├── DynamicExtensions.cs
└── QueryParametersExtensions.cs
├── IdentityConfig.cs
├── Migrations
├── 20171025161811_InitialCreate.Designer.cs
├── 20171025161811_InitialCreate.cs
└── FoodChooserDbContextModelSnapshot.cs
├── Models
├── FoodItem.cs
├── FoodList.cs
├── QueryParameters.cs
└── RegisterBindingModel.cs
├── Program.cs
├── Properties
└── launchSettings.json
├── Repositories
├── Food
│ ├── FoodRepository.cs
│ └── IFoodRepository.cs
├── FoodChooserDbContext.cs
└── List
│ ├── FoodListRepository.cs
│ └── IFoodListRepository.cs
├── Services
├── DataBaseInit
│ ├── DatabaseInitializer.cs
│ └── IDatabaseInitializer.cs
└── RandomNumber
│ ├── IRandomNumberGenerator.cs
│ └── RandomNumberGenerator.cs
├── Startup.cs
├── appsettings.development.json
├── appsettings.json
├── tempkey.rsa
└── wwwroot
└── FoodImages
├── 34f6c25a-8045-4c69-b4ab-cff2c8466758.png
├── 7f7c8988-2750-4bf6-9595-805880e10452.png
├── 8267a578-bd32-45ab-ad7e-0e44d7e67786.png
├── b2ba66c1-8914-42ca-84bf-924aad99da2f.png
└── dummy.png
/.github/Android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/.github/Android.png
--------------------------------------------------------------------------------
/.github/cordova.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/.github/cordova.png
--------------------------------------------------------------------------------
/.github/distFolder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/.github/distFolder.png
--------------------------------------------------------------------------------
/.github/electronnd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/.github/electronnd.png
--------------------------------------------------------------------------------
/.github/webnd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/.github/webnd.png
--------------------------------------------------------------------------------
/.github/webpack-server.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/.github/webpack-server.png
--------------------------------------------------------------------------------
/.github/win10nd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/.github/win10nd.png
--------------------------------------------------------------------------------
/.github/win81nd.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/.github/win81nd.png
--------------------------------------------------------------------------------
/.github/winMobile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/.github/winMobile.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | Client/node_modules
2 | Server/.vs/
3 | Client/app/*.js
4 | Client/app/*.js.map
5 | Client/app/components/**/*.js
6 | Client/app/components/**/*.js.map
7 | Server/FoodChooser/bin
8 | Server/FoodChooser/obj
9 | Server/packages/
10 | Server/FoodChooser/Properties/PublishProfiles/
11 | Client/typings
12 | .dist
13 | .temp
14 | Client/app/shared/services/*.js
15 | Client/app/shared/services/*.js.map
16 | Client/app/models/*.js.map
17 | Client/app/models/*.js
18 | Client/app/shared/app.constants.js
19 | Client/app/shared/app.constants.js.map
20 | Client/app/decorators/needsAuthentication.js
21 | Client/app/decorators/needsAuthentication.js.map
22 | Client/npm-debug.log
23 | Client/aot/
24 | Client/src/.aot
25 | Client/src/app/**/*.js
26 | Client/src/app/**/*.js.map
27 |
28 | /Server/FoodChooser/wwwroot/FoodImages/*.png
29 |
--------------------------------------------------------------------------------
/Client/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "typescript.check.workspaceVersion": false,
3 | "vsicons.presets.angular": true
4 | }
--------------------------------------------------------------------------------
/Client/assets/cordova/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | FoodChooser A2
4 |
5 | A small demo app to give yoou FoodSuggestions
6 |
7 |
8 | Offering.Solutions
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/Client/assets/electron/index.js:
--------------------------------------------------------------------------------
1 | // main/index.js
2 |
3 | 'use strict';
4 | const electron = require('electron'),
5 | app = electron.app,
6 | BrowserWindow = electron.BrowserWindow;
7 |
8 | var mainWindow = null;
9 |
10 | app.on('window-all-closed', function() {
11 | if (process.platform != 'darwin') {
12 | app.quit();
13 | }
14 | });
15 |
16 | app.on('ready', function() {
17 | mainWindow = new BrowserWindow({
18 | width: 1024,
19 | height: 768,
20 | nodeIntegration: false
21 | });
22 | mainWindow.loadURL('file://' + __dirname + '/index.html');
23 | //mainWindow.webContents.openDevTools();
24 | mainWindow.on('closed', function() {
25 | mainWindow = null;
26 | });
27 | });
--------------------------------------------------------------------------------
/Client/assets/electron/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "main" : "index.js",
3 | "version" : "0.0.1",
4 | "name": "FoodChooser"
5 | }
--------------------------------------------------------------------------------
/Client/assets/toggleHamburger.js:
--------------------------------------------------------------------------------
1 | // Make Hamburgermenu dissappear after cliking on it on mobile devices
2 | $(document).ready(function () {
3 | $(document).on('click', '.navbar-collapse.in', function (e) {
4 | if ($(e.target).is('a') && $(e.target).attr('class') != 'dropdown-toggle') {
5 | $(this).collapse('hide');
6 | }
7 | });
8 | });
--------------------------------------------------------------------------------
/Client/config/lite-prod-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "server": {
3 | "baseDir": "./.dist/web/aot/"
4 | }
5 | }
--------------------------------------------------------------------------------
/Client/img/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/Client/img/background.jpg
--------------------------------------------------------------------------------
/Client/img/background_bak.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/Client/img/background_bak.jpg
--------------------------------------------------------------------------------
/Client/img/windows/Square150x150Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/Client/img/windows/Square150x150Logo.png
--------------------------------------------------------------------------------
/Client/img/windows/Square310x310Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/Client/img/windows/Square310x310Logo.png
--------------------------------------------------------------------------------
/Client/img/windows/Square44x44Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/Client/img/windows/Square44x44Logo.png
--------------------------------------------------------------------------------
/Client/img/windows/Square70x70Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/Client/img/windows/Square70x70Logo.png
--------------------------------------------------------------------------------
/Client/img/windows/Square71x71Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/Client/img/windows/Square71x71Logo.png
--------------------------------------------------------------------------------
/Client/img/windows/Wide310x150Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/Client/img/windows/Wide310x150Logo.png
--------------------------------------------------------------------------------
/Client/img/windows/high.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/Client/img/windows/high.png
--------------------------------------------------------------------------------
/Client/img/windows/smalllogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/Client/img/windows/smalllogo.png
--------------------------------------------------------------------------------
/Client/img/windows/storelogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/Client/img/windows/storelogo.png
--------------------------------------------------------------------------------
/Client/img/windows/wide.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/Client/img/windows/wide.png
--------------------------------------------------------------------------------
/Client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "foodchooserangular2",
3 | "version": "1.0.0",
4 | "scripts": {
5 | "start": "tsc && webpack-dev-server --env=dev --hot --open",
6 | "lite": "lite-server --config=config/lite-prod-config.json",
7 | "tsc": "tsc",
8 | "tsc:w": "tsc -w",
9 | "test": "karma start karma.conf.js",
10 | "lint": "tslint ./app/**/*.ts -t verbose",
11 | "build-dev": "webpack --env=dev",
12 | "build-prod": "webpack --env=prod",
13 | "build-web": "npm run build-prod",
14 | "prepare-desktop": "mkdirp ./.temp/electron && ncp assets/electron .temp/electron/ && ncp .dist/web/aot .temp/electron/ && rimraf .dist/desktop/",
15 | "build-desktop": "npm run prepare-desktop && electron-packager .temp/electron/ --electronVersion=1.4.15 --platform=win32,linux --out=./.dist/desktop/ && npm run cleanup",
16 | "prepare-mobile": "rimraf ./.temp/mobile && mkdirp ./.temp/mobile/www && mkdirp ./.temp/mobile/www/img && ncp assets/cordova .temp/mobile/ && ncp .dist/web/aot .temp/mobile/www && ncp img .temp/mobile/www/img && rimraf .dist/mobile/ && trash .temp/mobile/www/**/*.js.gz",
17 | "build-mobile-windows": "mkdirp .dist/mobile/windows && cd .temp/mobile && cordova platform add windows && cordova build windows && cd ../.. && ncp .temp/mobile/platforms/windows .dist/mobile/windows",
18 | "build-mobile-android": "mkdirp .dist/mobile/android && cd .temp/mobile && cordova platform add android && cordova build android && cd ../.. && ncp .temp/mobile/platforms/android .dist/mobile/android",
19 | "build-mobile": "npm run prepare-mobile && npm run build-mobile-windows && npm run build-mobile-android && npm run cleanup",
20 | "build-all": "rimraf .dist && npm run build-web && npm run build-desktop && npm run build-mobile && npm run cleanup",
21 | "cleanup": "rimraf .temp"
22 | },
23 | "license": "ISC",
24 | "dependencies": {
25 | "@angular/animations": "^5.0.0",
26 | "@angular/common": "~5.0.0",
27 | "@angular/compiler": "~5.0.0",
28 | "@angular/compiler-cli": "~5.0.0",
29 | "@angular/core": "~5.0.0",
30 | "@angular/forms": "~5.0.0",
31 | "@angular/http": "~5.0.0",
32 | "@angular/platform-browser": "~5.0.0",
33 | "@angular/platform-browser-dynamic": "~5.0.0",
34 | "@angular/platform-server": "~5.0.0",
35 | "@angular/router": "~5.0.0",
36 | "@angular/upgrade": "~5.0.0",
37 | "bootstrap": "^3.3.7",
38 | "core-js": "2.5.1",
39 | "ie-shim": "~0.1.0",
40 | "jquery": "^3.2.1",
41 | "reflect-metadata": "0.1.10",
42 | "rxjs": "5.5.2",
43 | "zone.js": "0.8.18"
44 | },
45 | "devDependencies": {
46 | "@ngtools/webpack": "^1.8.0",
47 | "@types/jasmine": "^2.6.2",
48 | "@types/node": "8.0.47",
49 | "@types/selenium-webdriver": "^3.0.8",
50 | "angular-router-loader": "^0.6.0",
51 | "angular2-template-loader": "^0.6.2",
52 | "awesome-typescript-loader": "^3.3.0",
53 | "canonical-path": "0.0.2",
54 | "clean-webpack-plugin": "^0.1.17",
55 | "compression-webpack-plugin": "^1.0.1",
56 | "concurrently": "^3.5.0",
57 | "copy-webpack-plugin": "^4.2.0",
58 | "css-loader": "^0.28.7",
59 | "electron-packager": "^9.1.0",
60 | "extract-text-webpack-plugin": "^3.0.2",
61 | "favicons-webpack-plugin": "0.0.7",
62 | "file-loader": "^1.1.5",
63 | "html-loader": "^0.5.1",
64 | "html-webpack-plugin": "^2.30.1",
65 | "json-loader": "^0.5.7",
66 | "mkdirp": "^0.5.1",
67 | "ncp": "^2.0.0",
68 | "node-sass": "^4.6.0",
69 | "null-loader": "^0.1.1",
70 | "path": "^0.12.7",
71 | "raw-loader": "^0.5.1",
72 | "rimraf": "^2.6.2",
73 | "sass-loader": "^6.0.6",
74 | "source-map-loader": "^0.2.3",
75 | "style-loader": "^0.19.0",
76 | "trash-cli": "^1.4.0",
77 | "ts-helpers": "^1.1.2",
78 | "ts-loader": "^3.1.1",
79 | "tslint": "^5.8.0",
80 | "tslint-loader": "^3.5.3",
81 | "typescript": "2.6.1",
82 | "url-loader": "^0.6.2",
83 | "webdriver-manager": "12.0.6",
84 | "webpack": "^3.8.1",
85 | "webpack-bundle-analyzer": "^2.9.0",
86 | "webpack-dev-server": "2.9.4",
87 | "webpack-stream": "^4.0.0"
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/Client/src/app/about/about.module.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { NgModule } from '@angular/core';
3 |
4 | import { AboutRoutes } from './about.routes';
5 | import { AboutComponent } from './components/about/about.component';
6 |
7 | @NgModule({
8 | imports: [
9 | CommonModule,
10 | AboutRoutes
11 | ],
12 |
13 | declarations: [
14 | AboutComponent
15 | ],
16 |
17 | providers: [
18 | ]
19 | })
20 |
21 | export class AboutModule { }
22 |
--------------------------------------------------------------------------------
/Client/src/app/about/about.routes.js:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { AboutComponent } from './components/about/about.component';
3 | var aboutRoutes = [
4 | { path: '', component: AboutComponent }
5 | ];
6 | export var AboutRoutes = RouterModule.forChild(aboutRoutes);
7 | //# sourceMappingURL=about.routes.js.map
--------------------------------------------------------------------------------
/Client/src/app/about/about.routes.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"about.routes.js","sourceRoot":"","sources":["about.routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAU,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEpE,IAAM,WAAW,GAAW;IACxB,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE;CAC1C,CAAC;AAEF,MAAM,CAAC,IAAM,WAAW,GAAG,YAAY,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC"}
--------------------------------------------------------------------------------
/Client/src/app/about/about.routes.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule, Routes } from '@angular/router';
2 |
3 | import { AboutComponent } from './components/about/about.component';
4 |
5 | const aboutRoutes: Routes = [
6 | { path: '', component: AboutComponent }
7 | ];
8 |
9 | export const AboutRoutes = RouterModule.forChild(aboutRoutes);
10 |
--------------------------------------------------------------------------------
/Client/src/app/about/components/about/about.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Small application for demo purposes.
This application helps you to get suggestions what to cook if
6 | you have no idea. You can register and login, manage your food suggestions in lists, publish and unpublish them.
7 | If public they will be randomly shown on the startpage also to unregistered users to get some inspiration.
8 |
This page is NOT about giving you recipes because the Internet if full with sites to get recipes from. This
9 | is just to get inspirations what to bring on your plates.
10 |
This application was made for demo purposes and will not send you any newsletters or use your data for
11 | anything else.
Made with:
12 |
35 |
36 |
Hosted on
Azure
37 |
Offering.Solutions -
Fabian Gosebrink
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/Client/src/app/about/components/about/about.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'about-component',
5 | templateUrl: './about.component.html'
6 | })
7 |
8 | export class AboutComponent {
9 |
10 | constructor() { }
11 | }
12 |
--------------------------------------------------------------------------------
/Client/src/app/account/account.module.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { HttpClientModule } from '@angular/common/http';
3 | import { NgModule } from '@angular/core';
4 | import { FormsModule } from '@angular/forms';
5 |
6 | import { AccountRoutes } from './account.routes';
7 | import { LoginComponent } from './components/login/login.component';
8 | import { RegisterComponent } from './components/register/register.component';
9 |
10 | @NgModule({
11 | imports: [
12 | CommonModule,
13 | HttpClientModule,
14 | FormsModule,
15 | AccountRoutes
16 | ],
17 |
18 | declarations: [
19 | LoginComponent,
20 | RegisterComponent
21 | ],
22 |
23 | providers: [
24 | ]
25 | })
26 |
27 | export class AccountModule { }
28 |
--------------------------------------------------------------------------------
/Client/src/app/account/account.routes.js:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { LoginComponent } from './components/login/login.component';
3 | import { RegisterComponent } from './components/register/register.component';
4 | var accountRoutes = [
5 | { path: '', redirectTo: 'login' },
6 | { path: 'login', component: LoginComponent },
7 | { path: 'register', component: RegisterComponent }
8 | ];
9 | export var AccountRoutes = RouterModule.forChild(accountRoutes);
10 | //# sourceMappingURL=account.routes.js.map
--------------------------------------------------------------------------------
/Client/src/app/account/account.routes.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"account.routes.js","sourceRoot":"","sources":["account.routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAU,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAE7E,IAAM,aAAa,GAAW;IAC1B,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE;IACjC,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE;IAC5C,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE;CACrD,CAAC;AAEF,MAAM,CAAC,IAAM,aAAa,GAAG,YAAY,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC"}
--------------------------------------------------------------------------------
/Client/src/app/account/account.routes.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule, Routes } from '@angular/router';
2 |
3 | import { LoginComponent } from './components/login/login.component';
4 | import { RegisterComponent } from './components/register/register.component';
5 |
6 | const accountRoutes: Routes = [
7 | { path: '', redirectTo: 'login' },
8 | { path: 'login', component: LoginComponent },
9 | { path: 'register', component: RegisterComponent }
10 | ];
11 |
12 | export const AccountRoutes = RouterModule.forChild(accountRoutes);
13 |
--------------------------------------------------------------------------------
/Client/src/app/account/components/login/login.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Error! {{errorMessage}}
6 |
7 |
8 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/Client/src/app/account/components/login/login.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { Router } from '@angular/router';
3 |
4 | import { AuthenticationService } from './../../../core/services/authentication.service';
5 | import { LoginUser } from './../../../shared/models/loginUser';
6 | import { Token } from './../../../shared/models/token';
7 |
8 | @Component({
9 | selector: 'login-component',
10 | templateUrl: './login.component.html'
11 | })
12 |
13 | export class LoginComponent {
14 |
15 | loginUser: LoginUser;
16 | errorMessage: string;
17 |
18 | constructor(private authService: AuthenticationService, private router: Router) {
19 | this.loginUser = new LoginUser();
20 | }
21 |
22 | doLoginUser() {
23 | this.authService
24 | .loginUser(this.loginUser.Username, this.loginUser.Password)
25 | .subscribe(
26 | (response: Token) => this.router.navigate(['/home']),
27 | (error: any) => {
28 | console.log(error);
29 | this.errorMessage = JSON.parse(error._body).error_description;
30 | this.loginUser.Password = '';
31 | });
32 | }
33 |
34 | redirectTo(target: string, $event: any) {
35 | $event.preventDefault();
36 | this.router.navigate([target]);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Client/src/app/account/components/register/register.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Success! {{successMessage}}
5 |
6 |
7 |
8 | Error! {{errorMessage}}
9 |
10 |
11 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Client/src/app/account/components/register/register.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { Router } from '@angular/router';
3 |
4 | import { AuthenticationService } from './../../../core/services/authentication.service';
5 |
6 | @Component({
7 | selector: 'register-component',
8 | templateUrl: './register.component.html'
9 | })
10 |
11 |
12 | export class RegisterComponent {
13 |
14 | registerUser: any;
15 | errorMessage: string;
16 | successMessage: string;
17 |
18 | constructor(private authService: AuthenticationService, private router: Router) {
19 | this.registerUser = {};
20 | }
21 |
22 | doRegisterUser() {
23 | this.errorMessage = '';
24 | this.successMessage = '';
25 |
26 | this.authService
27 | .registerUser(
28 | this.registerUser.Username,
29 | this.registerUser.Email,
30 | this.registerUser.Password,
31 | this.registerUser.ConfirmPassword
32 | )
33 | .subscribe((response: any) => {
34 | this.successMessage = 'You have been registered. Please login.';
35 | }, (error) => {
36 | this.errorMessage = 'There was an Error: ';
37 | let errorObject = error._body;
38 | let parsedErrorObject = JSON.parse(errorObject);
39 |
40 | for (let propertyName of parsedErrorObject) {
41 | this.errorMessage += parsedErrorObject[propertyName][0];
42 | }
43 | });
44 | }
45 |
46 | redirectTo(target: string, $event: any) {
47 | $event.preventDefault();
48 | this.router.navigate([target]);
49 | }
50 | }
--------------------------------------------------------------------------------
/Client/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/Client/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { AuthenticationService } from './core/services/authentication.service';
4 |
5 | @Component({
6 | selector: 'foodChooser-app',
7 | templateUrl: './app.component.html'
8 | })
9 |
10 | export class AppComponent {
11 | constructor(public authenticationService: AuthenticationService) { }
12 | }
13 |
--------------------------------------------------------------------------------
/Client/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { HttpClientModule } from '@angular/common/http';
2 | import { NgModule } from '@angular/core';
3 | import { FormsModule } from '@angular/forms';
4 | import { BrowserModule } from '@angular/platform-browser';
5 |
6 | import { AppComponent } from './app.component';
7 | import { AppRoutes } from './app.routes';
8 | import { CoreModule } from './core/core.module';
9 | import { HomeModule } from './home/home.module';
10 | import { LayoutModule } from './layout/layout.module';
11 | import { SharedModule } from './shared/shared.module';
12 |
13 | @NgModule({
14 | imports: [
15 | BrowserModule,
16 | CoreModule.forRoot(),
17 | AppRoutes,
18 | HttpClientModule,
19 | FormsModule,
20 | HomeModule,
21 | LayoutModule,
22 |
23 | SharedModule
24 | ],
25 |
26 | declarations: [
27 | AppComponent
28 | ],
29 |
30 | providers: [],
31 |
32 | bootstrap: [AppComponent]
33 | })
34 |
35 | export class AppModule { }
36 |
--------------------------------------------------------------------------------
/Client/src/app/app.routes.ts:
--------------------------------------------------------------------------------
1 | import { Routes, RouterModule } from '@angular/router';
2 |
3 | const appRoutes: Routes = [
4 | { path: '', redirectTo: 'home', pathMatch: 'full' },
5 | { path: 'about', loadChildren: './about/about.module#AboutModule' },
6 | { path: 'account', loadChildren: './account/account.module#AccountModule' },
7 | { path: 'foodlists', loadChildren: './food/food.module#FoodModule' },
8 | {
9 | path: '**',
10 | redirectTo: 'home'
11 | }
12 | ];
13 |
14 | export const AppRoutes = RouterModule.forRoot(appRoutes, { useHash: true });
15 |
--------------------------------------------------------------------------------
/Client/src/app/core/core.module.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
3 | import { ModuleWithProviders } from '@angular/compiler/src/core';
4 | import { NgModule } from '@angular/core';
5 |
6 | import { CameraFactory } from './factories/cameraFactory';
7 | import { AuthenticationService } from './services/authentication.service';
8 | import { CurrentUserService } from './services/currentUser.service';
9 | import { FoodDataService } from './services/food-data.service';
10 | import { FoodListDataService } from './services/foodList-data.service';
11 | import { HttpWrapperService, MyFirstInterceptor } from './services/httpWrapper.service';
12 | import { PlatformInformationService } from './services/platformInformation.service';
13 | import { StorageService } from './services/storage.service';
14 |
15 | @NgModule({
16 | imports: [CommonModule, HttpClientModule],
17 | exports: [],
18 | declarations: [],
19 | providers: [
20 | // see below
21 | ],
22 | })
23 |
24 | export class CoreModule {
25 | static forRoot(): ModuleWithProviders {
26 | return {
27 | ngModule: CoreModule,
28 | providers: [
29 | AuthenticationService,
30 | HttpWrapperService,
31 | CurrentUserService,
32 | StorageService,
33 | PlatformInformationService,
34 | CameraFactory,
35 | FoodDataService,
36 | FoodListDataService,
37 | {
38 | provide: HTTP_INTERCEPTORS,
39 | useClass: MyFirstInterceptor,
40 | multi: true,
41 | }]
42 | };
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/Client/src/app/core/factories/cameraFactory.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | import { DesktopCameraService } from './../services/desktopCamera.service';
4 | import { MobileCameraService } from './../services/mobileCamera.service';
5 | import { PlatformInformationService } from './../services/platformInformation.service';
6 |
7 | @Injectable()
8 | export class CameraFactory {
9 |
10 | constructor(private _platfornInformationService: PlatformInformationService) {
11 |
12 | }
13 |
14 | getCameraService(): any {
15 |
16 | if (this._platfornInformationService.isMobile) {
17 | return new MobileCameraService();
18 | }
19 |
20 | return new DesktopCameraService();
21 | };
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/Client/src/app/core/services/authentication.service.ts:
--------------------------------------------------------------------------------
1 | import { HttpClient, HttpHeaders } from '@angular/common/http';
2 | import { Injectable } from '@angular/core';
3 | import { Router } from '@angular/router';
4 | import { Observable } from 'rxjs/Rx';
5 |
6 | import { CONFIGURATION } from './../../shared/app.constants';
7 | import { Token } from './../../shared/models/token';
8 | import { CurrentUserService } from './currentUser.service';
9 | import { Observer } from 'rxjs/Observer';
10 |
11 | @Injectable()
12 | export class AuthenticationService {
13 |
14 | constructor(private currentUserService: CurrentUserService,
15 | private http: HttpClient,
16 | private router: Router) { }
17 |
18 | get isAuthenticated(): boolean {
19 | return !!this.currentUserService.token;
20 | }
21 |
22 | loginUser(username: string, password: string): Observable {
23 | const clientId = 'client_id=' + CONFIGURATION.authConfig.CLIENT_ID;
24 | const grantType = 'grant_type=' + CONFIGURATION.authConfig.GRANT_TYPE;
25 | const usernameForBody = 'username=' + username;
26 | const passwordForBody = 'password=' + password;
27 | const scope = 'scope=' + CONFIGURATION.authConfig.SCOPE;
28 |
29 | const body = clientId.concat('&', grantType, '&', usernameForBody, '&', passwordForBody, '&', scope);
30 |
31 | const options = {
32 | headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')
33 | };
34 |
35 | return Observable.create((observer: Observer) => {
36 | this.http.post(CONFIGURATION.baseUrls.server + 'connect/token', body, options)
37 | .subscribe((tokenData: Token) => {
38 | this.currentUserService.token = tokenData.access_token;
39 | this.currentUserService.username = username;
40 | observer.next(tokenData);
41 | }, (error) => observer.error(error),
42 | () => observer.complete());
43 | });
44 | }
45 |
46 | logoutUser() {
47 | this.currentUserService.token = '';
48 | this.router.navigate(['/home']);
49 | }
50 |
51 | registerUser(username: string, email: string, password: string, confirmPassword: string): Observable {
52 | let registerData = {
53 | Email: email,
54 | Username: username,
55 | Password: password,
56 | ConfirmPassword: confirmPassword
57 | };
58 |
59 | return this.http.post(CONFIGURATION.baseUrls.server + CONFIGURATION.baseUrls.apiUrl + 'account/register',
60 | JSON.stringify(registerData));
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Client/src/app/core/services/camera.service.js:
--------------------------------------------------------------------------------
1 | //# sourceMappingURL=camera.service.js.map
--------------------------------------------------------------------------------
/Client/src/app/core/services/camera.service.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"camera.service.js","sourceRoot":"","sources":["camera.service.ts"],"names":[],"mappings":""}
--------------------------------------------------------------------------------
/Client/src/app/core/services/camera.service.ts:
--------------------------------------------------------------------------------
1 | import { Observable } from 'rxjs/Observable';
2 |
3 | export interface ICameraService {
4 | getPhoto(): Observable;
5 | }
6 |
--------------------------------------------------------------------------------
/Client/src/app/core/services/currentUser.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | import { StorageService } from './storage.service';
4 |
5 | @Injectable()
6 | export class CurrentUserService {
7 |
8 | constructor(private storageService: StorageService) {
9 |
10 | }
11 |
12 | get token(): string {
13 | return this.storageService.getItem('auth');
14 | }
15 |
16 | set token(token: string) {
17 | this.storageService.setItem('auth', token);
18 | }
19 |
20 | get username() {
21 | return this.storageService.getItem('username');
22 | }
23 |
24 | set username(username: string) {
25 | if (!username) {
26 | this.storageService.removeItem('username');
27 | } else {
28 | this.storageService.setItem('username', username);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Client/src/app/core/services/desktopCamera.service.js:
--------------------------------------------------------------------------------
1 | import { Observable } from 'rxjs/Observable';
2 | var DesktopCameraService = (function () {
3 | function DesktopCameraService() {
4 | console.log('DesktopCameraService');
5 | }
6 | DesktopCameraService.prototype.getMediaDevices = function () {
7 | var mediaDevices = ((window.navigator.mozGetUserMedia || window.navigator.webkitGetUserMedia) ? {
8 | getUserMedia: function (options) {
9 | return new Promise(function (resolve, reject) {
10 | (window.navigator.mozGetUserMedia ||
11 | window.navigator.webkitGetUserMedia).call(window.navigator, options, resolve, reject);
12 | });
13 | }
14 | } : null) || window.navigator.mediaDevices;
15 | return mediaDevices;
16 | };
17 | DesktopCameraService.prototype.getPhoto = function () {
18 | var _this = this;
19 | return Observable.create(function (observer) {
20 | _this.getMediaDevices()
21 | .getUserMedia({ video: true, audio: false })
22 | .then(function (stream) {
23 | var vendorURL = window.URL || window.webkitURL;
24 | var doc = document;
25 | var videoElement = doc.createElement('video');
26 | videoElement.src = vendorURL.createObjectURL(stream);
27 | videoElement.play();
28 | var takePhotoInternal = function () {
29 | var canvasElement = doc.createElement('canvas');
30 | canvasElement.setAttribute('width', videoElement.videoWidth.toString());
31 | canvasElement.setAttribute('height', videoElement.videoHeight.toString());
32 | setTimeout(function () {
33 | var context = canvasElement.getContext('2d');
34 | context.drawImage(videoElement, 0, 0, videoElement.videoWidth, videoElement.videoHeight);
35 | var url = canvasElement.toDataURL('image/png');
36 | videoElement.pause();
37 | if (stream.stop) {
38 | stream.stop();
39 | }
40 | if (stream.getAudioTracks) {
41 | stream.getAudioTracks().forEach(function (track) {
42 | track.stop();
43 | });
44 | }
45 | if (stream.getVideoTracks) {
46 | stream.getVideoTracks().forEach(function (track) {
47 | track.stop();
48 | });
49 | }
50 | observer.next(url);
51 | observer.complete();
52 | }, 500);
53 | };
54 | if (videoElement.readyState >= videoElement.HAVE_FUTURE_DATA) {
55 | takePhotoInternal();
56 | }
57 | else {
58 | videoElement.addEventListener('canplay', function () {
59 | takePhotoInternal();
60 | }, false);
61 | }
62 | }, (function (error) {
63 | console.log(error);
64 | }));
65 | });
66 | };
67 | return DesktopCameraService;
68 | }());
69 | export { DesktopCameraService };
70 | //# sourceMappingURL=desktopCamera.service.js.map
--------------------------------------------------------------------------------
/Client/src/app/core/services/desktopCamera.service.ts:
--------------------------------------------------------------------------------
1 | import { ICameraService } from './camera.service';
2 | import { Observer } from 'rxjs/Observer';
3 | import { Observable } from 'rxjs/Observable';
4 |
5 | declare let window: any;
6 |
7 | export class DesktopCameraService implements ICameraService {
8 |
9 | constructor() {
10 | console.log('DesktopCameraService');
11 | }
12 |
13 | private getMediaDevices(): any {
14 | const mediaDevices = ((window.navigator.mozGetUserMedia || window.navigator.webkitGetUserMedia) ? {
15 | getUserMedia: function (options: any) {
16 | return new Promise((resolve, reject) => {
17 | (window.navigator.mozGetUserMedia ||
18 | window.navigator.webkitGetUserMedia).call(window.navigator, options, resolve, reject);
19 | });
20 | }
21 | } : null) || window.navigator.mediaDevices;
22 |
23 | return mediaDevices;
24 | }
25 |
26 | getPhoto(): Observable {
27 | return Observable.create((observer: any) => {
28 | this.getMediaDevices()
29 | .getUserMedia({ video: true, audio: false })
30 | .then((stream: any) => {
31 | let vendorURL = window.URL || window.webkitURL;
32 | let doc = document;
33 | let videoElement = doc.createElement('video');
34 | videoElement.src = vendorURL.createObjectURL(stream);
35 | videoElement.play();
36 |
37 | let takePhotoInternal = () => {
38 | let canvasElement = doc.createElement('canvas');
39 | canvasElement.setAttribute('width', videoElement.videoWidth.toString());
40 | canvasElement.setAttribute('height', videoElement.videoHeight.toString());
41 |
42 | // Wait a bit before taking a screenshot so the camera has time to adjust lights
43 | setTimeout(() => {
44 | let context = canvasElement.getContext('2d');
45 | context.drawImage(videoElement, 0, 0, videoElement.videoWidth, videoElement.videoHeight);
46 |
47 | let url = canvasElement.toDataURL('image/png');
48 |
49 | videoElement.pause();
50 |
51 | if (stream.stop) {
52 | stream.stop();
53 | }
54 |
55 | if (stream.getAudioTracks) {
56 | stream.getAudioTracks().forEach((track: any) => {
57 | track.stop();
58 | });
59 | }
60 |
61 | if (stream.getVideoTracks) {
62 | stream.getVideoTracks().forEach((track: any) => {
63 | track.stop();
64 | });
65 | }
66 |
67 | observer.next(url);
68 | observer.complete();
69 |
70 | }, 500);
71 | };
72 |
73 | if (videoElement.readyState >= videoElement.HAVE_FUTURE_DATA) {
74 | takePhotoInternal()
75 | } else {
76 | videoElement.addEventListener('canplay', function () {
77 | takePhotoInternal()
78 | }, false);
79 | }
80 |
81 | }, ((error: any) => {
82 | console.log(error);
83 | }));
84 | });
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/Client/src/app/core/services/food-data.service.ts:
--------------------------------------------------------------------------------
1 | import { HttpResponse } from '@angular/common/http/src/response';
2 | import { Injectable } from '@angular/core';
3 | import { Observer } from 'rxjs/Observer';
4 | import { Observable } from 'rxjs/Observable';
5 | import { catchError, map } from 'rxjs/operators';
6 |
7 | import { CONFIGURATION } from './../../shared/app.constants';
8 | import { FoodItem } from './../../shared/models/foodItem';
9 | import { HttpWrapperService } from './httpWrapper.service';
10 |
11 | @Injectable()
12 | export class FoodDataService {
13 |
14 | private actionUrl: string;
15 |
16 | constructor(private _http: HttpWrapperService) {
17 | this.actionUrl = CONFIGURATION.baseUrls.server +
18 | CONFIGURATION.baseUrls.apiUrl +
19 | 'foods/';
20 | }
21 |
22 | getAllFood(): Observable {
23 | return this._http.get(this.actionUrl).pipe(catchError(this.handleError));
24 | }
25 |
26 | getSingleFood(id: number): Observable {
27 | return this._http.get(this.actionUrl + id).pipe(catchError(this.handleError));
28 | }
29 |
30 | getRandomFood(): Observable {
31 | return this._http.get(this.actionUrl + 'getrandomfood')
32 | .pipe(
33 | map((foodItem: FoodItem) => {
34 |
35 | foodItem.imageString =
36 | CONFIGURATION.baseUrls.server +
37 | CONFIGURATION.baseUrls.foodImageFolder +
38 | foodItem.imageString;
39 | return foodItem;
40 |
41 | }),
42 | catchError(this.handleError)
43 | );
44 | }
45 |
46 | addFood(foodItem: FoodItem): Observable {
47 | let toAdd: string = JSON.stringify(foodItem);
48 |
49 | return this._http.post(this.actionUrl, toAdd).pipe(catchError(this.handleError));
50 | }
51 |
52 | updateFood(id: string, foodToUpdate: FoodItem): Observable {
53 | return this._http.put(this.actionUrl + id, JSON.stringify(foodToUpdate))
54 | .pipe(catchError(this.handleError));
55 | }
56 |
57 | deleteFood(id: number): Observable {
58 | return this._http.delete(this.actionUrl + id)
59 | .pipe(catchError(this.handleError));
60 | }
61 |
62 | private handleError(error: HttpResponse) {
63 | console.error(error);
64 | return Observable.throw(error || 'Server error');
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/Client/src/app/core/services/foodList-data.service.ts:
--------------------------------------------------------------------------------
1 | import { HttpResponse } from '@angular/common/http/src/response';
2 | import { Injectable } from '@angular/core';
3 | import { Observable } from 'rxjs/Observable';
4 | import { catchError, map } from 'rxjs/operators';
5 |
6 | import { CONFIGURATION } from './../../shared/app.constants';
7 | import { FoodItem } from './../../shared/models/foodItem';
8 | import { FoodList } from './../../shared/models/foodList';
9 | import { HttpWrapperService } from './httpWrapper.service';
10 |
11 | @Injectable()
12 | export class FoodListDataService {
13 |
14 | private actionUrl: string;
15 |
16 | constructor(private _http: HttpWrapperService) {
17 |
18 | this.actionUrl = CONFIGURATION.baseUrls.server +
19 | CONFIGURATION.baseUrls.apiUrl +
20 | 'foodlists/';
21 | }
22 |
23 | getAllLists(): Observable {
24 | return this._http.get(this.actionUrl)
25 | .pipe(catchError(this.handleError));
26 | }
27 |
28 | getSingleList(id: string): Observable {
29 | return this._http.get(this.actionUrl + id)
30 | .pipe(catchError(this.handleError));
31 | }
32 |
33 | getFoodFromList(id: string): Observable {
34 | return this._http.get(this.actionUrl + id + '/foods')
35 | .pipe(
36 | map((foodItems: FoodItem[]) => {
37 | foodItems.map((foodItem: FoodItem) => {
38 | foodItem.created = new Date(String(foodItem.created));
39 | foodItem.imageString =
40 | CONFIGURATION.baseUrls.server +
41 | CONFIGURATION.baseUrls.foodImageFolder +
42 | foodItem.imageString;
43 | console.log(foodItem.imageString);
44 | });
45 | return foodItems;
46 | }),
47 | catchError(this.handleError));
48 | }
49 |
50 | addList(foodListName: string): Observable {
51 | let toAdd: string = JSON.stringify({ Name: foodListName });
52 |
53 | return this._http.post(this.actionUrl, toAdd)
54 | .pipe(catchError(this.handleError));
55 | }
56 |
57 | updateList(id: string, listToUpdate: FoodList): Observable {
58 | return this._http.put(this.actionUrl + id, JSON.stringify(listToUpdate))
59 | .pipe(catchError(this.handleError));
60 | }
61 |
62 | deleteList(id: string): Observable {
63 | return this._http.delete(this.actionUrl + id)
64 | .pipe(catchError(this.handleError));
65 | }
66 |
67 | getRandomImageStringFromList(id: string): Observable {
68 | return this._http.get(this.actionUrl + id + '/getrandomimage')
69 | .pipe(catchError(this.handleError));
70 | }
71 |
72 | private handleError(error: HttpResponse) {
73 | console.error(error);
74 | return Observable.throw(error || 'Server error');
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/Client/src/app/core/services/httpWrapper.service.ts:
--------------------------------------------------------------------------------
1 | import { HttpClient, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
2 | import { Injectable } from '@angular/core';
3 | import { Observable } from 'rxjs/Observable';
4 |
5 | import { CurrentUserService } from '../services/currentUser.service';
6 |
7 | @Injectable()
8 | export class HttpWrapperService {
9 | constructor(private http: HttpClient, private currentUserService: CurrentUserService) { }
10 |
11 | get(url: string): Observable {
12 | return this.http.get(url);
13 | }
14 |
15 | post(url: string, body: any): Observable {
16 | return this.http.post(url, body);
17 | }
18 |
19 | put(url: string, body: string): Observable {
20 | return this.http.put(url, body);
21 | }
22 |
23 | delete(url: string): Observable {
24 | return this.http.delete(url);
25 | }
26 |
27 | patch(url: string, body: string): Observable {
28 | return this.http.patch(url, body);
29 | }
30 | }
31 |
32 |
33 | @Injectable()
34 | export class MyFirstInterceptor implements HttpInterceptor {
35 |
36 | constructor(private currentUserService: CurrentUserService) { }
37 |
38 | intercept(req: HttpRequest, next: HttpHandler): Observable> {
39 | // console.log(JSON.stringify(req));
40 |
41 | const token: string = this.currentUserService.token;
42 |
43 | if (token) {
44 | req = req.clone({ headers: req.headers.set('Authorization', 'Bearer ' + token) });
45 | }
46 |
47 | if (!req.headers.has('Content-Type')) {
48 | req = req.clone({ headers: req.headers.set('Content-Type', 'application/json') });
49 | }
50 |
51 | req = req.clone({ headers: req.headers.set('Accept', 'application/json') });
52 | return next.handle(req);
53 | }
54 | }
--------------------------------------------------------------------------------
/Client/src/app/core/services/mobileCamera.service.js:
--------------------------------------------------------------------------------
1 | import { Observable } from 'rxjs/Observable';
2 | var MobileCameraService = (function () {
3 | function MobileCameraService() {
4 | this.getPhoto = function () {
5 | return Observable.create(function (observer) {
6 | var removeDomListener = function () {
7 | document.removeEventListener('deviceready', onCordovaDeviceReady);
8 | };
9 | var onCordovaDeviceReady = function () {
10 | var camera = window.navigator.camera;
11 | var options = {
12 | quality: 100,
13 | destinationType: camera.DestinationType.DATA_URL,
14 | sourceType: camera.PictureSourceType.CAMERA,
15 | encodingType: camera.EncodingType.PNG,
16 | pictureSourceType: camera.PictureSourceType.CAMERA,
17 | saveToPhotoAlbum: false,
18 | targetWidth: 640,
19 | targetHeight: 640,
20 | correctOrientation: true
21 | };
22 | camera.getPicture(function (imageData) {
23 | observer.next('data:image/png;base64,' + imageData);
24 | removeDomListener();
25 | observer.complete();
26 | }, function (error) {
27 | observer.error(error);
28 | removeDomListener();
29 | observer.complete();
30 | }, options);
31 | };
32 | document.addEventListener('deviceready', onCordovaDeviceReady);
33 | });
34 | };
35 | console.log('MobileCameraService');
36 | }
37 | return MobileCameraService;
38 | }());
39 | export { MobileCameraService };
40 | //# sourceMappingURL=mobileCamera.service.js.map
--------------------------------------------------------------------------------
/Client/src/app/core/services/mobileCamera.service.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"mobileCamera.service.js","sourceRoot":"","sources":["mobileCamera.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAK7C;IAEI;QAIA,aAAQ,GAAG;YACP,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,UAAC,QAA0B;gBAChD,IAAI,iBAAiB,GAAG;oBACpB,QAAQ,CAAC,mBAAmB,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAC;gBACtE,CAAC,CAAC;gBAEF,IAAI,oBAAoB,GAAG;oBACvB,IAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;oBAEvC,IAAI,OAAO,GAAG;wBACV,OAAO,EAAE,GAAG;wBACZ,eAAe,EAAE,MAAM,CAAC,eAAe,CAAC,QAAQ;wBAChD,UAAU,EAAE,MAAM,CAAC,iBAAiB,CAAC,MAAM;wBAC3C,YAAY,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG;wBACrC,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,CAAC,MAAM;wBAClD,gBAAgB,EAAE,KAAK;wBACvB,WAAW,EAAE,GAAG;wBAChB,YAAY,EAAE,GAAG;wBACjB,kBAAkB,EAAE,IAAI;qBAC3B,CAAC;oBAYF,MAAM,CAAC,UAAU,CAAC,UAAC,SAAc;wBAC7B,QAAQ,CAAC,IAAI,CAAC,wBAAwB,GAAG,SAAS,CAAC,CAAC;wBACpD,iBAAiB,EAAE,CAAC;wBACpB,QAAQ,CAAC,QAAQ,EAAE,CAAC;oBACxB,CAAC,EAAE,UAAC,KAAU;wBACV,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;wBACtB,iBAAiB,EAAE,CAAC;wBACpB,QAAQ,CAAC,QAAQ,EAAE,CAAC;oBACxB,CAAC,EAAE,OAAO,CAAC,CAAC;gBAChB,CAAC,CAAC;gBAEF,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAC;YACnE,CAAC,CAAC,CAAC;QACP,CAAC,CAAA;QA/CG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACvC,CAAC;IA+CL,0BAAC;AAAD,CAAC,AAnDD,IAmDC"}
--------------------------------------------------------------------------------
/Client/src/app/core/services/mobileCamera.service.ts:
--------------------------------------------------------------------------------
1 | import { ICameraService } from './camera.service';
2 | import { Observable } from 'rxjs/Observable';
3 | import { Observer } from 'rxjs/Observer';
4 |
5 | declare let window: any;
6 |
7 | export class MobileCameraService implements ICameraService {
8 |
9 | constructor() {
10 | console.log('MobileCameraService');
11 | }
12 |
13 | getPhoto = (): Observable => {
14 | return Observable.create((observer: Observer) => {
15 | let removeDomListener = () => {
16 | document.removeEventListener('deviceready', onCordovaDeviceReady);
17 | };
18 |
19 | let onCordovaDeviceReady = () => {
20 | const camera = window.navigator.camera;
21 |
22 | let options = {
23 | quality: 100,
24 | destinationType: camera.DestinationType.DATA_URL,
25 | sourceType: camera.PictureSourceType.CAMERA,
26 | encodingType: camera.EncodingType.PNG,
27 | pictureSourceType: camera.PictureSourceType.CAMERA,
28 | saveToPhotoAlbum: false,
29 | targetWidth: 640,
30 | targetHeight: 640,
31 | correctOrientation: true
32 | };
33 |
34 | // let options = {
35 | // quality: 100,
36 | // destinationType: camera.DestinationType.DATA_URL,
37 | // sourceType: camera.PictureSourceType.CAMERA,
38 | // allowEdit: true,
39 | // encodingType: camera.EncodingType.PNG,
40 | // saveToPhotoAlbum: false,
41 | // correctOrientation: true
42 | // };
43 |
44 | camera.getPicture((imageData: any) => {
45 | observer.next('data:image/png;base64,' + imageData);
46 | removeDomListener();
47 | observer.complete();
48 | }, (error: any) => {
49 | observer.error(error);
50 | removeDomListener();
51 | observer.complete();
52 | }, options);
53 | };
54 |
55 | document.addEventListener('deviceready', onCordovaDeviceReady);
56 | });
57 | }
58 | }
--------------------------------------------------------------------------------
/Client/src/app/core/services/platformInformation.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | declare let window: any;
4 |
5 | @Injectable()
6 | export class PlatformInformationService {
7 | private _isMobile: boolean;
8 | private _isDesktop: boolean;
9 | private _isWeb: boolean;
10 |
11 | get isMobile(): boolean {
12 | return this._isMobile;
13 | }
14 |
15 | get isDesktop(): boolean {
16 | return this._isDesktop;
17 | }
18 |
19 | get isWeb(): boolean {
20 | return this._isWeb;
21 | }
22 |
23 | constructor() {
24 | this.guessPlatform();
25 | }
26 |
27 | private guessPlatform(): void {
28 | this._isMobile = !!window.cordova;
29 | this._isDesktop = window.navigator.userAgent.match(/Electron/) !== null;
30 | this._isWeb = !(this._isMobile || this._isDesktop);
31 | console.log('mobile: ' + this._isMobile);
32 | console.log('desktop: ' + this._isDesktop);
33 | console.log('web: ' + this._isWeb);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Client/src/app/core/services/storage.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | @Injectable()
4 | export class StorageService {
5 |
6 | private _storage: Storage;
7 |
8 | constructor() {
9 | this._storage = localStorage;
10 | }
11 |
12 | setItem(key: string, value: any): void {
13 | this._storage.setItem(key, JSON.stringify(value));
14 | };
15 |
16 | removeItem(key: string): void {
17 | this._storage.removeItem(key);
18 | };
19 |
20 | getItem(key: string): any {
21 | let item: any = this._storage.getItem(key);
22 |
23 | if (item && item !== 'undefined') {
24 | return JSON.parse(this._storage.getItem(key));
25 | }
26 |
27 | return;
28 | };
29 | }
30 |
--------------------------------------------------------------------------------
/Client/src/app/food/components/food/food.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Client/src/app/food/components/food/food.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { map } from 'rxjs/operators';
3 |
4 | import { FoodListDataService } from '../../../core/services/foodList-data.service';
5 | import { FoodList } from '../../../shared/models/foodList';
6 |
7 | @Component({
8 | selector: 'food-component',
9 | templateUrl: './food.component.html'
10 | })
11 |
12 | export class FoodComponent implements OnInit {
13 |
14 | lists: FoodList[] = [];
15 |
16 | constructor(private foodListDataService: FoodListDataService) { }
17 |
18 | addFood(foodListname: string) {
19 | this.foodListDataService
20 | .addList(foodListname)
21 | .pipe(map((response: any) => response.value))
22 | .subscribe((addedList: FoodList) => {
23 | this.lists.push(addedList);
24 | });
25 | }
26 |
27 | ngOnInit(): void {
28 | this.foodListDataService
29 | .getAllLists()
30 | .pipe(map((response: any) => response.value))
31 | .subscribe((lists: FoodList[]) => {
32 | this.lists = lists;
33 | });
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Client/src/app/food/components/foodListDetails/foodListDetails.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
15 |
16 |
17 |
18 |
29 |
30 |
31 |
32 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
{{food.itemName}}
52 |
53 | {{food.created | date:'shortDate'}}
54 | Edit
55 | Delete
56 | Publish
57 | Unpublish
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/Client/src/app/food/components/foodListDetails/foodListDetails.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, NgZone, OnInit } from '@angular/core';
2 | import { ActivatedRoute, Router } from '@angular/router';
3 | import { map, switchMap } from 'rxjs/operators';
4 |
5 | import { CameraFactory } from './../../../core/factories/cameraFactory';
6 | import { ICameraService } from './../../../core/services/camera.service';
7 | import { FoodDataService } from './../../../core/services/food-data.service';
8 | import { FoodListDataService } from './../../../core/services/foodList-data.service';
9 | import { FoodItem } from './../../../shared/models/foodItem';
10 | import { FoodList } from './../../../shared/models/foodList';
11 |
12 | @Component({
13 | selector: 'foodListDetails-component',
14 | templateUrl: './foodListDetails.component.html'
15 | })
16 |
17 | export class FoodListDetails implements OnInit {
18 |
19 | currentFoodList: FoodList;
20 | currentFoodListBackup: FoodList;
21 | currentFood: FoodItem = new FoodItem();
22 |
23 | private _listId: string;
24 | private _cameraService: ICameraService;
25 |
26 | constructor(
27 | private _router: Router,
28 | private _activatedRoute: ActivatedRoute,
29 | private _foodDataService: FoodDataService,
30 | private _foodListDataService: FoodListDataService,
31 | private _cameraFactory: CameraFactory,
32 | private _ngZone: NgZone) {
33 |
34 | this._cameraService = _cameraFactory.getCameraService();
35 | }
36 |
37 | ngOnInit() {
38 | this._activatedRoute.params.subscribe(params => {
39 | this._listId = params['foodId'];
40 | this.getSingleList(this._listId);
41 | });
42 | }
43 |
44 | private getSingleList(listId: string) {
45 | this._foodListDataService
46 | .getSingleList(listId)
47 | .pipe(map((response: FoodList) => {
48 | this.currentFoodList = response;
49 | }),
50 | switchMap(() => {
51 | return this._foodListDataService.getFoodFromList(listId)
52 | }))
53 | .subscribe((foodItems: FoodItem[]) => {
54 | this.currentFoodList.foods = foodItems;
55 | this.currentFoodListBackup = Object.assign({}, this.currentFoodList);
56 | });
57 | }
58 |
59 | togglePublic(food: FoodItem) {
60 | food.isPublic = !food.isPublic;
61 | this._foodDataService
62 | .updateFood(food.id, food)
63 | .subscribe((response: FoodItem) => {
64 | console.log('updated');
65 | });
66 | }
67 |
68 | showRandomFoodFromList() {
69 |
70 | const foodCount = this.currentFoodListBackup.foods.length;
71 |
72 | if (this.currentFoodList.foods.length > 0) {
73 | let foodToShow: FoodItem[] = [];
74 | let index = Math.floor((Math.random() * foodCount));
75 | console.log(index);
76 | foodToShow.push(this.currentFoodListBackup.foods[index]);
77 | this.currentFoodList.foods = foodToShow;
78 | }
79 | }
80 |
81 | setToUpdate(foodItem: FoodItem) {
82 | this.currentFood = foodItem;
83 | }
84 |
85 | addOrUpdateFood() {
86 | if (this.currentFood.id) {
87 | this.updateFood(this.currentFood);
88 | } else {
89 | this.addFood(this.currentFood);
90 | }
91 | }
92 |
93 | private updateFood(foodItem: FoodItem) {
94 | this._foodDataService
95 | .updateFood(foodItem.id, foodItem)
96 | .subscribe((response: FoodItem) => {
97 | this.currentFood = new FoodItem();
98 | }, error => console.log(error));
99 | }
100 |
101 | private addFood(foodItem: FoodItem) {
102 | if (foodItem.itemName) {
103 | foodItem.foodListId = this.currentFoodList.id;
104 |
105 | this._foodDataService
106 | .addFood(foodItem)
107 | .pipe(map((response: FoodItem) => {
108 | this.currentFood = new FoodItem();
109 | }),
110 | switchMap(() => {
111 | return this._foodListDataService.getFoodFromList(foodItem.foodListId)
112 | }))
113 | .subscribe((foodItems: FoodItem[]) => {
114 | this.currentFoodList.foods = foodItems;
115 | });
116 | }
117 | }
118 |
119 | deleteList() {
120 | if (this.currentFoodList) {
121 | this._foodListDataService
122 | .deleteList(this.currentFoodList.id)
123 | .subscribe((response: any) => {
124 | let link = ['/foodlists'];
125 | this._router.navigate(link);
126 | }, error => console.log(error));
127 | }
128 | }
129 |
130 | deleteFood(foodId: number) {
131 |
132 | this._foodDataService
133 | .deleteFood(foodId)
134 | .subscribe((response: any) => {
135 |
136 | }, error => console.log(error));
137 |
138 | }
139 |
140 | takePhoto(foodItem: FoodItem) {
141 | this._cameraService
142 | .getPhoto()
143 | .pipe(
144 | map((url: string) => {
145 | foodItem.imageString = url;
146 | return foodItem;
147 | }),
148 | switchMap((item: FoodItem) => {
149 | return this._foodDataService.updateFood(item.id, item)
150 | }),
151 | switchMap(() => {
152 | return this._foodListDataService.getFoodFromList(foodItem.foodListId)
153 | })
154 | )
155 | .subscribe((foodItems: FoodItem[]) => {
156 | this.currentFoodList.foods = foodItems;
157 | });
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/Client/src/app/food/components/foodListForm/foodListForm.component.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Client/src/app/food/components/foodListForm/foodListForm.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, EventEmitter, Output } from '@angular/core';
2 |
3 | import { FoodListDataService } from './../../../core/services/foodList-data.service';
4 | import { FoodList } from './../../../shared/models/foodList';
5 |
6 | @Component({
7 | selector: 'foodListForm-component',
8 | templateUrl: './foodListForm.component.html'
9 | })
10 |
11 | export class FoodListFormComponent {
12 |
13 | @Output() onFoodListAdded = new EventEmitter();
14 | list: FoodList = new FoodList();
15 |
16 | constructor() { }
17 |
18 | addList() {
19 | this.onFoodListAdded.emit(this.list.name);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Client/src/app/food/components/foodlists/foodlists.component.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/Client/src/app/food/components/foodlists/foodlists.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, OnInit } from '@angular/core';
2 |
3 | import { FoodList } from './../../../shared/models/foodList';
4 |
5 | @Component({
6 | selector: 'foodlists-component',
7 | templateUrl: './foodlists.component.html'
8 | })
9 |
10 | export class FoodListComponent {
11 | @Input() allLists: FoodList[] = [];
12 | }
13 |
--------------------------------------------------------------------------------
/Client/src/app/food/food.module.ts:
--------------------------------------------------------------------------------
1 | import { HttpClientModule } from '@angular/common/http';
2 | import { CommonModule } from '@angular/common';
3 | import { NgModule } from '@angular/core';
4 | import { FormsModule } from '@angular/forms';
5 |
6 | import { FoodComponent } from './components/food/food.component';
7 | import { FoodListDetails } from './components/foodListDetails/foodListDetails.component';
8 | import { FoodListFormComponent } from './components/foodListForm/foodListForm.component';
9 | import { FoodListComponent } from './components/foodlists/foodlists.component';
10 | import { FoodRoutes } from './food.routes';
11 |
12 | @NgModule({
13 | imports: [
14 | CommonModule,
15 | HttpClientModule,
16 | FormsModule,
17 | FoodRoutes
18 | ],
19 |
20 | declarations: [
21 | FoodListComponent,
22 | FoodComponent,
23 | FoodListDetails,
24 | FoodListFormComponent
25 | ]
26 | })
27 |
28 | export class FoodModule { }
29 |
--------------------------------------------------------------------------------
/Client/src/app/food/food.routes.js:
--------------------------------------------------------------------------------
1 | import { NeedsAuthentication } from './../shared/decorators/needsAuthentication';
2 | import { FoodListDetails } from './components/foodListDetails/foodListDetails.component';
3 | import { FoodComponent } from './components/food/food.component';
4 | import { RouterModule } from '@angular/router';
5 | var foodRoutes = [
6 | { path: '', component: FoodComponent, canActivate: [NeedsAuthentication] },
7 | { path: ':foodId', component: FoodListDetails, canActivate: [NeedsAuthentication] },
8 | ];
9 | export var FoodRoutes = RouterModule.forChild(foodRoutes);
10 | //# sourceMappingURL=food.routes.js.map
--------------------------------------------------------------------------------
/Client/src/app/food/food.routes.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"food.routes.js","sourceRoot":"","sources":["food.routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,wDAAwD,CAAC;AACzF,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAU,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEvD,IAAM,UAAU,GAAW;IACvB,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC,mBAAmB,CAAC,EAAE;IAC1E,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC,mBAAmB,CAAC,EAAE;CACtF,CAAC;AAEF,MAAM,CAAC,IAAM,UAAU,GAAG,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC"}
--------------------------------------------------------------------------------
/Client/src/app/food/food.routes.ts:
--------------------------------------------------------------------------------
1 | import { NeedsAuthentication } from './../shared/decorators/needsAuthentication';
2 | import { FoodListDetails } from './components/foodListDetails/foodListDetails.component';
3 | import { FoodComponent } from './components/food/food.component';
4 | import { Routes, RouterModule } from '@angular/router';
5 |
6 | const foodRoutes: Routes = [
7 | { path: '', component: FoodComponent, canActivate: [NeedsAuthentication] },
8 | { path: ':foodId', component: FoodListDetails, canActivate: [NeedsAuthentication] },
9 | ];
10 |
11 | export const FoodRoutes = RouterModule.forChild(foodRoutes);
12 |
--------------------------------------------------------------------------------
/Client/src/app/home/components/home/home.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
{{randomFood?.itemName}}
6 |
7 |
8 |
9 |
{{errorMessage}}
10 |
16 |
17 |
Getting your food suggestions Please wait...
18 |
19 |
Get new suggestion
20 |
Google for recipes
21 |
Bing for recipes
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Client/src/app/home/components/home/home.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | import { AuthenticationService } from './../../../core/services/authentication.service';
4 | import { FoodDataService } from './../../../core/services/food-data.service';
5 | import { FoodItem } from './../../../shared/models/foodItem';
6 |
7 | @Component({
8 | selector: 'home-component',
9 | templateUrl: './home.component.html'
10 | })
11 |
12 | export class HomeComponent implements OnInit {
13 |
14 | randomFood: FoodItem;
15 | errorMessage: string;
16 |
17 | constructor(
18 | private foodDataService: FoodDataService,
19 | public authenticationService: AuthenticationService) { }
20 |
21 | ngOnInit() {
22 | this.getRandomFood();
23 | }
24 |
25 | getRandomFood() {
26 | this.foodDataService
27 | .getRandomFood()
28 | .subscribe((response: FoodItem) => {
29 | this.randomFood = response;
30 | }, (error: any) => {
31 | if (error.status === 400) {
32 | this.errorMessage = 'No food found :-(';
33 | } else {
34 | this.errorMessage = 'There was an error';
35 | }
36 | });
37 | }
38 |
39 | getRecipesWithGoogle(): void {
40 | window.open('https://www.google.de/search?q=' + this.randomFood.itemName, '_blank');
41 | }
42 |
43 | getRecipesWithBing(): void {
44 | window.open('https://www.bing.com/search?q=' + this.randomFood.itemName, '_blank');
45 | }
46 | }
--------------------------------------------------------------------------------
/Client/src/app/home/home.module.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { HttpClientModule } from '@angular/common/http';
3 | import { NgModule } from '@angular/core';
4 | import { FormsModule } from '@angular/forms';
5 |
6 | import { HomeComponent } from './components/home/home.component';
7 | import { HomeRoutes } from './home.routes';
8 |
9 | @NgModule({
10 | imports: [
11 | CommonModule,
12 | HomeRoutes,
13 | HttpClientModule,
14 | FormsModule
15 | ],
16 |
17 | declarations: [
18 | HomeComponent
19 | ],
20 |
21 | providers: [
22 |
23 | ]
24 | })
25 |
26 | export class HomeModule { }
27 |
--------------------------------------------------------------------------------
/Client/src/app/home/home.routes.js:
--------------------------------------------------------------------------------
1 | import { HomeComponent } from './components/home/home.component';
2 | import { RouterModule } from '@angular/router';
3 | var appRoutes = [
4 | { path: 'home', component: HomeComponent }
5 | ];
6 | export var HomeRoutes = RouterModule.forChild(appRoutes);
7 | //# sourceMappingURL=home.routes.js.map
--------------------------------------------------------------------------------
/Client/src/app/home/home.routes.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"home.routes.js","sourceRoot":"","sources":["home.routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAU,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEvD,IAAM,SAAS,GAAW;IACtB,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE;CAC7C,CAAC;AAEF,MAAM,CAAC,IAAM,UAAU,GAAG,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC"}
--------------------------------------------------------------------------------
/Client/src/app/home/home.routes.ts:
--------------------------------------------------------------------------------
1 | import { HomeComponent } from './components/home/home.component';
2 | import { Routes, RouterModule } from '@angular/router';
3 |
4 | const appRoutes: Routes = [
5 | { path: 'home', component: HomeComponent }
6 | ];
7 |
8 | export const HomeRoutes = RouterModule.forChild(appRoutes);
9 |
--------------------------------------------------------------------------------
/Client/src/app/layout/components/header/header.component.html:
--------------------------------------------------------------------------------
1 |
2 |
31 |
32 |
--------------------------------------------------------------------------------
/Client/src/app/layout/components/header/header.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { AuthenticationService } from './../../../core/services/authentication.service';
4 |
5 | @Component({
6 | selector: 'header-component',
7 | templateUrl: './header.component.html'
8 | })
9 |
10 | export class HeaderComponent {
11 |
12 | constructor(public authenticationService: AuthenticationService) { }
13 |
14 | logout() {
15 | this.authenticationService.logoutUser();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Client/src/app/layout/layout.module.ts:
--------------------------------------------------------------------------------
1 | import { RouterModule } from '@angular/router';
2 | import { HeaderComponent } from './components/header/header.component';
3 | import { CommonModule } from '@angular/common';
4 | import { NgModule } from '@angular/core';
5 |
6 | @NgModule({
7 | imports: [
8 | CommonModule,
9 | RouterModule
10 | ],
11 |
12 | declarations: [
13 | HeaderComponent
14 | ],
15 |
16 | providers: [
17 | ],
18 |
19 | exports: [
20 | HeaderComponent
21 | ]
22 | })
23 |
24 | export class LayoutModule { }
25 |
--------------------------------------------------------------------------------
/Client/src/app/main-aot.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["main-aot.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,OAAO,aAAa,CAAC;AACrB,OAAO,UAAU,CAAC;AAElB,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAE1E,cAAc,EAAE,CAAC;AAEjB,eAAe,EAAE,CAAC,sBAAsB,CAAC,kBAAkB,CAAC,CAAC","file":"main-aot.js","sourceRoot":""}
--------------------------------------------------------------------------------
/Client/src/app/main.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"main.js","sourceRoot":"","sources":["main.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AACrB,OAAO,UAAU,CAAC;AAElB,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,sBAAsB,EAAE,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC"}
--------------------------------------------------------------------------------
/Client/src/app/polyfills.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"polyfills.js","sourceRoot":"","sources":["polyfills.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,CAAC;AAEjB,OAAO,oBAAoB,CAAC;AAC5B,OAAO,oBAAoB,CAAC;AAC5B,OAAO,sBAAsB,CAAC;AAC9B,OAAO,uBAAuB,CAAC;AAC/B,OAAO,yBAAyB,CAAC;AACjC,OAAO,oBAAoB,CAAC;AAC5B,OAAO,kBAAkB,CAAC;AAC1B,OAAO,oBAAoB,CAAC;AAC5B,OAAO,kBAAkB,CAAC;AAC1B,OAAO,mBAAmB,CAAC;AAC3B,OAAO,oBAAoB,CAAC;AAC5B,OAAO,iBAAiB,CAAC;AACzB,OAAO,iBAAiB,CAAC;AACzB,OAAO,sBAAsB,CAAC;AAC9B,OAAO,sBAAsB,CAAC;AAC9B,OAAO,mBAAmB,CAAC;AAC3B,OAAO,qBAAqB,CAAC;AAC7B,OAAO,qBAAqB,CAAC;AAE7B,OAAO,mBAAmB,CAAC"}
--------------------------------------------------------------------------------
/Client/src/app/shared/app.constants.js:
--------------------------------------------------------------------------------
1 | export var CONFIGURATION = {
2 | baseUrls: {
3 | server: 'http://localhost:64943/',
4 | apiUrl: 'api/',
5 | foodImageFolder: 'foodimages/'
6 | },
7 | authConfig: {
8 | CLIENT_ID: 'AngularFoodClient',
9 | GRANT_TYPE: 'password',
10 | SCOPE: 'WebAPI'
11 | }
12 | };
13 | //# sourceMappingURL=app.constants.js.map
--------------------------------------------------------------------------------
/Client/src/app/shared/app.constants.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"app.constants.js","sourceRoot":"","sources":["app.constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,IAAI,aAAa,GAAG;IACzB,QAAQ,EAAE;QACR,MAAM,EAAE,yBAAyB;QAEjC,MAAM,EAAE,MAAM;QACd,eAAe,EAAE,aAAa;KAC/B;IACD,UAAU,EAAE;QACV,SAAS,EAAE,mBAAmB;QAC9B,UAAU,EAAE,UAAU;QACtB,KAAK,EAAE,QAAQ;KAChB;CACF,CAAC"}
--------------------------------------------------------------------------------
/Client/src/app/shared/app.constants.ts:
--------------------------------------------------------------------------------
1 | export let CONFIGURATION = {
2 | baseUrls: {
3 | // server: 'http://localhost:64943/',
4 | server: 'http://foodchooser.azurewebsites.net/',
5 | apiUrl: 'api/',
6 | foodImageFolder: 'foodimages/'
7 | },
8 | authConfig: {
9 | CLIENT_ID: 'AngularFoodClient',
10 | GRANT_TYPE: 'password',
11 | SCOPE: 'WebAPI'
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/Client/src/app/shared/decorators/needsAuthentication.ts:
--------------------------------------------------------------------------------
1 | import { StorageService } from './../../core/services/storage.service';
2 | import { CanActivate, Router } from '@angular/router';
3 | import { Injectable } from '@angular/core';
4 |
5 | @Injectable()
6 | export class NeedsAuthentication implements CanActivate {
7 | constructor(private _storeageService: StorageService, private _router: Router) {
8 |
9 | }
10 | canActivate() {
11 | if (this._storeageService.getItem('auth')) {
12 | return true;
13 | }
14 |
15 | this._router.navigate(['/login']);
16 | return false;
17 | }
18 | }
--------------------------------------------------------------------------------
/Client/src/app/shared/models/foodItem.js:
--------------------------------------------------------------------------------
1 | var FoodItem = (function () {
2 | function FoodItem() {
3 | }
4 | return FoodItem;
5 | }());
6 | export { FoodItem };
7 | //# sourceMappingURL=foodItem.js.map
--------------------------------------------------------------------------------
/Client/src/app/shared/models/foodItem.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"foodItem.js","sourceRoot":"","sources":["foodItem.ts"],"names":[],"mappings":"AAEA;IAAA;IAQA,CAAC;IAAD,eAAC;AAAD,CAAC,AARD,IAQC"}
--------------------------------------------------------------------------------
/Client/src/app/shared/models/foodItem.ts:
--------------------------------------------------------------------------------
1 | import { CONFIGURATION } from '../app.constants';
2 |
3 | export class FoodItem {
4 | id: string;
5 | foodListId: string;
6 | itemName: string;
7 | pictureUrl: string;
8 | created: Date;
9 | isPublic: Boolean;
10 | imageString: string;
11 | }
12 |
--------------------------------------------------------------------------------
/Client/src/app/shared/models/foodList.js:
--------------------------------------------------------------------------------
1 | import { CONFIGURATION } from './../app.constants';
2 | var FoodList = (function () {
3 | function FoodList() {
4 | this._imageString = '';
5 | }
6 | Object.defineProperty(FoodList.prototype, "imageString", {
7 | get: function () {
8 | return this._imageString;
9 | },
10 | enumerable: true,
11 | configurable: true
12 | });
13 | FoodList.prototype.setImage = function (imageString) {
14 | if (imageString) {
15 | this._imageString = CONFIGURATION.baseUrls.server + imageString;
16 | }
17 | };
18 | return FoodList;
19 | }());
20 | export { FoodList };
21 | //# sourceMappingURL=foodList.js.map
--------------------------------------------------------------------------------
/Client/src/app/shared/models/foodList.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"foodList.js","sourceRoot":"","sources":["foodList.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD;IAAA;QACY,iBAAY,GAAG,EAAE,CAAC;IAa9B,CAAC;IATG,sBAAI,iCAAW;aAAf;YACI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC;QAC7B,CAAC;;;OAAA;IAED,2BAAQ,GAAR,UAAS,WAAmB;QACxB,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;YACd,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC;QACpE,CAAC;IACL,CAAC;IACL,eAAC;AAAD,CAAC,AAdD,IAcC"}
--------------------------------------------------------------------------------
/Client/src/app/shared/models/foodList.ts:
--------------------------------------------------------------------------------
1 | import { CONFIGURATION } from './../app.constants';
2 | import { FoodItem } from './FoodItem';
3 |
4 | export class FoodList {
5 | private _imageString = '';
6 | id: string;
7 | name: string;
8 | foods: FoodItem[];
9 | get imageString(): string {
10 | return this._imageString;
11 | }
12 |
13 | setImage(imageString: string) {
14 | if (imageString) {
15 | this._imageString = CONFIGURATION.baseUrls.server + imageString;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Client/src/app/shared/models/loginUser.js:
--------------------------------------------------------------------------------
1 | var LoginUser = (function () {
2 | function LoginUser() {
3 | }
4 | return LoginUser;
5 | }());
6 | export { LoginUser };
7 | //# sourceMappingURL=loginUser.js.map
--------------------------------------------------------------------------------
/Client/src/app/shared/models/loginUser.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"loginUser.js","sourceRoot":"","sources":["loginUser.ts"],"names":[],"mappings":"AACA;IAAA;IAGA,CAAC;IAAD,gBAAC;AAAD,CAAC,AAHD,IAGC"}
--------------------------------------------------------------------------------
/Client/src/app/shared/models/loginUser.ts:
--------------------------------------------------------------------------------
1 |
2 | export class LoginUser {
3 | Username: string;
4 | Password: string;
5 | }
--------------------------------------------------------------------------------
/Client/src/app/shared/models/token.js:
--------------------------------------------------------------------------------
1 | var Token = (function () {
2 | function Token() {
3 | }
4 | return Token;
5 | }());
6 | export { Token };
7 | //# sourceMappingURL=token.js.map
--------------------------------------------------------------------------------
/Client/src/app/shared/models/token.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"token.js","sourceRoot":"","sources":["token.ts"],"names":[],"mappings":"AAAA;IAAA;IAIA,CAAC;IAAD,YAAC;AAAD,CAAC,AAJD,IAIC"}
--------------------------------------------------------------------------------
/Client/src/app/shared/models/token.ts:
--------------------------------------------------------------------------------
1 | export class Token {
2 | access_token: string;
3 | token_type: string;
4 | expires_in: number;
5 | }
--------------------------------------------------------------------------------
/Client/src/app/shared/shared.module.ts:
--------------------------------------------------------------------------------
1 | import { NeedsAuthentication } from './decorators/needsAuthentication';
2 | import { CommonModule } from '@angular/common';
3 | import { NgModule } from '@angular/core';
4 |
5 | @NgModule({
6 | imports: [
7 | CommonModule
8 | ],
9 |
10 | declarations: [
11 |
12 | ],
13 |
14 | providers: [
15 | NeedsAuthentication
16 | ]
17 | })
18 |
19 | export class SharedModule { }
20 |
--------------------------------------------------------------------------------
/Client/src/app/vendor.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"vendor.js","sourceRoot":"","sources":["vendor.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAC;AAC3B,OAAO,6BAA6B,CAAC;AACrC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,wCAAwC,CAAC;AAEhD,OAAO,mBAAmB,CAAC;AAE3B,OAAO,iCAAiC,CAAC"}
--------------------------------------------------------------------------------
/Client/src/css/custom.css:
--------------------------------------------------------------------------------
1 | html {
2 | background:url('../../img/background.jpg') no-repeat center center;
3 | min-height:100%;
4 | background-size:cover;
5 | }
6 |
7 | body {
8 | margin-top: 50px; /* Required margin for .navbar-fixed-top. Remove if using .navbar-static-top. Change if height of navigation changes. */
9 | background: transparent;
10 | min-height:100%;
11 | padding-top: 40px;
12 | padding-bottom: 40px;
13 | }
14 |
15 | .centered {
16 | position: absolute;
17 | top: 50%;
18 | left: 50%;
19 | transform: translate(-50%,-50%);
20 | }
21 |
22 | .starter-template {
23 | padding: 40px 15px;
24 | text-align: center;
25 | }
26 |
27 | h1 {
28 | font-family: Arial, Helvetica, sans-serif;
29 | font-size: 250%;
30 | }
31 |
32 | .form-signin {
33 | max-width: 330px;
34 | padding: 15px;
35 | margin: 0 auto;
36 | }
37 | .form-signin .form-signin-heading,
38 | .form-signin .checkbox {
39 | margin-bottom: 10px;
40 | }
41 | .form-signin .checkbox {
42 | font-weight: normal;
43 | }
44 | .form-signin .form-control {
45 | position: relative;
46 | height: auto;
47 | -webkit-box-sizing: border-box;
48 | -moz-box-sizing: border-box;
49 | box-sizing: border-box;
50 | padding: 10px;
51 | font-size: 16px;
52 | }
53 | .form-signin .form-control:focus {
54 | z-index: 2;
55 | }
56 | .form-signin input[type="email"] {
57 | margin-bottom: -1px;
58 | border-bottom-right-radius: 0;
59 | border-bottom-left-radius: 0;
60 | }
61 | .form-signin input[type="password"] {
62 | margin-bottom: 10px;
63 | border-top-left-radius: 0;
64 | border-top-right-radius: 0;
65 | }
66 |
67 | .img-responsive{
68 | max-width: 100%;
69 | height: 200;
70 | display:block ;
71 | }
--------------------------------------------------------------------------------
/Client/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FabianGosebrink/Foodchooser-ASPNET-Angular-Cross-Platform/0462b0f40bae73a754033676458f7374586d48cb/Client/src/favicon.ico
--------------------------------------------------------------------------------
/Client/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | FoodChooser Angular
5 |
6 |
7 |
8 |
9 | Loading...
10 |
11 |
12 |
13 |
14 |
15 |