diff --git a/assets/images/booking_successful.png b/assets/images/booking_successful.png new file mode 100644 index 0000000..43e2dcd Binary files /dev/null and b/assets/images/booking_successful.png differ diff --git a/assets/images/profile_default_img.png b/assets/images/profile_default_img.png new file mode 100644 index 0000000..a416806 Binary files /dev/null and b/assets/images/profile_default_img.png differ diff --git a/assets/logo/melbourne_logo.png b/assets/logo/melbourne_logo.png new file mode 100644 index 0000000..8ff4888 Binary files /dev/null and b/assets/logo/melbourne_logo.png differ diff --git a/assets/logo/melbourne_white.png b/assets/logo/melbourne_white.png new file mode 100644 index 0000000..64a7ddb Binary files /dev/null and b/assets/logo/melbourne_white.png differ diff --git a/lib/common_packages/app_bar.dart b/lib/common_packages/app_bar.dart index 5d51372..ae0154b 100644 --- a/lib/common_packages/app_bar.dart +++ b/lib/common_packages/app_bar.dart @@ -24,8 +24,8 @@ class CommonAppBar extends StatelessWidget { children: [ Image.asset( isWhiteLogo - ? "assets/logo/logo_city_cards_white.png" - : "assets/logo/logo_city_cards.png", + ? "assets/logo/melbourne_white.png" + : "assets/logo/melbourne_logo.png", scale: 4, ), Row( @@ -61,9 +61,7 @@ class CommonAppBar extends StatelessWidget { }, child: CircleAvatar( backgroundColor: Color(0xffFFDFDF), - backgroundImage: AssetImage( - "assets/images/profile_img.png", - ), + child: Image.asset( "assets/images/profile_default_img.png",), ), ), ], diff --git a/lib/core/inside_bottom_navigator.dart b/lib/core/inside_bottom_navigator.dart index d793606..97f87ef 100644 --- a/lib/core/inside_bottom_navigator.dart +++ b/lib/core/inside_bottom_navigator.dart @@ -6,19 +6,25 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import '../attraction_details/attraction_details_view.dart'; import '../attractions/views/attractions_page_view.dart'; +import '../itinerary_creation/bloc/itinerary_detail_bloc.dart'; +import '../itinerary_creation/bloc/itinerary_steps_selection_bloc.dart'; +import '../itinerary_creation/views/itinerary_creation_view.dart'; +import '../itinerary_creation/views/magic_itinerary_filled_view.dart'; import '../my_pass/views/booking_page_view.dart'; +import '../my_pass/views/booking_successful_page_view.dart'; import '../my_pass/views/qr_pass_page_view.dart'; import '../postcard/blocs/postcard_creation_bloc.dart'; import '../postcard/views/postcard_creation_page_view.dart'; import '../search_offers/bloc/search_offers_listing_bloc.dart'; import '../search_offers/view/search_offers_with_listing.dart'; +import '../your_itinerary/view/your_itinerary_view.dart'; Widget buildOffstageNavigator( - int index, - int currentIndex, - Widget child, - Key key, - ) { + int index, + int currentIndex, + Widget child, + Key key, +) { return Offstage( offstage: currentIndex != index, child: Navigator( @@ -28,22 +34,37 @@ Widget buildOffstageNavigator( case '/': return MaterialPageRoute(builder: (_) => child); - // πŸ”Ή Attractions Page + // πŸ”Ή Attractions Page case RouteConstants.attractionsPage: final args = settings.arguments as String; return MaterialPageRoute( - builder: (_) => AttractionsPage(source: args,), + builder: (_) => AttractionsPage(source: args), ); case RouteConstants.attractionDetails: - return MaterialPageRoute(builder: (_) { - return AttractionDetailsView(); - }); + return MaterialPageRoute( + builder: (_) { + return AttractionDetailsView(); + }, + ); - case RouteConstants.makeBooking: - return MaterialPageRoute(builder: (_) { - return MakeBookingView(title: 'asffdsf', description: 'afdsfadsfasdfads',); - }); + case RouteConstants.makeBooking: + return MaterialPageRoute( + builder: (_) { + return MakeBookingView( + title: 'Koh Rong Samloem', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Convallis condimentum morbi non egestas enim amet sagittis.ß', + ); + }, + ); + + case RouteConstants.bookingSuccessful: + return MaterialPageRoute( + builder: (_) { + return BookingSuccessfulPageView(); + }, + ); case RouteConstants.searchOffer: return MaterialPageRoute( @@ -55,7 +76,7 @@ Widget buildOffstageNavigator( }, ); - // πŸ”Ή Upload Photo Page (start of postcard creation flow) + // πŸ”Ή Upload Photo Page (start of postcard creation flow) case RouteConstants.uploadPhotoPage: return MaterialPageRoute( builder: (_) => BlocProvider( @@ -64,11 +85,13 @@ Widget buildOffstageNavigator( ), ); - // πŸ”Ή Add Filter Page (uses same bloc instance) + // πŸ”Ή Add Filter Page (uses same bloc instance) case RouteConstants.addFilterPage: return MaterialPageRoute( builder: (context) { - final previousBloc = BlocProvider.of(context); + final previousBloc = BlocProvider.of( + context, + ); return BlocProvider.value( value: previousBloc, child: const AddFilterStepPageView(), @@ -76,7 +99,6 @@ Widget buildOffstageNavigator( }, ); - case RouteConstants.qrPage: return MaterialPageRoute( builder: (context) { @@ -88,11 +110,40 @@ Widget buildOffstageNavigator( }, ); + case RouteConstants.itineraryCreation: + return MaterialPageRoute( + builder: (_) { + return MultiBlocProvider( + providers: [ + BlocProvider( + create: (_) => ItineraryStepNavigationBloc(), + ), + + BlocProvider( + create: (_) => AddItineraryDetailBloc(), + ), + ], + child: const ItineraryCreationPage(), + ); + }, + ); + + case RouteConstants.yourItinerary: + return MaterialPageRoute( + builder: (_) { + return YourItineraryView(); + }, + ); + + case RouteConstants.magicItineraryFilledScreen: + return MaterialPageRoute(builder: (_){ + return MagicItineraryFilledView(); + }); + default: return MaterialPageRoute( - builder: (_) => const Scaffold( - body: Center(child: Text('Page not found')), - ), + builder: (_) => + const Scaffold(body: Center(child: Text('Page not found'))), ); } }, diff --git a/lib/core/route_constants.dart b/lib/core/route_constants.dart index 768c7ee..e235102 100644 --- a/lib/core/route_constants.dart +++ b/lib/core/route_constants.dart @@ -49,4 +49,5 @@ class RouteConstants { static const String qrPage = '/qrPage'; static const String makeBooking = '/makeBooking'; + static const String bookingSuccessful = '/bookingSuccessful'; } diff --git a/lib/itinerary_creation/views/itinerary_creation_start_view.dart b/lib/itinerary_creation/views/itinerary_creation_start_view.dart index bb6ada6..a9a412a 100644 --- a/lib/itinerary_creation/views/itinerary_creation_start_view.dart +++ b/lib/itinerary_creation/views/itinerary_creation_start_view.dart @@ -57,9 +57,7 @@ class ItineraryCreationStartPage extends StatelessWidget { onTap: () { Navigator.of( context, - rootNavigator: true, - ).pushNamed(RouteConstants.itineraryCreation); - // Navigator.pushNamed(context, RouteConstants.itineraryCreation); + ).pushReplacementNamed(RouteConstants.itineraryCreation); }, showArrow: true, label: "Let’s Get Started", diff --git a/lib/itinerary_creation/views/itinerary_creation_steps/itinerary_completion_view.dart b/lib/itinerary_creation/views/itinerary_creation_steps/itinerary_completion_view.dart index 6fb1f49..cbec5be 100644 --- a/lib/itinerary_creation/views/itinerary_creation_steps/itinerary_completion_view.dart +++ b/lib/itinerary_creation/views/itinerary_creation_steps/itinerary_completion_view.dart @@ -6,6 +6,8 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:citycards_customer/common_packages/custom_text.dart'; import 'package:citycards_customer/common_packages/custom_filled_button.dart'; +import '../../../core/route_constants.dart'; + class ItineraryCompletionView extends StatelessWidget { const ItineraryCompletionView({super.key}); @@ -135,7 +137,9 @@ class ItineraryCompletionView extends StatelessWidget { label: "Get My Trip Plan", showArrow: true, onTap: () { - // Navigate to next step + Navigator.of( + context, + ).pushReplacementNamed((RouteConstants.yourItinerary)); }, ), ], diff --git a/lib/itinerary_creation/views/magic_itinerary_filled_view.dart b/lib/itinerary_creation/views/magic_itinerary_filled_view.dart index bc67260..f6be597 100644 --- a/lib/itinerary_creation/views/magic_itinerary_filled_view.dart +++ b/lib/itinerary_creation/views/magic_itinerary_filled_view.dart @@ -147,18 +147,23 @@ class ItineraryFilledCard extends StatelessWidget { 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, + InkWell( + onTap: (){ + Navigator.of(context).pushReplacementNamed(RouteConstants.yourItinerary); + }, + child: 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, + ), ), ), ), diff --git a/lib/my_pass/views/booking_page_view.dart b/lib/my_pass/views/booking_page_view.dart index 6e6a9aa..527c7b5 100644 --- a/lib/my_pass/views/booking_page_view.dart +++ b/lib/my_pass/views/booking_page_view.dart @@ -1,8 +1,11 @@ +import 'package:citycards_customer/common_packages/app_bar.dart'; +import 'package:citycards_customer/common_packages/back_widget.dart'; +import 'package:citycards_customer/core/route_constants.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:google_fonts/google_fonts.dart'; -import 'package:table_calendar/table_calendar.dart'; +import 'package:syncfusion_flutter_datepicker/datepicker.dart'; import '../blocs/make_booking_bloc.dart'; import '../blocs/make_booking_events.dart'; @@ -32,209 +35,180 @@ class MakeBookingView extends StatelessWidget { final now = DateTime.now(); return SafeArea( - child: SingleChildScrollView( - padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 20.h), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - // πŸ”™ Back + Title - GestureDetector( - onTap: () => Navigator.pop(context), - child: Row( - children: [ - const Icon(Icons.arrow_back, size: 20), - SizedBox(width: 6.w), - Text( - "Make Booking", - style: GoogleFonts.poppins( - fontSize: 14.sp, - fontWeight: FontWeight.w500, + child: Scaffold( + backgroundColor: Colors.white, + body: SingleChildScrollView( + padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 20.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + CommonAppBar(isWhiteLogo: false, isProfilePage: false), + backWidget(context, "Make Booking", Colors.black), + SizedBox( + height: 20.h, + ), + + // 🏝 Title + Text( + title, + style: GoogleFonts.poppins( + fontSize: 18.sp, + fontWeight: FontWeight.w600, + color: Colors.black, + ), + ), + SizedBox(height: 4.h), + + // πŸ“„ Description + Text( + description, + style: GoogleFonts.poppins( + fontSize: 12.sp, + color: Colors.black54, + ), + ), + SizedBox(height: 24.h), + + // πŸ“… Calendar Container + Container( + width: double.infinity, + padding: EdgeInsets.symmetric(vertical: 12.h, horizontal: 10.w), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(16.r), + boxShadow: [ + BoxShadow( + color: Colors.black12.withOpacity(0.06), + blurRadius: 12, + offset: const Offset(0, 4), + ), + ], + ), + child: Column( + children: [ + Text( + "When are you visiting?", + style: GoogleFonts.poppins( + fontSize: 14.sp, + fontWeight: FontWeight.w500, + color: Colors.black, + ), + ), + SizedBox(height: 8.h), + + // πŸ—“ SfDateRangePicker + SfDateRangePicker( + view: DateRangePickerView.month, + selectionMode: DateRangePickerSelectionMode.range, + minDate: now, + maxDate: now.add(const Duration(days: 365)), + enablePastDates: false, + backgroundColor: Colors.white, + showNavigationArrow: true, + + // βœ… Put the background color here + headerStyle: DateRangePickerHeaderStyle( + backgroundColor: Colors.white, // <-- removes the purple strip + textAlign: TextAlign.center, + textStyle: GoogleFonts.poppins( + fontSize: 13.sp, + fontWeight: FontWeight.w600, color: Colors.black, ), ), - ], - ), - ), - SizedBox(height: 20.h), - // 🏝 Attraction title - Text( - title, - style: GoogleFonts.poppins( - fontSize: 18.sp, - fontWeight: FontWeight.w600, - color: Colors.black, - ), - ), - SizedBox(height: 4.h), - - // Description - Text( - description, - style: GoogleFonts.poppins( - fontSize: 12.sp, - color: Colors.black54, - ), - ), - SizedBox(height: 24.h), - - // πŸ“… Calendar - Container( - padding: EdgeInsets.all(12.w), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(20.r), - boxShadow: [ - BoxShadow( - color: Colors.black12.withOpacity(0.05), - blurRadius: 6, - offset: const Offset(0, 3), - ), - ], - ), - child: Column( - children: [ - Text( - "When are you visiting?", - style: GoogleFonts.poppins( - fontSize: 14.sp, - fontWeight: FontWeight.w500, + monthViewSettings: DateRangePickerMonthViewSettings( + firstDayOfWeek: 7, + viewHeaderStyle: DateRangePickerViewHeaderStyle( + textStyle: GoogleFonts.poppins( + color: Colors.grey.shade600, + fontSize: 11.sp, + fontWeight: FontWeight.w500, + ), ), + blackoutDates: _getUnavailableDates(state.availableDates, now), ), - SizedBox(height: 10.h), - TableCalendar( - focusedDay: now, - firstDay: now, - lastDay: now.add(const Duration(days: 365)), - calendarFormat: CalendarFormat.month, - availableCalendarFormats: const { - CalendarFormat.month: 'Month' - }, - rangeStartDay: state.startDate, - rangeEndDay: state.endDate, - rangeSelectionMode: RangeSelectionMode.toggledOn, - onRangeSelected: (start, end, focusedDay) { + monthCellStyle: DateRangePickerMonthCellStyle( + textStyle: GoogleFonts.poppins(fontSize: 12.sp, color: Colors.black87), + todayTextStyle: GoogleFonts.poppins( + fontSize: 12.sp, color: Colors.black, fontWeight: FontWeight.w500), + blackoutDateTextStyle: GoogleFonts.poppins( + fontSize: 12.sp, color: Colors.grey.shade400, + decoration: TextDecoration.lineThrough), + ), + + rangeTextStyle: GoogleFonts.poppins( + fontSize: 12.sp, color: Colors.white, fontWeight: FontWeight.w500), + startRangeSelectionColor: const Color(0xffFF5A5F), + endRangeSelectionColor: const Color(0xffFF5A5F), + rangeSelectionColor: const Color(0xffFF5A5F).withOpacity(0.15), + selectionTextStyle: GoogleFonts.poppins( + fontSize: 12.sp, color: Colors.white, fontWeight: FontWeight.w500), + + initialSelectedRange: state.startDate != null && state.endDate != null + ? PickerDateRange(state.startDate, state.endDate) + : null, + onSelectionChanged: (DateRangePickerSelectionChangedArgs args) { + if (args.value is PickerDateRange) { + final start = args.value.startDate; + final end = args.value.endDate; if (start != null && end != null) { bloc.add(SelectDate(start, end)); } - }, - headerStyle: HeaderStyle( - titleCentered: true, - formatButtonVisible: false, - titleTextStyle: GoogleFonts.poppins( + } + }, + ), + ], + ), + ), + + SizedBox(height: 40.h), + + // βœ… Confirm button + GestureDetector( + onTap: () { + if (state.startDate != null && state.endDate != null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + "Booking confirmed from " + "${state.startDate!.toLocal().toString().split(' ')[0]} " + "to ${state.endDate!.toLocal().toString().split(' ')[0]}", + ), + ), + ); + Navigator.of(context).pushNamed(RouteConstants.bookingSuccessful); + } else { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text("Please select a valid date range"), + ), + ); + } + }, + child: Container( + width: double.infinity, + padding: EdgeInsets.symmetric(vertical: 14.h), + decoration: BoxDecoration( + color: const Color(0xffFF5A5F), + borderRadius: BorderRadius.circular(30.r), + ), + child: Center( + child: Text( + "Confirm Booking", + style: GoogleFonts.poppins( + color: Colors.white, fontSize: 14.sp, fontWeight: FontWeight.w600, ), ), - calendarStyle: CalendarStyle( - rangeHighlightColor: - const Color(0xffFF5A5F).withOpacity(0.2), - rangeStartDecoration: const BoxDecoration( - color: Color(0xffFF5A5F), - shape: BoxShape.circle, - ), - rangeEndDecoration: const BoxDecoration( - color: Color(0xffFF5A5F), - shape: BoxShape.circle, - ), - todayDecoration: const BoxDecoration( - color: Color(0xffFFEAEA), - shape: BoxShape.circle, - ), - outsideDaysVisible: false, - ), - - // Custom day builder for unavailable days - calendarBuilders: CalendarBuilders( - defaultBuilder: (context, day, focusedDay) { - final isAvailable = state.availableDates - .any((d) => isSameDay(d, day)); - - if (!isAvailable) { - // ❌ Strike-through unavailable date - return Stack( - alignment: Alignment.center, - children: [ - Text( - '${day.day}', - style: GoogleFonts.poppins( - fontSize: 12.sp, - color: Colors.grey.shade400, - ), - ), - Positioned( - top: 12.h, - child: Container( - width: 14.w, - height: 1.2.h, - color: Colors.grey.shade400, - ), - ), - ], - ); - } - - // βœ… Normal available day - return Center( - child: Text( - '${day.day}', - style: GoogleFonts.poppins( - fontSize: 12.sp, - color: Colors.black87, - ), - ), - ); - }, - ), - ), - ], - ), - ), - - SizedBox(height: 40.h), - - // βœ… Confirm Booking button - GestureDetector( - onTap: () { - if (state.startDate != null && state.endDate != null) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - "Booking confirmed from " - "${state.startDate!.toLocal().toString().split(' ')[0]} " - "to ${state.endDate!.toLocal().toString().split(' ')[0]}", - ), - ), - ); - } else { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text("Please select a valid date range"), - ), - ); - } - }, - child: Container( - width: double.infinity, - padding: EdgeInsets.symmetric(vertical: 14.h), - decoration: BoxDecoration( - color: const Color(0xffFF5A5F), - borderRadius: BorderRadius.circular(30.r), - ), - child: Center( - child: Text( - "Confirm Booking", - style: GoogleFonts.poppins( - color: Colors.white, - fontSize: 14.sp, - fontWeight: FontWeight.w600, - ), ), ), ), - ), - ], + ], + ), ), ), ); @@ -242,4 +216,18 @@ class MakeBookingView extends StatelessWidget { ), ); } + + /// Marks unavailable days (those not in availableDates) as blackout + List _getUnavailableDates(List available, DateTime start) { + final end = start.add(const Duration(days: 365)); + final allDays = List.generate( + end.difference(start).inDays, + (i) => DateTime(start.year, start.month, start.day + i), + ); + + return allDays + .where((day) => !available.any((a) => + a.year == day.year && a.month == day.month && a.day == day.day)) + .toList(); + } } diff --git a/lib/my_pass/views/booking_successful_page_view.dart b/lib/my_pass/views/booking_successful_page_view.dart new file mode 100644 index 0000000..db3dae2 --- /dev/null +++ b/lib/my_pass/views/booking_successful_page_view.dart @@ -0,0 +1,82 @@ +import 'package:citycards_customer/common_packages/app_bar.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:google_fonts/google_fonts.dart'; + +import '../../common_packages/back_widget.dart'; + +class BookingSuccessfulPageView extends StatelessWidget { + const BookingSuccessfulPageView({super.key}); + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Scaffold( + backgroundColor: Colors.white, + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CommonAppBar(isWhiteLogo: false, isProfilePage: false), + backWidget(context, "Make Booking", Colors.black), + SizedBox(height: 40.h), + + Image.asset("assets/images/booking_successful.png", scale: 4,), + + SizedBox(height: 20.h), + + Text( + "Booking Completed\nSuccessfully!", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 20.sp, + fontWeight: FontWeight.w600, + color: Color(0xff0A0D13), + ), + ), + + SizedBox(height: 20.h), + + Text( + "Your booking has been Confirmed on 08/01/2025", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 16.sp, + fontWeight: FontWeight.w400, + color: Color(0xff2D3134), + ), + ), + + SizedBox(height: 100.h), + + GestureDetector( + onTap: () { + + }, + child: Container( + width: double.infinity, + padding: EdgeInsets.symmetric(vertical: 14.h), + decoration: BoxDecoration( + color: const Color(0xffFF5A5F), + borderRadius: BorderRadius.circular(30.r), + ), + child: Center( + child: Text( + "Go Back", + style: GoogleFonts.poppins( + color: Colors.white, + fontSize: 14.sp, + fontWeight: FontWeight.w600, + ), + ), + ), + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/your_itinerary/view/your_itinerary_view.dart b/lib/your_itinerary/view/your_itinerary_view.dart index fb74d60..d4830f9 100644 --- a/lib/your_itinerary/view/your_itinerary_view.dart +++ b/lib/your_itinerary/view/your_itinerary_view.dart @@ -1,5 +1,6 @@ import 'package:citycards_customer/common_packages/app_bar.dart'; import 'package:citycards_customer/common_packages/custom_text.dart'; +import 'package:citycards_customer/core/route_constants.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'; @@ -54,7 +55,7 @@ class YourItineraryView extends StatelessWidget { children: [ GestureDetector( onTap: () { - Navigator.pop(context); + Navigator.of(context).pushReplacementNamed(RouteConstants.magicItineraryFilledScreen); }, child: Icon( Icons.arrow_back, diff --git a/pubspec.lock b/pubspec.lock index 92d85c5..7fc3f82 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -190,6 +190,11 @@ packages: url: "https://pub.dev" source: hosted version: "5.0.0" + flutter_localizations: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" flutter_otp_text_field: dependency: "direct main" description: @@ -709,6 +714,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.4.1" + syncfusion_flutter_calendar: + dependency: "direct main" + description: + name: syncfusion_flutter_calendar + sha256: "632de42a4cc82dfb1fbc9b40e7097477069aab516a842ca50b187052ab091180" + url: "https://pub.dev" + source: hosted + version: "31.2.4" + syncfusion_flutter_core: + dependency: transitive + description: + name: syncfusion_flutter_core + sha256: a24e9ec04e03c2c14b7b41b1afe60e455adef09b244ab4c425ce6c5b8f58c9ce + url: "https://pub.dev" + source: hosted + version: "31.2.4" + syncfusion_flutter_datepicker: + dependency: transitive + description: + name: syncfusion_flutter_datepicker + sha256: "554544875e7fcff8c244aa9e9e77c7b72f75808ebaa30f9f7af3fc9700d6ba18" + url: "https://pub.dev" + source: hosted + version: "31.2.4" + syncfusion_localizations: + dependency: transitive + description: + name: syncfusion_localizations + sha256: "4df6e5e1404f8e9c8c1affc38d476158b889c5e1b529514976181e49a7ba3944" + url: "https://pub.dev" + source: hosted + version: "31.2.4" table_calendar: dependency: "direct main" description: @@ -733,6 +770,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.6" + timezone: + dependency: transitive + description: + name: timezone + sha256: dd14a3b83cfd7cb19e7888f1cbc20f258b8d71b54c06f79ac585f14093a287d1 + url: "https://pub.dev" + source: hosted + version: "0.10.1" typed_data: dependency: transitive description: @@ -799,4 +844,4 @@ packages: version: "6.6.1" sdks: dart: ">=3.9.0 <4.0.0" - flutter: ">=3.35.0" + flutter: ">=3.35.1" diff --git a/pubspec.yaml b/pubspec.yaml index 461c3c3..befc6d6 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -45,6 +45,7 @@ dependencies: geolocator: ^14.0.2 equatable: ^2.0.7 table_calendar: ^3.2.0 + syncfusion_flutter_calendar: ^31.2.4 dev_dependencies: flutter_test: