diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3ff7671 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +node_modules +documentation +package-lock.json +dist \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..857b2a5 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog maintains details about all the releases of the application + + +# [1.0.0-alpha-1](https://github.com/ajaysajwan/FET_FEST/tree/master-parking-solution/1.0.0-alpha-1) (2019-06-15) + +## Initial Alpha Release +--- + +### Feature +* List here +* List here \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..29628d3 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1 @@ +# Team contributing for the development \ No newline at end of file diff --git a/README.md b/README.md index 7e54f0c..d832263 100644 --- a/README.md +++ b/README.md @@ -1,141 +1,2 @@ -# WELCOME TO TECHTONIC FET FEST 2019 - -The TECHTONIC FET fest will begin on **May 27, 2019** and will conclude with a highly competitive hackathon on **June 15, 2019**. - -This event is a XXXXX hosted organization wide event and will be conducted in three locations; **Pune, Gandhinagar and Hyderabad** - -The last date for applying for the hackathon is **June 10, 2019** Registration must be completed through the event website. - -The participation in the event comes with a list of rules and regulations. Read the rules carefully to fully understand the code of conduct during the event. Any non-compliance in the rules will lead to direct disqualification from the event. - -## GENERAL RULES - -* Responsibility of the components and the materials used during the hackathon lies solely on the participating teams. -* Administrator reserves the right in their sole discretion to disqualify any individual it finds tampering with the entry process or the operation of the hackathon. -* Any act of violation of the official rules or anything inappropriate, unsportsmanlike, not in the best interests of this hackathon, or a violation of any applicable law or regulation will be dealt with strict actions. - - -## ENROLLMENT /PARTICIPATION - -* Only 10 teams in each location will be allowed to participate. -* The selection of the team will solely depend on the selection of the topic submitted -* A selection panel will scrutinize the topics sent for participation. Based on the selection criteria, the most distinctive topics will be selected for final participation. You will receive a mail once selected. -* Each team can have a mentor who must be grade 5 or above (4 + 1 team) -* The mentor will guide the team in ideation, planning, and perfecting the pitch -* The TechTonic team will try its best to accommodate employees who register as individuals in multi-member teams. - -**Pune** – Participants will form a team of five members. A team can register with a minimum of 3 members, however, organizers will add two members to make it a 5-member team. The team must have at least 2 FET or Full stack developers. - -**Gandhinagar and Hyderabad** - Employees in Gandhinagar and Hyderabad can form a team of no more than 3 members. The team must have at least 1 FET or Full stack developer. - - -## TECHNOLOGY - -### Team vs Individual technology -* If you register as a team, the following technology rules will apply. -* If you register as an individual, the technologies applicable to the individual will be considered while allocating to an existing team. - -### Technology Rules -The following technology criteria will be considered for participation: - -### Must use at least one of these technology pairings -* Typescript + Angular -* ES6+ ReactJS -* VueJS - - -### Good to use these technology pairings -* HTML5/CSS3 -* SCSS/SASS -* Bootstrap/RWD -* jQuery, JavaScript, OOJS - -### Optional to use these technologies -* NodeJS -* .NET -* JAVA -* PHP -* PERL - -### SDKs, APIs & Data -Applications may integrate third-party SDKs, APIs, and services, provided the maker is authorized to use them. - -## EQUIPMENT - -* The participants must bring their own equipment such as a laptop, data dongle, and any other equipment necessary to prepare and be able to participate in the Hackathon. -* No network connection will be provided inside the premise. -* All the equipment will have to go through security check. - -## CHALLENGE YOURSELF - -### The creation -The team must build a working software application that runs on frontend technology and can be paired with the above-mentioned backend technologies. Do not build on top of old projects. - -### Review/Testing: -* The team must make the application available without any restriction, for testing, evaluation and for use by the judges following the event until the judging period ends. -* The topics for the articles will be reviewed beforehand to avoid any duplication. -* The team must make their application available for testing by Including a link to the application code on GitHub or BitBucket. -* The code repository may be public or private: -* If the repository is private, access must be given in the testing instructions provided with your submission. - - -The code will be used only for application review and testing. Include all deployment files and testing instructions required for testing the application. - -## IP RULES - -### Intellectual Property Rights -All submissions remain the intellectual property of the individuals or team that developed them. - -### Protection of Intellectual Property -By submitting an entry or accepting any prize, you represent and warrant the following: - -you will not submit content that is copyrighted, protected by trade secret or otherwise. subject to third-party intellectual property rights or other proprietary rights, including privacy and publicity rights, unless you are the owner of such rights or have permission from their rightful owner to post the content; and the content submitted by you does not contain any viruses, Trojan horses, worms or other disabling devices or harmful code. - -### Copyright -The participant represents and warrants that they are the sole author and copyright owner of the submission and that the submission is an original work of the participant. - -If the submission is a work based on an existing application, then the participant has acquired sufficient rights to use and authorize others; and that the submission does not infringe upon any copyright or upon any other third-party rights of which the participant is aware. The submission should be free of malware. - -## WINNER SELECTION/JUDGING CRITERIA - -The judges will evaluate all eligible submissions on the following criteria: - -* **Creativity**: Creativity and originality of the idea -* **Technology**: How well FET technologies were leveraged by the developer -* **Impact**: Extent to which the solution can be useful -* **Scalability**: Potential growth of the application - -### Small little tit-bits -* Any disputes arising out of or in relation with the Hackathon shall be settled amicably -* Questions with respect to the Hackathon can be directed to the appropriate location contact: techtonic@XXXXX.com - - -# CODE SETUP - -## Fork this repository - -Team leader need to fork this repository, for more help please visit (**https://help.github.com/en/articles/fork-a-repo**) Rest of the team member can contribute to the forked repository. - -* **Don't commit any code in master repo, it will be not approved. Only commit the code in forked repository** -* **You can create multiple fork repository, and PULL request to common fork repository for review** -* **Only one repository will be considered for code review from the panel, multiple repository/branch will not be considered** - - -## Set up Sonar - -Open **sonar-project.properties** file and update these properties before staring off the project. - -```sonar.projectKey=my: ``` - -Where **** will be team name and theme without space, however you can use ```_```. - -```sonar.projectName= ``` - -Where **** will be short name of your project/theme. - - -### Disclaimer -XXXXX is just a facilitator of such events and will not hold any responsibility or accountability of any incident/accident/mis happening/IP or copyright infringement. - -**The attendance to the event will be at your own discretion.** +# SMART SYSTEM diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..c419263 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-cayman \ No newline at end of file diff --git a/angular.json b/angular.json new file mode 100644 index 0000000..f4f3d2e --- /dev/null +++ b/angular.json @@ -0,0 +1,139 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "kisaan": { + "root": "", + "sourceRoot": "src", + "projectType": "application", + "prefix": "app", + "schematics": { + "@schematics/angular:component": { + "styleext": "scss" + } + }, + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:browser", + "options": { + "outputPath": "dist/kisaan", + "index": "src/index.html", + "main": "src/main.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "src/tsconfig.app.json", + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "src/styles.scss" + ], + "scripts": [] + }, + "configurations": { + "production": { + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "optimization": true, + "outputHashing": "all", + "sourceMap": false, + "extractCss": true, + "namedChunks": false, + "aot": true, + "extractLicenses": true, + "vendorChunk": false, + "buildOptimizer": true, + "budgets": [ + { + "type": "initial", + "maximumWarning": "2mb", + "maximumError": "5mb" + } + ] + } + } + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "options": { + "browserTarget": "kisaan:build" + }, + "configurations": { + "production": { + "browserTarget": "kisaan:build:production" + } + } + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n", + "options": { + "browserTarget": "kisaan:build" + } + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "main": "src/test.ts", + "polyfills": "src/polyfills.ts", + "tsConfig": "src/tsconfig.spec.json", + "karmaConfig": "src/karma.conf.js", + "styles": [ + "src/styles.scss" + ], + "scripts": [], + "assets": [ + "src/favicon.ico", + "src/assets" + ] + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": [ + "src/tsconfig.app.json", + "src/tsconfig.spec.json" + ], + "exclude": [ + "**/node_modules/**" + ] + } + } + } + }, + "kisaan-e2e": { + "root": "e2e/", + "projectType": "application", + "prefix": "", + "architect": { + "e2e": { + "builder": "@angular-devkit/build-angular:protractor", + "options": { + "protractorConfig": "e2e/protractor.conf.js", + "devServerTarget": "kisaan:serve" + }, + "configurations": { + "production": { + "devServerTarget": "kisaan:serve:production" + } + } + }, + "lint": { + "builder": "@angular-devkit/build-angular:tslint", + "options": { + "tsConfig": "e2e/tsconfig.e2e.json", + "exclude": [ + "**/node_modules/**" + ] + } + } + } + } + }, + "defaultProject": "kisaan" +} \ No newline at end of file diff --git a/e2e/protractor.conf.js b/e2e/protractor.conf.js new file mode 100644 index 0000000..86776a3 --- /dev/null +++ b/e2e/protractor.conf.js @@ -0,0 +1,28 @@ +// Protractor configuration file, see link for more information +// https://github.com/angular/protractor/blob/master/lib/config.ts + +const { SpecReporter } = require('jasmine-spec-reporter'); + +exports.config = { + allScriptsTimeout: 11000, + specs: [ + './src/**/*.e2e-spec.ts' + ], + capabilities: { + 'browserName': 'chrome' + }, + directConnect: true, + baseUrl: 'http://localhost:4200/', + framework: 'jasmine', + jasmineNodeOpts: { + showColors: true, + defaultTimeoutInterval: 30000, + print: function() {} + }, + onPrepare() { + require('ts-node').register({ + project: require('path').join(__dirname, './tsconfig.e2e.json') + }); + jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); + } +}; \ No newline at end of file diff --git a/e2e/src/app.e2e-spec.ts b/e2e/src/app.e2e-spec.ts new file mode 100644 index 0000000..7f9a0d9 --- /dev/null +++ b/e2e/src/app.e2e-spec.ts @@ -0,0 +1,14 @@ +import { AppPage } from './app.po'; + +describe('workspace-project App', () => { + let page: AppPage; + + beforeEach(() => { + page = new AppPage(); + }); + + it('should display welcome message', () => { + page.navigateTo(); + expect(page.getTitleText()).toEqual('Welcome to kisaan!'); + }); +}); diff --git a/e2e/src/app.po.ts b/e2e/src/app.po.ts new file mode 100644 index 0000000..72e463a --- /dev/null +++ b/e2e/src/app.po.ts @@ -0,0 +1,11 @@ +import { browser, by, element } from 'protractor'; + +export class AppPage { + navigateTo() { + return browser.get('/'); + } + + getTitleText() { + return element(by.css('app-root h1')).getText(); + } +} diff --git a/e2e/tsconfig.e2e.json b/e2e/tsconfig.e2e.json new file mode 100644 index 0000000..a6dd622 --- /dev/null +++ b/e2e/tsconfig.e2e.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "module": "commonjs", + "target": "es5", + "types": [ + "jasmine", + "jasminewd2", + "node" + ] + } +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..92d2880 --- /dev/null +++ b/package.json @@ -0,0 +1,64 @@ +{ + "name": "SPAS", + "version": "1.0.0-alpha", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "test": "ng test", + "lint": "ng lint", + "e2e": "ng e2e", + "compodoc": "./node_modules/.bin/compodoc -p tsconfig.json" + }, + "private": true, + "engines": { + "node": "10.16.0", + "npm": "6.9.0" + }, + "dependencies": { + "@angular/animations": "7.2.0", + "@angular/common": "7.2.0", + "@angular/compiler": "7.2.0", + "@angular/core": "7.2.0", + "@angular/fire": "^5.2.1", + "@angular/forms": "7.2.0", + "@angular/platform-browser": "7.2.0", + "@angular/platform-browser-dynamic": "7.2.0", + "@angular/router": "7.2.0", + "@firebase/auth": "^0.11.3", + "@firebase/auth-types": "^0.7.0", + "@firebase/firestore": "^1.3.5", + "@ng-bootstrap/ng-bootstrap": "4.0.0", + "@ngx-translate/core": "11.0.1", + "@ngx-translate/http-loader": "4.0.0", + "angularfire2": "^5.2.1", + "bootstrap": "4.0.0", + "core-js": "2.5.4", + "firebase": "^6.1.1", + "rxjs": "6.3.3", + "tslib": "1.9.0", + "zone.js": "0.8.26" + }, + "devDependencies": { + "@angular-devkit/build-angular": "0.12.0", + "@angular/cli": "7.2.0", + "@angular/compiler-cli": "7.2.0", + "@angular/language-service": "7.2.0", + "@types/node": "8.9.4", + "@types/jasmine": "2.8.8", + "@types/jasminewd2": "2.0.3", + "codelyzer": "4.5.0", + "jasmine-core": "2.99.1", + "jasmine-spec-reporter": "4.2.1", + "karma": "3.1.1", + "karma-chrome-launcher": "2.2.0", + "karma-coverage-istanbul-reporter": "2.0.1", + "karma-jasmine": "1.1.2", + "karma-jasmine-html-reporter": "0.2.2", + "protractor": "5.4.0", + "ts-node": "7.0.0", + "tslint": "5.11.0", + "typescript": "3.2.2", + "@compodoc/compodoc": "1.0.5" + } +} diff --git a/sonar-project.properties b/sonar-project.properties index 8b37ef1..dba2c8d 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,8 +1,8 @@ # must be unique in a given SonarQube instance -sonar.projectKey=my: +sonar.projectKey=my: # this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1. -sonar.projectName= +sonar.projectName= sonar.projectVersion=1.0 # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. diff --git a/src/app/app.component.html b/src/app/app.component.html new file mode 100644 index 0000000..9af5c1a --- /dev/null +++ b/src/app/app.component.html @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/app/app.component.scss b/src/app/app.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts new file mode 100644 index 0000000..cffbecc --- /dev/null +++ b/src/app/app.component.spec.ts @@ -0,0 +1,35 @@ +import { TestBed, async } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { AppComponent } from './app.component'; + +describe('AppComponent', () => { + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ + RouterTestingModule + ], + declarations: [ + AppComponent + ], + }).compileComponents(); + })); + + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app).toBeTruthy(); + }); + + it(`should have as title 'kisaan'`, () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.debugElement.componentInstance; + expect(app.title).toEqual('kisaan'); + }); + + it('should render title in a h1 tag', () => { + const fixture = TestBed.createComponent(AppComponent); + fixture.detectChanges(); + const compiled = fixture.debugElement.nativeElement; + expect(compiled.querySelector('h1').textContent).toContain('Welcome to kisaan!'); + }); +}); diff --git a/src/app/app.component.ts b/src/app/app.component.ts new file mode 100644 index 0000000..1601e9e --- /dev/null +++ b/src/app/app.component.ts @@ -0,0 +1,14 @@ +import { Component } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; + +@Component({ + selector: 'app-root', + templateUrl: './app.component.html', + styleUrls: ['./app.component.scss'] +}) +export class AppComponent { + constructor(private translateService: TranslateService) { + this.translateService.setDefaultLang('en-US'); + this.translateService.use('en-US'); + } +} diff --git a/src/app/app.module.ts b/src/app/app.module.ts new file mode 100644 index 0000000..5d0d4ff --- /dev/null +++ b/src/app/app.module.ts @@ -0,0 +1,43 @@ +import { BrowserModule } from '@angular/platform-browser'; +import { NgModule } from '@angular/core'; +import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { TranslateHttpLoader } from '@ngx-translate/http-loader'; +import { HttpClient, HttpClientModule } from '@angular/common/http'; + +import { environment } from '../environments/environment'; +import { AngularFireModule } from '@angular/fire'; +import { AngularFirestoreModule, AngularFirestore } from '@angular/fire/firestore'; +import { AngularFireStorageModule } from '@angular/fire/storage'; +import { AngularFireAuthModule } from '@angular/fire/auth'; + +import { AppComponent } from './app.component'; +import { routing } from 'src/app/app.routing'; + +export function createTranslateLoader(http: HttpClient) { + return new TranslateHttpLoader(http, './assets/i18n/', '.json'); +} + +@NgModule({ + declarations: [ + AppComponent, + ], + imports: [ + BrowserModule, + HttpClientModule, + routing, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: (createTranslateLoader), + deps: [HttpClient] + } + }), + AngularFireModule.initializeApp(environment.firebase, 'SPAS'), + AngularFirestoreModule, // imports firebase/firestore, only needed for database features + AngularFireAuthModule, // imports firebase/auth, only needed for auth features, + AngularFireStorageModule // imports firebase/storage only needed for storage features + ], + providers: [], + bootstrap: [AppComponent] +}) +export class AppModule { } diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts new file mode 100644 index 0000000..437f36c --- /dev/null +++ b/src/app/app.routing.ts @@ -0,0 +1,10 @@ +import { Routes, RouterModule } from '@angular/router'; +import { ModuleWithProviders } from '@angular/compiler/src/core'; + +const routes: Routes = [ + { path: '', redirectTo: 'spas', pathMatch: 'full' }, + { path: 'spas', loadChildren: '../modules/parking-module/spas.module#SpasModule' } +]; + +export const routing: ModuleWithProviders = RouterModule.forRoot(routes); + diff --git a/src/assets/.gitkeep b/src/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/assets/i18n/en-US.json b/src/assets/i18n/en-US.json new file mode 100644 index 0000000..3a6dad5 --- /dev/null +++ b/src/assets/i18n/en-US.json @@ -0,0 +1,3 @@ +{ + "label_name": "Smart Parking Assist System" +} \ No newline at end of file diff --git a/src/assets/i18n/hi-IN.json b/src/assets/i18n/hi-IN.json new file mode 100644 index 0000000..edb4f2b --- /dev/null +++ b/src/assets/i18n/hi-IN.json @@ -0,0 +1,4 @@ +{ + "label_name": "स्मार्ट पार्किंग असिस्ट सिस्टम" +} + diff --git a/src/assets/img/bg-1.png b/src/assets/img/bg-1.png new file mode 100644 index 0000000..0c05233 Binary files /dev/null and b/src/assets/img/bg-1.png differ diff --git a/src/assets/img/bg.png b/src/assets/img/bg.png new file mode 100644 index 0000000..bf8ac2f Binary files /dev/null and b/src/assets/img/bg.png differ diff --git a/src/assets/img/car.jpg b/src/assets/img/car.jpg new file mode 100644 index 0000000..7ff7ee1 Binary files /dev/null and b/src/assets/img/car.jpg differ diff --git a/src/assets/img/carred.png b/src/assets/img/carred.png new file mode 100644 index 0000000..4a0591b Binary files /dev/null and b/src/assets/img/carred.png differ diff --git a/src/assets/img/circled-left-arrow.png b/src/assets/img/circled-left-arrow.png new file mode 100644 index 0000000..f0b79d7 Binary files /dev/null and b/src/assets/img/circled-left-arrow.png differ diff --git a/src/assets/img/hourglass-sand-bottom.png b/src/assets/img/hourglass-sand-bottom.png new file mode 100644 index 0000000..da49c4f Binary files /dev/null and b/src/assets/img/hourglass-sand-bottom.png differ diff --git a/src/assets/img/imgpsh_fullsize_anim (1) - Copy.png b/src/assets/img/imgpsh_fullsize_anim (1) - Copy.png new file mode 100644 index 0000000..b0c1bcc Binary files /dev/null and b/src/assets/img/imgpsh_fullsize_anim (1) - Copy.png differ diff --git a/src/assets/img/imgpsh_fullsize_anim (1).png b/src/assets/img/imgpsh_fullsize_anim (1).png new file mode 100644 index 0000000..c3a758b Binary files /dev/null and b/src/assets/img/imgpsh_fullsize_anim (1).png differ diff --git a/src/assets/img/imgpsh_fullsize_anim.jpg b/src/assets/img/imgpsh_fullsize_anim.jpg new file mode 100644 index 0000000..b0defcf Binary files /dev/null and b/src/assets/img/imgpsh_fullsize_anim.jpg differ diff --git a/src/assets/img/marker.png b/src/assets/img/marker.png new file mode 100644 index 0000000..a81c54d Binary files /dev/null and b/src/assets/img/marker.png differ diff --git a/src/assets/img/time-machine.png b/src/assets/img/time-machine.png new file mode 100644 index 0000000..ca6ade0 Binary files /dev/null and b/src/assets/img/time-machine.png differ diff --git a/src/assets/scss/_variable.scss b/src/assets/scss/_variable.scss new file mode 100644 index 0000000..258f18c --- /dev/null +++ b/src/assets/scss/_variable.scss @@ -0,0 +1,10 @@ +$light-green: #baf055; +$blue: #0088ff; +$blue-0: rgb(152, 214, 245); +$grey: #e6ecec; +$dark-green: #00d800; +$green: #0ad90c; +$yellow: #ffba00; +$white: #ffffff; +$black: #000000; +$red: #ff0b0b; diff --git a/src/browserslist b/src/browserslist new file mode 100644 index 0000000..37371cb --- /dev/null +++ b/src/browserslist @@ -0,0 +1,11 @@ +# This file is currently used by autoprefixer to adjust CSS to support the below specified browsers +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries +# +# For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed + +> 0.5% +last 2 versions +Firefox ESR +not dead +not IE 9-11 \ No newline at end of file diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts new file mode 100644 index 0000000..3612073 --- /dev/null +++ b/src/environments/environment.prod.ts @@ -0,0 +1,3 @@ +export const environment = { + production: true +}; diff --git a/src/environments/environment.ts b/src/environments/environment.ts new file mode 100644 index 0000000..2eed6f0 --- /dev/null +++ b/src/environments/environment.ts @@ -0,0 +1,25 @@ +// This file can be replaced during build by using the `fileReplacements` array. +// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. +// The list of file replacements can be found in `angular.json`. + +export const environment = { + production: false, + firebase: { + apiKey: 'AIzaSyCt587x8YjEAbc0c0WPSdhrFMwfzGJtDXU', + authDomain: 'spas-a7b7a.firebaseapp.com', + databaseURL: 'https://spas-a7b7a.firebaseio.com', + projectId: 'spas-a7b7a', + storageBucket: 'spas-a7b7a.appspot.com', + messagingSenderId: '85818314017', + appId: '1:85818314017:web:3e7c99047fad2866' + } +}; + +/* + * For easier debugging in development mode, you can import the following file + * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. + * + * This import should be commented out in production mode because it will have a negative impact + * on performance if an error is thrown. + */ +// import 'zone.js/dist/zone-error'; // Included with Angular CLI. diff --git a/src/favicon.ico b/src/favicon.ico new file mode 100644 index 0000000..382a6d1 Binary files /dev/null and b/src/favicon.ico differ diff --git a/src/index.html b/src/index.html new file mode 100644 index 0000000..1eb5270 --- /dev/null +++ b/src/index.html @@ -0,0 +1,14 @@ + + + + + Smart Parking Assistant + + + + + + + + + diff --git a/src/karma.conf.js b/src/karma.conf.js new file mode 100644 index 0000000..ee9caa1 --- /dev/null +++ b/src/karma.conf.js @@ -0,0 +1,31 @@ +// Karma configuration file, see link for more information +// https://karma-runner.github.io/1.0/config/configuration-file.html + +module.exports = function (config) { + config.set({ + basePath: '', + frameworks: ['jasmine', '@angular-devkit/build-angular'], + plugins: [ + require('karma-jasmine'), + require('karma-chrome-launcher'), + require('karma-jasmine-html-reporter'), + require('karma-coverage-istanbul-reporter'), + require('@angular-devkit/build-angular/plugins/karma') + ], + client: { + clearContext: false // leave Jasmine Spec Runner output visible in browser + }, + coverageIstanbulReporter: { + dir: require('path').join(__dirname, '../coverage'), + reports: ['html', 'lcovonly', 'text-summary'], + fixWebpackSourcePaths: true + }, + reporters: ['progress', 'kjhtml'], + port: 9876, + colors: true, + logLevel: config.LOG_INFO, + autoWatch: true, + browsers: ['Chrome'], + singleRun: false + }); +}; \ No newline at end of file diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..c7b673c --- /dev/null +++ b/src/main.ts @@ -0,0 +1,12 @@ +import { enableProdMode } from '@angular/core'; +import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; + +import { AppModule } from './app/app.module'; +import { environment } from './environments/environment'; + +if (environment.production) { + enableProdMode(); +} + +platformBrowserDynamic().bootstrapModule(AppModule) + .catch(err => console.error(err)); diff --git a/src/modules/parking-module/components/location-list/location-list.component.html b/src/modules/parking-module/components/location-list/location-list.component.html new file mode 100644 index 0000000..3d1ddab --- /dev/null +++ b/src/modules/parking-module/components/location-list/location-list.component.html @@ -0,0 +1,19 @@ +
+
+
+ +
Available Locations
+
+
+
+
+
+ + + + +
+
+
\ No newline at end of file diff --git a/src/modules/parking-module/components/location-list/location-list.component.scss b/src/modules/parking-module/components/location-list/location-list.component.scss new file mode 100644 index 0000000..b613052 --- /dev/null +++ b/src/modules/parking-module/components/location-list/location-list.component.scss @@ -0,0 +1,43 @@ +@import "../../../../assets/scss/variable.scss"; +.available-locations-container { + background-color: #ffc306; + height: 100vh; + .available-locations-header { + height: 50px; + padding-top: 10px; + img { + height: 50px; + width: 50px; + } + h5 { + color: #3f51b5; + display: inline-block; + vertical-align: -webkit-baseline-middle; + } + } + .available-locations-body { + .btn-grp { + font-size: 24px; + button { + height: 100px; + width: 100px; + flex: 0 0 44%; + max-width: 44%; + margin: 3%; + background: rgba(255, 255, 255, 0.7); + } + } + + .select-location-btn { + background-color: #3f51b5; + color: #fff; + font-weight: 500; + position: absolute; + margin: 0 auto; + right: 0; + left: 0; + width: fit-content; + margin-bottom: 30px; + } + } +} diff --git a/src/modules/parking-module/components/location-list/location-list.component.spec.ts b/src/modules/parking-module/components/location-list/location-list.component.spec.ts new file mode 100644 index 0000000..1457d93 --- /dev/null +++ b/src/modules/parking-module/components/location-list/location-list.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LocationListComponent } from './location-list.component'; + +describe('LocationListComponent', () => { + let component: LocationListComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ LocationListComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LocationListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/modules/parking-module/components/location-list/location-list.component.ts b/src/modules/parking-module/components/location-list/location-list.component.ts new file mode 100644 index 0000000..c58d43f --- /dev/null +++ b/src/modules/parking-module/components/location-list/location-list.component.ts @@ -0,0 +1,21 @@ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'app-location-list', + templateUrl: './location-list.component.html', + styleUrls: ['./location-list.component.scss'] +}) +export class LocationListComponent implements OnInit { + + constructor(private router: Router) { } + locationList = [{name:'Parking 1'},{name:'Parking 3'},{name:'Parking 4'}] + ngOnInit() { + } + + viewLocationSlots(location){ + console.log(location); + this.router.navigate(['spas/user/location-slots']); + } + +} diff --git a/src/modules/parking-module/components/location-slots/location-slots.component.html b/src/modules/parking-module/components/location-slots/location-slots.component.html new file mode 100644 index 0000000..94bb739 --- /dev/null +++ b/src/modules/parking-module/components/location-slots/location-slots.component.html @@ -0,0 +1,94 @@ +
+
+
+ +
Select Parking Slot
+
+ +
+
 
+

Parked

+
+
+
 
+

Available

+
+
+
 
+

Selected

+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ +
+
\ No newline at end of file diff --git a/src/modules/parking-module/components/location-slots/location-slots.component.scss b/src/modules/parking-module/components/location-slots/location-slots.component.scss new file mode 100644 index 0000000..bf88149 --- /dev/null +++ b/src/modules/parking-module/components/location-slots/location-slots.component.scss @@ -0,0 +1,99 @@ +@import "../../../../assets/scss/variable.scss"; +.select-slot-container { + background-color: $white; + height: 100vh; + .select-slot-header { + height: 90px; + padding-top: 10px; + margin-bottom: 15px !important; + .page-title { + width: 100%; + margin-bottom: 10px; + } + + img { + height: 50px; + width: 50px; + } + h5 { + color: #3f51b5; + display: inline-block; + vertical-align: -webkit-baseline-middle; + } + + .circle-blue { + border-radius: 15px; + height: 15px; + width: 15px; + background: $blue-0; + display: inline-block; + } + .circle-red { + border-radius: 15px; + height: 15px; + width: 15px; + background: $red; + display: inline-block; + } + .circle-green { + border-radius: 15px; + height: 15px; + width: 15px; + background: $green; + display: inline-block; + } + p { + display: inline-block; + vertical-align: middle; + padding-left: 10px; + } + } + .select-slot-body { + .parking-block { + background: dimgray; + padding: 30px; + .slot { + background: $blue-0; + filter: alpha(opacity=50); + border: 1px dashed rgba(86, 61, 124, 0.2); + min-height: 50px; + transform: skew(0deg); + padding: 0; + div { + background: $blue-0; + min-height: 50px; + width: 100%; + border: 2px dashed white; + border-left: 0; + border-right: 0; + border-top: 0; + box-sizing: border-box; + &:first-child { + border-top:2px dashed white; + } + } + } + .parked { + background: $red !important; + // background: url("../../../../assets/img/imgpsh_fullsize_anim (1).png") 50% 50% no-repeat; + } + .available { + background: $blue-0 !important; + } + .selected { + background: $green !important; + } + } + .select-location-btn { + background-color: rgba(215, 40, 40, 0.7); + color: #fff; + font-weight: 500; + position: absolute; + margin: 30px auto; + right: 0; + left: 0; + width: fit-content; + margin-bottom: 30px; + } + } + } \ No newline at end of file diff --git a/src/modules/parking-module/components/location-slots/location-slots.component.spec.ts b/src/modules/parking-module/components/location-slots/location-slots.component.spec.ts new file mode 100644 index 0000000..dee412e --- /dev/null +++ b/src/modules/parking-module/components/location-slots/location-slots.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LocationSlotsComponent } from './location-slots.component'; + +describe('LocationSlotsComponent', () => { + let component: LocationSlotsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ LocationSlotsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LocationSlotsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/modules/parking-module/components/location-slots/location-slots.component.ts b/src/modules/parking-module/components/location-slots/location-slots.component.ts new file mode 100644 index 0000000..db5ddcf --- /dev/null +++ b/src/modules/parking-module/components/location-slots/location-slots.component.ts @@ -0,0 +1,20 @@ +import { Component, OnInit } from '@angular/core'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'app-location-slots', + templateUrl: './location-slots.component.html', + styleUrls: ['./location-slots.component.scss'] +}) +export class LocationSlotsComponent implements OnInit { + + constructor(private router: Router) { } + + ngOnInit() { + } + + onSlotConfirmation() { + this.router.navigate(['spas/slotConfirmation']); + } + +} diff --git a/src/modules/parking-module/components/search-location/search-location.component.html b/src/modules/parking-module/components/search-location/search-location.component.html new file mode 100644 index 0000000..191397f --- /dev/null +++ b/src/modules/parking-module/components/search-location/search-location.component.html @@ -0,0 +1,30 @@ +
+
+ +
+ +
Enter Location
+
+
+
+ +
diff --git a/src/modules/parking-module/components/search-location/search-location.component.scss b/src/modules/parking-module/components/search-location/search-location.component.scss new file mode 100644 index 0000000..dd72300 --- /dev/null +++ b/src/modules/parking-module/components/search-location/search-location.component.scss @@ -0,0 +1,84 @@ +@import "../../../../assets/scss/variable.scss"; + +.where-to-container { + background-color: #ffc306; + height: 100vh; + .where-to-header { + height: 50px; + padding-top: 10px; + .my-bookings-btn { + background-color: rgba(215, 40, 40, 0.7); + background: rgba(215, 40, 40, 0.7); + color: #fff; + font-weight: 500; + position: absolute; + right: 15px; + } + img { + height: 50px; + width: 50px; + } + h5 { + color: #3f51b5; + display: inline-block; + vertical-align: -webkit-baseline-middle; + } + } + .where-to-body { + label { + position: relative; + width: 100%; + } + + label.location:before { + content: ""; + position: absolute; + left: 10px; + top: 24px; + bottom: 0; + width: 20px; + background: url("../../../../assets/img/marker.png") 50% 50% no-repeat; + } + label.start-time:before { + content: ""; + position: absolute; + left: 10px; + top: 24px; + bottom: 0; + width: 30px; + background: url("../../../../assets/img/time-machine.png") 50% 50% no-repeat; + } + + label.duration:before { + content: ""; + position: absolute; + left: 10px; + top: 24px; + bottom: 0; + width: 30px; + background: url("../../../../assets/img/hourglass-sand-bottom.png") 50% 50% no-repeat; + } + + input { + padding: 10px 40px; + } + + .my-bookings-btn { + background-color: #3F51B5; + color: #fff; + font-weight: 500; + position: absolute; + margin: 0 auto; + right:0; + left: 0; + width: fit-content; + margin-bottom: 30px; + } + } + } + + .form-control { + &.has-error { + border: 1px solid red; + } + } \ No newline at end of file diff --git a/src/modules/parking-module/components/search-location/search-location.component.spec.ts b/src/modules/parking-module/components/search-location/search-location.component.spec.ts new file mode 100644 index 0000000..9c2bdd3 --- /dev/null +++ b/src/modules/parking-module/components/search-location/search-location.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SearchLocationComponent } from './search-location.component'; + +describe('SearchLocationComponent', () => { + let component: SearchLocationComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SearchLocationComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SearchLocationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/modules/parking-module/components/search-location/search-location.component.ts b/src/modules/parking-module/components/search-location/search-location.component.ts new file mode 100644 index 0000000..2ef08a3 --- /dev/null +++ b/src/modules/parking-module/components/search-location/search-location.component.ts @@ -0,0 +1,38 @@ +import { Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'app-search-location', + templateUrl: './search-location.component.html', + styleUrls: ['./search-location.component.scss'] +}) +export class SearchLocationComponent implements OnInit { + + searchForm: FormGroup; + + isSubmitted = false; + + constructor( private formBuilder: FormBuilder, private router: Router ) { } + + ngOnInit() { + this.searchForm = this.formBuilder.group({ + location: ['', Validators.required], + time: ['', Validators.required], + endTime: ['', Validators.required] + }); + } + + get formControls() { return this.searchForm.controls; } + + searchLocation() { + this.isSubmitted = true; + console.log(this.searchForm.value); + if(this.searchForm.invalid){ + return; + } + //this.parkingService.searchLocation(this.searchForm.value); + this.router.navigate(['spas/user/location-list']); + } + +} diff --git a/src/modules/parking-module/components/spas-booking-summary/spas-booking-summary.component.html b/src/modules/parking-module/components/spas-booking-summary/spas-booking-summary.component.html new file mode 100644 index 0000000..fc88f4a --- /dev/null +++ b/src/modules/parking-module/components/spas-booking-summary/spas-booking-summary.component.html @@ -0,0 +1,53 @@ +
+
+
+ +
Parking Receipt
+
+
+
+
+
+
+

Parking Details

+
+ + {{bookingSummary.username}} +
+
+ + {{bookingSummary.vehicleNo}} +
+
+
+ + {{bookingSummary.slotNumber}} +
+ + {{bookingSummary.startTime}} +
+
+ + {{bookingSummary.endTime}} +
+
+ + {{bookingSummary.status}} +
+
+ + + +
+
+

No Pending Dues

+
Thanks.. Visit Again
+
+
+
+ +
+ +
+
\ No newline at end of file diff --git a/src/modules/parking-module/components/spas-booking-summary/spas-booking-summary.component.scss b/src/modules/parking-module/components/spas-booking-summary/spas-booking-summary.component.scss new file mode 100644 index 0000000..a9303bb --- /dev/null +++ b/src/modules/parking-module/components/spas-booking-summary/spas-booking-summary.component.scss @@ -0,0 +1,49 @@ +@import "../../../../assets/scss/variable.scss"; +.receipt-container { + background-color: #ffc306; + height: 100vh; + .receipt-header { + height: 50px; + padding-top: 10px; + img { + height: 50px; + width: 50px; + } + h5 { + color: #3f51b5; + display: inline-block; + vertical-align: -webkit-baseline-middle; + } + } + .receipt-body { + hr { + border: 1px dotted white; + } + + .proceed-btn { + background-color: #3f51b5; + color: #fff; + font-weight: 500; + position: absolute; + margin: 30px auto; + right: 0; + left: 0; + width: fit-content; + margin-bottom: 30px; + } + .checkout-btn { + background-color: $light-green; + color: #fff; + font-weight: 500; + margin: 0px 0 30px 0; + width: fit-content; + margin-bottom: 30px; + } + } + label { + font-weight: 500; + } + span { + padding: 10px; + } +} diff --git a/src/modules/parking-module/components/spas-booking-summary/spas-booking-summary.component.spec.ts b/src/modules/parking-module/components/spas-booking-summary/spas-booking-summary.component.spec.ts new file mode 100644 index 0000000..b5f55f9 --- /dev/null +++ b/src/modules/parking-module/components/spas-booking-summary/spas-booking-summary.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SpasBookingSummaryComponent } from './spas-booking-summary.component'; + +describe('SpasBookingSummaryComponent', () => { + let component: SpasBookingSummaryComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SpasBookingSummaryComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SpasBookingSummaryComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/modules/parking-module/components/spas-booking-summary/spas-booking-summary.component.ts b/src/modules/parking-module/components/spas-booking-summary/spas-booking-summary.component.ts new file mode 100644 index 0000000..aff6b69 --- /dev/null +++ b/src/modules/parking-module/components/spas-booking-summary/spas-booking-summary.component.ts @@ -0,0 +1,27 @@ +import { Component, OnInit } from '@angular/core'; +import { SpasDataService } from 'src/modules/parking-module/services/spas-data.service'; + +@Component({ + selector: 'spas-booking-summary', + templateUrl: './spas-booking-summary.component.html', + styleUrls: ['./spas-booking-summary.component.scss'] +}) +export class SpasBookingSummaryComponent implements OnInit { + + bookingSummary: any; + checkoutFlag = false; + + constructor(private spasDataService: SpasDataService) { + this.bookingSummary = spasDataService.getBookingData(); + this.bookingSummary.status = 'Booked'; + } + + ngOnInit() { + + } + + confirmCheckout() { + this.checkoutFlag = true; + } + +} diff --git a/src/modules/parking-module/components/spas-booking/spas-booking.component.html b/src/modules/parking-module/components/spas-booking/spas-booking.component.html new file mode 100644 index 0000000..02602ca --- /dev/null +++ b/src/modules/parking-module/components/spas-booking/spas-booking.component.html @@ -0,0 +1,58 @@ +
+
+
+ +
Check In Details
+
+
+
+
+
+
+

User Details

+
+ + +
+
+ + +
+
+ + +
+
+
+
+
+
+

Parking Details

+
+ + {{bookingData.parkingName}} +
+
+ + {{bookingData.startTime}} +
+
+ + {{bookingData.endTime}} +
+
+ + {{bookingData.slotNumber}} +
+
+ Rs. 80 + +
+
+
+ +
+
\ No newline at end of file diff --git a/src/modules/parking-module/components/spas-booking/spas-booking.component.scss b/src/modules/parking-module/components/spas-booking/spas-booking.component.scss new file mode 100644 index 0000000..494f7f3 --- /dev/null +++ b/src/modules/parking-module/components/spas-booking/spas-booking.component.scss @@ -0,0 +1,41 @@ +@import "../../../../assets/scss/variable.scss"; +.checkin-container { + background-color: #ffc306; + height: 100vh; + .checkin-header { + height: 50px; + padding-top: 10px; + img { + height: 50px; + width: 50px; + } + h5 { + color: #3f51b5; + display: inline-block; + vertical-align: -webkit-baseline-middle; + } + } + .checkin-body { + hr { + border: 1px dotted white; + } + + .proceed-btn { + background-color: #3f51b5; + color: #fff; + font-weight: 500; + position: absolute; + margin: 30px auto; + right: 0; + left: 0; + width: fit-content; + margin-bottom: 30px; + } + } + label { + font-weight: 500; + } + span { + padding: 10px; + } +} diff --git a/src/modules/parking-module/components/spas-booking/spas-booking.component.spec.ts b/src/modules/parking-module/components/spas-booking/spas-booking.component.spec.ts new file mode 100644 index 0000000..ec7c7d9 --- /dev/null +++ b/src/modules/parking-module/components/spas-booking/spas-booking.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SpasBookingComponent } from './spas-booking.component'; + +describe('SpasBookingComponent', () => { + let component: SpasBookingComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SpasBookingComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SpasBookingComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/modules/parking-module/components/spas-booking/spas-booking.component.ts b/src/modules/parking-module/components/spas-booking/spas-booking.component.ts new file mode 100644 index 0000000..cba3945 --- /dev/null +++ b/src/modules/parking-module/components/spas-booking/spas-booking.component.ts @@ -0,0 +1,59 @@ +import { Component, OnInit } from '@angular/core'; +import { SpasDataService } from 'src/modules/parking-module/services/spas-data.service'; +import { Router } from '@angular/router'; +import { BookingData } from 'src/modules/parking-module/models/spas-booking-data'; + +@Component({ + selector: 'spas-booking', + templateUrl: './spas-booking.component.html', + styleUrls: ['./spas-booking.component.scss'] +}) +export class SpasBookingComponent implements OnInit { + + bookingData: BookingData; + + constructor( + private spasDataService: SpasDataService, + private router: Router + ) { + + // should be input - user selection + this.bookingData = new BookingData({ + area: 'kalyani nagar', + parkingName: 'dmart parking 1', + parkingId: '1', + startTime: '10.00', + endTime: '12.00', + row: '2', + column: '2' + }); + } + + ngOnInit() { + } + + /** + * Saves user booking details and accepts payment and books slot for user + * API call for booking data + */ + payNProceed() { + console.log(this.bookingData); + // fire Update request. + const updateBookingDetails = { + parkingId: this.bookingData.parkingId, + userId: this.bookingData.userId, + row: this.bookingData.row, + column: this.bookingData.column, + startTime: this.bookingData.startTime, + endTime: this.bookingData.endTime, + userContact: this.bookingData.userContact, + status: this.bookingData.status, + paymentStatus: this.bookingData.paymentStatus, + amount: this.bookingData.amount, + vehicleNo: this.bookingData.vehicleNo + } + this.spasDataService.storeCurrentBookingData(this.bookingData); + + this.router.navigate(['spas/bookingConfirmation']); + } +} diff --git a/src/modules/parking-module/models/spas-booking-data.ts b/src/modules/parking-module/models/spas-booking-data.ts new file mode 100644 index 0000000..16a7c18 --- /dev/null +++ b/src/modules/parking-module/models/spas-booking-data.ts @@ -0,0 +1,62 @@ +/** + * Holds user booking details + */ +export class BookingData { + area?: string; + parkingId?: string; + parkingName?: string; + username?: string; + userId?: string; + userContact?: string; + vehicleNo?: string; + startTime?: string; + endTime?: string; + row?: string; + column?: string; + amount?: string; + paymentStatus?: string; + status?: string; + slotNumber?: string; + + constructor(data?: any) { + this.area = data.area ? data.area : ''; + this.parkingName = data.parkingName ? data.parkingName : ''; + this.username = data.username ? data.username : ''; + this.userContact = data.userContact ? data.userContact : undefined; + this.vehicleNo = data.vehicleNo ? data.vehicleNo : ''; + this.startTime = data.startTime ? data.startTime : ''; + this.endTime = data.endTime ? data.endTime : ''; + this.row = data.row ? data.row : undefined; + this.column = data.column ? data.column : undefined; + this.slotNumber = data.row && data.column ? alphabets[data.row] + '-' + data.column : undefined; + this.amount = data.amount ? data.amount : undefined; + this.status = data.status ? data.status : undefined; + this.paymentStatus = data.paymentStatus ? data.paymentStatus : undefined; + this.userId = data.userId ? data.userId : undefined; + this.parkingId = data.parkingId ? data.parkingId : undefined; + + } +} + +/** + * Booking to be sent to API + */ +export interface BookingDetails { + parkingId: string; + userId: string; + row: string; + column: string; + startTime: string; + endTime: string; + userContact: string; + status: string; + paymentStatus: string; + amount: string; + vehicleNo: string; +} + +/** + * Holds Alphabets to have numbering for slots. + */ +export const alphabets = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; diff --git a/src/modules/parking-module/services/parking.service.ts b/src/modules/parking-module/services/parking.service.ts new file mode 100644 index 0000000..aad8777 --- /dev/null +++ b/src/modules/parking-module/services/parking.service.ts @@ -0,0 +1,158 @@ +import { Injectable } from '@angular/core'; +import { AngularFirestore } from '@angular/fire/firestore'; +import { BookingDetails } from 'src/modules/parking-module/models/spas-booking-data'; + +@Injectable({ + providedIn: 'root' +}) +export class ParkingService { + parkings: any; + bookings: any; + users: any; + constructor(private fireStore: AngularFirestore) { + this.parkings = this.fireStore.collection('parkings').get(); + this.bookings = this.fireStore.collection('bookings').get(); + this.users = this.fireStore.collection('users').get(); + } + + /** + * Gets a collection of parking locations from database + */ + getParkingLocations() { + return this.parkings; + } + + /** + * Gets a collection of bookngs from database + */ + getBookings() { + return this.bookings; + } + + /** + * Gets a collection of users from database + */ + getUsers() { + return this.users; + } + + /** + * Books a parking slot + * @param bookingDetail + */ + bookParkingSlot(bookingDetail: BookingDetails) { + const slotDetail = { + parkingId: bookingDetail.parkingId, + userId: bookingDetail.userId, + contact: bookingDetail.userContact, + row: bookingDetail.row, + column: bookingDetail.column, + startTime: bookingDetail.startTime, + endTime: bookingDetail.endTime, + status: 'B', + paymentStatus: 'P', + amount: bookingDetail.amount, + vehicleNo: bookingDetail.vehicleNo + }; + this.bookings + .doc(`${bookingDetail.parkingId}${slotDetail.row}${slotDetail.column}`) + .set(slotDetail) + .then(() => { + this.parkings + .doc(bookingDetail.parkingId) + .get() + .subscribe(data => { + const detail = data.data(); + const available = parseInt(detail.available, 10); + this.parkings + .doc(bookingDetail.parkingId) + .set({ + available: available - 1, + booked: [`${bookingDetail.row}${bookingDetail.column}`] + }, { merge: true }). + then(() => { + // this.parkings.doc(bookingDetail.parkingId) + // .collection('booked') + // .doc(`${bookingDetail.parkingId}${slotDetail.row}${slotDetail.column}`) + // .set({ + // 'booked': true + // }); + console.log('Booked successfully'); + }); + }); + + this.users.doc(bookingDetail.userId) + .set({ + userId: bookingDetail.userId, + bookedSlot: `${bookingDetail.parkingId}${slotDetail.row}${slotDetail.column}` + }); + }); + } + + /** + * Gets a slot details + * @param parkingId + * @param row + * @param column + */ + getSlotDetails(parkingId, row, column) { + return this.bookings.doc(`${parkingId}${row}${column}`).get(); + } + + /** + * Checks out from the parking and frees the slot + * @param parkingId + * @param row + * @param column + */ + checkOut(parkingId, userId, row, column) { + this.bookings + .doc(`${parkingId}${row}${column}`) + .delete() + .then(() => { + this.parkings + .doc(parkingId) + .get() + .subscribe(data => { + const detail = data.data(); + const available = parseInt(detail.available, 10); + this.parkings + .doc(parkingId) + .set({ + available: available + 1 + }, { merge: true }). + then(() => { + // this.parkings.doc(parkingId) + // .collection('booked') + // .doc(`${parkingId}${row}${column}`) + // .delete(); + console.log("Checked out Successfully"); + }); + }); + this.users.doc(userId).delete(); + }); + } + + /** + * Books a parking slot + * @param bookingDetail + */ + checkInParkingSlot(parkingId, row, column) { + this.bookings + .doc(`${parkingId}${row}${column}`) + .set({ + status: 'P' + }, { merge: true }) + .then(() => { + console.log('Checked In successfully'); + }); + } + + // getBookedSlots(parkingId) { + // this.fireStore.collection('booked').get().subscribe((data) => { + // data.map(d => { + // console.log('d', d); + // }); + // }); + // } +} diff --git a/src/modules/parking-module/services/spas-data.service.ts b/src/modules/parking-module/services/spas-data.service.ts new file mode 100644 index 0000000..901b200 --- /dev/null +++ b/src/modules/parking-module/services/spas-data.service.ts @@ -0,0 +1,28 @@ +import { Injectable } from '@angular/core'; +import { BookingData } from 'src/modules/parking-module/models/spas-booking-data'; + +@Injectable({ + providedIn: 'root', +}) +export class SpasDataService { + + bookingDetails: BookingData; + + /** + * Stores the current booking inforamation of user + * @param bookingData: Holds booking details + * @memberOf SpasDataService + */ + storeCurrentBookingData(bookingData: BookingData) { + this.bookingDetails = bookingData; + console.log(this.bookingDetails); + } + + /** + * Returns lastly booked details of user + * @memberOf SpasDataService + */ + getBookingData() { + return this.bookingDetails; + } +} \ No newline at end of file diff --git a/src/modules/parking-module/spas.component.html b/src/modules/parking-module/spas.component.html new file mode 100644 index 0000000..06aaff0 --- /dev/null +++ b/src/modules/parking-module/spas.component.html @@ -0,0 +1,15 @@ + +
+ +
+ +
+ +
+ + +
+ +
diff --git a/src/modules/parking-module/spas.component.scss b/src/modules/parking-module/spas.component.scss new file mode 100644 index 0000000..95a53f0 --- /dev/null +++ b/src/modules/parking-module/spas.component.scss @@ -0,0 +1,33 @@ +@import "../../assets/scss/variable.scss"; + +.root-container { + background-color: #FFC306; + height: 100vh; + + .btn-grp { + position: fixed; + bottom: 50px; + font-size: 24px; + width: calc(100% - 30px); + button { + height: 100px; + width: 100px; + flex: 0 0 44%; + max-width: 44%; + margin: 3%; + background: rgba(255,255,255,0.7) + } + } +} + +@media screen and (max-width:700px) { + img { + width: 100%; + height: 100%; + } +} +@media screen and (max-width:550px) { + img { + height: 600px; + } +} \ No newline at end of file diff --git a/src/modules/parking-module/spas.component.ts b/src/modules/parking-module/spas.component.ts new file mode 100644 index 0000000..83059a7 --- /dev/null +++ b/src/modules/parking-module/spas.component.ts @@ -0,0 +1,24 @@ +import { Component, OnInit } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; +import { Router } from '@angular/router'; + +@Component({ + selector: 'spas-app', + templateUrl: './spas.component.html', + styleUrls: ['./spas.component.scss'] +}) +export class SpasComponent { + + label_name = 'Smart Parking assit system'; + routeName: string; + + constructor( + private translateService: TranslateService, + private router: Router + ) { + this.translateService.setDefaultLang('en-US'); + this.translateService.use('en-US'); + this.routeName = router.url; + } + +} diff --git a/src/modules/parking-module/spas.module.ts b/src/modules/parking-module/spas.module.ts new file mode 100644 index 0000000..0ee8f96 --- /dev/null +++ b/src/modules/parking-module/spas.module.ts @@ -0,0 +1,56 @@ +/** + * Angular Imports + */ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { SpasComponent } from './spas.component'; +import { SpasRouting } from './spas.routing'; +import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { TranslateHttpLoader } from '@ngx-translate/http-loader'; +import { HttpClient } from '@angular/common/http'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; + +/** + * Module Imports + */ +import { createTranslateLoader } from 'src/app/app.module'; +import { SpasBookingComponent } from './components/spas-booking/spas-booking.component'; +import { SearchLocationComponent } from './components/search-location/search-location.component'; +import { LocationListComponent } from './components/location-list/location-list.component'; +import { LocationSlotsComponent } from './components/location-slots/location-slots.component'; +import { SpasDataService } from 'src/modules/parking-module/services/spas-data.service'; +import { AngularFirestore } from '@angular/fire/firestore'; +import { SpasBookingSummaryComponent } from './components/spas-booking-summary/spas-booking-summary.component'; + +@NgModule({ + declarations: [ + SpasComponent, + SpasBookingComponent, + SearchLocationComponent, + LocationListComponent, + LocationSlotsComponent, + SpasBookingSummaryComponent + ], + imports: [ + CommonModule, + FormsModule, + ReactiveFormsModule, + SpasRouting, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useFactory: (createTranslateLoader), + deps: [HttpClient] + } + }) + ], + exports: [ + SpasComponent + ], + providers: [ + SpasDataService, + AngularFirestore + ], + bootstrap: [SpasComponent] +}) +export class SpasModule { } diff --git a/src/modules/parking-module/spas.routing.ts b/src/modules/parking-module/spas.routing.ts new file mode 100644 index 0000000..0928f09 --- /dev/null +++ b/src/modules/parking-module/spas.routing.ts @@ -0,0 +1,27 @@ +/** + * Angular imports + */ +import { Routes, RouterModule } from "@angular/router"; +import { SpasComponent } from './spas.component'; +import { ModuleWithProviders } from '@angular/compiler/src/core'; +import { SpasBookingComponent } from 'src/modules/parking-module/components/spas-booking/spas-booking.component'; +import { SpasBookingSummaryComponent } from 'src/modules/parking-module/components/spas-booking-summary/spas-booking-summary.component'; + +/** + * Module Imports + */ +import { SearchLocationComponent } from './components/search-location/search-location.component'; +import { LocationListComponent } from './components/location-list/location-list.component'; +import { LocationSlotsComponent } from './components/location-slots/location-slots.component'; + +const routes: Routes = [ + { path: '', component: SpasComponent }, + { path: 'user/search-location', component: SearchLocationComponent }, + { path: 'operator/search-location', component: SearchLocationComponent }, + { path: 'user/location-list', component: LocationListComponent }, + { path: 'user/location-slots', component: LocationSlotsComponent }, + { path: 'bookingConfirmation', component: SpasBookingSummaryComponent }, + { path: 'slotConfirmation', component: SpasBookingComponent } +]; + +export const SpasRouting: ModuleWithProviders = RouterModule.forChild(routes); \ No newline at end of file diff --git a/src/polyfills.ts b/src/polyfills.ts new file mode 100644 index 0000000..a6d34ea --- /dev/null +++ b/src/polyfills.ts @@ -0,0 +1,85 @@ +/** + * This file includes polyfills needed by Angular and is loaded before the app. + * You can add your own extra polyfills to this file. + * + * This file is divided into 2 sections: + * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. + * 2. Application imports. Files imported after ZoneJS that should be loaded before your main + * file. + * + * The current setup is for so-called "evergreen" browsers; the last versions of browsers that + * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), + * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. + * + * Learn more in https://angular.io/guide/browser-support + */ + +/*************************************************************************************************** + * BROWSER POLYFILLS + */ + +/** IE9, IE10, IE11, and Chrome <55 requires all of the following polyfills. + * This also includes Android Emulators with older versions of Chrome and Google Search/Googlebot + */ + +// import 'core-js/es6/symbol'; +// import 'core-js/es6/object'; +// import 'core-js/es6/function'; +// import 'core-js/es6/parse-int'; +// import 'core-js/es6/parse-float'; +// import 'core-js/es6/number'; +// import 'core-js/es6/math'; +// import 'core-js/es6/string'; +// import 'core-js/es6/date'; +// import 'core-js/es6/array'; +// import 'core-js/es6/regexp'; +// import 'core-js/es6/map'; +// import 'core-js/es6/weak-map'; +// import 'core-js/es6/set'; + +/** IE10 and IE11 requires the following for NgClass support on SVG elements */ +// import 'classlist.js'; // Run `npm install --save classlist.js`. + +/** IE10 and IE11 requires the following for the Reflect API. */ +// import 'core-js/es6/reflect'; + +/** + * Web Animations `@angular/platform-browser/animations` + * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. + * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). + */ +// import 'web-animations-js'; // Run `npm install --save web-animations-js`. + +/** + * By default, zone.js will patch all possible macroTask and DomEvents + * user can disable parts of macroTask/DomEvents patch by setting following flags + * because those flags need to be set before `zone.js` being loaded, and webpack + * will put import in the top of bundle, so user need to create a separate file + * in this directory (for example: zone-flags.ts), and put the following flags + * into that file, and then add the following code before importing zone.js. + * import './zone-flags.ts'; + * + * The flags allowed in zone-flags.ts are listed here. + * + * The following flags will work for all browsers. + * + * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame + * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick + * (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames + * + * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js + * with the following flag, it will bypass `zone.js` patch for IE/Edge + * + * (window as any).__Zone_enable_cross_context_check = true; + * + */ + +/*************************************************************************************************** + * Zone JS is required by default for Angular itself. + */ +import 'zone.js/dist/zone'; // Included with Angular CLI. + + +/*************************************************************************************************** + * APPLICATION IMPORTS + */ diff --git a/src/styles.scss b/src/styles.scss new file mode 100644 index 0000000..9b16e06 --- /dev/null +++ b/src/styles.scss @@ -0,0 +1,6 @@ +/* You can add global styles to this file, and also import other style files */ +@import '../node_modules/bootstrap/dist/css/bootstrap.min.css'; + +body { + background-color: #ffc306; +} \ No newline at end of file diff --git a/src/test.ts b/src/test.ts new file mode 100644 index 0000000..1631789 --- /dev/null +++ b/src/test.ts @@ -0,0 +1,20 @@ +// This file is required by karma.conf.js and loads recursively all the .spec and framework files + +import 'zone.js/dist/zone-testing'; +import { getTestBed } from '@angular/core/testing'; +import { + BrowserDynamicTestingModule, + platformBrowserDynamicTesting +} from '@angular/platform-browser-dynamic/testing'; + +declare const require: any; + +// First, initialize the Angular testing environment. +getTestBed().initTestEnvironment( + BrowserDynamicTestingModule, + platformBrowserDynamicTesting() +); +// Then we find all the tests. +const context = require.context('./', true, /\.spec\.ts$/); +// And load the modules. +context.keys().map(context); diff --git a/src/tsconfig.app.json b/src/tsconfig.app.json new file mode 100644 index 0000000..190fd30 --- /dev/null +++ b/src/tsconfig.app.json @@ -0,0 +1,11 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/app", + "types": [] + }, + "exclude": [ + "test.ts", + "**/*.spec.ts" + ] +} diff --git a/src/tsconfig.spec.json b/src/tsconfig.spec.json new file mode 100644 index 0000000..de77336 --- /dev/null +++ b/src/tsconfig.spec.json @@ -0,0 +1,18 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "outDir": "../out-tsc/spec", + "types": [ + "jasmine", + "node" + ] + }, + "files": [ + "test.ts", + "polyfills.ts" + ], + "include": [ + "**/*.spec.ts", + "**/*.d.ts" + ] +} diff --git a/src/tslint.json b/src/tslint.json new file mode 100644 index 0000000..52e2c1a --- /dev/null +++ b/src/tslint.json @@ -0,0 +1,17 @@ +{ + "extends": "../tslint.json", + "rules": { + "directive-selector": [ + true, + "attribute", + "app", + "camelCase" + ], + "component-selector": [ + true, + "element", + "app", + "kebab-case" + ] + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..b271fd9 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "outDir": "./dist/out-tsc", + "sourceMap": true, + "declaration": false, + "module": "es2015", + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "importHelpers": true, + "target": "es5", + "typeRoots": [ + "node_modules/@types" + ], + "lib": [ + "es2018", + "dom" + ] + } +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..c740a7b --- /dev/null +++ b/tslint.json @@ -0,0 +1,131 @@ +{ + "rulesDirectory": [ + "codelyzer" + ], + "rules": { + "arrow-return-shorthand": true, + "callable-types": true, + "class-name": true, + "comment-format": [ + true, + "check-space" + ], + "curly": true, + "deprecation": { + "severity": "warn" + }, + "eofline": true, + "forin": true, + "import-blacklist": [ + true, + "rxjs/Rx" + ], + "import-spacing": true, + "indent": [ + true, + "spaces" + ], + "interface-over-type-literal": true, + "label-position": true, + "max-line-length": [ + true, + 140 + ], + "member-access": false, + "member-ordering": [ + true, + { + "order": [ + "static-field", + "instance-field", + "static-method", + "instance-method" + ] + } + ], + "no-arg": true, + "no-bitwise": true, + "no-console": [ + true, + "debug", + "info", + "time", + "timeEnd", + "trace" + ], + "no-construct": true, + "no-debugger": true, + "no-duplicate-super": true, + "no-empty": false, + "no-empty-interface": true, + "no-eval": true, + "no-inferrable-types": [ + true, + "ignore-params" + ], + "no-misused-new": true, + "no-non-null-assertion": true, + "no-redundant-jsdoc": true, + "no-shadowed-variable": true, + "no-string-literal": false, + "no-string-throw": true, + "no-switch-case-fall-through": true, + "no-trailing-whitespace": true, + "no-unnecessary-initializer": true, + "no-unused-expression": true, + "no-use-before-declare": true, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "one-line": [ + true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "prefer-const": true, + "quotemark": [ + true, + "single" + ], + "radix": true, + "semicolon": [ + true, + "always" + ], + "triple-equals": [ + true, + "allow-null-check" + ], + "typedef-whitespace": [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace" + } + ], + "unified-signatures": true, + "variable-name": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-separator", + "check-type" + ], + "no-output-on-prefix": true, + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-input-rename": true, + "no-output-rename": true, + "use-life-cycle-interface": true, + "use-pipe-transform-interface": true, + "component-class-suffix": true, + "directive-class-suffix": true + } +}