diff --git a/deprecated/.gitignore b/deprecated/.gitignore
deleted file mode 100644
index a5cf671..0000000
--- a/deprecated/.gitignore
+++ /dev/null
@@ -1,44 +0,0 @@
-# Flutter / Dart
-.dart_tool/
-.flutter-plugins
-.flutter-plugins-dependencies
-.pub-cache/
-.pub/
-/build/
-/coverage/
-**/doc/api/
-**/ios/Flutter/.last_build_id
-
-# IDE / editor
-.idea/
-.vscode/
-*.iml
-*.ipr
-*.iws
-
-# OS files
-.DS_Store
-*.swp
-
-# Environment and secrets
-.env
-.env.*
-!.env.example
-
-# Generated and platform artifacts
-android/key.properties
-android/app/debug
-android/app/profile
-android/app/release
-
-# Logs and temp files
-*.log
-*.tmp
-
-# Symbolication / obfuscation
-*.symbols
-*.map.json
-
-# Legacy migration note
-legacy_windows_xp_plan.md
-
diff --git a/deprecated/.metadata b/deprecated/.metadata
deleted file mode 100644
index 79dc3aa..0000000
--- a/deprecated/.metadata
+++ /dev/null
@@ -1,45 +0,0 @@
-# This file tracks properties of this Flutter project.
-# Used by Flutter tool to assess capabilities and perform upgrades etc.
-#
-# This file should be version controlled and should not be manually edited.
-
-version:
- revision: "00b0c91f06209d9e4a41f71b7a512d6eb3b9c694"
- channel: "stable"
-
-project_type: app
-
-# Tracks metadata for the flutter migrate command
-migration:
- platforms:
- - platform: root
- create_revision: 00b0c91f06209d9e4a41f71b7a512d6eb3b9c694
- base_revision: 00b0c91f06209d9e4a41f71b7a512d6eb3b9c694
- - platform: android
- create_revision: 00b0c91f06209d9e4a41f71b7a512d6eb3b9c694
- base_revision: 00b0c91f06209d9e4a41f71b7a512d6eb3b9c694
- - platform: ios
- create_revision: 00b0c91f06209d9e4a41f71b7a512d6eb3b9c694
- base_revision: 00b0c91f06209d9e4a41f71b7a512d6eb3b9c694
- - platform: linux
- create_revision: 00b0c91f06209d9e4a41f71b7a512d6eb3b9c694
- base_revision: 00b0c91f06209d9e4a41f71b7a512d6eb3b9c694
- - platform: macos
- create_revision: 00b0c91f06209d9e4a41f71b7a512d6eb3b9c694
- base_revision: 00b0c91f06209d9e4a41f71b7a512d6eb3b9c694
- - platform: web
- create_revision: 00b0c91f06209d9e4a41f71b7a512d6eb3b9c694
- base_revision: 00b0c91f06209d9e4a41f71b7a512d6eb3b9c694
- - platform: windows
- create_revision: 00b0c91f06209d9e4a41f71b7a512d6eb3b9c694
- base_revision: 00b0c91f06209d9e4a41f71b7a512d6eb3b9c694
-
- # User provided section
-
- # List of Local paths (relative to this file) that should be
- # ignored by the migrate tool.
- #
- # Files that are not part of the templates will be ignored by default.
- unmanaged_files:
- - 'lib/main.dart'
- - 'ios/Runner.xcodeproj/project.pbxproj'
diff --git a/deprecated/analysis_options.yaml b/deprecated/analysis_options.yaml
deleted file mode 100644
index 129a305..0000000
--- a/deprecated/analysis_options.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-analyzer:
- errors:
- deprecated_member_use: ignore
- use_build_context_synchronously: ignore
-include: package:flutter_lints/flutter.yaml
diff --git a/deprecated/android/.gitignore b/deprecated/android/.gitignore
deleted file mode 100644
index be3943c..0000000
--- a/deprecated/android/.gitignore
+++ /dev/null
@@ -1,14 +0,0 @@
-gradle-wrapper.jar
-/.gradle
-/captures/
-/gradlew
-/gradlew.bat
-/local.properties
-GeneratedPluginRegistrant.java
-.cxx/
-
-# Remember to never publicly share your keystore.
-# See https://flutter.dev/to/reference-keystore
-key.properties
-**/*.keystore
-**/*.jks
diff --git a/deprecated/android/app/build.gradle.kts b/deprecated/android/app/build.gradle.kts
deleted file mode 100644
index df7f4da..0000000
--- a/deprecated/android/app/build.gradle.kts
+++ /dev/null
@@ -1,44 +0,0 @@
-plugins {
- id("com.android.application")
- id("kotlin-android")
- // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
- id("dev.flutter.flutter-gradle-plugin")
-}
-
-android {
- namespace = "com.example.bus_terminal"
- compileSdk = flutter.compileSdkVersion
- ndkVersion = flutter.ndkVersion
-
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_17
- targetCompatibility = JavaVersion.VERSION_17
- }
-
- kotlinOptions {
- jvmTarget = JavaVersion.VERSION_17.toString()
- }
-
- defaultConfig {
- // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
- applicationId = "com.example.bus_terminal"
- // You can update the following values to match your application needs.
- // For more information, see: https://flutter.dev/to/review-gradle-config.
- minSdk = flutter.minSdkVersion
- targetSdk = flutter.targetSdkVersion
- versionCode = flutter.versionCode
- versionName = flutter.versionName
- }
-
- buildTypes {
- release {
- // TODO: Add your own signing config for the release build.
- // Signing with the debug keys for now, so `flutter run --release` works.
- signingConfig = signingConfigs.getByName("debug")
- }
- }
-}
-
-flutter {
- source = "../.."
-}
diff --git a/deprecated/android/app/src/debug/AndroidManifest.xml b/deprecated/android/app/src/debug/AndroidManifest.xml
deleted file mode 100644
index 399f698..0000000
--- a/deprecated/android/app/src/debug/AndroidManifest.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
diff --git a/deprecated/android/app/src/main/AndroidManifest.xml b/deprecated/android/app/src/main/AndroidManifest.xml
deleted file mode 100644
index a812ae5..0000000
--- a/deprecated/android/app/src/main/AndroidManifest.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/deprecated/android/app/src/main/kotlin/com/example/bus_terminal/MainActivity.kt b/deprecated/android/app/src/main/kotlin/com/example/bus_terminal/MainActivity.kt
deleted file mode 100644
index f004c55..0000000
--- a/deprecated/android/app/src/main/kotlin/com/example/bus_terminal/MainActivity.kt
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.example.bus_terminal
-
-import io.flutter.embedding.android.FlutterActivity
-
-class MainActivity : FlutterActivity()
diff --git a/deprecated/android/app/src/main/res/drawable-v21/launch_background.xml b/deprecated/android/app/src/main/res/drawable-v21/launch_background.xml
deleted file mode 100644
index f74085f..0000000
--- a/deprecated/android/app/src/main/res/drawable-v21/launch_background.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/deprecated/android/app/src/main/res/drawable/launch_background.xml b/deprecated/android/app/src/main/res/drawable/launch_background.xml
deleted file mode 100644
index 304732f..0000000
--- a/deprecated/android/app/src/main/res/drawable/launch_background.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/deprecated/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/deprecated/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
deleted file mode 100644
index db77bb4..0000000
Binary files a/deprecated/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ
diff --git a/deprecated/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/deprecated/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
deleted file mode 100644
index 17987b7..0000000
Binary files a/deprecated/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ
diff --git a/deprecated/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/deprecated/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
deleted file mode 100644
index 09d4391..0000000
Binary files a/deprecated/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/deprecated/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/deprecated/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
deleted file mode 100644
index d5f1c8d..0000000
Binary files a/deprecated/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ
diff --git a/deprecated/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/deprecated/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
deleted file mode 100644
index 4d6372e..0000000
Binary files a/deprecated/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ
diff --git a/deprecated/android/app/src/main/res/values-night/styles.xml b/deprecated/android/app/src/main/res/values-night/styles.xml
deleted file mode 100644
index 06952be..0000000
--- a/deprecated/android/app/src/main/res/values-night/styles.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
diff --git a/deprecated/android/app/src/main/res/values/styles.xml b/deprecated/android/app/src/main/res/values/styles.xml
deleted file mode 100644
index cb1ef88..0000000
--- a/deprecated/android/app/src/main/res/values/styles.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
diff --git a/deprecated/android/app/src/profile/AndroidManifest.xml b/deprecated/android/app/src/profile/AndroidManifest.xml
deleted file mode 100644
index 399f698..0000000
--- a/deprecated/android/app/src/profile/AndroidManifest.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
diff --git a/deprecated/android/build.gradle.kts b/deprecated/android/build.gradle.kts
deleted file mode 100644
index dbee657..0000000
--- a/deprecated/android/build.gradle.kts
+++ /dev/null
@@ -1,24 +0,0 @@
-allprojects {
- repositories {
- google()
- mavenCentral()
- }
-}
-
-val newBuildDir: Directory =
- rootProject.layout.buildDirectory
- .dir("../../build")
- .get()
-rootProject.layout.buildDirectory.value(newBuildDir)
-
-subprojects {
- val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
- project.layout.buildDirectory.value(newSubprojectBuildDir)
-}
-subprojects {
- project.evaluationDependsOn(":app")
-}
-
-tasks.register("clean") {
- delete(rootProject.layout.buildDirectory)
-}
diff --git a/deprecated/android/gradle.properties b/deprecated/android/gradle.properties
deleted file mode 100644
index fbee1d8..0000000
--- a/deprecated/android/gradle.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
-android.useAndroidX=true
diff --git a/deprecated/android/gradle/wrapper/gradle-wrapper.properties b/deprecated/android/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index e4ef43f..0000000
--- a/deprecated/android/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip
diff --git a/deprecated/android/settings.gradle.kts b/deprecated/android/settings.gradle.kts
deleted file mode 100644
index ca7fe06..0000000
--- a/deprecated/android/settings.gradle.kts
+++ /dev/null
@@ -1,26 +0,0 @@
-pluginManagement {
- val flutterSdkPath =
- run {
- val properties = java.util.Properties()
- file("local.properties").inputStream().use { properties.load(it) }
- val flutterSdkPath = properties.getProperty("flutter.sdk")
- require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
- flutterSdkPath
- }
-
- includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
-
- repositories {
- google()
- mavenCentral()
- gradlePluginPortal()
- }
-}
-
-plugins {
- id("dev.flutter.flutter-plugin-loader") version "1.0.0"
- id("com.android.application") version "8.11.1" apply false
- id("org.jetbrains.kotlin.android") version "2.2.20" apply false
-}
-
-include(":app")
diff --git a/deprecated/devtools_options.yaml b/deprecated/devtools_options.yaml
deleted file mode 100644
index fa0b357..0000000
--- a/deprecated/devtools_options.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-description: This file stores settings for Dart & Flutter DevTools.
-documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
-extensions:
diff --git a/deprecated/ios/.gitignore b/deprecated/ios/.gitignore
deleted file mode 100644
index 7a7f987..0000000
--- a/deprecated/ios/.gitignore
+++ /dev/null
@@ -1,34 +0,0 @@
-**/dgph
-*.mode1v3
-*.mode2v3
-*.moved-aside
-*.pbxuser
-*.perspectivev3
-**/*sync/
-.sconsign.dblite
-.tags*
-**/.vagrant/
-**/DerivedData/
-Icon?
-**/Pods/
-**/.symlinks/
-profile
-xcuserdata
-**/.generated/
-Flutter/App.framework
-Flutter/Flutter.framework
-Flutter/Flutter.podspec
-Flutter/Generated.xcconfig
-Flutter/ephemeral/
-Flutter/app.flx
-Flutter/app.zip
-Flutter/flutter_assets/
-Flutter/flutter_export_environment.sh
-ServiceDefinitions.json
-Runner/GeneratedPluginRegistrant.*
-
-# Exceptions to above rules.
-!default.mode1v3
-!default.mode2v3
-!default.pbxuser
-!default.perspectivev3
diff --git a/deprecated/ios/Flutter/AppFrameworkInfo.plist b/deprecated/ios/Flutter/AppFrameworkInfo.plist
deleted file mode 100644
index 391a902..0000000
--- a/deprecated/ios/Flutter/AppFrameworkInfo.plist
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- en
- CFBundleExecutable
- App
- CFBundleIdentifier
- io.flutter.flutter.app
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- App
- CFBundlePackageType
- FMWK
- CFBundleShortVersionString
- 1.0
- CFBundleSignature
- ????
- CFBundleVersion
- 1.0
-
-
diff --git a/deprecated/ios/Flutter/Debug.xcconfig b/deprecated/ios/Flutter/Debug.xcconfig
deleted file mode 100644
index 592ceee..0000000
--- a/deprecated/ios/Flutter/Debug.xcconfig
+++ /dev/null
@@ -1 +0,0 @@
-#include "Generated.xcconfig"
diff --git a/deprecated/ios/Flutter/Release.xcconfig b/deprecated/ios/Flutter/Release.xcconfig
deleted file mode 100644
index 592ceee..0000000
--- a/deprecated/ios/Flutter/Release.xcconfig
+++ /dev/null
@@ -1 +0,0 @@
-#include "Generated.xcconfig"
diff --git a/deprecated/ios/Runner.xcodeproj/project.pbxproj b/deprecated/ios/Runner.xcodeproj/project.pbxproj
deleted file mode 100644
index 5d66d34..0000000
--- a/deprecated/ios/Runner.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,620 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 54;
- objects = {
-
-/* Begin PBXBuildFile section */
- 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
- 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
- 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
- 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
- 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; };
- 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
- 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
- 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXContainerItemProxy section */
- 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 97C146E61CF9000F007C117D /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = 97C146ED1CF9000F007C117D;
- remoteInfo = Runner;
- };
-/* End PBXContainerItemProxy section */
-
-/* Begin PBXCopyFilesBuildPhase section */
- 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 10;
- files = (
- );
- name = "Embed Frameworks";
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXCopyFilesBuildPhase section */
-
-/* Begin PBXFileReference section */
- 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
- 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
- 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; };
- 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
- 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
- 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
- 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
- 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
- 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
- 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
- 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
- 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
- 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
- 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
- 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 97C146EB1CF9000F007C117D /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 331C8082294A63A400263BE5 /* RunnerTests */ = {
- isa = PBXGroup;
- children = (
- 331C807B294A618700263BE5 /* RunnerTests.swift */,
- );
- path = RunnerTests;
- sourceTree = "";
- };
- 9740EEB11CF90186004384FC /* Flutter */ = {
- isa = PBXGroup;
- children = (
- 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
- 9740EEB21CF90195004384FC /* Debug.xcconfig */,
- 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
- 9740EEB31CF90195004384FC /* Generated.xcconfig */,
- );
- name = Flutter;
- sourceTree = "";
- };
- 97C146E51CF9000F007C117D = {
- isa = PBXGroup;
- children = (
- 9740EEB11CF90186004384FC /* Flutter */,
- 97C146F01CF9000F007C117D /* Runner */,
- 97C146EF1CF9000F007C117D /* Products */,
- 331C8082294A63A400263BE5 /* RunnerTests */,
- );
- sourceTree = "";
- };
- 97C146EF1CF9000F007C117D /* Products */ = {
- isa = PBXGroup;
- children = (
- 97C146EE1CF9000F007C117D /* Runner.app */,
- 331C8081294A63A400263BE5 /* RunnerTests.xctest */,
- );
- name = Products;
- sourceTree = "";
- };
- 97C146F01CF9000F007C117D /* Runner */ = {
- isa = PBXGroup;
- children = (
- 97C146FA1CF9000F007C117D /* Main.storyboard */,
- 97C146FD1CF9000F007C117D /* Assets.xcassets */,
- 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
- 97C147021CF9000F007C117D /* Info.plist */,
- 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
- 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
- 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
- 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */,
- 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
- );
- path = Runner;
- sourceTree = "";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 331C8080294A63A400263BE5 /* RunnerTests */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
- buildPhases = (
- 331C807D294A63A400263BE5 /* Sources */,
- 331C807F294A63A400263BE5 /* Resources */,
- );
- buildRules = (
- );
- dependencies = (
- 331C8086294A63A400263BE5 /* PBXTargetDependency */,
- );
- name = RunnerTests;
- productName = RunnerTests;
- productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
- productType = "com.apple.product-type.bundle.unit-test";
- };
- 97C146ED1CF9000F007C117D /* Runner */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
- buildPhases = (
- 9740EEB61CF901F6004384FC /* Run Script */,
- 97C146EA1CF9000F007C117D /* Sources */,
- 97C146EB1CF9000F007C117D /* Frameworks */,
- 97C146EC1CF9000F007C117D /* Resources */,
- 9705A1C41CF9048500538489 /* Embed Frameworks */,
- 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = Runner;
- productName = Runner;
- productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
- productType = "com.apple.product-type.application";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 97C146E61CF9000F007C117D /* Project object */ = {
- isa = PBXProject;
- attributes = {
- BuildIndependentTargetsInParallel = YES;
- LastUpgradeCheck = 1510;
- ORGANIZATIONNAME = "";
- TargetAttributes = {
- 331C8080294A63A400263BE5 = {
- CreatedOnToolsVersion = 14.0;
- TestTargetID = 97C146ED1CF9000F007C117D;
- };
- 97C146ED1CF9000F007C117D = {
- CreatedOnToolsVersion = 7.3.1;
- LastSwiftMigration = 1100;
- };
- };
- };
- buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
- compatibilityVersion = "Xcode 9.3";
- developmentRegion = en;
- hasScannedForEncodings = 0;
- knownRegions = (
- en,
- Base,
- );
- mainGroup = 97C146E51CF9000F007C117D;
- productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 97C146ED1CF9000F007C117D /* Runner */,
- 331C8080294A63A400263BE5 /* RunnerTests */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
- 331C807F294A63A400263BE5 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 97C146EC1CF9000F007C117D /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
- 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
- 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
- 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXShellScriptBuildPhase section */
- 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
- isa = PBXShellScriptBuildPhase;
- alwaysOutOfDate = 1;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
- );
- name = "Thin Binary";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
- };
- 9740EEB61CF901F6004384FC /* Run Script */ = {
- isa = PBXShellScriptBuildPhase;
- alwaysOutOfDate = 1;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- );
- name = "Run Script";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
- };
-/* End PBXShellScriptBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
- 331C807D294A63A400263BE5 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- 97C146EA1CF9000F007C117D /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
- 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
- 7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin PBXTargetDependency section */
- 331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 97C146ED1CF9000F007C117D /* Runner */;
- targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
- };
-/* End PBXTargetDependency section */
-
-/* Begin PBXVariantGroup section */
- 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
- isa = PBXVariantGroup;
- children = (
- 97C146FB1CF9000F007C117D /* Base */,
- );
- name = Main.storyboard;
- sourceTree = "";
- };
- 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
- isa = PBXVariantGroup;
- children = (
- 97C147001CF9000F007C117D /* Base */,
- );
- name = LaunchScreen.storyboard;
- sourceTree = "";
- };
-/* End PBXVariantGroup section */
-
-/* Begin XCBuildConfiguration section */
- 249021D3217E4FDB00AE95B9 /* Profile */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- ENABLE_NS_ASSERTIONS = NO;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- ENABLE_USER_SCRIPT_SANDBOXING = NO;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 13.0;
- MTL_ENABLE_DEBUG_INFO = NO;
- SDKROOT = iphoneos;
- SUPPORTED_PLATFORMS = iphoneos;
- TARGETED_DEVICE_FAMILY = "1,2";
- VALIDATE_PRODUCT = YES;
- };
- name = Profile;
- };
- 249021D4217E4FDB00AE95B9 /* Profile */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CLANG_ENABLE_MODULES = YES;
- CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
- ENABLE_BITCODE = NO;
- INFOPLIST_FILE = Runner/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = (
- "$(inherited)",
- "@executable_path/Frameworks",
- );
- PRODUCT_BUNDLE_IDENTIFIER = com.example.busTerminal;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
- SWIFT_VERSION = 5.0;
- VERSIONING_SYSTEM = "apple-generic";
- };
- name = Profile;
- };
- 331C8088294A63A400263BE5 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- BUNDLE_LOADER = "$(TEST_HOST)";
- CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
- GENERATE_INFOPLIST_FILE = YES;
- MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.example.busTerminal.RunnerTests;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 5.0;
- TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
- };
- name = Debug;
- };
- 331C8089294A63A400263BE5 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- BUNDLE_LOADER = "$(TEST_HOST)";
- CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
- GENERATE_INFOPLIST_FILE = YES;
- MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.example.busTerminal.RunnerTests;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 5.0;
- TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
- };
- name = Release;
- };
- 331C808A294A63A400263BE5 /* Profile */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- BUNDLE_LOADER = "$(TEST_HOST)";
- CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
- GENERATE_INFOPLIST_FILE = YES;
- MARKETING_VERSION = 1.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.example.busTerminal.RunnerTests;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_VERSION = 5.0;
- TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
- };
- name = Profile;
- };
- 97C147031CF9000F007C117D /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = dwarf;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- ENABLE_TESTABILITY = YES;
- ENABLE_USER_SCRIPT_SANDBOXING = NO;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 13.0;
- MTL_ENABLE_DEBUG_INFO = YES;
- ONLY_ACTIVE_ARCH = YES;
- SDKROOT = iphoneos;
- TARGETED_DEVICE_FAMILY = "1,2";
- };
- name = Debug;
- };
- 97C147041CF9000F007C117D /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
- CLANG_ANALYZER_NONNULL = YES;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_COMMA = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INFINITE_RECURSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
- CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
- CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
- CLANG_WARN_STRICT_PROTOTYPES = YES;
- CLANG_WARN_SUSPICIOUS_MOVE = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- ENABLE_NS_ASSERTIONS = NO;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- ENABLE_USER_SCRIPT_SANDBOXING = NO;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- IPHONEOS_DEPLOYMENT_TARGET = 13.0;
- MTL_ENABLE_DEBUG_INFO = NO;
- SDKROOT = iphoneos;
- SUPPORTED_PLATFORMS = iphoneos;
- SWIFT_COMPILATION_MODE = wholemodule;
- SWIFT_OPTIMIZATION_LEVEL = "-O";
- TARGETED_DEVICE_FAMILY = "1,2";
- VALIDATE_PRODUCT = YES;
- };
- name = Release;
- };
- 97C147061CF9000F007C117D /* Debug */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CLANG_ENABLE_MODULES = YES;
- CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
- ENABLE_BITCODE = NO;
- INFOPLIST_FILE = Runner/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = (
- "$(inherited)",
- "@executable_path/Frameworks",
- );
- PRODUCT_BUNDLE_IDENTIFIER = com.example.busTerminal;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
- SWIFT_VERSION = 5.0;
- VERSIONING_SYSTEM = "apple-generic";
- };
- name = Debug;
- };
- 97C147071CF9000F007C117D /* Release */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
- buildSettings = {
- ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
- CLANG_ENABLE_MODULES = YES;
- CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
- ENABLE_BITCODE = NO;
- INFOPLIST_FILE = Runner/Info.plist;
- LD_RUNPATH_SEARCH_PATHS = (
- "$(inherited)",
- "@executable_path/Frameworks",
- );
- PRODUCT_BUNDLE_IDENTIFIER = com.example.busTerminal;
- PRODUCT_NAME = "$(TARGET_NAME)";
- SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
- SWIFT_VERSION = 5.0;
- VERSIONING_SYSTEM = "apple-generic";
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 331C8088294A63A400263BE5 /* Debug */,
- 331C8089294A63A400263BE5 /* Release */,
- 331C808A294A63A400263BE5 /* Profile */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 97C147031CF9000F007C117D /* Debug */,
- 97C147041CF9000F007C117D /* Release */,
- 249021D3217E4FDB00AE95B9 /* Profile */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 97C147061CF9000F007C117D /* Debug */,
- 97C147071CF9000F007C117D /* Release */,
- 249021D4217E4FDB00AE95B9 /* Profile */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 97C146E61CF9000F007C117D /* Project object */;
-}
diff --git a/deprecated/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/deprecated/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
deleted file mode 100644
index 919434a..0000000
--- a/deprecated/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
diff --git a/deprecated/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/deprecated/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
deleted file mode 100644
index 18d9810..0000000
--- a/deprecated/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- IDEDidComputeMac32BitWarning
-
-
-
diff --git a/deprecated/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/deprecated/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
deleted file mode 100644
index f9b0d7c..0000000
--- a/deprecated/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- PreviewsEnabled
-
-
-
diff --git a/deprecated/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/deprecated/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
deleted file mode 100644
index e3773d4..0000000
--- a/deprecated/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+++ /dev/null
@@ -1,101 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/deprecated/ios/Runner.xcworkspace/contents.xcworkspacedata b/deprecated/ios/Runner.xcworkspace/contents.xcworkspacedata
deleted file mode 100644
index 1d526a1..0000000
--- a/deprecated/ios/Runner.xcworkspace/contents.xcworkspacedata
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
diff --git a/deprecated/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/deprecated/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
deleted file mode 100644
index 18d9810..0000000
--- a/deprecated/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- IDEDidComputeMac32BitWarning
-
-
-
diff --git a/deprecated/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/deprecated/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
deleted file mode 100644
index f9b0d7c..0000000
--- a/deprecated/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- PreviewsEnabled
-
-
-
diff --git a/deprecated/ios/Runner/AppDelegate.swift b/deprecated/ios/Runner/AppDelegate.swift
deleted file mode 100644
index c30b367..0000000
--- a/deprecated/ios/Runner/AppDelegate.swift
+++ /dev/null
@@ -1,16 +0,0 @@
-import Flutter
-import UIKit
-
-@main
-@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
- override func application(
- _ application: UIApplication,
- didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
- ) -> Bool {
- return super.application(application, didFinishLaunchingWithOptions: launchOptions)
- }
-
- func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
- GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
- }
-}
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
deleted file mode 100644
index d36b1fa..0000000
--- a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ /dev/null
@@ -1,122 +0,0 @@
-{
- "images" : [
- {
- "size" : "20x20",
- "idiom" : "iphone",
- "filename" : "Icon-App-20x20@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "20x20",
- "idiom" : "iphone",
- "filename" : "Icon-App-20x20@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "29x29",
- "idiom" : "iphone",
- "filename" : "Icon-App-29x29@1x.png",
- "scale" : "1x"
- },
- {
- "size" : "29x29",
- "idiom" : "iphone",
- "filename" : "Icon-App-29x29@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "29x29",
- "idiom" : "iphone",
- "filename" : "Icon-App-29x29@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "40x40",
- "idiom" : "iphone",
- "filename" : "Icon-App-40x40@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "40x40",
- "idiom" : "iphone",
- "filename" : "Icon-App-40x40@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "60x60",
- "idiom" : "iphone",
- "filename" : "Icon-App-60x60@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "60x60",
- "idiom" : "iphone",
- "filename" : "Icon-App-60x60@3x.png",
- "scale" : "3x"
- },
- {
- "size" : "20x20",
- "idiom" : "ipad",
- "filename" : "Icon-App-20x20@1x.png",
- "scale" : "1x"
- },
- {
- "size" : "20x20",
- "idiom" : "ipad",
- "filename" : "Icon-App-20x20@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "29x29",
- "idiom" : "ipad",
- "filename" : "Icon-App-29x29@1x.png",
- "scale" : "1x"
- },
- {
- "size" : "29x29",
- "idiom" : "ipad",
- "filename" : "Icon-App-29x29@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "40x40",
- "idiom" : "ipad",
- "filename" : "Icon-App-40x40@1x.png",
- "scale" : "1x"
- },
- {
- "size" : "40x40",
- "idiom" : "ipad",
- "filename" : "Icon-App-40x40@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "76x76",
- "idiom" : "ipad",
- "filename" : "Icon-App-76x76@1x.png",
- "scale" : "1x"
- },
- {
- "size" : "76x76",
- "idiom" : "ipad",
- "filename" : "Icon-App-76x76@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "83.5x83.5",
- "idiom" : "ipad",
- "filename" : "Icon-App-83.5x83.5@2x.png",
- "scale" : "2x"
- },
- {
- "size" : "1024x1024",
- "idiom" : "ios-marketing",
- "filename" : "Icon-App-1024x1024@1x.png",
- "scale" : "1x"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
deleted file mode 100644
index dc9ada4..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
deleted file mode 100644
index 7353c41..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
deleted file mode 100644
index 797d452..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
deleted file mode 100644
index 6ed2d93..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
deleted file mode 100644
index 4cd7b00..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
deleted file mode 100644
index fe73094..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
deleted file mode 100644
index 321773c..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
deleted file mode 100644
index 797d452..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
deleted file mode 100644
index 502f463..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
deleted file mode 100644
index 0ec3034..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
deleted file mode 100644
index 0ec3034..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
deleted file mode 100644
index e9f5fea..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
deleted file mode 100644
index 84ac32a..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
deleted file mode 100644
index 8953cba..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
deleted file mode 100644
index 0467bf1..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
deleted file mode 100644
index 0bedcf2..0000000
--- a/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "images" : [
- {
- "idiom" : "universal",
- "filename" : "LaunchImage.png",
- "scale" : "1x"
- },
- {
- "idiom" : "universal",
- "filename" : "LaunchImage@2x.png",
- "scale" : "2x"
- },
- {
- "idiom" : "universal",
- "filename" : "LaunchImage@3x.png",
- "scale" : "3x"
- }
- ],
- "info" : {
- "version" : 1,
- "author" : "xcode"
- }
-}
diff --git a/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
deleted file mode 100644
index 9da19ea..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
deleted file mode 100644
index 9da19ea..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
deleted file mode 100644
index 9da19ea..0000000
Binary files a/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png and /dev/null differ
diff --git a/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
deleted file mode 100644
index 89c2725..0000000
--- a/deprecated/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Launch Screen Assets
-
-You can customize the launch screen with your own desired assets by replacing the image files in this directory.
-
-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.
\ No newline at end of file
diff --git a/deprecated/ios/Runner/Base.lproj/LaunchScreen.storyboard b/deprecated/ios/Runner/Base.lproj/LaunchScreen.storyboard
deleted file mode 100644
index f2e259c..0000000
--- a/deprecated/ios/Runner/Base.lproj/LaunchScreen.storyboard
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/deprecated/ios/Runner/Base.lproj/Main.storyboard b/deprecated/ios/Runner/Base.lproj/Main.storyboard
deleted file mode 100644
index f3c2851..0000000
--- a/deprecated/ios/Runner/Base.lproj/Main.storyboard
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/deprecated/ios/Runner/Info.plist b/deprecated/ios/Runner/Info.plist
deleted file mode 100644
index 38dcd24..0000000
--- a/deprecated/ios/Runner/Info.plist
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
- CADisableMinimumFrameDurationOnPhone
-
- CFBundleDevelopmentRegion
- $(DEVELOPMENT_LANGUAGE)
- CFBundleDisplayName
- Bus Terminal
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- bus_terminal
- CFBundlePackageType
- APPL
- CFBundleShortVersionString
- $(FLUTTER_BUILD_NAME)
- CFBundleSignature
- ????
- CFBundleVersion
- $(FLUTTER_BUILD_NUMBER)
- LSRequiresIPhoneOS
-
- UIApplicationSceneManifest
-
- UIApplicationSupportsMultipleScenes
-
- UISceneConfigurations
-
- UIWindowSceneSessionRoleApplication
-
-
- UISceneClassName
- UIWindowScene
- UISceneConfigurationName
- flutter
- UISceneDelegateClassName
- $(PRODUCT_MODULE_NAME).SceneDelegate
- UISceneStoryboardFile
- Main
-
-
-
-
- UIApplicationSupportsIndirectInputEvents
-
- UILaunchStoryboardName
- LaunchScreen
- UIMainStoryboardFile
- Main
- UISupportedInterfaceOrientations
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- UISupportedInterfaceOrientations~ipad
-
- UIInterfaceOrientationPortrait
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
-
- NSLocationWhenInUseUsageDescription
- We need your location to show the bus route on the map and navigate you through your scheduled stops.
- NSLocationAlwaysAndWhenInUseUsageDescription
- We need your location to show the bus route on the map and navigate you through your scheduled stops.
-
-
diff --git a/deprecated/ios/Runner/Runner-Bridging-Header.h b/deprecated/ios/Runner/Runner-Bridging-Header.h
deleted file mode 100644
index 308a2a5..0000000
--- a/deprecated/ios/Runner/Runner-Bridging-Header.h
+++ /dev/null
@@ -1 +0,0 @@
-#import "GeneratedPluginRegistrant.h"
diff --git a/deprecated/ios/Runner/SceneDelegate.swift b/deprecated/ios/Runner/SceneDelegate.swift
deleted file mode 100644
index b9ce8ea..0000000
--- a/deprecated/ios/Runner/SceneDelegate.swift
+++ /dev/null
@@ -1,6 +0,0 @@
-import Flutter
-import UIKit
-
-class SceneDelegate: FlutterSceneDelegate {
-
-}
diff --git a/deprecated/ios/RunnerTests/RunnerTests.swift b/deprecated/ios/RunnerTests/RunnerTests.swift
deleted file mode 100644
index 86a7c3b..0000000
--- a/deprecated/ios/RunnerTests/RunnerTests.swift
+++ /dev/null
@@ -1,12 +0,0 @@
-import Flutter
-import UIKit
-import XCTest
-
-class RunnerTests: XCTestCase {
-
- func testExample() {
- // If you add code to the Runner application, consider adding tests here.
- // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
- }
-
-}
diff --git a/deprecated/lib/main.dart b/deprecated/lib/main.dart
deleted file mode 100644
index af82419..0000000
--- a/deprecated/lib/main.dart
+++ /dev/null
@@ -1,94 +0,0 @@
-import 'dart:async';
-import 'dart:ui';
-
-import 'package:flutter/material.dart';
-import 'screens/login_screen.dart';
-import 'screens/schedule_overview_screen.dart';
-import 'services/auth_service.dart';
-import 'theme/app_theme.dart';
-import 'services/app_navigator.dart';
-import 'services/error_log_service.dart';
-
-void main() {
- WidgetsFlutterBinding.ensureInitialized();
-
- FlutterError.onError = (details) {
- FlutterError.presentError(details);
- void report() => ErrorLogService.report(
- service: 'deprecated',
- partOfService: 'FlutterError.onError',
- error: details.exceptionAsString(),
- );
- // ignore: unawaited_futures
- report();
- };
-
- PlatformDispatcher.instance.onError = (error, stack) {
- // ignore: unawaited_futures
- ErrorLogService.report(
- service: 'deprecated',
- partOfService: 'PlatformDispatcher.onError',
- error: '$error\n$stack',
- );
- return true;
- };
-
- runZonedGuarded(
- () {
- runApp(const MainApp());
- },
- (error, stack) {
- // ignore: unawaited_futures
- ErrorLogService.report(
- service: 'deprecated',
- partOfService: 'runZonedGuarded',
- error: '$error\n$stack',
- );
- },
- );
-}
-
-class MainApp extends StatelessWidget {
- const MainApp({super.key});
-
- @override
- Widget build(BuildContext context) {
- return MaterialApp(
- title: 'Bus Terminal',
- navigatorKey: navigatorKey,
- scaffoldMessengerKey: messengerKey,
- theme: AppTheme.lightTheme(),
- darkTheme: AppTheme.darkTheme(),
- themeMode: ThemeMode.system,
- routes: {
- '/login': (context) => const LoginScreen(),
- '/schedule': (context) => const ScheduleOverviewScreen(),
- },
- home: const _InitialRoute(),
- );
- }
-}
-
-/// Initial route checks if user is logged in
-class _InitialRoute extends StatelessWidget {
- const _InitialRoute();
-
- @override
- Widget build(BuildContext context) {
- return FutureBuilder(
- future: AuthService().isLoggedIn(),
- builder: (context, snapshot) {
- if (snapshot.connectionState == ConnectionState.waiting) {
- return const Scaffold(
- body: Center(child: CircularProgressIndicator()),
- );
- }
-
- // If logged in, go to schedule; otherwise go to login
- return snapshot.data == true
- ? const ScheduleOverviewScreen()
- : const LoginScreen();
- },
- );
- }
-}
diff --git a/deprecated/lib/models/.gitkeep b/deprecated/lib/models/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/deprecated/lib/models/navigation.dart b/deprecated/lib/models/navigation.dart
deleted file mode 100644
index d0ae054..0000000
--- a/deprecated/lib/models/navigation.dart
+++ /dev/null
@@ -1,211 +0,0 @@
-import 'package:latlong2/latlong.dart';
-
-/// Navigation route point
-class NavigationPoint {
- final double latitude;
- final double longitude;
- final String? name;
-
- NavigationPoint({
- required this.latitude,
- required this.longitude,
- this.name,
- });
-
- LatLng toLatLng() => LatLng(latitude, longitude);
-
- factory NavigationPoint.fromLatLng(LatLng latlng, {String? name}) {
- return NavigationPoint(
- latitude: latlng.latitude,
- longitude: latlng.longitude,
- name: name,
- );
- }
-
- Map toJson() {
- return {
- 'latitude': latitude,
- 'longitude': longitude,
- 'name': name,
- };
- }
-
- factory NavigationPoint.fromJson(Map json) {
- return NavigationPoint(
- latitude: json['latitude'] as double,
- longitude: json['longitude'] as double,
- name: json['name'] as String?,
- );
- }
-}
-
-/// Route leg with distance and duration
-class RouteLeg {
- final List points;
- final double distance; // in meters
- final int duration; // in seconds
- final String summary;
-
- RouteLeg({
- required this.points,
- required this.distance,
- required this.duration,
- required this.summary,
- });
-
- String getDistanceKm() => (distance / 1000).toStringAsFixed(1);
- String getDurationMinutes() => (duration ~/ 60).toString();
-
- factory RouteLeg.fromCoordinates(
- List coordinates, {
- double distance = 0.0,
- int duration = 0,
- String summary = 'Route',
- }) {
- return RouteLeg(
- points: coordinates
- .map((coord) {
- if (coord is List && coord.length >= 2) {
- return NavigationPoint(
- latitude: (coord[1] as num).toDouble(),
- longitude: (coord[0] as num).toDouble(),
- );
- }
- return null;
- })
- .whereType()
- .toList(),
- distance: distance,
- duration: duration,
- summary: summary,
- );
- }
-
- factory RouteLeg.fromPoints({
- required List points,
- required double distance,
- required int duration,
- String summary = 'Route',
- }) {
- return RouteLeg(
- points: points,
- distance: distance,
- duration: duration,
- summary: summary,
- );
- }
-
- factory RouteLeg.fromJson(Map json) {
- final geometry = json['geometry'] as Map?;
- final coordinates = geometry?['coordinates'] as List? ?? [];
-
- return RouteLeg(
- points: coordinates
- .map((coord) {
- if (coord is List && coord.length >= 2) {
- return NavigationPoint(
- latitude: (coord[1] as num).toDouble(),
- longitude: (coord[0] as num).toDouble(),
- );
- }
- return null;
- })
- .whereType()
- .toList(),
- distance: (json['distance'] as num?)?.toDouble() ?? 0.0,
- duration: (json['duration'] as num?)?.toInt() ?? 0,
- summary: (json['summary'] as String?) ?? 'Route',
- );
- }
-}
-
-/// Complete navigation route from start to end
-class NavigationRoute {
- final NavigationPoint start;
- final NavigationPoint end;
- final List legs;
- final double totalDistance; // in meters
- final int totalDuration; // in seconds
-
- NavigationRoute({
- required this.start,
- required this.end,
- required this.legs,
- required this.totalDistance,
- required this.totalDuration,
- });
-
- String getTotalDistanceKm() => (totalDistance / 1000).toStringAsFixed(1);
- String getTotalDurationMinutes() => (totalDuration ~/ 60).toString();
- String getTotalDurationHM() {
- final hours = totalDuration ~/ 3600;
- final minutes = (totalDuration % 3600) ~/ 60;
- if (hours > 0) {
- return '${hours}h ${minutes}m';
- }
- return '${minutes}m';
- }
-
- List getAllPoints() {
- final allPoints = [];
- for (final leg in legs) {
- allPoints.addAll(leg.points);
- }
- return allPoints;
- }
-
- factory NavigationRoute.fromJson(Map json) {
- final routes = json['routes'] as List?;
- if (routes == null || routes.isEmpty) {
- throw Exception('No route found in response');
- }
-
- final routeData = routes[0] as Map?;
- if (routeData == null) {
- throw Exception('Invalid route data');
- }
-
- return NavigationRoute.fromOsrmRouteData(
- routeData,
- start: NavigationPoint(latitude: 0, longitude: 0),
- end: NavigationPoint(latitude: 0, longitude: 0),
- );
- }
-
- factory NavigationRoute.fromOsrmRouteData(
- Map routeData, {
- required NavigationPoint start,
- required NavigationPoint end,
- }) {
- final geometry = routeData['geometry'] as Map?;
- final coordinates = geometry?['coordinates'] as List? ?? [];
- final distance = (routeData['distance'] as num?)?.toDouble() ?? 0.0;
- final duration = (routeData['duration'] as num?)?.toInt() ?? 0;
-
- final leg = RouteLeg.fromCoordinates(
- coordinates,
- distance: distance,
- duration: duration,
- summary: (routeData['summary'] as String?) ?? 'Route',
- );
-
- return NavigationRoute(
- start: start,
- end: end,
- legs: [leg],
- totalDistance: distance,
- totalDuration: duration,
- );
- }
-}
-
-/// Result of an optimized trip calculation with reordered stops.
-class OptimizedRouteResult {
- final NavigationRoute route;
- final List orderedStops;
-
- OptimizedRouteResult({
- required this.route,
- required this.orderedStops,
- });
-}
diff --git a/deprecated/lib/models/schedule.dart b/deprecated/lib/models/schedule.dart
deleted file mode 100644
index 766c200..0000000
--- a/deprecated/lib/models/schedule.dart
+++ /dev/null
@@ -1,222 +0,0 @@
-import 'dart:convert';
-
-/// Bus Line model
-class BusLine {
- final int id;
- final int lineNumber;
- final String startStop;
- final String endStop;
- final int estimatedDuration; // in minutes
- final String? description;
-
- BusLine({
- required this.id,
- required this.lineNumber,
- required this.startStop,
- required this.endStop,
- required this.estimatedDuration,
- this.description,
- });
-
- factory BusLine.fromJson(Map json) {
- return BusLine(
- id: json['id'] as int,
- lineNumber: json['lineNumber'] as int,
- startStop: json['startStop'] as String,
- endStop: json['endStop'] as String,
- estimatedDuration: json['estimatedDuration'] as int,
- description: json['description'] as String?,
- );
- }
-
- Map toJson() {
- return {
- 'id': id,
- 'lineNumber': lineNumber,
- 'startStop': startStop,
- 'endStop': endStop,
- 'estimatedDuration': estimatedDuration,
- 'description': description,
- };
- }
-}
-
-/// Bus type model
-class BusType {
- final int id;
- final String name;
- final int seatCapacity;
- final String licensePlate;
-
- BusType({
- required this.id,
- required this.name,
- required this.seatCapacity,
- required this.licensePlate,
- });
-
- factory BusType.fromJson(Map json) {
- return BusType(
- id: json['id'] as int,
- name: json['name'] as String,
- seatCapacity: json['seatCapacity'] as int,
- licensePlate: json['licensePlate'] as String,
- );
- }
-
- Map toJson() {
- return {
- 'id': id,
- 'name': name,
- 'seatCapacity': seatCapacity,
- 'licensePlate': licensePlate,
- };
- }
-}
-
-/// Route model for daily schedule
-class Route {
- final int id;
- final BusLine busLine;
- final BusType busType;
- final DateTime startTime;
- final DateTime? endTime;
- final String status; // scheduled, in_progress, completed, cancelled
-
- Route({
- required this.id,
- required this.busLine,
- required this.busType,
- required this.startTime,
- this.endTime,
- required this.status,
- });
-
- factory Route.fromJson(Map json) {
- return Route(
- id: json['id'] as int,
- busLine: BusLine.fromJson(json['busLine'] as Map),
- busType: BusType.fromJson(json['busType'] as Map),
- startTime: DateTime.parse(json['startTime'] as String),
- endTime:
- json['endTime'] != null ? DateTime.parse(json['endTime'] as String) : null,
- status: json['status'] as String,
- );
- }
-
- Map toJson() {
- return {
- 'id': id,
- 'busLine': busLine.toJson(),
- 'busType': busType.toJson(),
- 'startTime': startTime.toIso8601String(),
- 'endTime': endTime?.toIso8601String(),
- 'status': status,
- };
- }
-}
-
-/// Daily schedule model
-class DailySchedule {
- final List routes;
- final DateTime date;
-
- DailySchedule({
- required this.routes,
- required this.date,
- });
-
- factory DailySchedule.fromJson(Map json) {
- return DailySchedule(
- routes: (json['routes'] as List)
- .map((r) => Route.fromJson(r as Map))
- .toList(),
- date: DateTime.parse(json['date'] as String),
- );
- }
-
- Map toJson() {
- return {
- 'routes': routes.map((r) => r.toJson()).toList(),
- 'date': date.toIso8601String(),
- };
- }
-}
-
-/// Stop model for the new schedule system.
-class ScheduleStop {
- final int id;
- final int order;
- final String name;
- final double latitude;
- final double longitude;
- final int estimatedArrivalMinutes;
-
- ScheduleStop({
- required this.id,
- required this.order,
- required this.name,
- required this.latitude,
- required this.longitude,
- required this.estimatedArrivalMinutes,
- });
-
- factory ScheduleStop.fromJson(Map json) {
- return ScheduleStop(
- id: (json['id'] as num).toInt(),
- order: (json['order'] as num).toInt(),
- name: (json['name'] ?? json['stopName'] ?? '') as String,
- latitude: (json['latitude'] as num).toDouble(),
- longitude: (json['longitude'] as num).toDouble(),
- estimatedArrivalMinutes: (json['estimatedArrivalMinutes'] as num?)?.toInt() ?? 0,
- );
- }
-}
-
-/// Schedule model for the new public schedule API.
-class ServiceSchedule {
- final int id;
- final int busLineId;
- final int busId;
- final DateTime startTime;
- final DateTime endTime;
- final String status;
- final int lineNumber;
- final String busName;
- final List weekdays;
-
- ServiceSchedule({
- required this.id,
- required this.busLineId,
- required this.busId,
- required this.startTime,
- required this.endTime,
- required this.status,
- required this.lineNumber,
- required this.busName,
- required this.weekdays,
- });
-
- factory ServiceSchedule.fromJson(Map json) {
- final rawWeekdays = json['weekdays'];
- final weekdays = rawWeekdays is List
- ? rawWeekdays.map((day) => (day as num).toInt()).toList()
- : rawWeekdays is String
- ? (jsonDecode(rawWeekdays) as List).map((day) => (day as num).toInt()).toList()
- : [];
-
- return ServiceSchedule(
- id: (json['id'] as num).toInt(),
- busLineId: (json['busLineId'] as num).toInt(),
- busId: (json['busId'] as num).toInt(),
- startTime: DateTime.parse(json['startTime'] as String),
- endTime: DateTime.parse(json['endTime'] as String),
- status: (json['status'] ?? 'planned') as String,
- lineNumber: (json['lineNumber'] as num).toInt(),
- busName: (json['busName'] ?? '') as String,
- weekdays: weekdays,
- );
- }
-
- bool get isRecurring => weekdays.isNotEmpty;
-}
diff --git a/deprecated/lib/models/user.dart b/deprecated/lib/models/user.dart
deleted file mode 100644
index 1de7a49..0000000
--- a/deprecated/lib/models/user.dart
+++ /dev/null
@@ -1,85 +0,0 @@
-/// User model
-class User {
- final int id;
- final int userCode;
- final String? job;
-
- User({
- required this.id,
- required this.userCode,
- this.job,
- });
-
- factory User.fromJson(Map json) {
- // userCode may be provided as 'userCode' or 'usercode' and may be int or string
- final dynamic rawUserCode = json['userCode'] ?? json['usercode'] ?? json['user_code'];
- int parsedUserCode;
- if (rawUserCode is int) {
- parsedUserCode = rawUserCode;
- } else if (rawUserCode is String) {
- parsedUserCode = int.tryParse(rawUserCode) ?? (throw FormatException('Invalid userCode'));
- } else {
- // If the backend doesn't return a userCode, treat as unknown (-1)
- parsedUserCode = -1;
- }
-
- return User(
- id: json['id'] as int,
- userCode: parsedUserCode,
- job: json['job'] as String?,
- );
- }
-
- Map toJson() {
- return {
- 'id': id,
- 'userCode': userCode,
- 'job': job,
- };
- }
-}
-
-/// Login response model
-class AuthResponse {
- final String token;
- final User? user;
-
- AuthResponse({
- required this.token,
- this.user,
- });
-
- factory AuthResponse.fromJson(Map json) {
- final dynamic rawToken = json['token'] ?? json['Token'] ?? json['authToken'];
- final token = rawToken?.toString();
- if (token == null || token.isEmpty) throw FormatException('Missing token in auth response');
-
- // Determine if a user object exists and appears valid
- Map? userMap;
- if (json.containsKey('user') && json['user'] is Map) {
- userMap = json['user'] as Map;
- } else {
- // maybe user fields are top-level (id, userCode, job)
- final hasUserFields = json.containsKey('id') || json.containsKey('userCode') || json.containsKey('usercode') || json.containsKey('user_code');
- if (hasUserFields) {
- // treat whole json as user map
- userMap = json.cast();
- }
- }
-
- User? parsedUser;
- if (userMap != null) {
- try {
- parsedUser = User.fromJson(userMap);
- } catch (e) {
- // If parsing user fails, ignore user but keep token
- parsedUser = null;
- }
- }
-
- return AuthResponse(
- token: token,
- user: parsedUser,
- );
- }
-}
diff --git a/deprecated/lib/screens/.gitkeep b/deprecated/lib/screens/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/deprecated/lib/screens/daily_schedule_screen.dart b/deprecated/lib/screens/daily_schedule_screen.dart
deleted file mode 100644
index 4eb253d..0000000
--- a/deprecated/lib/screens/daily_schedule_screen.dart
+++ /dev/null
@@ -1,371 +0,0 @@
-import 'package:flutter/material.dart';
-import '../models/schedule.dart' as schedule;
-import '../services/schedule_service.dart';
-import '../services/auth_service.dart';
-import '../services/exceptions.dart';
-import '../widgets/route_card.dart';
-
-class DailyScheduleScreen extends StatefulWidget {
- const DailyScheduleScreen({super.key});
-
- @override
- State createState() => _DailyScheduleScreenState();
-}
-
-class _DailyScheduleScreenState extends State {
- final _scheduleService = ScheduleService();
- final _authService = AuthService();
- late Future _scheduleFuture;
- DateTime _selectedDate = DateTime.now();
-
- @override
- void initState() {
- super.initState();
- _scheduleFuture = _scheduleService.getTodaySchedule();
- }
-
- Future _handleLogout() async {
- await _authService.logout();
- if (mounted) {
- Navigator.of(context).pushReplacementNamed('/login');
- }
- }
-
- Future _refreshSchedule() async {
- setState(() {
- _scheduleFuture = _scheduleService.getDailySchedule(_selectedDate);
- });
- }
-
- Future _selectDate() async {
- final colorScheme = Theme.of(context).colorScheme;
- final picked = await showDatePicker(
- context: context,
- initialDate: _selectedDate,
- firstDate: DateTime.now().subtract(const Duration(days: 7)),
- lastDate: DateTime.now().add(const Duration(days: 30)),
- builder: (context, child) {
- return Theme(
- data: Theme.of(context).copyWith(
- dialogBackgroundColor: colorScheme.surface,
- ),
- child: child!,
- );
- },
- );
-
- if (picked != null && picked != _selectedDate) {
- setState(() {
- _selectedDate = picked;
- });
- _refreshSchedule();
- }
- }
-
- // Group routes by hour for better visual organization
- Map> _groupByHour(List routes) {
- final grouped = >{};
- for (final route in routes) {
- final hour = route.startTime.hour;
- grouped.putIfAbsent(hour, () => []).add(route);
- }
- return grouped;
- }
-
- void _moveDay(int deltaDays) {
- setState(() {
- _selectedDate = _selectedDate.add(Duration(days: deltaDays));
- _scheduleFuture = _scheduleService.getDailySchedule(_selectedDate);
- });
- }
-
- @override
- Widget build(BuildContext context) {
- final colorScheme = Theme.of(context).colorScheme;
- final dateStr =
- '${_selectedDate.year}-${_selectedDate.month.toString().padLeft(2, '0')}-${_selectedDate.day.toString().padLeft(2, '0')}';
- final today = DateTime.now();
- final isToday = DateTime(_selectedDate.year, _selectedDate.month, _selectedDate.day) ==
- DateTime(today.year, today.month, today.day);
-
- return Scaffold(
- appBar: AppBar(
- title: const Text('Today on the Road'),
- elevation: 0,
- actions: [
- IconButton(
- icon: const Icon(Icons.logout),
- tooltip: 'Logout',
- onPressed: _handleLogout,
- ),
- ],
- ),
- body: Container(
- decoration: BoxDecoration(
- gradient: LinearGradient(
- colors: Theme.of(context).brightness == Brightness.dark
- ? const [Color(0xFF0B1220), Color(0xFF111827)]
- : const [Color(0xFFF1F5F9), Color(0xFFE2E8F0)],
- begin: Alignment.topCenter,
- end: Alignment.bottomCenter,
- ),
- ),
- child: Column(
- children: [
- Container(
- margin: const EdgeInsets.fromLTRB(16, 16, 16, 12),
- padding: const EdgeInsets.all(18),
- decoration: BoxDecoration(
- gradient: const LinearGradient(
- colors: [Color(0xFF0F172A), Color(0xFF1D4ED8)],
- begin: Alignment.topLeft,
- end: Alignment.bottomRight,
- ),
- borderRadius: BorderRadius.circular(24),
- boxShadow: [
- BoxShadow(
- color: Colors.black.withOpacity(0.16),
- blurRadius: 22,
- offset: const Offset(0, 10),
- ),
- ],
- ),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- isToday ? 'Vandaag' : 'Geplande datum',
- style: Theme.of(context).textTheme.labelSmall?.copyWith(
- color: Colors.white.withOpacity(0.78),
- ),
- ),
- const SizedBox(height: 6),
- Text(
- dateStr,
- style: Theme.of(context).textTheme.headlineMedium?.copyWith(
- color: Colors.white,
- fontWeight: FontWeight.w800,
- ),
- ),
- const SizedBox(height: 6),
- Text(
- 'Routes, stops en status in één overzicht',
- style: Theme.of(context).textTheme.bodyMedium?.copyWith(
- color: Colors.white.withOpacity(0.84),
- ),
- ),
- const SizedBox(height: 14),
- Align(
- alignment: Alignment.centerRight,
- child: Wrap(
- spacing: 8,
- runSpacing: 8,
- alignment: WrapAlignment.end,
- children: [
- SizedBox(
- height: 48,
- child: OutlinedButton.icon(
- onPressed: () => _moveDay(-1),
- icon: const Icon(Icons.chevron_left, size: 18),
- label: const Text('Vorige dag'),
- style: OutlinedButton.styleFrom(
- foregroundColor: Colors.white,
- side: BorderSide(color: Colors.white.withOpacity(0.28)),
- padding: const EdgeInsets.symmetric(horizontal: 16),
- ),
- ),
- ),
- SizedBox(
- height: 48,
- child: OutlinedButton.icon(
- onPressed: _selectDate,
- icon: const Icon(Icons.calendar_today, size: 18),
- label: const Text('Kies datum'),
- style: OutlinedButton.styleFrom(
- foregroundColor: Colors.white,
- side: BorderSide(color: Colors.white.withOpacity(0.28)),
- padding: const EdgeInsets.symmetric(horizontal: 16),
- ),
- ),
- ),
- SizedBox(
- height: 48,
- child: OutlinedButton.icon(
- onPressed: () => _moveDay(1),
- icon: const Icon(Icons.chevron_right, size: 18),
- label: const Text('Volgende dag'),
- style: OutlinedButton.styleFrom(
- foregroundColor: Colors.white,
- side: BorderSide(color: Colors.white.withOpacity(0.28)),
- padding: const EdgeInsets.symmetric(horizontal: 16),
- ),
- ),
- ),
- ],
- ),
- ),
- ],
- ),
- ),
- Expanded(
- child: FutureBuilder(
- future: _scheduleFuture,
- builder: (context, snapshot) {
- if (snapshot.connectionState == ConnectionState.waiting) {
- return const Center(child: CircularProgressIndicator());
- }
-
- if (snapshot.hasError) {
- // Auto-logout on session expiry
- if (snapshot.error is UnauthorizedException) {
- WidgetsBinding.instance.addPostFrameCallback((_) {
- _handleLogout();
- });
- }
-
- return Center(
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 24),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(
- Icons.error_outline,
- size: 64,
- color: colorScheme.error,
- ),
- const SizedBox(height: 16),
- Text(
- snapshot.error is UnauthorizedException
- ? 'Session Expired'
- : 'Failed to load schedule',
- style: Theme.of(context).textTheme.titleMedium,
- ),
- const SizedBox(height: 8),
- Text(
- snapshot.error is UnauthorizedException
- ? 'Redirecting to login...'
- : snapshot.error.toString(),
- style: Theme.of(context).textTheme.bodySmall,
- textAlign: TextAlign.center,
- ),
- if (snapshot.error is! UnauthorizedException) ...[
- const SizedBox(height: 24),
- FilledButton.icon(
- onPressed: _refreshSchedule,
- icon: const Icon(Icons.refresh),
- label: const Text('Retry'),
- ),
- ],
- ],
- ),
- ),
- );
- }
-
- if (!snapshot.hasData || snapshot.data!.routes.isEmpty) {
- return Center(
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 24),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(
- Icons.calendar_today,
- size: 64,
- color: colorScheme.outline,
- ),
- const SizedBox(height: 16),
- Text(
- 'Geen actieve ritten',
- style: Theme.of(context).textTheme.titleMedium,
- ),
- const SizedBox(height: 8),
- Text(
- 'Je hebt geen geplande ritten voor deze dag',
- style: Theme.of(context).textTheme.bodySmall?.copyWith(
- color: colorScheme.onSurfaceVariant,
- ),
- textAlign: TextAlign.center,
- ),
- ],
- ),
- ),
- );
- }
-
- final routes = [...snapshot.data!.routes]
- ..sort((a, b) => a.startTime.compareTo(b.startTime));
- final scheduledRoutes = routes.where((r) => r.status == 'scheduled').toList();
- final inProgressRoutes = routes.where((r) => r.status == 'in_progress').toList();
-
- // Merge and group by hour
- final allActiveRoutes = [...inProgressRoutes, ...scheduledRoutes]
- ..sort((a, b) => a.startTime.compareTo(b.startTime));
- final hourGroups = _groupByHour(allActiveRoutes);
- final sortedHours = hourGroups.keys.toList()..sort();
-
- return RefreshIndicator(
- onRefresh: _refreshSchedule,
- child: ListView(
- padding: const EdgeInsets.only(bottom: 16),
- children: [
- if (allActiveRoutes.isEmpty)
- Center(
- child: Padding(
- padding: const EdgeInsets.symmetric(vertical: 32),
- child: Text(
- 'Geen actieve ritten voor deze dag',
- style: Theme.of(context).textTheme.bodyMedium?.copyWith(
- color: colorScheme.onSurfaceVariant,
- ),
- ),
- ),
- )
- else
- ...sortedHours.map((hour) {
- final routesForHour = hourGroups[hour] ?? [];
- return Column(
- children: [
- Padding(
- padding: const EdgeInsets.only(left: 16, top: 16, bottom: 8),
- child: Row(
- children: [
- Text(
- '${hour.toString().padLeft(2, '0')}:00 uur',
- style: Theme.of(context).textTheme.titleMedium?.copyWith(
- fontWeight: FontWeight.bold,
- color: colorScheme.primary,
- ),
- ),
- const SizedBox(width: 12),
- Expanded(
- child: Container(
- height: 1,
- color: colorScheme.outlineVariant,
- ),
- ),
- ],
- ),
- ),
- ...routesForHour.map((route) => Padding(
- padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
- child: RouteCard(route: route, onTap: () {}),
- )),
- const SizedBox(height: 4),
- ],
- );
- }),
- const SizedBox(height: 8),
- ],
- ),
- );
- },
- ),
- ),
- ],
- ),
- ),
- );
- }
-}
diff --git a/deprecated/lib/screens/login_screen.dart b/deprecated/lib/screens/login_screen.dart
deleted file mode 100644
index 4bc55a1..0000000
--- a/deprecated/lib/screens/login_screen.dart
+++ /dev/null
@@ -1,314 +0,0 @@
-import 'package:flutter/material.dart';
-import '../services/auth_service.dart';
-import '../services/error_log_service.dart';
-import '../widgets/custom_input_field.dart';
-
-class LoginScreen extends StatefulWidget {
- const LoginScreen({super.key});
-
- @override
- State createState() => _LoginScreenState();
-}
-
-class _LoginScreenState extends State {
- final _formKey = GlobalKey();
- final _userCodeController = TextEditingController();
- final _passwordController = TextEditingController();
- final _authService = AuthService();
-
- bool _isLoading = false;
- String? _errorMessage;
-
- @override
- void dispose() {
- _userCodeController.dispose();
- _passwordController.dispose();
- super.dispose();
- }
-
- Future _handleLogin() async {
- if (!_formKey.currentState!.validate()) return;
-
- setState(() {
- _isLoading = true;
- _errorMessage = null;
- });
-
- try {
- final input = _userCodeController.text.trim();
- final parsedUserCode = int.tryParse(input);
- if (parsedUserCode == null) {
- await ErrorLogService.report(
- service: 'bus_terminal',
- partOfService: 'LoginScreen._handleLogin',
- error: 'User code must be a number',
- );
- if (mounted) {
- setState(() {
- _errorMessage = 'User code must be a number';
- });
- }
- return;
- }
-
- await _authService.login(
- userCode: parsedUserCode,
- password: _passwordController.text,
- );
-
- if (mounted) {
- // Navigate to daily schedule screen
- Navigator.of(context).pushReplacementNamed('/schedule');
- }
- } catch (e) {
- await ErrorLogService.report(
- service: 'bus_terminal',
- partOfService: 'LoginScreen._handleLogin.catch',
- error: e.toString(),
- );
- if (mounted) {
- setState(() {
- _errorMessage = e.toString().replaceAll('Exception: ', '');
- });
- }
- } finally {
- if (mounted) {
- setState(() => _isLoading = false);
- }
- }
- }
-
- String? _validateUserCode(String? value) {
- final v = value?.trim();
- if (v?.isEmpty ?? true) {
- return 'User code is required';
- }
- if (int.tryParse(v!) == null) {
- return 'User code must be a number';
- }
- return null;
- }
-
- String? _validatePassword(String? value) {
- if (value?.isEmpty ?? true) {
- return 'Password is required';
- }
- if ((value?.length ?? 0) < 3) {
- return 'Password must be at least 3 characters';
- }
- return null;
- }
-
- @override
- Widget build(BuildContext context) {
- final colorScheme = Theme.of(context).colorScheme;
-
- return Scaffold(
- body: Container(
- decoration: BoxDecoration(
- gradient: LinearGradient(
- colors: Theme.of(context).brightness == Brightness.dark
- ? const [Color(0xFF0B1220), Color(0xFF111827), Color(0xFF1D4ED8)]
- : const [Color(0xFFF1F5F9), Color(0xFFE2E8F0), Color(0xFFBAE6FD)],
- begin: Alignment.topLeft,
- end: Alignment.bottomRight,
- ),
- ),
- child: SafeArea(
- child: SingleChildScrollView(
- child: Padding(
- padding: const EdgeInsets.all(20.0),
- child: Form(
- key: _formKey,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: [
- const SizedBox(height: 24),
- Container(
- padding: const EdgeInsets.all(20),
- decoration: BoxDecoration(
- gradient: const LinearGradient(
- colors: [Color(0xFF0F172A), Color(0xFF1D4ED8)],
- begin: Alignment.topLeft,
- end: Alignment.bottomRight,
- ),
- borderRadius: BorderRadius.circular(24),
- boxShadow: [
- BoxShadow(
- color: Colors.black.withOpacity(0.18),
- blurRadius: 24,
- offset: const Offset(0, 12),
- ),
- ],
- ),
- child: Row(
- children: [
- Container(
- width: 56,
- height: 56,
- decoration: BoxDecoration(
- color: Colors.white.withOpacity(0.16),
- shape: BoxShape.circle,
- ),
- child: const Icon(
- Icons.directions_bus,
- color: Colors.white,
- size: 30,
- ),
- ),
- const SizedBox(width: 16),
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- 'Bus Terminal',
- style: Theme.of(context).textTheme.titleLarge?.copyWith(
- color: Colors.white,
- fontWeight: FontWeight.w800,
- ),
- ),
- const SizedBox(height: 4),
- Text(
- 'Driver access dashboard',
- style: Theme.of(context).textTheme.bodyMedium?.copyWith(
- color: Colors.white.withOpacity(0.82),
- ),
- ),
- ],
- ),
- ),
- ],
- ),
- ),
- const SizedBox(height: 18),
- Container(
- padding: const EdgeInsets.all(20),
- decoration: BoxDecoration(
- color: colorScheme.surface.withOpacity(0.92),
- borderRadius: BorderRadius.circular(24),
- border: Border.all(color: colorScheme.outline.withOpacity(0.14)),
- boxShadow: [
- BoxShadow(
- color: Colors.black.withOpacity(0.08),
- blurRadius: 22,
- offset: const Offset(0, 10),
- ),
- ],
- ),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.stretch,
- children: [
- Text(
- 'Driver Login',
- style: Theme.of(context).textTheme.headlineMedium?.copyWith(
- fontWeight: FontWeight.w800,
- ),
- ),
- const SizedBox(height: 8),
- Text(
- 'Sign in to view your route, stops and live navigation.',
- style: Theme.of(context).textTheme.bodyMedium?.copyWith(
- color: colorScheme.onSurfaceVariant,
- ),
- ),
- const SizedBox(height: 28),
-
- if (_errorMessage != null) ...[
- Container(
- padding: const EdgeInsets.all(14),
- decoration: BoxDecoration(
- color: colorScheme.error.withOpacity(0.12),
- border: Border.all(color: colorScheme.error.withOpacity(0.35)),
- borderRadius: BorderRadius.circular(16),
- ),
- child: Row(
- children: [
- Icon(Icons.error_outline, color: colorScheme.error),
- const SizedBox(width: 10),
- Expanded(
- child: Text(
- _errorMessage!,
- style: Theme.of(context).textTheme.bodyMedium?.copyWith(
- color: colorScheme.onSurface,
- ),
- ),
- ),
- ],
- ),
- ),
- const SizedBox(height: 20),
- ],
-
- CustomInputField(
- label: 'User Code',
- hint: 'Enter your user code',
- controller: _userCodeController,
- validator: _validateUserCode,
- ),
- const SizedBox(height: 20),
- CustomInputField(
- label: 'Password',
- hint: 'Enter your password',
- controller: _passwordController,
- obscureText: true,
- validator: _validatePassword,
- ),
- const SizedBox(height: 28),
-
- FilledButton(
- onPressed: _isLoading ? null : _handleLogin,
- child: _isLoading
- ? SizedBox(
- height: 24,
- width: 24,
- child: CircularProgressIndicator(
- strokeWidth: 2,
- valueColor: AlwaysStoppedAnimation(colorScheme.onPrimary),
- ),
- )
- : const Text('Login'),
- ),
- const SizedBox(height: 16),
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- _statusPill(Icons.shield_outlined, 'Secure access'),
- const SizedBox(width: 10),
- _statusPill(Icons.route_outlined, 'Live route data'),
- ],
- ),
- ],
- ),
- ),
- ],
- ),
- ),
- ),
- ),
- ),
- ),
- );
- }
-
- Widget _statusPill(IconData icon, String label) {
- return Container(
- padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
- decoration: BoxDecoration(
- color: Theme.of(context).colorScheme.surfaceContainerHighest.withOpacity(0.72),
- borderRadius: BorderRadius.circular(999),
- ),
- child: Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Icon(icon, size: 16),
- const SizedBox(width: 6),
- Text(
- label,
- style: Theme.of(context).textTheme.labelMedium,
- ),
- ],
- ),
- );
- }
-}
diff --git a/deprecated/lib/screens/navigation_screen.dart b/deprecated/lib/screens/navigation_screen.dart
deleted file mode 100644
index 5a1d473..0000000
--- a/deprecated/lib/screens/navigation_screen.dart
+++ /dev/null
@@ -1,913 +0,0 @@
-// ignore_for_file: deprecated_member_use
-
-import 'dart:math';
-import 'package:flutter/material.dart';
-import 'package:flutter_map/flutter_map.dart';
-import 'package:latlong2/latlong.dart';
-import '../models/navigation.dart';
-import '../models/schedule.dart' as schedule;
-import '../services/navigation_service.dart';
-import '../services/schedule_service.dart';
-
-class NavigationScreen extends StatefulWidget {
- final schedule.Route route;
- final List? initialStops;
-
- const NavigationScreen({
- super.key,
- required this.route,
- this.initialStops,
- });
-
- @override
- State createState() => _NavigationScreenState();
-}
-
-class _NavigationScreenState extends State {
- final _navigationService = NavigationService();
- final _scheduleService = ScheduleService();
- late MapController _mapController;
-
- NavigationRoute? _currentRoute;
- NavigationPoint? _currentLocation;
- bool _isLoading = false;
- String? _errorMessage;
- List? _alternativeRoutes;
- List? _stops;
- String? _stopsFetchError;
- int _currentStopIndex = 0;
- final Set _completedStops = {};
-
- @override
- void initState() {
- super.initState();
- _mapController = MapController();
- _initializeNavigation();
- }
-
- Future _initializeNavigation() async {
- setState(() {
- _isLoading = true;
- _errorMessage = null;
- });
-
- try {
- // Get current location
- final currentLoc = await _navigationService.getCurrentLocation();
- setState(() => _currentLocation = currentLoc);
-
- // Use provided initial stops when available, otherwise fetch from API
- if (widget.initialStops != null) {
- _stops = widget.initialStops;
- _stopsFetchError = null;
- } else {
- try {
- _stops = await _scheduleService.getStops(widget.route.busLine.id);
- _stopsFetchError = null;
- } catch (e) {
- _stops = [];
- _stopsFetchError = e.toString().replaceAll('Exception: ', '');
- }
- }
-
- // Defensive: filter out invalid stops (missing/NaN coordinates) and deduplicate
- if (_stops != null) {
- _stops = _stops!
- .where((s) => s.latitude.isFinite && s.longitude.isFinite)
- .toList();
-
- // Remove exact duplicates by lat/lon
- final seen = {};
- _stops = _stops!.where((s) {
- final key = '${s.latitude.toStringAsFixed(6)}|${s.longitude.toStringAsFixed(6)}';
- if (seen.contains(key)) return false;
- seen.add(key);
- return true;
- }).toList();
- }
-
- // Determine start and end points: prefer stop locations if available.
- // If no stops are returned from the API, geocode the stop names.
- late NavigationPoint startPoint;
- late NavigationPoint endPoint;
-
- if (_stops != null && _stops!.length >= 2) {
- final hasScheduleStops = widget.initialStops != null;
-
- if (!hasScheduleStops) {
- final optimized = await _navigationService.getOptimizedRouteThroughStops(stops: _stops!);
- _stops = optimized.orderedStops;
- if (mounted) {
- setState(() {
- _currentRoute = optimized.route;
- _alternativeRoutes = null;
- _isLoading = false;
- });
- WidgetsBinding.instance.addPostFrameCallback((_) => _fitMapToRoute(optimized.route));
- }
- return;
- }
-
- final navRoute = await _navigationService.getRouteThroughStops(stops: _stops!);
- startPoint = _stops!.first;
- endPoint = _stops!.last;
-
- if (mounted) {
- setState(() {
- _currentRoute = navRoute;
- _alternativeRoutes = null;
- _isLoading = false;
- });
-
- WidgetsBinding.instance.addPostFrameCallback((_) => _fitMapToRoute(navRoute));
- }
-
- return;
- } else if (_stops != null && _stops!.length == 1) {
- // With exactly one linked stop, force that stop into the route as start
- // so the marker is guaranteed to be in-view.
- startPoint = _stops!.first;
-
- try {
- endPoint = await _navigationService.geocodePlace(widget.route.busLine.endStop);
- } catch (_) {
- endPoint = NavigationPoint(
- latitude: startPoint.latitude + 0.01,
- longitude: startPoint.longitude + 0.01,
- name: widget.route.busLine.endStop,
- );
- }
- } else {
- // Try geocoding names; fall back to conservative defaults on failure
- try {
- startPoint = await _navigationService.geocodePlace(widget.route.busLine.startStop);
- } catch (_) {
- startPoint = NavigationPoint(
- latitude: 52.5200,
- longitude: 13.4050,
- name: widget.route.busLine.startStop,
- );
- }
-
- try {
- endPoint = await _navigationService.geocodePlace(widget.route.busLine.endStop);
- } catch (_) {
- endPoint = NavigationPoint(
- latitude: 52.5300,
- longitude: 13.4150,
- name: widget.route.busLine.endStop,
- );
- }
- }
-
- // Get route without waypoints
- final navRoute = await _navigationService.getRoute(start: startPoint, end: endPoint);
-
- // Get alternative routes (but cap to a small number)
- final alternatives = await _navigationService.getMultipleRoutes(start: startPoint, end: endPoint);
-
- if (mounted) {
- setState(() {
- _currentRoute = navRoute;
- _alternativeRoutes = alternatives.take(2).toList();
- _isLoading = false;
- });
-
- // Fit map to route bounds after first frame so MapController is attached
- WidgetsBinding.instance.addPostFrameCallback((_) => _fitMapToRoute(navRoute));
- }
- } catch (e) {
- if (mounted) {
- setState(() {
- _errorMessage = e.toString().replaceAll('Exception: ', '');
- _isLoading = false;
- });
- }
- }
- }
-
- void _fitMapToRoute(NavigationRoute route) {
- // Build list of points to include in bounds, filter invalids
- final allPoints = [];
- allPoints.addAll(route.getAllPoints().where((p) => p.latitude.isFinite && p.longitude.isFinite).map((point) => LatLng(point.latitude, point.longitude)));
- allPoints.addAll((_stops ?? []).where((s) => s.latitude.isFinite && s.longitude.isFinite).map((stop) => LatLng(stop.latitude, stop.longitude)));
- if (_currentLocation != null && _currentLocation!.latitude.isFinite && _currentLocation!.longitude.isFinite) {
- allPoints.add(LatLng(_currentLocation!.latitude, _currentLocation!.longitude));
- }
-
- if (allPoints.isEmpty) return;
-
- double minLat = allPoints.first.latitude;
- double maxLat = allPoints.first.latitude;
- double minLon = allPoints.first.longitude;
- double maxLon = allPoints.first.longitude;
-
- for (final point in allPoints) {
- minLat = min(minLat, point.latitude);
- maxLat = max(maxLat, point.latitude);
- minLon = min(minLon, point.longitude);
- maxLon = max(maxLon, point.longitude);
- }
-
- // Clamp bounds to a reasonable maximum span to avoid huge map tiles requests
- const double maxSpanDegrees = 2.0; // ~222km lat span per degree ~111km; 2 degrees ~222km
- final latSpan = maxLat - minLat;
- final lonSpan = maxLon - minLon;
-
- double centerLat = (minLat + maxLat) / 2.0;
- double centerLon = (minLon + maxLon) / 2.0;
-
- double halfLat = latSpan / 2.0;
- double halfLon = lonSpan / 2.0;
-
- if (latSpan > maxSpanDegrees) halfLat = maxSpanDegrees / 2.0;
- if (lonSpan > maxSpanDegrees) halfLon = maxSpanDegrees / 2.0;
-
- final clampedMinLat = centerLat - halfLat;
- final clampedMaxLat = centerLat + halfLat;
- final clampedMinLon = centerLon - halfLon;
- final clampedMaxLon = centerLon + halfLon;
-
- final bounds = LatLngBounds(
- LatLng(clampedMinLat, clampedMinLon),
- LatLng(clampedMaxLat, clampedMaxLon),
- );
-
- _mapController.fitBounds(
- bounds,
- options: const FitBoundsOptions(padding: EdgeInsets.all(100)),
- );
- }
-
- int _nextUncompletedStopIndex([int startIndex = 0]) {
- if (_stops == null || _stops!.isEmpty) return 0;
-
- for (var index = startIndex; index < _stops!.length; index++) {
- if (!_completedStops.contains(index)) {
- return index;
- }
- }
-
- return _stops!.length - 1;
- }
-
- Future _refreshRouteFromIndex(int index) async {
- if (_stops == null || _stops!.isEmpty) return;
- if (index < 0 || index >= _stops!.length) return;
-
- setState(() {
- _isLoading = true;
- _errorMessage = null;
- _currentStopIndex = index;
- });
-
- try {
- final remainingStops = _stops!.sublist(index);
- final navRoute = remainingStops.length >= 2
- ? await _navigationService.getRouteThroughStops(stops: remainingStops)
- : _currentRoute;
-
- if (mounted) {
- setState(() {
- if (navRoute != null) {
- _currentRoute = navRoute;
- }
- _alternativeRoutes = null;
- _isLoading = false;
- });
-
- if (navRoute != null) {
- WidgetsBinding.instance.addPostFrameCallback((_) => _fitMapToRoute(navRoute));
- }
- }
- } catch (e) {
- if (mounted) {
- setState(() {
- _errorMessage = e.toString().replaceAll('Exception: ', '');
- _isLoading = false;
- });
- }
- }
- }
-
- Future _focusStop(int index) async {
- if (_stops == null || _stops!.isEmpty) return;
- if (index < 0 || index >= _stops!.length) return;
- await _refreshRouteFromIndex(index);
- }
-
- Future _markStopCompleted(int index) async {
- if (_stops == null || _stops!.isEmpty) return;
- if (index < 0 || index >= _stops!.length) return;
-
- // When this screen is opened from schedule overview, route.id maps to scheduleId.
- if (widget.initialStops != null) {
- try {
- await _scheduleService.markScheduleStopPassed(
- scheduleId: widget.route.id,
- stopOrder: index + 1,
- actualPassedAt: DateTime.now(),
- );
- } catch (e) {
- if (mounted) {
- setState(() {
- _errorMessage = 'Stop update mislukt: ${e.toString().replaceAll('Exception: ', '')}';
- });
- }
- }
- }
-
- setState(() {
- _completedStops.add(index);
- });
-
- final nextIndex = _nextUncompletedStopIndex(index + 1);
- await _refreshRouteFromIndex(nextIndex);
- }
-
- double get _routeProgress {
- if (_stops == null || _stops!.isEmpty) return 0;
- if (_stops!.length == 1) return 1;
- return _currentStopIndex / (_stops!.length - 1);
- }
-
- Color get _routeColor => Color.lerp(Colors.blue, Colors.orange, _routeProgress) ?? Colors.blue;
-
- Color _stopColor(int index) {
- if (_completedStops.contains(index) || index < _currentStopIndex) return Colors.green;
- if (index == _currentStopIndex) return Colors.orange;
- return Colors.blueGrey;
- }
-
- IconData _stopIcon(int index) {
- if (_completedStops.contains(index) || index < _currentStopIndex) return Icons.check_circle;
- if (index == _currentStopIndex) return Icons.radio_button_checked;
- return Icons.location_on;
- }
-
- bool _isStopCompleted(int index) => _completedStops.contains(index) || index < _currentStopIndex;
-
- bool _hasStopNearPoint(NavigationPoint point, {double threshold = 0.00005}) {
- if (_stops == null || _stops!.isEmpty) return false;
-
- for (final stop in _stops!) {
- final latDiff = (stop.latitude - point.latitude).abs();
- final lonDiff = (stop.longitude - point.longitude).abs();
- if (latDiff <= threshold && lonDiff <= threshold) {
- return true;
- }
- }
- return false;
- }
-
- NavigationPoint? get _currentStopPoint {
- if (_stops == null || _stops!.isEmpty) return null;
- return _stops![_currentStopIndex.clamp(0, _stops!.length - 1)];
- }
-
- NavigationPoint? get _nextStopPoint {
- if (_stops == null || _stops!.isEmpty) return null;
- final nextIndex = _nextUncompletedStopIndex(_currentStopIndex + 1);
- return _stops![nextIndex.clamp(0, _stops!.length - 1)];
- }
-
- double get _completionRatio {
- if (_stops == null || _stops!.isEmpty) return 0;
- return _completedStops.length / _stops!.length;
- }
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text('Route ${widget.route.busLine.lineNumber} Navigation'),
- elevation: 0,
- ),
- body: Row(
- children: [
- // Map area (left pane)
- Expanded(
- flex: 6,
- child: _currentRoute != null
- ? FlutterMap(
- mapController: _mapController,
- options: MapOptions(
- initialCenter: LatLng(
- _currentRoute!.start.latitude,
- _currentRoute!.start.longitude,
- ),
- initialZoom: 13.0,
- ),
- children: [
- TileLayer(
- urlTemplate:
- 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
- userAgentPackageName: 'com.example.bus_terminal',
- ),
- MarkerLayer(
- markers: [
- ...(_stops ?? []).asMap().entries.map((entry) {
- final index = entry.key;
- final stop = entry.value;
- final color = _stopColor(index);
-
- return Marker(
- point: LatLng(stop.latitude, stop.longitude),
- width: 46,
- height: 46,
- child: Container(
- decoration: BoxDecoration(
- color: color,
- shape: BoxShape.circle,
- border: Border.all(
- color: Colors.white,
- width: 3,
- ),
- boxShadow: [
- BoxShadow(
- color: Colors.black.withOpacity(0.22),
- blurRadius: 10,
- offset: const Offset(0, 4),
- ),
- ],
- ),
- child: Stack(
- alignment: Alignment.center,
- children: [
- Icon(
- _stopIcon(index),
- color: Colors.white,
- size: 20,
- ),
- Positioned(
- bottom: 4,
- child: Container(
- padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 1),
- decoration: BoxDecoration(
- color: Colors.black.withOpacity(0.35),
- borderRadius: BorderRadius.circular(999),
- ),
- child: Text(
- '${index + 1}',
- style: const TextStyle(
- color: Colors.white,
- fontSize: 9,
- fontWeight: FontWeight.w800,
- ),
- ),
- ),
- ),
- ],
- ),
- ),
- );
- }),
- // Start marker
- if (!_hasStopNearPoint(_currentRoute!.start))
- Marker(
- point: LatLng(
- _currentRoute!.start.latitude,
- _currentRoute!.start.longitude,
- ),
- width: 40,
- height: 40,
- child: Container(
- decoration: BoxDecoration(
- color: Colors.green,
- shape: BoxShape.circle,
- border: Border.all(
- color: Colors.white,
- width: 2,
- ),
- ),
- child: const Icon(
- Icons.location_on,
- color: Colors.white,
- size: 20,
- ),
- ),
- ),
- // End marker
- if (!_hasStopNearPoint(_currentRoute!.end))
- Marker(
- point: LatLng(
- _currentRoute!.end.latitude,
- _currentRoute!.end.longitude,
- ),
- width: 40,
- height: 40,
- child: Container(
- decoration: BoxDecoration(
- color: Colors.red,
- shape: BoxShape.circle,
- border: Border.all(
- color: Colors.white,
- width: 2,
- ),
- ),
- child: const Icon(
- Icons.location_on,
- color: Colors.white,
- size: 20,
- ),
- ),
- ),
- // Current location marker
- if (_currentLocation != null)
- Marker(
- point: LatLng(
- _currentLocation!.latitude,
- _currentLocation!.longitude,
- ),
- width: 30,
- height: 30,
- child: Container(
- decoration: BoxDecoration(
- color: Colors.blue,
- shape: BoxShape.circle,
- border: Border.all(
- color: Colors.white,
- width: 2,
- ),
- ),
- child: const Icon(
- Icons.directions_bus,
- color: Colors.white,
- size: 16,
- ),
- ),
- ),
- ],
- ),
- PolylineLayer(
- polylines: [
- // Main route
- Polyline(
- points: _currentRoute!
- .getAllPoints()
- .map((p) => LatLng(p.latitude, p.longitude))
- .toList(),
- color: _routeColor,
- strokeWidth: 5,
- ),
- // Alternative routes (lighter)
- if (_alternativeRoutes != null)
- ...List.generate(
- _alternativeRoutes!.length,
- (i) => Polyline(
- points: _alternativeRoutes![i]
- .getAllPoints()
- .map((p) => LatLng(p.latitude, p.longitude))
- .toList(),
- color: Colors.grey.withOpacity(0.5),
- strokeWidth: 2,
- ),
- ),
- ],
- ),
- ],
- )
- : (_isLoading
- ? const Center(child: CircularProgressIndicator())
- : Center(
- child: _errorMessage != null
- ? Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(
- Icons.error_outline,
- size: 64,
- color: Colors.red[300],
- ),
- const SizedBox(height: 16),
- Text(
- 'Failed to load route',
- style:
- Theme.of(context).textTheme.titleMedium,
- ),
- const SizedBox(height: 8),
- Text(
- _errorMessage!,
- style: Theme.of(context).textTheme.bodySmall,
- textAlign: TextAlign.center,
- ),
- ],
- )
- : const Text('No route'))),
- ),
-
- // Vertical divider
- Container(width: 1, color: Colors.grey[200]),
-
- // Stops / Info panel (right pane)
- Expanded(
- flex: 4,
- child: Container(
- decoration: BoxDecoration(
- color: Colors.white,
- borderRadius: const BorderRadius.only(
- topLeft: Radius.circular(16),
- bottomLeft: Radius.circular(16),
- ),
- boxShadow: [
- BoxShadow(
- color: Colors.black.withOpacity(0.1),
- blurRadius: 10,
- offset: const Offset(-2, 0),
- ),
- ],
- ),
- child: Padding(
- padding: const EdgeInsets.all(12),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Container(
- padding: const EdgeInsets.all(16),
- decoration: BoxDecoration(
- gradient: const LinearGradient(
- colors: [Color(0xFF0F172A), Color(0xFF1D4ED8)],
- begin: Alignment.topLeft,
- end: Alignment.bottomRight,
- ),
- borderRadius: BorderRadius.circular(18),
- boxShadow: [
- BoxShadow(
- color: Colors.black.withOpacity(0.12),
- blurRadius: 18,
- offset: const Offset(0, 8),
- ),
- ],
- ),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- children: [
- Container(
- width: 42,
- height: 42,
- decoration: BoxDecoration(
- color: Colors.white.withOpacity(0.18),
- shape: BoxShape.circle,
- ),
- child: const Icon(
- Icons.route,
- color: Colors.white,
- ),
- ),
- const SizedBox(width: 12),
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- 'Route ${widget.route.busLine.lineNumber}',
- style: Theme.of(context).textTheme.titleMedium?.copyWith(
- color: Colors.white,
- fontWeight: FontWeight.bold,
- ),
- ),
- const SizedBox(height: 2),
- Text(
- '${widget.route.busLine.startStop} → ${widget.route.busLine.endStop}',
- style: Theme.of(context).textTheme.bodySmall?.copyWith(
- color: Colors.white.withOpacity(0.85),
- ),
- maxLines: 2,
- overflow: TextOverflow.ellipsis,
- ),
- ],
- ),
- ),
- ],
- ),
- const SizedBox(height: 16),
- ClipRRect(
- borderRadius: BorderRadius.circular(999),
- child: LinearProgressIndicator(
- minHeight: 10,
- value: _completionRatio,
- backgroundColor: Colors.white.withOpacity(0.12),
- valueColor: const AlwaysStoppedAnimation(Colors.amberAccent),
- ),
- ),
- const SizedBox(height: 10),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- '${(_completionRatio * 100).round()}% afgerond',
- style: Theme.of(context).textTheme.bodySmall?.copyWith(
- color: Colors.white,
- fontWeight: FontWeight.w600,
- ),
- ),
- Text(
- '${_completedStops.length}/${_stops?.length ?? 0} stops',
- style: Theme.of(context).textTheme.bodySmall?.copyWith(
- color: Colors.white.withOpacity(0.85),
- ),
- ),
- ],
- ),
- const SizedBox(height: 12),
- Row(
- children: [
- Expanded(
- child: _buildSummaryPill(
- 'Huidig',
- _currentStopPoint?.name ?? 'Geen stop',
- Icons.radio_button_checked,
- ),
- ),
- const SizedBox(width: 8),
- Expanded(
- child: _buildSummaryPill(
- 'Volgend',
- _nextStopPoint?.name ?? 'Einde route',
- Icons.skip_next,
- ),
- ),
- ],
- ),
- const SizedBox(height: 12),
- SizedBox(
- width: double.infinity,
- child: ElevatedButton.icon(
- style: ElevatedButton.styleFrom(
- backgroundColor: Colors.white,
- foregroundColor: const Color(0xFF0F172A),
- padding: const EdgeInsets.symmetric(vertical: 14),
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(14),
- ),
- ),
- onPressed: _stops == null || _stops!.isEmpty || _isStopCompleted(_currentStopIndex)
- ? null
- : () => _markStopCompleted(_currentStopIndex),
- icon: const Icon(Icons.check_circle_outline),
- label: const Text('Markeer huidige stop afgerond'),
- ),
- ),
- ],
- ),
- ),
- const SizedBox(height: 14),
- Container(
- padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10),
- decoration: BoxDecoration(
- color: Colors.grey[100],
- borderRadius: BorderRadius.circular(12),
- ),
- child: Row(
- children: [
- _legendDot(Colors.green, 'Afgerond'),
- const SizedBox(width: 12),
- _legendDot(Colors.orange, 'Actief'),
- const SizedBox(width: 12),
- _legendDot(Colors.blueGrey, 'Te doen'),
- ],
- ),
- ),
- if (_stopsFetchError != null) ...[
- const SizedBox(height: 10),
- Container(
- width: double.infinity,
- padding: const EdgeInsets.all(10),
- decoration: BoxDecoration(
- color: Colors.red.withOpacity(0.08),
- borderRadius: BorderRadius.circular(10),
- border: Border.all(color: Colors.red.withOpacity(0.25)),
- ),
- child: Text(
- 'Stops konden niet geladen worden voor buslijn ${widget.route.busLine.id}: $_stopsFetchError',
- style: Theme.of(context).textTheme.bodySmall,
- ),
- ),
- ],
- const SizedBox(height: 12),
- Text(
- 'Stops',
- style: Theme.of(context)
- .textTheme
- .titleMedium
- ?.copyWith(fontWeight: FontWeight.bold),
- ),
- const SizedBox(height: 8),
- Expanded(
- child: _stops == null || _stops!.isEmpty
- ? Center(
- child: Text(
- 'No stops available for this line',
- style: Theme.of(context).textTheme.bodySmall,
- ),
- )
- : ListView.separated(
- itemCount: _stops!.length,
- separatorBuilder: (context, index) => const Divider(),
- itemBuilder: (context, index) {
- final s = _stops![index];
- final color = _stopColor(index);
- final completed = _isStopCompleted(index);
- final isCurrent = index == _currentStopIndex;
- return ListTile(
- leading: CircleAvatar(
- radius: 14,
- backgroundColor: color,
- child: Icon(
- _stopIcon(index),
- color: Colors.white,
- size: 16,
- ),
- ),
- title: Text(s.name ?? 'Stop ${index + 1}'),
- subtitle: Text('${s.latitude.toStringAsFixed(5)}, ${s.longitude.toStringAsFixed(5)}'),
- trailing: completed
- ? const Chip(
- label: Text('Afgerond'),
- visualDensity: VisualDensity.compact,
- )
- : TextButton.icon(
- onPressed: () => _markStopCompleted(index),
- icon: const Icon(Icons.check, size: 18),
- label: Text(isCurrent ? 'Afronden' : 'Klaarzetten'),
- ),
- onTap: () => _focusStop(index),
- );
- },
- ),
- ),
- ],
- ),
- ),
- ),
- ),
- ],
- ),
- );
- }
-
- Widget _legendDot(Color color, String label) {
- return Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Container(
- width: 10,
- height: 10,
- decoration: BoxDecoration(
- color: color,
- shape: BoxShape.circle,
- ),
- ),
- const SizedBox(width: 6),
- Text(
- label,
- style: Theme.of(context).textTheme.bodySmall,
- ),
- ],
- );
- }
-
- Widget _buildSummaryPill(String title, String value, IconData icon) {
- return Container(
- padding: const EdgeInsets.all(12),
- decoration: BoxDecoration(
- color: Colors.white.withOpacity(0.12),
- borderRadius: BorderRadius.circular(14),
- border: Border.all(color: Colors.white.withOpacity(0.16)),
- ),
- child: Row(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Icon(icon, color: Colors.white, size: 18),
- const SizedBox(width: 8),
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- title,
- style: Theme.of(context).textTheme.labelSmall?.copyWith(
- color: Colors.white.withOpacity(0.75),
- letterSpacing: 0.2,
- ),
- ),
- const SizedBox(height: 4),
- Text(
- value,
- style: Theme.of(context).textTheme.bodySmall?.copyWith(
- color: Colors.white,
- fontWeight: FontWeight.w600,
- ),
- maxLines: 2,
- overflow: TextOverflow.ellipsis,
- ),
- ],
- ),
- ),
- ],
- ),
- );
- }
-}
diff --git a/deprecated/lib/screens/recurring_schedules_screen.dart b/deprecated/lib/screens/recurring_schedules_screen.dart
deleted file mode 100644
index 83620d7..0000000
--- a/deprecated/lib/screens/recurring_schedules_screen.dart
+++ /dev/null
@@ -1,332 +0,0 @@
-// ignore_for_file: use_build_context_synchronously
-
-import 'package:flutter/material.dart';
-import '../models/schedule.dart' as sched;
-import '../services/schedule_service.dart';
-
-class RecurringSchedulesScreen extends StatefulWidget {
- const RecurringSchedulesScreen({super.key});
-
- @override
- State createState() => _RecurringSchedulesScreenState();
-}
-
-class _RecurringSchedulesScreenState extends State {
- final _scheduleService = ScheduleService();
- late Future> _schedulesFuture;
- String _selectedSortBy = 'line'; // 'line', 'time', 'weekday'
- final Set _expandedLineIds = {};
-
- @override
- void initState() {
- super.initState();
- _loadRecurringSchedules();
- }
-
- void _loadRecurringSchedules() {
- _schedulesFuture = _scheduleService.getRecurringSchedules();
- }
-
- String _formatWeekdays(List weekdays) {
- const dayLabels = ['Zo', 'Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za'];
- if (weekdays.isEmpty) return 'Eenmalig';
- if (weekdays.length == 7) return 'Dagelijks';
-
- final sorted = weekdays.toSet().toList()..sort((a, b) => a.compareTo(b));
- return sorted.map((d) => dayLabels[d]).join(', ');
- }
-
- String _formatTime(DateTime dt) {
- return '${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}';
- }
-
- List _sortSchedules(List schedules) {
- final sorted = List.from(schedules);
-
- switch (_selectedSortBy) {
- case 'line':
- sorted.sort((a, b) => a.lineNumber.compareTo(b.lineNumber));
- break;
- case 'time':
- sorted.sort((a, b) => a.startTime.compareTo(b.startTime));
- break;
- case 'weekday':
- sorted.sort((a, b) {
- final aFirst = a.weekdays.isEmpty ? 7 : a.weekdays.first;
- final bFirst = b.weekdays.isEmpty ? 7 : b.weekdays.first;
- return aFirst.compareTo(bFirst);
- });
- break;
- }
-
- return sorted;
- }
-
- Map> _groupByLine(List schedules) {
- final grouped = >{};
- for (final schedule in schedules) {
- grouped.putIfAbsent(schedule.lineNumber, () => []).add(schedule);
- }
- return grouped;
- }
-
- @override
- Widget build(BuildContext context) {
- final colorScheme = Theme.of(context).colorScheme;
-
- return Scaffold(
- appBar: AppBar(
- title: const Text('Vaste Diensten'),
- centerTitle: true,
- actions: [
- PopupMenuButton(
- onSelected: (value) {
- setState(() => _selectedSortBy = value);
- },
- itemBuilder: (context) => [
- PopupMenuItem(
- value: 'line',
- child: Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Icon(Icons.sort_by_alpha, color: _selectedSortBy == 'line' ? colorScheme.primary : null),
- const SizedBox(width: 8),
- const Text('Lijn'),
- ],
- ),
- ),
- PopupMenuItem(
- value: 'time',
- child: Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Icon(Icons.schedule, color: _selectedSortBy == 'time' ? colorScheme.primary : null),
- const SizedBox(width: 8),
- const Text('Tijd'),
- ],
- ),
- ),
- PopupMenuItem(
- value: 'weekday',
- child: Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Icon(Icons.calendar_today, color: _selectedSortBy == 'weekday' ? colorScheme.primary : null),
- const SizedBox(width: 8),
- const Text('Weekdag'),
- ],
- ),
- ),
- ],
- child: const Padding(
- padding: EdgeInsets.symmetric(horizontal: 16),
- child: Icon(Icons.filter_list),
- ),
- ),
- ],
- ),
- body: FutureBuilder>(
- future: _schedulesFuture,
- builder: (context, snapshot) {
- if (snapshot.connectionState == ConnectionState.waiting) {
- return const Center(child: CircularProgressIndicator());
- }
-
- if (snapshot.hasError) {
- return Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(Icons.error_outline, size: 48, color: colorScheme.error),
- const SizedBox(height: 16),
- Text(
- 'Fout bij laden: ${snapshot.error}',
- textAlign: TextAlign.center,
- ),
- const SizedBox(height: 16),
- FilledButton(
- onPressed: () {
- setState(() => _loadRecurringSchedules());
- },
- child: const Text('Opnieuw proberen'),
- ),
- ],
- ),
- );
- }
-
- final allSchedules = snapshot.data ?? [];
- // Filter to show only truly recurring schedules (with weekdays > 0)
- final schedules = allSchedules.where((s) => s.weekdays.isNotEmpty).toList();
-
- if (schedules.isEmpty) {
- return Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(Icons.event_note_outlined, size: 48, color: colorScheme.outline),
- const SizedBox(height: 16),
- Text(
- 'Geen herhaalde diensten gevonden',
- style: Theme.of(context).textTheme.titleMedium,
- ),
- const SizedBox(height: 8),
- Text(
- 'Herhaalde diensten worden hier weergegeven',
- style: Theme.of(context).textTheme.bodySmall?.copyWith(
- color: colorScheme.onSurfaceVariant,
- ),
- ),
- ],
- ),
- );
- }
-
- final sortedSchedules = _sortSchedules(schedules);
- final groupedByLine = _groupByLine(sortedSchedules);
-
- return ListView.builder(
- padding: const EdgeInsets.fromLTRB(12, 12, 12, 24),
- itemCount: groupedByLine.length,
- itemBuilder: (context, lineIndex) {
- final lineNumber = groupedByLine.keys.toList()[lineIndex];
- final lineSchedules = groupedByLine[lineNumber] ?? [];
- final isExpanded = _expandedLineIds.contains(lineNumber);
-
- return Column(
- children: [
- Card(
- child: InkWell(
- onTap: () {
- setState(() {
- if (isExpanded) {
- _expandedLineIds.remove(lineNumber);
- } else {
- _expandedLineIds.add(lineNumber);
- }
- });
- },
- child: Padding(
- padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- 'Lijn $lineNumber',
- style: Theme.of(context).textTheme.titleLarge?.copyWith(
- fontWeight: FontWeight.bold,
- ),
- ),
- const SizedBox(height: 4),
- Text(
- '${lineSchedules.length} diensten',
- style: Theme.of(context).textTheme.bodySmall?.copyWith(
- color: colorScheme.outline,
- ),
- ),
- ],
- ),
- Icon(
- isExpanded ? Icons.expand_less : Icons.expand_more,
- color: colorScheme.primary,
- ),
- ],
- ),
- ),
- ),
- ),
- if (isExpanded)
- Padding(
- padding: const EdgeInsets.only(top: 8),
- child: ListView.separated(
- shrinkWrap: true,
- physics: const NeverScrollableScrollPhysics(),
- itemCount: lineSchedules.length,
- separatorBuilder: (_, _) => const SizedBox(height: 8),
- itemBuilder: (context, scheduleIndex) {
- final schedule = lineSchedules[scheduleIndex];
- return _ScheduleCard(schedule: schedule, formatTime: _formatTime, formatWeekdays: _formatWeekdays);
- },
- ),
- ),
- const SizedBox(height: 8),
- ],
- );
- },
- );
- },
- ),
- );
- }
-}
-
-class _ScheduleCard extends StatelessWidget {
- final sched.ServiceSchedule schedule;
- final String Function(DateTime) formatTime;
- final String Function(List) formatWeekdays;
-
- const _ScheduleCard({
- required this.schedule,
- required this.formatTime,
- required this.formatWeekdays,
- });
-
- @override
- Widget build(BuildContext context) {
- final colorScheme = Theme.of(context).colorScheme;
-
- return Card(
- elevation: 1,
- child: Padding(
- padding: const EdgeInsets.all(12),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- children: [
- Expanded(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- '${formatTime(schedule.startTime)} - ${formatTime(schedule.endTime)}',
- style: Theme.of(context).textTheme.titleMedium?.copyWith(
- fontWeight: FontWeight.w600,
- ),
- ),
- const SizedBox(height: 4),
- Text(
- schedule.busName,
- style: Theme.of(context).textTheme.bodySmall?.copyWith(
- color: colorScheme.outline,
- ),
- ),
- ],
- ),
- ),
- ],
- ),
- const SizedBox(height: 8),
- Wrap(
- spacing: 8,
- runSpacing: 8,
- children: [
- Chip(
- label: Text(
- formatWeekdays(schedule.weekdays),
- style: Theme.of(context).textTheme.labelSmall,
- ),
- avatar: const Icon(Icons.calendar_today, size: 16),
- visualDensity: VisualDensity.compact,
- ),
- ],
- ),
- ],
- ),
- ),
- );
- }
-}
diff --git a/deprecated/lib/screens/schedule_overview_screen.dart b/deprecated/lib/screens/schedule_overview_screen.dart
deleted file mode 100644
index d512cba..0000000
--- a/deprecated/lib/screens/schedule_overview_screen.dart
+++ /dev/null
@@ -1,674 +0,0 @@
-// ignore_for_file: use_build_context_synchronously
-
-import 'package:flutter/material.dart';
-import '../models/schedule.dart' as sched;
-import '../models/navigation.dart';
-import '../services/auth_service.dart';
-import '../services/schedule_service.dart';
-import '../screens/navigation_screen.dart';
-import '../screens/recurring_schedules_screen.dart';
-
-class ScheduleOverviewScreen extends StatefulWidget {
- const ScheduleOverviewScreen({super.key});
-
- @override
- State createState() => _ScheduleOverviewScreenState();
-}
-
-class _ScheduleOverviewScreenState extends State with TickerProviderStateMixin {
- final _scheduleService = ScheduleService();
- final _authService = AuthService();
-
- late Future> _scheduleFuture;
- DateTime _selectedDate = DateTime.now();
- late TabController _tabController;
-
- @override
- void initState() {
- super.initState();
- _scheduleFuture = _scheduleService.getSchedules(_selectedDate);
- _tabController = TabController(length: 3, vsync: this);
- }
-
- @override
- void dispose() {
- _tabController.dispose();
- super.dispose();
- }
-
- Future _handleLogout() async {
- await _authService.logout();
- if (mounted) {
- Navigator.of(context).pushReplacementNamed('/login');
- }
- }
-
- Future _refreshSchedules() async {
- setState(() {
- _scheduleFuture = _scheduleService.getSchedules(_selectedDate);
- });
- }
-
- Future _selectDate() async {
- final colorScheme = Theme.of(context).colorScheme;
- final picked = await showDatePicker(
- context: context,
- initialDate: _selectedDate,
- firstDate: DateTime.now().subtract(const Duration(days: 7)),
- lastDate: DateTime.now().add(const Duration(days: 30)),
- builder: (context, child) {
- return Theme(
- data: Theme.of(context).copyWith(
- dialogBackgroundColor: colorScheme.surface,
- ),
- child: child!,
- );
- },
- );
-
- if (picked != null && picked != _selectedDate) {
- setState(() {
- _selectedDate = picked;
- });
- _refreshSchedules();
- }
- }
-
- Future _showScheduleDetails(sched.ServiceSchedule svc) async {
- try {
- final stops = await _scheduleService.getScheduleStops(svc.id);
- if (!mounted) return;
-
- await showModalBottomSheet(
- context: context,
- isScrollControlled: true,
- showDragHandle: true,
- builder: (sheetContext) {
- return DraggableScrollableSheet(
- expand: false,
- initialChildSize: 0.75,
- minChildSize: 0.45,
- maxChildSize: 0.95,
- builder: (context, scrollController) {
- return ListView(
- controller: scrollController,
- padding: const EdgeInsets.fromLTRB(20, 8, 20, 24),
- children: [
- Text(
- 'Lijn ${svc.lineNumber}',
- style: Theme.of(context).textTheme.headlineSmall?.copyWith(
- fontWeight: FontWeight.w800,
- ),
- ),
- const SizedBox(height: 8),
- Text(
- svc.busName,
- style: Theme.of(context).textTheme.titleMedium,
- ),
- const SizedBox(height: 4),
- Text(
- '${_formatTime(svc.startTime)} - ${_formatTime(svc.endTime)}',
- style: Theme.of(context).textTheme.bodyMedium,
- ),
- const SizedBox(height: 12),
- Wrap(
- spacing: 8,
- runSpacing: 8,
- children: [
- _InfoChip(label: svc.status),
- _InfoChip(label: svc.isRecurring ? _weekdayLabel(svc.weekdays) : 'Eenmalig'),
- ],
- ),
- const SizedBox(height: 20),
- SizedBox(
- width: double.infinity,
- child: FilledButton.icon(
- onPressed: () async {
- try {
- await _scheduleService.updateScheduleStatus(
- svc.id,
- 'in_progress',
- date: svc.startTime,
- );
- if (!mounted) return;
- Navigator.of(sheetContext).pop();
-
- final routeObj = sched.Route(
- id: svc.id,
- busLine: sched.BusLine(
- id: svc.busLineId,
- lineNumber: svc.lineNumber,
- startStop: '',
- endStop: '',
- estimatedDuration: 0,
- ),
- busType: sched.BusType(
- id: svc.busId,
- name: svc.busName,
- seatCapacity: 0,
- licensePlate: '',
- ),
- startTime: svc.startTime,
- endTime: svc.endTime,
- status: 'in_progress',
- );
-
- final navStops = stops
- .map((s) => NavigationPoint(
- latitude: s.latitude,
- longitude: s.longitude,
- name: s.name,
- ))
- .toList();
-
- try {
- await Navigator.of(context).push(
- MaterialPageRoute(
- builder: (_) => NavigationScreen(route: routeObj, initialStops: navStops),
- ),
- );
- } catch (navErr) {
- if (!mounted) return;
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(content: Text('Navigatiefout: ${navErr.toString()}')),
- );
- }
- } catch (e) {
- if (!mounted) return;
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(content: Text('Status bijwerken mislukt: $e')),
- );
- }
- },
- icon: const Icon(Icons.navigation),
- label: const Text('Start route'),
- ),
- ),
- Text(
- 'Haltes',
- style: Theme.of(context).textTheme.titleMedium?.copyWith(
- fontWeight: FontWeight.w700,
- ),
- ),
- const SizedBox(height: 12),
- if (stops.isEmpty)
- Text(
- 'Geen haltes gekoppeld aan deze dienst.',
- style: Theme.of(context).textTheme.bodyMedium,
- )
- else
- ...stops.map((stop) {
- final departureTime = svc.startTime.add(
- Duration(minutes: stop.estimatedArrivalMinutes),
- );
- return Card(
- child: ListTile(
- dense: true,
- title: Text('${stop.order}. ${stop.name}'),
- subtitle: Text('${stop.estimatedArrivalMinutes} min na vertrek'),
- trailing: Text(_formatTime(departureTime)),
- ),
- );
- }),
- ],
- );
- },
- );
- },
- );
- } catch (e) {
- if (!mounted) return;
- ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(content: Text('Kon dienstdetails niet laden: $e')),
- );
- }
- }
-
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: const Text('Diensten'),
- centerTitle: true,
- elevation: 0,
- bottom: TabBar(
- controller: _tabController,
- tabs: const [
- Tab(icon: Icon(Icons.calendar_today), text: 'Dagschema'),
- Tab(icon: Icon(Icons.repeat), text: 'Vaste diensten'),
- Tab(icon: Icon(Icons.timeline), text: 'Voortgang'),
- ],
- ),
- actions: [
- IconButton(
- icon: const Icon(Icons.logout),
- tooltip: 'Logout',
- onPressed: _handleLogout,
- ),
- ],
- ),
- body: TabBarView(
- controller: _tabController,
- children: [
- _DailyScheduleTab(
- scheduleService: _scheduleService,
- selectedDate: _selectedDate,
- onSelectDate: _selectDate,
- onRefresh: _refreshSchedules,
- onShowDetails: _showScheduleDetails,
- scheduleFuture: _scheduleFuture,
- ),
- const RecurringSchedulesScreen(),
- _ProgressTab(
- scheduleService: _scheduleService,
- selectedDate: _selectedDate,
- scheduleFuture: _scheduleFuture,
- ),
- ],
- ),
- );
- }
-}
-
-class _ProgressTab extends StatelessWidget {
- final ScheduleService scheduleService;
- final DateTime selectedDate;
- final Future> scheduleFuture;
-
- const _ProgressTab({
- required this.scheduleService,
- required this.selectedDate,
- required this.scheduleFuture,
- });
-
- @override
- Widget build(BuildContext context) {
- final dateStr = '${selectedDate.year}-${selectedDate.month.toString().padLeft(2, '0')}-${selectedDate.day.toString().padLeft(2, '0')}';
-
- return Column(
- children: [
- Container(
- padding: const EdgeInsets.all(16),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text('Voortgang voor $dateStr', style: Theme.of(context).textTheme.titleLarge),
- IconButton(
- onPressed: () async {
- // refresh handled by parent via reselecting date; show a simple feedback
- ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Ververs de datum in Dagschema-tab om andere datum te laden')));
- },
- icon: const Icon(Icons.info_outline),
- ),
- ],
- ),
- ),
- Expanded(
- child: FutureBuilder>(
- future: scheduleFuture,
- builder: (context, snapshot) {
- if (snapshot.connectionState == ConnectionState.waiting) return const Center(child: CircularProgressIndicator());
- if (snapshot.hasError) return Center(child: Text('Fout bij laden: ${snapshot.error}'));
-
- final schedules = snapshot.data ?? [];
- if (schedules.isEmpty) return Center(child: Text('Geen diensten op $dateStr'));
-
- return ListView.builder(
- padding: const EdgeInsets.all(12),
- itemCount: schedules.length,
- itemBuilder: (context, index) {
- final svc = schedules[index];
- return Card(
- child: ListTile(
- title: Text('Lijn ${svc.lineNumber} — ${svc.busName}'),
- subtitle: Text(_formatTime(svc.startTime)),
- trailing: TextButton(
- onPressed: () async {
- try {
- final progress = await scheduleService.getScheduleProgress(svc.id, selectedDate);
- if (!context.mounted) return;
- await showModalBottomSheet(
- context: context,
- isScrollControlled: true,
- builder: (ctx) {
- final stops = (progress['stops'] as List?) ?? [];
- return Padding(
- padding: const EdgeInsets.fromLTRB(16, 16, 16, 32),
- child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text('Voortgang — Lijn ${svc.lineNumber}', style: Theme.of(ctx).textTheme.headlineSmall),
- const SizedBox(height: 8),
- Text('Status: ${progress['schedule']?['status'] ?? 'onbekend'}'),
- Text('Driver state: ${progress['driverState'] ?? 'onbekend'}'),
- Text('Passed: ${progress['passedStopCount'] ?? 0} / ${progress['totalStopCount'] ?? 0}'),
- const SizedBox(height: 12),
- const Text('Haltes:'),
- const SizedBox(height: 8),
- Expanded(
- child: ListView.builder(
- shrinkWrap: true,
- itemCount: stops.length,
- itemBuilder: (c, i) {
- final s = stops[i] as Map;
- return ListTile(
- dense: true,
- title: Text('${s['stopOrder']}. ${s['stopName']}'),
- subtitle: Text('Scheduled: ${s['scheduledPassedAt'] ?? '-'}\nActual: ${s['actualPassedAt'] ?? '-'}'),
- );
- },
- ),
- ),
- ],
- ),
- );
- },
- );
- } catch (e) {
- if (!context.mounted) return;
- ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Kon voortgang niet laden: $e')));
- }
- },
- child: const Text('Bekijk voortgang'),
- ),
- ),
- );
- },
- );
- },
- ),
- ),
- ],
- );
- }
-}
-
-class _DailyScheduleTab extends StatelessWidget {
- final ScheduleService scheduleService;
- final DateTime selectedDate;
- final VoidCallback onSelectDate;
- final VoidCallback onRefresh;
- final Function(sched.ServiceSchedule) onShowDetails;
- final Future> scheduleFuture;
-
- const _DailyScheduleTab({
- required this.scheduleService,
- required this.selectedDate,
- required this.onSelectDate,
- required this.onRefresh,
- required this.onShowDetails,
- required this.scheduleFuture,
- });
-
- @override
- Widget build(BuildContext context) {
- final colorScheme = Theme.of(context).colorScheme;
- final dateStr =
- '${selectedDate.year}-${selectedDate.month.toString().padLeft(2, '0')}-${selectedDate.day.toString().padLeft(2, '0')}';
-
- return Container(
- decoration: BoxDecoration(
- gradient: LinearGradient(
- colors: Theme.of(context).brightness == Brightness.dark
- ? const [Color(0xFF0B1220), Color(0xFF111827)]
- : const [Color(0xFFF1F5F9), Color(0xFFE2E8F0)],
- begin: Alignment.topCenter,
- end: Alignment.bottomCenter,
- ),
- ),
- child: Column(
- children: [
- Container(
- margin: const EdgeInsets.fromLTRB(16, 16, 16, 12),
- padding: const EdgeInsets.all(18),
- decoration: BoxDecoration(
- gradient: const LinearGradient(
- colors: [Color(0xFF0F172A), Color(0xFF1D4ED8)],
- begin: Alignment.topLeft,
- end: Alignment.bottomRight,
- ),
- borderRadius: BorderRadius.circular(24),
- boxShadow: [
- BoxShadow(
- color: Colors.black.withOpacity(0.16),
- blurRadius: 22,
- offset: const Offset(0, 10),
- ),
- ],
- ),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- 'Geplande diensten',
- style: Theme.of(context).textTheme.labelSmall?.copyWith(
- color: Colors.white.withOpacity(0.78),
- ),
- ),
- const SizedBox(height: 6),
- Text(
- dateStr,
- style: Theme.of(context).textTheme.headlineMedium?.copyWith(
- color: Colors.white,
- fontWeight: FontWeight.w800,
- ),
- ),
- const SizedBox(height: 6),
- Text(
- 'Automatisch berekende eindtijden, haltes en herhalende weekdagen',
- style: Theme.of(context).textTheme.bodyMedium?.copyWith(
- color: Colors.white.withOpacity(0.84),
- ),
- ),
- const SizedBox(height: 14),
- Align(
- alignment: Alignment.centerRight,
- child: SizedBox(
- height: 48,
- child: OutlinedButton.icon(
- onPressed: onSelectDate,
- icon: const Icon(Icons.calendar_today, size: 18),
- label: const Text('Wijzig datum'),
- style: OutlinedButton.styleFrom(
- foregroundColor: Colors.white,
- side: BorderSide(color: Colors.white.withOpacity(0.28)),
- padding: const EdgeInsets.symmetric(horizontal: 16),
- ),
- ),
- ),
- ),
- ],
- ),
- ),
- Expanded(
- child: FutureBuilder>(
- future: scheduleFuture,
- builder: (context, snapshot) {
- if (snapshot.connectionState == ConnectionState.waiting) {
- return const Center(child: CircularProgressIndicator());
- }
-
- if (snapshot.hasError) {
- return Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(Icons.error_outline, size: 48, color: colorScheme.error),
- const SizedBox(height: 16),
- Text('Fout bij laden: ${snapshot.error}', textAlign: TextAlign.center),
- const SizedBox(height: 16),
- FilledButton(
- onPressed: onRefresh,
- child: const Text('Opnieuw proberen'),
- ),
- ],
- ),
- );
- }
-
- final schedules = snapshot.data ?? [];
- if (schedules.isEmpty) {
- return Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Icon(Icons.event_available_outlined, size: 48, color: colorScheme.outline),
- const SizedBox(height: 16),
- Text('Geen diensten op $dateStr', style: Theme.of(context).textTheme.titleMedium),
- ],
- ),
- );
- }
-
- return RefreshIndicator(
- onRefresh: () async => onRefresh(),
- child: ListView.builder(
- padding: const EdgeInsets.fromLTRB(0, 12, 0, 24),
- itemCount: schedules.length,
- itemBuilder: (context, index) {
- final schedule = schedules[index];
- return _ScheduleSummaryCard(
- schedule: schedule,
- onTap: () => onShowDetails(schedule),
- );
- },
- ),
- );
- },
- ),
- ),
- ],
- ),
- );
- }
-}
-
-class _ScheduleSummaryCard extends StatelessWidget {
- final sched.ServiceSchedule schedule;
- final VoidCallback onTap;
-
- const _ScheduleSummaryCard({
- required this.schedule,
- required this.onTap,
- });
-
- @override
- Widget build(BuildContext context) {
- final colorScheme = Theme.of(context).colorScheme;
-
- return Card(
- margin: const EdgeInsets.fromLTRB(16, 8, 16, 8),
- elevation: 0,
- color: colorScheme.surface,
- shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
- child: InkWell(
- borderRadius: BorderRadius.circular(20),
- onTap: onTap,
- child: Padding(
- padding: const EdgeInsets.all(16),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Container(
- padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
- decoration: BoxDecoration(
- gradient: LinearGradient(
- colors: [colorScheme.primary, colorScheme.tertiary],
- begin: Alignment.topLeft,
- end: Alignment.bottomRight,
- ),
- borderRadius: BorderRadius.circular(8),
- ),
- child: Text(
- 'Line ${schedule.lineNumber}',
- style: Theme.of(context).textTheme.titleMedium?.copyWith(
- color: Colors.white,
- fontWeight: FontWeight.bold,
- fontSize: 18,
- ),
- ),
- ),
- // Only show status for one-time schedules; recurring schedules have no fixed status
- if (!schedule.isRecurring)
- _InfoChip(label: schedule.status),
- ],
- ),
- const SizedBox(height: 16),
- Text(
- schedule.busName,
- style: Theme.of(context).textTheme.titleMedium?.copyWith(
- fontWeight: FontWeight.w700,
- ),
- ),
- const SizedBox(height: 4),
- Text(
- '${_formatTime(schedule.startTime)} - ${_formatTime(schedule.endTime)}',
- style: Theme.of(context).textTheme.bodyMedium?.copyWith(
- color: colorScheme.onSurfaceVariant,
- ),
- ),
- const SizedBox(height: 12),
- Text(
- schedule.isRecurring ? _weekdayLabel(schedule.weekdays) : 'Eenmalige dienst',
- style: Theme.of(context).textTheme.bodySmall?.copyWith(
- color: colorScheme.onSurfaceVariant,
- ),
- ),
- const SizedBox(height: 10),
- Align(
- alignment: Alignment.centerRight,
- child: TextButton.icon(
- onPressed: onTap,
- icon: const Icon(Icons.list_alt, size: 18),
- label: const Text('Haltes'),
- ),
- ),
- ],
- ),
- ),
- ),
- );
- }
-}
-
-class _InfoChip extends StatelessWidget {
- final String label;
-
- const _InfoChip({required this.label});
-
- @override
- Widget build(BuildContext context) {
- return Container(
- padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
- decoration: BoxDecoration(
- color: Theme.of(context).colorScheme.primaryContainer,
- borderRadius: BorderRadius.circular(20),
- ),
- child: Text(
- label,
- style: Theme.of(context).textTheme.labelMedium?.copyWith(
- fontWeight: FontWeight.w600,
- ),
- ),
- );
- }
-}
-
-String _formatTime(DateTime time) {
- return '${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}';
-}
-
-String _weekdayLabel(List weekdays) {
- const labels = ['Zo', 'Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za'];
- if (weekdays.isEmpty) {
- return 'Eenmalige dienst';
- }
- if (weekdays.length == 7) {
- return 'Dagelijks';
- }
- return weekdays.where((day) => day >= 0 && day < labels.length).map((day) => labels[day]).join(', ');
-}
diff --git a/deprecated/lib/services/.gitkeep b/deprecated/lib/services/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/deprecated/lib/services/app_navigator.dart b/deprecated/lib/services/app_navigator.dart
deleted file mode 100644
index c28be33..0000000
--- a/deprecated/lib/services/app_navigator.dart
+++ /dev/null
@@ -1,29 +0,0 @@
-import 'package:flutter/material.dart';
-import 'auth_service.dart';
-
-/// Global navigator and messenger keys so services can navigate/logout
-final GlobalKey navigatorKey = GlobalKey();
-final GlobalKey messengerKey = GlobalKey();
-
-/// Handle expired authentication: clear stored token and navigate to login.
-Future handleAuthExpired({String? message}) async {
- try {
- await AuthService().logout();
- } catch (_) {}
-
- // Show a message if possible
- try {
- final messenger = messengerKey.currentState;
- if (messenger != null && message != null) {
- messenger.showSnackBar(SnackBar(content: Text(message)));
- }
- } catch (_) {}
-
- // Navigate to login, removing all previous routes
- try {
- final nav = navigatorKey.currentState;
- if (nav != null) {
- nav.pushNamedAndRemoveUntil('/login', (r) => false);
- }
- } catch (_) {}
-}
diff --git a/deprecated/lib/services/auth_service.dart b/deprecated/lib/services/auth_service.dart
deleted file mode 100644
index dd4aed9..0000000
--- a/deprecated/lib/services/auth_service.dart
+++ /dev/null
@@ -1,95 +0,0 @@
-import 'dart:convert';
-import 'package:http/http.dart' as http;
-import 'package:shared_preferences/shared_preferences.dart';
-import '../models/user.dart';
-import 'error_log_service.dart';
-
-/// Authentication Service
-class AuthService {
- static const String _apiBaseUrl = 'https://transit.xtransit.testinstance.nl';
- static const String _tokenKey = 'auth_token';
-
- late SharedPreferences _prefs;
-
- Future _reportError(String partOfService, Object error) {
- return ErrorLogService.report(
- service: 'bus_terminal',
- partOfService: partOfService,
- error: error.toString(),
- );
- }
-
- Future _initPrefs() async {
- _prefs = await SharedPreferences.getInstance();
- }
-
- /// Login with userCode and password
- Future login({
- required int userCode,
- required String password,
- }) async {
- await _initPrefs();
-
- try {
- final response = await http.post(
- Uri.parse('$_apiBaseUrl/login'),
- headers: {'Content-Type': 'application/json'},
- body: jsonEncode({
- 'userCode': userCode,
- 'password': password,
- }),
- );
-
- if (response.statusCode == 200) {
- final body = response.body;
- try {
- final data = jsonDecode(body) as Map;
- final authResponse = AuthResponse.fromJson(data);
-
- // Store token
- await _prefs.setString(_tokenKey, authResponse.token);
-
- return authResponse;
- } catch (e) {
- await _reportError('AuthService.login.parse', e);
- // Surface the response body to help debug backend field names / formats
- throw Exception('Login parse error: $e -- response body: $body');
- }
- } else if (response.statusCode == 401) {
- throw Exception('Invalid credentials');
- } else {
- throw Exception('Login failed: ${response.statusCode}');
- }
- } catch (e) {
- await _reportError('AuthService.login', e);
- throw Exception('Login error: $e');
- }
- }
-
- /// Get stored token
- Future getToken() async {
- await _initPrefs();
- return _prefs.getString(_tokenKey);
- }
-
- /// Check if user is logged in
- Future isLoggedIn() async {
- final token = await getToken();
- return token != null;
- }
-
- /// Logout
- Future logout() async {
- await _initPrefs();
- await _prefs.remove(_tokenKey);
- }
-
- /// Get Authorization header
- Future