21 Commits

Author SHA1 Message Date
840a81f09e Update: Started API integration 2026-01-16 12:27:15 +05:30
mystery012728
a2bad0f139 Added NetworkApiService File 2026-01-08 17:07:53 +05:30
mystery012728
22f2de1bbe Flexi rename into Selective and mad taht dynamic and bug fixes 2026-01-07 18:27:24 +05:30
mystery012728
b77bcea769 Bug fixes and error solved 2026-01-07 14:45:24 +05:30
ada6040514 Fix :- Fixed the grey screen bug in get a pass and cart section. 2026-01-06 15:34:37 +05:30
3c05534262 Merge remote-tracking branch 'origin/vinayak' into dinesh
# Conflicts:
#	android/app/src/main/res/drawable-hdpi/android12splash.png
#	android/app/src/main/res/drawable-mdpi/android12splash.png
#	android/app/src/main/res/drawable-night-hdpi/android12splash.png
#	android/app/src/main/res/drawable-night-mdpi/android12splash.png
#	android/app/src/main/res/drawable-night-xhdpi/android12splash.png
#	android/app/src/main/res/drawable-night-xxhdpi/android12splash.png
#	android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png
#	android/app/src/main/res/drawable-v21/launch_background.xml
#	android/app/src/main/res/drawable-xhdpi/android12splash.png
#	android/app/src/main/res/drawable-xxhdpi/android12splash.png
#	android/app/src/main/res/drawable-xxxhdpi/android12splash.png
#	android/app/src/main/res/drawable/launch_background.xml
#	android/app/src/main/res/values-night-v31/styles.xml
#	android/app/src/main/res/values-v31/styles.xml
#	lib/core/route_constants.dart
#	pubspec.yaml
2025-11-14 11:21:36 +05:30
3caa52d9f8 vinayak's pull merged 2025-11-11 11:14:22 +05:30
Vinayakkadge04
e2f9217d57 Updated Splash Screen... 2025-11-10 12:38:50 +05:30
Vinayakkadge04
7d4c015134 worked on onboarding screen 2025-11-07 17:44:51 +05:30
Vinayakkadge04
061f196ece Merge remote-tracking branch 'origin/dinesh' into vinayak
# Conflicts:
#	pubspec.yaml
2025-10-30 16:52:30 +05:30
76e4fff06c Added all the navigation and all first time user condition also made changes in common app bar and added logo and splash screen 2025-10-30 03:39:40 +05:30
Vinayakkadge04
6a68a06b78 Updated yaml file for splash screen for android 15 2025-10-29 20:22:27 +05:30
9121cf1b1b Merge remote-tracking branch 'origin/vinayak' into dinesh
# Conflicts:
#	pubspec.lock
#	pubspec.yaml
2025-10-29 20:02:11 +05:30
Vinayakkadge04
a2ff4253ed Updated bottomsheet bg color 2025-10-29 19:59:49 +05:30
f43c2cc9f6 routing magic itenary 2025-10-29 19:59:11 +05:30
Vinayakkadge04
d73faf7506 Updated language bottomSheet bg color 2025-10-29 19:47:59 +05:30
Vinayakkadge04
560a10f4ea Used Back widget 2025-10-29 18:55:45 +05:30
Vinayakkadge04
5c11344c17 Used Screen Util in ticket card view 2025-10-29 17:56:38 +05:30
9dd76e1dac Merge remote-tracking branch 'origin/vinayak' into dinesh
# Conflicts:
#	lib/main.dart
2025-10-29 17:12:05 +05:30
Vinayakkadge04
c771ce335c Changed serch_city_bottomsheet navigation 2025-10-29 17:11:07 +05:30
Vinayakkadge04
f93ba6dad2 Worked on Search city bottomsheet 2025-10-29 17:07:27 +05:30
146 changed files with 3180 additions and 1495 deletions

View File

@@ -21,7 +21,7 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.citycards_customer.citycards_customer"
applicationId = "com.citycard.customer"
// 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

View File

@@ -5,15 +5,15 @@
<application
android:label="citycards_customer"
android:label="CityCard Customer"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
android:icon="@mipmap/launcher_icon">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:theme="@style/NormalTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 B

View File

@@ -1,12 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 B

View File

@@ -1,12 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowSplashScreenBackground">#F95F62</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@@ -5,6 +5,10 @@
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
<item name="android:windowSplashScreenBackground">#F95F62</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@@ -2,9 +2,12 @@
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<!-- Use a plain background instead of a splash drawable -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:windowFullscreen">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
assets/images/splash1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 MiB

BIN
assets/images/splash2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 MiB

BIN
assets/images/splash3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

1
assets/intro/anim.json Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1
assets/intro/splash.json Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

BIN
assets/logo/logoframe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
assets/logo/splash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

3
devtools_options.yaml Normal file
View File

@@ -0,0 +1,3 @@
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:

View File

@@ -0,0 +1,19 @@
# flutter pub run flutter_launcher_icons
flutter_launcher_icons:
image_path: "assets/logo/logo_city_cards.png"
android: "launcher_icon"
# image_path_android: "assets/icon/icon.png"
min_sdk_android: 21 # android min sdk min:16, default 21
# adaptive_icon_background: "assets/icon/background.png"
# adaptive_icon_foreground: "assets/icon/foreground.png"
# adaptive_icon_foreground_inset: 16
# adaptive_icon_monochrome: "assets/icon/monochrome.png"
ios: true
# image_path_ios: "assets/icon/icon.png"
remove_alpha_ios: true
# image_path_ios_dark_transparent: "assets/icon/icon_dark.png"
# image_path_ios_tinted_grayscale: "assets/icon/icon_tinted.png"
# desaturate_tinted_to_grayscale_ios: true
# background_color_ios: "#ffffff"

View File

@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '13.0'
platform :ios, '16.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'

99
ios/Podfile.lock Normal file
View File

@@ -0,0 +1,99 @@
PODS:
- Flutter (1.0.0)
- flutter_angle (0.3.8):
- Flutter
- FlutterAngle (~> 0.0.8)
- FlutterMacOS
- flutter_native_splash (2.4.3):
- Flutter
- FlutterAngle (0.0.8)
- geolocator_apple (1.2.0):
- Flutter
- FlutterMacOS
- Google-Maps-iOS-Utils (6.1.0):
- GoogleMaps (~> 9.0)
- google_maps_flutter_ios (0.0.1):
- Flutter
- Google-Maps-iOS-Utils (< 7.0, >= 5.0)
- GoogleMaps (< 10.0, >= 8.4)
- GoogleMaps (9.4.0):
- GoogleMaps/Maps (= 9.4.0)
- GoogleMaps/Maps (9.4.0)
- image_picker_ios (0.0.1):
- Flutter
- package_info_plus (0.4.5):
- Flutter
- path_provider_foundation (0.0.1):
- Flutter
- FlutterMacOS
- shared_preferences_foundation (0.0.1):
- Flutter
- FlutterMacOS
- three_js_sensors (0.1.2):
- Flutter
- video_player_avfoundation (0.0.1):
- Flutter
- FlutterMacOS
DEPENDENCIES:
- Flutter (from `Flutter`)
- flutter_angle (from `.symlinks/plugins/flutter_angle/darwin`)
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
- geolocator_apple (from `.symlinks/plugins/geolocator_apple/darwin`)
- google_maps_flutter_ios (from `.symlinks/plugins/google_maps_flutter_ios/ios`)
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
- path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
- three_js_sensors (from `.symlinks/plugins/three_js_sensors/ios`)
- video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
SPEC REPOS:
trunk:
- FlutterAngle
- Google-Maps-iOS-Utils
- GoogleMaps
EXTERNAL SOURCES:
Flutter:
:path: Flutter
flutter_angle:
:path: ".symlinks/plugins/flutter_angle/darwin"
flutter_native_splash:
:path: ".symlinks/plugins/flutter_native_splash/ios"
geolocator_apple:
:path: ".symlinks/plugins/geolocator_apple/darwin"
google_maps_flutter_ios:
:path: ".symlinks/plugins/google_maps_flutter_ios/ios"
image_picker_ios:
:path: ".symlinks/plugins/image_picker_ios/ios"
package_info_plus:
:path: ".symlinks/plugins/package_info_plus/ios"
path_provider_foundation:
:path: ".symlinks/plugins/path_provider_foundation/darwin"
shared_preferences_foundation:
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
three_js_sensors:
:path: ".symlinks/plugins/three_js_sensors/ios"
video_player_avfoundation:
:path: ".symlinks/plugins/video_player_avfoundation/darwin"
SPEC CHECKSUMS:
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
flutter_angle: 7b1a2b3e733221bf2e0325e42fc3edf95b5d44c4
flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
FlutterAngle: c810891af800750361b1d0e7cc944f2338d5ae18
geolocator_apple: ab36aa0e8b7d7a2d7639b3b4e48308394e8cef5e
Google-Maps-iOS-Utils: 0a484b05ed21d88c9f9ebbacb007956edd508a96
google_maps_flutter_ios: 0291eb2aa252298a769b04d075e4a9d747ff7264
GoogleMaps: 0608099d4870cac8754bdba9b6953db543432438
image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
three_js_sensors: f516b092803411e05b1e3dc7625efa36acd8f455
video_player_avfoundation: dd410b52df6d2466a42d28550e33e4146928280a
PODFILE CHECKSUM: 1857a7cdb7dfafe45f2b0e9a9af44644190f7506
COCOAPODS: 1.16.2

View File

@@ -7,10 +7,12 @@
objects = {
/* Begin PBXBuildFile section */
00C1AB7B0C8F1922F3F1AE65 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54C8901E9D1856D980DFFE46 /* Pods_Runner.framework */; };
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 */; };
81D638B66EB4658C8192CA0D /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 445696AB37183A7C63CB7E98 /* Pods_RunnerTests.framework */; };
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 */; };
@@ -45,6 +47,10 @@
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
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 = "<group>"; };
445696AB37183A7C63CB7E98 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4FD33ADDA221C4BBA29FA3D6 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
54C8901E9D1856D980DFFE46 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
626B072D1717B50A277DA3C7 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
@@ -55,6 +61,10 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B691822B373AD22ECA93B798 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
C1FCB3EF88270ED76DFA3FBD /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
D56ABB8F306EF9F6809C0C1E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
E2E6DC2B6718F55E3BF165E7 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -62,6 +72,15 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
00C1AB7B0C8F1922F3F1AE65 /* Pods_Runner.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
CF8A29BE993C0C902CB143AF /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
81D638B66EB4658C8192CA0D /* Pods_RunnerTests.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -76,6 +95,28 @@
path = RunnerTests;
sourceTree = "<group>";
};
5D45FB84C63476582408C414 /* Frameworks */ = {
isa = PBXGroup;
children = (
54C8901E9D1856D980DFFE46 /* Pods_Runner.framework */,
445696AB37183A7C63CB7E98 /* Pods_RunnerTests.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
6D4A73F1E55857ADBD000C6A /* Pods */ = {
isa = PBXGroup;
children = (
B691822B373AD22ECA93B798 /* Pods-Runner.debug.xcconfig */,
4FD33ADDA221C4BBA29FA3D6 /* Pods-Runner.release.xcconfig */,
D56ABB8F306EF9F6809C0C1E /* Pods-Runner.profile.xcconfig */,
E2E6DC2B6718F55E3BF165E7 /* Pods-RunnerTests.debug.xcconfig */,
626B072D1717B50A277DA3C7 /* Pods-RunnerTests.release.xcconfig */,
C1FCB3EF88270ED76DFA3FBD /* Pods-RunnerTests.profile.xcconfig */,
);
path = Pods;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
@@ -94,6 +135,8 @@
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
6D4A73F1E55857ADBD000C6A /* Pods */,
5D45FB84C63476582408C414 /* Frameworks */,
);
sourceTree = "<group>";
};
@@ -128,8 +171,10 @@
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
BC66FA7BADCD3982DC87655E /* [CP] Check Pods Manifest.lock */,
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
CF8A29BE993C0C902CB143AF /* Frameworks */,
);
buildRules = (
);
@@ -145,12 +190,15 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
3825EC0F330C0B58EA2A8981 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
41FC0A605EBADE26C841287E /* [CP] Embed Pods Frameworks */,
D10E98BB568B7005161E1ABD /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -222,6 +270,28 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3825EC0F330C0B58EA2A8981 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
@@ -238,6 +308,23 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
41FC0A605EBADE26C841287E /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
@@ -253,6 +340,45 @@
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
BC66FA7BADCD3982DC87655E /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
D10E98BB568B7005161E1ABD /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -361,24 +487,35 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = A89AY6VY4F;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "CityCard Customer";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.citycardscustomer.citycardsCustomer;
PRODUCT_BUNDLE_IDENTIFIER = com.citycard.customer;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = E2E6DC2B6718F55E3BF165E7 /* Pods-RunnerTests.debug.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@@ -396,6 +533,7 @@
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 626B072D1717B50A277DA3C7 /* Pods-RunnerTests.release.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@@ -411,6 +549,7 @@
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = C1FCB3EF88270ED76DFA3FBD /* Pods-RunnerTests.profile.xcconfig */;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
@@ -428,7 +567,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
@@ -475,7 +614,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
ONLY_ACTIVE_ARCH = NO;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
@@ -485,7 +624,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
@@ -526,6 +665,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
@@ -541,19 +681,29 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = A89AY6VY4F;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "CityCard Customer";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.citycardscustomer.citycardsCustomer;
PRODUCT_BUNDLE_IDENTIFIER = com.citycard.customer;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
@@ -564,18 +714,28 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = A89AY6VY4F;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = "CityCard Customer";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.citycardscustomer.citycardsCustomer;
PRODUCT_BUNDLE_IDENTIFIER = com.citycard.customer;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 1;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;

View File

@@ -4,4 +4,7 @@
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@@ -1,122 +1 @@
{
"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"
}
}
{"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":"57x57","idiom":"iphone","filename":"Icon-App-57x57@1x.png","scale":"1x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@2x.png","scale":"2x"},{"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":"50x50","idiom":"ipad","filename":"Icon-App-50x50@1x.png","scale":"1x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@2x.png","scale":"2x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@1x.png","scale":"1x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@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"}}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

After

Width:  |  Height:  |  Size: 678 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 282 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 462 B

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 704 B

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 862 B

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 762 B

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "background.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 B

View File

@@ -1,23 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "LaunchImage.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "LaunchImage@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

After

Width:  |  Height:  |  Size: 69 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

After

Width:  |  Height:  |  Size: 69 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

After

Width:  |  Height:  |  Size: 69 B

View File

@@ -16,13 +16,19 @@
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
</imageView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" image="LaunchBackground" translatesAutoresizingMaskIntoConstraints="NO" id="tWc-Dq-wcI"/>
<imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4"></imageView>
</subviews>
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="3T2-ad-Qdv"/>
<constraint firstItem="tWc-Dq-wcI" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="RPx-PI-7Xg"/>
<constraint firstItem="tWc-Dq-wcI" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="SdS-ul-q2q"/>
<constraint firstAttribute="trailing" secondItem="tWc-Dq-wcI" secondAttribute="trailing" id="Swv-Gf-Rwn"/>
<constraint firstAttribute="trailing" secondItem="YRO-k0-Ey4" secondAttribute="trailing" id="TQA-XW-tRk"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="bottom" secondItem="Ze5-6b-2t3" secondAttribute="bottom" id="duK-uY-Gun"/>
<constraint firstItem="tWc-Dq-wcI" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leading" id="kV7-tw-vXt"/>
<constraint firstItem="YRO-k0-Ey4" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="top" id="xPn-NY-SIU"/>
</constraints>
</view>
</viewController>
@@ -33,5 +39,6 @@
</scenes>
<resources>
<image name="LaunchImage" width="168" height="185"/>
<image name="LaunchBackground" width="1" height="1"/>
</resources>
</document>

View File

