diff --git a/assets/icons/bus.png b/assets/icons/bus.png new file mode 100644 index 0000000..85bf35e Binary files /dev/null and b/assets/icons/bus.png differ diff --git a/assets/icons/bx_qr.png b/assets/icons/bx_qr.png new file mode 100644 index 0000000..7a0b3ca Binary files /dev/null and b/assets/icons/bx_qr.png differ diff --git a/assets/icons/clock.png b/assets/icons/clock.png new file mode 100644 index 0000000..e14d503 Binary files /dev/null and b/assets/icons/clock.png differ diff --git a/assets/icons/facebook.png b/assets/icons/facebook.png new file mode 100644 index 0000000..158f0e1 Binary files /dev/null and b/assets/icons/facebook.png differ diff --git a/assets/icons/indeed.png b/assets/icons/indeed.png new file mode 100644 index 0000000..a84d8d2 Binary files /dev/null and b/assets/icons/indeed.png differ diff --git a/assets/icons/insta.png b/assets/icons/insta.png new file mode 100644 index 0000000..53cbdf7 Binary files /dev/null and b/assets/icons/insta.png differ diff --git a/assets/icons/skype.png b/assets/icons/skype.png new file mode 100644 index 0000000..cd70c64 Binary files /dev/null and b/assets/icons/skype.png differ diff --git a/assets/icons/snapchat.png b/assets/icons/snapchat.png new file mode 100644 index 0000000..ec4561a Binary files /dev/null and b/assets/icons/snapchat.png differ diff --git a/assets/icons/truecaller.png b/assets/icons/truecaller.png new file mode 100644 index 0000000..bcfa731 Binary files /dev/null and b/assets/icons/truecaller.png differ diff --git a/assets/icons/whatsapp.png b/assets/icons/whatsapp.png new file mode 100644 index 0000000..c5e4222 Binary files /dev/null and b/assets/icons/whatsapp.png differ diff --git a/assets/images/attra_detail_map.png b/assets/images/attra_detail_map.png new file mode 100644 index 0000000..520c305 Binary files /dev/null and b/assets/images/attra_detail_map.png differ diff --git a/assets/images/koh_rong_samloem_banner.png b/assets/images/koh_rong_samloem_banner.png new file mode 100644 index 0000000..c8cdda3 Binary files /dev/null and b/assets/images/koh_rong_samloem_banner.png differ diff --git a/lib/attraction_details/attraction_details_view.dart b/lib/attraction_details/attraction_details_view.dart new file mode 100644 index 0000000..6ca5de3 --- /dev/null +++ b/lib/attraction_details/attraction_details_view.dart @@ -0,0 +1,482 @@ +import 'package:citycards_customer/attraction_details/share_bottomsheet.dart'; +import 'package:citycards_customer/common_packages/app_bar.dart'; +import 'package:citycards_customer/common_packages/custom_text.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class AttractionDetailsView extends StatelessWidget { + const AttractionDetailsView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: SafeArea( + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + Stack( + children: [ + Image.asset( + 'assets/images/koh_rong_samloem_banner.png', + height: 377.h, + width: double.infinity, + fit: BoxFit.cover, + ), + Positioned( + top: 0, + left: 0, + right: 0, + child: SafeArea( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 10.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + CommonAppBar(isWhiteLogo: true, isProfilePage: false), + + SizedBox(height: 10.h), + Divider( + color: Colors.white.withOpacity(0.6), + height: 1.h, + ), + SizedBox(height: 8.h), + + Row( + children: [ + GestureDetector( + onTap: () => Navigator.pop(context), + child: Icon( + Icons.arrow_back, + size: 24.sp, + color: Colors.white, + ), + ), + SizedBox(width: 8.w), + Text( + "Koh Rong Samloem", + style: TextStyle( + fontSize: 14.sp, + fontWeight: FontWeight.w600, + color: Colors.white, + ), + ), + ], + ), + ], + ), + ), + ), + ), + + Positioned( + bottom: 31.h, + left: 12.w, + child: Text( + "Koh Rong\nSamloem", + style: TextStyle( + color: Colors.white, + fontSize: 44.sp, + fontWeight: FontWeight.w500, + height: 1.2, + ), + ), + ), + + Positioned( + bottom: 31.h, + right: 17.w, + child: GestureDetector( + onTap: () { + showModalBottomSheet( + context: context, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (context) => const ShareBottomSheet(), + ); + }, + child: Container( + height: 36.h, + width: 36.w, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(20.r), + ), + child: Center( + child: Icon( + Icons.share_sharp, + color: Colors.black, + size: 18.sp, + ), + ), + ), + ), + ), + ], + ), + + // About Section + Padding( + padding: EdgeInsets.only(left: 16.w, right: 16.w, top: 30.h), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "About", + style: TextStyle( + fontSize: 18.sp, + fontWeight: FontWeight.w400, + ), + ), + SizedBox(height: 12.32.h), + Text( + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Convallis condimentum morbi non egestas enim amet sagittis. Proin sed aliquet rhoncus ut pellentesque ullamcorper sit eget ac.Sit nisi, cras amet varius eget egestas pellentesque. Cursus gravida euismod non...", + style: TextStyle( + color: Color(0xFF262626), + fontWeight: FontWeight.w400, + fontSize: 14.sp, + height: 1.5, + ), + ), + ], + ), + ), + SizedBox(height: 41.h), + // Booking Section + Padding( + padding: EdgeInsets.symmetric(horizontal: 16.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "How to make a booking?", + style: TextStyle( + fontSize: 18.sp, + fontWeight: FontWeight.w400, + ), + ), + SizedBox(height: 16.h), + Container( + padding: EdgeInsets.symmetric( + horizontal: 12.w, + vertical: 12.h, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8.r), + border: Border.all(color: Color(0xFFF95F62)), + ), + child: Row( + children: [ + Icon( + Icons.call, + color: Color(0xFFF95F62), + size: 32.w, + ), + SizedBox(width: 16.w), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + CustomText( + text: "Contact Number", + color: Colors.black.withOpacity(.6), + size: 12.sp, + weight: FontWeight.w500, + ), + SizedBox(height: 6.h), + CustomText( + text: "+1012 3456 789", + color: Colors.black, + size: 14.sp, + weight: FontWeight.w600, + ), + + SizedBox(height: 6.h), + CustomText( + text: "Tap to call", + color: Colors.black.withOpacity(.4), + size: 12.sp, + weight: FontWeight.w400, + ), + ], + ), + ), + ], + ), + ), + SizedBox(height: 16.h), + Container( + padding: EdgeInsets.symmetric( + horizontal: 12.w, + vertical: 12.h, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(8.r), + border: Border.all(color: Color(0xFFF95F62)), + ), + child: Row( + children: [ + Icon( + Icons.email_sharp, + color: Color(0xFFF95F62), + size: 32.w, + ), + SizedBox(width: 16.w), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + CustomText( + text: "Email", + color: Colors.black.withOpacity(.6), + size: 12.sp, + weight: FontWeight.w500, + ), + SizedBox(height: 6.h), + CustomText( + text: "CityCards24@gmail.com", + color: Colors.black, + size: 14.sp, + weight: FontWeight.w600, + ), + + SizedBox(height: 6.h), + CustomText( + text: "Tap to email", + color: Colors.black.withOpacity(.4), + size: 12.sp, + weight: FontWeight.w400, + ), + ], + ), + ), + ], + ), + ), + SizedBox(height: 16.h), + + Container( + padding: EdgeInsets.symmetric( + horizontal: 24.w, + vertical: 18.h, + ), + decoration: BoxDecoration( + color: Color(0xFFF95F62), + borderRadius: BorderRadius.circular(10.r), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + CustomText( + text: "Via CityCards", + size: 16.sp, + weight: FontWeight.w500, + color: Colors.white, + ), + SizedBox(height: 8.h), + CustomText( + text: "Create a booking via app", + size: 11.sp, + weight: FontWeight.w400, + color: Colors.white, + ), + ], + ), + ), + + Icon( + Icons.arrow_forward_ios_outlined, + color: Colors.white, + ), + ], + ), + ), + + SizedBox(height: 30.h), + + Divider(color: Colors.black.withOpacity(0.2)), + SizedBox(height: 30.h), + Text( + "What is included", + style: TextStyle( + fontSize: 24.sp, + fontWeight: FontWeight.w500, + ), + ), + SizedBox(height: 4.h), + + Wrap( + runSpacing: 16.h, + spacing: 16.w, + children: [ + includedBox( + "assets/icons/bus.png", + "Bus", + "Transportation", + ), + includedBox( + "assets/icons/clock.png", + "2 day 1 night", + "Duration", + ), + includedBox( + "assets/icons/bx_qr.png", + "TAC200812695", + "Product code", + ), + ], + ), + SizedBox(height: 30.h), + + Divider(color: Colors.black.withOpacity(0.2)), + SizedBox(height: 30.h), + Text( + "Exact Location", + style: TextStyle( + fontSize: 18.sp, + fontWeight: FontWeight.w400, + ), + ), + SizedBox(height: 8.h), + + CustomText( + text: "View the location on map", + size: 12.sp, + color: Colors.black.withOpacity(.6), + ), + SizedBox(height: 17.h), + + ClipRRect( + borderRadius: BorderRadius.circular(13.54.r), + child: Image.asset( + height: 178.7.h, + width: double.infinity, + "assets/images/attra_detail_map.png", + fit: BoxFit.cover, + ), + ), + + SizedBox(height: 17.h), + + CustomText( + text: + "Angkor Mails Hotel \nNR6, Krong Siem Reap Cambodia", + size: 12.sp, + color: Colors.black.withOpacity(0.6), + ), + + SizedBox(height: 30.h), + + Divider(color: Colors.black.withOpacity(0.2)), + SizedBox(height: 30.h), + Text( + "People frequently ask", + style: TextStyle( + fontSize: 18.sp, + fontWeight: FontWeight.w400, + ), + ), + + SizedBox(height: 15.h), + + faqBox( + "About this place", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. A id diam nisl, non justo, in odio...", + ), + + SizedBox(height: 15.h), + + faqBox( + "Term and condition", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. A id diam nisl, non justo, in odio...", + ), + SizedBox(height: 15.h), + + faqBox( + "Cancellation Policy", + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. A id diam nisl, non justo, in odio...", + ), + ], + ), + ), + + SizedBox(height: 24.h), + ], + ), + ), + ), + ); + } + + Widget includedBox(String icon, String title, String disc) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 10.h), + decoration: BoxDecoration( + color: Color(0xFFFFF5F5), + borderRadius: BorderRadius.circular(10.r), + border: Border.all(color: Color(0xFFFDCDCE)), + ), + child: IntrinsicWidth( + child: Row( + children: [ + Image.asset(icon, scale: 4), + SizedBox(width: 16.w), + Column( + children: [ + CustomText( + text: title, + size: 16.sp, + weight: FontWeight.w500, + color: Color(0xFF212121), + ), + SizedBox(height: 4.h), + CustomText( + text: disc, + size: 11.sp, + weight: FontWeight.w400, + color: Color(0xFF666666), + ), + ], + ), + ], + ), + ), + ); + } + + Widget faqBox(String title, String desc) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 12.h), + decoration: BoxDecoration( + color: Color(0xFFFFF5F5), + border: Border.all(color: Color(0xFFFDCDCE)), + borderRadius: BorderRadius.circular(10.r), + ), + child: Column( + children: [ + Row( + children: [ + CustomText( + text: title, + size: 16.sp, + weight: FontWeight.w500, + color: Color(0xFF212121), + ), + SizedBox(width: 20.w), + Icon(Icons.arrow_forward_ios_outlined, size: 18.sp), + ], + ), + SizedBox(height: 9.h), + CustomText(text: desc, size: 11.sp, color: Color(0xFF7D7D7D)), + ], + ), + ); + } +} diff --git a/lib/attraction_details/share_bottomsheet.dart b/lib/attraction_details/share_bottomsheet.dart new file mode 100644 index 0000000..8358ca0 --- /dev/null +++ b/lib/attraction_details/share_bottomsheet.dart @@ -0,0 +1,103 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class ShareBottomSheet extends StatelessWidget { + const ShareBottomSheet({super.key}); + + @override + Widget build(BuildContext context) { + final shareItems = [ + {'icon': 'assets/icons/whatsapp.png', 'title': 'WhatsApp'}, + {'icon': 'assets/icons/insta.png', 'title': 'Direct'}, + {'icon': 'assets/icons/snapchat.png', 'title': 'Snapchat'}, + {'icon': 'assets/icons/skype.png', 'title': 'Skype'}, + {'icon': 'assets/icons/truecaller.png', 'title': 'Truecaller'}, + {'icon': 'assets/icons/indeed.png', 'title': 'Private Message'}, + {'icon': 'assets/icons/indeed.png', 'title': 'Share In A Post'}, + {'icon': 'assets/icons/facebook.png', 'title': 'News Feed'}, + ]; + + return Container( + padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 16.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.vertical(top: Radius.circular(12.r)), + ), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + height: 4.h, + width: 47.w, + margin: EdgeInsets.only(bottom: 16), + decoration: BoxDecoration( + color: Color(0xFF222222), + borderRadius: BorderRadius.circular(8), + ), + ), + TextField( + readOnly: true, + decoration: InputDecoration( + hintText: "https://www.linkedin.com/link", + suffixIcon: IconButton( + icon: const Icon(Icons.copy, color: Color(0xFF858585)), + onPressed: () {}, + ), + filled: true, + fillColor: const Color(0xffFEE7E7), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(10), + borderSide: BorderSide.none, + ), + ), + ), + SizedBox(height: 20.h), + GridView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: shareItems.length, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 4, + mainAxisSpacing: 16, + crossAxisSpacing: 8, + childAspectRatio: 0.8, + ), + itemBuilder: (context, index) { + final item = shareItems[index]; + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + Image.asset(item['icon']!, width: 55.w), + SizedBox(height: 8.h), + Text( + item['title']!, + style: TextStyle(fontSize: 12.sp), + textAlign: TextAlign.center, + ), + ], + ); + }, + ), + const SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: List.generate( + 4, + (index) => Container( + margin: const EdgeInsets.symmetric(horizontal: 3), + width: 8.w, + height: 8.h, + decoration: BoxDecoration( + color: index == 0 ? Color(0xFF676363) : Colors.white, + border: Border.all(color: Color(0xFF676363)), + shape: BoxShape.circle, + ), + ), + ), + ), + SizedBox(height: 10.h), + ], + ), + ); + } +} diff --git a/lib/buy_a_pass/buy_pass_view.dart b/lib/buy_a_pass/buy_pass_view.dart new file mode 100644 index 0000000..0470b84 --- /dev/null +++ b/lib/buy_a_pass/buy_pass_view.dart @@ -0,0 +1,32 @@ +import 'package:citycards_customer/common_packages/app_bar.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class BuyPassView extends StatelessWidget { + const BuyPassView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + body: SafeArea( + child: SingleChildScrollView( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 20.0.w), + child: Column( + children: [ + CommonAppBar(isWhiteLogo: false, isProfilePage: true), + SizedBox(height:24.h), + Row( + children: [ + Icon(Icons.arrow_back,) + ], + ) + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/core/app_router.dart b/lib/core/app_router.dart index d92cfc5..8a7df42 100644 --- a/lib/core/app_router.dart +++ b/lib/core/app_router.dart @@ -1,4 +1,6 @@ import 'package:citycards_customer/Profile/profile_page_view.dart'; +import 'package:citycards_customer/attraction_details/attraction_details_view.dart'; +import 'package:citycards_customer/buy_a_pass/buy_pass_view.dart'; import 'package:citycards_customer/common_bloc/language_selection_bloc.dart'; import 'package:citycards_customer/contact_us/contact_us_view.dart'; import 'package:citycards_customer/edit_profile/edit_profile_view.dart'; @@ -28,6 +30,8 @@ class AppRouter { return BlocProvider( create: (_) => NavigationBloc(), child: const HomePage(), + + ); }, ); @@ -111,10 +115,20 @@ class AppRouter { return EsimOfferPage(); }, ); + + case RouteConstants.attractionDetails: + return MaterialPageRoute(builder: (_) { + return AttractionDetailsView(); + }); + + case RouteConstants.buyPass: + return MaterialPageRoute(builder: (_) { + return BuyPassView(); + }); default: return MaterialPageRoute( builder: (_) => - const Scaffold(body: Center(child: Text('404 - Page Not Found'))), + const Scaffold(body: Center(child: Text('404 - Page Not Found'))), ); } } diff --git a/lib/core/route_constants.dart b/lib/core/route_constants.dart index 80b884f..6f1309b 100644 --- a/lib/core/route_constants.dart +++ b/lib/core/route_constants.dart @@ -25,4 +25,15 @@ class RouteConstants { static const String esimOffer = '/esim_offer'; static const String hotelOffer = '/hotelOffer'; + +/**************************** Attraction Page *****************************************/ + + static const String attractionDetails ='/attractionDetails'; + + /**************************** By Pass Page Page *****************************************/ + + static const String buyPass ='/buyPass'; + + + } diff --git a/lib/main.dart b/lib/main.dart index 2f2b1c8..be24e47 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -29,7 +29,7 @@ class MyApp extends StatelessWidget { builder: (context, child) { return MaterialApp( onGenerateRoute: _appRouter.onGenerateRoute, - initialRoute: RouteConstants.home, + initialRoute: RouteConstants.buyPass, debugShowCheckedModeBanner: false, title: 'City Cards', theme: ThemeData(