├── parking-locator-backend ├── src │ ├── controllers.js │ ├── routes.rar │ ├── services │ │ └── jwtService.js │ ├── config │ │ └── index.js │ ├── database │ │ ├── models │ │ │ ├── user.js │ │ │ ├── ParkingHistory.js │ │ │ └── parkingLocations.js │ │ └── connect.js │ ├── routes │ │ ├── index.js │ │ ├── auth.js │ │ ├── parking.js │ │ ├── booking.js │ │ └── user.js │ ├── helpers │ │ └── mapDistance.js │ ├── middleware │ │ └── authMiddleware.js │ └── index.js ├── .gitignore ├── env ├── README.md └── package.json ├── parking_locator ├── lib │ ├── models │ │ ├── booking.dart │ │ ├── location.dart │ │ ├── geometry.dart │ │ └── place.dart │ ├── screens │ │ ├── token.dart │ │ ├── authentication │ │ │ ├── login_option.dart │ │ │ ├── signup_option.dart │ │ │ ├── auth.dart │ │ │ ├── auth2.dart │ │ │ ├── signup.dart │ │ │ └── login.dart │ │ ├── signup.dart │ │ ├── addSpot.dart │ │ ├── confirm_booking.dart │ │ ├── mySpots.dart │ │ ├── search.dart │ │ ├── userHistory.dart │ │ └── slotdetails.dart │ ├── services │ │ ├── geolocator_service.dart │ │ ├── marker_service.dart │ │ ├── auth_service.dart │ │ ├── places_service.dart │ │ └── dbservice.dart │ ├── widgets │ │ ├── border_container.dart │ │ ├── constants.dart │ │ ├── form_input.dart │ │ └── drawer.dart │ ├── constants.dart │ └── main.dart ├── android │ ├── settings_aar.gradle │ ├── gradle.properties │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ └── parking_locator │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── settings.gradle │ └── build.gradle ├── ios │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ └── .gitignore ├── lib.rar ├── assets │ ├── icon.png │ ├── icon2.png │ └── parking-icon.png ├── web │ ├── favicon.png │ ├── icons │ │ ├── Icon-192.png │ │ └── Icon-512.png │ ├── manifest.json │ └── index.html ├── .metadata ├── README.md ├── .gitignore ├── test │ └── widget_test.dart ├── pubspec.yaml └── pubspec.lock ├── parking-locator-car-detector-model ├── demofile2.txt ├── .gitignore ├── requirements.txt ├── static │ ├── img │ │ └── car-1.jpeg │ ├── css │ │ └── index.css │ └── js │ │ └── index.js ├── __pycache__ │ └── app.cpython-36.pyc ├── templates │ └── index.html └── app.py ├── ss ├── p.jpg ├── 11.jpeg ├── 12.jpeg ├── 13.jpeg ├── 14.jpeg ├── 15.jpeg ├── 16.jpeg ├── 17.jpeg ├── 18.jpeg ├── 19.png ├── kk.png └── logo.png ├── .vscode └── launch.json └── readme.md /parking-locator-backend/src/controllers.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /parking_locator/lib/models/booking.dart: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /parking-locator-car-detector-model/demofile2.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /parking-locator-backend/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.env -------------------------------------------------------------------------------- /parking_locator/android/settings_aar.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /parking-locator-car-detector-model/.gitignore: -------------------------------------------------------------------------------- 1 | venv 2 | 3 | images -------------------------------------------------------------------------------- /parking_locator/lib/screens/token.dart: -------------------------------------------------------------------------------- 1 | 2 | 3 | String _token; -------------------------------------------------------------------------------- /parking_locator/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /parking_locator/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ss/p.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/ss/p.jpg -------------------------------------------------------------------------------- /ss/11.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/ss/11.jpeg -------------------------------------------------------------------------------- /ss/12.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/ss/12.jpeg -------------------------------------------------------------------------------- /ss/13.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/ss/13.jpeg -------------------------------------------------------------------------------- /ss/14.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/ss/14.jpeg -------------------------------------------------------------------------------- /ss/15.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/ss/15.jpeg -------------------------------------------------------------------------------- /ss/16.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/ss/16.jpeg -------------------------------------------------------------------------------- /ss/17.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/ss/17.jpeg -------------------------------------------------------------------------------- /ss/18.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/ss/18.jpeg -------------------------------------------------------------------------------- /ss/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/ss/19.png -------------------------------------------------------------------------------- /ss/kk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/ss/kk.png -------------------------------------------------------------------------------- /ss/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/ss/logo.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /parking_locator/lib.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/lib.rar -------------------------------------------------------------------------------- /parking_locator/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/assets/icon.png -------------------------------------------------------------------------------- /parking_locator/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/web/favicon.png -------------------------------------------------------------------------------- /parking_locator/assets/icon2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/assets/icon2.png -------------------------------------------------------------------------------- /parking-locator-backend/src/routes.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking-locator-backend/src/routes.rar -------------------------------------------------------------------------------- /parking_locator/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /parking_locator/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/web/icons/Icon-192.png -------------------------------------------------------------------------------- /parking_locator/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/web/icons/Icon-512.png -------------------------------------------------------------------------------- /parking_locator/assets/parking-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/assets/parking-icon.png -------------------------------------------------------------------------------- /parking-locator-backend/env: -------------------------------------------------------------------------------- 1 | MONGODB_URI=mongodb+srv://parkingApp:JA2T8IQrBPDqgZUN@cluster.bhj6a.mongodb.net/parkingFinder?retryWrites=true&w=majority 2 | 3 | -------------------------------------------------------------------------------- /parking-locator-backend/README.md: -------------------------------------------------------------------------------- 1 | # parking-finder-backend 2 | 3 | npm install -g nodemon 4 | 5 | npm install 6 | 7 | 8 | npm start 9 | 10 | 11 | -------------------------------------------------------------------------------- /parking-locator-car-detector-model/requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking-locator-car-detector-model/requirements.txt -------------------------------------------------------------------------------- /parking-locator-car-detector-model/static/img/car-1.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking-locator-car-detector-model/static/img/car-1.jpeg -------------------------------------------------------------------------------- /parking-locator-car-detector-model/__pycache__/app.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking-locator-car-detector-model/__pycache__/app.cpython-36.pyc -------------------------------------------------------------------------------- /parking_locator/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /parking_locator/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /parking_locator/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /parking_locator/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /parking_locator/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Sakshi107/parking-locator/HEAD/parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /parking_locator/android/app/src/main/kotlin/com/example/parking_locator/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.parking_locator 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /parking_locator/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /parking_locator/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /parking_locator/lib/models/location.dart: -------------------------------------------------------------------------------- 1 | class Location{ 2 | final double lat; 3 | final double lng; 4 | 5 | Location({this.lat, this.lng}); 6 | 7 | Location.fromJson(Map parsedJson) 8 | :lat = parsedJson['lat'], 9 | lng = parsedJson['lng']; 10 | } -------------------------------------------------------------------------------- /parking-locator-backend/src/services/jwtService.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken"); 2 | const { JWT_SECRET } = require("../config"); 3 | const generateJWTToken = (payload) => { 4 | const token = jwt.sign(payload, JWT_SECRET); 5 | return token; 6 | }; 7 | 8 | module.exports = { generateJWTToken }; 9 | -------------------------------------------------------------------------------- /parking_locator/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip 7 | -------------------------------------------------------------------------------- /parking-locator-backend/src/config/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | PORT: process.env.port || 5000, 3 | MONGODB_URI: process.env.MONGODB_URI || "mongodb+srv://parkingApp:JA2T8IQrBPDqgZUN@cluster.bhj6a.mongodb.net/parkingFinder?retryWrites=true&w=majority", 4 | JWT_SECRET: "secret", 5 | TIME_FORMAT: "HH:mm:ss", 6 | }; 7 | -------------------------------------------------------------------------------- /parking_locator/lib/models/geometry.dart: -------------------------------------------------------------------------------- 1 | import 'package:parking_locator/models/location.dart'; 2 | 3 | class Geometry { 4 | final Location location; 5 | 6 | Geometry({this.location}); 7 | 8 | Geometry.fromJson(Map parsedJson) 9 | :location = Location.fromJson(parsedJson['location']); 10 | } -------------------------------------------------------------------------------- /parking_locator/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /parking_locator/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /parking_locator/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /parking_locator/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /parking_locator/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /parking_locator/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 8962f6dc68ec8e2206ac2fa874da4a453856c7d3 8 | channel: unknown 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /parking_locator/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /parking_locator/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "parking_locator", 9 | "cwd": "parking_locator", 10 | "request": "launch", 11 | "type": "dart" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /parking_locator/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /parking_locator/lib/services/geolocator_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:geolocator/geolocator.dart'; 2 | 3 | class GeoLocatorService{ 4 | 5 | Future getLocation() async { 6 | 7 | return await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high); 8 | } 9 | 10 | Future getDistance(double startLatitude, double startLongitude, double endLatitude, double endLongitude) async { 11 | return Geolocator.distanceBetween(startLatitude, startLongitude, endLatitude, endLongitude); 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /parking_locator/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /parking_locator/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /parking-locator-backend/src/database/models/user.js: -------------------------------------------------------------------------------- 1 | // Library Imports 2 | const mongoose = require("mongoose"); 3 | const { v4: UUID } = require("uuid"); 4 | 5 | const UserSchema = mongoose.Schema({ 6 | name: { type: String, required: true }, 7 | email: { type: String, required: true }, 8 | mobile: { type: String, required: true }, 9 | password: { type: String, required: true }, 10 | walletBalance: { type: Number, default: 100 }, 11 | userID: { type: String, default: UUID }, 12 | }); 13 | 14 | const User = mongoose.model("users", UserSchema); 15 | 16 | module.exports = User; 17 | -------------------------------------------------------------------------------- /parking-locator-backend/src/routes/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const authRouter = require("./auth"); 4 | const parkingRouter = require("./parking"); 5 | const userRouter = require("./user"); 6 | const bookingRouter = require("./booking"); 7 | const { isLoggedIn } = require("../middleware/authMiddleware"); 8 | 9 | router.use("/auth", authRouter); 10 | router.use("/user", isLoggedIn, userRouter); 11 | router.use("/parking", isLoggedIn, parkingRouter); 12 | router.use("/booking", isLoggedIn, bookingRouter); 13 | 14 | module.exports = router; 15 | -------------------------------------------------------------------------------- /parking_locator/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | import GoogleMaps 4 | 5 | @UIApplicationMain 6 | @objc class AppDelegate: FlutterAppDelegate { 7 | override func application( 8 | _ application: UIApplication, 9 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 10 | ) -> Bool { 11 | GMSServices.provideAPIKey("AIzaSyCLuXe__CHkfuS42u3fc4e5H4Z5F-gjkLM") 12 | GeneratedPluginRegistrant.register(with: self) 13 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /parking-locator-backend/src/helpers/mapDistance.js: -------------------------------------------------------------------------------- 1 | function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) { 2 | var R = 6371; 3 | var dLat = deg2rad(lat2 - lat1); 4 | var dLon = deg2rad(lon2 - lon1); 5 | var a = 6 | Math.sin(dLat / 2) * Math.sin(dLat / 2) + 7 | Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2); 8 | var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 9 | var d = R * c * 1000; 10 | return d; 11 | } 12 | 13 | function deg2rad(deg) { 14 | return deg * (Math.PI / 180); 15 | } 16 | 17 | module.exports = getDistanceFromLatLonInKm; 18 | -------------------------------------------------------------------------------- /parking_locator/README.md: -------------------------------------------------------------------------------- 1 | # parking_locator 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /parking-locator-backend/src/database/models/ParkingHistory.js: -------------------------------------------------------------------------------- 1 | // Library Imports 2 | const mongoose = require("mongoose"); 3 | const ParkingHistorySchema = mongoose.Schema({ 4 | userID: { type: String, required: true }, 5 | isConfirmed: { type: Boolean, default: false }, 6 | startTime: { type: Date }, 7 | endTime: { type: Date }, 8 | advancedBooking: { type: Boolean }, 9 | estimatedStartTime: { type: Date }, 10 | estimatedEndTime: { type: Number }, 11 | duration: { type: Number }, 12 | slotID: { type: String, required: true }, 13 | }); 14 | 15 | const ParkingHistory = mongoose.model("parkingHistory", ParkingHistorySchema); 16 | 17 | module.exports = ParkingHistory; 18 | -------------------------------------------------------------------------------- /parking-locator-backend/src/middleware/authMiddleware.js: -------------------------------------------------------------------------------- 1 | const jwt = require("jsonwebtoken"); 2 | const { JWT_SECRET } = require("../config/"); 3 | function isLoggedIn(req, res, next) { 4 | if (req.headers.authorization) { 5 | const { authorization } = req.headers; 6 | const bearerToken = authorization.split(" ")[1]; 7 | try { 8 | result = jwt.verify(bearerToken, JWT_SECRET); 9 | req.user = result; 10 | next(); 11 | } catch (err) { 12 | res.status(401).send({ code: 0, message: "Something went wrong" }); 13 | } 14 | } else { 15 | res.status(401).json({ code: 0, message: "unauthorized" }); 16 | } 17 | } 18 | 19 | module.exports = { isLoggedIn }; 20 | -------------------------------------------------------------------------------- /parking-locator-backend/src/database/connect.js: -------------------------------------------------------------------------------- 1 | // Library Imports 2 | var mongoose = require("mongoose"); 3 | 4 | // Project Imports 5 | const { MONGODB_URI } = require("./../config"); 6 | 7 | const connectDB = (callback) => { 8 | console.log("connecting"); 9 | mongoose.connect( 10 | MONGODB_URI, 11 | { 12 | useNewUrlParser: true, 13 | useUnifiedTopology: true, 14 | useCreateIndex: true, 15 | useFindAndModify: false, 16 | }, 17 | (err) => { 18 | if (err) { 19 | callback(err); 20 | } else { 21 | console.log("connected"); 22 | callback(null); 23 | } 24 | } 25 | ); 26 | }; 27 | 28 | module.exports = { connectDB }; 29 | -------------------------------------------------------------------------------- /parking_locator/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /parking_locator/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "parking_locator", 3 | "short_name": "parking_locator", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /parking-locator-backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "parking-finder-backend", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "nodemon src/index.js", 9 | "start-prod": "node src/index.js" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "bcryptjs": "^2.4.3", 15 | "body-parser": "^1.19.0", 16 | "cors": "^2.8.5", 17 | "dotenv": "^8.2.0", 18 | "express": "^4.17.1", 19 | "jsonwebtoken": "^8.5.1", 20 | "lodash": "^4.17.21", 21 | "moment": "^2.29.1", 22 | "mongodb": "^3.6.5", 23 | "mongoose": "^5.12.3", 24 | "uuid": "^8.3.2" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /parking_locator/lib/services/marker_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:parking_locator/models/place.dart'; 2 | import 'package:google_maps_flutter/google_maps_flutter.dart'; 3 | 4 | class MarkerService { 5 | 6 | List getMarkers(List places){ 7 | var markers = List(); 8 | 9 | places.forEach((place){ 10 | Marker marker = Marker( 11 | markerId: MarkerId(place.address), 12 | draggable: false, 13 | // icon: place.icon, 14 | icon:BitmapDescriptor.defaultMarker, 15 | infoWindow: InfoWindow(title: place.address), 16 | position: LatLng(place.lat, place.long) 17 | ); 18 | 19 | markers.add(marker); 20 | }); 21 | 22 | return markers; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /parking_locator/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:4.1.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /parking_locator/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /parking_locator/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /parking-locator-backend/src/database/models/parkingLocations.js: -------------------------------------------------------------------------------- 1 | // Library Imports 2 | const mongoose = require("mongoose"); 3 | const { v4: UUID } = require("uuid"); 4 | 5 | const ParkingLocationsSchema = mongoose.Schema({ 6 | userID: { type: String, required: true }, 7 | Location: { 8 | type: { 9 | type: String, 10 | enum: ["Point", "Polygon"], 11 | }, 12 | coordinates: [Number], 13 | }, 14 | parkingType: { 15 | type: String, 16 | enum: ["COVERED", "OPEN"], 17 | }, 18 | chargesPerHour: { type: Number }, 19 | address: String, 20 | slotID: { type: String, default: UUID }, 21 | isEmpty: { type: Boolean, default: true }, 22 | activeHours: { start: { type: Number, default: 0 }, end: { type: Number, default: 1440 } }, 23 | }); 24 | ParkingLocationsSchema.index({ Location: "2dsphere" }); 25 | 26 | const ParkingLocations = mongoose.model("parkinglocations", ParkingLocationsSchema); 27 | 28 | module.exports = ParkingLocations; 29 | -------------------------------------------------------------------------------- /parking-locator-backend/src/index.js: -------------------------------------------------------------------------------- 1 | // Library Imports 2 | require("dotenv").config(); 3 | const express = require("express"); 4 | const bodyParser = require("body-parser"); 5 | const cors = require("cors"); 6 | const database = require("./database/connect"); 7 | const { PORT, MONGODB_URI } = require("./config"); 8 | const baseRouter = require("./routes"); 9 | 10 | const app = express(); 11 | app.use(cors()); 12 | 13 | app.use(bodyParser.json()); 14 | app.use(bodyParser.urlencoded({ extended: true })); 15 | app.use((err, req, res, next) => { 16 | if (err) { 17 | res.status(400).send({ message: "Error Parsing Data." }); 18 | } else { 19 | next(); 20 | } 21 | }); 22 | 23 | // Connect to database 24 | database.connectDB((err) => { 25 | if (err) { 26 | throw err; 27 | } 28 | app.use(baseRouter); 29 | 30 | app.use("/", (req, res) => res.send("api")); 31 | app.listen(PORT, () => { 32 | console.log(`listening to port ${PORT}`); 33 | }); 34 | }); 35 | // setup routes for the server 36 | -------------------------------------------------------------------------------- /parking_locator/lib/widgets/border_container.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class BorderedContainer extends StatelessWidget { 4 | final String title; 5 | final String value; 6 | const BorderedContainer({ 7 | this.title, 8 | this.value, 9 | }); 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return Card( 14 | elevation: 0.5, 15 | color:Color(0xFFC7D3D4).withOpacity(0.9), 16 | 17 | // margin: margin ?? const EdgeInsets.symmetric(vertical: 4.0), 18 | child: Container( 19 | // width: 100, 20 | padding: EdgeInsets.symmetric(horizontal: 20,vertical: 20), 21 | child: Column( 22 | crossAxisAlignment: CrossAxisAlignment.stretch, 23 | children: [ 24 | Text(title,maxLines:3,style: TextStyle( fontWeight: FontWeight.bold,fontSize:18.0)), 25 | SizedBox(height:8.0), 26 | Text(value,style: TextStyle( fontSize:18.0 ),), 27 | ], 28 | ), 29 | ), 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /parking_locator/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /parking_locator/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /parking_locator/lib/widgets/constants.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | // import 'package:google_fonts/google_fonts.dart'; 4 | 5 | class Constants{ 6 | static const mainColor=Color(0xFFAFEADC); 7 | static const secColor=Color(0xFF041E42); 8 | static const backgroundColor=Color(0xFFAFEADC); 9 | 10 | static const tileSelected=TextStyle(color:Colors.white70,fontSize:20,fontWeight:FontWeight.w600 ); 11 | 12 | static const tile=TextStyle(color:Colors.white,fontSize:20,fontWeight:FontWeight.w600 ); 13 | 14 | Color selectedColor = Color(0xFF4AC8EA); 15 | Color drawerBackgroundColor = Color(0xFF272D34); 16 | static const regularHeading = 17 | TextStyle(fontSize: 18.0, fontWeight: FontWeight.w600, color: Colors.black); 18 | 19 | static const boldHeading = 20 | TextStyle(fontSize: 22.0, fontWeight: FontWeight.w600, color: secColor); 21 | 22 | static const regularDarkText = 23 | TextStyle(fontSize: 16.0, fontWeight: FontWeight.w600, color: Colors.black); 24 | 25 | static const mainHead=TextStyle(fontWeight: FontWeight.bold,color: Color(0xFF2661FA),fontSize: 36); 26 | 27 | } -------------------------------------------------------------------------------- /parking_locator/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:parking_locator/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /parking-locator-car-detector-model/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 13 | 14 | Document 15 | 16 | 17 |
18 |
CAR DETECTOR
19 |
20 |
21 | 22 | 23 | 24 |
25 |
26 |