@@ -1,49 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Citycards Customer</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>citycards_customer</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(FLUTTER_BUILD_NAME)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
<dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Citycards Customer</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>citycards_customer</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>3</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>We need access to your camera for taking photos for profile and to build a postcard.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Citycard customer needs your location to find the closest place you can visit.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Citycard customer needs your location to find the closest place you can visit.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to your camera for taking photos for profile and to build a postcard.</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIStatusBarHidden</key>
<false/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@@ -28,6 +28,7 @@ class AddDetailsView extends StatelessWidget {
isWhiteLogo: false,
isProfilePage: false,
showCart: false,
showDivider: true,
),
Row(
children: [

View File

@@ -38,14 +38,9 @@ class AttractionDetailsView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CommonAppBar(isWhiteLogo: true, isProfilePage: false),
CommonAppBar(isWhiteLogo: true, isProfilePage: false, showDivider: true,),
SizedBox(height: 10.h),
Divider(
color: Colors.white.withOpacity(0.6),
height: 1.h,
),
SizedBox(height: 8.h),
Row(
children: [

View File

@@ -1,3 +1,5 @@
import 'package:citycards_customer/common_packages/common_app_texts.dart';
import '../models/attraction_model.dart';
class AttractionsRepository {
@@ -8,7 +10,7 @@ class AttractionsRepository {
location: "Krong Siem Reap",
price: "\$25",
image: "assets/dummy/dummy_1.jpg",
tags: ["Unlimited Card", "Flexi Card"],
tags: ["Unlimited Card", "${CommonAppText.selectiveCard} Card"],
isBookingRequired: false,
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Convallis condimentum morbi non egestas enim amet sagittis. Proin sed aliquet rhoncus ut pellentesque ullamcorper sit eget ac.Sit nisi, cras amet varius eget egestas pellentesque. Cursus gravida euismod non... ",
@@ -28,7 +30,7 @@ class AttractionsRepository {
location: "Krong Siem Reap",
price: "\$25",
image: "assets/dummy/dummy_3.jpg",
tags: ["Unlimited Card", "Flexi Card"],
tags: ["Unlimited Card", "${CommonAppText.selectiveCard} Card"],
isBookingRequired: false,
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Convallis condimentum morbi non egestas enim amet sagittis. Proin sed aliquet rhoncus ut pellentesque ullamcorper sit eget ac.Sit nisi, cras amet varius eget egestas pellentesque. Cursus gravida euismod non... ",
@@ -38,7 +40,7 @@ class AttractionsRepository {
location: "Krong Siem Reap",
price: "\$25",
image: "assets/dummy/dummy_4.jpg",
tags: ["Flexi Card"],
tags: ["${CommonAppText.selectiveCard} Card"],
isBookingRequired: false,
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Convallis condimentum morbi non egestas enim amet sagittis. Proin sed aliquet rhoncus ut pellentesque ullamcorper sit eget ac.Sit nisi, cras amet varius eget egestas pellentesque. Cursus gravida euismod non... ",
@@ -48,7 +50,7 @@ class AttractionsRepository {
location: "Krong Siem Reap",
price: "\$25",
image: "assets/dummy/dummy_5.jpg",
tags: ["Unlimited Card", "Flexi Card"],
tags: ["Unlimited Card", "${CommonAppText.selectiveCard} Card"],
isBookingRequired: false,
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Convallis condimentum morbi non egestas enim amet sagittis. Proin sed aliquet rhoncus ut pellentesque ullamcorper sit eget ac.Sit nisi, cras amet varius eget egestas pellentesque. Cursus gravida euismod non... ",
@@ -63,7 +65,7 @@ class AttractionsRepository {
location: "Krong Siem Reap",
price: "\$25",
image: "assets/dummy/dummy_1.jpg",
tags: ["Unlimited Card", "Flexi Card"],
tags: ["Unlimited Card", "${CommonAppText.selectiveCard} Card"],
isBookingRequired: true,
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Convallis condimentum morbi non egestas enim amet sagittis. Proin sed aliquet rhoncus ut pellentesque ullamcorper sit eget ac.Sit nisi, cras amet varius eget egestas pellentesque. Cursus gravida euismod non... ",
@@ -83,7 +85,7 @@ class AttractionsRepository {
location: "Krong Siem Reap",
price: "\$25",
image: "assets/dummy/dummy_3.jpg",
tags: ["Unlimited Card", "Flexi Card"],
tags: ["Unlimited Card", "${CommonAppText.selectiveCard} Card"],
isBookingRequired: true,
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Convallis condimentum morbi non egestas enim amet sagittis. Proin sed aliquet rhoncus ut pellentesque ullamcorper sit eget ac.Sit nisi, cras amet varius eget egestas pellentesque. Cursus gravida euismod non... ",
@@ -93,7 +95,7 @@ class AttractionsRepository {
location: "Krong Siem Reap",
price: "\$25",
image: "assets/dummy/dummy_4.jpg",
tags: ["Flexi Card"],
tags: ["${CommonAppText.selectiveCard} Card"],
isBookingRequired: true,
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Convallis condimentum morbi non egestas enim amet sagittis. Proin sed aliquet rhoncus ut pellentesque ullamcorper sit eget ac.Sit nisi, cras amet varius eget egestas pellentesque. Cursus gravida euismod non... ",
@@ -103,7 +105,7 @@ class AttractionsRepository {
location: "Krong Siem Reap",
price: "\$25",
image: "assets/dummy/dummy_5.jpg",
tags: ["Unlimited Card", "Flexi Card"],
tags: ["Unlimited Card", "${CommonAppText.selectiveCard} Card"],
isBookingRequired: true,
description:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Convallis condimentum morbi non egestas enim amet sagittis. Proin sed aliquet rhoncus ut pellentesque ullamcorper sit eget ac.Sit nisi, cras amet varius eget egestas pellentesque. Cursus gravida euismod non... ",

View File

@@ -41,7 +41,7 @@ class AttractionsPage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// App bar
CommonAppBar(isWhiteLogo: false, isProfilePage: false),
CommonAppBar(isWhiteLogo: false, isProfilePage: false, showDivider: true),
backWidget(context, "Your Attraction", Colors.black),
const SizedBox(height: 20),

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../../common_packages/common_app_texts.dart';
import '../../core/route_constants.dart';
import '../models/attraction_model.dart';
@@ -86,13 +87,13 @@ class AttractionCard extends StatelessWidget {
vertical: 4,
),
decoration: BoxDecoration(
color: tag == "Flexi Card"
color: tag == "${CommonAppText.selectiveCard} Card"
? const Color(0xffF95FAF).withOpacity(0.1)
: const Color(
0xffF95F62,
).withOpacity(0.1),
border: Border.all(
color: tag == "Flexi Card"
color: tag == "${CommonAppText.selectiveCard} Card"
? const Color(0xffF95FAF)
: const Color(0xffF95F62),
),

View File

@@ -7,6 +7,8 @@ import 'package:citycards_customer/core/route_constants.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../common_packages/common_app_texts.dart';
class BuyPassView extends StatelessWidget {
BuyPassView({super.key});
@@ -41,7 +43,7 @@ class BuyPassView extends StatelessWidget {
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 20.0.w),
child: CommonAppBar(isWhiteLogo: false, isProfilePage: true),
child: CommonAppBar(isWhiteLogo: false, isProfilePage: true,showDivider: true,),
),
Padding(
@@ -68,9 +70,9 @@ class BuyPassView extends StatelessWidget {
scrollDirection: Axis.horizontal,
child: Row(
children: [
PassCardView(themeColor: Color(0xFFF95FAF)),
PassCardView(themeColor: Color(0xFFF97316)),
SizedBox(width: 12.w),
PassCardView(themeColor: Color(0xFF1E8AF6)),
PassCardView(themeColor: Color(0xFF1E8AF6),),
],
),
),
@@ -203,6 +205,8 @@ class BuyPassView extends StatelessWidget {
text: offer["description"] ?? "",
color: Colors.black.withOpacity(.6),
size: 12.sp,
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
@@ -215,7 +219,7 @@ class BuyPassView extends StatelessWidget {
Center(
child: PaymentCard(
city: 'Melbourne',
tag: 'Flexi Card',
tag: '${CommonAppText.selectiveCard} Card',
oldPrice: 120,
newPrice: 90,
),

View File

@@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../common_packages/common_app_texts.dart';
class FeatureTable extends StatelessWidget {
const FeatureTable({super.key});
@@ -66,7 +68,7 @@ class FeatureTable extends StatelessWidget {
padding: EdgeInsets.symmetric(vertical: 6.h),
child: Center(
child: Text(
'Flexi',
'${CommonAppText.selectiveCard}',
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 16.sp),
),
),

View File

@@ -2,6 +2,8 @@ import 'package:citycards_customer/common_packages/custom_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../common_packages/common_app_texts.dart';
class PassCardView extends StatelessWidget {
final Color? themeColor;
final String? city;
@@ -26,140 +28,138 @@ class PassCardView extends StatelessWidget {
border: Border.all(color:( themeColor ?? Color(0xFFF95FAF)).withOpacity(0.24)),
borderRadius: BorderRadius.circular(8.r),
),
child: Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
ClipRRect(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8.r),
bottomLeft: Radius.circular(8.r)
),
child: Image.asset(
"assets/images/card_banner.png",
scale: 4,
width: 103.w,
height:140.h,
fit: BoxFit.cover,
),
),
SizedBox(width: 6.66.w),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CustomText(
text: "Melbourne",
weight: FontWeight.w500,
size: 16.sp,
),
Row(
children: [
Text(
"From ",
style: TextStyle(
color: Colors.black.withOpacity(0.6),
fontSize: 11.sp,
fontWeight: FontWeight.w400,
),
),
Text(
"\$80",
style: TextStyle(
color:themeColor,
fontWeight: FontWeight.w500,
fontSize: 24.sp,
),
),
Text(
" /Adult",
style: TextStyle(
color: Colors.black.withOpacity(0.8),
fontSize: 11.sp,
fontWeight: FontWeight.w400,
),
),
],
),
Row(
children: [
Text(
"and ",
style: TextStyle(
color: Colors.black.withOpacity(0.6),
fontSize: 11.sp,
fontWeight: FontWeight.w400,
),
),
Text(
"\$10",
style: TextStyle(
color: themeColor,
fontWeight: FontWeight.w500,
fontSize: 24.sp,
),
),
Text(
" /child",
style: TextStyle(
color: Colors.black.withOpacity(0.8),
fontSize: 11.sp,
fontWeight: FontWeight.w400,
),
),
],
),
SizedBox(
width: 193.w,
child: CustomText(
text:
"Dive into an extensive selection of thrilling destinations!",
color: Color(0xFF000000).withOpacity(0.6),
size: 11.sp,
),
),
],
),
],
),
Container(
width: 35.w,
height: 140.h,
decoration: BoxDecoration(
color: themeColor,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
ClipRRect(
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(8.r),
topRight: Radius.circular(8.r),
topLeft: Radius.circular(8.r),
bottomLeft: Radius.circular(8.r)
),
child: Image.asset(
"assets/images/card_banner.png",
scale: 4,
width: 103.w,
height:140.h,
fit: BoxFit.cover,
),
),
child: RotatedBox(
quarterTurns: -1,
child: Center(
child: RichText(
text: TextSpan(
children: [
TextSpan(
text: "Flexi ",
style: TextStyle(color: Colors.white, fontSize: 16.sp),
SizedBox(width: 6.66.w),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CustomText(
text: "Melbourne",
weight: FontWeight.w500,
size: 16.sp,
),
Row(
children: [
Text(
"From ",
style: TextStyle(
color: Colors.black.withOpacity(0.6),
fontSize: 11.sp,
fontWeight: FontWeight.w400,
),
TextSpan(
text: "Card",
style: TextStyle(color: Colors.white, fontSize: 12.sp),
),
Text(
"\$80",
style: TextStyle(
color:themeColor,
fontWeight: FontWeight.w500,
fontSize: 24.sp,
),
],
),
Text(
" /Adult",
style: TextStyle(
color: Colors.black.withOpacity(0.8),
fontSize: 11.sp,
fontWeight: FontWeight.w400,
),
),
],
),
Row(
children: [
Text(
"and ",
style: TextStyle(
color: Colors.black.withOpacity(0.6),
fontSize: 11.sp,
fontWeight: FontWeight.w400,
),
),
Text(
"\$10",
style: TextStyle(
color: themeColor,
fontWeight: FontWeight.w500,
fontSize: 24.sp,
),
),
Text(
" /child",
style: TextStyle(
color: Colors.black.withOpacity(0.8),
fontSize: 11.sp,
fontWeight: FontWeight.w400,
),
),
],
),
SizedBox(
width: 193.w,
child: CustomText(
text:
"Dive into an extensive selection of thrilling destinations!",
color: Color(0xFF000000).withOpacity(0.6),
size: 11.sp,
),
),
],
),
],
),
Container(
width: 35.w,
height: 140.h,
decoration: BoxDecoration(
color: themeColor,
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(8.r),
topRight: Radius.circular(8.r),
),
),
child: RotatedBox(
quarterTurns: -1,
child: Center(
child: RichText(
text: TextSpan(
children: [
TextSpan(
text: "${CommonAppText.selectiveCard} ",
style: TextStyle(color: Colors.white, fontSize: 16.sp),
),
TextSpan(
text: "Card",
style: TextStyle(color: Colors.white, fontSize: 12.sp),
),
],
),
),
),
),
],
),
),
],
),
);
);
}
}

View File

@@ -126,7 +126,6 @@ class _PaymentCardState extends State<PaymentCard> {
onTap: () {
Navigator.of(
context,
rootNavigator: true,
).pushNamed(RouteConstants.checkout);
},
label: "Proceed to Pay",

View File

@@ -38,6 +38,7 @@ class _MyCartPageState extends State<MyCartPage> {
isWhiteLogo: false,
isProfilePage: false,
showCart: false,
showDivider: true,
),
backWidget(context, "Your Cart", Colors.black),
SizedBox(height: 24.h),

View File

@@ -6,6 +6,8 @@ import 'package:citycards_customer/common_packages/custom_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../checkout/widget/login_email_bottomsheet.dart';
import '../../common_packages/common_app_texts.dart';
import '../blocs/pass_bloc.dart';
class MyPassesPage extends StatelessWidget {
@@ -23,14 +25,13 @@ class MyPassesPage extends StatelessWidget {
children: [
SizedBox(height: 22.h),
Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Color(0xFFF95FAF).withOpacity(0.2),
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(
color: Color(0xFFF95FAF).withOpacity(0.2),
),
borderRadius: BorderRadius.circular(8.r),
),
borderRadius: BorderRadius.circular(8.r),
),
child: Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -154,7 +155,7 @@ class MyPassesPage extends StatelessWidget {
width: 35.w,
height: 123.h,
decoration: BoxDecoration(
color: Color(0xFFF95FAF),
color: Color(0xFFF97316),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(8.r),
topRight: Radius.circular(8.r),
@@ -167,7 +168,7 @@ class MyPassesPage extends StatelessWidget {
text: TextSpan(
children: [
TextSpan(
text: "Flexi ",
text: "${CommonAppText.selectiveCard} ",
style: TextStyle(
color: Colors.white,
fontSize: 16.sp,
@@ -189,8 +190,6 @@ class MyPassesPage extends StatelessWidget {
],
),
),
),
SizedBox(height: 15.h),
Container(
padding: EdgeInsets.symmetric(
@@ -336,7 +335,19 @@ class MyPassesPage extends StatelessWidget {
SizedBox(height: 150.h,),
CustomFilledButton(
onTap: () {},
onTap: () {
showModalBottomSheet(
backgroundColor: Colors.white,
context: context,
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(12.r),
),
),
builder: (_) => const LoginEmailBottomsheet(),
);
},
width: double.infinity,
label: "Proceed to Checkout",
),

View File

@@ -5,6 +5,7 @@ import 'package:citycards_customer/common_packages/custom_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../checkout/widget/login_email_bottomsheet.dart';
import '../blocs/postcard_bloc.dart';
class MyPostCardsPage extends StatelessWidget {
@@ -156,7 +157,19 @@ class MyPostCardsPage extends StatelessWidget {
),
SizedBox(height: 60.h),
CustomFilledButton(
onTap: () {},
onTap: () {
showModalBottomSheet(
backgroundColor: Colors.white,
context: context,
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(12.r),
),
),
builder: (_) => const LoginEmailBottomsheet(),
);
},
width: double.infinity,
label: "Proceed to Checkout",
),

View File

@@ -14,26 +14,23 @@ class TicketCard extends StatelessWidget {
clipper: TicketClipper(),
child: Container(
width: 270.w,
height: 410.h,
height: 400.h,
padding: EdgeInsets.all(16.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12.r),
),
child: Column(
children: [
// Image Section
ClipRRect(
borderRadius: BorderRadius.circular(12.r),
child: Image.asset(
'assets/images/card_banner.png',
width: double.infinity,
width: 237.w,
height: 198.h,
fit: BoxFit.cover,
),
),
SizedBox(height: 24.h),
// Dashed divider
SizedBox(height: 20.h),
SizedBox(
width: 200.w,
child: DashedDivider(
@@ -41,7 +38,7 @@ class TicketCard extends StatelessWidget {
thickness: 2.h,
),
),
SizedBox(height: 6.h),
Text(
"Melbourne",
style: TextStyle(
@@ -49,7 +46,7 @@ class TicketCard extends StatelessWidget {
fontWeight: FontWeight.w500,
),
),
SizedBox(height: 12.h),
SizedBox(height: 6.h),
_infoRow("Postcards :", "5"),
_infoRow("Date :", "22/04/2025"),
_infoRow("Time :", "12:00PM - 2:00PM"),
@@ -84,36 +81,39 @@ class TicketCard extends StatelessWidget {
class TicketPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
const notchRadius = 23.0;
const dividerY = 222.0;
final notchRadius = 23.r;
final dividerY = 240.h;
final ticketPath = Path()
..moveTo(12, 0)
..lineTo(size.width - 12, 0)
..arcToPoint(Offset(size.width, 12), radius: const Radius.circular(12))
..moveTo(12.w, 0)
..lineTo(size.width - 12.w, 0)
..arcToPoint(Offset(size.width, 12.h), radius: Radius.circular(12.r))
..lineTo(size.width, dividerY - notchRadius)
..arcToPoint(
Offset(size.width, dividerY + notchRadius),
radius: const Radius.circular(notchRadius),
radius: Radius.circular(notchRadius),
clockwise: false,
)
..lineTo(size.width, size.height - 12)
..arcToPoint(Offset(size.width - 12, size.height),
radius: const Radius.circular(12))
..lineTo(12, size.height)
..arcToPoint(Offset(0, size.height - 12),
radius: const Radius.circular(12))
..lineTo(size.width, size.height - 12.h)
..arcToPoint(
Offset(size.width - 12.w, size.height),
radius: Radius.circular(12.r),
)
..lineTo(12.w, size.height)
..arcToPoint(
Offset(0, size.height - 12.h),
radius: Radius.circular(12.r),
)
..lineTo(0, dividerY + notchRadius)
..arcToPoint(
Offset(0, dividerY - notchRadius),
radius: const Radius.circular(notchRadius),
radius: Radius.circular(notchRadius),
clockwise: false,
)
..lineTo(0, 12)
..arcToPoint(Offset(12, 0), radius: const Radius.circular(12))
..lineTo(0, 12.h)
..arcToPoint(Offset(12.w, 0), radius: Radius.circular(12.r))
..close();
// 🌑 Draw even soft black shadow around all sides
final shadowPaint = Paint()
..color = Colors.black.withOpacity(0.3)
..maskFilter = const MaskFilter.blur(BlurStyle.outer, 8);
@@ -134,33 +134,37 @@ class TicketPainter extends CustomPainter {
class TicketClipper extends CustomClipper<Path> {
@override
Path getClip(Size size) {
const notchRadius = 23.0;
const dividerY = 222.0;
final notchRadius = 23.r;
final dividerY = 240.h;
final path = Path()
..moveTo(12, 0)
..lineTo(size.width - 12, 0)
..arcToPoint(Offset(size.width, 12), radius: const Radius.circular(12))
..moveTo(12.w, 0)
..lineTo(size.width - 12.w, 0)
..arcToPoint(Offset(size.width, 12.h), radius: Radius.circular(12.r))
..lineTo(size.width, dividerY - notchRadius)
..arcToPoint(
Offset(size.width, dividerY + notchRadius),
radius: const Radius.circular(notchRadius),
radius: Radius.circular(notchRadius),
clockwise: false,
)
..lineTo(size.width, size.height - 12)
..arcToPoint(Offset(size.width - 12, size.height),
radius: const Radius.circular(12))
..lineTo(12, size.height)
..arcToPoint(Offset(0, size.height - 12),
radius: const Radius.circular(12))
..lineTo(size.width, size.height - 12.h)
..arcToPoint(
Offset(size.width - 12.w, size.height),
radius: Radius.circular(12.r),
)
..lineTo(12.w, size.height)
..arcToPoint(
Offset(0, size.height - 12.h),
radius: Radius.circular(12.r),
)
..lineTo(0, dividerY + notchRadius)
..arcToPoint(
Offset(0, dividerY - notchRadius),
radius: const Radius.circular(notchRadius),
radius: Radius.circular(notchRadius),
clockwise: false,
)
..lineTo(0, 12)
..arcToPoint(Offset(12, 0), radius: const Radius.circular(12))
..lineTo(0, 12.h)
..arcToPoint(Offset(12.w, 0), radius: Radius.circular(12.r))
..close();
return path;

View File

@@ -7,6 +7,8 @@ import 'package:citycards_customer/common_packages/custom_dashed_line.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../common_packages/common_app_texts.dart';
class CheckoutView extends StatelessWidget {
const CheckoutView({super.key});
@@ -24,6 +26,7 @@ class CheckoutView extends StatelessWidget {
isWhiteLogo: false,
isProfilePage: false,
showCart: false,
showDivider: true,
),
Row(
children: [
@@ -39,13 +42,13 @@ class CheckoutView extends StatelessWidget {
),
SizedBox(height: 22.h),
Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Color(0xFFF95FAF).withOpacity(0.2)),
borderRadius: BorderRadius.circular(8.r),
),
child: Expanded(
Expanded(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Color(0xFFF95FAF).withOpacity(0.2)),
borderRadius: BorderRadius.circular(8.r),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -166,7 +169,7 @@ class CheckoutView extends StatelessWidget {
width: 35.w,
height: 123.h,
decoration: BoxDecoration(
color: Color(0xFFF95FAF),
color: Color(0xFFF97316),
borderRadius: BorderRadius.only(
bottomRight: Radius.circular(8.r),
topRight: Radius.circular(8.r),
@@ -179,7 +182,7 @@ class CheckoutView extends StatelessWidget {
text: TextSpan(
children: [
TextSpan(
text: "Flexi ",
text: "${CommonAppText.selectiveCard} ",
style: TextStyle(
color: Colors.white,
fontSize: 16.sp,
@@ -203,7 +206,7 @@ class CheckoutView extends StatelessWidget {
),
),
SizedBox(height: 15.h),
SizedBox(height: 10.h),
Container(
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 12.h),
decoration: BoxDecoration(
@@ -345,6 +348,7 @@ class CheckoutView extends StatelessWidget {
CustomFilledButton(
onTap: () {
showModalBottomSheet(
backgroundColor: Colors.white,
context: context,
isScrollControlled: true,
shape: RoundedRectangleBorder(

View File

@@ -1,4 +1,4 @@
import 'package:citycards_customer/checkout/widget/purchase_details_bottomsheet.dart';
import 'package:citycards_customer/postcard/widgets/purchase_details_bottom_sheet.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:citycards_customer/common_packages/custom_text.dart';
@@ -6,11 +6,23 @@ import 'package:citycards_customer/common_packages/custom_text.dart';
class AllCouponsBottomsheet extends StatelessWidget {
AllCouponsBottomsheet({super.key});
final List<String> coupons = [
"assets/images/red_coupon.png",
"assets/images/green_coupon.png",
"assets/images/orange_coupon.png",
"assets/images/orange_coupon.png",
final List<Map<String, String>> coupons = [
{
"text": "Flat 3% cashback using Amazon Pay Balance",
"coupon_code": "AMZNPAY3",
},
{
"text": "Flat 3% cashback using Amazon Pay Balance",
"coupon_code": "AMZNPAY3",
},
{
"text": "Flat 3% cashback using Amazon Pay Balance",
"coupon_code": "AMZNPAY3",
},
{
"text": "Flat 3% cashback using Amazon Pay Balance",
"coupon_code": "AMZNPAY3",
},
];
@override
@@ -48,6 +60,7 @@ class AllCouponsBottomsheet extends StatelessWidget {
itemCount: coupons.length,
separatorBuilder: (_, __) => SizedBox(height: 12.h),
itemBuilder: (context, index) {
final coupon = coupons[index];
return Container(
alignment: Alignment.center,
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 8.h),
@@ -58,42 +71,62 @@ class AllCouponsBottomsheet extends StatelessWidget {
color: const Color(0xFFF95F62).withOpacity(0.12),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Image.asset(
width: 183.9.w,
height: 72.82.h,
coupons[index],
fit: BoxFit.cover,
),
GestureDetector(
onTap: (){
Navigator.pop(context);
showModalBottomSheet(context: context,
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(12.r),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(
width: 220.w,
child: CustomText(
text: coupon['text'] ?? "",
size: 12.sp,
weight: FontWeight.w400,
),
),
GestureDetector(
onTap: () {
Navigator.pop(context);
PurchaseDetailsBottomSheet.show(context);
},
child: Container(
width: 110.w,
height: 44.h,
decoration: BoxDecoration(
color: Color(0xFFF95F62),
borderRadius: BorderRadius.circular(12.r),
),
child: Center(
child: CustomText(
text: "Apply Coupon",
size: 12.sp,
color: Colors.white,
),
),
builder: (_) => const PurchaseDetailsBottomsheet());
},
child: Container(
width: 110.w,
height: 44.h,
decoration: BoxDecoration(
color: Color(0xFFF95F62),
borderRadius: BorderRadius.circular(12.r),
),
child: Center(
child: CustomText(
text: "Apply Coupon",
size: 12.sp,
color: Colors.white,
),
),
],
),
SizedBox(height: 8.h),
Container(
height: 32.h,
width: 83.w,
decoration: BoxDecoration(
color: Color(0xFFF95F62).withOpacity(0.12),
border: Border.all(color: Color(0xFFF95F62)),
borderRadius: BorderRadius.circular(6.r),
),
child: Center(
child: CustomText(
text: coupon['coupon_code'] ?? "",
size: 12.sp,
weight: FontWeight.w400,
color: Color(0xFFF95F62),
),
),
),
],

View File

@@ -1,6 +1,7 @@
import 'package:citycards_customer/checkout/widget/verify_otp_bottomsheet.dart';
import 'package:citycards_customer/common_packages/custom_filled_button.dart';
import 'package:citycards_customer/common_packages/custom_text.dart';
import 'package:citycards_customer/core/route_constants.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
@@ -10,7 +11,6 @@ class LoginEmailBottomsheet extends StatelessWidget {
@override
Widget build(BuildContext context) {
return AnimatedPadding(
duration: const Duration(milliseconds: 250),
curve: Curves.easeOut,
padding: EdgeInsets.only(
@@ -19,87 +19,95 @@ class LoginEmailBottomsheet extends StatelessWidget {
right: 20.h,
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min, // shrink to fit content
children: [
Image.asset("assets/logo/logo_city_cards_orange.png", scale: 4),
SizedBox(height: 8.h),
CustomText(text: "Get Started", size: 18.sp, weight: FontWeight.w500),
SizedBox(height: 42.h),
CustomText(
text: "Enter your email to begin your CityCards journey",
size: 14.sp,
color: const Color(0xFF000000).withOpacity(.6),
),
SizedBox(height: 12.h),
TextField(
decoration: InputDecoration(
filled: true,
contentPadding: EdgeInsets.symmetric(vertical: 6.h),
fillColor: const Color(0xFFFFF5F5),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: const Color(0xFFBB474A), width: 0.4.w),
borderRadius: BorderRadius.circular(8.sp),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: const Color(0xFFBB474A), width: 0.4.w),
borderRadius: BorderRadius.circular(8.sp),
),
prefixIcon: const Icon(Icons.email_outlined, color: Color(0xFFF95F62)),
hintText: "john.doe@gmail.com",
hintStyle: TextStyle(
color: const Color(0xFF000000).withOpacity(0.6),
fontSize: 12.sp,
child: SafeArea(
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min, // shrink to fit content
children: [
Image.asset("assets/logo/logo_city_cards_orange.png", scale: 4),
SizedBox(height: 8.h),
CustomText(text: "Get Started", size: 18.sp, weight: FontWeight.w500),
SizedBox(height: 42.h),
CustomText(
text: "Enter your email to begin your CityCards journey",
size: 14.sp,
color: const Color(0xFF000000).withOpacity(.6),
),
SizedBox(height: 12.h),
TextField(
decoration: InputDecoration(
filled: true,
contentPadding: EdgeInsets.symmetric(vertical: 6.h),
fillColor: const Color(0xFFFFF5F5),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: const Color(0xFFBB474A), width: 0.4.w),
borderRadius: BorderRadius.circular(8.sp),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: const Color(0xFFBB474A), width: 0.4.w),
borderRadius: BorderRadius.circular(8.sp),
),
prefixIcon: const Icon(Icons.email_outlined, color: Color(0xFFF95F62)),
hintText: "john.doe@gmail.com",
hintStyle: TextStyle(
color: const Color(0xFF000000).withOpacity(0.6),
fontSize: 12.sp,
),
),
),
),
SizedBox(height: 38.h),
CustomFilledButton(
onTap: () {
Navigator.pop(context);
showModalBottomSheet(
context: context,
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(12.r),
SizedBox(height: 38.h),
CustomFilledButton(
onTap: () {
Navigator.pop(context);
showModalBottomSheet(
context: context,
backgroundColor: Colors.white,
isScrollControlled: true,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(12.r),
),
),
),
builder: (_) => VerifyOtpBottomsheet(),
);
},
label: "Continue",
width: double.infinity,
),
SizedBox(height: 20.h),
Text.rich(
TextSpan(
children: [
TextSpan(
text: "Already have an account?",
style: TextStyle(
color: Colors.black.withOpacity(0.6),
fontSize: 12.sp,
fontWeight: FontWeight.w400,
),
),
TextSpan(
text: " Sign in",
style: TextStyle(
color: const Color(0xFFF95F62),
fontSize: 12.sp,
fontWeight: FontWeight.w600,
),
),
],
builder: (_) => VerifyOtpBottomsheet(),
);
},
label: "Continue",
width: double.infinity,
),
),
SizedBox(height: 15.h),
],
SizedBox(height: 20.h),
InkWell(
onTap: (){
Navigator.of(context).pushNamed(RouteConstants.createAcct);
},
child: Text.rich(
TextSpan(
children: [
TextSpan(
text: "Already have an account?",
style: TextStyle(
color: Colors.black.withOpacity(0.6),
fontSize: 12.sp,
fontWeight: FontWeight.w400,
),
),
TextSpan(
text: " Sign in",
style: TextStyle(
color: const Color(0xFFF95F62),
fontSize: 12.sp,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
SizedBox(height: 15.h),
],
),
),
),
);

View File

@@ -1,215 +0,0 @@
import 'package:citycards_customer/checkout/bloc/purchase_details_bloc.dart';
import 'package:citycards_customer/common_packages/custom_filled_button.dart';
import 'package:citycards_customer/common_packages/custom_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class PurchaseDetailsBottomsheet extends StatelessWidget {
const PurchaseDetailsBottomsheet({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => PurchaseDetailsBloc(),
child: AnimatedPadding(
duration: const Duration(milliseconds: 250),
curve: Curves.easeOut,
padding: EdgeInsets.only(
top: 24.h,
left: 20.w,
right: 20.w,
bottom: MediaQuery.of(context).viewInsets.bottom,
),
child: BlocBuilder<PurchaseDetailsBloc, PurchaseDetailsState>(
builder: (context, state) {
final selected = state.buyPassState;
return Column(
mainAxisSize: MainAxisSize.min,
children: [
// --- Handle Bar ---
Container(
height: 4.h,
width: 40.w,
decoration: BoxDecoration(
color: const Color(0xFF2D3134),
borderRadius: BorderRadius.circular(4.r),
),
),
SizedBox(height: 12.h),
CustomText(
text: "Purchase Details",
size: 18.sp,
weight: FontWeight.w600,
),
SizedBox(height: 22.h),
// --- Option 1: Buy for Myself ---
GestureDetector(
onTap: () {
context.read<PurchaseDetailsBloc>().add(
SetPurchaseDetailsEvent("myself"),
);
},
child: Container(
padding: EdgeInsets.all(6),
decoration: BoxDecoration(
border: Border.all(
color: selected == "myself"
? const Color(0xFFF95F62)
: Colors.transparent,
),
borderRadius: BorderRadius.circular(10.r),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
selected == "myself"
? Icons.radio_button_checked
: Icons.radio_button_off,
color: selected == "myself"
? const Color(0xFFF95F62)
: Color(0xFF2B2929).withOpacity(.6),
size: 24.sp,
),
SizedBox(width: 8.w),
CustomText(
text: "Buy Pass for Myself",
color: selected == "myself"
? const Color(0xFFF95F62)
: Color(0xFF2B2929).withOpacity(.6),
size: 16.sp,
weight: FontWeight.w500,
),
],
),
if (selected == "myself") ...[
SizedBox(height: 6.h),
CustomText(
text: "Frank Adam",
size: 14.sp,
weight: FontWeight.w400,
color: Colors.black.withOpacity(0.6),
),
SizedBox(height: 4.h),
CustomText(
text: "132 My Street, Kingston, NY 12401",
size: 12.sp,
color: const Color(
0xFF000000,
).withOpacity(0.4),
),
],
],
),
),
if (selected == "myself")
Container(
padding: EdgeInsets.symmetric(
horizontal: 6.w,
vertical: 6.h,
),
decoration: BoxDecoration(
color: Color(0xFFF95F62).withOpacity(0.12),
border: Border.all(
color: const Color(0xFFF95F62),
width: 1,
),
borderRadius: BorderRadius.circular(12.r),
),
child: CustomText(
text: "Edit Details",
size: 16.sp,
weight: FontWeight.w500,
color: const Color(0xFFF95F62),
),
),
],
),
),
),
SizedBox(height: 16.h),
// --- Option 2: Gift the Pass ---
GestureDetector(
onTap: () {
context.read<PurchaseDetailsBloc>().add(
SetPurchaseDetailsEvent("gift"),
);
},
child: Container(
padding: EdgeInsets.all(12.w),
decoration: BoxDecoration(
border: Border.all(
color: selected == "gift"
? const Color(0xFFF95F62)
: Colors.transparent,
),
borderRadius: BorderRadius.circular(12.r),
),
child: Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Icon(
selected == "gift"
? Icons.radio_button_checked
: Icons.radio_button_off,
color: selected == "gift"
? const Color(0xFFF95F62)
: Color(0xFF2F2A2A).withOpacity(0.4),
size: 24.sp,
),
SizedBox(width: 8.w),
CustomText(
text: "Gift the pass",
color: selected == "gift"
? const Color(0xFFF95F62)
: Color(0xFF2F2A2A).withOpacity(0.4),
size: 16.sp,
weight: FontWeight.w500,
),
],
),
SizedBox(height: 6.h),
if (selected == "gift")
CustomText(
text: "Gift the pass for someone else",
size: 12.sp,
color: const Color(0xFF000000).withOpacity(0.6),
),
],
),
),
),
),
SizedBox(height: 24.h),
// --- Proceed Button ---
CustomFilledButton(
onTap: () {},
label: "Proceed",
width: double.infinity,
),
SizedBox(height: 20.h),
],
);
},
),
),
);
}
}

View File

@@ -4,6 +4,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_otp_text_field/flutter_otp_text_field.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../core/route_constants.dart';
class VerifyOtpBottomsheet extends StatelessWidget {
VerifyOtpBottomsheet({super.key});
@@ -76,32 +78,39 @@ class VerifyOtpBottomsheet extends StatelessWidget {
SizedBox(height: 42.h),
CustomFilledButton(
onTap: () {},
onTap: () {
Navigator.pop(context);
},
label: "Continue",
width: double.infinity,
),
SizedBox(height: 20.h),
Text.rich(
TextSpan(
children: [
TextSpan(
text: "Already have an account?",
style: TextStyle(
color: Colors.black.withOpacity(0.6),
fontSize: 12.sp,
fontWeight: FontWeight.w400,
InkWell(
onTap: () {
Navigator.of(context).pushNamed(RouteConstants.createAcct);
},
child: Text.rich(
TextSpan(
children: [
TextSpan(
text: "Already have an account?",
style: TextStyle(
color: Colors.black.withOpacity(0.6),
fontSize: 12.sp,
fontWeight: FontWeight.w400,
),
),
),
TextSpan(
text: " Sign in",
style: TextStyle(
color: const Color(0xFFF95F62),
fontSize: 12.sp,
fontWeight: FontWeight.w600,
TextSpan(
text: " Sign in",
style: TextStyle(
color: const Color(0xFFF95F62),
fontSize: 12.sp,
fontWeight: FontWeight.w600,
),
),
),
],
],
),
),
),
SizedBox(height: 15.h),

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../core/route_constants.dart';
import '../home/widgets/search_city_bottomsheet.dart';
class CommonAppBar extends StatelessWidget {
const CommonAppBar({
@@ -9,11 +10,13 @@ class CommonAppBar extends StatelessWidget {
required this.isWhiteLogo,
required this.isProfilePage,
this.showCart = true,
required this.showDivider
});
final bool isWhiteLogo;
final bool isProfilePage;
final bool? showCart;
final bool showDivider;
@override
Widget build(BuildContext context) {
@@ -22,11 +25,25 @@ class CommonAppBar extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Image.asset(
isWhiteLogo
? "assets/logo/logo_city_cards_white.png"
: "assets/logo/logo_city_cards.png",
scale: 4,
Row(
children: [
Image.asset(
isWhiteLogo
? "assets/logo/melbourne_white.png"
: "assets/logo/melbourne_logo.png",
scale: 4,
),
IconButton(onPressed: (){
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (_) => const CitySelectionBottomSheet(),
);
}, icon: Icon(Icons.arrow_drop_down, color: isWhiteLogo ? Colors.white : Color(0xffF95F62), size: 30,))
],
),
Row(
children: [
@@ -61,16 +78,14 @@ class CommonAppBar extends StatelessWidget {
},
child: CircleAvatar(
backgroundColor: Color(0xffFFDFDF),
backgroundImage: AssetImage(
"assets/images/profile_img.png",
),
child: Image.asset( "assets/images/profile_default_img.png",),
),
),
],
),
],
),
if (!isWhiteLogo)
if (showDivider)
Column(
children: [
SizedBox(height: 12.h),

View File

@@ -0,0 +1,3 @@
class CommonAppText {
static const String selectiveCard = "Selective";
}

View File

@@ -87,6 +87,7 @@ class LanguageSelectionBottomsheet extends StatelessWidget {
showModalBottomSheet(
context: context,
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(
top: Radius.circular(12.r),

View File

@@ -1,4 +1,5 @@
import 'package:citycards_customer/common_packages/app_bar.dart';
import 'package:citycards_customer/common_packages/back_widget.dart';
import 'package:flutter/material.dart';
import 'package:citycards_customer/common_packages/custom_text.dart';
import 'package:citycards_customer/common_packages/custom_textfield.dart';
@@ -24,30 +25,9 @@ class ContactUsPage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header bar
CommonAppBar(isWhiteLogo: false, isProfilePage: true),
SizedBox(height: 12.h),
Divider(height: 1.h, color: Color(0xFFD9D9D9)),
SizedBox(height: 22.h),
CommonAppBar(isWhiteLogo: false, isProfilePage: true, showDivider: true,),
// Back + Title
Row(
children: [
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back, size: 24.sp),
),
SizedBox(width: 8.w),
Text(
"Contact Us",
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
),
),
],
),
backWidget(context,"Contact Us", Colors.black),
SizedBox(height: 22.h),
CustomText(

View File

@@ -10,6 +10,7 @@ import 'package:citycards_customer/edit_profile/edit_profile_view.dart';
import 'package:citycards_customer/esim_offer/esim_offer_view.dart';
import 'package:citycards_customer/faq/faq_view.dart';
import 'package:citycards_customer/hotel_offer/hotel_offer_view.dart';
import 'package:citycards_customer/intro_screens/views/intro_screen_view.dart';
import 'package:citycards_customer/itinerary_creation/bloc/itinerary_detail_bloc.dart';
import 'package:citycards_customer/itinerary_creation/bloc/itinerary_steps_selection_bloc.dart';
import 'package:citycards_customer/itinerary_creation/views/itinerary_creation_start_view.dart';
@@ -20,7 +21,9 @@ import 'package:citycards_customer/offer_pass_detail/offer_pass_detail_view.dart
import 'package:citycards_customer/privacy/privacy_view.dart';
import 'package:citycards_customer/search_offers/bloc/search_offers_listing_bloc.dart';
import 'package:citycards_customer/search_offers/view/search_offers_with_listing.dart';
import 'package:citycards_customer/splash_screen/views/splash_screen.dart';
import 'package:citycards_customer/terms_and_condition/terms_and_condition_view.dart';
import 'package:citycards_customer/trail.dart';
import 'package:citycards_customer/your_itinerary/view/your_itinerary_view.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
@@ -28,10 +31,12 @@ import '../attractions/views/attractions_page_view.dart';
import '../cart/views/my_cart_view_page.dart';
import '../common_bloc/bottom_navigation_bloc.dart';
import '../home/views/home_page_view.dart';
import '../home/views/registered_user_home_page.dart';
import 'route_constants.dart';
class AppRouter {
Route onGenerateRoute(RouteSettings settings) {
print('Navigating to route: ${settings.name}');
switch (settings.name) {
case '/':
case RouteConstants.home:
@@ -43,6 +48,21 @@ class AppRouter {
);
},
);
case RouteConstants.splash:
print('✅ Splash route matched');
return MaterialPageRoute(
builder: (_) {
return SplashScreen();
},
);
case RouteConstants.intro:
return MaterialPageRoute(
builder: (_) {
return IntroScreensView();
},
);
case RouteConstants.attractionsPage:
final args = settings.arguments as String;
return MaterialPageRoute(builder: (_) => AttractionsPage(source: args));
@@ -185,19 +205,32 @@ class AppRouter {
);
case RouteConstants.magicItineraryEmptyScreen:
return MaterialPageRoute(builder: (_){
return MagicItineraryEmptyView();
});
return MaterialPageRoute(
builder: (_) {
return MagicItineraryEmptyView();
},
);
case RouteConstants.magicItineraryFilledScreen:
return MaterialPageRoute(builder: (_){
return MagicItineraryFilledView();
});
return MaterialPageRoute(
builder: (_) {
return MagicItineraryFilledView();
},
);
case RouteConstants.offerPassDetail:
return MaterialPageRoute(builder: (_){
return OfferPassDetailView();
});
return MaterialPageRoute(
builder: (_) {
return OfferPassDetailView();
},
);
case RouteConstants.registeredUserHome:
return MaterialPageRoute(
builder: (_) {
return RegisteredUserHomePage();
},
);
default:
return MaterialPageRoute(
builder: (_) =>

View File

@@ -1,4 +1,5 @@
import 'package:citycards_customer/core/route_constants.dart';
import 'package:citycards_customer/home/views/registered_user_home_page.dart';
import 'package:citycards_customer/my_pass/blocs/my_pass_bloc.dart';
import 'package:citycards_customer/postcard/views/add_filter_step_page_view.dart';
import 'package:flutter/material.dart';
@@ -6,19 +7,30 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import '../attraction_details/attraction_details_view.dart';
import '../attractions/views/attractions_page_view.dart';
import '../buy_a_pass/view/buy_pass_view.dart';
import '../checkout/view/checkout_view.dart';
import '../create_account/create_account_view.dart';
import '../intro_screens/views/intro_screen_view.dart';
import '../itinerary_creation/bloc/itinerary_detail_bloc.dart';
import '../itinerary_creation/bloc/itinerary_steps_selection_bloc.dart';
import '../itinerary_creation/views/itinerary_creation_view.dart';
import '../itinerary_creation/views/magic_itinerary_filled_view.dart';
import '../my_pass/views/booking_page_view.dart';
import '../my_pass/views/booking_successful_page_view.dart';
import '../my_pass/views/qr_pass_page_view.dart';
import '../offer_pass_detail/offer_pass_detail_view.dart';
import '../postcard/blocs/postcard_creation_bloc.dart';
import '../postcard/views/postcard_creation_page_view.dart';
import '../search_offers/bloc/search_offers_listing_bloc.dart';
import '../search_offers/view/search_offers_with_listing.dart';
import '../your_itinerary/view/your_itinerary_view.dart';
Widget buildOffstageNavigator(
int index,
int currentIndex,
Widget child,
Key key,
) {
int index,
int currentIndex,
Widget child,
Key key,
) {
return Offstage(
offstage: currentIndex != index,
child: Navigator(
@@ -28,21 +40,46 @@ Widget buildOffstageNavigator(
case '/':
return MaterialPageRoute(builder: (_) => child);
// 🔹 Attractions Page
case RouteConstants.intro:
return MaterialPageRoute(builder: (_){
return IntroScreensView();
});
// 🔹 Attractions Page
case RouteConstants.attractionsPage:
final args = settings.arguments as String;
return MaterialPageRoute(
builder: (_) => AttractionsPage(source: args,),
builder: (_) => AttractionsPage(source: args),
);
case RouteConstants.attractionDetails:
return MaterialPageRoute(builder: (_) {
return AttractionDetailsView();
});
return MaterialPageRoute(
builder: (_) {
return AttractionDetailsView();
},
);
case RouteConstants.makeBooking:
return MaterialPageRoute(builder: (_) {
return MakeBookingView(title: 'asffdsf', description: 'afdsfadsfasdfads',);
case RouteConstants.makeBooking:
return MaterialPageRoute(
builder: (_) {
return MakeBookingView(
title: 'Koh Rong Samloem',
description:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Convallis condimentum morbi non egestas enim amet sagittis.ß',
);
},
);
case RouteConstants.bookingSuccessful:
return MaterialPageRoute(
builder: (_) {
return BookingSuccessfulPageView();
},
);
case RouteConstants.offerPassDetail:
return MaterialPageRoute(builder: (_){
return OfferPassDetailView();
});
case RouteConstants.searchOffer:
@@ -55,7 +92,7 @@ Widget buildOffstageNavigator(
},
);
// 🔹 Upload Photo Page (start of postcard creation flow)
// 🔹 Upload Photo Page (start of postcard creation flow)
case RouteConstants.uploadPhotoPage:
return MaterialPageRoute(
builder: (_) => BlocProvider(
@@ -64,11 +101,13 @@ Widget buildOffstageNavigator(
),
);
// 🔹 Add Filter Page (uses same bloc instance)
// 🔹 Add Filter Page (uses same bloc instance)
case RouteConstants.addFilterPage:
return MaterialPageRoute(
builder: (context) {
final previousBloc = BlocProvider.of<PostcardCreationBloc>(context);
final previousBloc = BlocProvider.of<PostcardCreationBloc>(
context,
);
return BlocProvider.value(
value: previousBloc,
child: const AddFilterStepPageView(),
@@ -76,7 +115,6 @@ Widget buildOffstageNavigator(
},
);
case RouteConstants.qrPage:
return MaterialPageRoute(
builder: (context) {
@@ -88,11 +126,68 @@ Widget buildOffstageNavigator(
},
);
case RouteConstants.itineraryCreation:
return MaterialPageRoute(
builder: (_) {
return MultiBlocProvider(
providers: [
BlocProvider<ItineraryStepNavigationBloc>(
create: (_) => ItineraryStepNavigationBloc(),
),
BlocProvider<AddItineraryDetailBloc>(
create: (_) => AddItineraryDetailBloc(),
),
],
child: const ItineraryCreationPage(),
);
},
);
case RouteConstants.yourItinerary:
return MaterialPageRoute(
builder: (_) {
return YourItineraryView();
},
);
case RouteConstants.magicItineraryFilledScreen:
return MaterialPageRoute(builder: (_){
return MagicItineraryFilledView();
});
case RouteConstants.checkout:
return MaterialPageRoute(
builder: (_) {
return CheckoutView();
},
);
case RouteConstants.buyPass:
return MaterialPageRoute(
builder: (_) {
return BuyPassView();
},
);
case RouteConstants.createAcct:
return MaterialPageRoute(
builder: (_) {
return CreateAccountView();
},
);
case RouteConstants.registeredUserHome:
return MaterialPageRoute(
builder: (_) {
return RegisteredUserHomePage();
},
);
default:
return MaterialPageRoute(
builder: (_) => const Scaffold(
body: Center(child: Text('Page not found')),
),
builder: (_) =>
const Scaffold(body: Center(child: Text('Page not found'))),
);
}
},

View File

@@ -1,7 +1,13 @@
class RouteConstants {
static const String intro = '/intro';
static const String splash = '/splash';
/****************************** HOME SECTION ************************************/
static const String home = '/home';
static const String registeredUserHome = '/registeredUserHome';
static const String attractionsPage = "/attractions";
static const String postCardPage = "/postcards";
static const String uploadPhotoPage = "/uploadPhoto";
@@ -49,4 +55,5 @@ class RouteConstants {
static const String qrPage = '/qrPage';
static const String makeBooking = '/makeBooking';
static const String bookingSuccessful = '/bookingSuccessful';
}

View File

@@ -17,7 +17,6 @@ class CreateAccountView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: SafeArea(
@@ -29,6 +28,7 @@ class CreateAccountView extends StatelessWidget {
isWhiteLogo: false,
isProfilePage: false,
showCart: false,
showDivider: true,
),
Row(
children: [
@@ -109,7 +109,7 @@ class CreateAccountView extends StatelessWidget {
),
),
SizedBox(height: 36.h),
SizedBox(height: 16.h),
CustomFilledButton(
width: double.infinity,
onTap: (){}, label: "Create Account")

View File

@@ -1,4 +1,5 @@
import 'package:citycards_customer/common_packages/app_bar.dart';
import 'package:citycards_customer/common_packages/back_widget.dart';
import 'package:citycards_customer/common_packages/custom_textfield.dart';
import 'package:flutter/material.dart';
import 'package:citycards_customer/common_packages/custom_text.dart';
@@ -24,30 +25,10 @@ class EditProfilePage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// Header
CommonAppBar(isWhiteLogo: false, isProfilePage: true),
SizedBox(height: 12.h),
Divider(height: 1.h, color: Color(0xFFD9D9D9)),
SizedBox(height: 22.h),
CommonAppBar(isWhiteLogo: false, isProfilePage: true,showDivider: true,),
// Back + title
Row(
children: [
GestureDetector(
onTap: () {
Navigator.pop(context);
},
child: Icon(Icons.arrow_back, size: 24.sp),
),
SizedBox(width: 8.w),
Text(
"Edit Profile",
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
),
),
],
),
backWidget(context,"Edit Profile", Colors.black),
SizedBox(height: 33.h),
// Profile Image

View File

@@ -18,7 +18,7 @@ class EsimOfferPage extends StatelessWidget {
Container(
color: Colors.white,
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
child: CommonAppBar(isWhiteLogo: false, isProfilePage: false),
child: CommonAppBar(isWhiteLogo: false, isProfilePage: false,showDivider: true,),
),
/************************* Top Banner ***********************/

View File

@@ -1,4 +1,5 @@
import 'package:citycards_customer/common_packages/app_bar.dart';
import 'package:citycards_customer/common_packages/back_widget.dart';
import 'package:citycards_customer/common_packages/custom_expansion_tile.dart';
import 'package:citycards_customer/common_packages/custom_text.dart';
import 'package:flutter/material.dart';
@@ -18,34 +19,8 @@ class FaqPage extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CommonAppBar(isWhiteLogo: false, isProfilePage: true),
SizedBox(
height: 12.h,
),
Divider(
height: 1.h,
color: Color(0xFFD9D9D9),
),
SizedBox(height: 22.h),
// Back + Title
Row(
children: [
GestureDetector(
onTap: (){
Navigator.pop(context);
},
child: Icon(Icons.arrow_back, size: 24.sp)),
SizedBox(width: 8.w),
Text(
"FAQ",
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
),
),
],
),
CommonAppBar(isWhiteLogo: false, isProfilePage: true, showDivider: true,),
backWidget(context,"FAQ", Colors.black),
SizedBox(height: 34.h),
FAQSection(title: "🧭 General FAQs", faqs: generalFAQs),

View File

@@ -0,0 +1,42 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:shared_preferences/shared_preferences.dart';
/// --- Events ---
abstract class AppStartEvent {}
class CheckFirstTimeUser extends AppStartEvent {}
class MarkUserAsRegistered extends AppStartEvent {}
/// --- States ---
abstract class AppStartState {}
class AppStartLoading extends AppStartState {}
class AppStartFirstTime extends AppStartState {}
class AppStartRegistered extends AppStartState {}
/// --- Bloc ---
class AppStartBloc extends Bloc<AppStartEvent, AppStartState> {
AppStartBloc() : super(AppStartLoading()) {
on<CheckFirstTimeUser>(_onCheckFirstTimeUser);
on<MarkUserAsRegistered>(_onMarkUserAsRegistered);
}
Future<void> _onCheckFirstTimeUser(
CheckFirstTimeUser event, Emitter<AppStartState> emit) async {
emit(AppStartLoading());
final prefs = await SharedPreferences.getInstance();
final isFirstTime = prefs.getBool('isFirstTimeUser') ?? true;
if (isFirstTime) {
emit(AppStartFirstTime());
} else {
emit(AppStartRegistered());
}
}
Future<void> _onMarkUserAsRegistered(
MarkUserAsRegistered event, Emitter<AppStartState> emit) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool('isFirstTimeUser', false);
emit(AppStartRegistered());
}
}

View File

@@ -0,0 +1,54 @@
import 'package:flutter_bloc/flutter_bloc.dart';
abstract class LoadCityEvent {}
class LoadAllCity extends LoadCityEvent {}
class SearchCity extends LoadCityEvent {
final String query;
SearchCity(this.query);
}
// ----- State -----
class CityState {
final List<Map<String, String>> offers;
const CityState(this.offers);
}
// ----- Bloc -----
class SearchCityBloc extends Bloc<LoadCityEvent, CityState> {
SearchCityBloc() : super(const CityState([])) {
on<LoadAllCity>(_onLoadCity);
on<SearchCity>(_onSearchCity);
}
final List<Map<String, String>> _allOffers = [
{"image": "assets/images/aa1.png", "title": "Sydney"},
{"image": "assets/images/aa2.png", "title": "New York"},
{"image": "assets/images/aa3.png", "title": "Abu Dhabi"},
{"image": "assets/images/aa4.png", "title": "Dubai"},
{
"image": "assets/images/card_banner.png",
"title": "Tokyo",
},
{"image": "assets/images/city_germany.jpg", "title": "Ontario"},
{"image": "assets/images/aa2.png", "title": "Mumbai"},
{"image": "assets/images/aa3.png", "title": "Louisiana"},
];
void _onLoadCity(event, emit) {
emit(CityState(_allOffers));
}
void _onSearchCity(event, emit) {
final filtered = _allOffers
.where(
(offer) =>
offer["title"]!.toLowerCase().contains(event.query.toLowerCase()),
)
.toList();
emit(CityState(filtered));
}
}

View File

@@ -0,0 +1,112 @@
class CityList {
List<Cities>? cities;
List<UpcomingCities>? upcomingCities;
CityList({this.cities, this.upcomingCities});
CityList.fromJson(Map<String, dynamic> json) {
if (json['cities'] != null) {
cities = <Cities>[];
json['cities'].forEach((v) {
cities!.add(new Cities.fromJson(v));
});
}
if (json['upcomingCities'] != null) {
upcomingCities = <UpcomingCities>[];
json['upcomingCities'].forEach((v) {
upcomingCities!.add(new UpcomingCities.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.cities != null) {
data['cities'] = this.cities!.map((v) => v.toJson()).toList();
}
if (this.upcomingCities != null) {
data['upcomingCities'] =
this.upcomingCities!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Cities {
int? id;
String? cityName;
String? tagLine;
String? bannerImage;
int? indivisualTicketAmt;
int? cityCardTicketAmt;
int? saveAmount;
String? saveLabel;
List<UpcomingCities>? upcomingCities;
Cities(
{this.id,
this.cityName,
this.tagLine,
this.bannerImage,
this.indivisualTicketAmt,
this.cityCardTicketAmt,
this.saveAmount,
this.saveLabel,
this.upcomingCities});
Cities.fromJson(Map<String, dynamic> json) {
id = json['id'];
cityName = json['cityName'];
tagLine = json['tagLine'];
bannerImage = json['bannerImage'];
indivisualTicketAmt = json['indivisualTicketAmt'];
cityCardTicketAmt = json['cityCardTicketAmt'];
saveAmount = json['saveAmount'];
saveLabel = json['saveLabel'];
if (json['upcomingCities'] != null) {
upcomingCities = <UpcomingCities>[];
json['upcomingCities'].forEach((v) {
upcomingCities!.add(new UpcomingCities.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['cityName'] = this.cityName;
data['tagLine'] = this.tagLine;
data['bannerImage'] = this.bannerImage;
data['indivisualTicketAmt'] = this.indivisualTicketAmt;
data['cityCardTicketAmt'] = this.cityCardTicketAmt;
data['saveAmount'] = this.saveAmount;
data['saveLabel'] = this.saveLabel;
if (this.upcomingCities != null) {
data['upcomingCities'] =
this.upcomingCities!.map((v) => v.toJson()).toList();
}
return data;
}
}
class UpcomingCities {
int? id;
String? cityName;
String? imgPathName;
UpcomingCities({this.id, this.cityName, this.imgPathName});
UpcomingCities.fromJson(Map<String, dynamic> json) {
id = json['id'];
cityName = json['cityName'];
imgPathName = json['imgPathName'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['cityName'] = this.cityName;
data['imgPathName'] = this.imgPathName;
return data;
}
}

View File

@@ -5,7 +5,8 @@ import '../../common_packages/app_bar.dart';
import '../widgets/explore_cities_card.dart';
class FirstTimeUserHomePage extends StatefulWidget {
const FirstTimeUserHomePage({super.key});
final VoidCallback onContinue;
const FirstTimeUserHomePage({super.key, required this.onContinue});
@override
State<FirstTimeUserHomePage> createState() => _FirstTimeUserHomePageState();
@@ -92,7 +93,7 @@ class _FirstTimeUserHomePageState extends State<FirstTimeUserHomePage> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CommonAppBar(isWhiteLogo: true, isProfilePage: false),
CommonAppBar(isWhiteLogo: true, isProfilePage: false, showDivider: false),
SizedBox(height: 140.h),
Text(
"CityCards.\nSee More,\nSpend Less.",
@@ -120,7 +121,7 @@ class _FirstTimeUserHomePageState extends State<FirstTimeUserHomePage> {
borderRadius: BorderRadius.circular(25.r),
),
),
onPressed: () {},
onPressed: widget.onContinue,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [

View File

@@ -1,13 +1,14 @@
import 'package:citycards_customer/home/views/registered_user_home_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:citycards_customer/common_packages/custom_bottom_navbar.dart';
import 'package:citycards_customer/core/inside_bottom_navigator.dart';
import 'package:citycards_customer/itinerary_creation/views/itinerary_creation_start_view.dart';
import 'package:citycards_customer/my_pass/views/my_pass_page_view.dart';
import 'package:citycards_customer/postcard/views/postcard_initial_page_view.dart';
import '../../common_bloc/bottom_navigation_bloc.dart';
import '../../common_packages/custom_bottom_navbar.dart';
import '../../core/inside_bottom_navigator.dart';
import '../../itinerary_creation/views/itinerary_creation_start_view.dart';
import '../../my_pass/views/my_pass_page_view.dart';
import '../../postcard/views/postcard_initial_page_view.dart';
import '../bloc/app_start_bloc.dart';
import 'first_time_user_home_page.dart';
import 'registered_user_home_page.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@@ -18,33 +19,59 @@ class HomePage extends StatefulWidget {
class _HomePageState extends State<HomePage> {
final _navigatorKeys = [
GlobalKey<NavigatorState>(), // tab 0
GlobalKey<NavigatorState>(), // tab 1
GlobalKey<NavigatorState>(), // tab 2
GlobalKey<NavigatorState>(), // tab 2
GlobalKey<NavigatorState>(),
GlobalKey<NavigatorState>(),
GlobalKey<NavigatorState>(),
GlobalKey<NavigatorState>(),
];
@override
Widget build(BuildContext context) {
return BlocBuilder<NavigationBloc, NavigationState>(
builder: (context, state) {
final currentIndex = state.selectedIndex;
return BlocProvider(
create: (_) => AppStartBloc()..add(CheckFirstTimeUser()),
child: BlocBuilder<AppStartBloc, AppStartState>(
builder: (context, state) {
if (state is AppStartLoading) {
return const Scaffold(
body: Center(child: CircularProgressIndicator()),
);
}
return SafeArea(
top: false,
child: Scaffold(
body: Stack(
children: [
buildOffstageNavigator(0, currentIndex, const FirstTimeUserHomePage(), _navigatorKeys[0]),
buildOffstageNavigator(1, currentIndex, const ItineraryCreationStartPage(), _navigatorKeys[1]),
buildOffstageNavigator(2, currentIndex, const MyPassesView(), _navigatorKeys[2]),
buildOffstageNavigator(3, currentIndex, const PostcardPage(), _navigatorKeys[3]),
],
),
bottomNavigationBar: CustomBottomNavBar(),
),
);
},
if (state is AppStartFirstTime) {
return FirstTimeUserHomePage(
onContinue: () {
context.read<AppStartBloc>().add(MarkUserAsRegistered());
},
);
}
// Once registered → show normal main home tabs
return BlocBuilder<NavigationBloc, NavigationState>(
builder: (context, navState) {
final currentIndex = navState.selectedIndex;
return SafeArea(
top: false,
child: Scaffold(
body: Stack(
children: [
buildOffstageNavigator(0, currentIndex,
const RegisteredUserHomePage(), _navigatorKeys[0]),
buildOffstageNavigator(1, currentIndex,
const ItineraryCreationStartPage(), _navigatorKeys[1]),
buildOffstageNavigator(2, currentIndex,
const MyPassesView(), _navigatorKeys[2]),
buildOffstageNavigator(3, currentIndex,
const PostcardPage(), _navigatorKeys[3]),
],
),
bottomNavigationBar: const CustomBottomNavBar(),
),
);
},
);
},
),
);
}
}

Some files were not shown because too many files have changed in this diff Show More