Updated itinerary creation view
This commit is contained in:
@@ -1,4 +1,8 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<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
|
<application
|
||||||
android:label="citycards_customer"
|
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,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
CommonAppBar(isWhiteLogo: false, isProfilePage: false, showCart: false,),
|
CommonAppBar(isWhiteLogo: false, isProfilePage: false, showCart: false,),
|
||||||
backWidget(context, "Your Cart"),
|
backWidget(context, "Your Cart", Colors.black),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 24.h,
|
height: 24.h,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
|
||||||
Widget backWidget(BuildContext context, String title){
|
Widget backWidget(BuildContext context, String title, Color? textColor){
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.pop(context);
|
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),
|
SizedBox(width: 8.w),
|
||||||
Text(
|
Text(
|
||||||
@@ -16,6 +16,7 @@ Widget backWidget(BuildContext context, String title){
|
|||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 12.sp,
|
fontSize: 12.sp,
|
||||||
fontWeight: FontWeight.w500,
|
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/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_start_view.dart';
|
||||||
import 'package:citycards_customer/itinerary_creation/views/itinerary_creation_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/privacy/privacy_view.dart';
|
||||||
import 'package:citycards_customer/search_offers/bloc/search_offers_listing_bloc.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/search_offers/view/search_offers_with_listing.dart';
|
||||||
import 'package:citycards_customer/terms_and_condition/terms_and_condition_view.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/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import '../attractions/views/attractions_page_view.dart';
|
import '../attractions/views/attractions_page_view.dart';
|
||||||
@@ -121,46 +124,77 @@ class AppRouter {
|
|||||||
);
|
);
|
||||||
|
|
||||||
case RouteConstants.attractionDetails:
|
case RouteConstants.attractionDetails:
|
||||||
return MaterialPageRoute(builder: (_) {
|
return MaterialPageRoute(
|
||||||
return AttractionDetailsView();
|
builder: (_) {
|
||||||
});
|
return AttractionDetailsView();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
case RouteConstants.buyPass:
|
case RouteConstants.buyPass:
|
||||||
return MaterialPageRoute(builder: (_) {
|
return MaterialPageRoute(
|
||||||
return BuyPassView();
|
builder: (_) {
|
||||||
});
|
return BuyPassView();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
case RouteConstants.checkout:
|
case RouteConstants.checkout:
|
||||||
return MaterialPageRoute(builder: (_){
|
return MaterialPageRoute(
|
||||||
return CheckoutView();
|
builder: (_) {
|
||||||
});
|
return CheckoutView();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
case RouteConstants.cartPage:
|
case RouteConstants.cartPage:
|
||||||
return MaterialPageRoute(builder: (_){
|
return MaterialPageRoute(
|
||||||
return MyCartPage();
|
builder: (_) {
|
||||||
});
|
return MyCartPage();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
case RouteConstants.searchOffer:
|
case RouteConstants.searchOffer:
|
||||||
return MaterialPageRoute(builder: (_){
|
return MaterialPageRoute(
|
||||||
return BlocProvider(
|
builder: (_) {
|
||||||
|
return BlocProvider(
|
||||||
create: (_) => OffersBloc(),
|
create: (_) => OffersBloc(),
|
||||||
child: SearchOffersWithListing(),
|
child: SearchOffersWithListing(),
|
||||||
);
|
);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
case RouteConstants.addDetails:
|
case RouteConstants.addDetails:
|
||||||
return MaterialPageRoute(builder: (_){
|
return MaterialPageRoute(
|
||||||
return AddDetailsView();
|
builder: (_) {
|
||||||
});
|
return AddDetailsView();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
case RouteConstants.createAcct:
|
case RouteConstants.createAcct:
|
||||||
|
return MaterialPageRoute(
|
||||||
|
builder: (_) {
|
||||||
|
return CreateAccountView();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
case RouteConstants.yourItinerary:
|
||||||
|
return MaterialPageRoute(
|
||||||
|
builder: (_) {
|
||||||
|
return YourItineraryView();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
case RouteConstants.magicItineraryEmptyScreen:
|
||||||
return MaterialPageRoute(builder: (_){
|
return MaterialPageRoute(builder: (_){
|
||||||
return CreateAccountView();
|
return MagicItineraryEmptyView();
|
||||||
|
});
|
||||||
|
|
||||||
|
case RouteConstants.magicItineraryFilledScreen:
|
||||||
|
return MaterialPageRoute(builder: (_){
|
||||||
|
return MagicItineraryFilledView();
|
||||||
});
|
});
|
||||||
default:
|
default:
|
||||||
return MaterialPageRoute(
|
return MaterialPageRoute(
|
||||||
builder: (_) =>
|
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 ************************************/
|
/****************************** ITINERARY CREATION ************************************/
|
||||||
|
|
||||||
|
static const String magicItineraryEmptyScreen = '/magicItineraryEmptyScreen';
|
||||||
static const String itineraryCreationStart = '/itineraryCreationStart';
|
static const String itineraryCreationStart = '/itineraryCreationStart';
|
||||||
static const String itineraryCreation = '/itineraryCreation';
|
static const String itineraryCreation = '/itineraryCreation';
|
||||||
|
static const String magicItineraryFilledScreen = "/magicItineraryFilledScreen";
|
||||||
|
|
||||||
/**************************** ESIM Page *****************************************/
|
/**************************** ESIM Page *****************************************/
|
||||||
|
|
||||||
@@ -41,5 +43,6 @@ class RouteConstants {
|
|||||||
|
|
||||||
/************************** My card page ***************************************/
|
/************************** My card page ***************************************/
|
||||||
static const String cartPage = '/cartPage';
|
static const String cartPage = '/cartPage';
|
||||||
|
static const String yourItinerary = '/yourItinerary';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class ItineraryDetailState {
|
|||||||
final String? selectedCity;
|
final String? selectedCity;
|
||||||
final String? selectedEnergy;
|
final String? selectedEnergy;
|
||||||
final String? withKid;
|
final String? withKid;
|
||||||
final List<String>? selectedDietary;
|
final String? selectedDietary;
|
||||||
final String? museumRating;
|
final String? museumRating;
|
||||||
final String? scenicRating;
|
final String? scenicRating;
|
||||||
final String? culturalRating;
|
final String? culturalRating;
|
||||||
@@ -93,7 +93,7 @@ class ItineraryDetailState {
|
|||||||
String? selectedCity,
|
String? selectedCity,
|
||||||
String? selectedEnergy,
|
String? selectedEnergy,
|
||||||
String? withKid,
|
String? withKid,
|
||||||
List<String>? selectedDietary,
|
String? selectedDietary,
|
||||||
String? museumRating,
|
String? museumRating,
|
||||||
String? scenicRating,
|
String? scenicRating,
|
||||||
String? culturalRating,
|
String? culturalRating,
|
||||||
@@ -124,7 +124,7 @@ class AddItineraryDetailBloc
|
|||||||
selectedCity: "Paris",
|
selectedCity: "Paris",
|
||||||
selectedEnergy: "",
|
selectedEnergy: "",
|
||||||
withKid: "",
|
withKid: "",
|
||||||
selectedDietary: const [],
|
selectedDietary: "",
|
||||||
museumRating: "",
|
museumRating: "",
|
||||||
scenicRating: "",
|
scenicRating: "",
|
||||||
culturalRating: "",
|
culturalRating: "",
|
||||||
@@ -150,14 +150,14 @@ class AddItineraryDetailBloc
|
|||||||
});
|
});
|
||||||
|
|
||||||
on<AddDietaryToItinerary>((event, emit) {
|
on<AddDietaryToItinerary>((event, emit) {
|
||||||
final currentSelection = List<String>.from(state.selectedDietary ?? []);
|
// final currentSelection = List<String>.from(state.selectedDietary ?? []);
|
||||||
|
//
|
||||||
if (currentSelection.contains(event.dietary)) {
|
// if (currentSelection.contains(event.dietary)) {
|
||||||
currentSelection.remove(event.dietary);
|
// currentSelection.remove(event.dietary);
|
||||||
} else {
|
// } else {
|
||||||
currentSelection.add(event.dietary);
|
// currentSelection.add(event.dietary);
|
||||||
}
|
// }
|
||||||
emit(state.copyWith(selectedDietary: currentSelection));
|
emit(state.copyWith(selectedDietary: event.dietary));
|
||||||
});
|
});
|
||||||
|
|
||||||
on<AddMuseumRating>((event, emit) {
|
on<AddMuseumRating>((event, emit) {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class ItineraryStepNavigationBloc
|
|||||||
|
|
||||||
on<ItineraryStepNavigationNextEvent>((event, emit) {
|
on<ItineraryStepNavigationNextEvent>((event, emit) {
|
||||||
final nextIndex = state.selectedIndex + 1;
|
final nextIndex = state.selectedIndex + 1;
|
||||||
if (nextIndex <= 10) {
|
if (nextIndex <= 11) {
|
||||||
emit(ItineraryStepNavigationState(nextIndex));
|
emit(ItineraryStepNavigationState(nextIndex));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,27 +16,10 @@ class ItineraryCreationStartPage extends StatelessWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
|
||||||
height: 103.h,
|
Image.asset("assets/gif/create_itinerary.gif",width: 128.w),
|
||||||
width: 103.w,
|
|
||||||
|
|
||||||
decoration: BoxDecoration(
|
SizedBox(height: 21.h),
|
||||||
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),
|
|
||||||
Text.rich(
|
Text.rich(
|
||||||
TextSpan(
|
TextSpan(
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@@ -64,18 +64,10 @@ class HistoricalSiteRatingView extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||||
height: 82.h,
|
height: 83.h,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.circular(16.r),
|
borderRadius: BorderRadius.circular(28.r),
|
||||||
border: Border.all(color: Color(0xFFE5E7EB), width: 1.1),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.black12,
|
|
||||||
offset: Offset(1, 2),
|
|
||||||
blurRadius: 1,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Row(
|
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: 38.h),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 350.h,
|
height: 350.h,
|
||||||
child:
|
child: BlocBuilder<AddItineraryDetailBloc, ItineraryDetailState>(
|
||||||
BlocBuilder<
|
builder: (context, sate) {
|
||||||
AddItineraryDetailBloc,
|
return GridView.builder(
|
||||||
ItineraryDetailState
|
physics: NeverScrollableScrollPhysics(),
|
||||||
>(
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
builder: (context, sate) {
|
mainAxisSpacing: 12,
|
||||||
return GridView.builder(
|
crossAxisSpacing: 16,
|
||||||
physics: NeverScrollableScrollPhysics(),
|
crossAxisCount: 2,
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
childAspectRatio: 1.7,
|
||||||
mainAxisSpacing: 12,
|
),
|
||||||
crossAxisSpacing: 16,
|
itemCount: options.length,
|
||||||
crossAxisCount: 2,
|
itemBuilder: (BuildContext context, int index) {
|
||||||
childAspectRatio: 1.7,
|
final item = options[index];
|
||||||
),
|
final isSelected = sate.selectedDietary == item['name'];
|
||||||
itemCount: options.length,
|
return GestureDetector(
|
||||||
itemBuilder: (BuildContext context, int index) {
|
onTap: () {
|
||||||
final item = options[index];
|
context.read<AddItineraryDetailBloc>().add(
|
||||||
final isSelected = (sate.selectedDietary ?? []).contains(
|
AddDietaryToItinerary(item['name'] ?? ""),
|
||||||
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: 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),
|
SizedBox(height: 41.h),
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ class ItineraryCompletionView extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
_buildProfileRow(
|
_buildProfileRow(
|
||||||
"Dietary",
|
"Dietary",
|
||||||
(state.selectedDietary ?? []).join(', '),
|
state.selectedDietary ?? "",
|
||||||
),
|
),
|
||||||
_buildProfileRow(
|
_buildProfileRow(
|
||||||
"Museums",
|
"Museums",
|
||||||
|
|||||||
@@ -65,18 +65,10 @@ class ShoppingRatingView extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||||
height: 82.h,
|
height: 83.h,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.circular(16.r),
|
borderRadius: BorderRadius.circular(28.r),
|
||||||
border: Border.all(color: Color(0xFFE5E7EB), width: 1.1),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.black12,
|
|
||||||
offset: Offset(1, 2),
|
|
||||||
blurRadius: 1,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|||||||
@@ -50,21 +50,10 @@ class WildlifeRatingView extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
padding: EdgeInsets.symmetric(horizontal: 24.w),
|
||||||
height: 82.h,
|
height: 83.h,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.circular(16.r),
|
borderRadius: BorderRadius.circular(28.r),
|
||||||
border: Border.all(
|
|
||||||
color: Color(0xFFE5E7EB),
|
|
||||||
width: 1.1
|
|
||||||
),
|
|
||||||
boxShadow: [
|
|
||||||
BoxShadow(
|
|
||||||
color: Colors.black12,
|
|
||||||
offset: Offset(1,2),
|
|
||||||
blurRadius: 1,
|
|
||||||
)
|
|
||||||
]
|
|
||||||
),
|
),
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
|
|
||||||
import 'package:citycards_customer/itinerary_creation/bloc/itinerary_steps_selection_bloc.dart';
|
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/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
@@ -48,7 +49,7 @@ class _ItineraryCreationPageState extends State<ItineraryCreationPage> {
|
|||||||
>(
|
>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return Text(
|
return Text(
|
||||||
"${state.selectedIndex} / 10",
|
"${state.selectedIndex} / 11",
|
||||||
style: TextStyle(color: Color(0xFF4A5565), fontSize: 14.sp),
|
style: TextStyle(color: Color(0xFF4A5565), fontSize: 14.sp),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -84,7 +85,7 @@ class _ItineraryCreationPageState extends State<ItineraryCreationPage> {
|
|||||||
>(
|
>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return LinearProgressIndicator(
|
return LinearProgressIndicator(
|
||||||
value: state.selectedIndex / 10,
|
value: state.selectedIndex / 11,
|
||||||
borderRadius: BorderRadius.circular(10),
|
borderRadius: BorderRadius.circular(10),
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
color: const Color(0xFFF95F62),
|
color: const Color(0xFFF95F62),
|
||||||
@@ -103,7 +104,7 @@ class _ItineraryCreationPageState extends State<ItineraryCreationPage> {
|
|||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
children: [
|
children: [
|
||||||
DateSelectionView(),
|
DateSelectionView(),
|
||||||
|
CurrentLocationSelection(),
|
||||||
CitySelectionView(),
|
CitySelectionView(),
|
||||||
EnergySelectionView(),
|
EnergySelectionView(),
|
||||||
KidsSelectionView(),
|
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) {
|
builder: (context, child) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
onGenerateRoute: _appRouter.onGenerateRoute,
|
onGenerateRoute: _appRouter.onGenerateRoute,
|
||||||
initialRoute: RouteConstants.buyPass,
|
initialRoute: RouteConstants.magicItineraryFilledScreen,
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
title: 'City Cards',
|
title: 'City Cards',
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
|
|||||||
@@ -12,9 +12,7 @@ class DottedBorderContainer extends StatelessWidget {
|
|||||||
height: 300.h,
|
height: 300.h,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(16)),
|
||||||
borderRadius: BorderRadius.circular(16),
|
|
||||||
),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
@@ -24,7 +22,11 @@ class DottedBorderContainer extends StatelessWidget {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Icon(Icons.add_circle_outline, color: Color(0xffF95F62), size: 25,),
|
Icon(
|
||||||
|
Icons.add_circle_outline,
|
||||||
|
color: Color(0xffF95F62),
|
||||||
|
size: 25,
|
||||||
|
),
|
||||||
const Text(
|
const Text(
|
||||||
"Add image",
|
"Add image",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
@@ -52,18 +54,18 @@ class DottedBorderPainter extends CustomPainter {
|
|||||||
const double dashWidth = 6;
|
const double dashWidth = 6;
|
||||||
const double dashSpace = 3;
|
const double dashSpace = 3;
|
||||||
final path = Path()
|
final path = Path()
|
||||||
..addRRect(RRect.fromRectAndRadius(
|
..addRRect(
|
||||||
|
RRect.fromRectAndRadius(
|
||||||
Rect.fromLTWH(0, 0, size.width, size.height),
|
Rect.fromLTWH(0, 0, size.width, size.height),
|
||||||
const Radius.circular(16)));
|
const Radius.circular(16),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
final pathMetrics = path.computeMetrics();
|
final pathMetrics = path.computeMetrics();
|
||||||
for (final metric in pathMetrics) {
|
for (final metric in pathMetrics) {
|
||||||
double distance = 0.0;
|
double distance = 0.0;
|
||||||
while (distance < metric.length) {
|
while (distance < metric.length) {
|
||||||
final segment = metric.extractPath(
|
final segment = metric.extractPath(distance, distance + dashWidth);
|
||||||
distance,
|
|
||||||
distance + dashWidth,
|
|
||||||
);
|
|
||||||
canvas.drawPath(segment, paint);
|
canvas.drawPath(segment, paint);
|
||||||
distance += dashWidth + dashSpace;
|
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"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.0.7"
|
version: "4.0.7"
|
||||||
|
args:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: args
|
||||||
|
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.7.0"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -73,6 +81,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.6"
|
version: "3.0.6"
|
||||||
|
csslib:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: csslib
|
||||||
|
sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -81,6 +97,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.8"
|
version: "1.0.8"
|
||||||
|
dbus:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: dbus
|
||||||
|
sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.7.11"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -129,6 +153,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.9.3+4"
|
version: "0.9.3+4"
|
||||||
|
fixnum:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: fixnum
|
||||||
|
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.1"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -184,6 +216,70 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
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:
|
google_fonts:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -192,6 +288,70 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.3.2"
|
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:
|
http:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -360,6 +520,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
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:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -456,6 +632,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.5+1"
|
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:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@@ -469,6 +653,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.1"
|
version: "1.10.1"
|
||||||
|
sprintf:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sprintf
|
||||||
|
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "7.0.0"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -485,6 +677,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.4"
|
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:
|
string_scanner:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -517,6 +717,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.4.0"
|
||||||
|
uuid:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: uuid
|
||||||
|
sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.5.1"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -541,6 +749,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.1"
|
version: "1.1.1"
|
||||||
|
win32:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: win32
|
||||||
|
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.15.0"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ dependencies:
|
|||||||
image_picker: ^1.2.0
|
image_picker: ^1.2.0
|
||||||
image: ^4.5.4
|
image: ^4.5.4
|
||||||
flutter_otp_text_field: ^1.5.1+1
|
flutter_otp_text_field: ^1.5.1+1
|
||||||
|
google_maps_flutter: ^2.13.1
|
||||||
|
geolocator: ^14.0.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@@ -70,6 +72,7 @@ flutter:
|
|||||||
- assets/images/
|
- assets/images/
|
||||||
- assets/icons/
|
- assets/icons/
|
||||||
- assets/dummy/
|
- assets/dummy/
|
||||||
|
- assets/gif/
|
||||||
|
|
||||||
# An image asset can refer to one or more resolution-specific "variants", see
|
# An image asset can refer to one or more resolution-specific "variants", see
|
||||||
# https://flutter.dev/to/resolution-aware-images
|
# https://flutter.dev/to/resolution-aware-images
|
||||||
|
|||||||
Reference in New Issue
Block a user