Updated itinerary creation view
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
|
||||
|
||||
|
||||
<application
|
||||
android:label="citycards_customer"
|
||||
|
||||
BIN
assets/gif/create_itinerary.gif
Normal file
BIN
assets/gif/create_itinerary.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
BIN
assets/icons/calender_filled.png
Normal file
BIN
assets/icons/calender_filled.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 623 B |
BIN
assets/images/itinerary_banner.png
Normal file
BIN
assets/images/itinerary_banner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 92 KiB |
BIN
assets/images/itinerary_card.png
Normal file
BIN
assets/images/itinerary_card.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 744 KiB |
BIN
assets/images/trump_house.png
Normal file
BIN
assets/images/trump_house.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.3 MiB |
@@ -36,7 +36,7 @@ class _MyCartPageState extends State<MyCartPage> {
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
CommonAppBar(isWhiteLogo: false, isProfilePage: false, showCart: false,),
|
||||
backWidget(context, "Your Cart"),
|
||||
backWidget(context, "Your Cart", Colors.black),
|
||||
SizedBox(
|
||||
height: 24.h,
|
||||
),
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
Widget backWidget(BuildContext context, String title){
|
||||
Widget backWidget(BuildContext context, String title, Color? textColor){
|
||||
return Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Icon(Icons.arrow_back, size: 24.sp),
|
||||
child: Icon(Icons.arrow_back, size: 24.sp, color: textColor ?? Colors.black),
|
||||
),
|
||||
SizedBox(width: 8.w),
|
||||
Text(
|
||||
@@ -16,6 +16,7 @@ Widget backWidget(BuildContext context, String title){
|
||||
style: TextStyle(
|
||||
fontSize: 12.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: textColor ?? Colors.black
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
28
lib/common_packages/custom_bullet_points.dart
Normal file
28
lib/common_packages/custom_bullet_points.dart
Normal file
@@ -0,0 +1,28 @@
|
||||
import 'package:citycards_customer/common_packages/custom_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class CustomBulletPoints extends StatelessWidget {
|
||||
final Color textColor;
|
||||
final String text;
|
||||
|
||||
const CustomBulletPoints({
|
||||
super.key,
|
||||
required this.textColor,
|
||||
required this.text,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
CustomText(text: "•", size: 14.sp, color: textColor),
|
||||
SizedBox(width: 8.w),
|
||||
Expanded(
|
||||
child: CustomText(text: text, color: textColor, size: 14.sp),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -14,10 +14,13 @@ import 'package:citycards_customer/itinerary_creation/bloc/itinerary_detail_bloc
|
||||
import 'package:citycards_customer/itinerary_creation/bloc/itinerary_steps_selection_bloc.dart';
|
||||
import 'package:citycards_customer/itinerary_creation/views/itinerary_creation_start_view.dart';
|
||||
import 'package:citycards_customer/itinerary_creation/views/itinerary_creation_view.dart';
|
||||
import 'package:citycards_customer/itinerary_creation/views/magic_itinerary_empty_view.dart';
|
||||
import 'package:citycards_customer/itinerary_creation/views/magic_itinerary_filled_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/terms_and_condition/terms_and_condition_view.dart';
|
||||
import 'package:citycards_customer/your_itinerary/view/your_itinerary_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import '../attractions/views/attractions_page_view.dart';
|
||||
@@ -121,46 +124,77 @@ class AppRouter {
|
||||
);
|
||||
|
||||
case RouteConstants.attractionDetails:
|
||||
return MaterialPageRoute(builder: (_) {
|
||||
return AttractionDetailsView();
|
||||
});
|
||||
return MaterialPageRoute(
|
||||
builder: (_) {
|
||||
return AttractionDetailsView();
|
||||
},
|
||||
);
|
||||
|
||||
case RouteConstants.buyPass:
|
||||
return MaterialPageRoute(builder: (_) {
|
||||
return BuyPassView();
|
||||
});
|
||||
return MaterialPageRoute(
|
||||
builder: (_) {
|
||||
return BuyPassView();
|
||||
},
|
||||
);
|
||||
|
||||
case RouteConstants.checkout:
|
||||
return MaterialPageRoute(builder: (_){
|
||||
return CheckoutView();
|
||||
});
|
||||
return MaterialPageRoute(
|
||||
builder: (_) {
|
||||
return CheckoutView();
|
||||
},
|
||||
);
|
||||
|
||||
case RouteConstants.cartPage:
|
||||
return MaterialPageRoute(builder: (_){
|
||||
return MyCartPage();
|
||||
});
|
||||
return MaterialPageRoute(
|
||||
builder: (_) {
|
||||
return MyCartPage();
|
||||
},
|
||||
);
|
||||
|
||||
case RouteConstants.searchOffer:
|
||||
return MaterialPageRoute(builder: (_){
|
||||
return BlocProvider(
|
||||
return MaterialPageRoute(
|
||||
builder: (_) {
|
||||
return BlocProvider(
|
||||
create: (_) => OffersBloc(),
|
||||
child: SearchOffersWithListing(),
|
||||
);
|
||||
});
|
||||
child: SearchOffersWithListing(),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
case RouteConstants.addDetails:
|
||||
return MaterialPageRoute(builder: (_){
|
||||
return AddDetailsView();
|
||||
});
|
||||
return MaterialPageRoute(
|
||||
builder: (_) {
|
||||
return AddDetailsView();
|
||||
},
|
||||
);
|
||||
|
||||
case RouteConstants.createAcct:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) {
|
||||
return CreateAccountView();
|
||||
},
|
||||
);
|
||||
|
||||
case RouteConstants.yourItinerary:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) {
|
||||
return YourItineraryView();
|
||||
},
|
||||
);
|
||||
|
||||
case RouteConstants.magicItineraryEmptyScreen:
|
||||
return MaterialPageRoute(builder: (_){
|
||||
return CreateAccountView();
|
||||
return MagicItineraryEmptyView();
|
||||
});
|
||||
|
||||
case RouteConstants.magicItineraryFilledScreen:
|
||||
return MaterialPageRoute(builder: (_){
|
||||
return MagicItineraryFilledView();
|
||||
});
|
||||
default:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) =>
|
||||
const Scaffold(body: Center(child: Text('404 - Page Not Found'))),
|
||||
const Scaffold(body: Center(child: Text('404 - Page Not Found'))),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,10 @@ class RouteConstants {
|
||||
|
||||
/****************************** ITINERARY CREATION ************************************/
|
||||
|
||||
static const String magicItineraryEmptyScreen = '/magicItineraryEmptyScreen';
|
||||
static const String itineraryCreationStart = '/itineraryCreationStart';
|
||||
static const String itineraryCreation = '/itineraryCreation';
|
||||
static const String magicItineraryFilledScreen = "/magicItineraryFilledScreen";
|
||||
|
||||
/**************************** ESIM Page *****************************************/
|
||||
|
||||
@@ -41,5 +43,6 @@ class RouteConstants {
|
||||
|
||||
/************************** My card page ***************************************/
|
||||
static const String cartPage = '/cartPage';
|
||||
static const String yourItinerary = '/yourItinerary';
|
||||
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ class ItineraryDetailState {
|
||||
final String? selectedCity;
|
||||
final String? selectedEnergy;
|
||||
final String? withKid;
|
||||
final List<String>? selectedDietary;
|
||||
final String? selectedDietary;
|
||||
final String? museumRating;
|
||||
final String? scenicRating;
|
||||
final String? culturalRating;
|
||||
@@ -93,7 +93,7 @@ class ItineraryDetailState {
|
||||
String? selectedCity,
|
||||
String? selectedEnergy,
|
||||
String? withKid,
|
||||
List<String>? selectedDietary,
|
||||
String? selectedDietary,
|
||||
String? museumRating,
|
||||
String? scenicRating,
|
||||
String? culturalRating,
|
||||
@@ -124,7 +124,7 @@ class AddItineraryDetailBloc
|
||||
selectedCity: "Paris",
|
||||
selectedEnergy: "",
|
||||
withKid: "",
|
||||
selectedDietary: const [],
|
||||
selectedDietary: "",
|
||||
museumRating: "",
|
||||
scenicRating: "",
|
||||
culturalRating: "",
|
||||
@@ -150,14 +150,14 @@ class AddItineraryDetailBloc
|
||||
});
|
||||
|
||||
on<AddDietaryToItinerary>((event, emit) {
|
||||
final currentSelection = List<String>.from(state.selectedDietary ?? []);
|
||||
|
||||
if (currentSelection.contains(event.dietary)) {
|
||||
currentSelection.remove(event.dietary);
|
||||
} else {
|
||||
currentSelection.add(event.dietary);
|
||||
}
|
||||
emit(state.copyWith(selectedDietary: currentSelection));
|
||||
// final currentSelection = List<String>.from(state.selectedDietary ?? []);
|
||||
//
|
||||
// if (currentSelection.contains(event.dietary)) {
|
||||
// currentSelection.remove(event.dietary);
|
||||
// } else {
|
||||
// currentSelection.add(event.dietary);
|
||||
// }
|
||||
emit(state.copyWith(selectedDietary: event.dietary));
|
||||
});
|
||||
|
||||
on<AddMuseumRating>((event, emit) {
|
||||
|
||||
@@ -22,7 +22,7 @@ class ItineraryStepNavigationBloc
|
||||
|
||||
on<ItineraryStepNavigationNextEvent>((event, emit) {
|
||||
final nextIndex = state.selectedIndex + 1;
|
||||
if (nextIndex <= 10) {
|
||||
if (nextIndex <= 11) {
|
||||
emit(ItineraryStepNavigationState(nextIndex));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -16,27 +16,10 @@ class ItineraryCreationStartPage extends StatelessWidget {
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
height: 103.h,
|
||||
width: 103.w,
|
||||
|
||||
Image.asset("assets/gif/create_itinerary.gif",width: 128.w),
|
||||
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(24.r),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black12,
|
||||
offset: Offset(0, 4),
|
||||
blurRadius: 5,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Center(
|
||||
child: Image.asset("assets/icons/magic_creation.png", scale: 4),
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 34.h),
|
||||
SizedBox(height: 21.h),
|
||||
Text.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
|
||||
@@ -64,18 +64,10 @@ class HistoricalSiteRatingView extends StatelessWidget {
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||
height: 82.h,
|
||||
height: 83.h,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16.r),
|
||||
border: Border.all(color: Color(0xFFE5E7EB), width: 1.1),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black12,
|
||||
offset: Offset(1, 2),
|
||||
blurRadius: 1,
|
||||
),
|
||||
],
|
||||
borderRadius: BorderRadius.circular(28.r),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Row(
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
import 'package:citycards_customer/common_packages/custom_filled_button.dart';
|
||||
import 'package:citycards_customer/common_packages/custom_text.dart';
|
||||
import 'package:citycards_customer/itinerary_creation/bloc/itinerary_steps_selection_bloc.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
|
||||
class CurrentLocationSelection extends StatefulWidget {
|
||||
const CurrentLocationSelection({super.key});
|
||||
|
||||
@override
|
||||
State<CurrentLocationSelection> createState() =>
|
||||
_CurrentLocationSelectionState();
|
||||
}
|
||||
|
||||
class _CurrentLocationSelectionState extends State<CurrentLocationSelection> {
|
||||
final TextEditingController _controller = TextEditingController();
|
||||
LatLng? _currentLatLng;
|
||||
|
||||
Future<void> _getCurrentLocation() async {
|
||||
LocationPermission permission = await Geolocator.requestPermission();
|
||||
if (permission == LocationPermission.denied ||
|
||||
permission == LocationPermission.deniedForever) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text('Location permission denied')),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final position = await Geolocator.getCurrentPosition(
|
||||
desiredAccuracy: LocationAccuracy.high,
|
||||
);
|
||||
|
||||
setState(() {
|
||||
_currentLatLng = LatLng(position.latitude, position.longitude);
|
||||
_controller.text =
|
||||
"Lat: ${position.latitude.toStringAsFixed(5)}, Lng: ${position.longitude.toStringAsFixed(5)}";
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: const Color(0xFFFFF3F3),
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.w),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(height: 60.h),
|
||||
Text(
|
||||
"👋 Hello! We'd love to know more about you. Where are you visiting from",
|
||||
style: TextStyle(
|
||||
color: const Color(0xFF101828),
|
||||
fontSize: 20.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 32.h),
|
||||
|
||||
SizedBox(
|
||||
height: 56.h,
|
||||
child: TextField(
|
||||
controller: _controller,
|
||||
readOnly: true,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search for Area, street name",
|
||||
prefixIcon: Image.asset(
|
||||
"assets/icons/location.png",
|
||||
scale: 4,
|
||||
),
|
||||
hintStyle: TextStyle(
|
||||
color: Color(0xFF737373),
|
||||
fontSize: 14.sp,
|
||||
),
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(28.r),
|
||||
borderSide: BorderSide(color: Color(0xFFF95F62)),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(28.r),
|
||||
borderSide: BorderSide(color: Color(0xFFF95F62)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 16.h),
|
||||
(_currentLatLng != null)
|
||||
? ClipRRect(
|
||||
borderRadius: BorderRadius.circular(16.r),
|
||||
child: SizedBox(
|
||||
height: 250.h,
|
||||
width: double.infinity,
|
||||
|
||||
child: Image.asset(
|
||||
"assets/images/attra_detail_map.png",
|
||||
fit: BoxFit.cover,
|
||||
height: 236.h,
|
||||
),
|
||||
// child: GoogleMap(
|
||||
// initialCameraPosition: CameraPosition(
|
||||
// target: _currentLatLng!,
|
||||
// zoom: 15,
|
||||
// ),
|
||||
// markers: {
|
||||
// Marker(
|
||||
// markerId: const MarkerId("currentLocation"),
|
||||
// position: _currentLatLng!,
|
||||
// ),
|
||||
// },
|
||||
// myLocationEnabled: true,
|
||||
// myLocationButtonEnabled: false,
|
||||
// ),
|
||||
),
|
||||
)
|
||||
: GestureDetector(
|
||||
onTap: () {
|
||||
_getCurrentLocation();
|
||||
},
|
||||
child: Container(
|
||||
height: 46.h,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12.w),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFF95F62).withOpacity(0.4),
|
||||
borderRadius: BorderRadius.circular(28.r),
|
||||
border: Border.all(color: Color(0xFFF95F62)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.my_location,
|
||||
color: Color(0xFFFF7B7B),
|
||||
),
|
||||
SizedBox(width: 12.w),
|
||||
CustomText(
|
||||
text: "Use current location",
|
||||
size: 14.sp,
|
||||
color: Color(0xFFF95F62),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
const Spacer(),
|
||||
|
||||
// --- Continue button ---
|
||||
CustomFilledButton(
|
||||
onTap: () {
|
||||
context.read<ItineraryStepNavigationBloc>().add(
|
||||
ItineraryStepNavigationNextEvent(),
|
||||
);
|
||||
},
|
||||
label: "Continue",
|
||||
showArrow: true,
|
||||
),
|
||||
SizedBox(height: 20.h),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -51,62 +51,56 @@ class _DietarySelectionViewState extends State<DietarySelectionView> {
|
||||
SizedBox(height: 38.h),
|
||||
SizedBox(
|
||||
height: 350.h,
|
||||
child:
|
||||
BlocBuilder<
|
||||
AddItineraryDetailBloc,
|
||||
ItineraryDetailState
|
||||
>(
|
||||
builder: (context, sate) {
|
||||
return GridView.builder(
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
mainAxisSpacing: 12,
|
||||
crossAxisSpacing: 16,
|
||||
crossAxisCount: 2,
|
||||
childAspectRatio: 1.7,
|
||||
),
|
||||
itemCount: options.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final item = options[index];
|
||||
final isSelected = (sate.selectedDietary ?? []).contains(
|
||||
item['name'],
|
||||
);
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
context.read<AddItineraryDetailBloc>().add(
|
||||
AddDietaryToItinerary(item['name'] ?? ""),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
width: 168.w,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
border: isSelected
|
||||
? Border.all(color: Color(0xFFF95F62))
|
||||
: Border.all(color: Colors.transparent),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(item["icon"] ?? "", scale: 4),
|
||||
SizedBox(height: 8),
|
||||
CustomText(
|
||||
text: item["name"] ?? "",
|
||||
size: 16.sp,
|
||||
weight: FontWeight.w500,
|
||||
color: const Color(0xFF364153),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: BlocBuilder<AddItineraryDetailBloc, ItineraryDetailState>(
|
||||
builder: (context, sate) {
|
||||
return GridView.builder(
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
mainAxisSpacing: 12,
|
||||
crossAxisSpacing: 16,
|
||||
crossAxisCount: 2,
|
||||
childAspectRatio: 1.7,
|
||||
),
|
||||
itemCount: options.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
final item = options[index];
|
||||
final isSelected = sate.selectedDietary == item['name'];
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
context.read<AddItineraryDetailBloc>().add(
|
||||
AddDietaryToItinerary(item['name'] ?? ""),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
width: 168.w,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
border: isSelected
|
||||
? Border.all(color: Color(0xFFF95F62))
|
||||
: Border.all(color: Colors.transparent),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(item["icon"] ?? "", scale: 4),
|
||||
SizedBox(height: 8),
|
||||
CustomText(
|
||||
text: item["name"] ?? "",
|
||||
size: 16.sp,
|
||||
weight: FontWeight.w500,
|
||||
color: const Color(0xFF364153),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 41.h),
|
||||
|
||||
@@ -79,7 +79,7 @@ class ItineraryCompletionView extends StatelessWidget {
|
||||
),
|
||||
_buildProfileRow(
|
||||
"Dietary",
|
||||
(state.selectedDietary ?? []).join(', '),
|
||||
state.selectedDietary ?? "",
|
||||
),
|
||||
_buildProfileRow(
|
||||
"Museums",
|
||||
|
||||
@@ -65,18 +65,10 @@ class ShoppingRatingView extends StatelessWidget {
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||
height: 82.h,
|
||||
height: 83.h,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16.r),
|
||||
border: Border.all(color: Color(0xFFE5E7EB), width: 1.1),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black12,
|
||||
offset: Offset(1, 2),
|
||||
blurRadius: 1,
|
||||
),
|
||||
],
|
||||
borderRadius: BorderRadius.circular(28.r),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Row(
|
||||
|
||||
@@ -50,21 +50,10 @@ class WildlifeRatingView extends StatelessWidget {
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||
height: 82.h,
|
||||
height: 83.h,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(16.r),
|
||||
border: Border.all(
|
||||
color: Color(0xFFE5E7EB),
|
||||
width: 1.1
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black12,
|
||||
offset: Offset(1,2),
|
||||
blurRadius: 1,
|
||||
)
|
||||
]
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(28.r),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Row(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
import 'package:citycards_customer/itinerary_creation/bloc/itinerary_steps_selection_bloc.dart';
|
||||
import 'package:citycards_customer/itinerary_creation/views/itinerary_creation_steps/current_location_selection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
@@ -48,7 +49,7 @@ class _ItineraryCreationPageState extends State<ItineraryCreationPage> {
|
||||
>(
|
||||
builder: (context, state) {
|
||||
return Text(
|
||||
"${state.selectedIndex} / 10",
|
||||
"${state.selectedIndex} / 11",
|
||||
style: TextStyle(color: Color(0xFF4A5565), fontSize: 14.sp),
|
||||
);
|
||||
},
|
||||
@@ -84,7 +85,7 @@ class _ItineraryCreationPageState extends State<ItineraryCreationPage> {
|
||||
>(
|
||||
builder: (context, state) {
|
||||
return LinearProgressIndicator(
|
||||
value: state.selectedIndex / 10,
|
||||
value: state.selectedIndex / 11,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
backgroundColor: Colors.white,
|
||||
color: const Color(0xFFF95F62),
|
||||
@@ -103,7 +104,7 @@ class _ItineraryCreationPageState extends State<ItineraryCreationPage> {
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
children: [
|
||||
DateSelectionView(),
|
||||
|
||||
CurrentLocationSelection(),
|
||||
CitySelectionView(),
|
||||
EnergySelectionView(),
|
||||
KidsSelectionView(),
|
||||
|
||||
48
lib/itinerary_creation/views/magic_itinerary_empty_view.dart
Normal file
48
lib/itinerary_creation/views/magic_itinerary_empty_view.dart
Normal file
@@ -0,0 +1,48 @@
|
||||
import 'package:citycards_customer/common_packages/app_bar.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';
|
||||
|
||||
class MagicItineraryEmptyView extends StatelessWidget {
|
||||
const MagicItineraryEmptyView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Color(0xFFFFF5F5),
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 10.h),
|
||||
child: Column(
|
||||
children: [
|
||||
CommonAppBar(isWhiteLogo: false, isProfilePage: false),
|
||||
SizedBox(height: 90.h),
|
||||
Image.asset("assets/images/itinerary_banner.png", width: 260.w),
|
||||
SizedBox(height: 27.h),
|
||||
CustomText(
|
||||
text: "You Don’t have an Itinerary Yet! ☹️",
|
||||
size: 18.sp,
|
||||
),
|
||||
SizedBox(height: 12.h,),
|
||||
Text("Create your own personalized magic itinerary that suites your travel needs",
|
||||
style: TextStyle(
|
||||
color: Color(0xFF656565),
|
||||
fontSize: 14.sp
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(height: 27.h),
|
||||
|
||||
CustomFilledButton(onTap: (){
|
||||
Navigator.pushNamed(context, RouteConstants.itineraryCreationStart);
|
||||
},
|
||||
label: "Create My Itinerary", showArrow: true,)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
169
lib/itinerary_creation/views/magic_itinerary_filled_view.dart
Normal file
169
lib/itinerary_creation/views/magic_itinerary_filled_view.dart
Normal file
@@ -0,0 +1,169 @@
|
||||
import 'package:citycards_customer/common_packages/app_bar.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:citycards_customer/postcard/widgets/dotted_border_container.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class MagicItineraryFilledView extends StatelessWidget {
|
||||
const MagicItineraryFilledView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Color(0xFFFFF5F5),
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 10.h),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
CommonAppBar(isWhiteLogo: false, isProfilePage: false),
|
||||
|
||||
SizedBox(height: 24.h),
|
||||
ItineraryFilledCard(),
|
||||
|
||||
SizedBox(height: 32.h),
|
||||
|
||||
CustomPaint(
|
||||
painter: DottedBorderPainter(),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.symmetric(vertical: 24.h),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFF95F62).withOpacity(0.25),
|
||||
borderRadius: BorderRadius.circular(12.sp),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
CustomText(
|
||||
text: "Plan your next adventure",
|
||||
color: Color(0xFF656565),
|
||||
size: 14.sp,
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
CustomFilledButton(
|
||||
onTap: () {
|
||||
Navigator.pushNamed(context, RouteConstants.itineraryCreationStart);
|
||||
},
|
||||
label: "Create My Itinerary",
|
||||
showArrow: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ItineraryFilledCard extends StatelessWidget {
|
||||
const ItineraryFilledCard({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 8.h),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.black.withOpacity(0.12)),
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
CustomText(
|
||||
text: "Melbourne Unlimited Card",
|
||||
size: 16.sp,
|
||||
weight: FontWeight.w500,
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 2.h),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF439F6E),
|
||||
borderRadius: BorderRadius.circular(100.r),
|
||||
),
|
||||
child: CustomText(
|
||||
text: "Active",
|
||||
size: 11.sp,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 4.h),
|
||||
|
||||
CustomText(
|
||||
text: "Melbourne",
|
||||
size: 12.sp,
|
||||
color: Colors.black.withOpacity(0.4),
|
||||
),
|
||||
SizedBox(height: 12.h),
|
||||
Row(
|
||||
children: [
|
||||
Image.asset("assets/icons/calender_filled.png", width: 16.sp),
|
||||
SizedBox(width: 4.w),
|
||||
CustomText(text: "7 days", color: Color(0xFF8E8E8E), size: 12.sp),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 8.h),
|
||||
Row(
|
||||
children: [
|
||||
Icon(
|
||||
Icons.location_on_rounded,
|
||||
color: Color(0xFF8E8E8E),
|
||||
size: 16.sp,
|
||||
),
|
||||
SizedBox(width: 4.w),
|
||||
CustomText(
|
||||
text: "6 attractions",
|
||||
color: Color(0xFF8E8E8E),
|
||||
size: 12.sp,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 8.h),
|
||||
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.watch_later, color: Color(0xFF8E8E8E), size: 16.sp),
|
||||
SizedBox(width: 4.w),
|
||||
CustomText(
|
||||
text: "Created 1/15/2024",
|
||||
color: Color(0xFF8E8E8E),
|
||||
size: 12.sp,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
SizedBox(height: 12.h),
|
||||
|
||||
Container(
|
||||
height: 43.h,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
border: Border.all(color: Color(0xFFF95F62)),
|
||||
),
|
||||
child: Center(
|
||||
child: CustomText(
|
||||
text: "View Itinerary",
|
||||
size: 16.sp,
|
||||
color: Color(0xFFF95F62),
|
||||
weight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ class MyApp extends StatelessWidget {
|
||||
builder: (context, child) {
|
||||
return MaterialApp(
|
||||
onGenerateRoute: _appRouter.onGenerateRoute,
|
||||
initialRoute: RouteConstants.buyPass,
|
||||
initialRoute: RouteConstants.magicItineraryFilledScreen,
|
||||
debugShowCheckedModeBanner: false,
|
||||
title: 'City Cards',
|
||||
theme: ThemeData(
|
||||
|
||||
@@ -12,9 +12,7 @@ class DottedBorderContainer extends StatelessWidget {
|
||||
height: 300.h,
|
||||
width: double.infinity,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
decoration: BoxDecoration(borderRadius: BorderRadius.circular(16)),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
@@ -24,7 +22,11 @@ class DottedBorderContainer extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.add_circle_outline, color: Color(0xffF95F62), size: 25,),
|
||||
Icon(
|
||||
Icons.add_circle_outline,
|
||||
color: Color(0xffF95F62),
|
||||
size: 25,
|
||||
),
|
||||
const Text(
|
||||
"Add image",
|
||||
style: TextStyle(
|
||||
@@ -52,18 +54,18 @@ class DottedBorderPainter extends CustomPainter {
|
||||
const double dashWidth = 6;
|
||||
const double dashSpace = 3;
|
||||
final path = Path()
|
||||
..addRRect(RRect.fromRectAndRadius(
|
||||
..addRRect(
|
||||
RRect.fromRectAndRadius(
|
||||
Rect.fromLTWH(0, 0, size.width, size.height),
|
||||
const Radius.circular(16)));
|
||||
const Radius.circular(16),
|
||||
),
|
||||
);
|
||||
|
||||
final pathMetrics = path.computeMetrics();
|
||||
for (final metric in pathMetrics) {
|
||||
double distance = 0.0;
|
||||
while (distance < metric.length) {
|
||||
final segment = metric.extractPath(
|
||||
distance,
|
||||
distance + dashWidth,
|
||||
);
|
||||
final segment = metric.extractPath(distance, distance + dashWidth);
|
||||
canvas.drawPath(segment, paint);
|
||||
distance += dashWidth + dashSpace;
|
||||
}
|
||||
|
||||
24
lib/your_itinerary/bloc/itinerary_days_tabs_bloc.dart
Normal file
24
lib/your_itinerary/bloc/itinerary_days_tabs_bloc.dart
Normal file
@@ -0,0 +1,24 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
abstract class YourItineraryDayTab {}
|
||||
|
||||
class ChangeItineraryDayTabEvent extends YourItineraryDayTab {
|
||||
final int? tabIndex;
|
||||
|
||||
ChangeItineraryDayTabEvent(this.tabIndex);
|
||||
}
|
||||
|
||||
class ItineraryDayTabState {
|
||||
final int? tabIndex;
|
||||
|
||||
ItineraryDayTabState(this.tabIndex);
|
||||
}
|
||||
|
||||
class ItineraryChangeDayTabBloc
|
||||
extends Bloc<ChangeItineraryDayTabEvent, ItineraryDayTabState> {
|
||||
ItineraryChangeDayTabBloc() : super(ItineraryDayTabState(0)) {
|
||||
on<ChangeItineraryDayTabEvent>((event, emit) {
|
||||
emit(ItineraryDayTabState(event.tabIndex));
|
||||
});
|
||||
}
|
||||
}
|
||||
24
lib/your_itinerary/bloc/your_itinerary_tab_bloc.dart
Normal file
24
lib/your_itinerary/bloc/your_itinerary_tab_bloc.dart
Normal file
@@ -0,0 +1,24 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
abstract class YourItineraryTab {}
|
||||
|
||||
class ChangeItineraryTabEvent extends YourItineraryTab {
|
||||
final int? tabIndex;
|
||||
|
||||
ChangeItineraryTabEvent(this.tabIndex);
|
||||
}
|
||||
|
||||
class ItineraryTabState {
|
||||
final int? tabIndex;
|
||||
|
||||
ItineraryTabState(this.tabIndex);
|
||||
}
|
||||
|
||||
class ItineraryChangeTabBloc
|
||||
extends Bloc<ChangeItineraryTabEvent, ItineraryTabState> {
|
||||
ItineraryChangeTabBloc() : super(ItineraryTabState(0)) {
|
||||
on<ChangeItineraryTabEvent>((event, emit) {
|
||||
emit(ItineraryTabState(event.tabIndex));
|
||||
});
|
||||
}
|
||||
}
|
||||
371
lib/your_itinerary/view/your_itinerary_view.dart
Normal file
371
lib/your_itinerary/view/your_itinerary_view.dart
Normal file
@@ -0,0 +1,371 @@
|
||||
import 'package:citycards_customer/common_packages/app_bar.dart';
|
||||
import 'package:citycards_customer/common_packages/custom_text.dart';
|
||||
import 'package:citycards_customer/your_itinerary/bloc/itinerary_days_tabs_bloc.dart';
|
||||
import 'package:citycards_customer/your_itinerary/bloc/your_itinerary_tab_bloc.dart';
|
||||
import 'package:citycards_customer/your_itinerary/widgets/itinerary_card_widget.dart';
|
||||
import 'package:citycards_customer/your_itinerary/widgets/itinerary_tab_button.dart';
|
||||
import 'package:citycards_customer/your_itinerary/widgets/summary_card_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class YourItineraryView extends StatelessWidget {
|
||||
const YourItineraryView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MultiBlocProvider(
|
||||
providers: [
|
||||
BlocProvider(create: (_) => ItineraryChangeTabBloc()),
|
||||
BlocProvider(create: (_) => ItineraryChangeDayTabBloc()),
|
||||
],
|
||||
child: Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
body: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Stack(
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/images/trump_house.png",
|
||||
height: 155.h,
|
||||
width: double.infinity,
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.topCenter,
|
||||
),
|
||||
Positioned.fill(
|
||||
child: Container(color: Colors.black.withOpacity(0.3)),
|
||||
),
|
||||
Positioned(
|
||||
top: 20.h,
|
||||
left: 20.w,
|
||||
right: 20.w,
|
||||
child: Column(
|
||||
children: [
|
||||
CommonAppBar(isWhiteLogo: true, isProfilePage: false),
|
||||
SizedBox(height: 5.h),
|
||||
Divider(
|
||||
height: 0.4.h,
|
||||
color: Colors.white.withOpacity(.3),
|
||||
),
|
||||
SizedBox(height: 26.h),
|
||||
Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
child: Icon(
|
||||
Icons.arrow_back,
|
||||
size: 24.sp,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8.w),
|
||||
Text(
|
||||
"Melbourne Itinerary",
|
||||
style: TextStyle(
|
||||
fontSize: 16.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 12.h),
|
||||
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.w),
|
||||
child: Row(
|
||||
children: [
|
||||
CustomText(
|
||||
text: "Melbourne",
|
||||
size: 24.sp,
|
||||
weight: FontWeight.w500,
|
||||
),
|
||||
const Spacer(),
|
||||
Icon(Icons.edit, color: Color(0xFFF95F62), size: 16.sp),
|
||||
SizedBox(width: 24.w),
|
||||
Icon(Icons.share, color: Color(0xFFF95F62), size: 16.sp),
|
||||
SizedBox(width: 24.w),
|
||||
Icon(
|
||||
Icons.file_download_outlined,
|
||||
color: Color(0xFFF95F62),
|
||||
size: 20.sp,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.w),
|
||||
child: Row(
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/icons/calender_filled.png",
|
||||
width: 14.sp,
|
||||
color: Color(0xFF8E8E8E),
|
||||
),
|
||||
SizedBox(width: 4.w),
|
||||
CustomText(
|
||||
text: "22/02/2025",
|
||||
size: 12.sp,
|
||||
color: Color(0xFF8E8E8E),
|
||||
),
|
||||
SizedBox(width: 12.w),
|
||||
|
||||
Image.asset(
|
||||
"assets/icons/adult.png",
|
||||
width: 14.sp,
|
||||
color: Color(0xFF8E8E8E),
|
||||
),
|
||||
SizedBox(width: 4.w),
|
||||
CustomText(
|
||||
text: "3 adults",
|
||||
size: 12.sp,
|
||||
color: Color(0xFF8E8E8E),
|
||||
),
|
||||
SizedBox(width: 12.w),
|
||||
|
||||
Image.asset(
|
||||
"assets/icons/kid.png",
|
||||
height: 14.sp,
|
||||
color: Color(0xFF8E8E8E),
|
||||
),
|
||||
SizedBox(width: 4.w),
|
||||
CustomText(
|
||||
text: "3 kids",
|
||||
size: 12.sp,
|
||||
color: Color(0xFF8E8E8E),
|
||||
),
|
||||
SizedBox(width: 12.w),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 25.h),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.w),
|
||||
child: Container(
|
||||
height: 50.h,
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 4.h,
|
||||
horizontal: 4.w,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFFEE7E7),
|
||||
borderRadius: BorderRadius.circular(100.r),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
ItineraryTabButton(index: 0, label: "Daily View"),
|
||||
ItineraryTabButton(index: 1, label: "Summary"),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 25.h),
|
||||
|
||||
BlocBuilder<ItineraryChangeTabBloc, ItineraryTabState>(
|
||||
builder: (context, state) {
|
||||
if (state.tabIndex == 0) {
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.w),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: [
|
||||
...List.generate(4, (index) {
|
||||
return _DayTabButton(
|
||||
index: index,
|
||||
label: "Day ${index + 1}",
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 30.h),
|
||||
|
||||
Container(
|
||||
height: 70.h,
|
||||
width: double.infinity,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 8.w,
|
||||
vertical: 8.h,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFF000000).withOpacity(0.04),
|
||||
borderRadius: BorderRadius.circular(12.r),
|
||||
border: Border.all(
|
||||
color: Color(0xFFF95F62).withOpacity(0.12),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
child: Image.asset(
|
||||
"assets/images/trump_house.png",
|
||||
width: 54.w,
|
||||
height: 54.h,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 24.w),
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
CustomText(
|
||||
text: "Melbourne, Australia",
|
||||
size: 18.sp,
|
||||
weight: FontWeight.w500,
|
||||
),
|
||||
SizedBox(height: 4.h),
|
||||
CustomText(
|
||||
text: "18°C, Sunny",
|
||||
size: 12,
|
||||
weight: FontWeight.w500,
|
||||
color: Color(0xFFFFB23F),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 25.h),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: CustomText(
|
||||
text: "GMT",
|
||||
size: 12.sp,
|
||||
weight: FontWeight.w500,
|
||||
color: Colors.black.withOpacity(0.7),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 25.h),
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
CustomText(
|
||||
text: "8:00 am",
|
||||
size: 14.sp,
|
||||
color: Color(0xFF8E8E8E),
|
||||
),
|
||||
SizedBox(width: 26.w),
|
||||
Expanded(
|
||||
child: Divider(
|
||||
height: 1,
|
||||
color: Colors.black.withOpacity(0.2),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 20.h),
|
||||
|
||||
Column(
|
||||
children: List.generate(
|
||||
3,
|
||||
(index) => ItineraryVisitingPlaceCard(
|
||||
time: "9:00 am",
|
||||
image: "assets/images/itinerary_card.png",
|
||||
title: "Ibis Paris Montmartre Sacré-Coeur",
|
||||
subtitle:
|
||||
"5 Rue Caulaincourt, 75018 Paris France",
|
||||
amenities: [
|
||||
"Food",
|
||||
"Drinks",
|
||||
"Culture",
|
||||
"Souvenirs",
|
||||
],
|
||||
points: [
|
||||
"Coffee at Pellegrini’s Espresso Bar (iconic old-school spot)",
|
||||
"Try the famous hot jam doughnuts",
|
||||
"Shop for fresh produce in the Dairy Hall",
|
||||
"Pick up unique souvenirs in the General Merchandise section",
|
||||
"Join a guided history tour of the market",
|
||||
], dayIndex: 0,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
} else {
|
||||
/// Summary Tab
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 20.w),
|
||||
child: Column(
|
||||
children: [
|
||||
SummaryCard(day: "Day 1", date: "20/09/2024"),
|
||||
SummaryCard(day: "Day 2", date: "21/09/2024"),
|
||||
SummaryCard(day: "Day 3", date: "22/09/2024"),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _DayTabButton extends StatelessWidget {
|
||||
final int index;
|
||||
final String label;
|
||||
const _DayTabButton({required this.index, required this.label});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<ItineraryChangeDayTabBloc, ItineraryDayTabState>(
|
||||
builder: (context, state) {
|
||||
final isActive = state.tabIndex == index;
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
context.read<ItineraryChangeDayTabBloc>().add(
|
||||
ChangeItineraryDayTabEvent(index),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width * 0.224,
|
||||
padding: EdgeInsets.symmetric(vertical: 11.h),
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: isActive
|
||||
? Color(0xFF007AFF)
|
||||
: Colors.black.withOpacity(0.2),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: 16.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: isActive ? Color(0xFF007AFF) : Color(0xFF8E8E8E),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
105
lib/your_itinerary/widgets/itinerary_card_widget.dart
Normal file
105
lib/your_itinerary/widgets/itinerary_card_widget.dart
Normal file
@@ -0,0 +1,105 @@
|
||||
import 'package:citycards_customer/common_packages/custom_bullet_points.dart';
|
||||
import 'package:citycards_customer/common_packages/custom_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class ItineraryVisitingPlaceCard extends StatelessWidget {
|
||||
final String time;
|
||||
final int dayIndex;
|
||||
final String image;
|
||||
final String title;
|
||||
final String subtitle;
|
||||
final List<String> amenities;
|
||||
final List<String> points;
|
||||
|
||||
const ItineraryVisitingPlaceCard({
|
||||
required this.dayIndex,
|
||||
required this.image,
|
||||
required this.title,
|
||||
required this.subtitle,
|
||||
required this.amenities,
|
||||
required this.points,
|
||||
required this.time,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(bottom: 20.h),
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
CustomText(text: time, size: 14.sp, color: Color(0xFF8E8E8E)),
|
||||
SizedBox(width: 26.w),
|
||||
Expanded(
|
||||
child: Divider(height: 1, color: Colors.black.withOpacity(0.2)),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
SizedBox(height: 4.h),
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
child: Image.asset(
|
||||
image,
|
||||
width: double.infinity,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 6.h),
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(fontSize: 16.sp, fontWeight: FontWeight.w500),
|
||||
),
|
||||
SizedBox(height: 4.h),
|
||||
Text(
|
||||
subtitle,
|
||||
style: TextStyle(
|
||||
fontSize: 12.sp,
|
||||
color: Color(0xFF4E4E4E),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 12.h),
|
||||
|
||||
Row(
|
||||
children: [
|
||||
...List.generate(4, (index) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(right: 8.w),
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 6.h,
|
||||
horizontal: 12.w,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xFFFEE7E7),
|
||||
border: Border.all(color: Color(0xFFFDCDCE)),
|
||||
borderRadius: BorderRadius.circular(100.r),
|
||||
),
|
||||
child: Center(
|
||||
child: CustomText(
|
||||
text: amenities[index],
|
||||
color: Color(0xFFBB474A),
|
||||
size: 14.sp,
|
||||
),
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 12.h),
|
||||
...List.generate(points.length, (index) {
|
||||
return CustomBulletPoints(
|
||||
textColor: Colors.black.withOpacity(0.6),
|
||||
text: points[index],
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
46
lib/your_itinerary/widgets/itinerary_tab_button.dart
Normal file
46
lib/your_itinerary/widgets/itinerary_tab_button.dart
Normal file
@@ -0,0 +1,46 @@
|
||||
import 'package:citycards_customer/your_itinerary/bloc/your_itinerary_tab_bloc.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class ItineraryTabButton extends StatelessWidget {
|
||||
final int index;
|
||||
final String label;
|
||||
|
||||
const ItineraryTabButton({required this.index, required this.label});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocBuilder<ItineraryChangeTabBloc, ItineraryTabState>(
|
||||
builder: (context, state) {
|
||||
final isActive = state.tabIndex == index;
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
context
|
||||
.read<ItineraryChangeTabBloc>()
|
||||
.add(ChangeItineraryTabEvent(index));
|
||||
},
|
||||
child: Container(
|
||||
width: MediaQuery.of(context).size.width * 0.43,
|
||||
decoration: BoxDecoration(
|
||||
color: isActive
|
||||
? Colors.white
|
||||
: Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(100.r),
|
||||
),
|
||||
child: Center(
|
||||
child: Text(
|
||||
label,
|
||||
style: TextStyle(
|
||||
fontSize: 16.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
color:Colors.black
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
154
lib/your_itinerary/widgets/summary_card_view.dart
Normal file
154
lib/your_itinerary/widgets/summary_card_view.dart
Normal file
@@ -0,0 +1,154 @@
|
||||
import 'package:citycards_customer/common_packages/custom_bullet_points.dart';
|
||||
import 'package:citycards_customer/common_packages/custom_expansion_tile.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_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class SummaryCard extends StatelessWidget {
|
||||
final String day;
|
||||
final String date;
|
||||
|
||||
SummaryCard({required this.day, required this.date});
|
||||
|
||||
List<Map<String, dynamic>> itineraryStops = [
|
||||
{
|
||||
"title": "9:00 am: Pallegrini Expresso Bar",
|
||||
"details": [
|
||||
"Coffee at Pellegrini’s Espresso Bar (iconic old-school spot)",
|
||||
"Try the famous hot jam doughnuts",
|
||||
"Shop for fresh produce in the Dairy Hall",
|
||||
"Pick up unique souvenirs in the General Merchandise section",
|
||||
"Join a guided history tour of the market",
|
||||
],
|
||||
},
|
||||
{
|
||||
"title": "9:00 am: Pallegrini Expresso Bar",
|
||||
"details": [
|
||||
"Coffee at Pellegrini’s Espresso Bar (iconic old-school spot)",
|
||||
"Try the famous hot jam doughnuts",
|
||||
"Shop for fresh produce in the Dairy Hall",
|
||||
"Pick up unique souvenirs in the General Merchandise section",
|
||||
"Join a guided history tour of the market",
|
||||
],
|
||||
},
|
||||
{
|
||||
"title": "9:00 am: Pallegrini Expresso Bar",
|
||||
"details": [
|
||||
"Coffee at Pellegrini’s Espresso Bar (iconic old-school spot)",
|
||||
"Try the famous hot jam doughnuts",
|
||||
"Shop for fresh produce in the Dairy Hall",
|
||||
"Pick up unique souvenirs in the General Merchandise section",
|
||||
"Join a guided history tour of the market",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
margin: EdgeInsets.only(bottom: 20.h),
|
||||
padding: EdgeInsets.symmetric(vertical: 12.w, horizontal: 8.w),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
color: Colors.white,
|
||||
border: Border.all(color: Color(0xFFF95F62)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
CustomText(
|
||||
text: "${day} :",
|
||||
size: 16.sp,
|
||||
weight: FontWeight.w500,
|
||||
color: Color(0xFF212121),
|
||||
),
|
||||
SizedBox(width: 16.w),
|
||||
Row(
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/icons/calender_filled.png",
|
||||
color: Color(0xFFF95F62),
|
||||
width: 20.sp,
|
||||
),
|
||||
SizedBox(width: 4.w),
|
||||
CustomText(
|
||||
text: date,
|
||||
color: Color(0xfFF95F62),
|
||||
size: 16.sp,
|
||||
weight: FontWeight.w500,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 15.h),
|
||||
|
||||
...List.generate(itineraryStops.length, (index) {
|
||||
final item = itineraryStops[index];
|
||||
return Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.h),
|
||||
child: CustomExpansionTile(
|
||||
borderRadius: BorderRadius.circular(5.r),
|
||||
dense: true,
|
||||
visualDensity: VisualDensity.compact,
|
||||
backgroundColor: Color(0xFFFEE7E7),
|
||||
collapsedBackgroundColor: Color(0xFFFEE7E7),
|
||||
tilePadding: EdgeInsets.symmetric(
|
||||
horizontal: 12.w,
|
||||
vertical: 0,
|
||||
),
|
||||
childrenPadding: EdgeInsets.fromLTRB(20.w, 0, 20.w, 12.h),
|
||||
title: Text(
|
||||
item['title'],
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
...item['details'].map(
|
||||
(e) => CustomBulletPoints(
|
||||
textColor: Color(0xFF5C5C5C),
|
||||
text: e,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10.h),
|
||||
Container(
|
||||
height: 32.h,
|
||||
width: 124.w,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(100.r),
|
||||
color: Color(0xFFF95F62),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset("assets/icons/location.png",color: Colors.white,width: 14.sp),
|
||||
SizedBox(width: 6.w,),
|
||||
CustomText(
|
||||
text: "Get Directions",
|
||||
size: 11.sp,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
216
pubspec.lock
216
pubspec.lock
@@ -9,6 +9,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.7"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.7.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -73,6 +81,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.6"
|
||||
csslib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: csslib
|
||||
sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
cupertino_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -81,6 +97,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.8"
|
||||
dbus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dbus
|
||||
sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.11"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -129,6 +153,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.3+4"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fixnum
|
||||
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@@ -184,6 +216,70 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
geoclue:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geoclue
|
||||
sha256: c2a998c77474fc57aa00c6baa2928e58f4b267649057a1c76738656e9dbd2a7f
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.1"
|
||||
geolocator:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: geolocator
|
||||
sha256: "79939537046c9025be47ec645f35c8090ecadb6fe98eba146a0d25e8c1357516"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "14.0.2"
|
||||
geolocator_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_android
|
||||
sha256: "179c3cb66dfa674fc9ccbf2be872a02658724d1c067634e2c427cf6df7df901a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.2"
|
||||
geolocator_apple:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_apple
|
||||
sha256: dbdd8789d5aaf14cf69f74d4925ad1336b4433a6efdf2fce91e8955dc921bf22
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.13"
|
||||
geolocator_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_linux
|
||||
sha256: c4e966f0a7a87e70049eac7a2617f9e16fd4c585a26e4330bdfc3a71e6a721f3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.3"
|
||||
geolocator_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_platform_interface
|
||||
sha256: "30cb64f0b9adcc0fb36f628b4ebf4f731a2961a0ebd849f4b56200205056fe67"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.2.6"
|
||||
geolocator_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_web
|
||||
sha256: b1ae9bdfd90f861fde8fd4f209c37b953d65e92823cb73c7dee1fa021b06f172
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.3"
|
||||
geolocator_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: geolocator_windows
|
||||
sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.5"
|
||||
google_fonts:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -192,6 +288,70 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.3.2"
|
||||
google_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_maps
|
||||
sha256: "5d410c32112d7c6eb7858d359275b2aa04778eed3e36c745aeae905fb2fa6468"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.2.0"
|
||||
google_maps_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: google_maps_flutter
|
||||
sha256: c389e16fafc04b37a4105e0757ecb9d59806026cee72f408f1ba68811d01bfe6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.13.1"
|
||||
google_maps_flutter_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_maps_flutter_android
|
||||
sha256: f820a3990d4ff23e3baf01ce794f7f08cca9a9ce6c875ec96882d605f6f039df
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.18.4"
|
||||
google_maps_flutter_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_maps_flutter_ios
|
||||
sha256: ca02463b19a9abc7d31fcaf22631d021d647107467f741b917a69fa26659fd75
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.15.5"
|
||||
google_maps_flutter_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_maps_flutter_platform_interface
|
||||
sha256: f4b9b44f7b12a1f6707ffc79d082738e0b7e194bf728ee61d2b3cdf5fdf16081
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.14.0"
|
||||
google_maps_flutter_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: google_maps_flutter_web
|
||||
sha256: "53e5dbf73ff04153acc55a038248706967c21d5b6ef6657a57fce2be73c2895a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.14+2"
|
||||
gsettings:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: gsettings
|
||||
sha256: "1b0ce661f5436d2db1e51f3c4295a49849f03d304003a7ba177d01e3a858249c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.8"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: html
|
||||
sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.15.6"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -360,6 +520,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
package_info_plus:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus
|
||||
sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.3.1"
|
||||
package_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_platform_interface
|
||||
sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -456,6 +632,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.5+1"
|
||||
sanitize_html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sanitize_html
|
||||
sha256: "12669c4a913688a26555323fb9cec373d8f9fbe091f2d01c40c723b33caa8989"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@@ -469,6 +653,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.1"
|
||||
sprintf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sprintf
|
||||
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -485,6 +677,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
stream_transform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -517,6 +717,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: uuid
|
||||
sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.5.1"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -541,6 +749,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.15.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
||||
@@ -41,6 +41,8 @@ dependencies:
|
||||
image_picker: ^1.2.0
|
||||
image: ^4.5.4
|
||||
flutter_otp_text_field: ^1.5.1+1
|
||||
google_maps_flutter: ^2.13.1
|
||||
geolocator: ^14.0.2
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
@@ -70,6 +72,7 @@ flutter:
|
||||
- assets/images/
|
||||
- assets/icons/
|
||||
- assets/dummy/
|
||||
- assets/gif/
|
||||
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/to/resolution-aware-images
|
||||
|
||||
Reference in New Issue
Block a user