diff --git a/siro_rider/lib/views/transit/transit_home_page.dart b/siro_rider/lib/views/transit/transit_home_page.dart index bfbe662e..545a244b 100644 --- a/siro_rider/lib/views/transit/transit_home_page.dart +++ b/siro_rider/lib/views/transit/transit_home_page.dart @@ -22,25 +22,29 @@ class TransitHomePage extends StatelessWidget { title: 'Mawasalati'.tr, isleading: true, body: [ - Expanded( - child: RefreshIndicator( - onRefresh: c.fetchMyEnrollments, - child: c.isLoadingEnrollments - ? const Center(child: CircularProgressIndicator()) - : c.myEnrollments.isEmpty - ? _emptyState(c) - : ListView( - padding: const EdgeInsets.all(16), - children: [ - Text('My Memberships'.tr, - style: AppStyle.headTitle2.copyWith(fontSize: 18)), - const SizedBox(height: 12), - ...c.myEnrollments.map((e) => _enrollmentCard(e, c)), - const SizedBox(height: 20), - _addOrgTile(), - ], - ), - ), + Column( + children: [ + Expanded( + child: RefreshIndicator( + onRefresh: c.fetchMyEnrollments, + child: c.isLoadingEnrollments + ? const Center(child: CircularProgressIndicator()) + : c.myEnrollments.isEmpty + ? _emptyState(c) + : ListView( + padding: const EdgeInsets.all(16), + children: [ + Text('My Memberships'.tr, + style: AppStyle.headTitle2.copyWith(fontSize: 18)), + const SizedBox(height: 12), + ...c.myEnrollments.map((e) => _enrollmentCard(e, c)), + const SizedBox(height: 20), + _addOrgTile(), + ], + ), + ), + ), + ], ), ], ), diff --git a/siro_rider/lib/views/transit/transit_org_browse_page.dart b/siro_rider/lib/views/transit/transit_org_browse_page.dart index 52b86477..c931cc84 100644 --- a/siro_rider/lib/views/transit/transit_org_browse_page.dart +++ b/siro_rider/lib/views/transit/transit_org_browse_page.dart @@ -22,7 +22,9 @@ class _TransitOrgBrowsePageState extends State { @override void initState() { super.initState(); - Get.find().browseOrgs(); + WidgetsBinding.instance.addPostFrameCallback((_) { + Get.find().browseOrgs(); + }); } @override @@ -32,59 +34,69 @@ class _TransitOrgBrowsePageState extends State { title: 'Choose your institution'.tr, isleading: true, body: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - child: TextField( - controller: _searchCtrl, - onSubmitted: (v) => c.browseOrgs(search: v), - decoration: InputDecoration( - hintText: 'Search for a university or institution...'.tr, - prefixIcon: const Icon(Icons.search), - filled: true, - fillColor: AppColor.cardColor, - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(12), - borderSide: BorderSide(color: AppColor.borderColor), + Column( + children: [ + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: TextField( + controller: _searchCtrl, + onSubmitted: (v) => c.browseOrgs(search: v), + decoration: InputDecoration( + hintText: 'Search for a university or institution...'.tr, + prefixIcon: const Icon(Icons.search), + filled: true, + fillColor: AppColor.cardColor, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + borderSide: BorderSide(color: AppColor.borderColor), + ), + ), ), ), - ), - ), - Expanded( - child: c.isLoadingOrgs - ? const Center(child: CircularProgressIndicator()) - : c.browsableOrgs.isEmpty - ? Center( - child: Text('No results'.tr, style: AppStyle.title), - ) - : ListView.builder( - padding: const EdgeInsets.symmetric(horizontal: 16), - itemCount: c.browsableOrgs.length, - itemBuilder: (_, i) { - final org = c.browsableOrgs[i]; - return Card( - margin: const EdgeInsets.only(bottom: 10), - color: AppColor.cardColor, - elevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(14), - side: BorderSide(color: AppColor.borderColor), - ), - child: ListTile( - title: Text(org.nameAr, style: AppStyle.title), - subtitle: Text(org.city, style: AppStyle.subtitle), - trailing: const Icon(Icons.arrow_forward_ios, size: 16), - onTap: () => _showActivateSheet(context, c, org), - ), - ); - }, - ), + Expanded( + child: c.isLoadingOrgs + ? const Center(child: CircularProgressIndicator()) + : c.browsableOrgs.isEmpty + ? Center( + child: Text('No results'.tr, style: AppStyle.title), + ) + : ListView.builder( + padding: const EdgeInsets.symmetric(horizontal: 16), + itemCount: c.browsableOrgs.length, + itemBuilder: (_, i) { + final org = c.browsableOrgs[i]; + return Card( + margin: const EdgeInsets.only(bottom: 10), + color: AppColor.cardColor, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(14), + side: BorderSide(color: AppColor.borderColor), + ), + child: ListTile( + title: + Text(org.nameAr, style: AppStyle.title), + subtitle: + Text(org.city, style: AppStyle.subtitle), + trailing: const Icon(Icons.arrow_forward_ios, + size: 16), + onTap: () => + _showActivateSheet(context, c, org), + ), + ); + }, + ), + ), + ], ), ], ), ); } - void _showActivateSheet(BuildContext context, TransitController c, TransitOrg org) { + void _showActivateSheet( + BuildContext context, TransitController c, TransitOrg org) { final idCtrl = TextEditingController(); bool loading = false; @@ -107,7 +119,8 @@ class _TransitOrgBrowsePageState extends State { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text(org.nameAr, style: AppStyle.headTitle2.copyWith(fontSize: 18)), + Text(org.nameAr, + style: AppStyle.headTitle2.copyWith(fontSize: 18)), const SizedBox(height: 6), Text('Enter your student/employee ID to activate membership'.tr, style: AppStyle.subtitle), @@ -118,7 +131,8 @@ class _TransitOrgBrowsePageState extends State { hintText: 'Student ID'.tr, filled: true, fillColor: AppColor.secondaryColor, - border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12)), ), ), const SizedBox(height: 16), @@ -128,7 +142,8 @@ class _TransitOrgBrowsePageState extends State { onPressed: () async { if (idCtrl.text.trim().isEmpty) return; setState(() => loading = true); - final ok = await c.activateEnrollment(org.id, idCtrl.text.trim()); + final ok = + await c.activateEnrollment(org.id, idCtrl.text.trim()); setState(() => loading = false); if (ok && ctx.mounted) { Navigator.pop(ctx); diff --git a/siro_rider/lib/views/transit/transit_routes_page.dart b/siro_rider/lib/views/transit/transit_routes_page.dart index e69544d9..d42e2e44 100644 --- a/siro_rider/lib/views/transit/transit_routes_page.dart +++ b/siro_rider/lib/views/transit/transit_routes_page.dart @@ -21,7 +21,9 @@ class _TransitRoutesPageState extends State { @override void initState() { super.initState(); - Get.find().openOrgRoutes(widget.orgId); + WidgetsBinding.instance.addPostFrameCallback((_) { + Get.find().openOrgRoutes(widget.orgId); + }); } @override @@ -31,41 +33,45 @@ class _TransitRoutesPageState extends State { title: widget.orgName, isleading: true, body: [ - Expanded( - child: c.isLoadingRoutes - ? const Center(child: CircularProgressIndicator()) - : c.currentOrgRoutes.isEmpty - ? Center( - child: Text('No active routes currently'.tr, style: AppStyle.title), - ) - : ListView.builder( - padding: const EdgeInsets.all(16), - itemCount: c.currentOrgRoutes.length, - itemBuilder: (_, i) { - final r = c.currentOrgRoutes[i]; - return Card( - margin: const EdgeInsets.only(bottom: 10), - color: AppColor.cardColor, - elevation: 0, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(14), - side: BorderSide(color: AppColor.borderColor), - ), - child: ListTile( - leading: CircleAvatar( - backgroundColor: AppColor.accentColor.withOpacity(0.15), - child: Icon(Icons.directions_bus, color: AppColor.accentColor), - ), - title: Text(r.nameAr, style: AppStyle.title), - subtitle: Text('${r.stopCount} ${'Stops'.tr}', style: AppStyle.subtitle), - trailing: const Icon(Icons.arrow_forward_ios, size: 16), - onTap: () => Get.to( - () => TransitLiveMapPage(routeId: r.id, routeName: r.nameAr), - ), - ), - ); - }, - ), + Column( + children: [ + Expanded( + child: c.isLoadingRoutes + ? const Center(child: CircularProgressIndicator()) + : c.currentOrgRoutes.isEmpty + ? Center( + child: Text('No active routes currently'.tr, style: AppStyle.title), + ) + : ListView.builder( + padding: const EdgeInsets.all(16), + itemCount: c.currentOrgRoutes.length, + itemBuilder: (_, i) { + final r = c.currentOrgRoutes[i]; + return Card( + margin: const EdgeInsets.only(bottom: 10), + color: AppColor.cardColor, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(14), + side: BorderSide(color: AppColor.borderColor), + ), + child: ListTile( + leading: CircleAvatar( + backgroundColor: AppColor.accentColor.withOpacity(0.15), + child: Icon(Icons.directions_bus, color: AppColor.accentColor), + ), + title: Text(r.nameAr, style: AppStyle.title), + subtitle: Text('${r.stopCount} ${'Stops'.tr}', style: AppStyle.subtitle), + trailing: const Icon(Icons.arrow_forward_ios, size: 16), + onTap: () => Get.to( + () => TransitLiveMapPage(routeId: r.id, routeName: r.nameAr), + ), + ), + ); + }, + ), + ), + ], ), ], ),