From 2d4b93d2649ca7fab8eeb4660adbd455ffe95762 Mon Sep 17 00:00:00 2001 From: "taha.alam" Date: Tue, 16 Sep 2025 12:30:44 +0300 Subject: [PATCH] discount banner and offer detail page static page added --- assets/images/svg/details_page_banner.svg | 988 +++++++++++++++++ assets/images/svg/main_banner.svg | 998 ++++++++++++++++++ .../fragments/home_page_fragment2.dart | 7 + lib/pages/landing/fragments/offer_banner.dart | 122 +++ .../landing/fragments/offer_details_page.dart | 268 +++++ .../dialogs/location_selection_dialog.dart | 28 +- 6 files changed, 2403 insertions(+), 8 deletions(-) create mode 100644 assets/images/svg/details_page_banner.svg create mode 100644 assets/images/svg/main_banner.svg create mode 100644 lib/pages/landing/fragments/offer_banner.dart create mode 100644 lib/pages/landing/fragments/offer_details_page.dart diff --git a/assets/images/svg/details_page_banner.svg b/assets/images/svg/details_page_banner.svg new file mode 100644 index 00000000..9ea0b125 --- /dev/null +++ b/assets/images/svg/details_page_banner.svg @@ -0,0 +1,988 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/images/svg/main_banner.svg b/assets/images/svg/main_banner.svg new file mode 100644 index 00000000..26097502 --- /dev/null +++ b/assets/images/svg/main_banner.svg @@ -0,0 +1,998 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/pages/landing/fragments/home_page_fragment2.dart b/lib/pages/landing/fragments/home_page_fragment2.dart index f71122ff..e6eabcb2 100644 --- a/lib/pages/landing/fragments/home_page_fragment2.dart +++ b/lib/pages/landing/fragments/home_page_fragment2.dart @@ -10,6 +10,8 @@ import 'package:hmg_patient_app/models/hmg_services.dart'; import 'package:hmg_patient_app/models/slider_data.dart'; import 'package:hmg_patient_app/pages/AlHabibMedicalService/all_habib_medical_service_page2.dart'; import 'package:hmg_patient_app/pages/ErService/ErOptions.dart'; +import 'package:hmg_patient_app/pages/landing/fragments/offer_banner.dart'; +import 'package:hmg_patient_app/pages/landing/fragments/offer_details_page.dart'; import 'package:hmg_patient_app/pages/landing/widgets/logged_slider_view.dart'; import 'package:hmg_patient_app/pages/landing/widgets/services_view.dart'; import 'package:hmg_patient_app/pages/landing/widgets/slider_view.dart'; @@ -147,6 +149,11 @@ class _HomePageFragment2State extends State { // height: MediaQuery.of(context).size.width / 2.6, ), ), + InkWell( + onTap: (){ + Navigator.push(context, MaterialPageRoute(builder: (context) => OfferDetailsPage(title: "25% discount",))); + }, + child: DiscountCardWidget()), projectViewModel.isLogin ? Column( children: [ diff --git a/lib/pages/landing/fragments/offer_banner.dart b/lib/pages/landing/fragments/offer_banner.dart new file mode 100644 index 00000000..53ca0739 --- /dev/null +++ b/lib/pages/landing/fragments/offer_banner.dart @@ -0,0 +1,122 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +class DiscountCardWidget extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Directionality( + textDirection: TextDirection.ltr, + child: Container( + padding: EdgeInsets.only(left: 16,right: 16, top:8), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(24), + ), + child: Stack( + children: [ + // Left icon (replace with your asset if needed) + SvgPicture.asset("assets/images/svg/main_banner.svg", height: 170 ,width: MediaQuery.sizeOf(context).width,fit: BoxFit.fill), + // Main content + Padding( + padding: const EdgeInsets.only(right:8.0, left: 8.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded(child: SizedBox.shrink()), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + const SizedBox(height: 12), + + /// Arabic Section (top-right) + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: const [ + Text( + "خصم %25", + style: TextStyle( + fontSize: 20, + fontFamily: 'Cairo', + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + Text( + "عرض على الفحوصات الطبية", + style: TextStyle( + fontSize: 12, + fontFamily: 'Cairo', + fontWeight: FontWeight.w300, + color: Colors.white, + ), + ), + ], + ), + + const SizedBox(height: 8), + + /// English Section (middle-left) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text( + "25% Discount", + style: TextStyle( + fontFamily: 'Poppins', + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + Text( + "On a medical examination or test", + style: TextStyle( + fontSize: 12, + fontFamily: 'Poppins', + + color: Colors.white, + ), + ), + ], + ), + + ], + ), + ], + ), + + + SizedBox(height: 16), + // Bottom row + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + + Text( + 'This Offer is valid till 1st Oct 2025', + style: TextStyle( + fontFamily: 'Poppins', + fontSize: 11, + color: Colors.white, + ), + ), + Text( + 'يسري العرض حتى 1 أكتوبر 2025', + style: TextStyle( + fontFamily: 'Cairo', fontSize: 11, + fontWeight: FontWeight.w300, + color: Colors.white, + ), + ), + ], + ), + ], + ), + ), + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/pages/landing/fragments/offer_details_page.dart b/lib/pages/landing/fragments/offer_details_page.dart new file mode 100644 index 00000000..e0ed6418 --- /dev/null +++ b/lib/pages/landing/fragments/offer_details_page.dart @@ -0,0 +1,268 @@ +import 'dart:ui'; + +import 'package:auto_size_text/auto_size_text.dart' show AutoSizeText; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:hmg_patient_app/core/model/hospitals/hospitals_model.dart'; +import 'package:hmg_patient_app/core/viewModels/project_view_model.dart'; +import 'package:hmg_patient_app/uitl/translations_delegate_base.dart'; +import 'package:hmg_patient_app/uitl/utils.dart'; +import 'package:hmg_patient_app/uitl/utils_new.dart'; +import 'package:hmg_patient_app/widgets/buttons/custom_text_button.dart'; +import 'package:hmg_patient_app/widgets/dialogs/location_selection_dialog.dart' show LocationSelectionDialog; +import 'package:hmg_patient_app/widgets/others/app_scaffold_widget.dart'; +import 'package:provider/provider.dart'; + +class OfferDetailsPage extends StatefulWidget { + final String title; + + const OfferDetailsPage({super.key, required this.title}); + + @override + State createState() => _OfferDetailsPageState(); +} + +class _OfferDetailsPageState extends State { + HospitalsModel? selectedHospital; + @override + Widget build(BuildContext context) { + return Directionality( + // lock the whole page to LTR + textDirection: TextDirection.ltr, + child:AppScaffold( + isShowDecPage: false, + isShowAppBar: false, + showNewAppBar: true, + isHelp: true, + showNewAppBarTitle: true, + appBarTitle: widget.title, + body: Column( + children: [ + Expanded(child: SingleChildScrollView( + child: Column( + children: [ + /// Banner + SvgPicture.asset( + "assets/images/svg/details_page_banner.svg", + height: 120, + fit: BoxFit.fill, + ), + + /// Arabic Offer Section + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 24.0, vertical: 32.0), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(top: 32), + child: Directionality( + textDirection: TextDirection.rtl, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text( + "خصم %25", + style: TextStyle( + fontFamily: 'Cairo', + fontSize: 22, + fontWeight: FontWeight.bold, + ), + ), + Text( + "عرض على الفحوصات الطبية", + style: TextStyle( + fontFamily: 'Cairo', + fontWeight: FontWeight.w300, + fontSize: 16, + ), + ), + SizedBox(height: 12), + Text( + "تفاصيل العرض هنا تفاصيل العرض هنا تفاصيل العرض هنا تفاصيل العرض هنا تفاصيل العرض هنا تفاصيل العرض هنا تفاصيل العرض هنا تفاصيل العرض هنا تفاصيل العرض هنا", + style: TextStyle( + fontFamily: 'Cairo', + fontWeight: FontWeight.w300, + fontSize: 14, + ), + ), + ], + ), + ), + ), + + const SizedBox(height: 20), + + const Divider(thickness: 1, color: Colors.green), + + const SizedBox(height: 20), + + /// English Offer Section + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text( + "25% Discount", + style: TextStyle( + fontSize: 22, + fontWeight: FontWeight.bold, + color: Colors.green, + ), + ), + Text( + "On a medical examination or test", + style: TextStyle( + fontFamily: 'Poppins', + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(height: 12), + Text( + "OFFER DETAILS HERE OFFER DETAILS HERE OFFER DETAILS HERE OFFER DETAILS HERE OFFER DETAILS HERE", + style: TextStyle( + fontSize: 14, + fontFamily: 'Poppins', + ), + ), + ], + ), + ), + + const SizedBox(height: 24), + + /// Hospital Dropdown (mock UI) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 16, vertical: 12), + decoration: BoxDecoration( + color: Colors.grey.shade300, + borderRadius: BorderRadius.circular(12), + ), + child: InkWell( + onTap: (){ + openHospitalSelection(context); + }, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + children: [ + Directionality( + textDirection: TextDirection.rtl, + child: Text( + selectedHospital?.nameN ??"مستشفى المحمدية", + style: TextStyle( + fontWeight: FontWeight.bold, + fontFamily: 'Cairo', + ), + ), + ), + Text( + selectedHospital?.name??"Al Muhammadiya Hospital", + style: TextStyle( + fontWeight: FontWeight.bold, + fontFamily: 'Poppins', + ), + ), + ], + ), + ), + Icon(Icons.arrow_drop_down), + ], + ), + ), + ), + ), + + const SizedBox(height: 24), + + /// Buttons + + ], + ), + ), + + const SizedBox(height: 30), + ], + ), + ),), + + Padding( + padding: const EdgeInsets.only( + left: 12.0, right:12, bottom: 8), + child: Row( + children: [ + SizedBox( + width: MediaQuery.of(context).size.width-24, + height: 56, + + child: CustomTextButton( + + shape: cardRadiusNew(8), + //shape: OutlinedBorder(), + backgroundColor: Color(0xFFFBF2E31), + elevation: 0, + onPressed: () {}, + child: Center( + child: RichText( + text: TextSpan( + text: "Pay Now", + style: TextStyle( + fontFamily: 'Poppins', + ), + children: [ + TextSpan( + text:" ادفع الآن", + style: TextStyle( + fontWeight: FontWeight.w300, + fontFamily: 'Cairo', + ), + ), + ] + ), + + ), + ), + ), + ), + + ], + ), + ), + ], + ), + ), + ); + } + + openHospitalSelection(BuildContext context) { + var projectViewModel = Provider.of(context, listen: false); + int _selectedHospitalIndex = 0; + List projectsListLocal = []; + Utils.navigationProjectsList.forEach((v) { + projectsListLocal.add(new HospitalsModel.fromJson(v)); + }); + showDialog( + context: context, + builder: (cxt) => LocationSelectionDialog( + isArabic: projectViewModel.isArabic, + data: projectsListLocal, + + title: TranslationBase.of(context).selectHospital, + selectedIndex: _selectedHospitalIndex, + onValueSelected: (index) { + _selectedHospitalIndex = index; + setState(() { + selectedHospital = projectsListLocal[index]; + }); + }, + ), + ); + } +} diff --git a/lib/widgets/dialogs/location_selection_dialog.dart b/lib/widgets/dialogs/location_selection_dialog.dart index 3b9a7238..b6f60775 100644 --- a/lib/widgets/dialogs/location_selection_dialog.dart +++ b/lib/widgets/dialogs/location_selection_dialog.dart @@ -11,17 +11,20 @@ class LocationSelectionDialog extends StatelessWidget { final Function(int)? onValueSelected; final int? selectedIndex; final bool isArabic; + final String? title; - const LocationSelectionDialog({super.key, required this.data, this.onValueSelected, this.selectedIndex, required this.isArabic}); + const LocationSelectionDialog({super.key, required this.data, this.onValueSelected, this.selectedIndex, required this.isArabic, this.title }); @override Widget build(BuildContext context) { + print("the title is $title"); return Dialog( backgroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), child: LocationDialogBody( + title: title, isArabic: isArabic, data: data, onValueSelected: onValueSelected, @@ -31,12 +34,13 @@ class LocationSelectionDialog extends StatelessWidget { } class LocationDialogBody extends StatefulWidget { + final String? title; final List data; final Function(int)? onValueSelected; final int? selectedIndex; final bool isArabic; - const LocationDialogBody({super.key, required this.data, this.onValueSelected, this.selectedIndex, required this.isArabic}); + const LocationDialogBody({super.key, required this.data, this.onValueSelected, this.selectedIndex, required this.isArabic, this.title}); @override State createState() => _LocationDialogBodyState(); @@ -50,6 +54,7 @@ class _LocationDialogBodyState extends State { Widget build(BuildContext context) { return isListVisible ? LocationListExpandedBody( + title: widget.title, isArabic: widget.isArabic, data: widget.data, onItemClick: (data) { @@ -66,6 +71,7 @@ class _LocationDialogBodyState extends State { }, ) : LocationListWrapBody( + title: widget.title, onConfirmClicked: () { widget.onValueSelected?.call(currentlySelected); }, @@ -79,11 +85,12 @@ class _LocationDialogBodyState extends State { } class LocationListExpandedBody extends StatefulWidget { + final String? title; final List data; final Function(String) onItemClick; final bool isArabic; - const LocationListExpandedBody({super.key, required this.data, required this.onItemClick, required this.isArabic}); + const LocationListExpandedBody({super.key, required this.data, required this.onItemClick, required this.isArabic, this.title}); @override State createState() => _LocationListExpandedBodyState(); @@ -109,7 +116,7 @@ class _LocationListExpandedBodyState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: [ - SelectBranchHeader(), + SelectBranchHeader(title: widget.title,), SizedBox( height: 8, ), @@ -173,11 +180,13 @@ class _LocationListExpandedBodyState extends State { } class LocationListWrapBody extends StatelessWidget { + final String? title; + final VoidCallback? onConfirmClicked; final VoidCallback? onTextBoxClicked; final String selectedText; - const LocationListWrapBody({super.key, this.onConfirmClicked, this.onTextBoxClicked, required this.selectedText}); + const LocationListWrapBody({super.key, this.onConfirmClicked, this.onTextBoxClicked, required this.selectedText, this.title}); @override Widget build(BuildContext context) { @@ -186,7 +195,7 @@ class LocationListWrapBody extends StatelessWidget { child: Column( mainAxisSize: MainAxisSize.min, children: [ - SelectBranchHeader(), + SelectBranchHeader(title: title,), SizedBox( height: 24, ), @@ -195,7 +204,7 @@ class LocationListWrapBody extends StatelessWidget { onTextBoxClicked?.call(); }, title: Text( - TranslationBase.of(context).selectBranch, + title?? TranslationBase.of(context).selectBranch, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: Colors.black, letterSpacing: -0.96), ), subtitle: selectedText.isEmpty @@ -238,13 +247,16 @@ class LocationListWrapBody extends StatelessWidget { } class SelectBranchHeader extends StatelessWidget { + final String? title; + + const SelectBranchHeader({super.key, required this.title}); @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - TranslationBase.of(context).selectBranch, + title??TranslationBase.of(context).selectBranch, style: TextStyle(fontSize: 24, fontWeight: FontWeight.w600, color: Colors.black, letterSpacing: -0.96), ), InkWell(