27 | 28 | 29 | 30 |
31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /parking_locator/lib/widgets/form_input.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class Input extends StatelessWidget { 4 | final String str; 5 | final Function onChanged; 6 | final TextInputType type; 7 | final bool isPassword; 8 | Input({this.str, this.onChanged, this.type,this.isPassword}); 9 | @override 10 | Widget build(BuildContext context) { 11 | return TextField( 12 | obscureText: isPassword, 13 | onChanged: onChanged, 14 | textInputAction: TextInputAction.next, 15 | keyboardType: type, 16 | style: TextStyle(color: Colors.white), 17 | decoration: InputDecoration( 18 | hintText: str, 19 | hintStyle: TextStyle( 20 | fontSize: 16, 21 | color: Color(0xFF3F3C31), 22 | fontWeight: FontWeight.bold, 23 | ), 24 | border: OutlineInputBorder( 25 | borderRadius: BorderRadius.circular(25), 26 | borderSide: BorderSide( 27 | width: 0, 28 | style: BorderStyle.none, 29 | ), 30 | ), 31 | filled: true, 32 | fillColor: Colors.black38, 33 | contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 0), 34 | ), 35 | ); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /parking_locator/lib/constants.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter/material.dart'; 3 | // import 'package:google_fonts/google_fonts.dart'; 4 | 5 | class Constants{ 6 | // static const mainColor=Color(0xFFAFEADC); 7 | // static const secColor=Color(0xFF041E42); 8 | //static const backgroundColor=Color(0xFFAFEADC); 9 | static const mainColor=Color(0xFFC7D3D4); 10 | static const secColor=Color(0xFF603F83); 11 | static const tileSelected=TextStyle(color:Colors.white70,fontSize:20,fontWeight:FontWeight.w600 ); 12 | 13 | static const tile=TextStyle(color:Colors.white,fontSize:20,fontWeight:FontWeight.w600 ); 14 | 15 | Color selectedColor = Color(0xFF4AC8EA); 16 | Color drawerBackgroundColor = Color(0xFF272D34); 17 | static const regularHeading = 18 | TextStyle(fontSize: 18.0, fontWeight: FontWeight.w600, color: Colors.black); 19 | 20 | static const boldHeading = 21 | TextStyle(fontSize: 22.0, fontWeight: FontWeight.w600, color: secColor); 22 | 23 | static const regularDarkText = 24 | TextStyle(fontSize: 16.0, fontWeight: FontWeight.w600, color: Colors.black); 25 | 26 | static const mainHead=TextStyle(fontWeight: FontWeight.bold,color: Color(0xFF2661FA),fontSize: 36); 27 | 28 | } -------------------------------------------------------------------------------- /parking-locator-car-detector-model/static/css/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | 7 | .header { 8 | background-color: lightsalmon; 9 | color: crimson; 10 | padding: 1rem; 11 | display: flex; 12 | font-size: 2rem; 13 | justify-content: center; 14 | } 15 | 16 | .fileDisplay { 17 | margin: 2rem auto; 18 | width: 30%; 19 | 20 | /* height: 50vh; */ 21 | border: 2px dashed #bbb; 22 | display: flex; 23 | justify-content: center; 24 | align-items: center; 25 | } 26 | 27 | .fileDisplay img { 28 | max-height: 100%; 29 | object-fit: fill; 30 | max-width: 100%; 31 | } 32 | #camera { 33 | width: 100%; 34 | height: 100%; 35 | } 36 | 37 | .fileDisplay h3 { 38 | color: #999; 39 | } 40 | 41 | .iscar { 42 | display: flex; 43 | justify-content: center; 44 | } 45 | .actions { 46 | display: flex; 47 | justify-content: center; 48 | margin-top: 1rem; 49 | } 50 | .btn { 51 | border: none; 52 | border-radius: 5px; 53 | font-size: 1.2rem; 54 | padding: 0.7rem 2rem; 55 | color: white; 56 | margin: 0 1rem; 57 | } 58 | .upload { 59 | background-color: #0d6efd; 60 | } 61 | .predict { 62 | background-color: #198754; 63 | } 64 | 65 | .predict:disabled { 66 | opacity: 0.7; 67 | } 68 | -------------------------------------------------------------------------------- /parking-locator-backend/src/routes/auth.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const User = require("../database/models/user"); 3 | const { generateJWTToken } = require("../services/jwtService"); 4 | const router = express.Router(); 5 | 6 | router.get("/", (req, res) => { 7 | res.send("auth service"); 8 | }); 9 | 10 | router.post("/signup", async (req, res) => { 11 | try { 12 | const user = await User.create({ ...req.body }); 13 | console.log(user.toJSON()); 14 | const { password, ...profile } = user.toJSON(); 15 | const token = `bearer ` + generateJWTToken(profile); 16 | res.json({ status: "SUCCESS", authToken: token, profile }); 17 | } catch (error) { 18 | console.log(error.message); 19 | res.status(500).send({ message: error.message, errorType: error.name }); 20 | } 21 | }); 22 | 23 | router.post("/login", async (req, res) => { 24 | const { email, password } = req.body; 25 | 26 | try { 27 | const user = await User.findOne({ email }); 28 | if (user) { 29 | if (user.password === password) { 30 | const { password, ...profile } = user.toJSON(); 31 | const token = `bearer ` + generateJWTToken(profile); 32 | res.json({ status: "SUCCESS", token, profile }); 33 | } else { 34 | res.status(401).json({ status: "UNAUTHORIZED", message: "wrong password" }); 35 | } 36 | } else { 37 | res.status(401).json({ status: "UNAUTHORIZED", message: "User does not exist" }); 38 | } 39 | } catch (error) { 40 | res.status(500).send({ message: error.message, errorType: error.name }); 41 | } 42 | }); 43 | module.exports = router; 44 | -------------------------------------------------------------------------------- /parking_locator/lib/screens/authentication/login_option.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:parking_locator/constants.dart'; 3 | 4 | class LoginOption extends StatelessWidget { 5 | static const mainColor = Constants.mainColor; 6 | static const secColor = Constants.secColor; 7 | static const backgroundColor = Constants.mainColor; 8 | @override 9 | Widget build(BuildContext context) { 10 | return Column( 11 | crossAxisAlignment: CrossAxisAlignment.stretch, 12 | mainAxisAlignment: MainAxisAlignment.center, 13 | children: [ 14 | 15 | Text( 16 | "Existing user?", 17 | style: TextStyle( 18 | fontSize: 16, 19 | ), 20 | ), 21 | 22 | SizedBox( 23 | height: 16, 24 | ), 25 | 26 | Container( 27 | height: 40, 28 | decoration: BoxDecoration( 29 | color:secColor, 30 | borderRadius: BorderRadius.all( 31 | Radius.circular(25), 32 | ), 33 | boxShadow: [ 34 | BoxShadow( 35 | color: Color(0xFF041E42).withOpacity(0.2), 36 | spreadRadius: 3, 37 | blurRadius: 4, 38 | offset: Offset(0, 3), 39 | ), 40 | ], 41 | ), 42 | child: Center( 43 | child: Text( 44 | "LOGIN", 45 | style: TextStyle( 46 | fontSize: 24, 47 | fontWeight: FontWeight.bold, 48 | color: mainColor, 49 | ), 50 | ), 51 | ), 52 | ), 53 | 54 | ], 55 | ); 56 | } 57 | } -------------------------------------------------------------------------------- /parking_locator/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | parking_locator 30 | 31 | 32 | 33 | 36 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | parking_locator 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /parking_locator/lib/models/place.dart: -------------------------------------------------------------------------------- 1 | import 'package:google_maps_flutter/google_maps_flutter.dart'; 2 | import 'package:parking_locator/models/geometry.dart'; 3 | 4 | // class Place{ 5 | // final String name; 6 | // final double rating; 7 | // final int userRatingCount; 8 | // final String vicinity; 9 | // final Geometry geometry; 10 | // final BitmapDescriptor icon; 11 | 12 | // Place({this.geometry, this.name, this.rating, this.userRatingCount, this.vicinity, this.icon}); 13 | 14 | // Place.fromJson(Map parsedJson, BitmapDescriptor icon) 15 | // :name = parsedJson['name'], 16 | // rating = (parsedJson['rating'] !=null) ? parsedJson['rating'].toDouble() : null, 17 | // userRatingCount = (parsedJson['user_ratings_total'] != null) ? parsedJson['user_ratings_total'] : null, 18 | // vicinity = parsedJson['vicinity'], 19 | // geometry = Geometry.fromJson(parsedJson['geometry']), 20 | // icon=icon; 21 | 22 | // } 23 | // 24 | class Place { 25 | final String address; 26 | final double lat; 27 | final double long; 28 | final String slotID; 29 | final String from; 30 | final String to; 31 | final BitmapDescriptor icon; 32 | 33 | Place({ 34 | this.address, 35 | this.lat, 36 | this.long, 37 | this.from, 38 | this.to, 39 | this.slotID, 40 | this.icon 41 | }); 42 | 43 | Place.fromJson(Map parsedJson, BitmapDescriptor icon) 44 | : address = parsedJson['address'], 45 | lat = parsedJson['Location']['coordinates'][0].toDouble(), 46 | long = parsedJson['Location']['coordinates'][1].toDouble(), 47 | from = parsedJson['activeHours']['start'].toString(), 48 | to= parsedJson['activeHours']['end'].toString(), 49 | icon=icon, 50 | slotID = parsedJson['slotID']; 51 | } 52 | -------------------------------------------------------------------------------- /parking_locator/lib/screens/authentication/signup_option.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:parking_locator/constants.dart'; 3 | 4 | class SignUpOption extends StatelessWidget { 5 | static const mainColor = Constants.mainColor; 6 | static const secColor = Constants.secColor; 7 | static const backgroundColor = Constants.mainColor; 8 | @override 9 | Widget build(BuildContext context) { 10 | return Column( 11 | crossAxisAlignment: CrossAxisAlignment.stretch, 12 | mainAxisAlignment: MainAxisAlignment.center, 13 | children: [ 14 | 15 | Text( 16 | "OR", 17 | textAlign: TextAlign.center, 18 | style: TextStyle( 19 | fontSize: 24, 20 | fontWeight: FontWeight.bold, 21 | height: 1, 22 | color: mainColor, 23 | ), 24 | ), 25 | 26 | SizedBox( 27 | height: 24, 28 | ), 29 | 30 | Container( 31 | height: 40, 32 | decoration: BoxDecoration( 33 | color: mainColor, 34 | borderRadius: BorderRadius.all( 35 | Radius.circular(25), 36 | ), 37 | boxShadow: [ 38 | BoxShadow( 39 | color: Color(0xFFAFEADC).withOpacity(0.2), 40 | spreadRadius: 3, 41 | blurRadius: 4, 42 | offset: Offset(0, 3), 43 | ), 44 | ], 45 | ), 46 | child: Center( 47 | child: Text( 48 | "SIGN UP", 49 | style: TextStyle( 50 | fontSize: 24, 51 | fontWeight: FontWeight.bold, 52 | color:secColor, 53 | ), 54 | ), 55 | ), 56 | ), 57 | 58 | ], 59 | ); 60 | } 61 | } -------------------------------------------------------------------------------- /parking_locator/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 30 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | defaultConfig { 36 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 37 | applicationId "com.example.parking_locator" 38 | minSdkVersion 16 39 | targetSdkVersion 30 40 | versionCode flutterVersionCode.toInteger() 41 | versionName flutterVersionName 42 | } 43 | 44 | buildTypes { 45 | release { 46 | // TODO: Add your own signing config for the release build. 47 | // Signing with the debug keys for now, so `flutter run --release` works. 48 | signingConfig signingConfigs.debug 49 | } 50 | } 51 | } 52 | 53 | flutter { 54 | source '../..' 55 | } 56 | 57 | dependencies { 58 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 59 | } 60 | -------------------------------------------------------------------------------- /parking_locator/lib/services/auth_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:http/http.dart' as http; 2 | import 'dart:io'; 3 | import 'dart:convert'; 4 | import 'package:parking_locator/screens/token.dart'; 5 | 6 | class AuthMethods { 7 | signup(name, email, phone, password) async { 8 | print("imhere"); 9 | // try { 10 | var url = Uri.parse('http://127.0.0.1:5000/auth/signup'); 11 | print(url); 12 | // var request = await httpClient.post('192.168.0.108', 3000, "/auth/signup"); 13 | // var res = await request.close(); 14 | var res = await http.post( 15 | url, 16 | body: json.encode({ 17 | "name": name, 18 | "email": email, 19 | "mobile": phone, 20 | "password": password 21 | }), 22 | headers: { 23 | "Content-Type": "application/json", 24 | }, 25 | ); 26 | 27 | print(res.statusCode); 28 | var jsonresult = jsonDecode(res.body); 29 | print(jsonresult['token']); 30 | // _token= 31 | print(res.body); 32 | if (res.statusCode == 200) { 33 | print("signed up"); 34 | } else { 35 | throw Exception('Failed to create album.'); 36 | } 37 | } 38 | 39 | signin(email, password) async { 40 | print("imhere"); 41 | // try { 42 | var url = Uri.parse('http://127.0.0.1:5000/auth/login'); 43 | print(url); 44 | // var request = await httpClient.post('192.168.0.108', 3000, "/auth/signup"); 45 | // var res = await request.close(); 46 | var res = await http.post( 47 | url, 48 | body: json.encode({"email": email, "password": password}), 49 | headers: { 50 | "Content-Type": "application/json", 51 | }, 52 | ); 53 | 54 | print(res.statusCode); 55 | // print(res.body); 56 | var jsonresult = jsonDecode(res.body); 57 | print(jsonresult['token']); 58 | // _token = jsonresult['token']; 59 | if (res.statusCode == 200) { 60 | print("signed in"); 61 | } else { 62 | throw Exception('Failed to create album.'); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /parking_locator/lib/services/places_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:parking_locator/models/place.dart'; 2 | import 'package:google_maps_flutter/google_maps_flutter.dart'; 3 | import 'package:http/http.dart' as http; 4 | import 'dart:convert' as convert; 5 | 6 | class PlacesService { 7 | final key = 'AIzaSyCLuXe__CHkfuS42u3fc4e5H4Z5F-gjkLM'; 8 | 9 | Future> getPlaces( 10 | double lat, double lng, BitmapDescriptor icon) async { 11 | var url = Uri.parse( 12 | 'http://127.0.0.1:5000/parking/nearme/?lat=$lat&long=$lng&radius=5000'); 13 | print(url); 14 | String token = 15 | "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRCYWxhbmNlIjoxMDAsInVzZXJJRCI6IjBjNjgyMTk2LWVmMzMtNGJmZS1hNDlkLTAyYjk4ZmMwYjgzMSIsIl9pZCI6IjYwNjZiMjI1ODhiZjJlMjEyODhhOTU1YyIsIm5hbWUiOiJEZWVwYW5zaHUgVmFuZ2FuaSIsImVtYWlsIjoidmFuZ2FuaWRlZXBhbnNodUBnbWFpbC5jb20iLCJtb2JpbGUiOiI5MTY3Njg3NzEyIiwiX192IjowLCJpYXQiOjE2MTczNDMwMTN9.yoQOPwMZTmJ0YBd-jaAeCtHTG_gb76mnupvg0KYsa3w"; 16 | var response = await http.get( 17 | url, 18 | headers: { 19 | "authorization": token, 20 | "Content-Type": "application/json", 21 | }, 22 | ); 23 | 24 | // var response = await http.get(Uri.parse( 25 | // 'https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=$lat,$lng&type=parking&rankby=distance&key=$key')); 26 | // print(response.body); 27 | var json = convert.jsonDecode(response.body); 28 | // print(json); 29 | var jsonResults = json['parkings']; 30 | print("im here inside place servuces"); 31 | print(lat); 32 | print(lng); 33 | print(jsonResults); 34 | // for (int i = 0; i < jsonResults.length; i++) { 35 | // print(i); 36 | // print(jsonResults[i]); 37 | // print(jsonResults[i]['Location']['coordinates'][0]); 38 | // print(jsonResults[i]['activeHours']); 39 | // } 40 | // print(jsonResults.map((place) => Place.fromJson(place,icon)).toList()); 41 | return jsonResults 42 | .map((place) => Place.fromJson(place, icon)) 43 | .toList(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /parking-locator-backend/src/routes/parking.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const ParkingLocations = require("../database/models/parkingLocations"); 3 | const moment = require("moment"); 4 | const { TIME_FORMAT } = require("../config"); 5 | const router = express.Router(); 6 | 7 | router.get("/", (req, res) => { 8 | res.send("parking discovery service"); 9 | }); 10 | 11 | router.get("/nearme", async (req, res) => { 12 | const { lat, long, radius = 1000 } = req.query; 13 | 14 | const currentTimeinMinutesFromStartOfDay = moment().diff(moment().startOf("day"), "minutes"); 15 | try { 16 | const parkingsNearMe = await ParkingLocations.find( 17 | { 18 | Location: { 19 | $near: { $geometry: { type: "Point", coordinates: [lat, long] }, $maxDistance: radius }, 20 | }, 21 | // $and: [ 22 | // { "activeHours.start": { $lte: currentTimeinMinutesFromStartOfDay } }, 23 | // { "activeHours.end": { $gte: currentTimeinMinutesFromStartOfDay } }, 24 | // ], 25 | isEmpty: true, 26 | }, 27 | { slotID: 1, "Location.coordinates": 1, address: 1, activeHours: 1 } 28 | ); 29 | res.json({ status: "SUCCESS", parkings: parkingsNearMe }); 30 | } catch (error) { 31 | res.status(500).send({ message: error.message, errorType: error.name }); 32 | } 33 | }); 34 | 35 | router.get("/:spotID", async (req, res) => { 36 | try { 37 | const { spotID } = req.params; 38 | let parking = await ParkingLocations.findOne({ slotID: spotID }); 39 | if (parking) { 40 | parking = parking.toJSON(); 41 | parking.activeHours.start = moment().startOf("day").add(parking.activeHours.start, "minutes").format(TIME_FORMAT); 42 | parking.activeHours.end = moment().startOf("day").add(parking.activeHours.end, "minutes").format(TIME_FORMAT); 43 | console.log(parking.activeHours); 44 | res.json({ status: "SUCCESS", parking }); 45 | } else { 46 | res.json({ status: "NOTFOUND", message: "Could not find the requested spot" }); 47 | } 48 | } catch (error) { 49 | res.status(500).send({ message: error.message, errorType: error.name }); 50 | } 51 | }); 52 | 53 | module.exports = router; 54 | -------------------------------------------------------------------------------- /parking-locator-car-detector-model/app.py: -------------------------------------------------------------------------------- 1 | from flask_cors import CORS 2 | import base64 3 | import json 4 | import io 5 | import os 6 | import numpy as np 7 | import requests 8 | import cv2 9 | import numpy as np 10 | from flask import Flask, request, jsonify, render_template 11 | from json import JSONEncoder 12 | 13 | APP_ROOT = os.path.dirname(os.path.abspath(__file__)) 14 | app = Flask(__name__) 15 | CORS(app) 16 | PORT = 4000 17 | app.config["ENV"] = "development" 18 | 19 | 20 | class NumpyArrayEncoder(JSONEncoder): 21 | def default(self, obj): 22 | if isinstance(obj, np.ndarray): 23 | return obj.tolist() 24 | return JSONEncoder.default(self, obj) 25 | 26 | # Testing URL 27 | 28 | 29 | @app.route('/', methods=['GET']) 30 | def hello_world(): 31 | return render_template("index.html") 32 | 33 | 34 | target = os.path.join(APP_ROOT, 'images/') 35 | MODEL_ENDPOINT = 'http://localhost:8501/v1/models/carDetector:predict' 36 | 37 | 38 | @app.route('/predict/', methods=['POST']) 39 | def image_classifier(): 40 | if not os.path.isdir(target): 41 | os.mkdir(target) 42 | 43 | print(request.files) 44 | data_for_pred = [] 45 | for upload in request.files.getlist("files[]"): 46 | filename = upload.filename 47 | destination = "/".join([target, filename]) 48 | upload.save(destination) 49 | image = cv2.imread(destination) 50 | image = cv2.resize(image, (128, 128)) 51 | image = image * 1.0/255.0 52 | data_for_pred.append(image) 53 | 54 | data = np.array(data_for_pred) 55 | 56 | payload = json.dumps({"signature_name": "serving_default", 57 | "instances": data}, cls=NumpyArrayEncoder) 58 | headers = {"content-type": "application/json"} 59 | r = requests.post(MODEL_ENDPOINT, data=payload, headers=headers) 60 | 61 | preds = json.loads(r.text)['predictions'] 62 | response = [] 63 | files = request.files.getlist("files[]") 64 | i = 0 65 | for pred in preds: 66 | filename = files[i].filename 67 | response.append( 68 | {"filename": filename, "isCar": pred[0] > 0.4, "confidence": "{:.3f}".format(float(pred[0]))}) 69 | i += 1 70 | return jsonify(response) 71 | 72 | 73 | if __name__ == "__main__": 74 | app.run('0.0.0.0', port=PORT) 75 | -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 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 | -------------------------------------------------------------------------------- /parking_locator/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:geolocator/geolocator.dart'; 3 | import 'package:parking_locator/models/place.dart'; 4 | 5 | import 'package:parking_locator/screens/authentication/auth2.dart'; 6 | import 'package:parking_locator/screens/authentication/auth.dart'; 7 | import 'package:parking_locator/screens/addSpot.dart'; 8 | import 'package:parking_locator/screens/mySpots.dart'; 9 | import 'package:parking_locator/screens/placeDetails.dart'; 10 | import 'package:parking_locator/screens/userHistory.dart'; 11 | 12 | import 'package:parking_locator/screens/search.dart'; 13 | 14 | import 'package:parking_locator/services/geolocator_service.dart'; 15 | import 'package:parking_locator/services/places_service.dart'; 16 | import 'package:google_maps_flutter/google_maps_flutter.dart'; 17 | import 'package:provider/provider.dart'; 18 | 19 | void main() => runApp(MyApp()); 20 | 21 | class MyApp extends StatelessWidget { 22 | final locatorService = GeoLocatorService(); 23 | final placesService = PlacesService(); 24 | 25 | @override 26 | Widget build(BuildContext context) { 27 | return MultiProvider( 28 | providers: [ 29 | FutureProvider(create: (context) => locatorService.getLocation()), 30 | FutureProvider(create: (context) { 31 | ImageConfiguration configuration = 32 | createLocalImageConfiguration(context, size: Size(100, 100)); 33 | return BitmapDescriptor.fromAssetImage( 34 | configuration, 'assets/parking-icon.png'); 35 | }), 36 | ProxyProvider2>>( 37 | update: (context, position, icon, places) { 38 | return (position != null) 39 | ? placesService.getPlaces( 40 | position.latitude, position.longitude, icon) 41 | : null; 42 | }, 43 | ) 44 | ], 45 | child: MaterialApp( 46 | debugShowCheckedModeBanner: false, 47 | title: 'Parking App', 48 | theme: ThemeData( 49 | primarySwatch: Colors.blue, 50 | ), 51 | 52 | initialRoute: '/', 53 | routes: { 54 | // '/': (context) => Search(), 55 | 56 | '/': (context) => AuthScreen(), 57 | '/auth': (context) => HomePage(), 58 | '/search': (context) => Search(), 59 | '/add_spot': (context) => AddSpot(), 60 | '/my_spots': (context) => MySpots(), 61 | '/place_details': (context) => PlaceDetails(), 62 | '/my_booking': (context) => MyHistory(), 63 | }, 64 | )); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /parking_locator/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 14 | 18 | 22 | 27 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 41 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /parking_locator/lib/screens/authentication/auth.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:parking_locator/screens/authentication/auth2.dart'; 3 | 4 | import 'package:parking_locator/widgets/drawer.dart'; 5 | import 'package:parking_locator/constants.dart'; 6 | // const Color mainColor=Color(0xFF5a5aff); 7 | 8 | class AuthScreen extends StatelessWidget { 9 | static const mainColor = Constants.mainColor; 10 | static const secColor = Constants.secColor; 11 | static const backgroundColor = Constants.mainColor; 12 | @override 13 | Widget build(BuildContext context) { 14 | Size size = MediaQuery.of(context).size; 15 | return Scaffold( 16 | backgroundColor: mainColor, 17 | body: Column( 18 | mainAxisAlignment: MainAxisAlignment.center, 19 | crossAxisAlignment: CrossAxisAlignment.center, 20 | children: [ 21 | SizedBox(height: size.height * 0.05), 22 | Container( 23 | alignment: Alignment.center, 24 | padding: EdgeInsets.symmetric(horizontal: 40), 25 | child: Text( 26 | "Park Me", 27 | style: TextStyle( 28 | fontFamily: "Alegreya", 29 | fontWeight: FontWeight.bold, 30 | color: secColor, 31 | fontSize: 45), 32 | textAlign: TextAlign.left, 33 | ), 34 | ), 35 | SizedBox(height: size.height * 0.01), 36 | // Container( 37 | // alignment: Alignment.center, 38 | // child: new Image.asset('assets/images/img4.jpg'), 39 | // ), 40 | SizedBox(height: size.height * 0.03), 41 | Container( 42 | alignment: Alignment.center, 43 | margin: EdgeInsets.symmetric(horizontal: 40, vertical: 10), 44 | child: RaisedButton( 45 | onPressed: () { 46 | Navigator.pushReplacementNamed(context, '/auth'); 47 | }, 48 | shape: RoundedRectangleBorder( 49 | borderRadius: BorderRadius.circular(80.0)), 50 | textColor: Colors.white, 51 | padding: const EdgeInsets.all(0), 52 | child: Container( 53 | alignment: Alignment.center, 54 | height: 50.0, 55 | width: size.width * 0.5, 56 | color: secColor, 57 | padding: const EdgeInsets.all(0), 58 | child: Text( 59 | "Get Started", 60 | textAlign: TextAlign.center, 61 | style: TextStyle( 62 | fontWeight: FontWeight.bold, color: Colors.white), 63 | ), 64 | ), 65 | ), 66 | ), 67 | ], 68 | ), 69 | ); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /parking_locator/lib/widgets/drawer.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:parking_locator/constants.dart'; 3 | 4 | // const Constants.secColor = Color(0xFFFF785B); 5 | // const kSubMainColor = Color(0xFFDEE8FF); 6 | // const headingColor = Color(0xFF002140); 7 | 8 | class NavDrawer extends StatelessWidget { 9 | @override 10 | Widget build(BuildContext context) { 11 | return Drawer( 12 | child: Container( 13 | color:Constants.mainColor, 14 | child: ListView( 15 | padding: EdgeInsets.zero, 16 | children: [ 17 | DrawerHeader( 18 | child: Center( 19 | child: Column( 20 | children: [ 21 | Text( 22 | 'PARK ME', 23 | style: TextStyle(color: Constants.secColor, fontSize: 28), 24 | ), 25 | SizedBox(height:10.0), 26 | CircleAvatar( 27 | maxRadius: 35, 28 | backgroundColor:Constants.secColor, 29 | child: Text( 30 | "P", 31 | style: TextStyle(color: Constants.mainColor, fontSize: 40.0), 32 | ), 33 | ), 34 | ], 35 | ), 36 | ), 37 | ), 38 | ListTile( 39 | leading: Icon( 40 | Icons.menu, 41 | color: Constants.secColor, 42 | ), 43 | title: Text('Home'), 44 | onTap: () => {Navigator.of(context).pushNamed('/search')}, 45 | ), 46 | Divider(color: Constants.secColor), 47 | ListTile( 48 | leading: Icon( 49 | Icons.add_box, 50 | color: Constants.secColor, 51 | ), 52 | title: Text('Add Spot'), 53 | onTap: () => {Navigator.of(context).pushNamed('/add_spot')}, 54 | ), 55 | Divider(color: Constants.secColor), 56 | ListTile( 57 | leading: Icon( 58 | Icons.car_repair, 59 | color: Constants.secColor, 60 | ), 61 | title: Text('My Parking slots'), 62 | onTap: () => {Navigator.of(context).pushNamed('/my_spots')}, 63 | ), 64 | Divider(color: Constants.secColor), 65 | ListTile( 66 | leading: Icon( 67 | Icons.book, 68 | color: Constants.secColor, 69 | ), 70 | title: Text('My Bookings'), 71 | onTap: () => {Navigator.of(context).pushNamed('/my_booking')}, 72 | ), 73 | Divider(color: Constants.secColor), 74 | ], 75 | ), 76 | )); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /parking_locator/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /parking_locator/lib/screens/signup.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter/cupertino.dart'; 4 | import 'package:http/http.dart' as http; 5 | import 'dart:io'; 6 | 7 | class SignUpSection extends StatelessWidget { 8 | var email; 9 | var password; 10 | 11 | @override 12 | Widget build(BuildContext context) { 13 | return CupertinoPageScaffold( 14 | navigationBar: CupertinoNavigationBar( 15 | automaticallyImplyLeading: false, 16 | ), 17 | child: SafeArea( 18 | child: ListView(padding: const EdgeInsets.all(16), children: [ 19 | Padding( 20 | padding: const EdgeInsets.symmetric(vertical: 8), 21 | child: CupertinoTextField( 22 | placeholder: "Email", 23 | onChanged: (value) { 24 | email = value; 25 | })), 26 | Padding( 27 | padding: const EdgeInsets.symmetric(vertical: 8), 28 | child: CupertinoTextField( 29 | placeholder: "Password", 30 | obscureText: true, 31 | onChanged: (value) { 32 | password = value; 33 | })), 34 | FlatButton.icon( 35 | onPressed: () { 36 | print(email); 37 | print(password); 38 | signup(email, password); 39 | }, 40 | icon: Icon(Icons.save), 41 | label: Text("Sign UP")) 42 | ]))); 43 | } 44 | } 45 | 46 | signup(email, password) async { 47 | print("imhere"); 48 | var httpClient = HttpClient(); 49 | // try { 50 | var url = Uri.parse('http://127.0.0.1:5000/auth/signup'); 51 | print(url); 52 | // var request = await httpClient.post('192.168.0.108', 3000, "/auth/signup"); 53 | // var res = await request.close(); 54 | var res = await http.post( 55 | url, 56 | body: json.encode({ 57 | "name": "Hiral3", 58 | "email": email, 59 | "mobile": "1234567890", 60 | "password": password 61 | }), 62 | headers: { 63 | "Content-Type":"application/json", 64 | }, 65 | ); 66 | // final response = json.decode(res); 67 | print("hellooooo"); 68 | print(res); 69 | print(res.statusCode); 70 | print(res.body); 71 | if (res.statusCode == 200) { 72 | print("sign up"); 73 | } else { 74 | throw Exception('Failed to create album.'); 75 | } 76 | // } catch (e) { 77 | // print(e); 78 | // } 79 | 80 | // var url = Uri.parse('http://192.168.0.108:5000/auth/signup'); 81 | // final http.Response response = await http.post( 82 | // url, 83 | // headers: { 84 | // 'Content-Type': 'application/json; charset=UTF-8', 85 | // }, 86 | // body: jsonEncode({ 87 | // 'email': email, 88 | // 'password': password, 89 | // "name": "Sakshi", 90 | // "mobile": "1234456789" 91 | // }), 92 | // ); 93 | 94 | // if (response.statusCode == 201) { 95 | // print(response); 96 | // } else { 97 | // throw Exception('Failed to create album.'); 98 | // } 99 | } 100 | -------------------------------------------------------------------------------- /parking_locator/lib/screens/addSpot.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:google_maps_flutter/google_maps_flutter.dart'; 3 | import 'package:parking_locator/services/geolocator_service.dart'; 4 | import 'package:parking_locator/services/marker_service.dart'; 5 | import 'package:provider/provider.dart'; 6 | import 'package:geolocator/geolocator.dart'; 7 | import 'package:url_launcher/url_launcher.dart'; 8 | import 'package:parking_locator/constants.dart'; 9 | 10 | import 'package:geocoder/geocoder.dart'; 11 | import '../models/place.dart'; 12 | import 'package:parking_locator/screens/addForm.dart'; 13 | 14 | class AddSpot extends StatefulWidget { 15 | @override 16 | _AddSpotState createState() => _AddSpotState(); 17 | } 18 | 19 | class _AddSpotState extends State { 20 | List myMarker = []; 21 | LatLng abc; 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | final currentPosition = Provider.of(context); 26 | final placesProvider = Provider.of>>(context); 27 | final geoService = GeoLocatorService(); 28 | final markerService = MarkerService(); 29 | return Scaffold( 30 | appBar: AppBar( 31 | backgroundColor: Constants.secColor, 32 | title: Text('Add a Parking Spot'), 33 | ), 34 | body: GoogleMap( 35 | initialCameraPosition: CameraPosition( 36 | target: 37 | LatLng(currentPosition.latitude, currentPosition.longitude), 38 | zoom: 16.0), 39 | zoomGesturesEnabled: true, 40 | markers: Set.from(myMarker), 41 | mapType: MapType.hybrid, 42 | onTap: _handleTap, 43 | ), 44 | floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, 45 | floatingActionButton: FloatingActionButton( 46 | child: Icon(Icons.add_location_rounded), 47 | backgroundColor: Constants.secColor, 48 | onPressed: () { 49 | Navigator.push( 50 | context, 51 | MaterialPageRoute( 52 | builder: (context) => 53 | AddForm(tappedpoint: abc, address: address), 54 | )); 55 | }, 56 | )); 57 | } 58 | 59 | _handleTap(LatLng tappedPoint) { 60 | print(tappedPoint); 61 | setState(() { 62 | abc = tappedPoint; 63 | print(abc); 64 | getUserLocation(); 65 | myMarker = []; 66 | myMarker.add(Marker( 67 | markerId: MarkerId(tappedPoint.toString()), 68 | position: tappedPoint, 69 | draggable: true, 70 | onDragEnd: (dragEndPosition) { 71 | print(dragEndPosition); 72 | })); 73 | }); 74 | } 75 | 76 | double lat, long; 77 | String address = "No address selected"; 78 | 79 | void getUserLocation() async { 80 | print("yoo"); 81 | print(abc.latitude); 82 | lat = abc.latitude; 83 | long = abc.longitude; 84 | final coordinates = new Coordinates(lat, long); 85 | var addresses = 86 | await Geocoder.local.findAddressesFromCoordinates(coordinates); 87 | var first = addresses.first; 88 | setState(() { 89 | address = first.addressLine; 90 | }); 91 | print( 92 | ' ${first.locality}, ${first.adminArea},${first.subLocality}, ${first.subAdminArea},${first.addressLine}, ${first.featureName},${first.thoroughfare}, ${first.subThoroughfare}'); 93 | // return first.addressLine; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /parking_locator/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: parking_locator 2 | description: A new Flutter project. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: ">=2.7.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | 27 | # The following adds the Cupertino Icons font to your application. 28 | # Use with the CupertinoIcons class for iOS style icons. 29 | cupertino_icons: ^1.0.2 30 | google_maps_flutter: ^2.0.2 31 | geolocator: ^7.0.1 32 | provider: ^5.0.0 33 | url_launcher: ^6.0.3 34 | http: ^0.13.1 35 | flutter_rating_bar: ^4.0.0 36 | geocoder: ^0.2.0 37 | form_field_validator: ^1.0.1 38 | date_format: ^2.0.2 39 | intl: ^0.17.0 40 | flutter_datetime_picker: ^1.5.0 41 | google_fonts: ^2.0.0 42 | loading_animations: ^2.2.0 43 | lottie: ^1.0.1 44 | 45 | 46 | 47 | 48 | dev_dependencies: 49 | flutter_test: 50 | sdk: flutter 51 | 52 | # For information on the generic Dart part of this file, see the 53 | # following page: https://dart.dev/tools/pub/pubspec 54 | 55 | # The following section is specific to Flutter. 56 | flutter: 57 | 58 | # The following line ensures that the Material Icons font is 59 | # included with your application, so that you can use the icons in 60 | # the material Icons class. 61 | uses-material-design: true 62 | 63 | # To add assets to your application, add an assets section, like this: 64 | assets: 65 | - assets/parking-icon.png 66 | 67 | 68 | # An image asset can refer to one or more resolution-specific "variants", see 69 | # https://flutter.dev/assets-and-images/#resolution-aware. 70 | 71 | # For details regarding adding assets from package dependencies, see 72 | # https://flutter.dev/assets-and-images/#from-packages 73 | 74 | # To add custom fonts to your application, add a fonts section here, 75 | # in this "flutter" section. Each entry in this list should have a 76 | # "family" key with the font family name, and a "fonts" key with a 77 | # list giving the asset and other descriptors for the font. For 78 | # example: 79 | # fonts: 80 | # - family: Schyler 81 | # fonts: 82 | # - asset: fonts/Schyler-Regular.ttf 83 | # - asset: fonts/Schyler-Italic.ttf 84 | # style: italic 85 | # - family: Trajan Pro 86 | # fonts: 87 | # - asset: fonts/TrajanPro.ttf 88 | # - asset: fonts/TrajanPro_Bold.ttf 89 | # weight: 700 90 | # 91 | # For details regarding fonts from package dependencies, 92 | # see https://flutter.dev/custom-fonts/#from-packages 93 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | [![](https://img.shields.io/badge/Made_with-Flutter-red?style=for-the-badge&logo=flutter)](https://flutter.dev/docs) 7 | [![](https://img.shields.io/badge/Database-MongoDB-blue?style=for-the-badge&logo=mongodb)]( "Firestore") 8 | [![](https://img.shields.io/badge/Made_with-Nodejs-red?style=for-the-badge&logo=node.js)](https://nodejs.org/en/) 9 | [![](https://img.shields.io/badge/IDE-Visual_Studio_Code-purple?style=for-the-badge&logo=visual-studio-code)](https://code.visualstudio.com/ "Visual Studio Code") 10 | 11 |

12 | 13 | 14 | 15 |

16 |

Park ME

17 | 18 | ## Description ## 19 | 20 |

21 | On any given working day approximately 40% of the roads in urban India are taken up for just parking the cars !!! 22 | The global average of time spent looking for a parking spot is 20 minutes,If we could somehow minimize this time it could save people a lot of time daily. 23 | We have developed a mobile app that can help people find parking spots around their current location easily and on-demand 24 | .A simple hassle-free process that involves pulling up into the parking spot and engaging it at the click of a button. 25 | We incorporate the use of a image recognition model that automatically detects whether the parking spot is empty or full 26 |

27 | For more details- 28 | 29 | Youtube link 30 | 31 |

32 | 33 | 34 | ------------------------------------------ 35 | ## Features ## 36 | - Easily find empty parking spots nearby. 37 | - Get directions to the parking spot of your choice. 38 | - Host your own parking space and get paid for it. 39 | - Easy check-in to the spot after pulling in. 40 | - Be charged on hourly basis for the use of the parking space. 41 | - User authentication. 42 | 43 | 44 | ------------------------------------------ 45 | ## Demo ## 46 | Sign Up/Sign In 47 | 48 | 49 | 50 |
51 | 52 |
53 | 54 |
55 | 56 | 57 |
58 | 59 | 60 |
61 | 62 | 63 |
64 | 65 | 66 |
67 | 68 | 69 |
70 | 71 | 72 | 73 | 74 | 75 | 76 | ------------------------------------------ 77 | 78 | ## How To Use 79 | #### Software Requirements 80 | VSCode or Android Studio 81 | 82 | ## Installation 83 | Install the dependencies by running: 84 | ```html 85 | npm install 86 | ``` 87 | ```html 88 | flutter pub get 89 | ``` 90 | 91 | 92 | #### Run using Command Prompt 93 | ```html 94 | node start 95 | ``` 96 | 97 | ```html 98 | flutter run 99 | ``` 100 | 101 | --- 102 | ### Tech stack 103 | 104 | `Frontend` : Flutter
105 | `Backend` : Nodejs
106 | `Database` : MongoDB
107 | 108 | ------------------------------------------ 109 | 110 |

Developed by Deepanshu Vangani , Parth Shah , Sakshi Shelar and Hiral Sheth

111 | 112 | 113 | 114 | 115 | 116 | ! 117 | -------------------------------------------------------------------------------- /parking_locator/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /parking_locator/lib/screens/confirm_booking.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:parking_locator/services/dbservice.dart'; 3 | import 'package:parking_locator/widgets/drawer.dart'; 4 | 5 | import 'package:parking_locator/constants.dart'; 6 | 7 | class ConfirmBooking extends StatefulWidget { 8 | final String carImage; 9 | final String bookingId; 10 | final String slotID; 11 | 12 | ConfirmBooking({this.slotID, this.carImage, this.bookingId}); 13 | @override 14 | _ConfirmBookingState createState() => _ConfirmBookingState(); 15 | } 16 | 17 | class _ConfirmBookingState extends State { 18 | @override 19 | Widget build(BuildContext context) { 20 | var height = MediaQuery.of(context).size.height; 21 | var width = MediaQuery.of(context).size.width; 22 | DbBookingMethods _dbmethod = DbBookingMethods(); 23 | void _submit() async { 24 | var obj = await _dbmethod.confirmBook(widget.slotID, widget.bookingId); 25 | print(obj); 26 | if (obj["status"] == "SUCCESS") { 27 | Navigator.of(context).pushNamed('/my_booking'); 28 | // Navigator.push( 29 | // context, 30 | // MaterialPageRoute( 31 | // builder: (context) => ConfirmBooking(obj["carImage"])), 32 | // ); 33 | } 34 | } 35 | 36 | return Scaffold( 37 | appBar: AppBar( 38 | backgroundColor: Constants.secColor, 39 | title: Text("ParkMe"), 40 | 41 | ), 42 | 43 | body: Center( 44 | child: Container( 45 | child: Card( 46 | elevation: 10.0, 47 | shape: RoundedRectangleBorder( 48 | borderRadius: BorderRadius.all( 49 | Radius.circular(25), 50 | ), 51 | // side: BorderSide(width: 1, color: Colors.green), 52 | ), 53 | margin: EdgeInsets.all(10), 54 | child: Column( 55 | crossAxisAlignment: CrossAxisAlignment.stretch, 56 | children: [ 57 | ClipRRect( 58 | borderRadius: BorderRadius.all(Radius.circular(10)), 59 | child: Image.network( 60 | widget.carImage, 61 | height: height * 0.65, 62 | width: width * 0.7, 63 | fit: BoxFit.cover, 64 | ), 65 | ), 66 | SizedBox( 67 | height: height * 0.05, 68 | ), 69 | Center( 70 | child: ElevatedButton( 71 | style: ElevatedButton.styleFrom( 72 | shape: new RoundedRectangleBorder( 73 | borderRadius: new BorderRadius.circular(20.0), 74 | ), 75 | //primary: kMainColor 76 | ), 77 | onPressed: () { 78 | _submit(); 79 | }, 80 | child: Padding( 81 | padding: const EdgeInsets.all(18.0), 82 | child: Text( 83 | 'Confirm Booking', 84 | style: TextStyle( 85 | fontSize: 18, color: Colors.white), 86 | ), 87 | ), 88 | ), 89 | ), 90 | ]))))); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /parking-locator-car-detector-model/static/js/index.js: -------------------------------------------------------------------------------- 1 | $(".upload").click(function (e) { 2 | $("#uploader").click(); 3 | }); 4 | 5 | var uploadedFiles = []; 6 | var cameraStream = null; 7 | 8 | $("#uploader").change(function (event) { 9 | const files = event.target.files; 10 | if (files && files.length > 0 && FileReader) { 11 | const file = event.target.files[0]; 12 | var fr = new FileReader(); 13 | fr.onload = function () { 14 | uploadedFiles = [file]; 15 | $(".fileDisplay img").prop("src", fr.result); 16 | $(".fileDisplay h3").hide(); 17 | $(".iscar h1").text(""); 18 | $(".predict").removeAttr("disabled"); 19 | }; 20 | fr.readAsDataURL(file); 21 | } 22 | }); 23 | 24 | $(".predict").click(function (e) { 25 | console.log("here"); 26 | var fd = new FormData(); 27 | var dataURI = snapshot.firstChild.getAttribute("src"); 28 | var imageData = dataURItoBlob(dataURI); 29 | fd.append("files[]", imageData, "myImage"); 30 | $(".predict").text("loading"); 31 | $(".predict").prop("disabled", "true"); 32 | $.ajax({ 33 | method: "POST", 34 | data: fd, 35 | processData: false, 36 | contentType: false, 37 | cache: false, 38 | url: "/predict/", 39 | success: function (data) { 40 | console.log($(this)); 41 | const res = data[0]; 42 | $(".predict").text("Predict"); 43 | $(".predict").removeAttr("disabled"); 44 | $(".iscar h1").text( 45 | res.isCar ? `Car Present. (${res.confidence * 100}%)` : `No car Present. (${100 - res.confidence * 100}%)` 46 | ); 47 | }, 48 | }); 49 | }); 50 | var camera = document.getElementById("camera"); 51 | 52 | window.addEventListener( 53 | "load", 54 | function () { 55 | var constraints = { video: true }; 56 | 57 | function success(stream) { 58 | cameraStream = stream; 59 | camera.srcObject = stream; 60 | var playPromise = camera.play(); 61 | if (playPromise !== undefined) { 62 | playPromise 63 | .then(function () { 64 | setInterval(function () { 65 | captureSnapshot(); 66 | }, 1000); 67 | }) 68 | .catch(function (error) { 69 | console.error(error); 70 | }); 71 | } 72 | } 73 | 74 | function failure(error) { 75 | alert(JSON.stringify(error)); 76 | } 77 | 78 | if (navigator.getUserMedia) navigator.getUserMedia(constraints, success, failure); 79 | else alert("Your browser does not support getUserMedia()"); 80 | }, 81 | false 82 | ); 83 | function sendToServer() { 84 | var fd = new FormData(); 85 | var dataURI = snapshot.firstChild.getAttribute("src"); 86 | var imageData = dataURItoBlob(dataURI); 87 | fd.append("files[]", imageData, "myImage"); 88 | 89 | $.ajax({ 90 | method: "POST", 91 | data: fd, 92 | processData: false, 93 | contentType: false, 94 | cache: false, 95 | url: "/predict/", 96 | success: function (data) { 97 | console.log($(this)); 98 | const res = data[0]; 99 | 100 | $(".iscar h1").text( 101 | res.isCar ? `Car Present. (${res.confidence * 100}%)` : `No car Present. (${100 - res.confidence * 100}%)` 102 | ); 103 | }, 104 | }); 105 | } 106 | 107 | var capture = document.getElementById("capture"); 108 | 109 | function captureSnapshot() { 110 | if (null != cameraStream) { 111 | var ctx = capture.getContext("2d"); 112 | var img = new Image(); 113 | 114 | ctx.drawImage(camera, 0, 0, capture.width, capture.height); 115 | 116 | img.src = capture.toDataURL("image/png"); 117 | img.width = 240; 118 | 119 | snapshot.innerHTML = ""; 120 | 121 | snapshot.appendChild(img); 122 | sendToServer(); 123 | } 124 | } 125 | 126 | function dataURItoBlob(dataURI) { 127 | var byteString = atob(dataURI.split(",")[1]); 128 | var mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0]; 129 | 130 | var buffer = new ArrayBuffer(byteString.length); 131 | var data = new DataView(buffer); 132 | 133 | for (var i = 0; i < byteString.length; i++) { 134 | data.setUint8(i, byteString.charCodeAt(i)); 135 | } 136 | 137 | return new Blob([buffer], { type: mimeString }); 138 | } 139 | -------------------------------------------------------------------------------- /parking_locator/lib/screens/authentication/auth2.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:google_fonts/google_fonts.dart'; 3 | import 'package:parking_locator/screens/authentication/login.dart'; 4 | import 'package:parking_locator/screens/authentication/login_option.dart'; 5 | import 'package:parking_locator/screens/authentication/signup.dart'; 6 | import 'package:parking_locator/screens/authentication/signup_option.dart'; 7 | import 'package:parking_locator/constants.dart'; 8 | 9 | 10 | class HomePage extends StatefulWidget { 11 | @override 12 | _HomePageState createState() => _HomePageState(); 13 | } 14 | 15 | class _HomePageState extends State { 16 | 17 | bool login = true; 18 | static const mainColor = Constants.mainColor; 19 | static const secColor = Constants.secColor; 20 | 21 | @override 22 | Widget build(BuildContext context) { 23 | return Scaffold( 24 | backgroundColor: secColor,//Color(0xFF1C1C1C), 25 | body: SingleChildScrollView( 26 | child: Column( 27 | crossAxisAlignment: CrossAxisAlignment.stretch, 28 | mainAxisAlignment: MainAxisAlignment.center, 29 | children: [ 30 | 31 | GestureDetector( 32 | onTap: () { 33 | setState(() { 34 | login = true; 35 | }); 36 | }, 37 | child: AnimatedContainer( 38 | duration: Duration(milliseconds: 500), 39 | curve: Curves.ease, 40 | height: login ? MediaQuery.of(context).size.height * 0.6 : MediaQuery.of(context).size.height * 0.4, 41 | child: CustomPaint( 42 | painter: CurvePainter(login), 43 | child: Container( 44 | padding: EdgeInsets.only(bottom: login ? 0 : 55), 45 | child: Center( 46 | child: SingleChildScrollView( 47 | child: Padding( 48 | padding: EdgeInsets.symmetric(horizontal: 32, vertical: 16), 49 | child: login 50 | ? Login() 51 | : LoginOption(), 52 | ), 53 | ), 54 | ), 55 | ), 56 | ), 57 | ), 58 | ), 59 | 60 | GestureDetector( 61 | onTap: () { 62 | setState(() { 63 | login = false; 64 | }); 65 | }, 66 | child: AnimatedContainer( 67 | duration: Duration(milliseconds: 500), 68 | curve: Curves.ease, 69 | height: login ? MediaQuery.of(context).size.height * 0.4 : MediaQuery.of(context).size.height * 0.6, 70 | child: Container( 71 | color: Colors.transparent, 72 | padding: EdgeInsets.only(top: login ? 55 : 0), 73 | child: Center( 74 | child: SingleChildScrollView( 75 | child: Padding( 76 | padding: EdgeInsets.symmetric(horizontal: 32, vertical: 16), 77 | child: !login 78 | ? SignUp() 79 | : SignUpOption(), 80 | ), 81 | ), 82 | ) 83 | ), 84 | ), 85 | ), 86 | 87 | ], 88 | ), 89 | ), 90 | ); 91 | } 92 | } 93 | 94 | class CurvePainter extends CustomPainter { 95 | static const mainColor = Constants.mainColor; 96 | static const secColor = Constants.secColor; 97 | static const backgroundColor = Constants.mainColor; 98 | bool outterCurve; 99 | 100 | CurvePainter(this.outterCurve); 101 | 102 | @override 103 | void paint(Canvas canvas, Size size) { 104 | var paint = Paint(); 105 | paint.color = mainColor; 106 | paint.style = PaintingStyle.fill; 107 | 108 | Path path = Path(); 109 | path.moveTo(0, 0); 110 | path.lineTo(0, size.height); 111 | path.quadraticBezierTo(size.width * 0.5, outterCurve ? size.height + 110 : size.height - 110, size.width, size.height); 112 | path.lineTo(size.width, 0); 113 | path.close(); 114 | 115 | canvas.drawPath(path, paint); 116 | } 117 | 118 | @override 119 | bool shouldRepaint(CustomPainter oldDelegate) => false; 120 | } -------------------------------------------------------------------------------- /parking-locator-backend/src/routes/booking.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const ParkingLocations = require("../database/models/parkingLocations"); 3 | const ParkingHistory = require("../database/models/ParkingHistory"); 4 | const moment = require("moment"); 5 | const getDistanceFromLatLonInKm = require("../helpers/mapDistance"); 6 | const router = express.Router(); 7 | const {TIME_FORMAT}=require('../config'); 8 | 9 | router.get("/", async (req, res) => { 10 | res.send("booking service"); 11 | }); 12 | 13 | router.post("/checkin", async (req, res) => { 14 | console.log(req.body); 15 | console.log(req.user); 16 | const { userID } = req.user; 17 | const { spotID, lat, long,isEmpty } = req.body; 18 | 19 | const imageIfFull = "https://martolex-book-images.s3.ap-south-1.amazonaws.com/car-1.jpeg"; 20 | try { 21 | console.log("lets tryy"); 22 | const parkingSpot = await ParkingLocations.findOne({ slotID: spotID }); 23 | if (parkingSpot) { 24 | console.log(parkingSpot); 25 | if (parkingSpot.isEmpty) { 26 | const parkingLocation = parkingSpot.Location.coordinates; 27 | const distance = getDistanceFromLatLonInKm(parkingLocation[0], parkingLocation[1], lat, long); 28 | if (distance < 100) { 29 | if (isEmpty === "false") { 30 | const parkingHistory = await ParkingHistory.create({ userID, slotID: spotID }); 31 | res.json({ STATUS: "SUCCESS", carImage: imageIfFull, bookingID: parkingHistory._id }); 32 | } else { 33 | res.json({ status: "FAILED", message: "NO car is present in the slot" }); 34 | } 35 | } else { 36 | res.json({ status: "FAILED", message: "You are too far away from the parking" }); 37 | } 38 | } else { 39 | res.json({ status: "FAILED", message: "Slot is not empty" }); 40 | } 41 | } else { 42 | res.json({ status: "FAILED", message: "Slot not found" }); 43 | } 44 | 45 | } catch (error) { 46 | res.status(500).send({ message: error.message, errorType: error.name }); 47 | } 48 | }); 49 | 50 | router.post("/bookPrior", async (req, res) => { 51 | try { 52 | const { spotID, startTime, duration } = req.body; 53 | console.log(startTime); 54 | const { userID } = req.user; 55 | const parkingSpot = await ParkingLocations.findOne({ slotID: spotID }); 56 | if (parkingSpot) { 57 | const startTimeObj = moment(startTime,TIME_FORMAT); 58 | const endTime = startTimeObj.clone().add(duration, "hours"); 59 | const startTimeMinutesSinceDayStart = startTimeObj.diff(startTimeObj.clone().startOf("day"), "minutes"); 60 | console.log(parkingSpot.activeHours.start, startTimeMinutesSinceDayStart,); 61 | if ( 62 | parkingSpot.activeHours.start <= startTimeMinutesSinceDayStart && 63 | parkingSpot.activeHours.end > startTimeMinutesSinceDayStart + 60 * duration 64 | ) { 65 | const booking = await ParkingHistory.create({ 66 | userID, 67 | slotID: spotID, 68 | advancedBooking: true, 69 | estimatedStartTime: startTimeObj.toDate(), 70 | estimatedEndTime: endTime.toDate(), 71 | isConfirmed: true, 72 | }); 73 | res.json({ status: "SUCCESS", bookingDetails: booking }); 74 | } else { 75 | res.json({ status: "FAILED", message: "cannot book for this time duration." }); 76 | } 77 | } else { 78 | res.json({ status: "FAILED", message: "Slot not found" }); 79 | } 80 | } catch (err) { 81 | res.status(500).send({ message: err.message, errorType: err.name }); 82 | } 83 | }); 84 | 85 | router.post("/checkin/verify", async (req, res) => { 86 | const { userID } = req.user; 87 | const { spotID, bookingID } = req.body; 88 | try { 89 | const booking = await ParkingHistory.findOne({ slotID: spotID, userID, _id: bookingID }); 90 | if (booking) { 91 | booking.isConfirmed = true; 92 | booking.startTime = new Date(); 93 | await booking.save(); 94 | await ParkingLocations.findOneAndUpdate({ spotID }, { $set: { isEmpty: false } }); 95 | res.json({ status: "SUCCESS", bookingDetails: booking }); 96 | } else { 97 | res.json({ status: "FAILED", message: "invali details" }); 98 | } 99 | } catch (error) { 100 | res.status(500).send({ message: error.message, errorType: error.name }); 101 | } 102 | }); 103 | 104 | router.post("/checkout", async (req, res) => { 105 | const { userID } = req.user; 106 | const { spotID } = req.body; 107 | try { 108 | const booking = await ParkingHistory.findOne({ 109 | userID, 110 | slotID: spotID, 111 | isConfirmed: true, 112 | endTime: { $exists: false }, 113 | duration: { $exists: false }, 114 | }); 115 | 116 | if (booking) { 117 | booking.endTime = new Date(); 118 | booking.duration = Math.max(1, moment().diff(booking.startTime, "hours")); 119 | await booking.save(); 120 | await ParkingLocations.findOneAndUpdate({ spotID }, { $set: { isEmpty: true } }); 121 | res.json({ status: "SUCCESS", message: "checked Out", billedPeriod: booking.duration }); 122 | } else { 123 | res.json({ status: "FAILED", message: "no such booking" }); 124 | } 125 | } catch (error) { 126 | res.status(500).send({ message: error.message, errorType: error.name }); 127 | } 128 | }); 129 | 130 | module.exports = router; 131 | -------------------------------------------------------------------------------- /parking_locator/lib/screens/mySpots.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:parking_locator/services/dbservice.dart'; 3 | import 'package:parking_locator/screens/slotdetails.dart'; 4 | import 'package:parking_locator/constants.dart'; 5 | 6 | 7 | class MySpots extends StatefulWidget { 8 | @override 9 | _MySpotsState createState() => _MySpotsState(); 10 | } 11 | 12 | class _MySpotsState extends State { 13 | final db_methods = DbMethods(); 14 | List spots; 15 | 16 | void getspots() async { 17 | List spots1; 18 | spots1 = await db_methods.mySpots(); 19 | setState(() { 20 | spots = spots1; 21 | }); 22 | } 23 | 24 | @override 25 | void initState() { 26 | getspots(); 27 | } 28 | 29 | @override 30 | Widget build(BuildContext context) { 31 | final height = MediaQuery.of(context).size.height; 32 | final width = MediaQuery.of(context).size.width; 33 | return Scaffold( 34 | appBar: AppBar( 35 | backgroundColor: Constants.secColor, 36 | title: Text('My Parking Spots'), 37 | ), 38 | body: Column( 39 | children: [ 40 | // Text(spots[1]['address']), 41 | Expanded( 42 | child: (spots != null) 43 | ? ListView.builder( 44 | itemCount: spots.length, 45 | itemBuilder: (context, index) { 46 | return Container( 47 | child: Card( 48 | shape: RoundedRectangleBorder( 49 | borderRadius: BorderRadius.circular(15.0), 50 | ), 51 | color: Colors.white, 52 | elevation: 7, 53 | child: InkWell( 54 | borderRadius: BorderRadius.circular(15.0), 55 | onTap: () { 56 | Navigator.push( 57 | context, 58 | MaterialPageRoute( 59 | builder: (context) => SlotDetails( 60 | spotID: spots[index]['slotID']), 61 | ), 62 | ); 63 | }, 64 | child: Container( 65 | child: Column( 66 | children: [ 67 | // Column( 68 | // crossAxisAlignment: CrossAxisAlignment.start, 69 | // children: [ 70 | // Text(spots[index]['address']), 71 | // Text("Start time: " + 72 | // spots[index]['activeHours']['start']), 73 | // Text("End time: " + 74 | // spots[index]['activeHours']['end']), 75 | // Row( 76 | // children: [ 77 | // Text("Parking Type: " + 78 | // spots[index]['parkingType']), 79 | // SizedBox( 80 | // width: width * 2 / 5, 81 | // ), 82 | // Text("Charges: " + 83 | // (spots[index]['chargesPerHour']) 84 | // .toString()), 85 | // ], 86 | // ), 87 | // ], 88 | // ) 89 | ListTile( 90 | isThreeLine: true, 91 | title: Text(spots[index]['address']), 92 | subtitle: Text("Start time: " + 93 | spots[index]['activeHours'] 94 | ['start'] + 95 | "\nEnd time: " + 96 | spots[index]['activeHours']['end'] + 97 | "\nParking Type: " + 98 | spots[index]['parkingType'] + 99 | " Charges: " + 100 | (spots[index]['chargesPerHour']) 101 | .toString()), 102 | ) 103 | ], 104 | ), 105 | )), 106 | ), 107 | ); 108 | }) 109 | : Center( 110 | child: Text('No Parking Spot Found'), 111 | )), 112 | ], 113 | ), 114 | ); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /parking_locator/lib/screens/authentication/signup.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:parking_locator/services/auth_service.dart'; 3 | import 'package:parking_locator/widgets/form_input.dart'; 4 | 5 | import 'package:parking_locator/constants.dart'; 6 | 7 | 8 | 9 | class SignUp extends StatefulWidget { 10 | @override 11 | _SignUpState createState() => _SignUpState(); 12 | } 13 | 14 | class _SignUpState extends State { 15 | static const mainColor = Constants.mainColor; 16 | static const secColor = Constants.secColor; 17 | static const backgroundColor = Constants.mainColor; 18 | AuthMethods _authMethods = AuthMethods(); 19 | 20 | Future _alertDialogBuilder(String error) async { 21 | return showDialog( 22 | context: context, 23 | barrierDismissible: false, 24 | builder: (context) { 25 | return AlertDialog( 26 | title: Text("Error"), 27 | content: Container( 28 | child: Text(error), 29 | ), 30 | actions: [ 31 | FlatButton( 32 | child: Text("Close Dialog"), 33 | onPressed: () { 34 | Navigator.pop(context); 35 | }, 36 | ) 37 | ], 38 | ); 39 | }); 40 | } 41 | 42 | Future createUser() async { 43 | 44 | 45 | // Call the user's CollectionReference to add a new user 46 | await _authMethods.signup(_registerName,_registerEmail,_registerPhone,_registerPassword) 47 | .then((value) => Navigator.pushReplacementNamed(context, '/search')) 48 | .catchError((error) => print("Failed to add user: $error")); 49 | return "xyz"; 50 | } 51 | 52 | void _submitForm() async { 53 | setState(() { 54 | _registerFormLoading = true; 55 | }); 56 | 57 | String _createAccountFeedback = await createUser(); 58 | 59 | if (_createAccountFeedback != null) { 60 | _alertDialogBuilder(_createAccountFeedback); 61 | 62 | setState(() { 63 | _registerFormLoading = false; 64 | }); 65 | } else { 66 | Navigator.pop(context); 67 | } 68 | } 69 | 70 | bool _registerFormLoading = false; 71 | String _registerEmail = ""; 72 | String _registerName = ""; 73 | String _registerPassword = ""; 74 | String _registerPhone = ""; 75 | 76 | 77 | 78 | @override 79 | Widget build(BuildContext context) { 80 | return Column( 81 | crossAxisAlignment: CrossAxisAlignment.stretch, 82 | mainAxisAlignment: MainAxisAlignment.center, 83 | children: [ 84 | Text( 85 | "Sign up with", 86 | style: TextStyle( 87 | fontSize: 16, 88 | color: mainColor, 89 | height: 2, 90 | ), 91 | ), 92 | Text( 93 | "ParkMe", 94 | style: TextStyle( 95 | fontSize: 36, 96 | fontWeight: FontWeight.bold, 97 | color: mainColor, 98 | letterSpacing: 2, 99 | height: 1, 100 | ), 101 | ), 102 | SizedBox( 103 | height: 16, 104 | ), 105 | Input(str:"Name", 106 | onChanged: (value) { 107 | _registerName = value; 108 | }, 109 | type:TextInputType.text, 110 | isPassword: false, 111 | ), 112 | SizedBox( 113 | height: 16, 114 | ), 115 | Input(str:"Email", 116 | onChanged: (value) { 117 | _registerEmail = value; 118 | }, 119 | type:TextInputType.text, 120 | isPassword: false, 121 | ), 122 | SizedBox( 123 | height: 16, 124 | ), 125 | Input(str:"Phone", 126 | onChanged: (value) { 127 | _registerPhone = value; 128 | }, 129 | type:TextInputType.phone, 130 | isPassword: false, 131 | ), 132 | SizedBox( 133 | height: 16, 134 | ), 135 | Input(str:"Password", 136 | onChanged: (value) { 137 | _registerPassword = value; 138 | }, 139 | type:TextInputType.visiblePassword, 140 | isPassword: true, 141 | ), 142 | SizedBox( 143 | height: 16, 144 | ), 145 | InkWell( 146 | child: Container( 147 | 148 | height: 40, 149 | decoration: BoxDecoration( 150 | color: mainColor, 151 | borderRadius: BorderRadius.all( 152 | Radius.circular(25), 153 | ), 154 | boxShadow: [ 155 | BoxShadow( 156 | color: mainColor, 157 | spreadRadius: 3, 158 | blurRadius: 3, 159 | offset: Offset(0, 3), 160 | ), 161 | ], 162 | ), 163 | child: Center( 164 | child: Text( 165 | "SIGN UP", 166 | style: TextStyle( 167 | fontSize: 24, 168 | fontWeight: FontWeight.bold, 169 | color: secColor, 170 | ), 171 | ), 172 | ), 173 | ), 174 | onTap: () { 175 | _submitForm(); 176 | }, 177 | //isLoading: _registerFormLoading, 178 | ), 179 | SizedBox( 180 | height: 24, 181 | ), 182 | ], 183 | ); 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /parking-locator-backend/src/routes/user.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const ParkingHistory = require("../database/models/ParkingHistory"); 3 | const ParkingLocations = require("../database/models/parkingLocations"); 4 | const moment = require("moment"); 5 | const { TIME_FORMAT } = require("../config"); 6 | 7 | const router = express.Router(); 8 | 9 | router.get("/", (req, res) => { 10 | res.send("user service"); 11 | }); 12 | 13 | router.post("/myParking", async (req, res) => { 14 | try { 15 | const { lat, long, startTime, endTime, address, parkingType, chargesPerHour } = req.body; 16 | const { userID } = req.user; 17 | const startTimeObj = moment(startTime, TIME_FORMAT); 18 | console.log(req.body); 19 | const endTimeObj = moment(endTime, TIME_FORMAT); 20 | console.log(endTime); 21 | const startOfDay = moment().startOf("day"); 22 | console.log(address); 23 | const parking = await ParkingLocations.create({ 24 | userID, 25 | Location: { type: "Point", coordinates: [lat, long] }, 26 | activeHours: { 27 | start: startTimeObj.diff(startOfDay, "minutes"), 28 | end: endTimeObj.diff(startOfDay, "minutes"), 29 | }, 30 | address, 31 | parkingType, 32 | chargesPerHour, 33 | }); 34 | 35 | res.json({ status: "SUCCESS", parking }); 36 | } catch (error) { 37 | res.status(500).send({ message: error.message, errorType: error.name }); 38 | } 39 | }); 40 | 41 | router.post("/myParking/:spotID/setActiveHours", async (req, res) => { 42 | const { userID } = req.user; 43 | const { spotID } = req.params; 44 | const { startTime, endTime } = req.body; 45 | console.log(spotID, userID); 46 | try { 47 | const parking = await ParkingLocations.findOne({ slotID: spotID, userID }); 48 | if (parking) { 49 | const startTimeObj = moment(startTime, TIME_FORMAT); 50 | const endTimeObj = moment(endTime, TIME_FORMAT); 51 | if (startTimeObj.isAfter(endTimeObj)) { 52 | res.json({ status: "FAILED", message: "invalid start and end times" }); 53 | return; 54 | } 55 | const isCurrentTimeSlot = moment().isBetween(startTimeObj, endTimeObj); 56 | if (parking.isEmpty || !isCurrentTimeSlot) { 57 | const startOfDay = moment().startOf("day"); 58 | parking.activeHours = { 59 | start: startTimeObj.diff(startOfDay, "minutes"), 60 | end: endTimeObj.diff(startOfDay, "minutes"), 61 | }; 62 | await parking.save(); 63 | res.json({ status: "SUCCESS", parking }); 64 | } else { 65 | res.json({ status: "FAILED", message: "Cannot modify at the moment" }); 66 | } 67 | } else { 68 | res.json({ status: "FAILED", message: "parking not found" }); 69 | } 70 | } catch (error) { 71 | res.status(500).send({ message: error.message, errorType: error.name }); 72 | } 73 | }); 74 | 75 | router.get("/myParking", async (req, res) => { 76 | try { 77 | const { userID } = req.user; 78 | const parkings = await ParkingLocations.find({ userID }); 79 | const parkingsRes = parkings.map((parking) => { 80 | const startTime = moment().startOf("day").add(parking.activeHours.start, "minutes").format(TIME_FORMAT); 81 | const endTime = moment().startOf("day").add(parking.activeHours.end, "minutes").format(TIME_FORMAT); 82 | const parkingJSON = parking.toJSON(); 83 | return { ...parkingJSON, activeHours: { start: startTime, end: endTime } }; 84 | }); 85 | res.json({ status: "SUCCESS", parkings: parkingsRes }); 86 | } catch (error) { 87 | res.status(500).send({ message: error.message, errorType: error.name }); 88 | } 89 | }); 90 | 91 | router.get("/myParking/bookings", async (req, res) => { 92 | try { 93 | const { spotID } = req.query; 94 | const bookings = await ParkingHistory.aggregate([ 95 | { $match: { slotID: spotID, isConfirmed: true } }, 96 | { $lookup: { from: "users", localField: "userID", foreignField: "userID", as: "user" } }, 97 | { $unwind: { path: "$user" } }, 98 | { $project: { "user.password": 0, "user.mobile": 0, "user.walletBalance": 0 } }, 99 | ]); 100 | if (bookings) { 101 | res.json({ status: "SUCCESS", bookings }); 102 | } else { 103 | res.json({ status: "NOTFOUND", message: "Could not find the requested slot" }); 104 | } 105 | } catch (error) { 106 | res.status(500).send({ message: error.message, errorType: error.name }); 107 | } 108 | }); 109 | 110 | router.get("/myParking/:spotID", async (req, res) => { 111 | try { 112 | const { spotID } = req.params; 113 | const { userID } = req.user; 114 | let parking = await ParkingLocations.findOne({ slotID: spotID, userID }); 115 | if (parking) { 116 | parking = parking.toJSON(); 117 | 118 | parking.activeHours.start = moment().startOf("day").add(parking.activeHours.start, "minutes").format(TIME_FORMAT); 119 | parking.activeHours.end = moment().startOf("day").add(parking.activeHours.end, "minutes").format(TIME_FORMAT); 120 | res.json({ status: "SUCCESS", parking }); 121 | } else { 122 | res.json({ status: "NOTFOUND", message: "Could not find the requested spot" }); 123 | } 124 | } catch (error) { 125 | res.status(500).send({ message: error.message, errorType: error.name }); 126 | } 127 | }); 128 | 129 | router.delete("/myParking", async (req, res) => { 130 | const { userID } = req.user; 131 | const { spotID } = req.body; 132 | try { 133 | const parking = await ParkingLocations.findOne({ userID, slotID: spotID }); 134 | if (parking) { 135 | await ParkingLocations.findOneAndDelete({ userID, slotID: spotID }); 136 | res.json({ status: "SUCCESS", message: "deleted" }); 137 | } else { 138 | res.json({ status: "NOTFOUND", message: "Could not find the requested spot" }); 139 | } 140 | } catch (error) { 141 | res.status(500).send({ message: error.message, errorType: error.name }); 142 | } 143 | }); 144 | 145 | router.get("/bookings", async (req, res) => { 146 | const { userID } = req.user; 147 | console.log(userID); 148 | try { 149 | const bookings = await ParkingHistory.aggregate([ 150 | { $match: { userID } }, 151 | { 152 | $lookup: { 153 | from: "parkinglocations", 154 | localField: "slotID", 155 | foreignField: "slotID", 156 | as: "parkingLocation", 157 | }, 158 | }, 159 | { 160 | $unwind: { 161 | path: "$parkingLocation", 162 | }, 163 | }, 164 | ]); 165 | res.json({ status: "SUCCESS", bookings }); 166 | } catch (error) { 167 | res.status(500).send({ message: error.message, errorType: error.name }); 168 | } 169 | }); 170 | 171 | router.get("/bookings/active", async (req, res) => { 172 | const { userID } = req.user; 173 | try { 174 | const bookings = await ParkingHistory.find({ userID,endTime:undefined }); 175 | res.json({ status: "SUCCESS", bookings }); 176 | } catch (error) { 177 | res.status(500).send({ message: error.message, errorType: error.name }); 178 | } 179 | }); 180 | 181 | module.exports = router; 182 | -------------------------------------------------------------------------------- /parking_locator/lib/screens/authentication/login.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:parking_locator/services/auth_service.dart'; 3 | import 'package:parking_locator/constants.dart'; 4 | 5 | 6 | // import 'package:firebase_auth/firebase_auth.dart'; 7 | class Login extends StatefulWidget { 8 | @override 9 | _LoginState createState() => _LoginState(); 10 | } 11 | 12 | class _LoginState extends State { 13 | static const mainColor = Constants.mainColor; 14 | static const secColor = Constants.secColor; 15 | static const backgroundColor = Constants.mainColor; 16 | 17 | final TextEditingController _controller = TextEditingController(); 18 | Future _alertDialogBuilder(String error) async { 19 | return showDialog( 20 | context: context, 21 | barrierDismissible: false, 22 | builder: (context) { 23 | return AlertDialog( 24 | title: Text("Error"), 25 | content: Container( 26 | child: Text(error), 27 | ), 28 | actions: [ 29 | FlatButton( 30 | child: Text("Close Dialog"), 31 | onPressed: () { 32 | Navigator.pop(context); 33 | }, 34 | ) 35 | ], 36 | ); 37 | }); 38 | } 39 | AuthMethods _authMethods = AuthMethods(); 40 | 41 | Future _loginAccount() async { 42 | // Call the user's CollectionReference to add a new user 43 | await _authMethods 44 | .signin( 45 | _loginEmail, _loginPassword) 46 | .then((value) => Navigator.pushReplacementNamed(context, '/search')) 47 | .catchError((error) => print("Failed to add user: $error")); 48 | return "Icorrect Password!"; 49 | } 50 | 51 | void _submitForm() async { 52 | setState(() { 53 | _loginFormLoading = true; 54 | }); 55 | 56 | String _loginFeedback = await _loginAccount(); 57 | 58 | if (_loginFeedback != null) { 59 | _alertDialogBuilder(_loginFeedback); 60 | 61 | setState(() { 62 | print("hi"); 63 | _loginFormLoading = false; 64 | }); 65 | } else { 66 | Navigator.pop(context); 67 | } 68 | } 69 | 70 | bool _loginFormLoading = false; 71 | String _loginEmail = ""; 72 | String _loginPassword = ""; 73 | 74 | FocusNode _passwordFocusNode; 75 | 76 | @override 77 | void initState() { 78 | _passwordFocusNode = FocusNode(); 79 | super.initState(); 80 | } 81 | 82 | @override 83 | void dispose() { 84 | _passwordFocusNode.dispose(); 85 | super.dispose(); 86 | } 87 | 88 | @override 89 | Widget build(BuildContext context) { 90 | return Column( 91 | crossAxisAlignment: CrossAxisAlignment.stretch, 92 | mainAxisAlignment: MainAxisAlignment.center, 93 | children: [ 94 | Text( 95 | "Welcome to", 96 | style: TextStyle( 97 | fontSize: 16, 98 | color: secColor, 99 | height: 2, 100 | ), 101 | ), 102 | Text( 103 | "ParkMe", 104 | style: TextStyle( 105 | fontSize: 36, 106 | fontWeight: FontWeight.bold, 107 | color: secColor, 108 | letterSpacing: 2, 109 | height: 1, 110 | ), 111 | ), 112 | SizedBox( 113 | height: 10.0, 114 | ), 115 | Text( 116 | "Please login to continue", 117 | style: TextStyle( 118 | fontSize: 16, 119 | color: Color(0xFF1C1C1C), 120 | height: 1, 121 | ), 122 | ), 123 | SizedBox( 124 | height: 16, 125 | ), 126 | TextField( 127 | onChanged: (value) { 128 | _loginEmail = value; 129 | }, 130 | onSubmitted: (value) { 131 | _passwordFocusNode.requestFocus(); 132 | }, 133 | textInputAction: TextInputAction.next, 134 | // controller: _controller, 135 | decoration: InputDecoration( 136 | hintText: 'Email / Username', 137 | hintStyle: TextStyle( 138 | fontSize: 16, 139 | color: secColor, 140 | fontWeight: FontWeight.bold, 141 | ), 142 | border: OutlineInputBorder( 143 | borderRadius: BorderRadius.circular(25), 144 | borderSide: BorderSide( 145 | width: 0, 146 | style: BorderStyle.none, 147 | ), 148 | ), 149 | filled: true, 150 | fillColor: Colors.black12, 151 | contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 0), 152 | ), 153 | ), 154 | SizedBox( 155 | height: 16, 156 | ), 157 | TextField( 158 | obscureText: true, 159 | onChanged: (value) { 160 | _loginPassword = value; 161 | }, 162 | focusNode: _passwordFocusNode, 163 | //isPasswordField: true, 164 | onSubmitted: (value) { 165 | _submitForm(); 166 | }, 167 | decoration: InputDecoration( 168 | hintText: 'Password', 169 | hintStyle: TextStyle( 170 | fontSize: 16, 171 | color: secColor, 172 | fontWeight: FontWeight.bold, 173 | ), 174 | border: OutlineInputBorder( 175 | borderRadius: BorderRadius.circular(25), 176 | borderSide: BorderSide( 177 | width: 0, 178 | style: BorderStyle.none, 179 | ), 180 | ), 181 | filled: true, 182 | fillColor: Colors.black12, 183 | contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 0), 184 | ), 185 | ), 186 | SizedBox( 187 | height: 24, 188 | ), 189 | InkWell( 190 | child: Container( 191 | height: 40, 192 | decoration: BoxDecoration( 193 | color: secColor, 194 | borderRadius: BorderRadius.all( 195 | Radius.circular(25), 196 | ), 197 | boxShadow: [ 198 | BoxShadow( 199 | color: Color(0xFF041E42).withOpacity(0.2), 200 | spreadRadius: 3, 201 | blurRadius: 4, 202 | offset: Offset(0, 3), 203 | ), 204 | ], 205 | ), 206 | child: Center( 207 | child: Text( 208 | "LOGIN", 209 | style: TextStyle( 210 | fontSize: 24, 211 | fontWeight: FontWeight.bold, 212 | color: mainColor, 213 | ), 214 | ), 215 | ), 216 | ), 217 | onTap: () { 218 | _submitForm(); 219 | //HomePage(); 220 | }, 221 | ), 222 | SizedBox( 223 | height: 16, 224 | ), 225 | ], 226 | ); 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /parking_locator/lib/screens/search.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:google_maps_flutter/google_maps_flutter.dart'; 3 | import 'package:parking_locator/screens/placeDetails.dart'; 4 | import 'package:parking_locator/services/geolocator_service.dart'; 5 | // import 'package:parking_locator/services/dbservice.dart'; 6 | // import 'package:parking_locator/screens/confirm_booking.dart'; 7 | import 'package:parking_locator/services/marker_service.dart'; 8 | import 'package:parking_locator/widgets/drawer.dart'; 9 | import 'package:parking_locator/constants.dart'; 10 | 11 | 12 | 13 | import 'package:provider/provider.dart'; 14 | import 'package:geolocator/geolocator.dart'; 15 | import 'package:url_launcher/url_launcher.dart'; 16 | import '../models/place.dart'; 17 | 18 | class Search extends StatelessWidget { 19 | @override 20 | Widget build(BuildContext context) { 21 | final currentPosition = Provider.of(context); 22 | final placesProvider = Provider.of>>(context); 23 | final geoService = GeoLocatorService(); 24 | final markerService = MarkerService(); 25 | 26 | return FutureProvider( 27 | create: (context) => placesProvider, 28 | child: Scaffold( 29 | appBar: AppBar( 30 | backgroundColor: Constants.secColor, 31 | title: Text("ParkMe"), 32 | ), 33 | drawer: NavDrawer(), 34 | body: (currentPosition != null) 35 | ? Consumer>( 36 | builder: (_, places, __) { 37 | var markers = (places != null) 38 | ? markerService.getMarkers(places) 39 | : List(); 40 | return (places != null) 41 | ? Column( 42 | children: [ 43 | Container( 44 | height: MediaQuery.of(context).size.height / 2, 45 | width: MediaQuery.of(context).size.width, 46 | child: GoogleMap( 47 | initialCameraPosition: CameraPosition( 48 | target: LatLng(currentPosition.latitude, 49 | currentPosition.longitude), 50 | zoom: 16.0), 51 | zoomGesturesEnabled: true, 52 | markers: Set.of(markers), 53 | ), 54 | ), 55 | SizedBox( 56 | height: 10.0, 57 | ), 58 | Expanded( 59 | child:Container( 60 | color: Constants.mainColor, 61 | child: (places.length > 0) 62 | ? ListView.builder( 63 | itemCount: places.length, 64 | itemBuilder: (context, index) { 65 | return FutureProvider( 66 | initialData: Container(), 67 | create: (context) => 68 | geoService.getDistance( 69 | currentPosition.latitude, 70 | currentPosition.longitude, 71 | places[index].lat, 72 | places[index].long, 73 | ), 74 | child: GestureDetector( 75 | onTap: () { 76 | Navigator.push( 77 | context, 78 | MaterialPageRoute( 79 | builder: (context) => 80 | PlaceDetails( 81 | spotId: 82 | places[index].slotID, 83 | ), 84 | )); 85 | }, 86 | child: Card( 87 | 88 | child: ListTile( 89 | title: 90 | Text(places[index].address,style: TextStyle(color:Constants.secColor),), 91 | subtitle: Column( 92 | crossAxisAlignment: 93 | CrossAxisAlignment.start, 94 | children: [ 95 | SizedBox( 96 | height: 3.0, 97 | ), 98 | SizedBox( 99 | height: 5.0, 100 | ), 101 | ], 102 | ), 103 | trailing: IconButton( 104 | icon: Icon(Icons.directions), 105 | color: Theme.of(context) 106 | .primaryColor, 107 | onPressed: () { 108 | _launchMapsUrl( 109 | places[index].lat, 110 | places[index].long); 111 | }, 112 | ), 113 | ), 114 | ), 115 | ), 116 | ); 117 | }) 118 | : Center( 119 | child: Text('No Parking Found Nearby'), 120 | ), 121 | ) 122 | ) 123 | ], 124 | ) 125 | : Center(child: CircularProgressIndicator()); 126 | }, 127 | ) 128 | : Center( 129 | child: CircularProgressIndicator(), 130 | ), 131 | ), 132 | ); 133 | } 134 | 135 | void _launchMapsUrl(double lat, double lng) async { 136 | final url = 'https://www.google.com/maps/search/?api=1&query=$lat,$lng'; 137 | if (await canLaunch(url)) { 138 | await launch(url); 139 | } else { 140 | throw 'Could not launch $url'; 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /parking_locator/lib/screens/userHistory.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:parking_locator/services/dbservice.dart'; 3 | import 'package:parking_locator/constants.dart'; 4 | import 'package:parking_locator/widgets/drawer.dart'; 5 | 6 | class MyHistory extends StatefulWidget { 7 | @override 8 | _MyHistoryState createState() => _MyHistoryState(); 9 | } 10 | 11 | class _MyHistoryState extends State { 12 | final db_methods = DbMethods(); 13 | final db2_methods = DbBookingMethods(); 14 | 15 | List history; 16 | 17 | void gethistory() async { 18 | List result; 19 | result = await db_methods.userHistory(); 20 | setState(() { 21 | history = result; 22 | print("My History "); 23 | print(history); 24 | }); 25 | } 26 | 27 | void _checkout(id) { 28 | db2_methods.checkout(id); 29 | } 30 | 31 | @override 32 | void initState() { 33 | gethistory(); 34 | // db_methods.userHistory(); 35 | } 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | final height = MediaQuery.of(context).size.height; 40 | final width = MediaQuery.of(context).size.width; 41 | return Scaffold( 42 | appBar: AppBar( 43 | backgroundColor: Constants.secColor, 44 | title: Text('My Bookings'), 45 | ), 46 | drawer:NavDrawer(), 47 | body: Column( 48 | children: [ 49 | // Text(spots[1]['address']), 50 | Expanded( 51 | child: (history != null) 52 | ? ListView.builder( 53 | itemCount: history.length, 54 | itemBuilder: (context, index) { 55 | return Container( 56 | child: Card( 57 | shape: RoundedRectangleBorder( 58 | borderRadius: BorderRadius.circular(15.0), 59 | ), 60 | color: Colors.white, 61 | elevation: 7, 62 | child: Column( 63 | children: [ 64 | GestureDetector( 65 | onTap: () { 66 | _checkout(history[index]['slotID']); 67 | }, 68 | child: Container( 69 | child: 70 | 71 | // Column( 72 | // crossAxisAlignment: CrossAxisAlignment.start, 73 | // children: [ 74 | // Text(history[index]['address']), 75 | // Text("Start time: " + 76 | // history[index]['activeHours']['start']), 77 | // Text("End time: " + 78 | // history[index]['activeHours']['end']), 79 | // Row( 80 | // children: [ 81 | // Text("Parking Type: " + 82 | // history[index]['parkingType']), 83 | // SizedBox( 84 | // width: width * 2 / 5, 85 | // ), 86 | // Text("Charges: " + 87 | // (history[index]['chargesPerHour']) 88 | // .toString()), 89 | // ], 90 | // ), 91 | // ], 92 | // ) 93 | // , 94 | (history[index]['startTime'] == 95 | null) 96 | ? ListTile( 97 | // isThreeLine: true, 98 | subtitle: Text( 99 | "Parking Type: " + 100 | history[index] 101 | [ 102 | 'parkingLocation'] 103 | [ 104 | 'parkingType']), 105 | title: Text( 106 | // "Start time: " + 107 | // history[index][ 108 | // 'startTime'] 109 | // .toString() + 110 | "\nParking Address: " + 111 | history[index][ 112 | 'parkingLocation'] 113 | ['address'] + 114 | "\nCharges per hour: " + 115 | history[index][ 116 | 'parkingLocation'] 117 | [ 118 | 'chargesPerHour'] 119 | .toString() 120 | // " Charges: " + 121 | // (history[index]['parkingLocation']['chargesPerHour']) 122 | // .toString() 123 | ), 124 | ) 125 | : ListTile( 126 | // isThreeLine: true, 127 | subtitle: Text( 128 | "Parking Type: " + 129 | history[index] 130 | [ 131 | 'parkingLocation'] 132 | [ 133 | 'parkingType']), 134 | title: Text( 135 | // "Estimated Start time: " + 136 | // history[index][ 137 | // 'estimatedStartTime'] 138 | // .toString() + 139 | "\nParking Address: " + 140 | history[index][ 141 | 'parkingLocation'] 142 | ['address'] + 143 | "\nCharges per hour: " + 144 | history[index][ 145 | 'parkingLocation'] 146 | [ 147 | 'chargesPerHour'] 148 | .toString() 149 | // " Charges: " + 150 | // (history[index]['parkingLocation']['chargesPerHour']) 151 | // .toString() 152 | ), 153 | ))) 154 | ], 155 | ), 156 | ), 157 | ); 158 | }) 159 | : Center( 160 | child: Text('No Parking History Found'), 161 | )), 162 | ], 163 | ), 164 | ); 165 | } 166 | } 167 | -------------------------------------------------------------------------------- /parking_locator/lib/services/dbservice.dart: -------------------------------------------------------------------------------- 1 | import 'package:http/http.dart' as http; 2 | import 'dart:io'; 3 | import 'dart:convert' as convert; 4 | import 'package:parking_locator/models/place.dart'; 5 | 6 | class DbMethods { 7 | addSpot(lat, long, startTime, endTime, address, type, cost) async { 8 | String token = 9 | "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRCYWxhbmNlIjoxMDAsIl9pZCI6IjYwNjZmYTZkYTQxY2JmMmEwOGY2YTY0NiIsIm5hbWUiOiJIaXJhbCIsImVtYWlsIjoiaGlyYWxAZ21haWwuY29tIiwibW9iaWxlIjoiMTIzNDU2Nzg5MCIsInVzZXJJRCI6IjE4NWNhZGQyLWI2Y2YtNGM4MC05MGZjLTc3M2Q5NTg3MGRhYiIsIl9fdiI6MCwiaWF0IjoxNjE3NDUzNjE5fQ.czhfN16oe57qpS8wt_CNt3giA2f5FFOvKjhD46IPnbU"; 10 | // try { 11 | var url = Uri.parse('http://127.0.0.1:5000/user/myParking'); 12 | print(url); 13 | var obj = { 14 | "lat": lat, 15 | "long": long, 16 | "startTime": startTime, 17 | "endTime": endTime, 18 | "address": address, 19 | "parkingType": type, 20 | "chargesPerHour": cost 21 | }; 22 | print(obj); 23 | 24 | var res = await http.post( 25 | url, 26 | body: convert.json.encode({ 27 | "lat": lat, 28 | "long": long, 29 | "startTime": startTime, 30 | "endTime": endTime, 31 | "address": address, 32 | "parkingType": type, 33 | "chargesPerHour": cost 34 | }), 35 | headers: { 36 | "authorization": token, 37 | "Content-Type": "application/json", 38 | }, 39 | ); 40 | 41 | print(res.statusCode); 42 | print(res.body); 43 | var jsonRes = convert.jsonDecode(res.body); 44 | print(jsonRes); 45 | return jsonRes; 46 | } 47 | // addSpot(lat, long, startTime, endTime, address, type) async { 48 | // print("imhere"); 49 | // print("end" + endTime); 50 | // print("type" + type); 51 | // String token = 52 | // "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRCYWxhbmNlIjoxMDAsIl9pZCI6IjYwNjZmYTZkYTQxY2JmMmEwOGY2YTY0NiIsIm5hbWUiOiJIaXJhbCIsImVtYWlsIjoiaGlyYWxAZ21haWwuY29tIiwibW9iaWxlIjoiMTIzNDU2Nzg5MCIsInVzZXJJRCI6IjE4NWNhZGQyLWI2Y2YtNGM4MC05MGZjLTc3M2Q5NTg3MGRhYiIsIl9fdiI6MCwiaWF0IjoxNjE3NDUzNjE5fQ.czhfN16oe57qpS8wt_CNt3giA2f5FFOvKjhD46IPnbU"; 53 | // // try { 54 | // var url = Uri.parse('http://127.0.0.1:5000/user/myParking'); 55 | // print(url); 56 | // var res = await http.post( 57 | // url, 58 | // body: convert.json.encode({ 59 | // "lat": lat, 60 | // "long": long, 61 | // "startTime": startTime, 62 | // "endTime": endTime, 63 | // "address": address, 64 | // "parkingType": type, 65 | // "chargesPerHour": 100 66 | // }), 67 | // headers: { 68 | // "authorization": token, 69 | // "Content-Type": "application/json", 70 | // }, 71 | // ); 72 | 73 | // print(res.statusCode); 74 | // print(res.body); 75 | // if (res.statusCode == 200) { 76 | // print("Spot added"); 77 | // } else { 78 | // throw Exception('Failed to create album.'); 79 | // } 80 | // } 81 | 82 | mySpots() async { 83 | String token = 84 | "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRCYWxhbmNlIjoxMDAsIl9pZCI6IjYwNjZmYTZkYTQxY2JmMmEwOGY2YTY0NiIsIm5hbWUiOiJIaXJhbCIsImVtYWlsIjoiaGlyYWxAZ21haWwuY29tIiwibW9iaWxlIjoiMTIzNDU2Nzg5MCIsInVzZXJJRCI6IjE4NWNhZGQyLWI2Y2YtNGM4MC05MGZjLTc3M2Q5NTg3MGRhYiIsIl9fdiI6MCwiaWF0IjoxNjE3NDUzNjE5fQ.czhfN16oe57qpS8wt_CNt3giA2f5FFOvKjhD46IPnbU"; 85 | // try { 86 | var url = Uri.parse('http://127.0.0.1:5000/user/myParking'); 87 | print(url); 88 | var res = await http.get( 89 | url, 90 | headers: { 91 | "authorization": token, 92 | "Content-Type": "application/json", 93 | }, 94 | ); 95 | var json = convert.jsonDecode(res.body); 96 | print("hi"); 97 | print(json); 98 | 99 | var jsonResults = json['parkings']; 100 | print(jsonResults); 101 | return jsonResults; 102 | } 103 | 104 | spotDetail(String spotID) async { 105 | String token = 106 | "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRCYWxhbmNlIjoxMDAsIl9pZCI6IjYwNjZmYTZkYTQxY2JmMmEwOGY2YTY0NiIsIm5hbWUiOiJIaXJhbCIsImVtYWlsIjoiaGlyYWxAZ21haWwuY29tIiwibW9iaWxlIjoiMTIzNDU2Nzg5MCIsInVzZXJJRCI6IjE4NWNhZGQyLWI2Y2YtNGM4MC05MGZjLTc3M2Q5NTg3MGRhYiIsIl9fdiI6MCwiaWF0IjoxNjE3NDUzNjE5fQ.czhfN16oe57qpS8wt_CNt3giA2f5FFOvKjhD46IPnbU"; 107 | // try { 108 | var url = Uri.parse( 109 | 'http://127.0.0.1:5000/user/myParking/bookings/?spotID=$spotID'); 110 | print(url); 111 | var res = await http.get( 112 | url, 113 | headers: { 114 | "authorization": token, 115 | "Content-Type": "application/json", 116 | }, 117 | ); 118 | var json = convert.jsonDecode(res.body); 119 | print("hi"); 120 | print(json); 121 | 122 | var jsonResults = json['bookings']; 123 | print(jsonResults); 124 | return jsonResults; 125 | } 126 | 127 | bookingDetails(String spotID, startTime, endTime) async { 128 | String token = 129 | "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRCYWxhbmNlIjoxMDAsIl9pZCI6IjYwNjZmYTZkYTQxY2JmMmEwOGY2YTY0NiIsIm5hbWUiOiJIaXJhbCIsImVtYWlsIjoiaGlyYWxAZ21haWwuY29tIiwibW9iaWxlIjoiMTIzNDU2Nzg5MCIsInVzZXJJRCI6IjE4NWNhZGQyLWI2Y2YtNGM4MC05MGZjLTc3M2Q5NTg3MGRhYiIsIl9fdiI6MCwiaWF0IjoxNjE3NDUzNjE5fQ.czhfN16oe57qpS8wt_CNt3giA2f5FFOvKjhD46IPnbU"; 130 | // try { 131 | var url = Uri.parse( 132 | 'http://127.0.0.1:5000/user/myParking/$spotID/setActiveHours'); 133 | print(url); 134 | var res = await http.post( 135 | url, 136 | body: convert.json.encode({ 137 | "startTime": startTime, 138 | "endTime": endTime, 139 | }), 140 | headers: { 141 | "authorization": token, 142 | "Content-Type": "application/json", 143 | }, 144 | ); 145 | print(res.statusCode); 146 | print(res.body); 147 | if (res.statusCode == 200) { 148 | print("Spot added"); 149 | } else { 150 | throw Exception('Failed to create album.2'); 151 | } 152 | } 153 | 154 | userHistory() async { 155 | String token = 156 | "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRCYWxhbmNlIjoxMDAsIl9pZCI6IjYwNjZmYTZkYTQxY2JmMmEwOGY2YTY0NiIsIm5hbWUiOiJIaXJhbCIsImVtYWlsIjoiaGlyYWxAZ21haWwuY29tIiwibW9iaWxlIjoiMTIzNDU2Nzg5MCIsInVzZXJJRCI6IjE4NWNhZGQyLWI2Y2YtNGM4MC05MGZjLTc3M2Q5NTg3MGRhYiIsIl9fdiI6MCwiaWF0IjoxNjE3NDUzNjE5fQ.czhfN16oe57qpS8wt_CNt3giA2f5FFOvKjhD46IPnbU"; 157 | // try { 158 | var url = Uri.parse('http://127.0.0.1:5000/user/bookings'); 159 | print(url); 160 | var res = await http.get( 161 | url, 162 | headers: { 163 | "authorization": token, 164 | "Content-Type": "application/json", 165 | }, 166 | ); 167 | var json = convert.jsonDecode(res.body); 168 | print("hi"); 169 | print(json); 170 | 171 | var jsonResults = json['bookings']; 172 | print(jsonResults); 173 | return jsonResults; 174 | } 175 | 176 | //get details of a parkspot 177 | Future getPlaceDetails(String spotId) async { 178 | var url = Uri.parse('http://127.0.0.1:5000/parking/$spotId'); 179 | print(url); 180 | String token = 181 | "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRCYWxhbmNlIjoxMDAsIl9pZCI6IjYwNjZmYTZkYTQxY2JmMmEwOGY2YTY0NiIsIm5hbWUiOiJIaXJhbCIsImVtYWlsIjoiaGlyYWxAZ21haWwuY29tIiwibW9iaWxlIjoiMTIzNDU2Nzg5MCIsInVzZXJJRCI6IjE4NWNhZGQyLWI2Y2YtNGM4MC05MGZjLTc3M2Q5NTg3MGRhYiIsIl9fdiI6MCwiaWF0IjoxNjE3NDUzNjE5fQ.czhfN16oe57qpS8wt_CNt3giA2f5FFOvKjhD46IPnbU"; 182 | var response = await http.get( 183 | url, 184 | headers: { 185 | "authorization": token, 186 | "Content-Type": "application/json", 187 | }, 188 | ); 189 | var jsonResults = convert.jsonDecode(response.body); 190 | print(jsonResults['parking']); 191 | return jsonResults['parking']; 192 | } 193 | } 194 | 195 | class DbBookingMethods { 196 | onSubmit(spotid, lat, long, canBook) async { 197 | print("imhere"); 198 | 199 | String token = 200 | "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRCYWxhbmNlIjoxMDAsIl9pZCI6IjYwNjZmYTZkYTQxY2JmMmEwOGY2YTY0NiIsIm5hbWUiOiJIaXJhbCIsImVtYWlsIjoiaGlyYWxAZ21haWwuY29tIiwibW9iaWxlIjoiMTIzNDU2Nzg5MCIsInVzZXJJRCI6IjE4NWNhZGQyLWI2Y2YtNGM4MC05MGZjLTc3M2Q5NTg3MGRhYiIsIl9fdiI6MCwiaWF0IjoxNjE3NDUzNjE5fQ.czhfN16oe57qpS8wt_CNt3giA2f5FFOvKjhD46IPnbU"; 201 | // try { 202 | var url = Uri.parse('http://127.0.0.1:5000/booking/checkin'); 203 | print(url); 204 | var res = await http.post( 205 | url, 206 | body: convert.json.encode({ 207 | "spotID": spotid, 208 | "lat": lat, 209 | "long": long, 210 | "isEmpty": canBook, 211 | }), 212 | headers: { 213 | "authorization": token, 214 | "Content-Type": "application/json", 215 | }, 216 | ); 217 | 218 | print(res.statusCode); 219 | print(res.body); 220 | if (res.statusCode == 200) { 221 | print("Spot added"); 222 | var status = res.body; 223 | var json = convert.jsonDecode(res.body); 224 | print(json); 225 | return json; 226 | } else { 227 | throw Exception('Failed to see booking.'); 228 | } 229 | } 230 | 231 | PriorBook(spotid, startTime, duration) async { 232 | print("imhere"); 233 | 234 | String token = 235 | "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRCYWxhbmNlIjoxMDAsIl9pZCI6IjYwNjZmYTZkYTQxY2JmMmEwOGY2YTY0NiIsIm5hbWUiOiJIaXJhbCIsImVtYWlsIjoiaGlyYWxAZ21haWwuY29tIiwibW9iaWxlIjoiMTIzNDU2Nzg5MCIsInVzZXJJRCI6IjE4NWNhZGQyLWI2Y2YtNGM4MC05MGZjLTc3M2Q5NTg3MGRhYiIsIl9fdiI6MCwiaWF0IjoxNjE3NDUzNjE5fQ.czhfN16oe57qpS8wt_CNt3giA2f5FFOvKjhD46IPnbU"; 236 | // try { 237 | var url = Uri.parse('http://127.0.0.1:5000/booking/bookPrior'); 238 | print(url); 239 | var res = await http.post( 240 | url, 241 | body: convert.json.encode({ 242 | "spotID": spotid, 243 | "startTime": startTime, 244 | "duration": duration, 245 | }), 246 | headers: { 247 | "authorization": token, 248 | "Content-Type": "application/json", 249 | }, 250 | ); 251 | 252 | print(res.statusCode); 253 | print(res.body); 254 | if (res.statusCode == 200) { 255 | print("Spot added"); 256 | var status = res.body; 257 | var json = convert.jsonDecode(res.body); 258 | print(json); 259 | return json; 260 | } else { 261 | throw Exception('Failed to see booking.'); 262 | } 263 | } 264 | 265 | confirmBook(spotid, bookingid) async { 266 | print("imhere"); 267 | print(spotid); 268 | print(bookingid); 269 | 270 | String token = 271 | "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRCYWxhbmNlIjoxMDAsIl9pZCI6IjYwNjZmYTZkYTQxY2JmMmEwOGY2YTY0NiIsIm5hbWUiOiJIaXJhbCIsImVtYWlsIjoiaGlyYWxAZ21haWwuY29tIiwibW9iaWxlIjoiMTIzNDU2Nzg5MCIsInVzZXJJRCI6IjE4NWNhZGQyLWI2Y2YtNGM4MC05MGZjLTc3M2Q5NTg3MGRhYiIsIl9fdiI6MCwiaWF0IjoxNjE3NDUzNjE5fQ.czhfN16oe57qpS8wt_CNt3giA2f5FFOvKjhD46IPnbU"; 272 | // try { 273 | var url = Uri.parse('http://127.0.0.1:5000/booking/checkin/verify'); 274 | print(url); 275 | var res = await http.post( 276 | url, 277 | body: convert.json.encode({"spotID": spotid, "bookingID": bookingid}), 278 | headers: { 279 | "authorization": token, 280 | "Content-Type": "application/json", 281 | }, 282 | ); 283 | 284 | print(res.statusCode); 285 | print(res.body); 286 | var json = convert.jsonDecode(res.body); 287 | print(json); 288 | 289 | if (res.statusCode == 200) { 290 | print("Confirm booking"); 291 | } else { 292 | throw Exception('Failed confirm booking.'); 293 | } 294 | return json; 295 | } 296 | 297 | checkout(spotid) async { 298 | print("imhere"); 299 | 300 | String token = 301 | "bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3YWxsZXRCYWxhbmNlIjoxMDAsIl9pZCI6IjYwNjZmYTZkYTQxY2JmMmEwOGY2YTY0NiIsIm5hbWUiOiJIaXJhbCIsImVtYWlsIjoiaGlyYWxAZ21haWwuY29tIiwibW9iaWxlIjoiMTIzNDU2Nzg5MCIsInVzZXJJRCI6IjE4NWNhZGQyLWI2Y2YtNGM4MC05MGZjLTc3M2Q5NTg3MGRhYiIsIl9fdiI6MCwiaWF0IjoxNjE3NDUzNjE5fQ.czhfN16oe57qpS8wt_CNt3giA2f5FFOvKjhD46IPnbU"; 302 | // try { 303 | var url = Uri.parse('http://127.0.0.1:5000/booking/checkout'); 304 | print(url); 305 | var res = await http.post( 306 | url, 307 | body: convert.json.encode({"spotID": spotid}), 308 | headers: { 309 | "authorization": token, 310 | "Content-Type": "application/json", 311 | }, 312 | ); 313 | print(res.statusCode); 314 | print(res.body); 315 | if (res.statusCode == 200) { 316 | print("Checkout!!"); 317 | } else { 318 | throw Exception('Failed confirm booking.'); 319 | } 320 | } 321 | } 322 | -------------------------------------------------------------------------------- /parking_locator/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | archive: 5 | dependency: transitive 6 | description: 7 | name: archive 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "3.1.2" 11 | async: 12 | dependency: transitive 13 | description: 14 | name: async 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "2.5.0" 18 | boolean_selector: 19 | dependency: transitive 20 | description: 21 | name: boolean_selector 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "2.1.0" 25 | characters: 26 | dependency: transitive 27 | description: 28 | name: characters 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.1.0" 32 | charcode: 33 | dependency: transitive 34 | description: 35 | name: charcode 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "1.2.0" 39 | clock: 40 | dependency: transitive 41 | description: 42 | name: clock 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.1.0" 46 | collection: 47 | dependency: transitive 48 | description: 49 | name: collection 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "1.15.0" 53 | crypto: 54 | dependency: transitive 55 | description: 56 | name: crypto 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "3.0.1" 60 | cupertino_icons: 61 | dependency: "direct main" 62 | description: 63 | name: cupertino_icons 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "1.0.2" 67 | date_format: 68 | dependency: "direct main" 69 | description: 70 | name: date_format 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "2.0.2" 74 | fake_async: 75 | dependency: transitive 76 | description: 77 | name: fake_async 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "1.2.0" 81 | ffi: 82 | dependency: transitive 83 | description: 84 | name: ffi 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "1.0.0" 88 | file: 89 | dependency: transitive 90 | description: 91 | name: file 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "6.1.0" 95 | flutter: 96 | dependency: "direct main" 97 | description: flutter 98 | source: sdk 99 | version: "0.0.0" 100 | flutter_datetime_picker: 101 | dependency: "direct main" 102 | description: 103 | name: flutter_datetime_picker 104 | url: "https://pub.dartlang.org" 105 | source: hosted 106 | version: "1.5.0" 107 | flutter_plugin_android_lifecycle: 108 | dependency: transitive 109 | description: 110 | name: flutter_plugin_android_lifecycle 111 | url: "https://pub.dartlang.org" 112 | source: hosted 113 | version: "2.0.1" 114 | flutter_rating_bar: 115 | dependency: "direct main" 116 | description: 117 | name: flutter_rating_bar 118 | url: "https://pub.dartlang.org" 119 | source: hosted 120 | version: "4.0.0" 121 | flutter_test: 122 | dependency: "direct dev" 123 | description: flutter 124 | source: sdk 125 | version: "0.0.0" 126 | flutter_web_plugins: 127 | dependency: transitive 128 | description: flutter 129 | source: sdk 130 | version: "0.0.0" 131 | form_field_validator: 132 | dependency: "direct main" 133 | description: 134 | name: form_field_validator 135 | url: "https://pub.dartlang.org" 136 | source: hosted 137 | version: "1.1.0" 138 | geocoder: 139 | dependency: "direct main" 140 | description: 141 | name: geocoder 142 | url: "https://pub.dartlang.org" 143 | source: hosted 144 | version: "0.2.1" 145 | geolocator: 146 | dependency: "direct main" 147 | description: 148 | name: geolocator 149 | url: "https://pub.dartlang.org" 150 | source: hosted 151 | version: "7.0.1" 152 | geolocator_platform_interface: 153 | dependency: transitive 154 | description: 155 | name: geolocator_platform_interface 156 | url: "https://pub.dartlang.org" 157 | source: hosted 158 | version: "2.0.0" 159 | geolocator_web: 160 | dependency: transitive 161 | description: 162 | name: geolocator_web 163 | url: "https://pub.dartlang.org" 164 | source: hosted 165 | version: "2.0.3" 166 | google_fonts: 167 | dependency: "direct main" 168 | description: 169 | name: google_fonts 170 | url: "https://pub.dartlang.org" 171 | source: hosted 172 | version: "2.0.0" 173 | google_maps_flutter: 174 | dependency: "direct main" 175 | description: 176 | name: google_maps_flutter 177 | url: "https://pub.dartlang.org" 178 | source: hosted 179 | version: "2.0.2" 180 | google_maps_flutter_platform_interface: 181 | dependency: transitive 182 | description: 183 | name: google_maps_flutter_platform_interface 184 | url: "https://pub.dartlang.org" 185 | source: hosted 186 | version: "2.0.4" 187 | http: 188 | dependency: "direct main" 189 | description: 190 | name: http 191 | url: "https://pub.dartlang.org" 192 | source: hosted 193 | version: "0.13.1" 194 | http_parser: 195 | dependency: transitive 196 | description: 197 | name: http_parser 198 | url: "https://pub.dartlang.org" 199 | source: hosted 200 | version: "4.0.0" 201 | intl: 202 | dependency: "direct main" 203 | description: 204 | name: intl 205 | url: "https://pub.dartlang.org" 206 | source: hosted 207 | version: "0.17.0" 208 | js: 209 | dependency: transitive 210 | description: 211 | name: js 212 | url: "https://pub.dartlang.org" 213 | source: hosted 214 | version: "0.6.3" 215 | loading_animations: 216 | dependency: "direct main" 217 | description: 218 | name: loading_animations 219 | url: "https://pub.dartlang.org" 220 | source: hosted 221 | version: "2.2.0" 222 | logging: 223 | dependency: transitive 224 | description: 225 | name: logging 226 | url: "https://pub.dartlang.org" 227 | source: hosted 228 | version: "1.0.1" 229 | lottie: 230 | dependency: "direct main" 231 | description: 232 | name: lottie 233 | url: "https://pub.dartlang.org" 234 | source: hosted 235 | version: "1.0.1" 236 | matcher: 237 | dependency: transitive 238 | description: 239 | name: matcher 240 | url: "https://pub.dartlang.org" 241 | source: hosted 242 | version: "0.12.10" 243 | meta: 244 | dependency: transitive 245 | description: 246 | name: meta 247 | url: "https://pub.dartlang.org" 248 | source: hosted 249 | version: "1.3.0" 250 | nested: 251 | dependency: transitive 252 | description: 253 | name: nested 254 | url: "https://pub.dartlang.org" 255 | source: hosted 256 | version: "1.0.0" 257 | path: 258 | dependency: transitive 259 | description: 260 | name: path 261 | url: "https://pub.dartlang.org" 262 | source: hosted 263 | version: "1.8.0" 264 | path_provider: 265 | dependency: transitive 266 | description: 267 | name: path_provider 268 | url: "https://pub.dartlang.org" 269 | source: hosted 270 | version: "2.0.1" 271 | path_provider_linux: 272 | dependency: transitive 273 | description: 274 | name: path_provider_linux 275 | url: "https://pub.dartlang.org" 276 | source: hosted 277 | version: "2.0.0" 278 | path_provider_macos: 279 | dependency: transitive 280 | description: 281 | name: path_provider_macos 282 | url: "https://pub.dartlang.org" 283 | source: hosted 284 | version: "2.0.0" 285 | path_provider_platform_interface: 286 | dependency: transitive 287 | description: 288 | name: path_provider_platform_interface 289 | url: "https://pub.dartlang.org" 290 | source: hosted 291 | version: "2.0.1" 292 | path_provider_windows: 293 | dependency: transitive 294 | description: 295 | name: path_provider_windows 296 | url: "https://pub.dartlang.org" 297 | source: hosted 298 | version: "2.0.0" 299 | pedantic: 300 | dependency: transitive 301 | description: 302 | name: pedantic 303 | url: "https://pub.dartlang.org" 304 | source: hosted 305 | version: "1.11.0" 306 | platform: 307 | dependency: transitive 308 | description: 309 | name: platform 310 | url: "https://pub.dartlang.org" 311 | source: hosted 312 | version: "3.0.0" 313 | plugin_platform_interface: 314 | dependency: transitive 315 | description: 316 | name: plugin_platform_interface 317 | url: "https://pub.dartlang.org" 318 | source: hosted 319 | version: "2.0.0" 320 | process: 321 | dependency: transitive 322 | description: 323 | name: process 324 | url: "https://pub.dartlang.org" 325 | source: hosted 326 | version: "4.2.1" 327 | provider: 328 | dependency: "direct main" 329 | description: 330 | name: provider 331 | url: "https://pub.dartlang.org" 332 | source: hosted 333 | version: "5.0.0" 334 | sky_engine: 335 | dependency: transitive 336 | description: flutter 337 | source: sdk 338 | version: "0.0.99" 339 | source_span: 340 | dependency: transitive 341 | description: 342 | name: source_span 343 | url: "https://pub.dartlang.org" 344 | source: hosted 345 | version: "1.8.0" 346 | stack_trace: 347 | dependency: transitive 348 | description: 349 | name: stack_trace 350 | url: "https://pub.dartlang.org" 351 | source: hosted 352 | version: "1.10.0" 353 | stream_channel: 354 | dependency: transitive 355 | description: 356 | name: stream_channel 357 | url: "https://pub.dartlang.org" 358 | source: hosted 359 | version: "2.1.0" 360 | stream_transform: 361 | dependency: transitive 362 | description: 363 | name: stream_transform 364 | url: "https://pub.dartlang.org" 365 | source: hosted 366 | version: "2.0.0" 367 | string_scanner: 368 | dependency: transitive 369 | description: 370 | name: string_scanner 371 | url: "https://pub.dartlang.org" 372 | source: hosted 373 | version: "1.1.0" 374 | term_glyph: 375 | dependency: transitive 376 | description: 377 | name: term_glyph 378 | url: "https://pub.dartlang.org" 379 | source: hosted 380 | version: "1.2.0" 381 | test_api: 382 | dependency: transitive 383 | description: 384 | name: test_api 385 | url: "https://pub.dartlang.org" 386 | source: hosted 387 | version: "0.2.19" 388 | typed_data: 389 | dependency: transitive 390 | description: 391 | name: typed_data 392 | url: "https://pub.dartlang.org" 393 | source: hosted 394 | version: "1.3.0" 395 | url_launcher: 396 | dependency: "direct main" 397 | description: 398 | name: url_launcher 399 | url: "https://pub.dartlang.org" 400 | source: hosted 401 | version: "6.0.3" 402 | url_launcher_linux: 403 | dependency: transitive 404 | description: 405 | name: url_launcher_linux 406 | url: "https://pub.dartlang.org" 407 | source: hosted 408 | version: "2.0.0" 409 | url_launcher_macos: 410 | dependency: transitive 411 | description: 412 | name: url_launcher_macos 413 | url: "https://pub.dartlang.org" 414 | source: hosted 415 | version: "2.0.0" 416 | url_launcher_platform_interface: 417 | dependency: transitive 418 | description: 419 | name: url_launcher_platform_interface 420 | url: "https://pub.dartlang.org" 421 | source: hosted 422 | version: "2.0.2" 423 | url_launcher_web: 424 | dependency: transitive 425 | description: 426 | name: url_launcher_web 427 | url: "https://pub.dartlang.org" 428 | source: hosted 429 | version: "2.0.0" 430 | url_launcher_windows: 431 | dependency: transitive 432 | description: 433 | name: url_launcher_windows 434 | url: "https://pub.dartlang.org" 435 | source: hosted 436 | version: "2.0.0" 437 | vector_math: 438 | dependency: transitive 439 | description: 440 | name: vector_math 441 | url: "https://pub.dartlang.org" 442 | source: hosted 443 | version: "2.1.0" 444 | win32: 445 | dependency: transitive 446 | description: 447 | name: win32 448 | url: "https://pub.dartlang.org" 449 | source: hosted 450 | version: "2.0.5" 451 | xdg_directories: 452 | dependency: transitive 453 | description: 454 | name: xdg_directories 455 | url: "https://pub.dartlang.org" 456 | source: hosted 457 | version: "0.2.0" 458 | sdks: 459 | dart: ">=2.12.0 <3.0.0" 460 | flutter: ">=1.22.0" 461 | -------------------------------------------------------------------------------- /parking_locator/lib/screens/slotdetails.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:parking_locator/services/dbservice.dart'; 3 | import 'package:intl/intl.dart'; 4 | import 'package:date_format/date_format.dart'; 5 | import 'package:parking_locator/constants.dart'; 6 | 7 | 8 | 9 | const headingColor = Color(0xFF002140); 10 | 11 | class SlotDetails extends StatefulWidget { 12 | final String spotID; 13 | SlotDetails({this.spotID}); 14 | @override 15 | _SlotDetailsState createState() => _SlotDetailsState(); 16 | } 17 | 18 | class _SlotDetailsState extends State { 19 | final db_methods = DbMethods(); 20 | GlobalKey _formKey = GlobalKey(); 21 | TextEditingController _timeControllerFrom = TextEditingController(); 22 | TextEditingController _timeControllerTo = TextEditingController(); 23 | List spotbooking; 24 | double _height; 25 | double _width; 26 | String _setFromTime, _setToTime; 27 | String _hour, _minute, _time; 28 | TimeOfDay startTime, endTime; 29 | bool _formLoading = false; 30 | TimeOfDay selectedFromTime = TimeOfDay(hour: 00, minute: 00); 31 | TimeOfDay selectedToTime = TimeOfDay(hour: 00, minute: 00); 32 | 33 | Future _selectTime(BuildContext context, int a) async { 34 | final TimeOfDay picked = await showTimePicker( 35 | context: context, 36 | initialTime: selectedFromTime, 37 | ); 38 | if (picked != null) 39 | setState(() { 40 | if (a == 0) { 41 | selectedFromTime = picked; 42 | _timeControllerFrom.text = formatDate( 43 | DateTime( 44 | 2019, 08, 1, selectedFromTime.hour, selectedFromTime.minute), 45 | [hh, ':', nn, " ", am]).toString(); 46 | } else { 47 | selectedToTime = picked; 48 | _timeControllerTo.text = formatDate( 49 | DateTime(2019, 08, 1, selectedToTime.hour, selectedToTime.minute), 50 | [hh, ':', nn, " ", am]).toString(); 51 | } 52 | }); 53 | } 54 | 55 | String formatTimeOfDay(TimeOfDay tod) { 56 | final now = new DateTime.now(); 57 | final dt = DateTime(now.year, now.month, now.day, tod.hour, tod.minute); 58 | final format = DateFormat('HH:mm:ss'); 59 | // print(format.format(dt)); 60 | return format.format(dt); 61 | } 62 | 63 | @override 64 | void initState() { 65 | getbookings(); 66 | _timeControllerFrom.text = formatDate( 67 | DateTime(2019, 08, 1, DateTime.now().hour, DateTime.now().minute), 68 | [hh, ':', nn, " ", am]).toString(); 69 | _timeControllerTo.text = formatDate( 70 | DateTime(2019, 08, 1, DateTime.now().hour, DateTime.now().minute), 71 | [hh, ':', nn, " ", am]).toString(); 72 | super.initState(); 73 | } 74 | 75 | Future _alertDialogBuilder(String error) async { 76 | return showDialog( 77 | context: context, 78 | barrierDismissible: false, 79 | builder: (context) { 80 | return AlertDialog( 81 | title: Text("Error"), 82 | content: Container( 83 | child: Text(error), 84 | ), 85 | actions: [ 86 | FlatButton( 87 | child: Text("Close Dialog"), 88 | onPressed: () { 89 | Navigator.pop(context); 90 | }, 91 | ) 92 | ], 93 | ); 94 | }); 95 | } 96 | 97 | Future add() async { 98 | print(startTime); 99 | print(endTime); 100 | var start = formatTimeOfDay(startTime).toString(); 101 | var end = formatTimeOfDay(endTime).toString(); 102 | print("end" + end); 103 | // toTime: formatTimeOfDay(selectedToTime).toString(), 104 | await db_methods 105 | .bookingDetails(widget.spotID, start, end) 106 | .then((obj) => print("Changed the timings of the parking spot")) 107 | .catchError((error) => 108 | print("Failed to change the timings of the parking spot: $error")); 109 | return "Successfully updated"; 110 | } 111 | 112 | void _submit() async { 113 | setState(() { 114 | _formLoading = true; 115 | }); 116 | 117 | startTime = selectedFromTime; 118 | endTime = selectedToTime; 119 | print(startTime); 120 | print(endTime); 121 | String _addSpotFeedback = await add(); 122 | if (_addSpotFeedback != null) { 123 | _alertDialogBuilder(_addSpotFeedback); 124 | 125 | setState(() { 126 | _formLoading = false; 127 | }); 128 | } else { 129 | Navigator.pop(context); 130 | } 131 | } 132 | 133 | void getbookings() async { 134 | List result; 135 | result = await db_methods.spotDetail(widget.spotID); 136 | setState(() { 137 | spotbooking = result; 138 | }); 139 | print("hi"); 140 | print(spotbooking); 141 | } 142 | 143 | // @override 144 | // void initState() { 145 | // getbookings(); 146 | // // db_methods.spotDetail(widget.spotID); 147 | // } 148 | 149 | @override 150 | Widget build(BuildContext context) { 151 | _height = MediaQuery.of(context).size.height; 152 | _width = MediaQuery.of(context).size.width; 153 | return Scaffold( 154 | appBar: AppBar( 155 | backgroundColor: Constants.secColor, 156 | title: Text('Slot details'), 157 | ), 158 | body: Column( 159 | children: [ 160 | Form( 161 | key: _formKey, 162 | child: Column( 163 | children: [ 164 | Text("Edits the spot's timings:"), 165 | Row( 166 | mainAxisAlignment: MainAxisAlignment.spaceEvenly, 167 | children: [ 168 | InkWell( 169 | onTap: () { 170 | _selectTime(context, 0); 171 | }, 172 | child: Container( 173 | // padding: EdgeInsets.fromLTRB(10, 10, 10, 0), 174 | width: _width / 2.4, 175 | height: _height / 10, 176 | alignment: Alignment.center, 177 | child: TextFormField( 178 | // style: TextStyle(fontSize: 40), 179 | textAlign: TextAlign.center, 180 | onSaved: (String val) { 181 | _setFromTime = val; 182 | }, 183 | enabled: false, 184 | keyboardType: TextInputType.text, 185 | controller: _timeControllerFrom, 186 | decoration: InputDecoration( 187 | contentPadding: EdgeInsets.all(5), 188 | prefixIcon: Icon( 189 | Icons.alarm, 190 | color:Constants.secColor, 191 | ), 192 | enabledBorder: const OutlineInputBorder( 193 | borderSide: const BorderSide( 194 | color:Constants.secColor, width: 1.0), 195 | ), 196 | border: OutlineInputBorder( 197 | // borderRadius: new BorderRadius.circular(20.0), 198 | borderSide: BorderSide(color:Constants.secColor), 199 | ), 200 | focusedBorder: new OutlineInputBorder( 201 | // borderRadius: new BorderRadius.circular(20.0), 202 | borderSide: BorderSide(color:Constants.secColor), 203 | ), 204 | labelStyle: new TextStyle( 205 | color: headingColor, fontSize: 15), 206 | labelText: "From time", 207 | )), 208 | ), 209 | ), 210 | InkWell( 211 | onTap: () { 212 | _selectTime(context, 1); 213 | }, 214 | child: Container( 215 | width: _width / 2.4, 216 | height: _height / 10, 217 | alignment: Alignment.center, 218 | child: TextFormField( 219 | textAlign: TextAlign.center, 220 | onSaved: (String val) { 221 | _setToTime = val; 222 | }, 223 | enabled: false, 224 | keyboardType: TextInputType.text, 225 | controller: _timeControllerTo, 226 | decoration: InputDecoration( 227 | contentPadding: EdgeInsets.all(5), 228 | prefixIcon: Icon( 229 | Icons.alarm, 230 | color:Constants.secColor, 231 | ), 232 | enabledBorder: const OutlineInputBorder( 233 | borderSide: const BorderSide( 234 | color:Constants.secColor, width: 1.0), 235 | ), 236 | border: OutlineInputBorder( 237 | // borderRadius: new BorderRadius.circular(20.0), 238 | borderSide: BorderSide(color:Constants.secColor), 239 | ), 240 | focusedBorder: new OutlineInputBorder( 241 | // borderRadius: new BorderRadius.circular(20.0), 242 | borderSide: BorderSide(color:Constants.secColor), 243 | ), 244 | labelStyle: new TextStyle( 245 | color: headingColor, fontSize: 15), 246 | labelText: "To time", 247 | )), 248 | ), 249 | ), 250 | ], 251 | ), 252 | Center( 253 | child: ElevatedButton( 254 | style: ElevatedButton.styleFrom( 255 | shape: new RoundedRectangleBorder( 256 | borderRadius: new BorderRadius.circular(20.0), 257 | ), 258 | //primary:Constants.secColor 259 | ), 260 | onPressed: () { 261 | if (_formKey.currentState.validate()) { 262 | // If the form is valid, display a Snackbar. 263 | ScaffoldMessenger.of(context).showSnackBar( 264 | SnackBar(content: Text('Processing Data'))); 265 | _submit(); 266 | } 267 | }, 268 | child: Text( 269 | 'Submit', 270 | style: TextStyle(fontSize: 16.9, color: Colors.white), 271 | ), 272 | // textColor: Colors.white70, 273 | )) 274 | ], 275 | )), 276 | SizedBox(height:5.0), 277 | Text("Slot's booking details"), 278 | SizedBox(height:10.0), 279 | Expanded( 280 | child: (spotbooking != null) 281 | ? ListView.builder( 282 | itemCount: spotbooking.length, 283 | itemBuilder: (context, index) { 284 | return Container( 285 | //color:Constants.mainColor, 286 | child: Card( 287 | shape: RoundedRectangleBorder( 288 | borderRadius: BorderRadius.circular(15.0), 289 | ), 290 | color: Constants.secColor.withOpacity(0.7), 291 | elevation: 7, 292 | child: InkWell( 293 | borderRadius: BorderRadius.circular(15.0), 294 | onTap: () { 295 | Navigator.push( 296 | context, 297 | MaterialPageRoute( 298 | builder: (context) => SlotDetails( 299 | spotID: spotbooking[index]['slotID']), 300 | ), 301 | ); 302 | }, 303 | child: Container( 304 | child: Column( 305 | children: [ 306 | // Column( 307 | // crossAxisAlignment: CrossAxisAlignment.start, 308 | // children: [ 309 | // Text(spots[index]['address']), 310 | // Text("Start time: " + 311 | // spots[index]['activeHours']['start']), 312 | // Text("End time: " + 313 | // spots[index]['activeHours']['end']), 314 | // Row( 315 | // children: [ 316 | // Text("Parking Type: " + 317 | // spots[index]['parkingType']), 318 | // SizedBox( 319 | // width: width * 2 / 5, 320 | // ), 321 | // Text("Charges: " + 322 | // (spots[index]['chargesPerHour']) 323 | // .toString()), 324 | // ], 325 | // ), 326 | // ], 327 | // ) 328 | ListTile( 329 | isThreeLine: true, 330 | title: Text( 331 | spotbooking[index]['user']['name'],style: TextStyle(color:Colors.white),), 332 | subtitle: Text("User email id: " + 333 | spotbooking[index]['user'] 334 | ['email'],style: TextStyle(color:Colors.white),), 335 | ) 336 | ], 337 | ), 338 | )), 339 | ), 340 | ); 341 | }) 342 | : Center( 343 | child: Text('No Slot Bookings Found'), 344 | )), 345 | ], 346 | ), 347 | ); 348 | } 349 | } --------------------------------------------------------------------------------