Updated itinerary creation view

This commit is contained in:
Vinayakkadge04
2025-10-28 19:54:12 +05:30
parent 93749af445
commit b42812f0c2
33 changed files with 1513 additions and 158 deletions

View File

@@ -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"

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 MiB

View File

@@ -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,
),

View File

@@ -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
),
),
],

View 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),
),
],
);
}
}

View File

@@ -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'))),
);
}
}

View File

@@ -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';
}

View File

@@ -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) {

View File

@@ -22,7 +22,7 @@ class ItineraryStepNavigationBloc
on<ItineraryStepNavigationNextEvent>((event, emit) {
final nextIndex = state.selectedIndex + 1;
if (nextIndex <= 10) {
if (nextIndex <= 11) {
emit(ItineraryStepNavigationState(nextIndex));
}
});

View File

@@ -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: [

View File

@@ -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(

View File

@@ -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),
],
),
),
),
);
}
}

View File

@@ -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),

View File

@@ -79,7 +79,7 @@ class ItineraryCompletionView extends StatelessWidget {
),
_buildProfileRow(
"Dietary",
(state.selectedDietary ?? []).join(', '),
state.selectedDietary ?? "",
),
_buildProfileRow(
"Museums",

View File

@@ -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(

View File

@@ -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(

View File

@@ -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(),

View 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 Dont 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,)
],
),
),
),
);
}
}

View 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,
),
),
),
],
),
);
}
}

View File

@@ -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(

View File

@@ -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;
}

View 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));
});
}
}

View 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));
});
}
}

View 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 Pellegrinis 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),
),
),
),
),
);
},
);
}
}

View 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],
);
}),
],
),
);
}
}

View 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
),
),
),
),
);
},
);
}
}

View 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 Pellegrinis 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 Pellegrinis 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 Pellegrinis 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,
),
],
),
),
],
),
],
),
);
}),
],
),
);
}
}

View File

@@ -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:

View File

@@ -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