import 'package:auto_route/auto_route.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:carousel_slider/carousel_slider.dart'; import 'package:drag_and_drop_lists/drag_and_drop_lists.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_linkify/flutter_linkify.dart'; import 'package:provider/provider.dart'; import 'package:telnow_mobile_new/src/api/api_auth_provider.dart'; import 'package:telnow_mobile_new/src/injector/injector.dart'; import 'package:telnow_mobile_new/src/layouts/functions/home.dart'; import 'package:telnow_mobile_new/src/layouts/components/template.dart'; import 'package:telnow_mobile_new/src/layouts/web/banner_detail.dart'; import 'package:telnow_mobile_new/src/layouts/web/message_list.dart'; import 'package:telnow_mobile_new/src/layouts/web/request_create.dart'; import 'package:telnow_mobile_new/src/layouts/web/request_select.dart'; import 'package:telnow_mobile_new/src/storage/sharedpreferences/shared_preferences_manager.dart'; import 'package:telnow_mobile_new/src/utils/U.dart'; import 'package:telnow_mobile_new/src/utils/cache_manager.dart'; import 'package:telnow_mobile_new/src/utils/provider.dart'; import 'package:url_launcher/url_launcher.dart'; class WebHomePage extends StatefulWidget { const WebHomePage({super.key}); @override State createState() => _WebHomePageState(); } class _WebHomePageState extends State { final HomeFunction homeFunc = HomeFunction(); final SharedPreferencesManager sharedPreferencesManager = locator(); @override void initState() { Provider.of(context, listen: false).reset(); Provider.of(context, listen: false).reset(); WidgetsBinding.instance.addPostFrameCallback((_) { Future.delayed(Duration(seconds: 1), (){ homeFunc.getProfileData(context); }); FirebaseMessaging.onMessage.listen((event) { if(event.data['type'] == 'MESSAGE'){ homeFunc.getUnreadMessages(context); } }); }); // TODO: implement initState super.initState(); } bool _timeLimit = false; @override Widget build(BuildContext context) { return Provider.of(context).user().isNotEmpty?Scaffold( backgroundColor: backgroundColor, appBar: PreferredSize(preferredSize: Size.fromHeight(0), child: AppBar(elevation: 0, backgroundColor: primaryColor)), body: Column( children: [ Container( width: double.infinity, color: primaryColor, padding: EdgeInsets.symmetric(vertical: 20, horizontal: 60), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.asset('assets/image/logo/logo.png', height: 35), SizedBox(width: 60), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: GestureDetector( child: Container( padding: EdgeInsets.symmetric(vertical: 8, horizontal: 15), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(50))), child: Row( children: [ U.iconsax('search-normal-1', color: textColor), SizedBox(width: 13), Expanded(child: Text(Provider.of(context).profile()['searchText'][context.locale.toString()] ?? 'searchAsk'.tr(), style: TextStyle(color: textColor.withValues(alpha: 0.5), fontSize: 14), overflow: TextOverflow.ellipsis)) ], ), ), onTap: () => navigateTo(context, WebReqSelectPage(user: Provider.of(context, listen: false).user(), title: 'search'.tr(), scope: Provider.of(context, listen: false).scoopeValue(), placeholder: Provider.of(context, listen: false).profile()['searchText'][context.locale.toString()] != null ? Provider.of(context, listen: false).profile()['searchText'][context.locale.toString()] : 'searchAsk'.tr())).then((val){ val = val??true; if(val) homeFunc.getFrequentlyRequested(context); }), ), ), SizedBox(width: 30), GestureDetector( child: Container( padding: EdgeInsets.all(8), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(50))), child: Stack( alignment: Alignment.topRight, children: [ U.iconsax('sms-notification', color: primaryColor), Provider.of(context).unreadMessage() ? Container( width: 9, height: 9, margin: EdgeInsets.only(top: 1.3), decoration: BoxDecoration(color: Colors.red, borderRadius: BorderRadius.all(Radius.circular(50))), ):Container() ], ), ), onTap: ()=>navigateTo(context, WebMessageListPage(Provider.of(context, listen: false).user())), ), SizedBox(width: 10), GestureDetector( child: Container( padding: EdgeInsets.all(8), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(50))), child: U.iconsax('archive-2', color: primaryColor), ), onTap: (){ var pid = U.getPidFromUrl(context.router.currentUrl); context.router.removeLast(); context.navigateToPath("/app/$pid/menu/history"); }, ), SizedBox(width: 10), GestureDetector( child: Container( padding: EdgeInsets.all(8), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(50))), child: U.iconsax('personalcard', color: primaryColor), ), onTap: (){ var pid = U.getPidFromUrl(context.router.currentUrl); context.router.removeLast(); context.navigateToPath("/app/$pid/menu/account"); }, ) ], ), Provider.of(context).profile()['greeting'][context.locale.toString()] != null ? Padding( padding: EdgeInsets.fromLTRB(15, 5, 15, 0), child: Text(Provider.of(context).profile()['greeting'][context.locale.toString()], style: TextStyle(color: Colors.white, fontSize: 14), overflow: TextOverflow.ellipsis), ) : Container(), ], ), ), SizedBox(width: 60), Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text('${Provider.of(context).user()['name']}${(Provider.of(context).user()['guestName']!=null&&Provider.of(context).user()['guestName']!=''?' - ${Provider.of(context).user()['guestName']}':'')}', style: TextStyle(color: Colors.white, fontSize: 18), overflow: TextOverflow.ellipsis), SizedBox(height: 10), Container( child: Row( children: [ GestureDetector(child: Icon(Icons.info_outline, color: Colors.white, size: 20), onTap: () => showSuccess(context, "scopeDesc".tr()),), SizedBox(width: 8), Text('scope'.tr(), style: TextStyle(color: Colors.white, fontSize: 14)), SizedBox(width: 16), GestureDetector( child: Container( padding: EdgeInsets.fromLTRB(16, 4, 16, 4), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(50))), child: Row( children: [ Text(Provider.of(context).scoopeName(), style: TextStyle(color: primaryColor, fontSize: 14)), SizedBox(width: 8), U.iconsax('arrow-down-1', color: primaryColor, size: 14), ], ), ), onTap: (){ if(Provider.of(context, listen: false).scoope().isNotEmpty){ showDialog( context: context, builder: (contexts) { return AlertDialog( contentPadding: EdgeInsets.symmetric(vertical: 0, horizontal: 10), content: Column( mainAxisSize: MainAxisSize.min, children: [ Container( margin: EdgeInsets.symmetric(vertical: 16), child: Text('changeScope'.tr(), style: TextStyle(color: textColor, fontSize: 14), textAlign: TextAlign.center), ), divider(), SizedBox(height: 16), Column( children: List.generate(Provider.of(context).getScoopeLength(), (i){ return GestureDetector( child: Container( color: Colors.white, padding: EdgeInsets.symmetric(vertical: 16, horizontal: 16), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(Provider.of(context).scoope()[i]['value'], style: TextStyle(color: textColor, fontSize: 14)), Icon(Provider.of(context).checkScoope(Provider.of(context).scoope()[i]['key'])?Icons.radio_button_checked:Icons.radio_button_off, color: Provider.of(context).checkScoope(Provider.of(context).scoope()[i]['key'])?primaryColor:Colors.black45, size: 22), ], ), ), onTap: () async{ await sharedPreferencesManager.putString(SharedPreferencesManager.keyScoope, Provider.of(context, listen: false).scoope()[i]['key']); Provider.of(context, listen: false).setScoopeValue(Provider.of(context, listen: false).scoope()[i]['key']); Provider.of(context, listen: false).setScoopeName(Provider.of(context, listen: false).scoope()[i]['value']); Navigator.of(contexts).pop(); var profile = Provider.of(context, listen: false).profile(); if(profile['topMenu']['show'] != null && profile['topMenu']['show'] == true) { if(U.newServerVersion(1709864293)){ homeFunc.getTopMenuNew(context); } else{ homeFunc.getTopMenu(context); homeFunc.getReqGroup(context); } } if(profile['specialOffer'] != null && profile['specialOffer']['show'] == true) homeFunc.getSpecialOffer(context); if(profile['frequentlyRequested'] != null && profile['frequentlyRequested']['show'] == true) homeFunc.getFrequentlyRequested(context); if(profile['banner'] != null && profile['banner']['show'] == true) homeFunc.getBanner(context); if(profile['quickAction'] != null && profile['quickAction']['show'] == true) homeFunc.getQuickAction(context); } ); }), ), SizedBox(height: 16), ], ), ); }, ); } }, ) ], ), ), ], ) ], ), ), Expanded( child: Center( child: Container( alignment: Alignment.topCenter, child: SingleChildScrollView( padding: EdgeInsets.symmetric(vertical: 25, horizontal: 100), child: Column( children: [ Provider.of(context).profile()['banner'] != null && Provider.of(context).profile()['banner']['show'] == true ? Container( child: Provider.of(context).banner().isNotEmpty ? LayoutBuilder( builder: (context, constraints) => CarouselSlider.builder( itemCount: Provider.of(context).banner().length, options: CarouselOptions( height: constraints.maxWidth/3.2, initialPage: 0, viewportFraction: 1, autoPlay: true, autoPlayInterval: Duration(seconds: 5), autoPlayAnimationDuration: Duration(seconds: 1), autoPlayCurve: Curves.fastOutSlowIn, enlargeCenterPage: true, enableInfiniteScroll: true, scrollDirection: Axis.horizontal, ), itemBuilder: (BuildContext context, int i, int pageViewIndex) => GestureDetector( child: Container( width: double.infinity, decoration: BoxDecoration( color: Colors.white, border: Border.all(color: textColor.withValues(alpha: 0.15)), borderRadius: BorderRadius.all(Radius.circular(12)) ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Container( width: double.infinity, height: double.infinity, child: Provider.of(context).banner()[i]['image'] != null ? null : Center(child: Text("noImage".tr(), style: TextStyle(fontStyle: FontStyle.italic, color: Colors.black38), textAlign: TextAlign.center)), decoration: BoxDecoration( color: textColor.withValues(alpha: 0.1), borderRadius: BorderRadius.all(Radius.circular(12)), image: Provider.of(context).banner()[i]['image'] != null ? DecorationImage( image: CachedNetworkImageProvider(Provider.of(context).banner()[i]['image']+'?bridge-cache=true', cacheManager: CacheManager(CacheMan.config(Provider.of(context).banner()[i]['image']))), fit: BoxFit.cover, ):null, ), ), ), Container( padding: EdgeInsets.all(12), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(Provider.of(context).banner()[i][U.langColumn(context, 'title')] != null && Provider.of(context).banner()[i][U.langColumn(context, 'title')] != '' ? Provider.of(context).banner()[i][U.langColumn(context, 'title')]:Provider.of(context).banner()[i]['titleEn']!=null?Provider.of(context).banner()[i]['titleEn']:Provider.of(context).banner()[i]['title'], style: TextStyle(color: textColor, fontWeight: FontWeight.w500), overflow: TextOverflow.ellipsis), SizedBox(height: 5), Linkify( text: Provider.of(context).banner()[i][U.langColumn(context, 'description')] != null && Provider.of(context).banner()[i][U.langColumn(context, 'description')] != '' ? Provider.of(context).banner()[i][U.langColumn(context, 'description')]:Provider.of(context).banner()[i]['descriptionEn']!=null?Provider.of(context).banner()[i]['descriptionEn']:Provider.of(context).banner()[i]['description'], style: TextStyle(color: textColor, fontSize: 14), maxLines: 2, overflow: TextOverflow.ellipsis, onOpen: (link) async { if (await canLaunchUrl(Uri.parse(link.url))) { await launchUrl(Uri.parse(link.url)); } }, ) ], ), ), Padding( padding: const EdgeInsets.fromLTRB(12.0, 8.0, 8.0, 8.0), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate(Provider.of(context).banner().length, (index) => Padding( padding: const EdgeInsets.only(right: 8.0), child: Container( width: index == i ? 16.0 : 8.0, height: 8.0, decoration: BoxDecoration(borderRadius: BorderRadius.all(Radius.circular(8)), color: primaryColor.withValues(alpha: index == i ? 1 : 0.3)), ), )) ), ) ], ), ), onTap: ()=>navigateTo(context, WebBannerDetailPage(user: Provider.of(context, listen: false).user(), data: Provider.of(context, listen: false).banner()[i])).then((val){ val = val??true; if(val) homeFunc.getFrequentlyRequested(context); }), ), ), ) : Container(), ):Container(), Provider.of(context).profile()['topMenu']['show'] != null && Provider.of(context).profile()['topMenu']['show'] == true ? Container( margin: EdgeInsets.only(top: 25, bottom: 25), padding: EdgeInsets.only(top: 20, bottom: 10), decoration: BoxDecoration(color: Colors.white, border: Border.all(color: textColor.withValues(alpha: 0.15)), borderRadius: BorderRadius.all(Radius.circular(12))), child: Column( children: [ LayoutBuilder( builder: (context, constraints) { double size = constraints.maxWidth/10; double minHeight = 135; return Row( children: [ Provider.of(context).topMenu() != null ? Row( children: List.generate(Provider.of(context).topMenu()!.length+1, (i) { bool hideOther = i == Provider.of(context).topMenu()!.length && U.servantDisplay() && Provider.of(context).reqGroup()!.length == 0; return ConstrainedBox( constraints: BoxConstraints(minHeight: minHeight), child: Container( width: size, height: size, alignment: Alignment.center, child: GestureDetector( child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.start, children: [ hideOther ? Container(width: size/1.8) : i == Provider.of(context).topMenu()!.length ? Container( child: Container( padding: EdgeInsets.all(5), child: SizedBox(width: size/1.8, height: size/1.8, child: U.iconsax('category', color: Color(0xff564F4F), size: 34)), decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20)), boxShadow: [BoxShadow(color: Colors.grey.withValues(alpha: 0.3), blurRadius: 3, offset: Offset(0, 1))]), ), ) : Container( padding: EdgeInsets.all(5), child: Image(image: CachedNetworkImageProvider(Provider.of(context).topMenu()![i]['iconUrl']+'?bridge-cache=true', cacheManager: CacheManager(CacheMan.config(Provider.of(context).topMenu()![i]['iconUrl']+'?bridge-cache=true'))), width: size/1.8, height: size/1.8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20)), border: Border.all(width: 0.2, color: Colors.black12), boxShadow: [BoxShadow(color: Colors.grey.withValues(alpha: 0.3), blurRadius: 2, offset: Offset(0, 2))] ), ), SizedBox(height: hideOther ? 0:8), Expanded( child: hideOther ? Container(width: 70) : SizedBox(width: 70, child: Text(i == Provider.of(context).topMenu()!.length ? Provider.of(context).expand() ? 'showLess'.tr() : 'more'.tr() : U.servantDisplay() ? Provider.of(context).topMenu()![i]['description'] : Provider.of(context).topMenu()![i][U.langColumn(context, 'description')]??'', style: TextStyle(color: textColor, fontSize: 12, fontWeight: FontWeight.w300), maxLines: 2, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center)), ) ], ), onTap: (){ if(i == Provider.of(context, listen: false).topMenu()!.length){ if(!hideOther){ Provider.of(context, listen: false).setExpand(!Provider.of(context, listen: false).expand()); } } else{ navigateTo(context, WebReqSelectPage(user: Provider.of(context, listen: false).user(), title: U.servantDisplay() ? Provider.of(context, listen: false).topMenu()![i]['description'] : Provider.of(context, listen: false).topMenu()![i][U.langColumn(context, 'description')]??'', scope: Provider.of(context, listen: false).scoopeValue(), groupCode: Provider.of(context, listen: false).topMenu()![i]['code'])).then((val){ val = val??true; if(val) homeFunc.getFrequentlyRequested(context); }); } }, ), ), ); }), ) : Container(), Provider.of(context).user()['checkedIn'] && Provider.of(context).houseKeeping() && Provider.of(context).dndStatus() ? GestureDetector( child: Container( width: size*2, padding: EdgeInsets.symmetric(horizontal: 25), child: Container( padding: EdgeInsets.all(10), child: Column( children: [ Icon(Icons.remove_circle, color: Color(0xffD81010), size: 18), SizedBox(height: 10), Text('info_dnd'.tr(), style: TextStyle(color: textColor, fontSize: 14)) ], ), decoration: BoxDecoration(color: Color(0xffD81010).withValues(alpha: 0.15), borderRadius: BorderRadius.all(Radius.circular(10)), border: Border.all(color: Color(0xffD81010))), ), decoration: BoxDecoration(border: Border(left: BorderSide(color: Colors.grey))), ), onTap: (){ showDialog( context: context, builder: (context) => AlertDialog( content: Text('msg_dnd'.tr(), style: TextStyle(fontSize: 14, color: textColor), textAlign: TextAlign.center), ), ); } ) : Container() ], ); }, ), Provider.of(context).expand() ? Column( children: [ Padding(padding: EdgeInsets.symmetric(horizontal: 30, vertical: 15), child: divider()), Align( alignment: Alignment.centerRight, child: GestureDetector( child: Container( padding: EdgeInsets.symmetric(horizontal: 16, vertical: 4), margin: EdgeInsets.only(right: 30), child: Text('customize'.tr(), style: TextStyle(color: primaryColor, fontSize: 14)), decoration: BoxDecoration( color: primaryColor.withValues(alpha: 0.1), borderRadius: BorderRadius.all(Radius.circular(50)) ), ), onTap: ()=>navigateTo(context, WebMenuEditorPage(scope: Provider.of(context, listen: false).scoopeValue())), ), ), SizedBox(height: 20), LayoutBuilder( builder: (context, constraints) { double size = constraints.maxWidth/10; double minHeight = 125; return Provider.of(context).reqGroup() != null ? Wrap( children: List.generate(Provider.of(context).reqGroup()!.length, (i) { return ConstrainedBox( constraints: BoxConstraints(minHeight: minHeight), child: Container( width: size, height: size, alignment: Alignment.center, child: GestureDetector( child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.start, children: [ Container( padding: EdgeInsets.all(5), child: Image(image: CachedNetworkImageProvider(Provider.of(context).reqGroup()![i]['iconUrl']+'?bridge-cache=true', cacheManager: CacheManager(CacheMan.config(Provider.of(context).reqGroup()![i]['iconUrl']+'?bridge-cache=true'))), width: size/1.8, height: size/1.8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(20)), border: Border.all(width: 0.2, color: Colors.black12), boxShadow: [BoxShadow(color: Colors.grey.withValues(alpha: 0.3), blurRadius: 2, offset: Offset(0, 2))] ), ), SizedBox(height: 8), Expanded( child: SizedBox(width: 70, child: Text(U.servantDisplay() ? Provider.of(context).reqGroup()![i]['description'] : Provider.of(context).reqGroup()![i][U.langColumn(context, 'description')]??'', style: TextStyle(color: textColor, fontSize: 12, fontWeight: FontWeight.w300), maxLines: 2, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center)) ) ], ), onTap: (){ navigateTo(context, WebReqSelectPage(user: Provider.of(context, listen: false).user(), title: U.servantDisplay() ? Provider.of(context, listen: false).reqGroup()![i]['description'] : Provider.of(context, listen: false).reqGroup()![i][U.langColumn(context, 'description')]??'', scope: Provider.of(context, listen: false).scoopeValue(), groupCode: Provider.of(context, listen: false).reqGroup()![i]['code'])).then((val){ val = val??true; if(val) homeFunc.getFrequentlyRequested(context); }); }, ), ), ); }), ) : Container(); }, ) ], ) : Container(), ], ), ) : Container(), Provider.of(context).profile()['topMenu']['show'] != null && Provider.of(context).profile()['topMenu']['show'] == true ? separator() : Container(), Provider.of(context).profile()['specialOffer'] != null && Provider.of(context).profile()['specialOffer']['show'] == true ? Container( width: double.infinity, margin: EdgeInsets.only(top: 25), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(Provider.of(context).profile()['specialOffer']['label'][context.locale.toString()]??'Not Set', style: TextStyle(color: textColor, fontSize: 17, fontWeight: FontWeight.w600)), SizedBox(height: 12), Provider.of(context).specialOffer().isNotEmpty ? LayoutBuilder( builder: (context, constraints) { double size = (constraints.maxWidth/6)-13; double minWidth = 185; double minHeight = 250; return Wrap( spacing: 15, runSpacing: 15, children: List.generate(Provider.of(context).specialOffer().length, (i) => GestureDetector( child: ConstrainedBox( constraints: BoxConstraints(minWidth: minWidth, minHeight: minHeight), child: Container( width: size, height: size*1.4, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded(child: imageTiles(imageUrl: Provider.of(context).specialOffer()[i]['_mobileImage'] ?? "null", width: double.infinity, height: double.infinity)), Container( height: ((size*1.4) > minHeight ? (size*1.4) : minHeight) / 2.3, padding: EdgeInsets.fromLTRB(6, 12, 6, 0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(Provider.of(context).specialOffer()[i][U.langColumn(context, 'subject')], style: TextStyle(color: textColor, fontWeight: FontWeight.w600), maxLines: 2, overflow: TextOverflow.ellipsis), dashed(), Text(Provider.of(context).specialOffer()[i][U.langColumn(context, 'subjectDescription')], style: TextStyle(color: textColor, fontSize: 13), maxLines: 2, overflow: TextOverflow.ellipsis) ], ), ) ], ), decoration: BoxDecoration(color: Colors.white, border: Border.all(color: textColor.withValues(alpha: 0.15)), borderRadius: BorderRadius.all(Radius.circular(12))), ), ), onTap: ()=>navigateTo(context, WebReqCreatePage(user: Provider.of(context, listen: false).user(), request: Provider.of(context, listen: false).specialOffer()[i])), )), ); }, ) : emptyWidget() ], ), ) : Container(), Provider.of(context).profile()['frequentlyRequested'] != null && Provider.of(context).profile()['frequentlyRequested']['show'] == true ? Container( width: double.infinity, margin: EdgeInsets.only(top: 36, bottom: 25), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(Provider.of(context).profile()['frequentlyRequested']['label'][context.locale.toString()]??'Not Set', style: TextStyle(color: textColor, fontSize: 17, fontWeight: FontWeight.w600)), SizedBox(height: 12), Provider.of(context).data().isNotEmpty ? LayoutBuilder( builder: (context, constraints) { double size = (constraints.maxWidth/6)-13; double minWidth = 185; double minHeight = 220; return Wrap( spacing: 15, runSpacing: 15, children: List.generate(Provider.of(context).data().length, (i){ return GestureDetector( child: ConstrainedBox( constraints: BoxConstraints(minWidth: minWidth, minHeight: minHeight), child: Container( width: size, height: size*1.2, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded(child: imageTiles(imageUrl: Provider.of(context).data()[i]['_mobileImage'] ?? "null", width: double.infinity, height: double.infinity)), Container( height: ((size*1.2) > minHeight ? (size*1.2) : minHeight) / 2.6, padding: EdgeInsets.symmetric(vertical: 12, horizontal: 6), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded(child: Text(Provider.of(context).data()[i][U.langColumn(context, 'subject')], style: TextStyle(color: textColor, fontWeight: FontWeight.w600), maxLines: 2, overflow: TextOverflow.ellipsis)), Text(Provider.of(context).data()[i]['_frequentlyCount'].toString() + 'times'.tr(), style: TextStyle(color: textColor, fontSize: 14), overflow: TextOverflow.ellipsis) ], ), ) ], ), decoration: BoxDecoration(color: Colors.white, border: Border.all(color: textColor.withValues(alpha: 0.15)), borderRadius: BorderRadius.all(Radius.circular(12))), ), ), onTap: ()=>navigateTo(context, WebReqCreatePage(user: Provider.of(context, listen: false).user(), request: Provider.of(context, listen: false).data()[i])).then((val){ val = val??true; if(val) homeFunc.getFrequentlyRequested(context); }), ); }), ); }, ) : emptyWidget(), ], ), ):Container(), Provider.of(context).profile()['quickAction'] != null && Provider.of(context).profile()['quickAction']['show'] == true ? separator() : Container(), Provider.of(context).profile()['quickAction'] != null && Provider.of(context).profile()['quickAction']['show'] == true ? Container( width: double.infinity, margin: EdgeInsets.only(top: 25), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(Provider.of(context).profile()['quickAction']['label'][context.locale.toString()]??'Not Set', style: TextStyle(color: textColor, fontSize: 17, fontWeight: FontWeight.w600)), SizedBox(height: 12), Provider.of(context).quickAct().isNotEmpty ? LayoutBuilder( builder: (context, constraints) { var size = (constraints.maxWidth/2)-10; return Wrap( spacing: 20, runSpacing: 15, children: List.generate(Provider.of(context).quickAct().length, (i) { return GestureDetector( child: Container( width: size, child: Row( children: [ imageTiles(imageUrl: Provider.of(context).quickAct()[i]['_mobileImage'] ?? "null", width: 110, height: 90), SizedBox(width: 20), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(Provider.of(context).quickAct()[i][U.langColumn(context, 'subject')], style: TextStyle(color: textColor, fontWeight: FontWeight.w600), maxLines: 2, overflow: TextOverflow.ellipsis), dashed(), Text(Provider.of(context).quickAct()[i][U.langColumn(context, 'subjectDescription')], style: TextStyle(color: textColor), maxLines: 2, overflow: TextOverflow.ellipsis) ], ), ), Padding(padding: EdgeInsets.symmetric(horizontal: 20), child: U.iconsax('arrow-right-3', size: 16, color: textColor.withValues(alpha: 0.75))) ], ), decoration: BoxDecoration( color: Colors.white, border: Border.all(color: textColor.withValues(alpha: 0.15)), borderRadius: BorderRadius.all(Radius.circular(12)) ), ), onTap: ()=>navigateTo(context, WebReqCreatePage(user: Provider.of(context, listen: false).user(), request: Provider.of(context, listen: false).quickAct()[i])), ); }), ); }, ) : emptyWidget() ], ), ) : Container() ], ), ), ), ), ) ], ), ) : Provider.of(context).resetData() ? RefreshPage(() { Provider.of(context).setResetData(false); homeFunc.getProfileData(context); }) : _timeLimit ? showButton(context) : loadingTemplate(() {if(mounted) setState(()=>_timeLimit=true);},); } Widget emptyWidget(){ return Container( width: double.infinity, alignment: Alignment.center, margin: EdgeInsets.symmetric(vertical: 30), child: Text("notAvailable".tr(), style: TextStyle(color: textColor.withValues(alpha: 0.5), fontSize: 14, fontWeight: FontWeight.w400)), ); } } // --------------------------------------------------------------------------------------------------------------------------------------------- class WebMenuEditorPage extends StatefulWidget { String scope; WebMenuEditorPage({required this.scope, super.key}); @override State createState() => _WebMenuEditorPageState(); } class _WebMenuEditorPageState extends State { List data = []; List available = []; @override void initState() { data.addAll(Provider.of(context, listen: false).topMenu()!); available.addAll(Provider.of(context, listen: false).reqGroup()!); super.initState(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: backgroundColor, appBar: PreferredSize(preferredSize: Size.fromHeight(0), child: AppBar(elevation: 0, backgroundColor: primaryColor)), body: Column( children: [ Container( padding: EdgeInsets.symmetric(vertical: 25, horizontal: 100), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('customTopMenu'.tr(), style: TextStyle(color: textColor, fontSize: 17, fontWeight: FontWeight.w500), overflow: TextOverflow.ellipsis), GestureDetector( child: Text('buttonBack'.tr(), style: TextStyle(color: primaryColor, fontSize: 14)), onTap: ()=>navigateBack(context), ) ], ), ), divider(), Expanded( child: SingleChildScrollView( padding: EdgeInsets.symmetric(vertical: 25, horizontal: 100), child: Column( children: [ Container( padding: EdgeInsets.symmetric(vertical: 20, horizontal: 30), decoration: BoxDecoration(color: Colors.white, border: Border.all(color: textColor.withValues(alpha: 0.15)), borderRadius: BorderRadius.all(Radius.circular(12))), child: IntrinsicHeight( child: Row( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ DragAndDropLists( disableScrolling: true, lastItemTargetHeight: 8, lastListTargetSize: 0, children: [ DragAndDropList( contentsWhenEmpty: Padding( padding: const EdgeInsets.only(top: 16.0, bottom: 16.0), child: Text("emptyMenuAlert".tr(), style: TextStyle(fontStyle: FontStyle.italic, color: primaryColor.withValues(alpha: 0.60)),), ), canDrag: false, children: List.generate(data.length, (i){ return DragAndDropItem( child: Container( padding: EdgeInsets.symmetric(vertical: 8), child: Row( children: [ imageContainer(data[i]['iconUrl']), SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(data[i][U.langColumn(context, 'description')], style: TextStyle(color: textColor, fontSize: 14), overflow: TextOverflow.ellipsis), SizedBox(height: 4), Text(data[i][U.langColumn(context, 'description')], style: TextStyle(color: textColor, fontSize: 12, fontWeight: FontWeight.w300), overflow: TextOverflow.ellipsis), ], ), ), GestureDetector( child: U.iconsax('bold/minus-cirlce', color: Color(0xffD81010)), onTap: (){ setState(() { available.add(data[i]); data.remove(data[i]); }); }, ), SizedBox(width: 40) ], ), ), ); }), ) ], onItemReorder: (int oldItemIndex, int oldListIndex, int newItemIndex, int newListIndex) { setState(() { var movedItem = data.removeAt(oldItemIndex); data.insert(newItemIndex, movedItem); }); }, onListReorder: (int oldListIndex, int newListIndex) {}, itemDragHandle: DragHandle( child: Icon(Icons.menu_rounded, color: textColor), ), ), SizedBox(height: 20), Text('*${'limitTopMenu'.tr()}', style: TextStyle(color: textColor)) ], ), ), Container( width: 1, height: double.infinity, color: textColor.withValues(alpha: 0.15), margin: EdgeInsets.symmetric(horizontal: 30), ), Expanded( child: Column( children: List.generate(available.length, (i){ return Container( padding: EdgeInsets.symmetric(vertical: 8), child: Row( children: [ imageContainer(available[i]['iconUrl']), SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(available[i][U.langColumn(context, 'description')], style: TextStyle(color: textColor, fontSize: 14), overflow: TextOverflow.ellipsis), SizedBox(height: 4), Text(available[i][U.langColumn(context, 'description')], style: TextStyle(color: textColor, fontSize: 12, fontWeight: FontWeight.w300), overflow: TextOverflow.ellipsis), ], ), ), GestureDetector( child: U.iconsax('bold/add-circle', color: Color(0xffD81010)), onTap: (){ if(data.length < 7){ setState(() { data.add(available[i]); available.remove(available[i]); }); } else{ showError(context, 'maxMenu'.tr()); } }, ), ], ), ); }), ), ) ], ), ), ), SizedBox(height: 20), Row( mainAxisAlignment: MainAxisAlignment.start, children: [ buttonTemplate(text: 'textCancel'.tr(), backgroundColor: Colors.black12, borderColor: Colors.black12, textColor: textColor, width: 120, height: 40, action: (){ navigateBack(context); }), SizedBox(width: 20), buttonTemplate(text: 'done'.tr(), backgroundColor: primaryColor, borderColor: primaryColor, width: 120, height: 40, action: ()async{ if(data.isNotEmpty){ List codes = []; data.forEach((element) { codes.add(element['code']); }); var res = await ApiAuthProvider().postData('/api/informants/topMenu/${widget.scope}', {'topMenu': codes.join(';')}, null, context); if(res != null){ Provider.of(context, listen: false).setTopMenu(data); Provider.of(context, listen: false).setReqGroup(available); navigateBack(context, exc: true); } } else if(available.isEmpty) { navigateBack(context); } else { showError(context, "selectAlert".tr()); } }) ], ) ], ), ), ) ], ), ); } imageContainer(iconUrl){ return Container( padding: EdgeInsets.all(5), child: Image(image: CachedNetworkImageProvider(iconUrl+'?bridge-cache=true', cacheManager: CacheManager(CacheMan.config(iconUrl+'?bridge-cache=true'))), width: 50, height: 50), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(12)), border: Border.all(width: 0.2, color: Colors.black12), boxShadow: [BoxShadow(color: Colors.grey.withValues(alpha: 0.3), blurRadius: 2, offset: Offset(0, 2))] ), ); } }